| author | |
| committer | |
| log | 3200ebc2ea5f6bb51130cbc69d6533144a9f4ddc |
| tree | e234c061c28a95c35afbb35b80b89e3114ecdeb9 |
| parent | 2e010c60ae006944ae20ab8b3445598471c9f1e8 |
| parent | b57cb04afc1898c3b21ef3486709f0c0aa285433 |
Zig now depends on LLVM 6.0.0.
The latest commit that depends on LLVM 5.0.1 is
2e010c60ae006944ae20ab8b3445598471c9f1e8.939 files changed, 48720 insertions(+), 15126 deletions(-)
CMakeLists.txt+112-56| ... | ... | @@ -64,97 +64,118 @@ else() |
| 64 | 64 | include_directories(${LLVM_INCLUDE_DIRS}) |
| 65 | 65 | include_directories(${CLANG_INCLUDE_DIRS}) |
| 66 | 66 | set(EMBEDDED_LLD_LIB_SOURCES |
| 67 | "${CMAKE_SOURCE_DIR}/deps/lld/Common/Args.cpp" | |
| 68 | "${CMAKE_SOURCE_DIR}/deps/lld/Common/ErrorHandler.cpp" | |
| 69 | "${CMAKE_SOURCE_DIR}/deps/lld/Common/Memory.cpp" | |
| 70 | "${CMAKE_SOURCE_DIR}/deps/lld/Common/Reproduce.cpp" | |
| 71 | "${CMAKE_SOURCE_DIR}/deps/lld/Common/Strings.cpp" | |
| 72 | "${CMAKE_SOURCE_DIR}/deps/lld/Common/TargetOptionsCommandFlags.cpp" | |
| 73 | "${CMAKE_SOURCE_DIR}/deps/lld/Common/Threads.cpp" | |
| 74 | "${CMAKE_SOURCE_DIR}/deps/lld/Common/Version.cpp" | |
| 75 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/DefinedAtom.cpp" | |
| 76 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/Error.cpp" | |
| 77 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/File.cpp" | |
| 78 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/LinkingContext.cpp" | |
| 79 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/Reader.cpp" | |
| 80 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/Resolver.cpp" | |
| 81 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/SymbolTable.cpp" | |
| 82 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/Writer.cpp" | |
| 67 | 83 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Driver/DarwinLdDriver.cpp" |
| 68 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Config/Version.cpp" | |
| 69 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp" | |
| 70 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/LayoutPass.cpp" | |
| 84 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/FileArchive.cpp" | |
| 71 | 85 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ArchHandler.cpp" |
| 86 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp" | |
| 72 | 87 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp" |
| 73 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ObjCPass.cpp" | |
| 74 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp" | |
| 75 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp" | |
| 76 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp" | |
| 77 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/TLVPass.cpp" | |
| 78 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp" | |
| 79 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/GOTPass.cpp" | |
| 80 | 88 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp" |
| 81 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp" | |
| 82 | 89 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp" |
| 90 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp" | |
| 91 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/GOTPass.cpp" | |
| 92 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/LayoutPass.cpp" | |
| 83 | 93 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp" |
| 94 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp" | |
| 95 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp" | |
| 96 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp" | |
| 97 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp" | |
| 98 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp" | |
| 99 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ObjCPass.cpp" | |
| 84 | 100 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ShimPass.cpp" |
| 85 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/WriterMachO.cpp" | |
| 86 | 101 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/StubsPass.cpp" |
| 87 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp" | |
| 88 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp" | |
| 89 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/FileArchive.cpp" | |
| 90 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/TargetOptionsCommandFlags.cpp" | |
| 91 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/File.cpp" | |
| 92 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/Error.cpp" | |
| 93 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/SymbolTable.cpp" | |
| 94 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/Reader.cpp" | |
| 95 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/Reproduce.cpp" | |
| 96 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/Writer.cpp" | |
| 97 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/LinkingContext.cpp" | |
| 98 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/Resolver.cpp" | |
| 99 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/DefinedAtom.cpp" | |
| 102 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/TLVPass.cpp" | |
| 103 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/WriterMachO.cpp" | |
| 104 | "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp" | |
| 100 | 105 | ) |
| 101 | 106 | set(EMBEDDED_LLD_ELF_SOURCES |
| 102 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/ScriptLexer.cpp" | |
| 107 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/AArch64ErrataFix.cpp" | |
| 108 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/AArch64.cpp" | |
| 103 | 109 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/AMDGPU.cpp" |
| 104 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/PPC.cpp" | |
| 105 | 110 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/ARM.cpp" |
| 106 | 111 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/AVR.cpp" |
| 107 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/SPARCV9.cpp" | |
| 108 | 112 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/Mips.cpp" |
| 109 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/AArch64.cpp" | |
| 110 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/X86_64.cpp" | |
| 111 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/PPC64.cpp" | |
| 112 | 113 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/MipsArchTree.cpp" |
| 114 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/PPC.cpp" | |
| 115 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/PPC64.cpp" | |
| 116 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/SPARCV9.cpp" | |
| 113 | 117 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/X86.cpp" |
| 114 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/GdbIndex.cpp" | |
| 118 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/X86_64.cpp" | |
| 115 | 119 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Driver.cpp" |
| 116 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Relocations.cpp" | |
| 117 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Error.cpp" | |
| 118 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/LTO.cpp" | |
| 119 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Strings.cpp" | |
| 120 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/ScriptParser.cpp" | |
| 121 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/MarkLive.cpp" | |
| 122 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/SyntheticSections.cpp" | |
| 123 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/SymbolTable.cpp" | |
| 124 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/LinkerScript.cpp" | |
| 120 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/DriverUtils.cpp" | |
| 125 | 121 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/EhFrame.cpp" |
| 126 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Target.cpp" | |
| 127 | 122 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Filesystem.cpp" |
| 128 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/OutputSections.cpp" | |
| 129 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Symbols.cpp" | |
| 123 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/GdbIndex.cpp" | |
| 130 | 124 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/ICF.cpp" |
| 131 | 125 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/InputFiles.cpp" |
| 132 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Thunks.cpp" | |
| 133 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/DriverUtils.cpp" | |
| 134 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Writer.cpp" | |
| 135 | 126 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/InputSection.cpp" |
| 127 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/LTO.cpp" | |
| 128 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/LinkerScript.cpp" | |
| 136 | 129 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/MapFile.cpp" |
| 130 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/MarkLive.cpp" | |
| 131 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/OutputSections.cpp" | |
| 132 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Relocations.cpp" | |
| 133 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/ScriptLexer.cpp" | |
| 134 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/ScriptParser.cpp" | |
| 135 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Strings.cpp" | |
| 136 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/SymbolTable.cpp" | |
| 137 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Symbols.cpp" | |
| 138 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/SyntheticSections.cpp" | |
| 139 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Target.cpp" | |
| 140 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Thunks.cpp" | |
| 141 | "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Writer.cpp" | |
| 137 | 142 | ) |
| 143 | ||
| 138 | 144 | set(EMBEDDED_LLD_COFF_SOURCES |
| 145 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Chunks.cpp" | |
| 139 | 146 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/DLL.cpp" |
| 140 | 147 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Driver.cpp" |
| 141 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Chunks.cpp" | |
| 142 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/PDB.cpp" | |
| 143 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Error.cpp" | |
| 148 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/DriverUtils.cpp" | |
| 149 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/ICF.cpp" | |
| 150 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/InputFiles.cpp" | |
| 144 | 151 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/LTO.cpp" |
| 145 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Strings.cpp" | |
| 152 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/MapFile.cpp" | |
| 146 | 153 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/MarkLive.cpp" |
| 154 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/MinGW.cpp" | |
| 155 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/PDB.cpp" | |
| 156 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Strings.cpp" | |
| 147 | 157 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/SymbolTable.cpp" |
| 148 | 158 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Symbols.cpp" |
| 149 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/ICF.cpp" | |
| 150 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/InputFiles.cpp" | |
| 151 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/DriverUtils.cpp" | |
| 152 | 159 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Writer.cpp" |
| 153 | "${CMAKE_SOURCE_DIR}/deps/lld/COFF/MapFile.cpp" | |
| 160 | ) | |
| 161 | set(EMBEDDED_LLD_MINGW_SOURCES | |
| 162 | "${CMAKE_SOURCE_DIR}/deps/lld/MinGW/Driver.cpp" | |
| 163 | ) | |
| 164 | set(EMBEDDED_LLD_WASM_SOURCES | |
| 165 | "${CMAKE_SOURCE_DIR}/deps/lld/wasm/Driver.cpp" | |
| 166 | "${CMAKE_SOURCE_DIR}/deps/lld/wasm/InputFiles.cpp" | |
| 167 | "${CMAKE_SOURCE_DIR}/deps/lld/wasm/InputSegment.cpp" | |
| 168 | "${CMAKE_SOURCE_DIR}/deps/lld/wasm/OutputSections.cpp" | |
| 169 | "${CMAKE_SOURCE_DIR}/deps/lld/wasm/Symbols.cpp" | |
| 170 | "${CMAKE_SOURCE_DIR}/deps/lld/wasm/SymbolTable.cpp" | |
| 171 | "${CMAKE_SOURCE_DIR}/deps/lld/wasm/Writer.cpp" | |
| 172 | "${CMAKE_SOURCE_DIR}/deps/lld/wasm/WriterUtils.cpp" | |
| 154 | 173 | ) |
| 155 | 174 | add_library(embedded_lld_lib ${EMBEDDED_LLD_LIB_SOURCES}) |
| 156 | 175 | add_library(embedded_lld_elf ${EMBEDDED_LLD_ELF_SOURCES}) |
| 157 | 176 | add_library(embedded_lld_coff ${EMBEDDED_LLD_COFF_SOURCES}) |
| 177 | add_library(embedded_lld_mingw ${EMBEDDED_LLD_MINGW_SOURCES}) | |
| 178 | add_library(embedded_lld_wasm ${EMBEDDED_LLD_WASM_SOURCES}) | |
| 158 | 179 | if(MSVC) |
| 159 | 180 | set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -D_CRT_SECURE_NO_WARNINGS /w") |
| 160 | 181 | else() |
| ... | ... | @@ -172,6 +193,14 @@ else() |
| 172 | 193 | COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS} |
| 173 | 194 | LINK_FLAGS " " |
| 174 | 195 | ) |
| 196 | set_target_properties(embedded_lld_mingw PROPERTIES | |
| 197 | COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS} | |
| 198 | LINK_FLAGS " " | |
| 199 | ) | |
| 200 | set_target_properties(embedded_lld_wasm PROPERTIES | |
| 201 | COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS} | |
| 202 | LINK_FLAGS " " | |
| 203 | ) | |
| 175 | 204 | target_include_directories(embedded_lld_lib PRIVATE |
| 176 | 205 | "${CMAKE_SOURCE_DIR}/deps/lld/include" |
| 177 | 206 | "${CMAKE_SOURCE_DIR}/deps/lld-prebuilt" |
| ... | ... | @@ -188,13 +217,27 @@ else() |
| 188 | 217 | "${CMAKE_SOURCE_DIR}/deps/lld-prebuilt/COFF" |
| 189 | 218 | "${CMAKE_SOURCE_DIR}/deps/lld-prebuilt" |
| 190 | 219 | ) |
| 220 | target_include_directories(embedded_lld_mingw PRIVATE | |
| 221 | "${CMAKE_SOURCE_DIR}/deps/lld/MinGW" | |
| 222 | "${CMAKE_SOURCE_DIR}/deps/lld/include" | |
| 223 | "${CMAKE_SOURCE_DIR}/deps/lld-prebuilt/MinGW" | |
| 224 | "${CMAKE_SOURCE_DIR}/deps/lld-prebuilt" | |
| 225 | ) | |
| 226 | target_include_directories(embedded_lld_wasm PRIVATE | |
| 227 | "${CMAKE_SOURCE_DIR}/deps/lld/wasm" | |
| 228 | "${CMAKE_SOURCE_DIR}/deps/lld/include" | |
| 229 | "${CMAKE_SOURCE_DIR}/deps/lld-prebuilt/wasm" | |
| 230 | "${CMAKE_SOURCE_DIR}/deps/lld-prebuilt" | |
| 231 | ) | |
| 191 | 232 | set(LLD_INCLUDE_DIRS "") |
| 192 | 233 | set(LLD_LIBRARIES |
| 193 | 234 | embedded_lld_elf |
| 194 | 235 | embedded_lld_coff |
| 236 | embedded_lld_mingw | |
| 237 | embedded_lld_wasm | |
| 195 | 238 | embedded_lld_lib |
| 196 | 239 | ) |
| 197 | install(TARGETS embedded_lld_elf embedded_lld_coff embedded_lld_lib DESTINATION "${ZIG_CPP_LIB_DIR}") | |
| 240 | install(TARGETS embedded_lld_elf embedded_lld_coff embedded_lld_mingw embedded_lld_wasm embedded_lld_lib DESTINATION "${ZIG_CPP_LIB_DIR}") | |
| 198 | 241 | endif() |
| 199 | 242 | |
| 200 | 243 | # No patches have been applied to SoftFloat-3d |
| ... | ... | @@ -498,10 +541,12 @@ set(ZIG_C_HEADER_FILES |
| 498 | 541 | "adxintrin.h" |
| 499 | 542 | "altivec.h" |
| 500 | 543 | "ammintrin.h" |
| 544 | "arm64intr.h" | |
| 501 | 545 | "arm_acle.h" |
| 502 | 546 | "arm_neon.h" |
| 503 | 547 | "armintr.h" |
| 504 | 548 | "avx2intrin.h" |
| 549 | "avx512bitalgintrin.h" | |
| 505 | 550 | "avx512bwintrin.h" |
| 506 | 551 | "avx512cdintrin.h" |
| 507 | 552 | "avx512dqintrin.h" |
| ... | ... | @@ -510,17 +555,25 @@ set(ZIG_C_HEADER_FILES |
| 510 | 555 | "avx512ifmaintrin.h" |
| 511 | 556 | "avx512ifmavlintrin.h" |
| 512 | 557 | "avx512pfintrin.h" |
| 558 | "avx512vbmi2intrin.h" | |
| 513 | 559 | "avx512vbmiintrin.h" |
| 514 | 560 | "avx512vbmivlintrin.h" |
| 561 | "avx512vlbitalgintrin.h" | |
| 515 | 562 | "avx512vlbwintrin.h" |
| 516 | 563 | "avx512vlcdintrin.h" |
| 517 | 564 | "avx512vldqintrin.h" |
| 518 | 565 | "avx512vlintrin.h" |
| 566 | "avx512vlvbmi2intrin.h" | |
| 567 | "avx512vlvnniintrin.h" | |
| 568 | "avx512vnniintrin.h" | |
| 519 | 569 | "avx512vpopcntdqintrin.h" |
| 570 | "avx512vpopcntdqvlintrin.h" | |
| 520 | 571 | "avxintrin.h" |
| 521 | 572 | "bmi2intrin.h" |
| 522 | 573 | "bmiintrin.h" |
| 574 | "cetintrin.h" | |
| 523 | 575 | "clflushoptintrin.h" |
| 576 | "clwbintrin.h" | |
| 524 | 577 | "clzerointrin.h" |
| 525 | 578 | "cpuid.h" |
| 526 | 579 | "cuda_wrappers/algorithm" |
| ... | ... | @@ -532,6 +585,7 @@ set(ZIG_C_HEADER_FILES |
| 532 | 585 | "fma4intrin.h" |
| 533 | 586 | "fmaintrin.h" |
| 534 | 587 | "fxsrintrin.h" |
| 588 | "gfniintrin.h" | |
| 535 | 589 | "htmintrin.h" |
| 536 | 590 | "htmxlintrin.h" |
| 537 | 591 | "ia32intrin.h" |
| ... | ... | @@ -571,8 +625,10 @@ set(ZIG_C_HEADER_FILES |
| 571 | 625 | "tmmintrin.h" |
| 572 | 626 | "unwind.h" |
| 573 | 627 | "vadefs.h" |
| 628 | "vaesintrin.h" | |
| 574 | 629 | "varargs.h" |
| 575 | 630 | "vecintrin.h" |
| 631 | "vpclmulqdqintrin.h" | |
| 576 | 632 | "wmmintrin.h" |
| 577 | 633 | "x86intrin.h" |
| 578 | 634 | "xmmintrin.h" |
README.md+6-6| ... | ... | @@ -124,14 +124,14 @@ libc. Create demo games using Zig. |
| 124 | 124 | ##### POSIX |
| 125 | 125 | |
| 126 | 126 | * cmake >= 2.8.5 |
| 127 | * g++ >= 5.0.0 or clang >= 3.6.0 | |
| 128 | * LLVM, Clang, LLD development libraries == 5.0.1, compiled with the same gcc or clang version above | |
| 127 | * gcc >= 5.0.0 or clang >= 3.6.0 | |
| 128 | * LLVM, Clang, LLD development libraries == 6.x, compiled with the same gcc or clang version above | |
| 129 | 129 | |
| 130 | 130 | ##### Windows |
| 131 | 131 | |
| 132 | 132 | * cmake >= 2.8.5 |
| 133 | 133 | * Microsoft Visual Studio 2015 |
| 134 | * LLVM, Clang, LLD development libraries == 5.0.1, compiled with the same MSVC version above | |
| 134 | * LLVM, Clang, LLD development libraries == 6.x, compiled with the same MSVC version above | |
| 135 | 135 | |
| 136 | 136 | #### Instructions |
| 137 | 137 | |
| ... | ... | @@ -155,11 +155,11 @@ make install |
| 155 | 155 | `ZIG_LIBC_LIB_DIR` and `ZIG_LIBC_STATIC_LIB_DIR` are unused. |
| 156 | 156 | |
| 157 | 157 | ``` |
| 158 | brew install cmake llvm@5 | |
| 159 | brew outdated llvm@5 || brew upgrade llvm@5 | |
| 158 | brew install cmake llvm@6 | |
| 159 | brew outdated llvm@6 || brew upgrade llvm@6 | |
| 160 | 160 | mkdir build |
| 161 | 161 | cd build |
| 162 | cmake .. -DCMAKE_PREFIX_PATH=/usr/local/opt/llvm@5/ -DCMAKE_INSTALL_PREFIX=$(pwd) | |
| 162 | cmake .. -DCMAKE_PREFIX_PATH=/usr/local/opt/llvm@6/ -DCMAKE_INSTALL_PREFIX=$(pwd) | |
| 163 | 163 | make install |
| 164 | 164 | ./zig build --build-file ../build.zig test |
| 165 | 165 | ``` |
c_headers/__clang_cuda_cmath.h+4-19| ... | ... | @@ -131,15 +131,6 @@ __DEVICE__ float ldexp(float __arg, int __exp) { |
| 131 | 131 | __DEVICE__ float log(float __x) { return ::logf(__x); } |
| 132 | 132 | __DEVICE__ float log10(float __x) { return ::log10f(__x); } |
| 133 | 133 | __DEVICE__ float modf(float __x, float *__iptr) { return ::modff(__x, __iptr); } |
| 134 | __DEVICE__ float nexttoward(float __from, double __to) { | |
| 135 | return __builtin_nexttowardf(__from, __to); | |
| 136 | } | |
| 137 | __DEVICE__ double nexttoward(double __from, double __to) { | |
| 138 | return __builtin_nexttoward(__from, __to); | |
| 139 | } | |
| 140 | __DEVICE__ float nexttowardf(float __from, double __to) { | |
| 141 | return __builtin_nexttowardf(__from, __to); | |
| 142 | } | |
| 143 | 134 | __DEVICE__ float pow(float __base, float __exp) { |
| 144 | 135 | return ::powf(__base, __exp); |
| 145 | 136 | } |
| ... | ... | @@ -157,6 +148,10 @@ __DEVICE__ float sqrt(float __x) { return ::sqrtf(__x); } |
| 157 | 148 | __DEVICE__ float tan(float __x) { return ::tanf(__x); } |
| 158 | 149 | __DEVICE__ float tanh(float __x) { return ::tanhf(__x); } |
| 159 | 150 | |
| 151 | // Notably missing above is nexttoward. We omit it because | |
| 152 | // libdevice doesn't provide an implementation, and we don't want to be in the | |
| 153 | // business of implementing tricky libm functions in this header. | |
| 154 | ||
| 160 | 155 | // Now we've defined everything we promised we'd define in |
| 161 | 156 | // __clang_cuda_math_forward_declares.h. We need to do two additional things to |
| 162 | 157 | // fix up our math functions. |
| ... | ... | @@ -295,13 +290,6 @@ ldexp(__T __x, int __exp) { |
| 295 | 290 | return std::ldexp((double)__x, __exp); |
| 296 | 291 | } |
| 297 | 292 | |
| 298 | template <typename __T> | |
| 299 | __DEVICE__ typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer, | |
| 300 | double>::type | |
| 301 | nexttoward(__T __from, double __to) { | |
| 302 | return std::nexttoward((double)__from, __to); | |
| 303 | } | |
| 304 | ||
| 305 | 293 | template <typename __T1, typename __T2> |
| 306 | 294 | __DEVICE__ typename __clang_cuda_enable_if< |
| 307 | 295 | std::numeric_limits<__T1>::is_specialized && |
| ... | ... | @@ -388,7 +376,6 @@ using ::lrint; |
| 388 | 376 | using ::lround; |
| 389 | 377 | using ::nearbyint; |
| 390 | 378 | using ::nextafter; |
| 391 | using ::nexttoward; | |
| 392 | 379 | using ::pow; |
| 393 | 380 | using ::remainder; |
| 394 | 381 | using ::remquo; |
| ... | ... | @@ -456,8 +443,6 @@ using ::lroundf; |
| 456 | 443 | using ::modff; |
| 457 | 444 | using ::nearbyintf; |
| 458 | 445 | using ::nextafterf; |
| 459 | using ::nexttowardf; | |
| 460 | using ::nexttowardf; | |
| 461 | 446 | using ::powf; |
| 462 | 447 | using ::remainderf; |
| 463 | 448 | using ::remquof; |
c_headers/__clang_cuda_intrinsics.h+179-12| ... | ... | @@ -34,23 +34,24 @@ |
| 34 | 34 | #if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 300 |
| 35 | 35 | |
| 36 | 36 | #pragma push_macro("__MAKE_SHUFFLES") |
| 37 | #define __MAKE_SHUFFLES(__FnName, __IntIntrinsic, __FloatIntrinsic, __Mask) \ | |
| 38 | inline __device__ int __FnName(int __val, int __offset, \ | |
| 37 | #define __MAKE_SHUFFLES(__FnName, __IntIntrinsic, __FloatIntrinsic, __Mask, \ | |
| 38 | __Type) \ | |
| 39 | inline __device__ int __FnName(int __val, __Type __offset, \ | |
| 39 | 40 | int __width = warpSize) { \ |
| 40 | 41 | return __IntIntrinsic(__val, __offset, \ |
| 41 | 42 | ((warpSize - __width) << 8) | (__Mask)); \ |
| 42 | 43 | } \ |
| 43 | inline __device__ float __FnName(float __val, int __offset, \ | |
| 44 | inline __device__ float __FnName(float __val, __Type __offset, \ | |
| 44 | 45 | int __width = warpSize) { \ |
| 45 | 46 | return __FloatIntrinsic(__val, __offset, \ |
| 46 | 47 | ((warpSize - __width) << 8) | (__Mask)); \ |
| 47 | 48 | } \ |
| 48 | inline __device__ unsigned int __FnName(unsigned int __val, int __offset, \ | |
| 49 | inline __device__ unsigned int __FnName(unsigned int __val, __Type __offset, \ | |
| 49 | 50 | int __width = warpSize) { \ |
| 50 | 51 | return static_cast<unsigned int>( \ |
| 51 | 52 | ::__FnName(static_cast<int>(__val), __offset, __width)); \ |
| 52 | 53 | } \ |
| 53 | inline __device__ long long __FnName(long long __val, int __offset, \ | |
| 54 | inline __device__ long long __FnName(long long __val, __Type __offset, \ | |
| 54 | 55 | int __width = warpSize) { \ |
| 55 | 56 | struct __Bits { \ |
| 56 | 57 | int __a, __b; \ |
| ... | ... | @@ -65,12 +66,29 @@ |
| 65 | 66 | memcpy(&__ret, &__tmp, sizeof(__tmp)); \ |
| 66 | 67 | return __ret; \ |
| 67 | 68 | } \ |
| 69 | inline __device__ long __FnName(long __val, __Type __offset, \ | |
| 70 | int __width = warpSize) { \ | |
| 71 | _Static_assert(sizeof(long) == sizeof(long long) || \ | |
| 72 | sizeof(long) == sizeof(int)); \ | |
| 73 | if (sizeof(long) == sizeof(long long)) { \ | |
| 74 | return static_cast<long>( \ | |
| 75 | ::__FnName(static_cast<long long>(__val), __offset, __width)); \ | |
| 76 | } else if (sizeof(long) == sizeof(int)) { \ | |
| 77 | return static_cast<long>( \ | |
| 78 | ::__FnName(static_cast<int>(__val), __offset, __width)); \ | |
| 79 | } \ | |
| 80 | } \ | |
| 81 | inline __device__ unsigned long __FnName( \ | |
| 82 | unsigned long __val, __Type __offset, int __width = warpSize) { \ | |
| 83 | return static_cast<unsigned long>( \ | |
| 84 | ::__FnName(static_cast<long>(__val), __offset, __width)); \ | |
| 85 | } \ | |
| 68 | 86 | inline __device__ unsigned long long __FnName( \ |
| 69 | unsigned long long __val, int __offset, int __width = warpSize) { \ | |
| 87 | unsigned long long __val, __Type __offset, int __width = warpSize) { \ | |
| 70 | 88 | return static_cast<unsigned long long>(::__FnName( \ |
| 71 | 89 | static_cast<unsigned long long>(__val), __offset, __width)); \ |
| 72 | 90 | } \ |
| 73 | inline __device__ double __FnName(double __val, int __offset, \ | |
| 91 | inline __device__ double __FnName(double __val, __Type __offset, \ | |
| 74 | 92 | int __width = warpSize) { \ |
| 75 | 93 | long long __tmp; \ |
| 76 | 94 | _Static_assert(sizeof(__tmp) == sizeof(__val)); \ |
| ... | ... | @@ -81,17 +99,166 @@ |
| 81 | 99 | return __ret; \ |
| 82 | 100 | } |
| 83 | 101 | |
| 84 | __MAKE_SHUFFLES(__shfl, __nvvm_shfl_idx_i32, __nvvm_shfl_idx_f32, 0x1f); | |
| 102 | __MAKE_SHUFFLES(__shfl, __nvvm_shfl_idx_i32, __nvvm_shfl_idx_f32, 0x1f, int); | |
| 85 | 103 | // We use 0 rather than 31 as our mask, because shfl.up applies to lanes >= |
| 86 | 104 | // maxLane. |
| 87 | __MAKE_SHUFFLES(__shfl_up, __nvvm_shfl_up_i32, __nvvm_shfl_up_f32, 0); | |
| 88 | __MAKE_SHUFFLES(__shfl_down, __nvvm_shfl_down_i32, __nvvm_shfl_down_f32, 0x1f); | |
| 89 | __MAKE_SHUFFLES(__shfl_xor, __nvvm_shfl_bfly_i32, __nvvm_shfl_bfly_f32, 0x1f); | |
| 90 | ||
| 105 | __MAKE_SHUFFLES(__shfl_up, __nvvm_shfl_up_i32, __nvvm_shfl_up_f32, 0, | |
| 106 | unsigned int); | |
| 107 | __MAKE_SHUFFLES(__shfl_down, __nvvm_shfl_down_i32, __nvvm_shfl_down_f32, 0x1f, | |
| 108 | unsigned int); | |
| 109 | __MAKE_SHUFFLES(__shfl_xor, __nvvm_shfl_bfly_i32, __nvvm_shfl_bfly_f32, 0x1f, | |
| 110 | int); | |
| 91 | 111 | #pragma pop_macro("__MAKE_SHUFFLES") |
| 92 | 112 | |
| 93 | 113 | #endif // !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 300 |
| 94 | 114 | |
| 115 | #if CUDA_VERSION >= 9000 | |
| 116 | #if (!defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 300) | |
| 117 | // __shfl_sync_* variants available in CUDA-9 | |
| 118 | #pragma push_macro("__MAKE_SYNC_SHUFFLES") | |
| 119 | #define __MAKE_SYNC_SHUFFLES(__FnName, __IntIntrinsic, __FloatIntrinsic, \ | |
| 120 | __Mask, __Type) \ | |
| 121 | inline __device__ int __FnName(unsigned int __mask, int __val, \ | |
| 122 | __Type __offset, int __width = warpSize) { \ | |
| 123 | return __IntIntrinsic(__mask, __val, __offset, \ | |
| 124 | ((warpSize - __width) << 8) | (__Mask)); \ | |
| 125 | } \ | |
| 126 | inline __device__ float __FnName(unsigned int __mask, float __val, \ | |
| 127 | __Type __offset, int __width = warpSize) { \ | |
| 128 | return __FloatIntrinsic(__mask, __val, __offset, \ | |
| 129 | ((warpSize - __width) << 8) | (__Mask)); \ | |
| 130 | } \ | |
| 131 | inline __device__ unsigned int __FnName(unsigned int __mask, \ | |
| 132 | unsigned int __val, __Type __offset, \ | |
| 133 | int __width = warpSize) { \ | |
| 134 | return static_cast<unsigned int>( \ | |
| 135 | ::__FnName(__mask, static_cast<int>(__val), __offset, __width)); \ | |
| 136 | } \ | |
| 137 | inline __device__ long long __FnName(unsigned int __mask, long long __val, \ | |
| 138 | __Type __offset, \ | |
| 139 | int __width = warpSize) { \ | |
| 140 | struct __Bits { \ | |
| 141 | int __a, __b; \ | |
| 142 | }; \ | |
| 143 | _Static_assert(sizeof(__val) == sizeof(__Bits)); \ | |
| 144 | _Static_assert(sizeof(__Bits) == 2 * sizeof(int)); \ | |
| 145 | __Bits __tmp; \ | |
| 146 | memcpy(&__val, &__tmp, sizeof(__val)); \ | |
| 147 | __tmp.__a = ::__FnName(__mask, __tmp.__a, __offset, __width); \ | |
| 148 | __tmp.__b = ::__FnName(__mask, __tmp.__b, __offset, __width); \ | |
| 149 | long long __ret; \ | |
| 150 | memcpy(&__ret, &__tmp, sizeof(__tmp)); \ | |
| 151 | return __ret; \ | |
| 152 | } \ | |
| 153 | inline __device__ unsigned long long __FnName( \ | |
| 154 | unsigned int __mask, unsigned long long __val, __Type __offset, \ | |
| 155 | int __width = warpSize) { \ | |
| 156 | return static_cast<unsigned long long>(::__FnName( \ | |
| 157 | __mask, static_cast<unsigned long long>(__val), __offset, __width)); \ | |
| 158 | } \ | |
| 159 | inline __device__ long __FnName(unsigned int __mask, long __val, \ | |
| 160 | __Type __offset, int __width = warpSize) { \ | |
| 161 | _Static_assert(sizeof(long) == sizeof(long long) || \ | |
| 162 | sizeof(long) == sizeof(int)); \ | |
| 163 | if (sizeof(long) == sizeof(long long)) { \ | |
| 164 | return static_cast<long>(::__FnName( \ | |
| 165 | __mask, static_cast<long long>(__val), __offset, __width)); \ | |
| 166 | } else if (sizeof(long) == sizeof(int)) { \ | |
| 167 | return static_cast<long>( \ | |
| 168 | ::__FnName(__mask, static_cast<int>(__val), __offset, __width)); \ | |
| 169 | } \ | |
| 170 | } \ | |
| 171 | inline __device__ unsigned long __FnName( \ | |
| 172 | unsigned int __mask, unsigned long __val, __Type __offset, \ | |
| 173 | int __width = warpSize) { \ | |
| 174 | return static_cast<unsigned long>( \ | |
| 175 | ::__FnName(__mask, static_cast<long>(__val), __offset, __width)); \ | |
| 176 | } \ | |
| 177 | inline __device__ double __FnName(unsigned int __mask, double __val, \ | |
| 178 | __Type __offset, int __width = warpSize) { \ | |
| 179 | long long __tmp; \ | |
| 180 | _Static_assert(sizeof(__tmp) == sizeof(__val)); \ | |
| 181 | memcpy(&__tmp, &__val, sizeof(__val)); \ | |
| 182 | __tmp = ::__FnName(__mask, __tmp, __offset, __width); \ | |
| 183 | double __ret; \ | |
| 184 | memcpy(&__ret, &__tmp, sizeof(__ret)); \ | |
| 185 | return __ret; \ | |
| 186 | } | |
| 187 | __MAKE_SYNC_SHUFFLES(__shfl_sync, __nvvm_shfl_sync_idx_i32, | |
| 188 | __nvvm_shfl_sync_idx_f32, 0x1f, int); | |
| 189 | // We use 0 rather than 31 as our mask, because shfl.up applies to lanes >= | |
| 190 | // maxLane. | |
| 191 | __MAKE_SYNC_SHUFFLES(__shfl_up_sync, __nvvm_shfl_sync_up_i32, | |
| 192 | __nvvm_shfl_sync_up_f32, 0, unsigned int); | |
| 193 | __MAKE_SYNC_SHUFFLES(__shfl_down_sync, __nvvm_shfl_sync_down_i32, | |
| 194 | __nvvm_shfl_sync_down_f32, 0x1f, unsigned int); | |
| 195 | __MAKE_SYNC_SHUFFLES(__shfl_xor_sync, __nvvm_shfl_sync_bfly_i32, | |
| 196 | __nvvm_shfl_sync_bfly_f32, 0x1f, int); | |
| 197 | #pragma pop_macro("__MAKE_SYNC_SHUFFLES") | |
| 198 | ||
| 199 | inline __device__ void __syncwarp(unsigned int mask = 0xffffffff) { | |
| 200 | return __nvvm_bar_warp_sync(mask); | |
| 201 | } | |
| 202 | ||
| 203 | inline __device__ void __barrier_sync(unsigned int id) { | |
| 204 | __nvvm_barrier_sync(id); | |
| 205 | } | |
| 206 | ||
| 207 | inline __device__ void __barrier_sync_count(unsigned int id, | |
| 208 | unsigned int count) { | |
| 209 | __nvvm_barrier_sync_cnt(id, count); | |
| 210 | } | |
| 211 | ||
| 212 | inline __device__ int __all_sync(unsigned int mask, int pred) { | |
| 213 | return __nvvm_vote_all_sync(mask, pred); | |
| 214 | } | |
| 215 | ||
| 216 | inline __device__ int __any_sync(unsigned int mask, int pred) { | |
| 217 | return __nvvm_vote_any_sync(mask, pred); | |
| 218 | } | |
| 219 | ||
| 220 | inline __device__ int __uni_sync(unsigned int mask, int pred) { | |
| 221 | return __nvvm_vote_uni_sync(mask, pred); | |
| 222 | } | |
| 223 | ||
| 224 | inline __device__ unsigned int __ballot_sync(unsigned int mask, int pred) { | |
| 225 | return __nvvm_vote_ballot_sync(mask, pred); | |
| 226 | } | |
| 227 | ||
| 228 | inline __device__ unsigned int __activemask() { return __nvvm_vote_ballot(1); } | |
| 229 | ||
| 230 | inline __device__ unsigned int __fns(unsigned mask, unsigned base, int offset) { | |
| 231 | return __nvvm_fns(mask, base, offset); | |
| 232 | } | |
| 233 | ||
| 234 | #endif // !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 300 | |
| 235 | ||
| 236 | // Define __match* builtins CUDA-9 headers expect to see. | |
| 237 | #if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 700 | |
| 238 | inline __device__ unsigned int __match32_any_sync(unsigned int mask, | |
| 239 | unsigned int value) { | |
| 240 | return __nvvm_match_any_sync_i32(mask, value); | |
| 241 | } | |
| 242 | ||
| 243 | inline __device__ unsigned long long | |
| 244 | __match64_any_sync(unsigned int mask, unsigned long long value) { | |
| 245 | return __nvvm_match_any_sync_i64(mask, value); | |
| 246 | } | |
| 247 | ||
| 248 | inline __device__ unsigned int | |
| 249 | __match32_all_sync(unsigned int mask, unsigned int value, int *pred) { | |
| 250 | return __nvvm_match_all_sync_i32p(mask, value, pred); | |
| 251 | } | |
| 252 | ||
| 253 | inline __device__ unsigned long long | |
| 254 | __match64_all_sync(unsigned int mask, unsigned long long value, int *pred) { | |
| 255 | return __nvvm_match_all_sync_i64p(mask, value, pred); | |
| 256 | } | |
| 257 | #include "crt/sm_70_rt.hpp" | |
| 258 | ||
| 259 | #endif // !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 700 | |
| 260 | #endif // __CUDA_VERSION >= 9000 | |
| 261 | ||
| 95 | 262 | // sm_32 intrinsics: __ldg and __funnelshift_{l,lc,r,rc}. |
| 96 | 263 | |
| 97 | 264 | // Prevent the vanilla sm_32 intrinsics header from being included. |
c_headers/__clang_cuda_math_forward_declares.h+4-4| ... | ... | @@ -149,9 +149,6 @@ __DEVICE__ double nearbyint(double); |
| 149 | 149 | __DEVICE__ float nearbyint(float); |
| 150 | 150 | __DEVICE__ double nextafter(double, double); |
| 151 | 151 | __DEVICE__ float nextafter(float, float); |
| 152 | __DEVICE__ double nexttoward(double, double); | |
| 153 | __DEVICE__ float nexttoward(float, double); | |
| 154 | __DEVICE__ float nexttowardf(float, double); | |
| 155 | 152 | __DEVICE__ double pow(double, double); |
| 156 | 153 | __DEVICE__ double pow(double, int); |
| 157 | 154 | __DEVICE__ float pow(float, float); |
| ... | ... | @@ -185,6 +182,10 @@ __DEVICE__ float tgamma(float); |
| 185 | 182 | __DEVICE__ double trunc(double); |
| 186 | 183 | __DEVICE__ float trunc(float); |
| 187 | 184 | |
| 185 | // Notably missing above is nexttoward, which we don't define on | |
| 186 | // the device side because libdevice doesn't give us an implementation, and we | |
| 187 | // don't want to be in the business of writing one ourselves. | |
| 188 | ||
| 188 | 189 | // We need to define these overloads in exactly the namespace our standard |
| 189 | 190 | // library uses (including the right inline namespace), otherwise they won't be |
| 190 | 191 | // picked up by other functions in the standard library (e.g. functions in |
| ... | ... | @@ -255,7 +256,6 @@ using ::nan; |
| 255 | 256 | using ::nanf; |
| 256 | 257 | using ::nearbyint; |
| 257 | 258 | using ::nextafter; |
| 258 | using ::nexttoward; | |
| 259 | 259 | using ::pow; |
| 260 | 260 | using ::remainder; |
| 261 | 261 | using ::remquo; |
c_headers/__clang_cuda_runtime_wrapper.h+35-1| ... | ... | @@ -62,7 +62,7 @@ |
| 62 | 62 | #include "cuda.h" |
| 63 | 63 | #if !defined(CUDA_VERSION) |
| 64 | 64 | #error "cuda.h did not define CUDA_VERSION" |
| 65 | #elif CUDA_VERSION < 7000 || CUDA_VERSION > 8000 | |
| 65 | #elif CUDA_VERSION < 7000 || CUDA_VERSION > 9000 | |
| 66 | 66 | #error "Unsupported CUDA version!" |
| 67 | 67 | #endif |
| 68 | 68 | |
| ... | ... | @@ -86,7 +86,11 @@ |
| 86 | 86 | #define __COMMON_FUNCTIONS_H__ |
| 87 | 87 | |
| 88 | 88 | #undef __CUDACC__ |
| 89 | #if CUDA_VERSION < 9000 | |
| 89 | 90 | #define __CUDABE__ |
| 91 | #else | |
| 92 | #define __CUDA_LIBDEVICE__ | |
| 93 | #endif | |
| 90 | 94 | // Disables definitions of device-side runtime support stubs in |
| 91 | 95 | // cuda_device_runtime_api.h |
| 92 | 96 | #include "driver_types.h" |
| ... | ... | @@ -94,6 +98,7 @@ |
| 94 | 98 | #include "host_defines.h" |
| 95 | 99 | |
| 96 | 100 | #undef __CUDABE__ |
| 101 | #undef __CUDA_LIBDEVICE__ | |
| 97 | 102 | #define __CUDACC__ |
| 98 | 103 | #include "cuda_runtime.h" |
| 99 | 104 | |
| ... | ... | @@ -105,7 +110,9 @@ |
| 105 | 110 | #define __nvvm_memcpy(s, d, n, a) __builtin_memcpy(s, d, n) |
| 106 | 111 | #define __nvvm_memset(d, c, n, a) __builtin_memset(d, c, n) |
| 107 | 112 | |
| 113 | #if CUDA_VERSION < 9000 | |
| 108 | 114 | #include "crt/device_runtime.h" |
| 115 | #endif | |
| 109 | 116 | #include "crt/host_runtime.h" |
| 110 | 117 | // device_runtime.h defines __cxa_* macros that will conflict with |
| 111 | 118 | // cxxabi.h. |
| ... | ... | @@ -166,7 +173,18 @@ inline __host__ double __signbitd(double x) { |
| 166 | 173 | // __device__. |
| 167 | 174 | #pragma push_macro("__forceinline__") |
| 168 | 175 | #define __forceinline__ __device__ __inline__ __attribute__((always_inline)) |
| 176 | ||
| 177 | #pragma push_macro("__float2half_rn") | |
| 178 | #if CUDA_VERSION >= 9000 | |
| 179 | // CUDA-9 has conflicting prototypes for __float2half_rn(float f) in | |
| 180 | // cuda_fp16.h[pp] and device_functions.hpp. We need to get the one in | |
| 181 | // device_functions.hpp out of the way. | |
| 182 | #define __float2half_rn __float2half_rn_disabled | |
| 183 | #endif | |
| 184 | ||
| 169 | 185 | #include "device_functions.hpp" |
| 186 | #pragma pop_macro("__float2half_rn") | |
| 187 | ||
| 170 | 188 | |
| 171 | 189 | // math_function.hpp uses the __USE_FAST_MATH__ macro to determine whether we |
| 172 | 190 | // get the slow-but-accurate or fast-but-inaccurate versions of functions like |
| ... | ... | @@ -247,7 +265,23 @@ static inline __device__ void __brkpt(int __c) { __brkpt(); } |
| 247 | 265 | #pragma push_macro("__GNUC__") |
| 248 | 266 | #undef __GNUC__ |
| 249 | 267 | #define signbit __ignored_cuda_signbit |
| 268 | ||
| 269 | // CUDA-9 omits device-side definitions of some math functions if it sees | |
| 270 | // include guard from math.h wrapper from libstdc++. We have to undo the header | |
| 271 | // guard temporarily to get the definitions we need. | |
| 272 | #pragma push_macro("_GLIBCXX_MATH_H") | |
| 273 | #pragma push_macro("_LIBCPP_VERSION") | |
| 274 | #if CUDA_VERSION >= 9000 | |
| 275 | #undef _GLIBCXX_MATH_H | |
| 276 | // We also need to undo another guard that checks for libc++ 3.8+ | |
| 277 | #ifdef _LIBCPP_VERSION | |
| 278 | #define _LIBCPP_VERSION 3700 | |
| 279 | #endif | |
| 280 | #endif | |
| 281 | ||
| 250 | 282 | #include "math_functions.hpp" |
| 283 | #pragma pop_macro("_GLIBCXX_MATH_H") | |
| 284 | #pragma pop_macro("_LIBCPP_VERSION") | |
| 251 | 285 | #pragma pop_macro("__GNUC__") |
| 252 | 286 | #pragma pop_macro("signbit") |
| 253 | 287 |
c_headers/arm64intr.h created+49| ... | ... | @@ -0,0 +1,49 @@ |
| 1 | /*===---- arm64intr.h - ARM64 Windows intrinsics -------------------------------=== | |
| 2 | * | |
| 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 4 | * of this software and associated documentation files (the "Software"), to deal | |
| 5 | * in the Software without restriction, including without limitation the rights | |
| 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 7 | * copies of the Software, and to permit persons to whom the Software is | |
| 8 | * furnished to do so, subject to the following conditions: | |
| 9 | * | |
| 10 | * The above copyright notice and this permission notice shall be included in | |
| 11 | * all copies or substantial portions of the Software. | |
| 12 | * | |
| 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 19 | * THE SOFTWARE. | |
| 20 | * | |
| 21 | *===-----------------------------------------------------------------------=== | |
| 22 | */ | |
| 23 | ||
| 24 | /* Only include this if we're compiling for the windows platform. */ | |
| 25 | #ifndef _MSC_VER | |
| 26 | #include_next <arm64intr.h> | |
| 27 | #else | |
| 28 | ||
| 29 | #ifndef __ARM64INTR_H | |
| 30 | #define __ARM64INTR_H | |
| 31 | ||
| 32 | typedef enum | |
| 33 | { | |
| 34 | _ARM64_BARRIER_SY = 0xF, | |
| 35 | _ARM64_BARRIER_ST = 0xE, | |
| 36 | _ARM64_BARRIER_LD = 0xD, | |
| 37 | _ARM64_BARRIER_ISH = 0xB, | |
| 38 | _ARM64_BARRIER_ISHST = 0xA, | |
| 39 | _ARM64_BARRIER_ISHLD = 0x9, | |
| 40 | _ARM64_BARRIER_NSH = 0x7, | |
| 41 | _ARM64_BARRIER_NSHST = 0x6, | |
| 42 | _ARM64_BARRIER_NSHLD = 0x5, | |
| 43 | _ARM64_BARRIER_OSH = 0x3, | |
| 44 | _ARM64_BARRIER_OSHST = 0x2, | |
| 45 | _ARM64_BARRIER_OSHLD = 0x1 | |
| 46 | } _ARM64INTR_BARRIER_TYPE; | |
| 47 | ||
| 48 | #endif /* __ARM64INTR_H */ | |
| 49 | #endif /* _MSC_VER */ |
c_headers/arm_neon.h+5360-1992| ... | ... | @@ -40460,6 +40460,3318 @@ __ai float32x2_t vfms_f32(float32x2_t __p0, float32x2_t __p1, float32x2_t __p2) |
| 40460 | 40460 | } |
| 40461 | 40461 | #endif |
| 40462 | 40462 | |
| 40463 | #endif | |
| 40464 | #if defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarch64__) | |
| 40465 | #ifdef __LITTLE_ENDIAN__ | |
| 40466 | __ai float16x8_t vabdq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40467 | float16x8_t __ret; | |
| 40468 | __ret = (float16x8_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 40469 | return __ret; | |
| 40470 | } | |
| 40471 | #else | |
| 40472 | __ai float16x8_t vabdq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40473 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40474 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40475 | float16x8_t __ret; | |
| 40476 | __ret = (float16x8_t) __builtin_neon_vabdq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 40477 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40478 | return __ret; | |
| 40479 | } | |
| 40480 | #endif | |
| 40481 | ||
| 40482 | #ifdef __LITTLE_ENDIAN__ | |
| 40483 | __ai float16x4_t vabd_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40484 | float16x4_t __ret; | |
| 40485 | __ret = (float16x4_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 40486 | return __ret; | |
| 40487 | } | |
| 40488 | #else | |
| 40489 | __ai float16x4_t vabd_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40490 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40491 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 40492 | float16x4_t __ret; | |
| 40493 | __ret = (float16x4_t) __builtin_neon_vabd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 40494 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40495 | return __ret; | |
| 40496 | } | |
| 40497 | #endif | |
| 40498 | ||
| 40499 | #ifdef __LITTLE_ENDIAN__ | |
| 40500 | __ai float16x8_t vabsq_f16(float16x8_t __p0) { | |
| 40501 | float16x8_t __ret; | |
| 40502 | __ret = (float16x8_t) __builtin_neon_vabsq_v((int8x16_t)__p0, 40); | |
| 40503 | return __ret; | |
| 40504 | } | |
| 40505 | #else | |
| 40506 | __ai float16x8_t vabsq_f16(float16x8_t __p0) { | |
| 40507 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40508 | float16x8_t __ret; | |
| 40509 | __ret = (float16x8_t) __builtin_neon_vabsq_v((int8x16_t)__rev0, 40); | |
| 40510 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40511 | return __ret; | |
| 40512 | } | |
| 40513 | #endif | |
| 40514 | ||
| 40515 | #ifdef __LITTLE_ENDIAN__ | |
| 40516 | __ai float16x4_t vabs_f16(float16x4_t __p0) { | |
| 40517 | float16x4_t __ret; | |
| 40518 | __ret = (float16x4_t) __builtin_neon_vabs_v((int8x8_t)__p0, 8); | |
| 40519 | return __ret; | |
| 40520 | } | |
| 40521 | #else | |
| 40522 | __ai float16x4_t vabs_f16(float16x4_t __p0) { | |
| 40523 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40524 | float16x4_t __ret; | |
| 40525 | __ret = (float16x4_t) __builtin_neon_vabs_v((int8x8_t)__rev0, 8); | |
| 40526 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40527 | return __ret; | |
| 40528 | } | |
| 40529 | #endif | |
| 40530 | ||
| 40531 | #ifdef __LITTLE_ENDIAN__ | |
| 40532 | __ai float16x8_t vaddq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40533 | float16x8_t __ret; | |
| 40534 | __ret = __p0 + __p1; | |
| 40535 | return __ret; | |
| 40536 | } | |
| 40537 | #else | |
| 40538 | __ai float16x8_t vaddq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40539 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40540 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40541 | float16x8_t __ret; | |
| 40542 | __ret = __rev0 + __rev1; | |
| 40543 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40544 | return __ret; | |
| 40545 | } | |
| 40546 | #endif | |
| 40547 | ||
| 40548 | #ifdef __LITTLE_ENDIAN__ | |
| 40549 | __ai float16x4_t vadd_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40550 | float16x4_t __ret; | |
| 40551 | __ret = __p0 + __p1; | |
| 40552 | return __ret; | |
| 40553 | } | |
| 40554 | #else | |
| 40555 | __ai float16x4_t vadd_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40556 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40557 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 40558 | float16x4_t __ret; | |
| 40559 | __ret = __rev0 + __rev1; | |
| 40560 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40561 | return __ret; | |
| 40562 | } | |
| 40563 | #endif | |
| 40564 | ||
| 40565 | #ifdef __LITTLE_ENDIAN__ | |
| 40566 | __ai float16x8_t vbslq_f16(uint16x8_t __p0, float16x8_t __p1, float16x8_t __p2) { | |
| 40567 | float16x8_t __ret; | |
| 40568 | __ret = (float16x8_t) __builtin_neon_vbslq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 40); | |
| 40569 | return __ret; | |
| 40570 | } | |
| 40571 | #else | |
| 40572 | __ai float16x8_t vbslq_f16(uint16x8_t __p0, float16x8_t __p1, float16x8_t __p2) { | |
| 40573 | uint16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40574 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40575 | float16x8_t __rev2; __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40576 | float16x8_t __ret; | |
| 40577 | __ret = (float16x8_t) __builtin_neon_vbslq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 40); | |
| 40578 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40579 | return __ret; | |
| 40580 | } | |
| 40581 | #endif | |
| 40582 | ||
| 40583 | #ifdef __LITTLE_ENDIAN__ | |
| 40584 | __ai float16x4_t vbsl_f16(uint16x4_t __p0, float16x4_t __p1, float16x4_t __p2) { | |
| 40585 | float16x4_t __ret; | |
| 40586 | __ret = (float16x4_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 8); | |
| 40587 | return __ret; | |
| 40588 | } | |
| 40589 | #else | |
| 40590 | __ai float16x4_t vbsl_f16(uint16x4_t __p0, float16x4_t __p1, float16x4_t __p2) { | |
| 40591 | uint16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40592 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 40593 | float16x4_t __rev2; __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0); | |
| 40594 | float16x4_t __ret; | |
| 40595 | __ret = (float16x4_t) __builtin_neon_vbsl_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 8); | |
| 40596 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40597 | return __ret; | |
| 40598 | } | |
| 40599 | #endif | |
| 40600 | ||
| 40601 | #ifdef __LITTLE_ENDIAN__ | |
| 40602 | __ai uint16x8_t vcageq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40603 | uint16x8_t __ret; | |
| 40604 | __ret = (uint16x8_t) __builtin_neon_vcageq_v((int8x16_t)__p0, (int8x16_t)__p1, 49); | |
| 40605 | return __ret; | |
| 40606 | } | |
| 40607 | #else | |
| 40608 | __ai uint16x8_t vcageq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40609 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40610 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40611 | uint16x8_t __ret; | |
| 40612 | __ret = (uint16x8_t) __builtin_neon_vcageq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49); | |
| 40613 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40614 | return __ret; | |
| 40615 | } | |
| 40616 | #endif | |
| 40617 | ||
| 40618 | #ifdef __LITTLE_ENDIAN__ | |
| 40619 | __ai uint16x4_t vcage_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40620 | uint16x4_t __ret; | |
| 40621 | __ret = (uint16x4_t) __builtin_neon_vcage_v((int8x8_t)__p0, (int8x8_t)__p1, 17); | |
| 40622 | return __ret; | |
| 40623 | } | |
| 40624 | #else | |
| 40625 | __ai uint16x4_t vcage_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40626 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40627 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 40628 | uint16x4_t __ret; | |
| 40629 | __ret = (uint16x4_t) __builtin_neon_vcage_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17); | |
| 40630 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40631 | return __ret; | |
| 40632 | } | |
| 40633 | #endif | |
| 40634 | ||
| 40635 | #ifdef __LITTLE_ENDIAN__ | |
| 40636 | __ai uint16x8_t vcagtq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40637 | uint16x8_t __ret; | |
| 40638 | __ret = (uint16x8_t) __builtin_neon_vcagtq_v((int8x16_t)__p0, (int8x16_t)__p1, 49); | |
| 40639 | return __ret; | |
| 40640 | } | |
| 40641 | #else | |
| 40642 | __ai uint16x8_t vcagtq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40643 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40644 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40645 | uint16x8_t __ret; | |
| 40646 | __ret = (uint16x8_t) __builtin_neon_vcagtq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49); | |
| 40647 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40648 | return __ret; | |
| 40649 | } | |
| 40650 | #endif | |
| 40651 | ||
| 40652 | #ifdef __LITTLE_ENDIAN__ | |
| 40653 | __ai uint16x4_t vcagt_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40654 | uint16x4_t __ret; | |
| 40655 | __ret = (uint16x4_t) __builtin_neon_vcagt_v((int8x8_t)__p0, (int8x8_t)__p1, 17); | |
| 40656 | return __ret; | |
| 40657 | } | |
| 40658 | #else | |
| 40659 | __ai uint16x4_t vcagt_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40660 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40661 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 40662 | uint16x4_t __ret; | |
| 40663 | __ret = (uint16x4_t) __builtin_neon_vcagt_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17); | |
| 40664 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40665 | return __ret; | |
| 40666 | } | |
| 40667 | #endif | |
| 40668 | ||
| 40669 | #ifdef __LITTLE_ENDIAN__ | |
| 40670 | __ai uint16x8_t vcaleq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40671 | uint16x8_t __ret; | |
| 40672 | __ret = (uint16x8_t) __builtin_neon_vcaleq_v((int8x16_t)__p0, (int8x16_t)__p1, 49); | |
| 40673 | return __ret; | |
| 40674 | } | |
| 40675 | #else | |
| 40676 | __ai uint16x8_t vcaleq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40677 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40678 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40679 | uint16x8_t __ret; | |
| 40680 | __ret = (uint16x8_t) __builtin_neon_vcaleq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49); | |
| 40681 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40682 | return __ret; | |
| 40683 | } | |
| 40684 | #endif | |
| 40685 | ||
| 40686 | #ifdef __LITTLE_ENDIAN__ | |
| 40687 | __ai uint16x4_t vcale_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40688 | uint16x4_t __ret; | |
| 40689 | __ret = (uint16x4_t) __builtin_neon_vcale_v((int8x8_t)__p0, (int8x8_t)__p1, 17); | |
| 40690 | return __ret; | |
| 40691 | } | |
| 40692 | #else | |
| 40693 | __ai uint16x4_t vcale_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40694 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40695 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 40696 | uint16x4_t __ret; | |
| 40697 | __ret = (uint16x4_t) __builtin_neon_vcale_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17); | |
| 40698 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40699 | return __ret; | |
| 40700 | } | |
| 40701 | #endif | |
| 40702 | ||
| 40703 | #ifdef __LITTLE_ENDIAN__ | |
| 40704 | __ai uint16x8_t vcaltq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40705 | uint16x8_t __ret; | |
| 40706 | __ret = (uint16x8_t) __builtin_neon_vcaltq_v((int8x16_t)__p0, (int8x16_t)__p1, 49); | |
| 40707 | return __ret; | |
| 40708 | } | |
| 40709 | #else | |
| 40710 | __ai uint16x8_t vcaltq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40711 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40712 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40713 | uint16x8_t __ret; | |
| 40714 | __ret = (uint16x8_t) __builtin_neon_vcaltq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49); | |
| 40715 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40716 | return __ret; | |
| 40717 | } | |
| 40718 | #endif | |
| 40719 | ||
| 40720 | #ifdef __LITTLE_ENDIAN__ | |
| 40721 | __ai uint16x4_t vcalt_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40722 | uint16x4_t __ret; | |
| 40723 | __ret = (uint16x4_t) __builtin_neon_vcalt_v((int8x8_t)__p0, (int8x8_t)__p1, 17); | |
| 40724 | return __ret; | |
| 40725 | } | |
| 40726 | #else | |
| 40727 | __ai uint16x4_t vcalt_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40728 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40729 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 40730 | uint16x4_t __ret; | |
| 40731 | __ret = (uint16x4_t) __builtin_neon_vcalt_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17); | |
| 40732 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40733 | return __ret; | |
| 40734 | } | |
| 40735 | #endif | |
| 40736 | ||
| 40737 | #ifdef __LITTLE_ENDIAN__ | |
| 40738 | __ai uint16x8_t vceqq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40739 | uint16x8_t __ret; | |
| 40740 | __ret = (uint16x8_t)(__p0 == __p1); | |
| 40741 | return __ret; | |
| 40742 | } | |
| 40743 | #else | |
| 40744 | __ai uint16x8_t vceqq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40745 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40746 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40747 | uint16x8_t __ret; | |
| 40748 | __ret = (uint16x8_t)(__rev0 == __rev1); | |
| 40749 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40750 | return __ret; | |
| 40751 | } | |
| 40752 | #endif | |
| 40753 | ||
| 40754 | #ifdef __LITTLE_ENDIAN__ | |
| 40755 | __ai uint16x4_t vceq_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40756 | uint16x4_t __ret; | |
| 40757 | __ret = (uint16x4_t)(__p0 == __p1); | |
| 40758 | return __ret; | |
| 40759 | } | |
| 40760 | #else | |
| 40761 | __ai uint16x4_t vceq_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40762 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40763 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 40764 | uint16x4_t __ret; | |
| 40765 | __ret = (uint16x4_t)(__rev0 == __rev1); | |
| 40766 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40767 | return __ret; | |
| 40768 | } | |
| 40769 | #endif | |
| 40770 | ||
| 40771 | #ifdef __LITTLE_ENDIAN__ | |
| 40772 | __ai uint16x8_t vceqzq_f16(float16x8_t __p0) { | |
| 40773 | uint16x8_t __ret; | |
| 40774 | __ret = (uint16x8_t) __builtin_neon_vceqzq_v((int8x16_t)__p0, 49); | |
| 40775 | return __ret; | |
| 40776 | } | |
| 40777 | #else | |
| 40778 | __ai uint16x8_t vceqzq_f16(float16x8_t __p0) { | |
| 40779 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40780 | uint16x8_t __ret; | |
| 40781 | __ret = (uint16x8_t) __builtin_neon_vceqzq_v((int8x16_t)__rev0, 49); | |
| 40782 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40783 | return __ret; | |
| 40784 | } | |
| 40785 | #endif | |
| 40786 | ||
| 40787 | #ifdef __LITTLE_ENDIAN__ | |
| 40788 | __ai uint16x4_t vceqz_f16(float16x4_t __p0) { | |
| 40789 | uint16x4_t __ret; | |
| 40790 | __ret = (uint16x4_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 17); | |
| 40791 | return __ret; | |
| 40792 | } | |
| 40793 | #else | |
| 40794 | __ai uint16x4_t vceqz_f16(float16x4_t __p0) { | |
| 40795 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40796 | uint16x4_t __ret; | |
| 40797 | __ret = (uint16x4_t) __builtin_neon_vceqz_v((int8x8_t)__rev0, 17); | |
| 40798 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40799 | return __ret; | |
| 40800 | } | |
| 40801 | #endif | |
| 40802 | ||
| 40803 | #ifdef __LITTLE_ENDIAN__ | |
| 40804 | __ai uint16x8_t vcgeq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40805 | uint16x8_t __ret; | |
| 40806 | __ret = (uint16x8_t)(__p0 >= __p1); | |
| 40807 | return __ret; | |
| 40808 | } | |
| 40809 | #else | |
| 40810 | __ai uint16x8_t vcgeq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40811 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40812 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40813 | uint16x8_t __ret; | |
| 40814 | __ret = (uint16x8_t)(__rev0 >= __rev1); | |
| 40815 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40816 | return __ret; | |
| 40817 | } | |
| 40818 | #endif | |
| 40819 | ||
| 40820 | #ifdef __LITTLE_ENDIAN__ | |
| 40821 | __ai uint16x4_t vcge_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40822 | uint16x4_t __ret; | |
| 40823 | __ret = (uint16x4_t)(__p0 >= __p1); | |
| 40824 | return __ret; | |
| 40825 | } | |
| 40826 | #else | |
| 40827 | __ai uint16x4_t vcge_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40828 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40829 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 40830 | uint16x4_t __ret; | |
| 40831 | __ret = (uint16x4_t)(__rev0 >= __rev1); | |
| 40832 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40833 | return __ret; | |
| 40834 | } | |
| 40835 | #endif | |
| 40836 | ||
| 40837 | #ifdef __LITTLE_ENDIAN__ | |
| 40838 | __ai uint16x8_t vcgezq_f16(float16x8_t __p0) { | |
| 40839 | uint16x8_t __ret; | |
| 40840 | __ret = (uint16x8_t) __builtin_neon_vcgezq_v((int8x16_t)__p0, 49); | |
| 40841 | return __ret; | |
| 40842 | } | |
| 40843 | #else | |
| 40844 | __ai uint16x8_t vcgezq_f16(float16x8_t __p0) { | |
| 40845 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40846 | uint16x8_t __ret; | |
| 40847 | __ret = (uint16x8_t) __builtin_neon_vcgezq_v((int8x16_t)__rev0, 49); | |
| 40848 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40849 | return __ret; | |
| 40850 | } | |
| 40851 | #endif | |
| 40852 | ||
| 40853 | #ifdef __LITTLE_ENDIAN__ | |
| 40854 | __ai uint16x4_t vcgez_f16(float16x4_t __p0) { | |
| 40855 | uint16x4_t __ret; | |
| 40856 | __ret = (uint16x4_t) __builtin_neon_vcgez_v((int8x8_t)__p0, 17); | |
| 40857 | return __ret; | |
| 40858 | } | |
| 40859 | #else | |
| 40860 | __ai uint16x4_t vcgez_f16(float16x4_t __p0) { | |
| 40861 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40862 | uint16x4_t __ret; | |
| 40863 | __ret = (uint16x4_t) __builtin_neon_vcgez_v((int8x8_t)__rev0, 17); | |
| 40864 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40865 | return __ret; | |
| 40866 | } | |
| 40867 | #endif | |
| 40868 | ||
| 40869 | #ifdef __LITTLE_ENDIAN__ | |
| 40870 | __ai uint16x8_t vcgtq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40871 | uint16x8_t __ret; | |
| 40872 | __ret = (uint16x8_t)(__p0 > __p1); | |
| 40873 | return __ret; | |
| 40874 | } | |
| 40875 | #else | |
| 40876 | __ai uint16x8_t vcgtq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40877 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40878 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40879 | uint16x8_t __ret; | |
| 40880 | __ret = (uint16x8_t)(__rev0 > __rev1); | |
| 40881 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40882 | return __ret; | |
| 40883 | } | |
| 40884 | #endif | |
| 40885 | ||
| 40886 | #ifdef __LITTLE_ENDIAN__ | |
| 40887 | __ai uint16x4_t vcgt_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40888 | uint16x4_t __ret; | |
| 40889 | __ret = (uint16x4_t)(__p0 > __p1); | |
| 40890 | return __ret; | |
| 40891 | } | |
| 40892 | #else | |
| 40893 | __ai uint16x4_t vcgt_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40894 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40895 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 40896 | uint16x4_t __ret; | |
| 40897 | __ret = (uint16x4_t)(__rev0 > __rev1); | |
| 40898 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40899 | return __ret; | |
| 40900 | } | |
| 40901 | #endif | |
| 40902 | ||
| 40903 | #ifdef __LITTLE_ENDIAN__ | |
| 40904 | __ai uint16x8_t vcgtzq_f16(float16x8_t __p0) { | |
| 40905 | uint16x8_t __ret; | |
| 40906 | __ret = (uint16x8_t) __builtin_neon_vcgtzq_v((int8x16_t)__p0, 49); | |
| 40907 | return __ret; | |
| 40908 | } | |
| 40909 | #else | |
| 40910 | __ai uint16x8_t vcgtzq_f16(float16x8_t __p0) { | |
| 40911 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40912 | uint16x8_t __ret; | |
| 40913 | __ret = (uint16x8_t) __builtin_neon_vcgtzq_v((int8x16_t)__rev0, 49); | |
| 40914 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40915 | return __ret; | |
| 40916 | } | |
| 40917 | #endif | |
| 40918 | ||
| 40919 | #ifdef __LITTLE_ENDIAN__ | |
| 40920 | __ai uint16x4_t vcgtz_f16(float16x4_t __p0) { | |
| 40921 | uint16x4_t __ret; | |
| 40922 | __ret = (uint16x4_t) __builtin_neon_vcgtz_v((int8x8_t)__p0, 17); | |
| 40923 | return __ret; | |
| 40924 | } | |
| 40925 | #else | |
| 40926 | __ai uint16x4_t vcgtz_f16(float16x4_t __p0) { | |
| 40927 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40928 | uint16x4_t __ret; | |
| 40929 | __ret = (uint16x4_t) __builtin_neon_vcgtz_v((int8x8_t)__rev0, 17); | |
| 40930 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40931 | return __ret; | |
| 40932 | } | |
| 40933 | #endif | |
| 40934 | ||
| 40935 | #ifdef __LITTLE_ENDIAN__ | |
| 40936 | __ai uint16x8_t vcleq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40937 | uint16x8_t __ret; | |
| 40938 | __ret = (uint16x8_t)(__p0 <= __p1); | |
| 40939 | return __ret; | |
| 40940 | } | |
| 40941 | #else | |
| 40942 | __ai uint16x8_t vcleq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 40943 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40944 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40945 | uint16x8_t __ret; | |
| 40946 | __ret = (uint16x8_t)(__rev0 <= __rev1); | |
| 40947 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40948 | return __ret; | |
| 40949 | } | |
| 40950 | #endif | |
| 40951 | ||
| 40952 | #ifdef __LITTLE_ENDIAN__ | |
| 40953 | __ai uint16x4_t vcle_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40954 | uint16x4_t __ret; | |
| 40955 | __ret = (uint16x4_t)(__p0 <= __p1); | |
| 40956 | return __ret; | |
| 40957 | } | |
| 40958 | #else | |
| 40959 | __ai uint16x4_t vcle_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 40960 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40961 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 40962 | uint16x4_t __ret; | |
| 40963 | __ret = (uint16x4_t)(__rev0 <= __rev1); | |
| 40964 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40965 | return __ret; | |
| 40966 | } | |
| 40967 | #endif | |
| 40968 | ||
| 40969 | #ifdef __LITTLE_ENDIAN__ | |
| 40970 | __ai uint16x8_t vclezq_f16(float16x8_t __p0) { | |
| 40971 | uint16x8_t __ret; | |
| 40972 | __ret = (uint16x8_t) __builtin_neon_vclezq_v((int8x16_t)__p0, 49); | |
| 40973 | return __ret; | |
| 40974 | } | |
| 40975 | #else | |
| 40976 | __ai uint16x8_t vclezq_f16(float16x8_t __p0) { | |
| 40977 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40978 | uint16x8_t __ret; | |
| 40979 | __ret = (uint16x8_t) __builtin_neon_vclezq_v((int8x16_t)__rev0, 49); | |
| 40980 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 40981 | return __ret; | |
| 40982 | } | |
| 40983 | #endif | |
| 40984 | ||
| 40985 | #ifdef __LITTLE_ENDIAN__ | |
| 40986 | __ai uint16x4_t vclez_f16(float16x4_t __p0) { | |
| 40987 | uint16x4_t __ret; | |
| 40988 | __ret = (uint16x4_t) __builtin_neon_vclez_v((int8x8_t)__p0, 17); | |
| 40989 | return __ret; | |
| 40990 | } | |
| 40991 | #else | |
| 40992 | __ai uint16x4_t vclez_f16(float16x4_t __p0) { | |
| 40993 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 40994 | uint16x4_t __ret; | |
| 40995 | __ret = (uint16x4_t) __builtin_neon_vclez_v((int8x8_t)__rev0, 17); | |
| 40996 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 40997 | return __ret; | |
| 40998 | } | |
| 40999 | #endif | |
| 41000 | ||
| 41001 | #ifdef __LITTLE_ENDIAN__ | |
| 41002 | __ai uint16x8_t vcltq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 41003 | uint16x8_t __ret; | |
| 41004 | __ret = (uint16x8_t)(__p0 < __p1); | |
| 41005 | return __ret; | |
| 41006 | } | |
| 41007 | #else | |
| 41008 | __ai uint16x8_t vcltq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 41009 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41010 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41011 | uint16x8_t __ret; | |
| 41012 | __ret = (uint16x8_t)(__rev0 < __rev1); | |
| 41013 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41014 | return __ret; | |
| 41015 | } | |
| 41016 | #endif | |
| 41017 | ||
| 41018 | #ifdef __LITTLE_ENDIAN__ | |
| 41019 | __ai uint16x4_t vclt_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 41020 | uint16x4_t __ret; | |
| 41021 | __ret = (uint16x4_t)(__p0 < __p1); | |
| 41022 | return __ret; | |
| 41023 | } | |
| 41024 | #else | |
| 41025 | __ai uint16x4_t vclt_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 41026 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41027 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 41028 | uint16x4_t __ret; | |
| 41029 | __ret = (uint16x4_t)(__rev0 < __rev1); | |
| 41030 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41031 | return __ret; | |
| 41032 | } | |
| 41033 | #endif | |
| 41034 | ||
| 41035 | #ifdef __LITTLE_ENDIAN__ | |
| 41036 | __ai uint16x8_t vcltzq_f16(float16x8_t __p0) { | |
| 41037 | uint16x8_t __ret; | |
| 41038 | __ret = (uint16x8_t) __builtin_neon_vcltzq_v((int8x16_t)__p0, 49); | |
| 41039 | return __ret; | |
| 41040 | } | |
| 41041 | #else | |
| 41042 | __ai uint16x8_t vcltzq_f16(float16x8_t __p0) { | |
| 41043 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41044 | uint16x8_t __ret; | |
| 41045 | __ret = (uint16x8_t) __builtin_neon_vcltzq_v((int8x16_t)__rev0, 49); | |
| 41046 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41047 | return __ret; | |
| 41048 | } | |
| 41049 | #endif | |
| 41050 | ||
| 41051 | #ifdef __LITTLE_ENDIAN__ | |
| 41052 | __ai uint16x4_t vcltz_f16(float16x4_t __p0) { | |
| 41053 | uint16x4_t __ret; | |
| 41054 | __ret = (uint16x4_t) __builtin_neon_vcltz_v((int8x8_t)__p0, 17); | |
| 41055 | return __ret; | |
| 41056 | } | |
| 41057 | #else | |
| 41058 | __ai uint16x4_t vcltz_f16(float16x4_t __p0) { | |
| 41059 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41060 | uint16x4_t __ret; | |
| 41061 | __ret = (uint16x4_t) __builtin_neon_vcltz_v((int8x8_t)__rev0, 17); | |
| 41062 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41063 | return __ret; | |
| 41064 | } | |
| 41065 | #endif | |
| 41066 | ||
| 41067 | #ifdef __LITTLE_ENDIAN__ | |
| 41068 | __ai float16x8_t vcvtq_f16_u16(uint16x8_t __p0) { | |
| 41069 | float16x8_t __ret; | |
| 41070 | __ret = (float16x8_t) __builtin_neon_vcvtq_f16_v((int8x16_t)__p0, 49); | |
| 41071 | return __ret; | |
| 41072 | } | |
| 41073 | #else | |
| 41074 | __ai float16x8_t vcvtq_f16_u16(uint16x8_t __p0) { | |
| 41075 | uint16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41076 | float16x8_t __ret; | |
| 41077 | __ret = (float16x8_t) __builtin_neon_vcvtq_f16_v((int8x16_t)__rev0, 49); | |
| 41078 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41079 | return __ret; | |
| 41080 | } | |
| 41081 | #endif | |
| 41082 | ||
| 41083 | #ifdef __LITTLE_ENDIAN__ | |
| 41084 | __ai float16x8_t vcvtq_f16_s16(int16x8_t __p0) { | |
| 41085 | float16x8_t __ret; | |
| 41086 | __ret = (float16x8_t) __builtin_neon_vcvtq_f16_v((int8x16_t)__p0, 33); | |
| 41087 | return __ret; | |
| 41088 | } | |
| 41089 | #else | |
| 41090 | __ai float16x8_t vcvtq_f16_s16(int16x8_t __p0) { | |
| 41091 | int16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41092 | float16x8_t __ret; | |
| 41093 | __ret = (float16x8_t) __builtin_neon_vcvtq_f16_v((int8x16_t)__rev0, 33); | |
| 41094 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41095 | return __ret; | |
| 41096 | } | |
| 41097 | #endif | |
| 41098 | ||
| 41099 | #ifdef __LITTLE_ENDIAN__ | |
| 41100 | __ai float16x4_t vcvt_f16_u16(uint16x4_t __p0) { | |
| 41101 | float16x4_t __ret; | |
| 41102 | __ret = (float16x4_t) __builtin_neon_vcvt_f16_v((int8x8_t)__p0, 17); | |
| 41103 | return __ret; | |
| 41104 | } | |
| 41105 | #else | |
| 41106 | __ai float16x4_t vcvt_f16_u16(uint16x4_t __p0) { | |
| 41107 | uint16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41108 | float16x4_t __ret; | |
| 41109 | __ret = (float16x4_t) __builtin_neon_vcvt_f16_v((int8x8_t)__rev0, 17); | |
| 41110 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41111 | return __ret; | |
| 41112 | } | |
| 41113 | #endif | |
| 41114 | ||
| 41115 | #ifdef __LITTLE_ENDIAN__ | |
| 41116 | __ai float16x4_t vcvt_f16_s16(int16x4_t __p0) { | |
| 41117 | float16x4_t __ret; | |
| 41118 | __ret = (float16x4_t) __builtin_neon_vcvt_f16_v((int8x8_t)__p0, 1); | |
| 41119 | return __ret; | |
| 41120 | } | |
| 41121 | #else | |
| 41122 | __ai float16x4_t vcvt_f16_s16(int16x4_t __p0) { | |
| 41123 | int16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41124 | float16x4_t __ret; | |
| 41125 | __ret = (float16x4_t) __builtin_neon_vcvt_f16_v((int8x8_t)__rev0, 1); | |
| 41126 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41127 | return __ret; | |
| 41128 | } | |
| 41129 | #endif | |
| 41130 | ||
| 41131 | #ifdef __LITTLE_ENDIAN__ | |
| 41132 | #define vcvtq_n_f16_u16(__p0, __p1) __extension__ ({ \ | |
| 41133 | uint16x8_t __s0 = __p0; \ | |
| 41134 | float16x8_t __ret; \ | |
| 41135 | __ret = (float16x8_t) __builtin_neon_vcvtq_n_f16_v((int8x16_t)__s0, __p1, 49); \ | |
| 41136 | __ret; \ | |
| 41137 | }) | |
| 41138 | #else | |
| 41139 | #define vcvtq_n_f16_u16(__p0, __p1) __extension__ ({ \ | |
| 41140 | uint16x8_t __s0 = __p0; \ | |
| 41141 | uint16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41142 | float16x8_t __ret; \ | |
| 41143 | __ret = (float16x8_t) __builtin_neon_vcvtq_n_f16_v((int8x16_t)__rev0, __p1, 49); \ | |
| 41144 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41145 | __ret; \ | |
| 41146 | }) | |
| 41147 | #endif | |
| 41148 | ||
| 41149 | #ifdef __LITTLE_ENDIAN__ | |
| 41150 | #define vcvtq_n_f16_s16(__p0, __p1) __extension__ ({ \ | |
| 41151 | int16x8_t __s0 = __p0; \ | |
| 41152 | float16x8_t __ret; \ | |
| 41153 | __ret = (float16x8_t) __builtin_neon_vcvtq_n_f16_v((int8x16_t)__s0, __p1, 33); \ | |
| 41154 | __ret; \ | |
| 41155 | }) | |
| 41156 | #else | |
| 41157 | #define vcvtq_n_f16_s16(__p0, __p1) __extension__ ({ \ | |
| 41158 | int16x8_t __s0 = __p0; \ | |
| 41159 | int16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41160 | float16x8_t __ret; \ | |
| 41161 | __ret = (float16x8_t) __builtin_neon_vcvtq_n_f16_v((int8x16_t)__rev0, __p1, 33); \ | |
| 41162 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41163 | __ret; \ | |
| 41164 | }) | |
| 41165 | #endif | |
| 41166 | ||
| 41167 | #ifdef __LITTLE_ENDIAN__ | |
| 41168 | #define vcvt_n_f16_u16(__p0, __p1) __extension__ ({ \ | |
| 41169 | uint16x4_t __s0 = __p0; \ | |
| 41170 | float16x4_t __ret; \ | |
| 41171 | __ret = (float16x4_t) __builtin_neon_vcvt_n_f16_v((int8x8_t)__s0, __p1, 17); \ | |
| 41172 | __ret; \ | |
| 41173 | }) | |
| 41174 | #else | |
| 41175 | #define vcvt_n_f16_u16(__p0, __p1) __extension__ ({ \ | |
| 41176 | uint16x4_t __s0 = __p0; \ | |
| 41177 | uint16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 41178 | float16x4_t __ret; \ | |
| 41179 | __ret = (float16x4_t) __builtin_neon_vcvt_n_f16_v((int8x8_t)__rev0, __p1, 17); \ | |
| 41180 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 41181 | __ret; \ | |
| 41182 | }) | |
| 41183 | #endif | |
| 41184 | ||
| 41185 | #ifdef __LITTLE_ENDIAN__ | |
| 41186 | #define vcvt_n_f16_s16(__p0, __p1) __extension__ ({ \ | |
| 41187 | int16x4_t __s0 = __p0; \ | |
| 41188 | float16x4_t __ret; \ | |
| 41189 | __ret = (float16x4_t) __builtin_neon_vcvt_n_f16_v((int8x8_t)__s0, __p1, 1); \ | |
| 41190 | __ret; \ | |
| 41191 | }) | |
| 41192 | #else | |
| 41193 | #define vcvt_n_f16_s16(__p0, __p1) __extension__ ({ \ | |
| 41194 | int16x4_t __s0 = __p0; \ | |
| 41195 | int16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 41196 | float16x4_t __ret; \ | |
| 41197 | __ret = (float16x4_t) __builtin_neon_vcvt_n_f16_v((int8x8_t)__rev0, __p1, 1); \ | |
| 41198 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 41199 | __ret; \ | |
| 41200 | }) | |
| 41201 | #endif | |
| 41202 | ||
| 41203 | #ifdef __LITTLE_ENDIAN__ | |
| 41204 | #define vcvtq_n_s16_f16(__p0, __p1) __extension__ ({ \ | |
| 41205 | float16x8_t __s0 = __p0; \ | |
| 41206 | int16x8_t __ret; \ | |
| 41207 | __ret = (int16x8_t) __builtin_neon_vcvtq_n_s16_v((int8x16_t)__s0, __p1, 33); \ | |
| 41208 | __ret; \ | |
| 41209 | }) | |
| 41210 | #else | |
| 41211 | #define vcvtq_n_s16_f16(__p0, __p1) __extension__ ({ \ | |
| 41212 | float16x8_t __s0 = __p0; \ | |
| 41213 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41214 | int16x8_t __ret; \ | |
| 41215 | __ret = (int16x8_t) __builtin_neon_vcvtq_n_s16_v((int8x16_t)__rev0, __p1, 33); \ | |
| 41216 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41217 | __ret; \ | |
| 41218 | }) | |
| 41219 | #endif | |
| 41220 | ||
| 41221 | #ifdef __LITTLE_ENDIAN__ | |
| 41222 | #define vcvt_n_s16_f16(__p0, __p1) __extension__ ({ \ | |
| 41223 | float16x4_t __s0 = __p0; \ | |
| 41224 | int16x4_t __ret; \ | |
| 41225 | __ret = (int16x4_t) __builtin_neon_vcvt_n_s16_v((int8x8_t)__s0, __p1, 1); \ | |
| 41226 | __ret; \ | |
| 41227 | }) | |
| 41228 | #else | |
| 41229 | #define vcvt_n_s16_f16(__p0, __p1) __extension__ ({ \ | |
| 41230 | float16x4_t __s0 = __p0; \ | |
| 41231 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 41232 | int16x4_t __ret; \ | |
| 41233 | __ret = (int16x4_t) __builtin_neon_vcvt_n_s16_v((int8x8_t)__rev0, __p1, 1); \ | |
| 41234 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 41235 | __ret; \ | |
| 41236 | }) | |
| 41237 | #endif | |
| 41238 | ||
| 41239 | #ifdef __LITTLE_ENDIAN__ | |
| 41240 | #define vcvtq_n_u16_f16(__p0, __p1) __extension__ ({ \ | |
| 41241 | float16x8_t __s0 = __p0; \ | |
| 41242 | uint16x8_t __ret; \ | |
| 41243 | __ret = (uint16x8_t) __builtin_neon_vcvtq_n_u16_v((int8x16_t)__s0, __p1, 49); \ | |
| 41244 | __ret; \ | |
| 41245 | }) | |
| 41246 | #else | |
| 41247 | #define vcvtq_n_u16_f16(__p0, __p1) __extension__ ({ \ | |
| 41248 | float16x8_t __s0 = __p0; \ | |
| 41249 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41250 | uint16x8_t __ret; \ | |
| 41251 | __ret = (uint16x8_t) __builtin_neon_vcvtq_n_u16_v((int8x16_t)__rev0, __p1, 49); \ | |
| 41252 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41253 | __ret; \ | |
| 41254 | }) | |
| 41255 | #endif | |
| 41256 | ||
| 41257 | #ifdef __LITTLE_ENDIAN__ | |
| 41258 | #define vcvt_n_u16_f16(__p0, __p1) __extension__ ({ \ | |
| 41259 | float16x4_t __s0 = __p0; \ | |
| 41260 | uint16x4_t __ret; \ | |
| 41261 | __ret = (uint16x4_t) __builtin_neon_vcvt_n_u16_v((int8x8_t)__s0, __p1, 17); \ | |
| 41262 | __ret; \ | |
| 41263 | }) | |
| 41264 | #else | |
| 41265 | #define vcvt_n_u16_f16(__p0, __p1) __extension__ ({ \ | |
| 41266 | float16x4_t __s0 = __p0; \ | |
| 41267 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 41268 | uint16x4_t __ret; \ | |
| 41269 | __ret = (uint16x4_t) __builtin_neon_vcvt_n_u16_v((int8x8_t)__rev0, __p1, 17); \ | |
| 41270 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 41271 | __ret; \ | |
| 41272 | }) | |
| 41273 | #endif | |
| 41274 | ||
| 41275 | #ifdef __LITTLE_ENDIAN__ | |
| 41276 | __ai int16x8_t vcvtq_s16_f16(float16x8_t __p0) { | |
| 41277 | int16x8_t __ret; | |
| 41278 | __ret = (int16x8_t) __builtin_neon_vcvtq_s16_v((int8x16_t)__p0, 33); | |
| 41279 | return __ret; | |
| 41280 | } | |
| 41281 | #else | |
| 41282 | __ai int16x8_t vcvtq_s16_f16(float16x8_t __p0) { | |
| 41283 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41284 | int16x8_t __ret; | |
| 41285 | __ret = (int16x8_t) __builtin_neon_vcvtq_s16_v((int8x16_t)__rev0, 33); | |
| 41286 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41287 | return __ret; | |
| 41288 | } | |
| 41289 | #endif | |
| 41290 | ||
| 41291 | #ifdef __LITTLE_ENDIAN__ | |
| 41292 | __ai int16x4_t vcvt_s16_f16(float16x4_t __p0) { | |
| 41293 | int16x4_t __ret; | |
| 41294 | __ret = (int16x4_t) __builtin_neon_vcvt_s16_v((int8x8_t)__p0, 1); | |
| 41295 | return __ret; | |
| 41296 | } | |
| 41297 | #else | |
| 41298 | __ai int16x4_t vcvt_s16_f16(float16x4_t __p0) { | |
| 41299 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41300 | int16x4_t __ret; | |
| 41301 | __ret = (int16x4_t) __builtin_neon_vcvt_s16_v((int8x8_t)__rev0, 1); | |
| 41302 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41303 | return __ret; | |
| 41304 | } | |
| 41305 | #endif | |
| 41306 | ||
| 41307 | #ifdef __LITTLE_ENDIAN__ | |
| 41308 | __ai uint16x8_t vcvtq_u16_f16(float16x8_t __p0) { | |
| 41309 | uint16x8_t __ret; | |
| 41310 | __ret = (uint16x8_t) __builtin_neon_vcvtq_u16_v((int8x16_t)__p0, 49); | |
| 41311 | return __ret; | |
| 41312 | } | |
| 41313 | #else | |
| 41314 | __ai uint16x8_t vcvtq_u16_f16(float16x8_t __p0) { | |
| 41315 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41316 | uint16x8_t __ret; | |
| 41317 | __ret = (uint16x8_t) __builtin_neon_vcvtq_u16_v((int8x16_t)__rev0, 49); | |
| 41318 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41319 | return __ret; | |
| 41320 | } | |
| 41321 | #endif | |
| 41322 | ||
| 41323 | #ifdef __LITTLE_ENDIAN__ | |
| 41324 | __ai uint16x4_t vcvt_u16_f16(float16x4_t __p0) { | |
| 41325 | uint16x4_t __ret; | |
| 41326 | __ret = (uint16x4_t) __builtin_neon_vcvt_u16_v((int8x8_t)__p0, 17); | |
| 41327 | return __ret; | |
| 41328 | } | |
| 41329 | #else | |
| 41330 | __ai uint16x4_t vcvt_u16_f16(float16x4_t __p0) { | |
| 41331 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41332 | uint16x4_t __ret; | |
| 41333 | __ret = (uint16x4_t) __builtin_neon_vcvt_u16_v((int8x8_t)__rev0, 17); | |
| 41334 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41335 | return __ret; | |
| 41336 | } | |
| 41337 | #endif | |
| 41338 | ||
| 41339 | #ifdef __LITTLE_ENDIAN__ | |
| 41340 | __ai int16x8_t vcvtaq_s16_f16(float16x8_t __p0) { | |
| 41341 | int16x8_t __ret; | |
| 41342 | __ret = (int16x8_t) __builtin_neon_vcvtaq_s16_v((int8x16_t)__p0, 33); | |
| 41343 | return __ret; | |
| 41344 | } | |
| 41345 | #else | |
| 41346 | __ai int16x8_t vcvtaq_s16_f16(float16x8_t __p0) { | |
| 41347 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41348 | int16x8_t __ret; | |
| 41349 | __ret = (int16x8_t) __builtin_neon_vcvtaq_s16_v((int8x16_t)__rev0, 33); | |
| 41350 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41351 | return __ret; | |
| 41352 | } | |
| 41353 | #endif | |
| 41354 | ||
| 41355 | #ifdef __LITTLE_ENDIAN__ | |
| 41356 | __ai int16x4_t vcvta_s16_f16(float16x4_t __p0) { | |
| 41357 | int16x4_t __ret; | |
| 41358 | __ret = (int16x4_t) __builtin_neon_vcvta_s16_v((int8x8_t)__p0, 1); | |
| 41359 | return __ret; | |
| 41360 | } | |
| 41361 | #else | |
| 41362 | __ai int16x4_t vcvta_s16_f16(float16x4_t __p0) { | |
| 41363 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41364 | int16x4_t __ret; | |
| 41365 | __ret = (int16x4_t) __builtin_neon_vcvta_s16_v((int8x8_t)__rev0, 1); | |
| 41366 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41367 | return __ret; | |
| 41368 | } | |
| 41369 | #endif | |
| 41370 | ||
| 41371 | #ifdef __LITTLE_ENDIAN__ | |
| 41372 | __ai uint16x8_t vcvtaq_u16_f16(float16x8_t __p0) { | |
| 41373 | uint16x8_t __ret; | |
| 41374 | __ret = (uint16x8_t) __builtin_neon_vcvtaq_u16_v((int8x16_t)__p0, 49); | |
| 41375 | return __ret; | |
| 41376 | } | |
| 41377 | #else | |
| 41378 | __ai uint16x8_t vcvtaq_u16_f16(float16x8_t __p0) { | |
| 41379 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41380 | uint16x8_t __ret; | |
| 41381 | __ret = (uint16x8_t) __builtin_neon_vcvtaq_u16_v((int8x16_t)__rev0, 49); | |
| 41382 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41383 | return __ret; | |
| 41384 | } | |
| 41385 | #endif | |
| 41386 | ||
| 41387 | #ifdef __LITTLE_ENDIAN__ | |
| 41388 | __ai uint16x4_t vcvta_u16_f16(float16x4_t __p0) { | |
| 41389 | uint16x4_t __ret; | |
| 41390 | __ret = (uint16x4_t) __builtin_neon_vcvta_u16_v((int8x8_t)__p0, 17); | |
| 41391 | return __ret; | |
| 41392 | } | |
| 41393 | #else | |
| 41394 | __ai uint16x4_t vcvta_u16_f16(float16x4_t __p0) { | |
| 41395 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41396 | uint16x4_t __ret; | |
| 41397 | __ret = (uint16x4_t) __builtin_neon_vcvta_u16_v((int8x8_t)__rev0, 17); | |
| 41398 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41399 | return __ret; | |
| 41400 | } | |
| 41401 | #endif | |
| 41402 | ||
| 41403 | #ifdef __LITTLE_ENDIAN__ | |
| 41404 | __ai int16x8_t vcvtmq_s16_f16(float16x8_t __p0) { | |
| 41405 | int16x8_t __ret; | |
| 41406 | __ret = (int16x8_t) __builtin_neon_vcvtmq_s16_v((int8x16_t)__p0, 33); | |
| 41407 | return __ret; | |
| 41408 | } | |
| 41409 | #else | |
| 41410 | __ai int16x8_t vcvtmq_s16_f16(float16x8_t __p0) { | |
| 41411 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41412 | int16x8_t __ret; | |
| 41413 | __ret = (int16x8_t) __builtin_neon_vcvtmq_s16_v((int8x16_t)__rev0, 33); | |
| 41414 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41415 | return __ret; | |
| 41416 | } | |
| 41417 | #endif | |
| 41418 | ||
| 41419 | #ifdef __LITTLE_ENDIAN__ | |
| 41420 | __ai int16x4_t vcvtm_s16_f16(float16x4_t __p0) { | |
| 41421 | int16x4_t __ret; | |
| 41422 | __ret = (int16x4_t) __builtin_neon_vcvtm_s16_v((int8x8_t)__p0, 1); | |
| 41423 | return __ret; | |
| 41424 | } | |
| 41425 | #else | |
| 41426 | __ai int16x4_t vcvtm_s16_f16(float16x4_t __p0) { | |
| 41427 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41428 | int16x4_t __ret; | |
| 41429 | __ret = (int16x4_t) __builtin_neon_vcvtm_s16_v((int8x8_t)__rev0, 1); | |
| 41430 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41431 | return __ret; | |
| 41432 | } | |
| 41433 | #endif | |
| 41434 | ||
| 41435 | #ifdef __LITTLE_ENDIAN__ | |
| 41436 | __ai uint16x8_t vcvtmq_u16_f16(float16x8_t __p0) { | |
| 41437 | uint16x8_t __ret; | |
| 41438 | __ret = (uint16x8_t) __builtin_neon_vcvtmq_u16_v((int8x16_t)__p0, 49); | |
| 41439 | return __ret; | |
| 41440 | } | |
| 41441 | #else | |
| 41442 | __ai uint16x8_t vcvtmq_u16_f16(float16x8_t __p0) { | |
| 41443 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41444 | uint16x8_t __ret; | |
| 41445 | __ret = (uint16x8_t) __builtin_neon_vcvtmq_u16_v((int8x16_t)__rev0, 49); | |
| 41446 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41447 | return __ret; | |
| 41448 | } | |
| 41449 | #endif | |
| 41450 | ||
| 41451 | #ifdef __LITTLE_ENDIAN__ | |
| 41452 | __ai uint16x4_t vcvtm_u16_f16(float16x4_t __p0) { | |
| 41453 | uint16x4_t __ret; | |
| 41454 | __ret = (uint16x4_t) __builtin_neon_vcvtm_u16_v((int8x8_t)__p0, 17); | |
| 41455 | return __ret; | |
| 41456 | } | |
| 41457 | #else | |
| 41458 | __ai uint16x4_t vcvtm_u16_f16(float16x4_t __p0) { | |
| 41459 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41460 | uint16x4_t __ret; | |
| 41461 | __ret = (uint16x4_t) __builtin_neon_vcvtm_u16_v((int8x8_t)__rev0, 17); | |
| 41462 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41463 | return __ret; | |
| 41464 | } | |
| 41465 | #endif | |
| 41466 | ||
| 41467 | #ifdef __LITTLE_ENDIAN__ | |
| 41468 | __ai int16x8_t vcvtnq_s16_f16(float16x8_t __p0) { | |
| 41469 | int16x8_t __ret; | |
| 41470 | __ret = (int16x8_t) __builtin_neon_vcvtnq_s16_v((int8x16_t)__p0, 33); | |
| 41471 | return __ret; | |
| 41472 | } | |
| 41473 | #else | |
| 41474 | __ai int16x8_t vcvtnq_s16_f16(float16x8_t __p0) { | |
| 41475 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41476 | int16x8_t __ret; | |
| 41477 | __ret = (int16x8_t) __builtin_neon_vcvtnq_s16_v((int8x16_t)__rev0, 33); | |
| 41478 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41479 | return __ret; | |
| 41480 | } | |
| 41481 | #endif | |
| 41482 | ||
| 41483 | #ifdef __LITTLE_ENDIAN__ | |
| 41484 | __ai int16x4_t vcvtn_s16_f16(float16x4_t __p0) { | |
| 41485 | int16x4_t __ret; | |
| 41486 | __ret = (int16x4_t) __builtin_neon_vcvtn_s16_v((int8x8_t)__p0, 1); | |
| 41487 | return __ret; | |
| 41488 | } | |
| 41489 | #else | |
| 41490 | __ai int16x4_t vcvtn_s16_f16(float16x4_t __p0) { | |
| 41491 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41492 | int16x4_t __ret; | |
| 41493 | __ret = (int16x4_t) __builtin_neon_vcvtn_s16_v((int8x8_t)__rev0, 1); | |
| 41494 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41495 | return __ret; | |
| 41496 | } | |
| 41497 | #endif | |
| 41498 | ||
| 41499 | #ifdef __LITTLE_ENDIAN__ | |
| 41500 | __ai uint16x8_t vcvtnq_u16_f16(float16x8_t __p0) { | |
| 41501 | uint16x8_t __ret; | |
| 41502 | __ret = (uint16x8_t) __builtin_neon_vcvtnq_u16_v((int8x16_t)__p0, 49); | |
| 41503 | return __ret; | |
| 41504 | } | |
| 41505 | #else | |
| 41506 | __ai uint16x8_t vcvtnq_u16_f16(float16x8_t __p0) { | |
| 41507 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41508 | uint16x8_t __ret; | |
| 41509 | __ret = (uint16x8_t) __builtin_neon_vcvtnq_u16_v((int8x16_t)__rev0, 49); | |
| 41510 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41511 | return __ret; | |
| 41512 | } | |
| 41513 | #endif | |
| 41514 | ||
| 41515 | #ifdef __LITTLE_ENDIAN__ | |
| 41516 | __ai uint16x4_t vcvtn_u16_f16(float16x4_t __p0) { | |
| 41517 | uint16x4_t __ret; | |
| 41518 | __ret = (uint16x4_t) __builtin_neon_vcvtn_u16_v((int8x8_t)__p0, 17); | |
| 41519 | return __ret; | |
| 41520 | } | |
| 41521 | #else | |
| 41522 | __ai uint16x4_t vcvtn_u16_f16(float16x4_t __p0) { | |
| 41523 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41524 | uint16x4_t __ret; | |
| 41525 | __ret = (uint16x4_t) __builtin_neon_vcvtn_u16_v((int8x8_t)__rev0, 17); | |
| 41526 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41527 | return __ret; | |
| 41528 | } | |
| 41529 | #endif | |
| 41530 | ||
| 41531 | #ifdef __LITTLE_ENDIAN__ | |
| 41532 | __ai int16x8_t vcvtpq_s16_f16(float16x8_t __p0) { | |
| 41533 | int16x8_t __ret; | |
| 41534 | __ret = (int16x8_t) __builtin_neon_vcvtpq_s16_v((int8x16_t)__p0, 33); | |
| 41535 | return __ret; | |
| 41536 | } | |
| 41537 | #else | |
| 41538 | __ai int16x8_t vcvtpq_s16_f16(float16x8_t __p0) { | |
| 41539 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41540 | int16x8_t __ret; | |
| 41541 | __ret = (int16x8_t) __builtin_neon_vcvtpq_s16_v((int8x16_t)__rev0, 33); | |
| 41542 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41543 | return __ret; | |
| 41544 | } | |
| 41545 | #endif | |
| 41546 | ||
| 41547 | #ifdef __LITTLE_ENDIAN__ | |
| 41548 | __ai int16x4_t vcvtp_s16_f16(float16x4_t __p0) { | |
| 41549 | int16x4_t __ret; | |
| 41550 | __ret = (int16x4_t) __builtin_neon_vcvtp_s16_v((int8x8_t)__p0, 1); | |
| 41551 | return __ret; | |
| 41552 | } | |
| 41553 | #else | |
| 41554 | __ai int16x4_t vcvtp_s16_f16(float16x4_t __p0) { | |
| 41555 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41556 | int16x4_t __ret; | |
| 41557 | __ret = (int16x4_t) __builtin_neon_vcvtp_s16_v((int8x8_t)__rev0, 1); | |
| 41558 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41559 | return __ret; | |
| 41560 | } | |
| 41561 | #endif | |
| 41562 | ||
| 41563 | #ifdef __LITTLE_ENDIAN__ | |
| 41564 | __ai uint16x8_t vcvtpq_u16_f16(float16x8_t __p0) { | |
| 41565 | uint16x8_t __ret; | |
| 41566 | __ret = (uint16x8_t) __builtin_neon_vcvtpq_u16_v((int8x16_t)__p0, 49); | |
| 41567 | return __ret; | |
| 41568 | } | |
| 41569 | #else | |
| 41570 | __ai uint16x8_t vcvtpq_u16_f16(float16x8_t __p0) { | |
| 41571 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41572 | uint16x8_t __ret; | |
| 41573 | __ret = (uint16x8_t) __builtin_neon_vcvtpq_u16_v((int8x16_t)__rev0, 49); | |
| 41574 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41575 | return __ret; | |
| 41576 | } | |
| 41577 | #endif | |
| 41578 | ||
| 41579 | #ifdef __LITTLE_ENDIAN__ | |
| 41580 | __ai uint16x4_t vcvtp_u16_f16(float16x4_t __p0) { | |
| 41581 | uint16x4_t __ret; | |
| 41582 | __ret = (uint16x4_t) __builtin_neon_vcvtp_u16_v((int8x8_t)__p0, 17); | |
| 41583 | return __ret; | |
| 41584 | } | |
| 41585 | #else | |
| 41586 | __ai uint16x4_t vcvtp_u16_f16(float16x4_t __p0) { | |
| 41587 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41588 | uint16x4_t __ret; | |
| 41589 | __ret = (uint16x4_t) __builtin_neon_vcvtp_u16_v((int8x8_t)__rev0, 17); | |
| 41590 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41591 | return __ret; | |
| 41592 | } | |
| 41593 | #endif | |
| 41594 | ||
| 41595 | #ifdef __LITTLE_ENDIAN__ | |
| 41596 | __ai float16x8_t vdivq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 41597 | float16x8_t __ret; | |
| 41598 | __ret = __p0 / __p1; | |
| 41599 | return __ret; | |
| 41600 | } | |
| 41601 | #else | |
| 41602 | __ai float16x8_t vdivq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 41603 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41604 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41605 | float16x8_t __ret; | |
| 41606 | __ret = __rev0 / __rev1; | |
| 41607 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41608 | return __ret; | |
| 41609 | } | |
| 41610 | #endif | |
| 41611 | ||
| 41612 | #ifdef __LITTLE_ENDIAN__ | |
| 41613 | __ai float16x4_t vdiv_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 41614 | float16x4_t __ret; | |
| 41615 | __ret = __p0 / __p1; | |
| 41616 | return __ret; | |
| 41617 | } | |
| 41618 | #else | |
| 41619 | __ai float16x4_t vdiv_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 41620 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41621 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 41622 | float16x4_t __ret; | |
| 41623 | __ret = __rev0 / __rev1; | |
| 41624 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41625 | return __ret; | |
| 41626 | } | |
| 41627 | #endif | |
| 41628 | ||
| 41629 | #ifdef __LITTLE_ENDIAN__ | |
| 41630 | #define vduph_lane_f16(__p0, __p1) __extension__ ({ \ | |
| 41631 | float16x4_t __s0 = __p0; \ | |
| 41632 | float16_t __ret; \ | |
| 41633 | __ret = (float16_t) __builtin_neon_vduph_lane_f16((int8x8_t)__s0, __p1); \ | |
| 41634 | __ret; \ | |
| 41635 | }) | |
| 41636 | #else | |
| 41637 | #define vduph_lane_f16(__p0, __p1) __extension__ ({ \ | |
| 41638 | float16x4_t __s0 = __p0; \ | |
| 41639 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 41640 | float16_t __ret; \ | |
| 41641 | __ret = (float16_t) __builtin_neon_vduph_lane_f16((int8x8_t)__rev0, __p1); \ | |
| 41642 | __ret; \ | |
| 41643 | }) | |
| 41644 | #endif | |
| 41645 | ||
| 41646 | #ifdef __LITTLE_ENDIAN__ | |
| 41647 | #define vduph_laneq_f16(__p0, __p1) __extension__ ({ \ | |
| 41648 | float16x8_t __s0 = __p0; \ | |
| 41649 | float16_t __ret; \ | |
| 41650 | __ret = (float16_t) __builtin_neon_vduph_laneq_f16((int8x16_t)__s0, __p1); \ | |
| 41651 | __ret; \ | |
| 41652 | }) | |
| 41653 | #else | |
| 41654 | #define vduph_laneq_f16(__p0, __p1) __extension__ ({ \ | |
| 41655 | float16x8_t __s0 = __p0; \ | |
| 41656 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41657 | float16_t __ret; \ | |
| 41658 | __ret = (float16_t) __builtin_neon_vduph_laneq_f16((int8x16_t)__rev0, __p1); \ | |
| 41659 | __ret; \ | |
| 41660 | }) | |
| 41661 | #endif | |
| 41662 | ||
| 41663 | #ifdef __LITTLE_ENDIAN__ | |
| 41664 | #define vextq_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 41665 | float16x8_t __s0 = __p0; \ | |
| 41666 | float16x8_t __s1 = __p1; \ | |
| 41667 | float16x8_t __ret; \ | |
| 41668 | __ret = (float16x8_t) __builtin_neon_vextq_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 40); \ | |
| 41669 | __ret; \ | |
| 41670 | }) | |
| 41671 | #else | |
| 41672 | #define vextq_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 41673 | float16x8_t __s0 = __p0; \ | |
| 41674 | float16x8_t __s1 = __p1; \ | |
| 41675 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41676 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41677 | float16x8_t __ret; \ | |
| 41678 | __ret = (float16x8_t) __builtin_neon_vextq_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 40); \ | |
| 41679 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41680 | __ret; \ | |
| 41681 | }) | |
| 41682 | #endif | |
| 41683 | ||
| 41684 | #ifdef __LITTLE_ENDIAN__ | |
| 41685 | #define vext_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 41686 | float16x4_t __s0 = __p0; \ | |
| 41687 | float16x4_t __s1 = __p1; \ | |
| 41688 | float16x4_t __ret; \ | |
| 41689 | __ret = (float16x4_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 8); \ | |
| 41690 | __ret; \ | |
| 41691 | }) | |
| 41692 | #else | |
| 41693 | #define vext_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 41694 | float16x4_t __s0 = __p0; \ | |
| 41695 | float16x4_t __s1 = __p1; \ | |
| 41696 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 41697 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \ | |
| 41698 | float16x4_t __ret; \ | |
| 41699 | __ret = (float16x4_t) __builtin_neon_vext_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 8); \ | |
| 41700 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 41701 | __ret; \ | |
| 41702 | }) | |
| 41703 | #endif | |
| 41704 | ||
| 41705 | #ifdef __LITTLE_ENDIAN__ | |
| 41706 | __ai float16x8_t vfmaq_f16(float16x8_t __p0, float16x8_t __p1, float16x8_t __p2) { | |
| 41707 | float16x8_t __ret; | |
| 41708 | __ret = (float16x8_t) __builtin_neon_vfmaq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 40); | |
| 41709 | return __ret; | |
| 41710 | } | |
| 41711 | #else | |
| 41712 | __ai float16x8_t vfmaq_f16(float16x8_t __p0, float16x8_t __p1, float16x8_t __p2) { | |
| 41713 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41714 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41715 | float16x8_t __rev2; __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41716 | float16x8_t __ret; | |
| 41717 | __ret = (float16x8_t) __builtin_neon_vfmaq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 40); | |
| 41718 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41719 | return __ret; | |
| 41720 | } | |
| 41721 | __ai float16x8_t __noswap_vfmaq_f16(float16x8_t __p0, float16x8_t __p1, float16x8_t __p2) { | |
| 41722 | float16x8_t __ret; | |
| 41723 | __ret = (float16x8_t) __builtin_neon_vfmaq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 40); | |
| 41724 | return __ret; | |
| 41725 | } | |
| 41726 | #endif | |
| 41727 | ||
| 41728 | #ifdef __LITTLE_ENDIAN__ | |
| 41729 | __ai float16x4_t vfma_f16(float16x4_t __p0, float16x4_t __p1, float16x4_t __p2) { | |
| 41730 | float16x4_t __ret; | |
| 41731 | __ret = (float16x4_t) __builtin_neon_vfma_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 8); | |
| 41732 | return __ret; | |
| 41733 | } | |
| 41734 | #else | |
| 41735 | __ai float16x4_t vfma_f16(float16x4_t __p0, float16x4_t __p1, float16x4_t __p2) { | |
| 41736 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 41737 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 41738 | float16x4_t __rev2; __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0); | |
| 41739 | float16x4_t __ret; | |
| 41740 | __ret = (float16x4_t) __builtin_neon_vfma_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 8); | |
| 41741 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 41742 | return __ret; | |
| 41743 | } | |
| 41744 | __ai float16x4_t __noswap_vfma_f16(float16x4_t __p0, float16x4_t __p1, float16x4_t __p2) { | |
| 41745 | float16x4_t __ret; | |
| 41746 | __ret = (float16x4_t) __builtin_neon_vfma_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 8); | |
| 41747 | return __ret; | |
| 41748 | } | |
| 41749 | #endif | |
| 41750 | ||
| 41751 | #ifdef __LITTLE_ENDIAN__ | |
| 41752 | #define vfmah_lane_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41753 | float16_t __s0 = __p0; \ | |
| 41754 | float16_t __s1 = __p1; \ | |
| 41755 | float16x4_t __s2 = __p2; \ | |
| 41756 | float16_t __ret; \ | |
| 41757 | __ret = (float16_t) __builtin_neon_vfmah_lane_f16(__s0, __s1, (int8x8_t)__s2, __p3); \ | |
| 41758 | __ret; \ | |
| 41759 | }) | |
| 41760 | #else | |
| 41761 | #define vfmah_lane_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41762 | float16_t __s0 = __p0; \ | |
| 41763 | float16_t __s1 = __p1; \ | |
| 41764 | float16x4_t __s2 = __p2; \ | |
| 41765 | float16x4_t __rev2; __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \ | |
| 41766 | float16_t __ret; \ | |
| 41767 | __ret = (float16_t) __builtin_neon_vfmah_lane_f16(__s0, __s1, (int8x8_t)__rev2, __p3); \ | |
| 41768 | __ret; \ | |
| 41769 | }) | |
| 41770 | #define __noswap_vfmah_lane_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41771 | float16_t __s0 = __p0; \ | |
| 41772 | float16_t __s1 = __p1; \ | |
| 41773 | float16x4_t __s2 = __p2; \ | |
| 41774 | float16_t __ret; \ | |
| 41775 | __ret = (float16_t) __builtin_neon_vfmah_lane_f16(__s0, __s1, (int8x8_t)__s2, __p3); \ | |
| 41776 | __ret; \ | |
| 41777 | }) | |
| 41778 | #endif | |
| 41779 | ||
| 41780 | #ifdef __LITTLE_ENDIAN__ | |
| 41781 | #define vfmaq_lane_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41782 | float16x8_t __s0 = __p0; \ | |
| 41783 | float16x8_t __s1 = __p1; \ | |
| 41784 | float16x4_t __s2 = __p2; \ | |
| 41785 | float16x8_t __ret; \ | |
| 41786 | __ret = (float16x8_t) __builtin_neon_vfmaq_lane_v((int8x16_t)__s0, (int8x16_t)__s1, (int8x8_t)__s2, __p3, 40); \ | |
| 41787 | __ret; \ | |
| 41788 | }) | |
| 41789 | #else | |
| 41790 | #define vfmaq_lane_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41791 | float16x8_t __s0 = __p0; \ | |
| 41792 | float16x8_t __s1 = __p1; \ | |
| 41793 | float16x4_t __s2 = __p2; \ | |
| 41794 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41795 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41796 | float16x4_t __rev2; __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \ | |
| 41797 | float16x8_t __ret; \ | |
| 41798 | __ret = (float16x8_t) __builtin_neon_vfmaq_lane_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x8_t)__rev2, __p3, 40); \ | |
| 41799 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41800 | __ret; \ | |
| 41801 | }) | |
| 41802 | #define __noswap_vfmaq_lane_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41803 | float16x8_t __s0 = __p0; \ | |
| 41804 | float16x8_t __s1 = __p1; \ | |
| 41805 | float16x4_t __s2 = __p2; \ | |
| 41806 | float16x8_t __ret; \ | |
| 41807 | __ret = (float16x8_t) __builtin_neon_vfmaq_lane_v((int8x16_t)__s0, (int8x16_t)__s1, (int8x8_t)__s2, __p3, 40); \ | |
| 41808 | __ret; \ | |
| 41809 | }) | |
| 41810 | #endif | |
| 41811 | ||
| 41812 | #ifdef __LITTLE_ENDIAN__ | |
| 41813 | #define vfma_lane_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41814 | float16x4_t __s0 = __p0; \ | |
| 41815 | float16x4_t __s1 = __p1; \ | |
| 41816 | float16x4_t __s2 = __p2; \ | |
| 41817 | float16x4_t __ret; \ | |
| 41818 | __ret = (float16x4_t) __builtin_neon_vfma_lane_v((int8x8_t)__s0, (int8x8_t)__s1, (int8x8_t)__s2, __p3, 8); \ | |
| 41819 | __ret; \ | |
| 41820 | }) | |
| 41821 | #else | |
| 41822 | #define vfma_lane_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41823 | float16x4_t __s0 = __p0; \ | |
| 41824 | float16x4_t __s1 = __p1; \ | |
| 41825 | float16x4_t __s2 = __p2; \ | |
| 41826 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 41827 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \ | |
| 41828 | float16x4_t __rev2; __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \ | |
| 41829 | float16x4_t __ret; \ | |
| 41830 | __ret = (float16x4_t) __builtin_neon_vfma_lane_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, __p3, 8); \ | |
| 41831 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 41832 | __ret; \ | |
| 41833 | }) | |
| 41834 | #define __noswap_vfma_lane_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41835 | float16x4_t __s0 = __p0; \ | |
| 41836 | float16x4_t __s1 = __p1; \ | |
| 41837 | float16x4_t __s2 = __p2; \ | |
| 41838 | float16x4_t __ret; \ | |
| 41839 | __ret = (float16x4_t) __builtin_neon_vfma_lane_v((int8x8_t)__s0, (int8x8_t)__s1, (int8x8_t)__s2, __p3, 8); \ | |
| 41840 | __ret; \ | |
| 41841 | }) | |
| 41842 | #endif | |
| 41843 | ||
| 41844 | #ifdef __LITTLE_ENDIAN__ | |
| 41845 | #define vfmah_laneq_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41846 | float16_t __s0 = __p0; \ | |
| 41847 | float16_t __s1 = __p1; \ | |
| 41848 | float16x8_t __s2 = __p2; \ | |
| 41849 | float16_t __ret; \ | |
| 41850 | __ret = (float16_t) __builtin_neon_vfmah_laneq_f16(__s0, __s1, (int8x16_t)__s2, __p3); \ | |
| 41851 | __ret; \ | |
| 41852 | }) | |
| 41853 | #else | |
| 41854 | #define vfmah_laneq_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41855 | float16_t __s0 = __p0; \ | |
| 41856 | float16_t __s1 = __p1; \ | |
| 41857 | float16x8_t __s2 = __p2; \ | |
| 41858 | float16x8_t __rev2; __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41859 | float16_t __ret; \ | |
| 41860 | __ret = (float16_t) __builtin_neon_vfmah_laneq_f16(__s0, __s1, (int8x16_t)__rev2, __p3); \ | |
| 41861 | __ret; \ | |
| 41862 | }) | |
| 41863 | #define __noswap_vfmah_laneq_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41864 | float16_t __s0 = __p0; \ | |
| 41865 | float16_t __s1 = __p1; \ | |
| 41866 | float16x8_t __s2 = __p2; \ | |
| 41867 | float16_t __ret; \ | |
| 41868 | __ret = (float16_t) __builtin_neon_vfmah_laneq_f16(__s0, __s1, (int8x16_t)__s2, __p3); \ | |
| 41869 | __ret; \ | |
| 41870 | }) | |
| 41871 | #endif | |
| 41872 | ||
| 41873 | #ifdef __LITTLE_ENDIAN__ | |
| 41874 | #define vfmaq_laneq_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41875 | float16x8_t __s0 = __p0; \ | |
| 41876 | float16x8_t __s1 = __p1; \ | |
| 41877 | float16x8_t __s2 = __p2; \ | |
| 41878 | float16x8_t __ret; \ | |
| 41879 | __ret = (float16x8_t) __builtin_neon_vfmaq_laneq_v((int8x16_t)__s0, (int8x16_t)__s1, (int8x16_t)__s2, __p3, 40); \ | |
| 41880 | __ret; \ | |
| 41881 | }) | |
| 41882 | #else | |
| 41883 | #define vfmaq_laneq_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41884 | float16x8_t __s0 = __p0; \ | |
| 41885 | float16x8_t __s1 = __p1; \ | |
| 41886 | float16x8_t __s2 = __p2; \ | |
| 41887 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41888 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41889 | float16x8_t __rev2; __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41890 | float16x8_t __ret; \ | |
| 41891 | __ret = (float16x8_t) __builtin_neon_vfmaq_laneq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, __p3, 40); \ | |
| 41892 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41893 | __ret; \ | |
| 41894 | }) | |
| 41895 | #define __noswap_vfmaq_laneq_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41896 | float16x8_t __s0 = __p0; \ | |
| 41897 | float16x8_t __s1 = __p1; \ | |
| 41898 | float16x8_t __s2 = __p2; \ | |
| 41899 | float16x8_t __ret; \ | |
| 41900 | __ret = (float16x8_t) __builtin_neon_vfmaq_laneq_v((int8x16_t)__s0, (int8x16_t)__s1, (int8x16_t)__s2, __p3, 40); \ | |
| 41901 | __ret; \ | |
| 41902 | }) | |
| 41903 | #endif | |
| 41904 | ||
| 41905 | #ifdef __LITTLE_ENDIAN__ | |
| 41906 | #define vfma_laneq_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41907 | float16x4_t __s0 = __p0; \ | |
| 41908 | float16x4_t __s1 = __p1; \ | |
| 41909 | float16x8_t __s2 = __p2; \ | |
| 41910 | float16x4_t __ret; \ | |
| 41911 | __ret = (float16x4_t) __builtin_neon_vfma_laneq_v((int8x8_t)__s0, (int8x8_t)__s1, (int8x16_t)__s2, __p3, 8); \ | |
| 41912 | __ret; \ | |
| 41913 | }) | |
| 41914 | #else | |
| 41915 | #define vfma_laneq_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41916 | float16x4_t __s0 = __p0; \ | |
| 41917 | float16x4_t __s1 = __p1; \ | |
| 41918 | float16x8_t __s2 = __p2; \ | |
| 41919 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 41920 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \ | |
| 41921 | float16x8_t __rev2; __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41922 | float16x4_t __ret; \ | |
| 41923 | __ret = (float16x4_t) __builtin_neon_vfma_laneq_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x16_t)__rev2, __p3, 8); \ | |
| 41924 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 41925 | __ret; \ | |
| 41926 | }) | |
| 41927 | #define __noswap_vfma_laneq_f16(__p0, __p1, __p2, __p3) __extension__ ({ \ | |
| 41928 | float16x4_t __s0 = __p0; \ | |
| 41929 | float16x4_t __s1 = __p1; \ | |
| 41930 | float16x8_t __s2 = __p2; \ | |
| 41931 | float16x4_t __ret; \ | |
| 41932 | __ret = (float16x4_t) __builtin_neon_vfma_laneq_v((int8x8_t)__s0, (int8x8_t)__s1, (int8x16_t)__s2, __p3, 8); \ | |
| 41933 | __ret; \ | |
| 41934 | }) | |
| 41935 | #endif | |
| 41936 | ||
| 41937 | #ifdef __LITTLE_ENDIAN__ | |
| 41938 | #define vfmaq_n_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 41939 | float16x8_t __s0 = __p0; \ | |
| 41940 | float16x8_t __s1 = __p1; \ | |
| 41941 | float16_t __s2 = __p2; \ | |
| 41942 | float16x8_t __ret; \ | |
| 41943 | __ret = vfmaq_f16(__s0, __s1, (float16x8_t) {__s2, __s2, __s2, __s2, __s2, __s2, __s2, __s2}); \ | |
| 41944 | __ret; \ | |
| 41945 | }) | |
| 41946 | #else | |
| 41947 | #define vfmaq_n_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 41948 | float16x8_t __s0 = __p0; \ | |
| 41949 | float16x8_t __s1 = __p1; \ | |
| 41950 | float16_t __s2 = __p2; \ | |
| 41951 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41952 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41953 | float16x8_t __ret; \ | |
| 41954 | __ret = __noswap_vfmaq_f16(__rev0, __rev1, (float16x8_t) {__s2, __s2, __s2, __s2, __s2, __s2, __s2, __s2}); \ | |
| 41955 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 41956 | __ret; \ | |
| 41957 | }) | |
| 41958 | #endif | |
| 41959 | ||
| 41960 | #ifdef __LITTLE_ENDIAN__ | |
| 41961 | #define vfma_n_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 41962 | float16x4_t __s0 = __p0; \ | |
| 41963 | float16x4_t __s1 = __p1; \ | |
| 41964 | float16_t __s2 = __p2; \ | |
| 41965 | float16x4_t __ret; \ | |
| 41966 | __ret = vfma_f16(__s0, __s1, (float16x4_t) {__s2, __s2, __s2, __s2}); \ | |
| 41967 | __ret; \ | |
| 41968 | }) | |
| 41969 | #else | |
| 41970 | #define vfma_n_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 41971 | float16x4_t __s0 = __p0; \ | |
| 41972 | float16x4_t __s1 = __p1; \ | |
| 41973 | float16_t __s2 = __p2; \ | |
| 41974 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 41975 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \ | |
| 41976 | float16x4_t __ret; \ | |
| 41977 | __ret = __noswap_vfma_f16(__rev0, __rev1, (float16x4_t) {__s2, __s2, __s2, __s2}); \ | |
| 41978 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 41979 | __ret; \ | |
| 41980 | }) | |
| 41981 | #endif | |
| 41982 | ||
| 41983 | #ifdef __LITTLE_ENDIAN__ | |
| 41984 | __ai float16x8_t vfmsq_f16(float16x8_t __p0, float16x8_t __p1, float16x8_t __p2) { | |
| 41985 | float16x8_t __ret; | |
| 41986 | __ret = vfmaq_f16(__p0, -__p1, __p2); | |
| 41987 | return __ret; | |
| 41988 | } | |
| 41989 | #else | |
| 41990 | __ai float16x8_t vfmsq_f16(float16x8_t __p0, float16x8_t __p1, float16x8_t __p2) { | |
| 41991 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41992 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41993 | float16x8_t __rev2; __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41994 | float16x8_t __ret; | |
| 41995 | __ret = __noswap_vfmaq_f16(__rev0, -__rev1, __rev2); | |
| 41996 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 41997 | return __ret; | |
| 41998 | } | |
| 41999 | #endif | |
| 42000 | ||
| 42001 | #ifdef __LITTLE_ENDIAN__ | |
| 42002 | __ai float16x4_t vfms_f16(float16x4_t __p0, float16x4_t __p1, float16x4_t __p2) { | |
| 42003 | float16x4_t __ret; | |
| 42004 | __ret = vfma_f16(__p0, -__p1, __p2); | |
| 42005 | return __ret; | |
| 42006 | } | |
| 42007 | #else | |
| 42008 | __ai float16x4_t vfms_f16(float16x4_t __p0, float16x4_t __p1, float16x4_t __p2) { | |
| 42009 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 42010 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 42011 | float16x4_t __rev2; __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0); | |
| 42012 | float16x4_t __ret; | |
| 42013 | __ret = __noswap_vfma_f16(__rev0, -__rev1, __rev2); | |
| 42014 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 42015 | return __ret; | |
| 42016 | } | |
| 42017 | #endif | |
| 42018 | ||
| 42019 | #ifdef __LITTLE_ENDIAN__ | |
| 42020 | #define vfmsh_lane_f16(__p0_0, __p1_0, __p2_0, __p3_0) __extension__ ({ \ | |
| 42021 | float16_t __s0_0 = __p0_0; \ | |
| 42022 | float16_t __s1_0 = __p1_0; \ | |
| 42023 | float16x4_t __s2_0 = __p2_0; \ | |
| 42024 | float16_t __ret_0; \ | |
| 42025 | __ret_0 = vfmah_lane_f16(__s0_0, -__s1_0, __s2_0, __p3_0); \ | |
| 42026 | __ret_0; \ | |
| 42027 | }) | |
| 42028 | #else | |
| 42029 | #define vfmsh_lane_f16(__p0_1, __p1_1, __p2_1, __p3_1) __extension__ ({ \ | |
| 42030 | float16_t __s0_1 = __p0_1; \ | |
| 42031 | float16_t __s1_1 = __p1_1; \ | |
| 42032 | float16x4_t __s2_1 = __p2_1; \ | |
| 42033 | float16x4_t __rev2_1; __rev2_1 = __builtin_shufflevector(__s2_1, __s2_1, 3, 2, 1, 0); \ | |
| 42034 | float16_t __ret_1; \ | |
| 42035 | __ret_1 = __noswap_vfmah_lane_f16(__s0_1, -__s1_1, __rev2_1, __p3_1); \ | |
| 42036 | __ret_1; \ | |
| 42037 | }) | |
| 42038 | #endif | |
| 42039 | ||
| 42040 | #ifdef __LITTLE_ENDIAN__ | |
| 42041 | #define vfmsq_lane_f16(__p0_2, __p1_2, __p2_2, __p3_2) __extension__ ({ \ | |
| 42042 | float16x8_t __s0_2 = __p0_2; \ | |
| 42043 | float16x8_t __s1_2 = __p1_2; \ | |
| 42044 | float16x4_t __s2_2 = __p2_2; \ | |
| 42045 | float16x8_t __ret_2; \ | |
| 42046 | __ret_2 = vfmaq_lane_f16(__s0_2, -__s1_2, __s2_2, __p3_2); \ | |
| 42047 | __ret_2; \ | |
| 42048 | }) | |
| 42049 | #else | |
| 42050 | #define vfmsq_lane_f16(__p0_3, __p1_3, __p2_3, __p3_3) __extension__ ({ \ | |
| 42051 | float16x8_t __s0_3 = __p0_3; \ | |
| 42052 | float16x8_t __s1_3 = __p1_3; \ | |
| 42053 | float16x4_t __s2_3 = __p2_3; \ | |
| 42054 | float16x8_t __rev0_3; __rev0_3 = __builtin_shufflevector(__s0_3, __s0_3, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42055 | float16x8_t __rev1_3; __rev1_3 = __builtin_shufflevector(__s1_3, __s1_3, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42056 | float16x4_t __rev2_3; __rev2_3 = __builtin_shufflevector(__s2_3, __s2_3, 3, 2, 1, 0); \ | |
| 42057 | float16x8_t __ret_3; \ | |
| 42058 | __ret_3 = __noswap_vfmaq_lane_f16(__rev0_3, -__rev1_3, __rev2_3, __p3_3); \ | |
| 42059 | __ret_3 = __builtin_shufflevector(__ret_3, __ret_3, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42060 | __ret_3; \ | |
| 42061 | }) | |
| 42062 | #endif | |
| 42063 | ||
| 42064 | #ifdef __LITTLE_ENDIAN__ | |
| 42065 | #define vfms_lane_f16(__p0_4, __p1_4, __p2_4, __p3_4) __extension__ ({ \ | |
| 42066 | float16x4_t __s0_4 = __p0_4; \ | |
| 42067 | float16x4_t __s1_4 = __p1_4; \ | |
| 42068 | float16x4_t __s2_4 = __p2_4; \ | |
| 42069 | float16x4_t __ret_4; \ | |
| 42070 | __ret_4 = vfma_lane_f16(__s0_4, -__s1_4, __s2_4, __p3_4); \ | |
| 42071 | __ret_4; \ | |
| 42072 | }) | |
| 42073 | #else | |
| 42074 | #define vfms_lane_f16(__p0_5, __p1_5, __p2_5, __p3_5) __extension__ ({ \ | |
| 42075 | float16x4_t __s0_5 = __p0_5; \ | |
| 42076 | float16x4_t __s1_5 = __p1_5; \ | |
| 42077 | float16x4_t __s2_5 = __p2_5; \ | |
| 42078 | float16x4_t __rev0_5; __rev0_5 = __builtin_shufflevector(__s0_5, __s0_5, 3, 2, 1, 0); \ | |
| 42079 | float16x4_t __rev1_5; __rev1_5 = __builtin_shufflevector(__s1_5, __s1_5, 3, 2, 1, 0); \ | |
| 42080 | float16x4_t __rev2_5; __rev2_5 = __builtin_shufflevector(__s2_5, __s2_5, 3, 2, 1, 0); \ | |
| 42081 | float16x4_t __ret_5; \ | |
| 42082 | __ret_5 = __noswap_vfma_lane_f16(__rev0_5, -__rev1_5, __rev2_5, __p3_5); \ | |
| 42083 | __ret_5 = __builtin_shufflevector(__ret_5, __ret_5, 3, 2, 1, 0); \ | |
| 42084 | __ret_5; \ | |
| 42085 | }) | |
| 42086 | #endif | |
| 42087 | ||
| 42088 | #ifdef __LITTLE_ENDIAN__ | |
| 42089 | #define vfmsh_laneq_f16(__p0_6, __p1_6, __p2_6, __p3_6) __extension__ ({ \ | |
| 42090 | float16_t __s0_6 = __p0_6; \ | |
| 42091 | float16_t __s1_6 = __p1_6; \ | |
| 42092 | float16x8_t __s2_6 = __p2_6; \ | |
| 42093 | float16_t __ret_6; \ | |
| 42094 | __ret_6 = vfmah_laneq_f16(__s0_6, -__s1_6, __s2_6, __p3_6); \ | |
| 42095 | __ret_6; \ | |
| 42096 | }) | |
| 42097 | #else | |
| 42098 | #define vfmsh_laneq_f16(__p0_7, __p1_7, __p2_7, __p3_7) __extension__ ({ \ | |
| 42099 | float16_t __s0_7 = __p0_7; \ | |
| 42100 | float16_t __s1_7 = __p1_7; \ | |
| 42101 | float16x8_t __s2_7 = __p2_7; \ | |
| 42102 | float16x8_t __rev2_7; __rev2_7 = __builtin_shufflevector(__s2_7, __s2_7, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42103 | float16_t __ret_7; \ | |
| 42104 | __ret_7 = __noswap_vfmah_laneq_f16(__s0_7, -__s1_7, __rev2_7, __p3_7); \ | |
| 42105 | __ret_7; \ | |
| 42106 | }) | |
| 42107 | #endif | |
| 42108 | ||
| 42109 | #ifdef __LITTLE_ENDIAN__ | |
| 42110 | #define vfmsq_laneq_f16(__p0_8, __p1_8, __p2_8, __p3_8) __extension__ ({ \ | |
| 42111 | float16x8_t __s0_8 = __p0_8; \ | |
| 42112 | float16x8_t __s1_8 = __p1_8; \ | |
| 42113 | float16x8_t __s2_8 = __p2_8; \ | |
| 42114 | float16x8_t __ret_8; \ | |
| 42115 | __ret_8 = vfmaq_laneq_f16(__s0_8, -__s1_8, __s2_8, __p3_8); \ | |
| 42116 | __ret_8; \ | |
| 42117 | }) | |
| 42118 | #else | |
| 42119 | #define vfmsq_laneq_f16(__p0_9, __p1_9, __p2_9, __p3_9) __extension__ ({ \ | |
| 42120 | float16x8_t __s0_9 = __p0_9; \ | |
| 42121 | float16x8_t __s1_9 = __p1_9; \ | |
| 42122 | float16x8_t __s2_9 = __p2_9; \ | |
| 42123 | float16x8_t __rev0_9; __rev0_9 = __builtin_shufflevector(__s0_9, __s0_9, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42124 | float16x8_t __rev1_9; __rev1_9 = __builtin_shufflevector(__s1_9, __s1_9, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42125 | float16x8_t __rev2_9; __rev2_9 = __builtin_shufflevector(__s2_9, __s2_9, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42126 | float16x8_t __ret_9; \ | |
| 42127 | __ret_9 = __noswap_vfmaq_laneq_f16(__rev0_9, -__rev1_9, __rev2_9, __p3_9); \ | |
| 42128 | __ret_9 = __builtin_shufflevector(__ret_9, __ret_9, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42129 | __ret_9; \ | |
| 42130 | }) | |
| 42131 | #endif | |
| 42132 | ||
| 42133 | #ifdef __LITTLE_ENDIAN__ | |
| 42134 | #define vfms_laneq_f16(__p0_10, __p1_10, __p2_10, __p3_10) __extension__ ({ \ | |
| 42135 | float16x4_t __s0_10 = __p0_10; \ | |
| 42136 | float16x4_t __s1_10 = __p1_10; \ | |
| 42137 | float16x8_t __s2_10 = __p2_10; \ | |
| 42138 | float16x4_t __ret_10; \ | |
| 42139 | __ret_10 = vfma_laneq_f16(__s0_10, -__s1_10, __s2_10, __p3_10); \ | |
| 42140 | __ret_10; \ | |
| 42141 | }) | |
| 42142 | #else | |
| 42143 | #define vfms_laneq_f16(__p0_11, __p1_11, __p2_11, __p3_11) __extension__ ({ \ | |
| 42144 | float16x4_t __s0_11 = __p0_11; \ | |
| 42145 | float16x4_t __s1_11 = __p1_11; \ | |
| 42146 | float16x8_t __s2_11 = __p2_11; \ | |
| 42147 | float16x4_t __rev0_11; __rev0_11 = __builtin_shufflevector(__s0_11, __s0_11, 3, 2, 1, 0); \ | |
| 42148 | float16x4_t __rev1_11; __rev1_11 = __builtin_shufflevector(__s1_11, __s1_11, 3, 2, 1, 0); \ | |
| 42149 | float16x8_t __rev2_11; __rev2_11 = __builtin_shufflevector(__s2_11, __s2_11, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42150 | float16x4_t __ret_11; \ | |
| 42151 | __ret_11 = __noswap_vfma_laneq_f16(__rev0_11, -__rev1_11, __rev2_11, __p3_11); \ | |
| 42152 | __ret_11 = __builtin_shufflevector(__ret_11, __ret_11, 3, 2, 1, 0); \ | |
| 42153 | __ret_11; \ | |
| 42154 | }) | |
| 42155 | #endif | |
| 42156 | ||
| 42157 | #ifdef __LITTLE_ENDIAN__ | |
| 42158 | #define vfmsq_n_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42159 | float16x8_t __s0 = __p0; \ | |
| 42160 | float16x8_t __s1 = __p1; \ | |
| 42161 | float16_t __s2 = __p2; \ | |
| 42162 | float16x8_t __ret; \ | |
| 42163 | __ret = vfmaq_f16(__s0, -__s1, (float16x8_t) {__s2, __s2, __s2, __s2, __s2, __s2, __s2, __s2}); \ | |
| 42164 | __ret; \ | |
| 42165 | }) | |
| 42166 | #else | |
| 42167 | #define vfmsq_n_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42168 | float16x8_t __s0 = __p0; \ | |
| 42169 | float16x8_t __s1 = __p1; \ | |
| 42170 | float16_t __s2 = __p2; \ | |
| 42171 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42172 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42173 | float16x8_t __ret; \ | |
| 42174 | __ret = __noswap_vfmaq_f16(__rev0, -__rev1, (float16x8_t) {__s2, __s2, __s2, __s2, __s2, __s2, __s2, __s2}); \ | |
| 42175 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42176 | __ret; \ | |
| 42177 | }) | |
| 42178 | #endif | |
| 42179 | ||
| 42180 | #ifdef __LITTLE_ENDIAN__ | |
| 42181 | #define vfms_n_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42182 | float16x4_t __s0 = __p0; \ | |
| 42183 | float16x4_t __s1 = __p1; \ | |
| 42184 | float16_t __s2 = __p2; \ | |
| 42185 | float16x4_t __ret; \ | |
| 42186 | __ret = vfma_f16(__s0, -__s1, (float16x4_t) {__s2, __s2, __s2, __s2}); \ | |
| 42187 | __ret; \ | |
| 42188 | }) | |
| 42189 | #else | |
| 42190 | #define vfms_n_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42191 | float16x4_t __s0 = __p0; \ | |
| 42192 | float16x4_t __s1 = __p1; \ | |
| 42193 | float16_t __s2 = __p2; \ | |
| 42194 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 42195 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \ | |
| 42196 | float16x4_t __ret; \ | |
| 42197 | __ret = __noswap_vfma_f16(__rev0, -__rev1, (float16x4_t) {__s2, __s2, __s2, __s2}); \ | |
| 42198 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 42199 | __ret; \ | |
| 42200 | }) | |
| 42201 | #endif | |
| 42202 | ||
| 42203 | #ifdef __LITTLE_ENDIAN__ | |
| 42204 | __ai float16x8_t vmaxq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42205 | float16x8_t __ret; | |
| 42206 | __ret = (float16x8_t) __builtin_neon_vmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 42207 | return __ret; | |
| 42208 | } | |
| 42209 | #else | |
| 42210 | __ai float16x8_t vmaxq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42211 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42212 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42213 | float16x8_t __ret; | |
| 42214 | __ret = (float16x8_t) __builtin_neon_vmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 42215 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42216 | return __ret; | |
| 42217 | } | |
| 42218 | #endif | |
| 42219 | ||
| 42220 | #ifdef __LITTLE_ENDIAN__ | |
| 42221 | __ai float16x4_t vmax_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42222 | float16x4_t __ret; | |
| 42223 | __ret = (float16x4_t) __builtin_neon_vmax_v((int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 42224 | return __ret; | |
| 42225 | } | |
| 42226 | #else | |
| 42227 | __ai float16x4_t vmax_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42228 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 42229 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 42230 | float16x4_t __ret; | |
| 42231 | __ret = (float16x4_t) __builtin_neon_vmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 42232 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 42233 | return __ret; | |
| 42234 | } | |
| 42235 | #endif | |
| 42236 | ||
| 42237 | #ifdef __LITTLE_ENDIAN__ | |
| 42238 | __ai float16x8_t vmaxnmq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42239 | float16x8_t __ret; | |
| 42240 | __ret = (float16x8_t) __builtin_neon_vmaxnmq_v((int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 42241 | return __ret; | |
| 42242 | } | |
| 42243 | #else | |
| 42244 | __ai float16x8_t vmaxnmq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42245 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42246 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42247 | float16x8_t __ret; | |
| 42248 | __ret = (float16x8_t) __builtin_neon_vmaxnmq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 42249 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42250 | return __ret; | |
| 42251 | } | |
| 42252 | #endif | |
| 42253 | ||
| 42254 | #ifdef __LITTLE_ENDIAN__ | |
| 42255 | __ai float16x4_t vmaxnm_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42256 | float16x4_t __ret; | |
| 42257 | __ret = (float16x4_t) __builtin_neon_vmaxnm_v((int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 42258 | return __ret; | |
| 42259 | } | |
| 42260 | #else | |
| 42261 | __ai float16x4_t vmaxnm_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42262 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 42263 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 42264 | float16x4_t __ret; | |
| 42265 | __ret = (float16x4_t) __builtin_neon_vmaxnm_v((int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 42266 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 42267 | return __ret; | |
| 42268 | } | |
| 42269 | #endif | |
| 42270 | ||
| 42271 | #ifdef __LITTLE_ENDIAN__ | |
| 42272 | #define vmaxnmvq_f16(__p0) __extension__ ({ \ | |
| 42273 | float16x8_t __s0 = __p0; \ | |
| 42274 | float16_t __ret; \ | |
| 42275 | __ret = (float16_t) __builtin_neon_vmaxnmvq_f16((int8x16_t)__s0); \ | |
| 42276 | __ret; \ | |
| 42277 | }) | |
| 42278 | #else | |
| 42279 | #define vmaxnmvq_f16(__p0) __extension__ ({ \ | |
| 42280 | float16x8_t __s0 = __p0; \ | |
| 42281 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42282 | float16_t __ret; \ | |
| 42283 | __ret = (float16_t) __builtin_neon_vmaxnmvq_f16((int8x16_t)__rev0); \ | |
| 42284 | __ret; \ | |
| 42285 | }) | |
| 42286 | #endif | |
| 42287 | ||
| 42288 | #ifdef __LITTLE_ENDIAN__ | |
| 42289 | #define vmaxnmv_f16(__p0) __extension__ ({ \ | |
| 42290 | float16x4_t __s0 = __p0; \ | |
| 42291 | float16_t __ret; \ | |
| 42292 | __ret = (float16_t) __builtin_neon_vmaxnmv_f16((int8x8_t)__s0); \ | |
| 42293 | __ret; \ | |
| 42294 | }) | |
| 42295 | #else | |
| 42296 | #define vmaxnmv_f16(__p0) __extension__ ({ \ | |
| 42297 | float16x4_t __s0 = __p0; \ | |
| 42298 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 42299 | float16_t __ret; \ | |
| 42300 | __ret = (float16_t) __builtin_neon_vmaxnmv_f16((int8x8_t)__rev0); \ | |
| 42301 | __ret; \ | |
| 42302 | }) | |
| 42303 | #endif | |
| 42304 | ||
| 42305 | #ifdef __LITTLE_ENDIAN__ | |
| 42306 | #define vmaxvq_f16(__p0) __extension__ ({ \ | |
| 42307 | float16x8_t __s0 = __p0; \ | |
| 42308 | float16_t __ret; \ | |
| 42309 | __ret = (float16_t) __builtin_neon_vmaxvq_f16((int8x16_t)__s0); \ | |
| 42310 | __ret; \ | |
| 42311 | }) | |
| 42312 | #else | |
| 42313 | #define vmaxvq_f16(__p0) __extension__ ({ \ | |
| 42314 | float16x8_t __s0 = __p0; \ | |
| 42315 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42316 | float16_t __ret; \ | |
| 42317 | __ret = (float16_t) __builtin_neon_vmaxvq_f16((int8x16_t)__rev0); \ | |
| 42318 | __ret; \ | |
| 42319 | }) | |
| 42320 | #endif | |
| 42321 | ||
| 42322 | #ifdef __LITTLE_ENDIAN__ | |
| 42323 | #define vmaxv_f16(__p0) __extension__ ({ \ | |
| 42324 | float16x4_t __s0 = __p0; \ | |
| 42325 | float16_t __ret; \ | |
| 42326 | __ret = (float16_t) __builtin_neon_vmaxv_f16((int8x8_t)__s0); \ | |
| 42327 | __ret; \ | |
| 42328 | }) | |
| 42329 | #else | |
| 42330 | #define vmaxv_f16(__p0) __extension__ ({ \ | |
| 42331 | float16x4_t __s0 = __p0; \ | |
| 42332 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 42333 | float16_t __ret; \ | |
| 42334 | __ret = (float16_t) __builtin_neon_vmaxv_f16((int8x8_t)__rev0); \ | |
| 42335 | __ret; \ | |
| 42336 | }) | |
| 42337 | #endif | |
| 42338 | ||
| 42339 | #ifdef __LITTLE_ENDIAN__ | |
| 42340 | __ai float16x8_t vminq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42341 | float16x8_t __ret; | |
| 42342 | __ret = (float16x8_t) __builtin_neon_vminq_v((int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 42343 | return __ret; | |
| 42344 | } | |
| 42345 | #else | |
| 42346 | __ai float16x8_t vminq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42347 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42348 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42349 | float16x8_t __ret; | |
| 42350 | __ret = (float16x8_t) __builtin_neon_vminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 42351 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42352 | return __ret; | |
| 42353 | } | |
| 42354 | #endif | |
| 42355 | ||
| 42356 | #ifdef __LITTLE_ENDIAN__ | |
| 42357 | __ai float16x4_t vmin_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42358 | float16x4_t __ret; | |
| 42359 | __ret = (float16x4_t) __builtin_neon_vmin_v((int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 42360 | return __ret; | |
| 42361 | } | |
| 42362 | #else | |
| 42363 | __ai float16x4_t vmin_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42364 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 42365 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 42366 | float16x4_t __ret; | |
| 42367 | __ret = (float16x4_t) __builtin_neon_vmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 42368 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 42369 | return __ret; | |
| 42370 | } | |
| 42371 | #endif | |
| 42372 | ||
| 42373 | #ifdef __LITTLE_ENDIAN__ | |
| 42374 | __ai float16x8_t vminnmq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42375 | float16x8_t __ret; | |
| 42376 | __ret = (float16x8_t) __builtin_neon_vminnmq_v((int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 42377 | return __ret; | |
| 42378 | } | |
| 42379 | #else | |
| 42380 | __ai float16x8_t vminnmq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42381 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42382 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42383 | float16x8_t __ret; | |
| 42384 | __ret = (float16x8_t) __builtin_neon_vminnmq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 42385 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42386 | return __ret; | |
| 42387 | } | |
| 42388 | #endif | |
| 42389 | ||
| 42390 | #ifdef __LITTLE_ENDIAN__ | |
| 42391 | __ai float16x4_t vminnm_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42392 | float16x4_t __ret; | |
| 42393 | __ret = (float16x4_t) __builtin_neon_vminnm_v((int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 42394 | return __ret; | |
| 42395 | } | |
| 42396 | #else | |
| 42397 | __ai float16x4_t vminnm_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42398 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 42399 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 42400 | float16x4_t __ret; | |
| 42401 | __ret = (float16x4_t) __builtin_neon_vminnm_v((int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 42402 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 42403 | return __ret; | |
| 42404 | } | |
| 42405 | #endif | |
| 42406 | ||
| 42407 | #ifdef __LITTLE_ENDIAN__ | |
| 42408 | #define vminnmvq_f16(__p0) __extension__ ({ \ | |
| 42409 | float16x8_t __s0 = __p0; \ | |
| 42410 | float16_t __ret; \ | |
| 42411 | __ret = (float16_t) __builtin_neon_vminnmvq_f16((int8x16_t)__s0); \ | |
| 42412 | __ret; \ | |
| 42413 | }) | |
| 42414 | #else | |
| 42415 | #define vminnmvq_f16(__p0) __extension__ ({ \ | |
| 42416 | float16x8_t __s0 = __p0; \ | |
| 42417 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42418 | float16_t __ret; \ | |
| 42419 | __ret = (float16_t) __builtin_neon_vminnmvq_f16((int8x16_t)__rev0); \ | |
| 42420 | __ret; \ | |
| 42421 | }) | |
| 42422 | #endif | |
| 42423 | ||
| 42424 | #ifdef __LITTLE_ENDIAN__ | |
| 42425 | #define vminnmv_f16(__p0) __extension__ ({ \ | |
| 42426 | float16x4_t __s0 = __p0; \ | |
| 42427 | float16_t __ret; \ | |
| 42428 | __ret = (float16_t) __builtin_neon_vminnmv_f16((int8x8_t)__s0); \ | |
| 42429 | __ret; \ | |
| 42430 | }) | |
| 42431 | #else | |
| 42432 | #define vminnmv_f16(__p0) __extension__ ({ \ | |
| 42433 | float16x4_t __s0 = __p0; \ | |
| 42434 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 42435 | float16_t __ret; \ | |
| 42436 | __ret = (float16_t) __builtin_neon_vminnmv_f16((int8x8_t)__rev0); \ | |
| 42437 | __ret; \ | |
| 42438 | }) | |
| 42439 | #endif | |
| 42440 | ||
| 42441 | #ifdef __LITTLE_ENDIAN__ | |
| 42442 | #define vminvq_f16(__p0) __extension__ ({ \ | |
| 42443 | float16x8_t __s0 = __p0; \ | |
| 42444 | float16_t __ret; \ | |
| 42445 | __ret = (float16_t) __builtin_neon_vminvq_f16((int8x16_t)__s0); \ | |
| 42446 | __ret; \ | |
| 42447 | }) | |
| 42448 | #else | |
| 42449 | #define vminvq_f16(__p0) __extension__ ({ \ | |
| 42450 | float16x8_t __s0 = __p0; \ | |
| 42451 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42452 | float16_t __ret; \ | |
| 42453 | __ret = (float16_t) __builtin_neon_vminvq_f16((int8x16_t)__rev0); \ | |
| 42454 | __ret; \ | |
| 42455 | }) | |
| 42456 | #endif | |
| 42457 | ||
| 42458 | #ifdef __LITTLE_ENDIAN__ | |
| 42459 | #define vminv_f16(__p0) __extension__ ({ \ | |
| 42460 | float16x4_t __s0 = __p0; \ | |
| 42461 | float16_t __ret; \ | |
| 42462 | __ret = (float16_t) __builtin_neon_vminv_f16((int8x8_t)__s0); \ | |
| 42463 | __ret; \ | |
| 42464 | }) | |
| 42465 | #else | |
| 42466 | #define vminv_f16(__p0) __extension__ ({ \ | |
| 42467 | float16x4_t __s0 = __p0; \ | |
| 42468 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 42469 | float16_t __ret; \ | |
| 42470 | __ret = (float16_t) __builtin_neon_vminv_f16((int8x8_t)__rev0); \ | |
| 42471 | __ret; \ | |
| 42472 | }) | |
| 42473 | #endif | |
| 42474 | ||
| 42475 | #ifdef __LITTLE_ENDIAN__ | |
| 42476 | __ai float16x8_t vmulq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42477 | float16x8_t __ret; | |
| 42478 | __ret = __p0 * __p1; | |
| 42479 | return __ret; | |
| 42480 | } | |
| 42481 | #else | |
| 42482 | __ai float16x8_t vmulq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42483 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42484 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42485 | float16x8_t __ret; | |
| 42486 | __ret = __rev0 * __rev1; | |
| 42487 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42488 | return __ret; | |
| 42489 | } | |
| 42490 | #endif | |
| 42491 | ||
| 42492 | #ifdef __LITTLE_ENDIAN__ | |
| 42493 | __ai float16x4_t vmul_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42494 | float16x4_t __ret; | |
| 42495 | __ret = __p0 * __p1; | |
| 42496 | return __ret; | |
| 42497 | } | |
| 42498 | #else | |
| 42499 | __ai float16x4_t vmul_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42500 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 42501 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 42502 | float16x4_t __ret; | |
| 42503 | __ret = __rev0 * __rev1; | |
| 42504 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 42505 | return __ret; | |
| 42506 | } | |
| 42507 | #endif | |
| 42508 | ||
| 42509 | #ifdef __LITTLE_ENDIAN__ | |
| 42510 | #define vmulq_lane_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42511 | float16x8_t __s0 = __p0; \ | |
| 42512 | float16x4_t __s1 = __p1; \ | |
| 42513 | float16x8_t __ret; \ | |
| 42514 | __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2); \ | |
| 42515 | __ret; \ | |
| 42516 | }) | |
| 42517 | #else | |
| 42518 | #define vmulq_lane_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42519 | float16x8_t __s0 = __p0; \ | |
| 42520 | float16x4_t __s1 = __p1; \ | |
| 42521 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42522 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \ | |
| 42523 | float16x8_t __ret; \ | |
| 42524 | __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2); \ | |
| 42525 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42526 | __ret; \ | |
| 42527 | }) | |
| 42528 | #endif | |
| 42529 | ||
| 42530 | #ifdef __LITTLE_ENDIAN__ | |
| 42531 | #define vmul_lane_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42532 | float16x4_t __s0 = __p0; \ | |
| 42533 | float16x4_t __s1 = __p1; \ | |
| 42534 | float16x4_t __ret; \ | |
| 42535 | __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2); \ | |
| 42536 | __ret; \ | |
| 42537 | }) | |
| 42538 | #else | |
| 42539 | #define vmul_lane_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42540 | float16x4_t __s0 = __p0; \ | |
| 42541 | float16x4_t __s1 = __p1; \ | |
| 42542 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 42543 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \ | |
| 42544 | float16x4_t __ret; \ | |
| 42545 | __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2); \ | |
| 42546 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 42547 | __ret; \ | |
| 42548 | }) | |
| 42549 | #endif | |
| 42550 | ||
| 42551 | #ifdef __LITTLE_ENDIAN__ | |
| 42552 | #define vmulq_laneq_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42553 | float16x8_t __s0 = __p0; \ | |
| 42554 | float16x8_t __s1 = __p1; \ | |
| 42555 | float16x8_t __ret; \ | |
| 42556 | __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2); \ | |
| 42557 | __ret; \ | |
| 42558 | }) | |
| 42559 | #else | |
| 42560 | #define vmulq_laneq_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42561 | float16x8_t __s0 = __p0; \ | |
| 42562 | float16x8_t __s1 = __p1; \ | |
| 42563 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42564 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42565 | float16x8_t __ret; \ | |
| 42566 | __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2); \ | |
| 42567 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42568 | __ret; \ | |
| 42569 | }) | |
| 42570 | #endif | |
| 42571 | ||
| 42572 | #ifdef __LITTLE_ENDIAN__ | |
| 42573 | #define vmul_laneq_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42574 | float16x4_t __s0 = __p0; \ | |
| 42575 | float16x8_t __s1 = __p1; \ | |
| 42576 | float16x4_t __ret; \ | |
| 42577 | __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2); \ | |
| 42578 | __ret; \ | |
| 42579 | }) | |
| 42580 | #else | |
| 42581 | #define vmul_laneq_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42582 | float16x4_t __s0 = __p0; \ | |
| 42583 | float16x8_t __s1 = __p1; \ | |
| 42584 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 42585 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42586 | float16x4_t __ret; \ | |
| 42587 | __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2); \ | |
| 42588 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 42589 | __ret; \ | |
| 42590 | }) | |
| 42591 | #endif | |
| 42592 | ||
| 42593 | #ifdef __LITTLE_ENDIAN__ | |
| 42594 | #define vmulq_n_f16(__p0, __p1) __extension__ ({ \ | |
| 42595 | float16x8_t __s0 = __p0; \ | |
| 42596 | float16_t __s1 = __p1; \ | |
| 42597 | float16x8_t __ret; \ | |
| 42598 | __ret = __s0 * (float16x8_t) {__s1, __s1, __s1, __s1, __s1, __s1, __s1, __s1}; \ | |
| 42599 | __ret; \ | |
| 42600 | }) | |
| 42601 | #else | |
| 42602 | #define vmulq_n_f16(__p0, __p1) __extension__ ({ \ | |
| 42603 | float16x8_t __s0 = __p0; \ | |
| 42604 | float16_t __s1 = __p1; \ | |
| 42605 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42606 | float16x8_t __ret; \ | |
| 42607 | __ret = __rev0 * (float16x8_t) {__s1, __s1, __s1, __s1, __s1, __s1, __s1, __s1}; \ | |
| 42608 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42609 | __ret; \ | |
| 42610 | }) | |
| 42611 | #endif | |
| 42612 | ||
| 42613 | #ifdef __LITTLE_ENDIAN__ | |
| 42614 | #define vmul_n_f16(__p0, __p1) __extension__ ({ \ | |
| 42615 | float16x4_t __s0 = __p0; \ | |
| 42616 | float16_t __s1 = __p1; \ | |
| 42617 | float16x4_t __ret; \ | |
| 42618 | __ret = __s0 * (float16x4_t) {__s1, __s1, __s1, __s1}; \ | |
| 42619 | __ret; \ | |
| 42620 | }) | |
| 42621 | #else | |
| 42622 | #define vmul_n_f16(__p0, __p1) __extension__ ({ \ | |
| 42623 | float16x4_t __s0 = __p0; \ | |
| 42624 | float16_t __s1 = __p1; \ | |
| 42625 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 42626 | float16x4_t __ret; \ | |
| 42627 | __ret = __rev0 * (float16x4_t) {__s1, __s1, __s1, __s1}; \ | |
| 42628 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 42629 | __ret; \ | |
| 42630 | }) | |
| 42631 | #endif | |
| 42632 | ||
| 42633 | #ifdef __LITTLE_ENDIAN__ | |
| 42634 | __ai float16x8_t vmulxq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42635 | float16x8_t __ret; | |
| 42636 | __ret = (float16x8_t) __builtin_neon_vmulxq_v((int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 42637 | return __ret; | |
| 42638 | } | |
| 42639 | #else | |
| 42640 | __ai float16x8_t vmulxq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42641 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42642 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42643 | float16x8_t __ret; | |
| 42644 | __ret = (float16x8_t) __builtin_neon_vmulxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 42645 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42646 | return __ret; | |
| 42647 | } | |
| 42648 | __ai float16x8_t __noswap_vmulxq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42649 | float16x8_t __ret; | |
| 42650 | __ret = (float16x8_t) __builtin_neon_vmulxq_v((int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 42651 | return __ret; | |
| 42652 | } | |
| 42653 | #endif | |
| 42654 | ||
| 42655 | #ifdef __LITTLE_ENDIAN__ | |
| 42656 | __ai float16x4_t vmulx_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42657 | float16x4_t __ret; | |
| 42658 | __ret = (float16x4_t) __builtin_neon_vmulx_v((int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 42659 | return __ret; | |
| 42660 | } | |
| 42661 | #else | |
| 42662 | __ai float16x4_t vmulx_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42663 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 42664 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 42665 | float16x4_t __ret; | |
| 42666 | __ret = (float16x4_t) __builtin_neon_vmulx_v((int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 42667 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 42668 | return __ret; | |
| 42669 | } | |
| 42670 | __ai float16x4_t __noswap_vmulx_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42671 | float16x4_t __ret; | |
| 42672 | __ret = (float16x4_t) __builtin_neon_vmulx_v((int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 42673 | return __ret; | |
| 42674 | } | |
| 42675 | #endif | |
| 42676 | ||
| 42677 | #ifdef __LITTLE_ENDIAN__ | |
| 42678 | #define vmulxq_lane_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42679 | float16x8_t __s0 = __p0; \ | |
| 42680 | float16x4_t __s1 = __p1; \ | |
| 42681 | float16x8_t __ret; \ | |
| 42682 | __ret = vmulxq_f16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2)); \ | |
| 42683 | __ret; \ | |
| 42684 | }) | |
| 42685 | #else | |
| 42686 | #define vmulxq_lane_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42687 | float16x8_t __s0 = __p0; \ | |
| 42688 | float16x4_t __s1 = __p1; \ | |
| 42689 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42690 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \ | |
| 42691 | float16x8_t __ret; \ | |
| 42692 | __ret = __noswap_vmulxq_f16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2)); \ | |
| 42693 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42694 | __ret; \ | |
| 42695 | }) | |
| 42696 | #endif | |
| 42697 | ||
| 42698 | #ifdef __LITTLE_ENDIAN__ | |
| 42699 | #define vmulx_lane_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42700 | float16x4_t __s0 = __p0; \ | |
| 42701 | float16x4_t __s1 = __p1; \ | |
| 42702 | float16x4_t __ret; \ | |
| 42703 | __ret = vmulx_f16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \ | |
| 42704 | __ret; \ | |
| 42705 | }) | |
| 42706 | #else | |
| 42707 | #define vmulx_lane_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42708 | float16x4_t __s0 = __p0; \ | |
| 42709 | float16x4_t __s1 = __p1; \ | |
| 42710 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 42711 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \ | |
| 42712 | float16x4_t __ret; \ | |
| 42713 | __ret = __noswap_vmulx_f16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \ | |
| 42714 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 42715 | __ret; \ | |
| 42716 | }) | |
| 42717 | #endif | |
| 42718 | ||
| 42719 | #ifdef __LITTLE_ENDIAN__ | |
| 42720 | #define vmulxq_laneq_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42721 | float16x8_t __s0 = __p0; \ | |
| 42722 | float16x8_t __s1 = __p1; \ | |
| 42723 | float16x8_t __ret; \ | |
| 42724 | __ret = vmulxq_f16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2)); \ | |
| 42725 | __ret; \ | |
| 42726 | }) | |
| 42727 | #else | |
| 42728 | #define vmulxq_laneq_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42729 | float16x8_t __s0 = __p0; \ | |
| 42730 | float16x8_t __s1 = __p1; \ | |
| 42731 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42732 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42733 | float16x8_t __ret; \ | |
| 42734 | __ret = __noswap_vmulxq_f16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2)); \ | |
| 42735 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42736 | __ret; \ | |
| 42737 | }) | |
| 42738 | #endif | |
| 42739 | ||
| 42740 | #ifdef __LITTLE_ENDIAN__ | |
| 42741 | #define vmulx_laneq_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42742 | float16x4_t __s0 = __p0; \ | |
| 42743 | float16x8_t __s1 = __p1; \ | |
| 42744 | float16x4_t __ret; \ | |
| 42745 | __ret = vmulx_f16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \ | |
| 42746 | __ret; \ | |
| 42747 | }) | |
| 42748 | #else | |
| 42749 | #define vmulx_laneq_f16(__p0, __p1, __p2) __extension__ ({ \ | |
| 42750 | float16x4_t __s0 = __p0; \ | |
| 42751 | float16x8_t __s1 = __p1; \ | |
| 42752 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 42753 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42754 | float16x4_t __ret; \ | |
| 42755 | __ret = __noswap_vmulx_f16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \ | |
| 42756 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 42757 | __ret; \ | |
| 42758 | }) | |
| 42759 | #endif | |
| 42760 | ||
| 42761 | #ifdef __LITTLE_ENDIAN__ | |
| 42762 | #define vmulxq_n_f16(__p0, __p1) __extension__ ({ \ | |
| 42763 | float16x8_t __s0 = __p0; \ | |
| 42764 | float16_t __s1 = __p1; \ | |
| 42765 | float16x8_t __ret; \ | |
| 42766 | __ret = vmulxq_f16(__s0, (float16x8_t) {__s1, __s1, __s1, __s1, __s1, __s1, __s1, __s1}); \ | |
| 42767 | __ret; \ | |
| 42768 | }) | |
| 42769 | #else | |
| 42770 | #define vmulxq_n_f16(__p0, __p1) __extension__ ({ \ | |
| 42771 | float16x8_t __s0 = __p0; \ | |
| 42772 | float16_t __s1 = __p1; \ | |
| 42773 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42774 | float16x8_t __ret; \ | |
| 42775 | __ret = __noswap_vmulxq_f16(__rev0, (float16x8_t) {__s1, __s1, __s1, __s1, __s1, __s1, __s1, __s1}); \ | |
| 42776 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 42777 | __ret; \ | |
| 42778 | }) | |
| 42779 | #endif | |
| 42780 | ||
| 42781 | #ifdef __LITTLE_ENDIAN__ | |
| 42782 | #define vmulx_n_f16(__p0, __p1) __extension__ ({ \ | |
| 42783 | float16x4_t __s0 = __p0; \ | |
| 42784 | float16_t __s1 = __p1; \ | |
| 42785 | float16x4_t __ret; \ | |
| 42786 | __ret = vmulx_f16(__s0, (float16x4_t) {__s1, __s1, __s1, __s1}); \ | |
| 42787 | __ret; \ | |
| 42788 | }) | |
| 42789 | #else | |
| 42790 | #define vmulx_n_f16(__p0, __p1) __extension__ ({ \ | |
| 42791 | float16x4_t __s0 = __p0; \ | |
| 42792 | float16_t __s1 = __p1; \ | |
| 42793 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \ | |
| 42794 | float16x4_t __ret; \ | |
| 42795 | __ret = __noswap_vmulx_f16(__rev0, (float16x4_t) {__s1, __s1, __s1, __s1}); \ | |
| 42796 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \ | |
| 42797 | __ret; \ | |
| 42798 | }) | |
| 42799 | #endif | |
| 42800 | ||
| 42801 | #ifdef __LITTLE_ENDIAN__ | |
| 42802 | __ai float16x8_t vnegq_f16(float16x8_t __p0) { | |
| 42803 | float16x8_t __ret; | |
| 42804 | __ret = -__p0; | |
| 42805 | return __ret; | |
| 42806 | } | |
| 42807 | #else | |
| 42808 | __ai float16x8_t vnegq_f16(float16x8_t __p0) { | |
| 42809 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42810 | float16x8_t __ret; | |
| 42811 | __ret = -__rev0; | |
| 42812 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42813 | return __ret; | |
| 42814 | } | |
| 42815 | #endif | |
| 42816 | ||
| 42817 | #ifdef __LITTLE_ENDIAN__ | |
| 42818 | __ai float16x4_t vneg_f16(float16x4_t __p0) { | |
| 42819 | float16x4_t __ret; | |
| 42820 | __ret = -__p0; | |
| 42821 | return __ret; | |
| 42822 | } | |
| 42823 | #else | |
| 42824 | __ai float16x4_t vneg_f16(float16x4_t __p0) { | |
| 42825 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 42826 | float16x4_t __ret; | |
| 42827 | __ret = -__rev0; | |
| 42828 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 42829 | return __ret; | |
| 42830 | } | |
| 42831 | #endif | |
| 42832 | ||
| 42833 | #ifdef __LITTLE_ENDIAN__ | |
| 42834 | __ai float16x8_t vpaddq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42835 | float16x8_t __ret; | |
| 42836 | __ret = (float16x8_t) __builtin_neon_vpaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 42837 | return __ret; | |
| 42838 | } | |
| 42839 | #else | |
| 42840 | __ai float16x8_t vpaddq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42841 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42842 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42843 | float16x8_t __ret; | |
| 42844 | __ret = (float16x8_t) __builtin_neon_vpaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 42845 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42846 | return __ret; | |
| 42847 | } | |
| 42848 | #endif | |
| 42849 | ||
| 42850 | #ifdef __LITTLE_ENDIAN__ | |
| 42851 | __ai float16x4_t vpadd_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42852 | float16x4_t __ret; | |
| 42853 | __ret = (float16x4_t) __builtin_neon_vpadd_v((int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 42854 | return __ret; | |
| 42855 | } | |
| 42856 | #else | |
| 42857 | __ai float16x4_t vpadd_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42858 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 42859 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 42860 | float16x4_t __ret; | |
| 42861 | __ret = (float16x4_t) __builtin_neon_vpadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 42862 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 42863 | return __ret; | |
| 42864 | } | |
| 42865 | #endif | |
| 42866 | ||
| 42867 | #ifdef __LITTLE_ENDIAN__ | |
| 42868 | __ai float16x8_t vpmaxq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42869 | float16x8_t __ret; | |
| 42870 | __ret = (float16x8_t) __builtin_neon_vpmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 42871 | return __ret; | |
| 42872 | } | |
| 42873 | #else | |
| 42874 | __ai float16x8_t vpmaxq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42875 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42876 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42877 | float16x8_t __ret; | |
| 42878 | __ret = (float16x8_t) __builtin_neon_vpmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 42879 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42880 | return __ret; | |
| 42881 | } | |
| 42882 | #endif | |
| 42883 | ||
| 42884 | #ifdef __LITTLE_ENDIAN__ | |
| 42885 | __ai float16x4_t vpmax_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42886 | float16x4_t __ret; | |
| 42887 | __ret = (float16x4_t) __builtin_neon_vpmax_v((int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 42888 | return __ret; | |
| 42889 | } | |
| 42890 | #else | |
| 42891 | __ai float16x4_t vpmax_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42892 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 42893 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 42894 | float16x4_t __ret; | |
| 42895 | __ret = (float16x4_t) __builtin_neon_vpmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 42896 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 42897 | return __ret; | |
| 42898 | } | |
| 42899 | #endif | |
| 42900 | ||
| 42901 | #ifdef __LITTLE_ENDIAN__ | |
| 42902 | __ai float16x8_t vpmaxnmq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42903 | float16x8_t __ret; | |
| 42904 | __ret = (float16x8_t) __builtin_neon_vpmaxnmq_v((int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 42905 | return __ret; | |
| 42906 | } | |
| 42907 | #else | |
| 42908 | __ai float16x8_t vpmaxnmq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42909 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42910 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42911 | float16x8_t __ret; | |
| 42912 | __ret = (float16x8_t) __builtin_neon_vpmaxnmq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 42913 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42914 | return __ret; | |
| 42915 | } | |
| 42916 | #endif | |
| 42917 | ||
| 42918 | #ifdef __LITTLE_ENDIAN__ | |
| 42919 | __ai float16x4_t vpmaxnm_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42920 | float16x4_t __ret; | |
| 42921 | __ret = (float16x4_t) __builtin_neon_vpmaxnm_v((int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 42922 | return __ret; | |
| 42923 | } | |
| 42924 | #else | |
| 42925 | __ai float16x4_t vpmaxnm_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42926 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 42927 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 42928 | float16x4_t __ret; | |
| 42929 | __ret = (float16x4_t) __builtin_neon_vpmaxnm_v((int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 42930 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 42931 | return __ret; | |
| 42932 | } | |
| 42933 | #endif | |
| 42934 | ||
| 42935 | #ifdef __LITTLE_ENDIAN__ | |
| 42936 | __ai float16x8_t vpminq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42937 | float16x8_t __ret; | |
| 42938 | __ret = (float16x8_t) __builtin_neon_vpminq_v((int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 42939 | return __ret; | |
| 42940 | } | |
| 42941 | #else | |
| 42942 | __ai float16x8_t vpminq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42943 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42944 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42945 | float16x8_t __ret; | |
| 42946 | __ret = (float16x8_t) __builtin_neon_vpminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 42947 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42948 | return __ret; | |
| 42949 | } | |
| 42950 | #endif | |
| 42951 | ||
| 42952 | #ifdef __LITTLE_ENDIAN__ | |
| 42953 | __ai float16x4_t vpmin_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42954 | float16x4_t __ret; | |
| 42955 | __ret = (float16x4_t) __builtin_neon_vpmin_v((int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 42956 | return __ret; | |
| 42957 | } | |
| 42958 | #else | |
| 42959 | __ai float16x4_t vpmin_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42960 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 42961 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 42962 | float16x4_t __ret; | |
| 42963 | __ret = (float16x4_t) __builtin_neon_vpmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 42964 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 42965 | return __ret; | |
| 42966 | } | |
| 42967 | #endif | |
| 42968 | ||
| 42969 | #ifdef __LITTLE_ENDIAN__ | |
| 42970 | __ai float16x8_t vpminnmq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42971 | float16x8_t __ret; | |
| 42972 | __ret = (float16x8_t) __builtin_neon_vpminnmq_v((int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 42973 | return __ret; | |
| 42974 | } | |
| 42975 | #else | |
| 42976 | __ai float16x8_t vpminnmq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 42977 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42978 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42979 | float16x8_t __ret; | |
| 42980 | __ret = (float16x8_t) __builtin_neon_vpminnmq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 42981 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 42982 | return __ret; | |
| 42983 | } | |
| 42984 | #endif | |
| 42985 | ||
| 42986 | #ifdef __LITTLE_ENDIAN__ | |
| 42987 | __ai float16x4_t vpminnm_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42988 | float16x4_t __ret; | |
| 42989 | __ret = (float16x4_t) __builtin_neon_vpminnm_v((int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 42990 | return __ret; | |
| 42991 | } | |
| 42992 | #else | |
| 42993 | __ai float16x4_t vpminnm_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 42994 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 42995 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 42996 | float16x4_t __ret; | |
| 42997 | __ret = (float16x4_t) __builtin_neon_vpminnm_v((int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 42998 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 42999 | return __ret; | |
| 43000 | } | |
| 43001 | #endif | |
| 43002 | ||
| 43003 | #ifdef __LITTLE_ENDIAN__ | |
| 43004 | __ai float16x8_t vrecpeq_f16(float16x8_t __p0) { | |
| 43005 | float16x8_t __ret; | |
| 43006 | __ret = (float16x8_t) __builtin_neon_vrecpeq_v((int8x16_t)__p0, 40); | |
| 43007 | return __ret; | |
| 43008 | } | |
| 43009 | #else | |
| 43010 | __ai float16x8_t vrecpeq_f16(float16x8_t __p0) { | |
| 43011 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43012 | float16x8_t __ret; | |
| 43013 | __ret = (float16x8_t) __builtin_neon_vrecpeq_v((int8x16_t)__rev0, 40); | |
| 43014 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43015 | return __ret; | |
| 43016 | } | |
| 43017 | #endif | |
| 43018 | ||
| 43019 | #ifdef __LITTLE_ENDIAN__ | |
| 43020 | __ai float16x4_t vrecpe_f16(float16x4_t __p0) { | |
| 43021 | float16x4_t __ret; | |
| 43022 | __ret = (float16x4_t) __builtin_neon_vrecpe_v((int8x8_t)__p0, 8); | |
| 43023 | return __ret; | |
| 43024 | } | |
| 43025 | #else | |
| 43026 | __ai float16x4_t vrecpe_f16(float16x4_t __p0) { | |
| 43027 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43028 | float16x4_t __ret; | |
| 43029 | __ret = (float16x4_t) __builtin_neon_vrecpe_v((int8x8_t)__rev0, 8); | |
| 43030 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43031 | return __ret; | |
| 43032 | } | |
| 43033 | #endif | |
| 43034 | ||
| 43035 | #ifdef __LITTLE_ENDIAN__ | |
| 43036 | __ai float16x8_t vrecpsq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43037 | float16x8_t __ret; | |
| 43038 | __ret = (float16x8_t) __builtin_neon_vrecpsq_v((int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 43039 | return __ret; | |
| 43040 | } | |
| 43041 | #else | |
| 43042 | __ai float16x8_t vrecpsq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43043 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43044 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43045 | float16x8_t __ret; | |
| 43046 | __ret = (float16x8_t) __builtin_neon_vrecpsq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 43047 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43048 | return __ret; | |
| 43049 | } | |
| 43050 | #endif | |
| 43051 | ||
| 43052 | #ifdef __LITTLE_ENDIAN__ | |
| 43053 | __ai float16x4_t vrecps_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43054 | float16x4_t __ret; | |
| 43055 | __ret = (float16x4_t) __builtin_neon_vrecps_v((int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 43056 | return __ret; | |
| 43057 | } | |
| 43058 | #else | |
| 43059 | __ai float16x4_t vrecps_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43060 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43061 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 43062 | float16x4_t __ret; | |
| 43063 | __ret = (float16x4_t) __builtin_neon_vrecps_v((int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 43064 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43065 | return __ret; | |
| 43066 | } | |
| 43067 | #endif | |
| 43068 | ||
| 43069 | #ifdef __LITTLE_ENDIAN__ | |
| 43070 | __ai float16x8_t vrev64q_f16(float16x8_t __p0) { | |
| 43071 | float16x8_t __ret; | |
| 43072 | __ret = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0, 7, 6, 5, 4); | |
| 43073 | return __ret; | |
| 43074 | } | |
| 43075 | #else | |
| 43076 | __ai float16x8_t vrev64q_f16(float16x8_t __p0) { | |
| 43077 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43078 | float16x8_t __ret; | |
| 43079 | __ret = __builtin_shufflevector(__rev0, __rev0, 3, 2, 1, 0, 7, 6, 5, 4); | |
| 43080 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43081 | return __ret; | |
| 43082 | } | |
| 43083 | #endif | |
| 43084 | ||
| 43085 | #ifdef __LITTLE_ENDIAN__ | |
| 43086 | __ai float16x4_t vrev64_f16(float16x4_t __p0) { | |
| 43087 | float16x4_t __ret; | |
| 43088 | __ret = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43089 | return __ret; | |
| 43090 | } | |
| 43091 | #else | |
| 43092 | __ai float16x4_t vrev64_f16(float16x4_t __p0) { | |
| 43093 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43094 | float16x4_t __ret; | |
| 43095 | __ret = __builtin_shufflevector(__rev0, __rev0, 3, 2, 1, 0); | |
| 43096 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43097 | return __ret; | |
| 43098 | } | |
| 43099 | #endif | |
| 43100 | ||
| 43101 | #ifdef __LITTLE_ENDIAN__ | |
| 43102 | __ai float16x8_t vrndq_f16(float16x8_t __p0) { | |
| 43103 | float16x8_t __ret; | |
| 43104 | __ret = (float16x8_t) __builtin_neon_vrndq_v((int8x16_t)__p0, 40); | |
| 43105 | return __ret; | |
| 43106 | } | |
| 43107 | #else | |
| 43108 | __ai float16x8_t vrndq_f16(float16x8_t __p0) { | |
| 43109 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43110 | float16x8_t __ret; | |
| 43111 | __ret = (float16x8_t) __builtin_neon_vrndq_v((int8x16_t)__rev0, 40); | |
| 43112 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43113 | return __ret; | |
| 43114 | } | |
| 43115 | #endif | |
| 43116 | ||
| 43117 | #ifdef __LITTLE_ENDIAN__ | |
| 43118 | __ai float16x4_t vrnd_f16(float16x4_t __p0) { | |
| 43119 | float16x4_t __ret; | |
| 43120 | __ret = (float16x4_t) __builtin_neon_vrnd_v((int8x8_t)__p0, 8); | |
| 43121 | return __ret; | |
| 43122 | } | |
| 43123 | #else | |
| 43124 | __ai float16x4_t vrnd_f16(float16x4_t __p0) { | |
| 43125 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43126 | float16x4_t __ret; | |
| 43127 | __ret = (float16x4_t) __builtin_neon_vrnd_v((int8x8_t)__rev0, 8); | |
| 43128 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43129 | return __ret; | |
| 43130 | } | |
| 43131 | #endif | |
| 43132 | ||
| 43133 | #ifdef __LITTLE_ENDIAN__ | |
| 43134 | __ai float16x8_t vrndaq_f16(float16x8_t __p0) { | |
| 43135 | float16x8_t __ret; | |
| 43136 | __ret = (float16x8_t) __builtin_neon_vrndaq_v((int8x16_t)__p0, 40); | |
| 43137 | return __ret; | |
| 43138 | } | |
| 43139 | #else | |
| 43140 | __ai float16x8_t vrndaq_f16(float16x8_t __p0) { | |
| 43141 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43142 | float16x8_t __ret; | |
| 43143 | __ret = (float16x8_t) __builtin_neon_vrndaq_v((int8x16_t)__rev0, 40); | |
| 43144 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43145 | return __ret; | |
| 43146 | } | |
| 43147 | #endif | |
| 43148 | ||
| 43149 | #ifdef __LITTLE_ENDIAN__ | |
| 43150 | __ai float16x4_t vrnda_f16(float16x4_t __p0) { | |
| 43151 | float16x4_t __ret; | |
| 43152 | __ret = (float16x4_t) __builtin_neon_vrnda_v((int8x8_t)__p0, 8); | |
| 43153 | return __ret; | |
| 43154 | } | |
| 43155 | #else | |
| 43156 | __ai float16x4_t vrnda_f16(float16x4_t __p0) { | |
| 43157 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43158 | float16x4_t __ret; | |
| 43159 | __ret = (float16x4_t) __builtin_neon_vrnda_v((int8x8_t)__rev0, 8); | |
| 43160 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43161 | return __ret; | |
| 43162 | } | |
| 43163 | #endif | |
| 43164 | ||
| 43165 | #ifdef __LITTLE_ENDIAN__ | |
| 43166 | __ai float16x8_t vrndiq_f16(float16x8_t __p0) { | |
| 43167 | float16x8_t __ret; | |
| 43168 | __ret = (float16x8_t) __builtin_neon_vrndiq_v((int8x16_t)__p0, 40); | |
| 43169 | return __ret; | |
| 43170 | } | |
| 43171 | #else | |
| 43172 | __ai float16x8_t vrndiq_f16(float16x8_t __p0) { | |
| 43173 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43174 | float16x8_t __ret; | |
| 43175 | __ret = (float16x8_t) __builtin_neon_vrndiq_v((int8x16_t)__rev0, 40); | |
| 43176 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43177 | return __ret; | |
| 43178 | } | |
| 43179 | #endif | |
| 43180 | ||
| 43181 | #ifdef __LITTLE_ENDIAN__ | |
| 43182 | __ai float16x4_t vrndi_f16(float16x4_t __p0) { | |
| 43183 | float16x4_t __ret; | |
| 43184 | __ret = (float16x4_t) __builtin_neon_vrndi_v((int8x8_t)__p0, 8); | |
| 43185 | return __ret; | |
| 43186 | } | |
| 43187 | #else | |
| 43188 | __ai float16x4_t vrndi_f16(float16x4_t __p0) { | |
| 43189 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43190 | float16x4_t __ret; | |
| 43191 | __ret = (float16x4_t) __builtin_neon_vrndi_v((int8x8_t)__rev0, 8); | |
| 43192 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43193 | return __ret; | |
| 43194 | } | |
| 43195 | #endif | |
| 43196 | ||
| 43197 | #ifdef __LITTLE_ENDIAN__ | |
| 43198 | __ai float16x8_t vrndmq_f16(float16x8_t __p0) { | |
| 43199 | float16x8_t __ret; | |
| 43200 | __ret = (float16x8_t) __builtin_neon_vrndmq_v((int8x16_t)__p0, 40); | |
| 43201 | return __ret; | |
| 43202 | } | |
| 43203 | #else | |
| 43204 | __ai float16x8_t vrndmq_f16(float16x8_t __p0) { | |
| 43205 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43206 | float16x8_t __ret; | |
| 43207 | __ret = (float16x8_t) __builtin_neon_vrndmq_v((int8x16_t)__rev0, 40); | |
| 43208 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43209 | return __ret; | |
| 43210 | } | |
| 43211 | #endif | |
| 43212 | ||
| 43213 | #ifdef __LITTLE_ENDIAN__ | |
| 43214 | __ai float16x4_t vrndm_f16(float16x4_t __p0) { | |
| 43215 | float16x4_t __ret; | |
| 43216 | __ret = (float16x4_t) __builtin_neon_vrndm_v((int8x8_t)__p0, 8); | |
| 43217 | return __ret; | |
| 43218 | } | |
| 43219 | #else | |
| 43220 | __ai float16x4_t vrndm_f16(float16x4_t __p0) { | |
| 43221 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43222 | float16x4_t __ret; | |
| 43223 | __ret = (float16x4_t) __builtin_neon_vrndm_v((int8x8_t)__rev0, 8); | |
| 43224 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43225 | return __ret; | |
| 43226 | } | |
| 43227 | #endif | |
| 43228 | ||
| 43229 | #ifdef __LITTLE_ENDIAN__ | |
| 43230 | __ai float16x8_t vrndnq_f16(float16x8_t __p0) { | |
| 43231 | float16x8_t __ret; | |
| 43232 | __ret = (float16x8_t) __builtin_neon_vrndnq_v((int8x16_t)__p0, 40); | |
| 43233 | return __ret; | |
| 43234 | } | |
| 43235 | #else | |
| 43236 | __ai float16x8_t vrndnq_f16(float16x8_t __p0) { | |
| 43237 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43238 | float16x8_t __ret; | |
| 43239 | __ret = (float16x8_t) __builtin_neon_vrndnq_v((int8x16_t)__rev0, 40); | |
| 43240 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43241 | return __ret; | |
| 43242 | } | |
| 43243 | #endif | |
| 43244 | ||
| 43245 | #ifdef __LITTLE_ENDIAN__ | |
| 43246 | __ai float16x4_t vrndn_f16(float16x4_t __p0) { | |
| 43247 | float16x4_t __ret; | |
| 43248 | __ret = (float16x4_t) __builtin_neon_vrndn_v((int8x8_t)__p0, 8); | |
| 43249 | return __ret; | |
| 43250 | } | |
| 43251 | #else | |
| 43252 | __ai float16x4_t vrndn_f16(float16x4_t __p0) { | |
| 43253 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43254 | float16x4_t __ret; | |
| 43255 | __ret = (float16x4_t) __builtin_neon_vrndn_v((int8x8_t)__rev0, 8); | |
| 43256 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43257 | return __ret; | |
| 43258 | } | |
| 43259 | #endif | |
| 43260 | ||
| 43261 | #ifdef __LITTLE_ENDIAN__ | |
| 43262 | __ai float16x8_t vrndpq_f16(float16x8_t __p0) { | |
| 43263 | float16x8_t __ret; | |
| 43264 | __ret = (float16x8_t) __builtin_neon_vrndpq_v((int8x16_t)__p0, 40); | |
| 43265 | return __ret; | |
| 43266 | } | |
| 43267 | #else | |
| 43268 | __ai float16x8_t vrndpq_f16(float16x8_t __p0) { | |
| 43269 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43270 | float16x8_t __ret; | |
| 43271 | __ret = (float16x8_t) __builtin_neon_vrndpq_v((int8x16_t)__rev0, 40); | |
| 43272 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43273 | return __ret; | |
| 43274 | } | |
| 43275 | #endif | |
| 43276 | ||
| 43277 | #ifdef __LITTLE_ENDIAN__ | |
| 43278 | __ai float16x4_t vrndp_f16(float16x4_t __p0) { | |
| 43279 | float16x4_t __ret; | |
| 43280 | __ret = (float16x4_t) __builtin_neon_vrndp_v((int8x8_t)__p0, 8); | |
| 43281 | return __ret; | |
| 43282 | } | |
| 43283 | #else | |
| 43284 | __ai float16x4_t vrndp_f16(float16x4_t __p0) { | |
| 43285 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43286 | float16x4_t __ret; | |
| 43287 | __ret = (float16x4_t) __builtin_neon_vrndp_v((int8x8_t)__rev0, 8); | |
| 43288 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43289 | return __ret; | |
| 43290 | } | |
| 43291 | #endif | |
| 43292 | ||
| 43293 | #ifdef __LITTLE_ENDIAN__ | |
| 43294 | __ai float16x8_t vrndxq_f16(float16x8_t __p0) { | |
| 43295 | float16x8_t __ret; | |
| 43296 | __ret = (float16x8_t) __builtin_neon_vrndxq_v((int8x16_t)__p0, 40); | |
| 43297 | return __ret; | |
| 43298 | } | |
| 43299 | #else | |
| 43300 | __ai float16x8_t vrndxq_f16(float16x8_t __p0) { | |
| 43301 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43302 | float16x8_t __ret; | |
| 43303 | __ret = (float16x8_t) __builtin_neon_vrndxq_v((int8x16_t)__rev0, 40); | |
| 43304 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43305 | return __ret; | |
| 43306 | } | |
| 43307 | #endif | |
| 43308 | ||
| 43309 | #ifdef __LITTLE_ENDIAN__ | |
| 43310 | __ai float16x4_t vrndx_f16(float16x4_t __p0) { | |
| 43311 | float16x4_t __ret; | |
| 43312 | __ret = (float16x4_t) __builtin_neon_vrndx_v((int8x8_t)__p0, 8); | |
| 43313 | return __ret; | |
| 43314 | } | |
| 43315 | #else | |
| 43316 | __ai float16x4_t vrndx_f16(float16x4_t __p0) { | |
| 43317 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43318 | float16x4_t __ret; | |
| 43319 | __ret = (float16x4_t) __builtin_neon_vrndx_v((int8x8_t)__rev0, 8); | |
| 43320 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43321 | return __ret; | |
| 43322 | } | |
| 43323 | #endif | |
| 43324 | ||
| 43325 | #ifdef __LITTLE_ENDIAN__ | |
| 43326 | __ai float16x8_t vrsqrteq_f16(float16x8_t __p0) { | |
| 43327 | float16x8_t __ret; | |
| 43328 | __ret = (float16x8_t) __builtin_neon_vrsqrteq_v((int8x16_t)__p0, 40); | |
| 43329 | return __ret; | |
| 43330 | } | |
| 43331 | #else | |
| 43332 | __ai float16x8_t vrsqrteq_f16(float16x8_t __p0) { | |
| 43333 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43334 | float16x8_t __ret; | |
| 43335 | __ret = (float16x8_t) __builtin_neon_vrsqrteq_v((int8x16_t)__rev0, 40); | |
| 43336 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43337 | return __ret; | |
| 43338 | } | |
| 43339 | #endif | |
| 43340 | ||
| 43341 | #ifdef __LITTLE_ENDIAN__ | |
| 43342 | __ai float16x4_t vrsqrte_f16(float16x4_t __p0) { | |
| 43343 | float16x4_t __ret; | |
| 43344 | __ret = (float16x4_t) __builtin_neon_vrsqrte_v((int8x8_t)__p0, 8); | |
| 43345 | return __ret; | |
| 43346 | } | |
| 43347 | #else | |
| 43348 | __ai float16x4_t vrsqrte_f16(float16x4_t __p0) { | |
| 43349 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43350 | float16x4_t __ret; | |
| 43351 | __ret = (float16x4_t) __builtin_neon_vrsqrte_v((int8x8_t)__rev0, 8); | |
| 43352 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43353 | return __ret; | |
| 43354 | } | |
| 43355 | #endif | |
| 43356 | ||
| 43357 | #ifdef __LITTLE_ENDIAN__ | |
| 43358 | __ai float16x8_t vrsqrtsq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43359 | float16x8_t __ret; | |
| 43360 | __ret = (float16x8_t) __builtin_neon_vrsqrtsq_v((int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 43361 | return __ret; | |
| 43362 | } | |
| 43363 | #else | |
| 43364 | __ai float16x8_t vrsqrtsq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43365 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43366 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43367 | float16x8_t __ret; | |
| 43368 | __ret = (float16x8_t) __builtin_neon_vrsqrtsq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 43369 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43370 | return __ret; | |
| 43371 | } | |
| 43372 | #endif | |
| 43373 | ||
| 43374 | #ifdef __LITTLE_ENDIAN__ | |
| 43375 | __ai float16x4_t vrsqrts_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43376 | float16x4_t __ret; | |
| 43377 | __ret = (float16x4_t) __builtin_neon_vrsqrts_v((int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 43378 | return __ret; | |
| 43379 | } | |
| 43380 | #else | |
| 43381 | __ai float16x4_t vrsqrts_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43382 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43383 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 43384 | float16x4_t __ret; | |
| 43385 | __ret = (float16x4_t) __builtin_neon_vrsqrts_v((int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 43386 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43387 | return __ret; | |
| 43388 | } | |
| 43389 | #endif | |
| 43390 | ||
| 43391 | #ifdef __LITTLE_ENDIAN__ | |
| 43392 | __ai float16x8_t vsqrtq_f16(float16x8_t __p0) { | |
| 43393 | float16x8_t __ret; | |
| 43394 | __ret = (float16x8_t) __builtin_neon_vsqrtq_v((int8x16_t)__p0, 40); | |
| 43395 | return __ret; | |
| 43396 | } | |
| 43397 | #else | |
| 43398 | __ai float16x8_t vsqrtq_f16(float16x8_t __p0) { | |
| 43399 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43400 | float16x8_t __ret; | |
| 43401 | __ret = (float16x8_t) __builtin_neon_vsqrtq_v((int8x16_t)__rev0, 40); | |
| 43402 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43403 | return __ret; | |
| 43404 | } | |
| 43405 | #endif | |
| 43406 | ||
| 43407 | #ifdef __LITTLE_ENDIAN__ | |
| 43408 | __ai float16x4_t vsqrt_f16(float16x4_t __p0) { | |
| 43409 | float16x4_t __ret; | |
| 43410 | __ret = (float16x4_t) __builtin_neon_vsqrt_v((int8x8_t)__p0, 8); | |
| 43411 | return __ret; | |
| 43412 | } | |
| 43413 | #else | |
| 43414 | __ai float16x4_t vsqrt_f16(float16x4_t __p0) { | |
| 43415 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43416 | float16x4_t __ret; | |
| 43417 | __ret = (float16x4_t) __builtin_neon_vsqrt_v((int8x8_t)__rev0, 8); | |
| 43418 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43419 | return __ret; | |
| 43420 | } | |
| 43421 | #endif | |
| 43422 | ||
| 43423 | #ifdef __LITTLE_ENDIAN__ | |
| 43424 | __ai float16x8_t vsubq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43425 | float16x8_t __ret; | |
| 43426 | __ret = __p0 - __p1; | |
| 43427 | return __ret; | |
| 43428 | } | |
| 43429 | #else | |
| 43430 | __ai float16x8_t vsubq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43431 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43432 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43433 | float16x8_t __ret; | |
| 43434 | __ret = __rev0 - __rev1; | |
| 43435 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43436 | return __ret; | |
| 43437 | } | |
| 43438 | #endif | |
| 43439 | ||
| 43440 | #ifdef __LITTLE_ENDIAN__ | |
| 43441 | __ai float16x4_t vsub_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43442 | float16x4_t __ret; | |
| 43443 | __ret = __p0 - __p1; | |
| 43444 | return __ret; | |
| 43445 | } | |
| 43446 | #else | |
| 43447 | __ai float16x4_t vsub_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43448 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43449 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 43450 | float16x4_t __ret; | |
| 43451 | __ret = __rev0 - __rev1; | |
| 43452 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43453 | return __ret; | |
| 43454 | } | |
| 43455 | #endif | |
| 43456 | ||
| 43457 | #ifdef __LITTLE_ENDIAN__ | |
| 43458 | __ai float16x8x2_t vtrnq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43459 | float16x8x2_t __ret; | |
| 43460 | __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 43461 | return __ret; | |
| 43462 | } | |
| 43463 | #else | |
| 43464 | __ai float16x8x2_t vtrnq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43465 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43466 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43467 | float16x8x2_t __ret; | |
| 43468 | __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 43469 | ||
| 43470 | __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43471 | __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43472 | return __ret; | |
| 43473 | } | |
| 43474 | #endif | |
| 43475 | ||
| 43476 | #ifdef __LITTLE_ENDIAN__ | |
| 43477 | __ai float16x4x2_t vtrn_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43478 | float16x4x2_t __ret; | |
| 43479 | __builtin_neon_vtrn_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 43480 | return __ret; | |
| 43481 | } | |
| 43482 | #else | |
| 43483 | __ai float16x4x2_t vtrn_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43484 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43485 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 43486 | float16x4x2_t __ret; | |
| 43487 | __builtin_neon_vtrn_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 43488 | ||
| 43489 | __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); | |
| 43490 | __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); | |
| 43491 | return __ret; | |
| 43492 | } | |
| 43493 | #endif | |
| 43494 | ||
| 43495 | #ifdef __LITTLE_ENDIAN__ | |
| 43496 | __ai float16x8_t vtrn1q_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43497 | float16x8_t __ret; | |
| 43498 | __ret = __builtin_shufflevector(__p0, __p1, 0, 8, 2, 10, 4, 12, 6, 14); | |
| 43499 | return __ret; | |
| 43500 | } | |
| 43501 | #else | |
| 43502 | __ai float16x8_t vtrn1q_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43503 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43504 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43505 | float16x8_t __ret; | |
| 43506 | __ret = __builtin_shufflevector(__rev0, __rev1, 0, 8, 2, 10, 4, 12, 6, 14); | |
| 43507 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43508 | return __ret; | |
| 43509 | } | |
| 43510 | #endif | |
| 43511 | ||
| 43512 | #ifdef __LITTLE_ENDIAN__ | |
| 43513 | __ai float16x4_t vtrn1_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43514 | float16x4_t __ret; | |
| 43515 | __ret = __builtin_shufflevector(__p0, __p1, 0, 4, 2, 6); | |
| 43516 | return __ret; | |
| 43517 | } | |
| 43518 | #else | |
| 43519 | __ai float16x4_t vtrn1_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43520 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43521 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 43522 | float16x4_t __ret; | |
| 43523 | __ret = __builtin_shufflevector(__rev0, __rev1, 0, 4, 2, 6); | |
| 43524 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43525 | return __ret; | |
| 43526 | } | |
| 43527 | #endif | |
| 43528 | ||
| 43529 | #ifdef __LITTLE_ENDIAN__ | |
| 43530 | __ai float16x8_t vtrn2q_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43531 | float16x8_t __ret; | |
| 43532 | __ret = __builtin_shufflevector(__p0, __p1, 1, 9, 3, 11, 5, 13, 7, 15); | |
| 43533 | return __ret; | |
| 43534 | } | |
| 43535 | #else | |
| 43536 | __ai float16x8_t vtrn2q_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43537 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43538 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43539 | float16x8_t __ret; | |
| 43540 | __ret = __builtin_shufflevector(__rev0, __rev1, 1, 9, 3, 11, 5, 13, 7, 15); | |
| 43541 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43542 | return __ret; | |
| 43543 | } | |
| 43544 | #endif | |
| 43545 | ||
| 43546 | #ifdef __LITTLE_ENDIAN__ | |
| 43547 | __ai float16x4_t vtrn2_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43548 | float16x4_t __ret; | |
| 43549 | __ret = __builtin_shufflevector(__p0, __p1, 1, 5, 3, 7); | |
| 43550 | return __ret; | |
| 43551 | } | |
| 43552 | #else | |
| 43553 | __ai float16x4_t vtrn2_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43554 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43555 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 43556 | float16x4_t __ret; | |
| 43557 | __ret = __builtin_shufflevector(__rev0, __rev1, 1, 5, 3, 7); | |
| 43558 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43559 | return __ret; | |
| 43560 | } | |
| 43561 | #endif | |
| 43562 | ||
| 43563 | #ifdef __LITTLE_ENDIAN__ | |
| 43564 | __ai float16x8x2_t vuzpq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43565 | float16x8x2_t __ret; | |
| 43566 | __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 43567 | return __ret; | |
| 43568 | } | |
| 43569 | #else | |
| 43570 | __ai float16x8x2_t vuzpq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43571 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43572 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43573 | float16x8x2_t __ret; | |
| 43574 | __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 43575 | ||
| 43576 | __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43577 | __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43578 | return __ret; | |
| 43579 | } | |
| 43580 | #endif | |
| 43581 | ||
| 43582 | #ifdef __LITTLE_ENDIAN__ | |
| 43583 | __ai float16x4x2_t vuzp_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43584 | float16x4x2_t __ret; | |
| 43585 | __builtin_neon_vuzp_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 43586 | return __ret; | |
| 43587 | } | |
| 43588 | #else | |
| 43589 | __ai float16x4x2_t vuzp_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43590 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43591 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 43592 | float16x4x2_t __ret; | |
| 43593 | __builtin_neon_vuzp_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 43594 | ||
| 43595 | __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); | |
| 43596 | __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); | |
| 43597 | return __ret; | |
| 43598 | } | |
| 43599 | #endif | |
| 43600 | ||
| 43601 | #ifdef __LITTLE_ENDIAN__ | |
| 43602 | __ai float16x8_t vuzp1q_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43603 | float16x8_t __ret; | |
| 43604 | __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6, 8, 10, 12, 14); | |
| 43605 | return __ret; | |
| 43606 | } | |
| 43607 | #else | |
| 43608 | __ai float16x8_t vuzp1q_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43609 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43610 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43611 | float16x8_t __ret; | |
| 43612 | __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6, 8, 10, 12, 14); | |
| 43613 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43614 | return __ret; | |
| 43615 | } | |
| 43616 | #endif | |
| 43617 | ||
| 43618 | #ifdef __LITTLE_ENDIAN__ | |
| 43619 | __ai float16x4_t vuzp1_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43620 | float16x4_t __ret; | |
| 43621 | __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6); | |
| 43622 | return __ret; | |
| 43623 | } | |
| 43624 | #else | |
| 43625 | __ai float16x4_t vuzp1_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43626 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43627 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 43628 | float16x4_t __ret; | |
| 43629 | __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6); | |
| 43630 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43631 | return __ret; | |
| 43632 | } | |
| 43633 | #endif | |
| 43634 | ||
| 43635 | #ifdef __LITTLE_ENDIAN__ | |
| 43636 | __ai float16x8_t vuzp2q_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43637 | float16x8_t __ret; | |
| 43638 | __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7, 9, 11, 13, 15); | |
| 43639 | return __ret; | |
| 43640 | } | |
| 43641 | #else | |
| 43642 | __ai float16x8_t vuzp2q_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43643 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43644 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43645 | float16x8_t __ret; | |
| 43646 | __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7, 9, 11, 13, 15); | |
| 43647 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43648 | return __ret; | |
| 43649 | } | |
| 43650 | #endif | |
| 43651 | ||
| 43652 | #ifdef __LITTLE_ENDIAN__ | |
| 43653 | __ai float16x4_t vuzp2_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43654 | float16x4_t __ret; | |
| 43655 | __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7); | |
| 43656 | return __ret; | |
| 43657 | } | |
| 43658 | #else | |
| 43659 | __ai float16x4_t vuzp2_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43660 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43661 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 43662 | float16x4_t __ret; | |
| 43663 | __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7); | |
| 43664 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43665 | return __ret; | |
| 43666 | } | |
| 43667 | #endif | |
| 43668 | ||
| 43669 | #ifdef __LITTLE_ENDIAN__ | |
| 43670 | __ai float16x8x2_t vzipq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43671 | float16x8x2_t __ret; | |
| 43672 | __builtin_neon_vzipq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 40); | |
| 43673 | return __ret; | |
| 43674 | } | |
| 43675 | #else | |
| 43676 | __ai float16x8x2_t vzipq_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43677 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43678 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43679 | float16x8x2_t __ret; | |
| 43680 | __builtin_neon_vzipq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 40); | |
| 43681 | ||
| 43682 | __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43683 | __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43684 | return __ret; | |
| 43685 | } | |
| 43686 | #endif | |
| 43687 | ||
| 43688 | #ifdef __LITTLE_ENDIAN__ | |
| 43689 | __ai float16x4x2_t vzip_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43690 | float16x4x2_t __ret; | |
| 43691 | __builtin_neon_vzip_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 8); | |
| 43692 | return __ret; | |
| 43693 | } | |
| 43694 | #else | |
| 43695 | __ai float16x4x2_t vzip_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43696 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43697 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 43698 | float16x4x2_t __ret; | |
| 43699 | __builtin_neon_vzip_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 8); | |
| 43700 | ||
| 43701 | __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); | |
| 43702 | __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); | |
| 43703 | return __ret; | |
| 43704 | } | |
| 43705 | #endif | |
| 43706 | ||
| 43707 | #ifdef __LITTLE_ENDIAN__ | |
| 43708 | __ai float16x8_t vzip1q_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43709 | float16x8_t __ret; | |
| 43710 | __ret = __builtin_shufflevector(__p0, __p1, 0, 8, 1, 9, 2, 10, 3, 11); | |
| 43711 | return __ret; | |
| 43712 | } | |
| 43713 | #else | |
| 43714 | __ai float16x8_t vzip1q_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43715 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43716 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43717 | float16x8_t __ret; | |
| 43718 | __ret = __builtin_shufflevector(__rev0, __rev1, 0, 8, 1, 9, 2, 10, 3, 11); | |
| 43719 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43720 | return __ret; | |
| 43721 | } | |
| 43722 | #endif | |
| 43723 | ||
| 43724 | #ifdef __LITTLE_ENDIAN__ | |
| 43725 | __ai float16x4_t vzip1_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43726 | float16x4_t __ret; | |
| 43727 | __ret = __builtin_shufflevector(__p0, __p1, 0, 4, 1, 5); | |
| 43728 | return __ret; | |
| 43729 | } | |
| 43730 | #else | |
| 43731 | __ai float16x4_t vzip1_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43732 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43733 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 43734 | float16x4_t __ret; | |
| 43735 | __ret = __builtin_shufflevector(__rev0, __rev1, 0, 4, 1, 5); | |
| 43736 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43737 | return __ret; | |
| 43738 | } | |
| 43739 | #endif | |
| 43740 | ||
| 43741 | #ifdef __LITTLE_ENDIAN__ | |
| 43742 | __ai float16x8_t vzip2q_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43743 | float16x8_t __ret; | |
| 43744 | __ret = __builtin_shufflevector(__p0, __p1, 4, 12, 5, 13, 6, 14, 7, 15); | |
| 43745 | return __ret; | |
| 43746 | } | |
| 43747 | #else | |
| 43748 | __ai float16x8_t vzip2q_f16(float16x8_t __p0, float16x8_t __p1) { | |
| 43749 | float16x8_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43750 | float16x8_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43751 | float16x8_t __ret; | |
| 43752 | __ret = __builtin_shufflevector(__rev0, __rev1, 4, 12, 5, 13, 6, 14, 7, 15); | |
| 43753 | __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 43754 | return __ret; | |
| 43755 | } | |
| 43756 | #endif | |
| 43757 | ||
| 43758 | #ifdef __LITTLE_ENDIAN__ | |
| 43759 | __ai float16x4_t vzip2_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43760 | float16x4_t __ret; | |
| 43761 | __ret = __builtin_shufflevector(__p0, __p1, 2, 6, 3, 7); | |
| 43762 | return __ret; | |
| 43763 | } | |
| 43764 | #else | |
| 43765 | __ai float16x4_t vzip2_f16(float16x4_t __p0, float16x4_t __p1) { | |
| 43766 | float16x4_t __rev0; __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0); | |
| 43767 | float16x4_t __rev1; __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0); | |
| 43768 | float16x4_t __ret; | |
| 43769 | __ret = __builtin_shufflevector(__rev0, __rev1, 2, 6, 3, 7); | |
| 43770 | __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); | |
| 43771 | return __ret; | |
| 43772 | } | |
| 43773 | #endif | |
| 43774 | ||
| 40463 | 43775 | #endif |
| 40464 | 43776 | #if defined(__ARM_FEATURE_QRDMX) |
| 40465 | 43777 | #ifdef __LITTLE_ENDIAN__ |
| ... | ... | @@ -44220,917 +47532,917 @@ __ai float64x2_t vcombine_f64(float64x1_t __p0, float64x1_t __p1) { |
| 44220 | 47532 | #endif |
| 44221 | 47533 | |
| 44222 | 47534 | #ifdef __LITTLE_ENDIAN__ |
| 44223 | #define vcopyq_lane_p8(__p0_0, __p1_0, __p2_0, __p3_0) __extension__ ({ \ | |
| 44224 | poly8x16_t __s0_0 = __p0_0; \ | |
| 44225 | poly8x8_t __s2_0 = __p2_0; \ | |
| 44226 | poly8x16_t __ret_0; \ | |
| 44227 | __ret_0 = vsetq_lane_p8(vget_lane_p8(__s2_0, __p3_0), __s0_0, __p1_0); \ | |
| 44228 | __ret_0; \ | |
| 44229 | }) | |
| 44230 | #else | |
| 44231 | #define vcopyq_lane_p8(__p0_1, __p1_1, __p2_1, __p3_1) __extension__ ({ \ | |
| 44232 | poly8x16_t __s0_1 = __p0_1; \ | |
| 44233 | poly8x8_t __s2_1 = __p2_1; \ | |
| 44234 | poly8x16_t __rev0_1; __rev0_1 = __builtin_shufflevector(__s0_1, __s0_1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44235 | poly8x8_t __rev2_1; __rev2_1 = __builtin_shufflevector(__s2_1, __s2_1, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44236 | poly8x16_t __ret_1; \ | |
| 44237 | __ret_1 = __noswap_vsetq_lane_p8(__noswap_vget_lane_p8(__rev2_1, __p3_1), __rev0_1, __p1_1); \ | |
| 44238 | __ret_1 = __builtin_shufflevector(__ret_1, __ret_1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44239 | __ret_1; \ | |
| 44240 | }) | |
| 44241 | #endif | |
| 44242 | ||
| 44243 | #ifdef __LITTLE_ENDIAN__ | |
| 44244 | #define vcopyq_lane_p16(__p0_2, __p1_2, __p2_2, __p3_2) __extension__ ({ \ | |
| 44245 | poly16x8_t __s0_2 = __p0_2; \ | |
| 44246 | poly16x4_t __s2_2 = __p2_2; \ | |
| 44247 | poly16x8_t __ret_2; \ | |
| 44248 | __ret_2 = vsetq_lane_p16(vget_lane_p16(__s2_2, __p3_2), __s0_2, __p1_2); \ | |
| 44249 | __ret_2; \ | |
| 44250 | }) | |
| 44251 | #else | |
| 44252 | #define vcopyq_lane_p16(__p0_3, __p1_3, __p2_3, __p3_3) __extension__ ({ \ | |
| 44253 | poly16x8_t __s0_3 = __p0_3; \ | |
| 44254 | poly16x4_t __s2_3 = __p2_3; \ | |
| 44255 | poly16x8_t __rev0_3; __rev0_3 = __builtin_shufflevector(__s0_3, __s0_3, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44256 | poly16x4_t __rev2_3; __rev2_3 = __builtin_shufflevector(__s2_3, __s2_3, 3, 2, 1, 0); \ | |
| 44257 | poly16x8_t __ret_3; \ | |
| 44258 | __ret_3 = __noswap_vsetq_lane_p16(__noswap_vget_lane_p16(__rev2_3, __p3_3), __rev0_3, __p1_3); \ | |
| 44259 | __ret_3 = __builtin_shufflevector(__ret_3, __ret_3, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44260 | __ret_3; \ | |
| 44261 | }) | |
| 44262 | #endif | |
| 44263 | ||
| 44264 | #ifdef __LITTLE_ENDIAN__ | |
| 44265 | #define vcopyq_lane_u8(__p0_4, __p1_4, __p2_4, __p3_4) __extension__ ({ \ | |
| 44266 | uint8x16_t __s0_4 = __p0_4; \ | |
| 44267 | uint8x8_t __s2_4 = __p2_4; \ | |
| 44268 | uint8x16_t __ret_4; \ | |
| 44269 | __ret_4 = vsetq_lane_u8(vget_lane_u8(__s2_4, __p3_4), __s0_4, __p1_4); \ | |
| 44270 | __ret_4; \ | |
| 44271 | }) | |
| 44272 | #else | |
| 44273 | #define vcopyq_lane_u8(__p0_5, __p1_5, __p2_5, __p3_5) __extension__ ({ \ | |
| 44274 | uint8x16_t __s0_5 = __p0_5; \ | |
| 44275 | uint8x8_t __s2_5 = __p2_5; \ | |
| 44276 | uint8x16_t __rev0_5; __rev0_5 = __builtin_shufflevector(__s0_5, __s0_5, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44277 | uint8x8_t __rev2_5; __rev2_5 = __builtin_shufflevector(__s2_5, __s2_5, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44278 | uint8x16_t __ret_5; \ | |
| 44279 | __ret_5 = __noswap_vsetq_lane_u8(__noswap_vget_lane_u8(__rev2_5, __p3_5), __rev0_5, __p1_5); \ | |
| 44280 | __ret_5 = __builtin_shufflevector(__ret_5, __ret_5, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44281 | __ret_5; \ | |
| 44282 | }) | |
| 44283 | #endif | |
| 44284 | ||
| 44285 | #ifdef __LITTLE_ENDIAN__ | |
| 44286 | #define vcopyq_lane_u32(__p0_6, __p1_6, __p2_6, __p3_6) __extension__ ({ \ | |
| 44287 | uint32x4_t __s0_6 = __p0_6; \ | |
| 44288 | uint32x2_t __s2_6 = __p2_6; \ | |
| 44289 | uint32x4_t __ret_6; \ | |
| 44290 | __ret_6 = vsetq_lane_u32(vget_lane_u32(__s2_6, __p3_6), __s0_6, __p1_6); \ | |
| 44291 | __ret_6; \ | |
| 44292 | }) | |
| 44293 | #else | |
| 44294 | #define vcopyq_lane_u32(__p0_7, __p1_7, __p2_7, __p3_7) __extension__ ({ \ | |
| 44295 | uint32x4_t __s0_7 = __p0_7; \ | |
| 44296 | uint32x2_t __s2_7 = __p2_7; \ | |
| 44297 | uint32x4_t __rev0_7; __rev0_7 = __builtin_shufflevector(__s0_7, __s0_7, 3, 2, 1, 0); \ | |
| 44298 | uint32x2_t __rev2_7; __rev2_7 = __builtin_shufflevector(__s2_7, __s2_7, 1, 0); \ | |
| 44299 | uint32x4_t __ret_7; \ | |
| 44300 | __ret_7 = __noswap_vsetq_lane_u32(__noswap_vget_lane_u32(__rev2_7, __p3_7), __rev0_7, __p1_7); \ | |
| 44301 | __ret_7 = __builtin_shufflevector(__ret_7, __ret_7, 3, 2, 1, 0); \ | |
| 44302 | __ret_7; \ | |
| 44303 | }) | |
| 44304 | #endif | |
| 44305 | ||
| 44306 | #ifdef __LITTLE_ENDIAN__ | |
| 44307 | #define vcopyq_lane_u64(__p0_8, __p1_8, __p2_8, __p3_8) __extension__ ({ \ | |
| 44308 | uint64x2_t __s0_8 = __p0_8; \ | |
| 44309 | uint64x1_t __s2_8 = __p2_8; \ | |
| 44310 | uint64x2_t __ret_8; \ | |
| 44311 | __ret_8 = vsetq_lane_u64(vget_lane_u64(__s2_8, __p3_8), __s0_8, __p1_8); \ | |
| 44312 | __ret_8; \ | |
| 44313 | }) | |
| 44314 | #else | |
| 44315 | #define vcopyq_lane_u64(__p0_9, __p1_9, __p2_9, __p3_9) __extension__ ({ \ | |
| 44316 | uint64x2_t __s0_9 = __p0_9; \ | |
| 44317 | uint64x1_t __s2_9 = __p2_9; \ | |
| 44318 | uint64x2_t __rev0_9; __rev0_9 = __builtin_shufflevector(__s0_9, __s0_9, 1, 0); \ | |
| 44319 | uint64x2_t __ret_9; \ | |
| 44320 | __ret_9 = __noswap_vsetq_lane_u64(__noswap_vget_lane_u64(__s2_9, __p3_9), __rev0_9, __p1_9); \ | |
| 44321 | __ret_9 = __builtin_shufflevector(__ret_9, __ret_9, 1, 0); \ | |
| 44322 | __ret_9; \ | |
| 44323 | }) | |
| 44324 | #endif | |
| 44325 | ||
| 44326 | #ifdef __LITTLE_ENDIAN__ | |
| 44327 | #define vcopyq_lane_u16(__p0_10, __p1_10, __p2_10, __p3_10) __extension__ ({ \ | |
| 44328 | uint16x8_t __s0_10 = __p0_10; \ | |
| 44329 | uint16x4_t __s2_10 = __p2_10; \ | |
| 44330 | uint16x8_t __ret_10; \ | |
| 44331 | __ret_10 = vsetq_lane_u16(vget_lane_u16(__s2_10, __p3_10), __s0_10, __p1_10); \ | |
| 44332 | __ret_10; \ | |
| 44333 | }) | |
| 44334 | #else | |
| 44335 | #define vcopyq_lane_u16(__p0_11, __p1_11, __p2_11, __p3_11) __extension__ ({ \ | |
| 44336 | uint16x8_t __s0_11 = __p0_11; \ | |
| 44337 | uint16x4_t __s2_11 = __p2_11; \ | |
| 44338 | uint16x8_t __rev0_11; __rev0_11 = __builtin_shufflevector(__s0_11, __s0_11, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44339 | uint16x4_t __rev2_11; __rev2_11 = __builtin_shufflevector(__s2_11, __s2_11, 3, 2, 1, 0); \ | |
| 44340 | uint16x8_t __ret_11; \ | |
| 44341 | __ret_11 = __noswap_vsetq_lane_u16(__noswap_vget_lane_u16(__rev2_11, __p3_11), __rev0_11, __p1_11); \ | |
| 44342 | __ret_11 = __builtin_shufflevector(__ret_11, __ret_11, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44343 | __ret_11; \ | |
| 44344 | }) | |
| 44345 | #endif | |
| 44346 | ||
| 44347 | #ifdef __LITTLE_ENDIAN__ | |
| 44348 | #define vcopyq_lane_s8(__p0_12, __p1_12, __p2_12, __p3_12) __extension__ ({ \ | |
| 44349 | int8x16_t __s0_12 = __p0_12; \ | |
| 44350 | int8x8_t __s2_12 = __p2_12; \ | |
| 44351 | int8x16_t __ret_12; \ | |
| 44352 | __ret_12 = vsetq_lane_s8(vget_lane_s8(__s2_12, __p3_12), __s0_12, __p1_12); \ | |
| 47535 | #define vcopyq_lane_p8(__p0_12, __p1_12, __p2_12, __p3_12) __extension__ ({ \ | |
| 47536 | poly8x16_t __s0_12 = __p0_12; \ | |
| 47537 | poly8x8_t __s2_12 = __p2_12; \ | |
| 47538 | poly8x16_t __ret_12; \ | |
| 47539 | __ret_12 = vsetq_lane_p8(vget_lane_p8(__s2_12, __p3_12), __s0_12, __p1_12); \ | |
| 44353 | 47540 | __ret_12; \ |
| 44354 | 47541 | }) |
| 44355 | 47542 | #else |
| 44356 | #define vcopyq_lane_s8(__p0_13, __p1_13, __p2_13, __p3_13) __extension__ ({ \ | |
| 44357 | int8x16_t __s0_13 = __p0_13; \ | |
| 44358 | int8x8_t __s2_13 = __p2_13; \ | |
| 44359 | int8x16_t __rev0_13; __rev0_13 = __builtin_shufflevector(__s0_13, __s0_13, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44360 | int8x8_t __rev2_13; __rev2_13 = __builtin_shufflevector(__s2_13, __s2_13, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44361 | int8x16_t __ret_13; \ | |
| 44362 | __ret_13 = __noswap_vsetq_lane_s8(__noswap_vget_lane_s8(__rev2_13, __p3_13), __rev0_13, __p1_13); \ | |
| 47543 | #define vcopyq_lane_p8(__p0_13, __p1_13, __p2_13, __p3_13) __extension__ ({ \ | |
| 47544 | poly8x16_t __s0_13 = __p0_13; \ | |
| 47545 | poly8x8_t __s2_13 = __p2_13; \ | |
| 47546 | poly8x16_t __rev0_13; __rev0_13 = __builtin_shufflevector(__s0_13, __s0_13, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47547 | poly8x8_t __rev2_13; __rev2_13 = __builtin_shufflevector(__s2_13, __s2_13, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47548 | poly8x16_t __ret_13; \ | |
| 47549 | __ret_13 = __noswap_vsetq_lane_p8(__noswap_vget_lane_p8(__rev2_13, __p3_13), __rev0_13, __p1_13); \ | |
| 44363 | 47550 | __ret_13 = __builtin_shufflevector(__ret_13, __ret_13, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ |
| 44364 | 47551 | __ret_13; \ |
| 44365 | 47552 | }) |
| 44366 | 47553 | #endif |
| 44367 | 47554 | |
| 44368 | 47555 | #ifdef __LITTLE_ENDIAN__ |
| 44369 | #define vcopyq_lane_f32(__p0_14, __p1_14, __p2_14, __p3_14) __extension__ ({ \ | |
| 44370 | float32x4_t __s0_14 = __p0_14; \ | |
| 44371 | float32x2_t __s2_14 = __p2_14; \ | |
| 44372 | float32x4_t __ret_14; \ | |
| 44373 | __ret_14 = vsetq_lane_f32(vget_lane_f32(__s2_14, __p3_14), __s0_14, __p1_14); \ | |
| 47556 | #define vcopyq_lane_p16(__p0_14, __p1_14, __p2_14, __p3_14) __extension__ ({ \ | |
| 47557 | poly16x8_t __s0_14 = __p0_14; \ | |
| 47558 | poly16x4_t __s2_14 = __p2_14; \ | |
| 47559 | poly16x8_t __ret_14; \ | |
| 47560 | __ret_14 = vsetq_lane_p16(vget_lane_p16(__s2_14, __p3_14), __s0_14, __p1_14); \ | |
| 44374 | 47561 | __ret_14; \ |
| 44375 | 47562 | }) |
| 44376 | 47563 | #else |
| 44377 | #define vcopyq_lane_f32(__p0_15, __p1_15, __p2_15, __p3_15) __extension__ ({ \ | |
| 44378 | float32x4_t __s0_15 = __p0_15; \ | |
| 44379 | float32x2_t __s2_15 = __p2_15; \ | |
| 44380 | float32x4_t __rev0_15; __rev0_15 = __builtin_shufflevector(__s0_15, __s0_15, 3, 2, 1, 0); \ | |
| 44381 | float32x2_t __rev2_15; __rev2_15 = __builtin_shufflevector(__s2_15, __s2_15, 1, 0); \ | |
| 44382 | float32x4_t __ret_15; \ | |
| 44383 | __ret_15 = __noswap_vsetq_lane_f32(__noswap_vget_lane_f32(__rev2_15, __p3_15), __rev0_15, __p1_15); \ | |
| 44384 | __ret_15 = __builtin_shufflevector(__ret_15, __ret_15, 3, 2, 1, 0); \ | |
| 47564 | #define vcopyq_lane_p16(__p0_15, __p1_15, __p2_15, __p3_15) __extension__ ({ \ | |
| 47565 | poly16x8_t __s0_15 = __p0_15; \ | |
| 47566 | poly16x4_t __s2_15 = __p2_15; \ | |
| 47567 | poly16x8_t __rev0_15; __rev0_15 = __builtin_shufflevector(__s0_15, __s0_15, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47568 | poly16x4_t __rev2_15; __rev2_15 = __builtin_shufflevector(__s2_15, __s2_15, 3, 2, 1, 0); \ | |
| 47569 | poly16x8_t __ret_15; \ | |
| 47570 | __ret_15 = __noswap_vsetq_lane_p16(__noswap_vget_lane_p16(__rev2_15, __p3_15), __rev0_15, __p1_15); \ | |
| 47571 | __ret_15 = __builtin_shufflevector(__ret_15, __ret_15, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44385 | 47572 | __ret_15; \ |
| 44386 | 47573 | }) |
| 44387 | 47574 | #endif |
| 44388 | 47575 | |
| 44389 | 47576 | #ifdef __LITTLE_ENDIAN__ |
| 44390 | #define vcopyq_lane_s32(__p0_16, __p1_16, __p2_16, __p3_16) __extension__ ({ \ | |
| 44391 | int32x4_t __s0_16 = __p0_16; \ | |
| 44392 | int32x2_t __s2_16 = __p2_16; \ | |
| 44393 | int32x4_t __ret_16; \ | |
| 44394 | __ret_16 = vsetq_lane_s32(vget_lane_s32(__s2_16, __p3_16), __s0_16, __p1_16); \ | |
| 47577 | #define vcopyq_lane_u8(__p0_16, __p1_16, __p2_16, __p3_16) __extension__ ({ \ | |
| 47578 | uint8x16_t __s0_16 = __p0_16; \ | |
| 47579 | uint8x8_t __s2_16 = __p2_16; \ | |
| 47580 | uint8x16_t __ret_16; \ | |
| 47581 | __ret_16 = vsetq_lane_u8(vget_lane_u8(__s2_16, __p3_16), __s0_16, __p1_16); \ | |
| 44395 | 47582 | __ret_16; \ |
| 44396 | 47583 | }) |
| 44397 | 47584 | #else |
| 44398 | #define vcopyq_lane_s32(__p0_17, __p1_17, __p2_17, __p3_17) __extension__ ({ \ | |
| 44399 | int32x4_t __s0_17 = __p0_17; \ | |
| 44400 | int32x2_t __s2_17 = __p2_17; \ | |
| 44401 | int32x4_t __rev0_17; __rev0_17 = __builtin_shufflevector(__s0_17, __s0_17, 3, 2, 1, 0); \ | |
| 44402 | int32x2_t __rev2_17; __rev2_17 = __builtin_shufflevector(__s2_17, __s2_17, 1, 0); \ | |
| 44403 | int32x4_t __ret_17; \ | |
| 44404 | __ret_17 = __noswap_vsetq_lane_s32(__noswap_vget_lane_s32(__rev2_17, __p3_17), __rev0_17, __p1_17); \ | |
| 44405 | __ret_17 = __builtin_shufflevector(__ret_17, __ret_17, 3, 2, 1, 0); \ | |
| 47585 | #define vcopyq_lane_u8(__p0_17, __p1_17, __p2_17, __p3_17) __extension__ ({ \ | |
| 47586 | uint8x16_t __s0_17 = __p0_17; \ | |
| 47587 | uint8x8_t __s2_17 = __p2_17; \ | |
| 47588 | uint8x16_t __rev0_17; __rev0_17 = __builtin_shufflevector(__s0_17, __s0_17, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47589 | uint8x8_t __rev2_17; __rev2_17 = __builtin_shufflevector(__s2_17, __s2_17, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47590 | uint8x16_t __ret_17; \ | |
| 47591 | __ret_17 = __noswap_vsetq_lane_u8(__noswap_vget_lane_u8(__rev2_17, __p3_17), __rev0_17, __p1_17); \ | |
| 47592 | __ret_17 = __builtin_shufflevector(__ret_17, __ret_17, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44406 | 47593 | __ret_17; \ |
| 44407 | 47594 | }) |
| 44408 | 47595 | #endif |
| 44409 | 47596 | |
| 44410 | 47597 | #ifdef __LITTLE_ENDIAN__ |
| 44411 | #define vcopyq_lane_s64(__p0_18, __p1_18, __p2_18, __p3_18) __extension__ ({ \ | |
| 44412 | int64x2_t __s0_18 = __p0_18; \ | |
| 44413 | int64x1_t __s2_18 = __p2_18; \ | |
| 44414 | int64x2_t __ret_18; \ | |
| 44415 | __ret_18 = vsetq_lane_s64(vget_lane_s64(__s2_18, __p3_18), __s0_18, __p1_18); \ | |
| 47598 | #define vcopyq_lane_u32(__p0_18, __p1_18, __p2_18, __p3_18) __extension__ ({ \ | |
| 47599 | uint32x4_t __s0_18 = __p0_18; \ | |
| 47600 | uint32x2_t __s2_18 = __p2_18; \ | |
| 47601 | uint32x4_t __ret_18; \ | |
| 47602 | __ret_18 = vsetq_lane_u32(vget_lane_u32(__s2_18, __p3_18), __s0_18, __p1_18); \ | |
| 44416 | 47603 | __ret_18; \ |
| 44417 | 47604 | }) |
| 44418 | 47605 | #else |
| 44419 | #define vcopyq_lane_s64(__p0_19, __p1_19, __p2_19, __p3_19) __extension__ ({ \ | |
| 44420 | int64x2_t __s0_19 = __p0_19; \ | |
| 44421 | int64x1_t __s2_19 = __p2_19; \ | |
| 44422 | int64x2_t __rev0_19; __rev0_19 = __builtin_shufflevector(__s0_19, __s0_19, 1, 0); \ | |
| 44423 | int64x2_t __ret_19; \ | |
| 44424 | __ret_19 = __noswap_vsetq_lane_s64(__noswap_vget_lane_s64(__s2_19, __p3_19), __rev0_19, __p1_19); \ | |
| 44425 | __ret_19 = __builtin_shufflevector(__ret_19, __ret_19, 1, 0); \ | |
| 47606 | #define vcopyq_lane_u32(__p0_19, __p1_19, __p2_19, __p3_19) __extension__ ({ \ | |
| 47607 | uint32x4_t __s0_19 = __p0_19; \ | |
| 47608 | uint32x2_t __s2_19 = __p2_19; \ | |
| 47609 | uint32x4_t __rev0_19; __rev0_19 = __builtin_shufflevector(__s0_19, __s0_19, 3, 2, 1, 0); \ | |
| 47610 | uint32x2_t __rev2_19; __rev2_19 = __builtin_shufflevector(__s2_19, __s2_19, 1, 0); \ | |
| 47611 | uint32x4_t __ret_19; \ | |
| 47612 | __ret_19 = __noswap_vsetq_lane_u32(__noswap_vget_lane_u32(__rev2_19, __p3_19), __rev0_19, __p1_19); \ | |
| 47613 | __ret_19 = __builtin_shufflevector(__ret_19, __ret_19, 3, 2, 1, 0); \ | |
| 44426 | 47614 | __ret_19; \ |
| 44427 | 47615 | }) |
| 44428 | 47616 | #endif |
| 44429 | 47617 | |
| 44430 | 47618 | #ifdef __LITTLE_ENDIAN__ |
| 44431 | #define vcopyq_lane_s16(__p0_20, __p1_20, __p2_20, __p3_20) __extension__ ({ \ | |
| 44432 | int16x8_t __s0_20 = __p0_20; \ | |
| 44433 | int16x4_t __s2_20 = __p2_20; \ | |
| 44434 | int16x8_t __ret_20; \ | |
| 44435 | __ret_20 = vsetq_lane_s16(vget_lane_s16(__s2_20, __p3_20), __s0_20, __p1_20); \ | |
| 47619 | #define vcopyq_lane_u64(__p0_20, __p1_20, __p2_20, __p3_20) __extension__ ({ \ | |
| 47620 | uint64x2_t __s0_20 = __p0_20; \ | |
| 47621 | uint64x1_t __s2_20 = __p2_20; \ | |
| 47622 | uint64x2_t __ret_20; \ | |
| 47623 | __ret_20 = vsetq_lane_u64(vget_lane_u64(__s2_20, __p3_20), __s0_20, __p1_20); \ | |
| 44436 | 47624 | __ret_20; \ |
| 44437 | 47625 | }) |
| 44438 | 47626 | #else |
| 44439 | #define vcopyq_lane_s16(__p0_21, __p1_21, __p2_21, __p3_21) __extension__ ({ \ | |
| 44440 | int16x8_t __s0_21 = __p0_21; \ | |
| 44441 | int16x4_t __s2_21 = __p2_21; \ | |
| 44442 | int16x8_t __rev0_21; __rev0_21 = __builtin_shufflevector(__s0_21, __s0_21, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44443 | int16x4_t __rev2_21; __rev2_21 = __builtin_shufflevector(__s2_21, __s2_21, 3, 2, 1, 0); \ | |
| 44444 | int16x8_t __ret_21; \ | |
| 44445 | __ret_21 = __noswap_vsetq_lane_s16(__noswap_vget_lane_s16(__rev2_21, __p3_21), __rev0_21, __p1_21); \ | |
| 44446 | __ret_21 = __builtin_shufflevector(__ret_21, __ret_21, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47627 | #define vcopyq_lane_u64(__p0_21, __p1_21, __p2_21, __p3_21) __extension__ ({ \ | |
| 47628 | uint64x2_t __s0_21 = __p0_21; \ | |
| 47629 | uint64x1_t __s2_21 = __p2_21; \ | |
| 47630 | uint64x2_t __rev0_21; __rev0_21 = __builtin_shufflevector(__s0_21, __s0_21, 1, 0); \ | |
| 47631 | uint64x2_t __ret_21; \ | |
| 47632 | __ret_21 = __noswap_vsetq_lane_u64(__noswap_vget_lane_u64(__s2_21, __p3_21), __rev0_21, __p1_21); \ | |
| 47633 | __ret_21 = __builtin_shufflevector(__ret_21, __ret_21, 1, 0); \ | |
| 44447 | 47634 | __ret_21; \ |
| 44448 | 47635 | }) |
| 44449 | 47636 | #endif |
| 44450 | 47637 | |
| 44451 | 47638 | #ifdef __LITTLE_ENDIAN__ |
| 44452 | #define vcopy_lane_p8(__p0_22, __p1_22, __p2_22, __p3_22) __extension__ ({ \ | |
| 44453 | poly8x8_t __s0_22 = __p0_22; \ | |
| 44454 | poly8x8_t __s2_22 = __p2_22; \ | |
| 44455 | poly8x8_t __ret_22; \ | |
| 44456 | __ret_22 = vset_lane_p8(vget_lane_p8(__s2_22, __p3_22), __s0_22, __p1_22); \ | |
| 47639 | #define vcopyq_lane_u16(__p0_22, __p1_22, __p2_22, __p3_22) __extension__ ({ \ | |
| 47640 | uint16x8_t __s0_22 = __p0_22; \ | |
| 47641 | uint16x4_t __s2_22 = __p2_22; \ | |
| 47642 | uint16x8_t __ret_22; \ | |
| 47643 | __ret_22 = vsetq_lane_u16(vget_lane_u16(__s2_22, __p3_22), __s0_22, __p1_22); \ | |
| 44457 | 47644 | __ret_22; \ |
| 44458 | 47645 | }) |
| 44459 | 47646 | #else |
| 44460 | #define vcopy_lane_p8(__p0_23, __p1_23, __p2_23, __p3_23) __extension__ ({ \ | |
| 44461 | poly8x8_t __s0_23 = __p0_23; \ | |
| 44462 | poly8x8_t __s2_23 = __p2_23; \ | |
| 44463 | poly8x8_t __rev0_23; __rev0_23 = __builtin_shufflevector(__s0_23, __s0_23, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44464 | poly8x8_t __rev2_23; __rev2_23 = __builtin_shufflevector(__s2_23, __s2_23, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44465 | poly8x8_t __ret_23; \ | |
| 44466 | __ret_23 = __noswap_vset_lane_p8(__noswap_vget_lane_p8(__rev2_23, __p3_23), __rev0_23, __p1_23); \ | |
| 47647 | #define vcopyq_lane_u16(__p0_23, __p1_23, __p2_23, __p3_23) __extension__ ({ \ | |
| 47648 | uint16x8_t __s0_23 = __p0_23; \ | |
| 47649 | uint16x4_t __s2_23 = __p2_23; \ | |
| 47650 | uint16x8_t __rev0_23; __rev0_23 = __builtin_shufflevector(__s0_23, __s0_23, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47651 | uint16x4_t __rev2_23; __rev2_23 = __builtin_shufflevector(__s2_23, __s2_23, 3, 2, 1, 0); \ | |
| 47652 | uint16x8_t __ret_23; \ | |
| 47653 | __ret_23 = __noswap_vsetq_lane_u16(__noswap_vget_lane_u16(__rev2_23, __p3_23), __rev0_23, __p1_23); \ | |
| 44467 | 47654 | __ret_23 = __builtin_shufflevector(__ret_23, __ret_23, 7, 6, 5, 4, 3, 2, 1, 0); \ |
| 44468 | 47655 | __ret_23; \ |
| 44469 | 47656 | }) |
| 44470 | 47657 | #endif |
| 44471 | 47658 | |
| 44472 | 47659 | #ifdef __LITTLE_ENDIAN__ |
| 44473 | #define vcopy_lane_p16(__p0_24, __p1_24, __p2_24, __p3_24) __extension__ ({ \ | |
| 44474 | poly16x4_t __s0_24 = __p0_24; \ | |
| 44475 | poly16x4_t __s2_24 = __p2_24; \ | |
| 44476 | poly16x4_t __ret_24; \ | |
| 44477 | __ret_24 = vset_lane_p16(vget_lane_p16(__s2_24, __p3_24), __s0_24, __p1_24); \ | |
| 47660 | #define vcopyq_lane_s8(__p0_24, __p1_24, __p2_24, __p3_24) __extension__ ({ \ | |
| 47661 | int8x16_t __s0_24 = __p0_24; \ | |
| 47662 | int8x8_t __s2_24 = __p2_24; \ | |
| 47663 | int8x16_t __ret_24; \ | |
| 47664 | __ret_24 = vsetq_lane_s8(vget_lane_s8(__s2_24, __p3_24), __s0_24, __p1_24); \ | |
| 44478 | 47665 | __ret_24; \ |
| 44479 | 47666 | }) |
| 44480 | 47667 | #else |
| 44481 | #define vcopy_lane_p16(__p0_25, __p1_25, __p2_25, __p3_25) __extension__ ({ \ | |
| 44482 | poly16x4_t __s0_25 = __p0_25; \ | |
| 44483 | poly16x4_t __s2_25 = __p2_25; \ | |
| 44484 | poly16x4_t __rev0_25; __rev0_25 = __builtin_shufflevector(__s0_25, __s0_25, 3, 2, 1, 0); \ | |
| 44485 | poly16x4_t __rev2_25; __rev2_25 = __builtin_shufflevector(__s2_25, __s2_25, 3, 2, 1, 0); \ | |
| 44486 | poly16x4_t __ret_25; \ | |
| 44487 | __ret_25 = __noswap_vset_lane_p16(__noswap_vget_lane_p16(__rev2_25, __p3_25), __rev0_25, __p1_25); \ | |
| 44488 | __ret_25 = __builtin_shufflevector(__ret_25, __ret_25, 3, 2, 1, 0); \ | |
| 47668 | #define vcopyq_lane_s8(__p0_25, __p1_25, __p2_25, __p3_25) __extension__ ({ \ | |
| 47669 | int8x16_t __s0_25 = __p0_25; \ | |
| 47670 | int8x8_t __s2_25 = __p2_25; \ | |
| 47671 | int8x16_t __rev0_25; __rev0_25 = __builtin_shufflevector(__s0_25, __s0_25, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47672 | int8x8_t __rev2_25; __rev2_25 = __builtin_shufflevector(__s2_25, __s2_25, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47673 | int8x16_t __ret_25; \ | |
| 47674 | __ret_25 = __noswap_vsetq_lane_s8(__noswap_vget_lane_s8(__rev2_25, __p3_25), __rev0_25, __p1_25); \ | |
| 47675 | __ret_25 = __builtin_shufflevector(__ret_25, __ret_25, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44489 | 47676 | __ret_25; \ |
| 44490 | 47677 | }) |
| 44491 | 47678 | #endif |
| 44492 | 47679 | |
| 44493 | 47680 | #ifdef __LITTLE_ENDIAN__ |
| 44494 | #define vcopy_lane_u8(__p0_26, __p1_26, __p2_26, __p3_26) __extension__ ({ \ | |
| 44495 | uint8x8_t __s0_26 = __p0_26; \ | |
| 44496 | uint8x8_t __s2_26 = __p2_26; \ | |
| 44497 | uint8x8_t __ret_26; \ | |
| 44498 | __ret_26 = vset_lane_u8(vget_lane_u8(__s2_26, __p3_26), __s0_26, __p1_26); \ | |
| 47681 | #define vcopyq_lane_f32(__p0_26, __p1_26, __p2_26, __p3_26) __extension__ ({ \ | |
| 47682 | float32x4_t __s0_26 = __p0_26; \ | |
| 47683 | float32x2_t __s2_26 = __p2_26; \ | |
| 47684 | float32x4_t __ret_26; \ | |
| 47685 | __ret_26 = vsetq_lane_f32(vget_lane_f32(__s2_26, __p3_26), __s0_26, __p1_26); \ | |
| 44499 | 47686 | __ret_26; \ |
| 44500 | 47687 | }) |
| 44501 | 47688 | #else |
| 44502 | #define vcopy_lane_u8(__p0_27, __p1_27, __p2_27, __p3_27) __extension__ ({ \ | |
| 44503 | uint8x8_t __s0_27 = __p0_27; \ | |
| 44504 | uint8x8_t __s2_27 = __p2_27; \ | |
| 44505 | uint8x8_t __rev0_27; __rev0_27 = __builtin_shufflevector(__s0_27, __s0_27, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44506 | uint8x8_t __rev2_27; __rev2_27 = __builtin_shufflevector(__s2_27, __s2_27, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44507 | uint8x8_t __ret_27; \ | |
| 44508 | __ret_27 = __noswap_vset_lane_u8(__noswap_vget_lane_u8(__rev2_27, __p3_27), __rev0_27, __p1_27); \ | |
| 44509 | __ret_27 = __builtin_shufflevector(__ret_27, __ret_27, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47689 | #define vcopyq_lane_f32(__p0_27, __p1_27, __p2_27, __p3_27) __extension__ ({ \ | |
| 47690 | float32x4_t __s0_27 = __p0_27; \ | |
| 47691 | float32x2_t __s2_27 = __p2_27; \ | |
| 47692 | float32x4_t __rev0_27; __rev0_27 = __builtin_shufflevector(__s0_27, __s0_27, 3, 2, 1, 0); \ | |
| 47693 | float32x2_t __rev2_27; __rev2_27 = __builtin_shufflevector(__s2_27, __s2_27, 1, 0); \ | |
| 47694 | float32x4_t __ret_27; \ | |
| 47695 | __ret_27 = __noswap_vsetq_lane_f32(__noswap_vget_lane_f32(__rev2_27, __p3_27), __rev0_27, __p1_27); \ | |
| 47696 | __ret_27 = __builtin_shufflevector(__ret_27, __ret_27, 3, 2, 1, 0); \ | |
| 44510 | 47697 | __ret_27; \ |
| 44511 | 47698 | }) |
| 44512 | 47699 | #endif |
| 44513 | 47700 | |
| 44514 | 47701 | #ifdef __LITTLE_ENDIAN__ |
| 44515 | #define vcopy_lane_u32(__p0_28, __p1_28, __p2_28, __p3_28) __extension__ ({ \ | |
| 44516 | uint32x2_t __s0_28 = __p0_28; \ | |
| 44517 | uint32x2_t __s2_28 = __p2_28; \ | |
| 44518 | uint32x2_t __ret_28; \ | |
| 44519 | __ret_28 = vset_lane_u32(vget_lane_u32(__s2_28, __p3_28), __s0_28, __p1_28); \ | |
| 47702 | #define vcopyq_lane_s32(__p0_28, __p1_28, __p2_28, __p3_28) __extension__ ({ \ | |
| 47703 | int32x4_t __s0_28 = __p0_28; \ | |
| 47704 | int32x2_t __s2_28 = __p2_28; \ | |
| 47705 | int32x4_t __ret_28; \ | |
| 47706 | __ret_28 = vsetq_lane_s32(vget_lane_s32(__s2_28, __p3_28), __s0_28, __p1_28); \ | |
| 44520 | 47707 | __ret_28; \ |
| 44521 | 47708 | }) |
| 44522 | 47709 | #else |
| 44523 | #define vcopy_lane_u32(__p0_29, __p1_29, __p2_29, __p3_29) __extension__ ({ \ | |
| 44524 | uint32x2_t __s0_29 = __p0_29; \ | |
| 44525 | uint32x2_t __s2_29 = __p2_29; \ | |
| 44526 | uint32x2_t __rev0_29; __rev0_29 = __builtin_shufflevector(__s0_29, __s0_29, 1, 0); \ | |
| 44527 | uint32x2_t __rev2_29; __rev2_29 = __builtin_shufflevector(__s2_29, __s2_29, 1, 0); \ | |
| 44528 | uint32x2_t __ret_29; \ | |
| 44529 | __ret_29 = __noswap_vset_lane_u32(__noswap_vget_lane_u32(__rev2_29, __p3_29), __rev0_29, __p1_29); \ | |
| 44530 | __ret_29 = __builtin_shufflevector(__ret_29, __ret_29, 1, 0); \ | |
| 47710 | #define vcopyq_lane_s32(__p0_29, __p1_29, __p2_29, __p3_29) __extension__ ({ \ | |
| 47711 | int32x4_t __s0_29 = __p0_29; \ | |
| 47712 | int32x2_t __s2_29 = __p2_29; \ | |
| 47713 | int32x4_t __rev0_29; __rev0_29 = __builtin_shufflevector(__s0_29, __s0_29, 3, 2, 1, 0); \ | |
| 47714 | int32x2_t __rev2_29; __rev2_29 = __builtin_shufflevector(__s2_29, __s2_29, 1, 0); \ | |
| 47715 | int32x4_t __ret_29; \ | |
| 47716 | __ret_29 = __noswap_vsetq_lane_s32(__noswap_vget_lane_s32(__rev2_29, __p3_29), __rev0_29, __p1_29); \ | |
| 47717 | __ret_29 = __builtin_shufflevector(__ret_29, __ret_29, 3, 2, 1, 0); \ | |
| 44531 | 47718 | __ret_29; \ |
| 44532 | 47719 | }) |
| 44533 | 47720 | #endif |
| 44534 | 47721 | |
| 44535 | 47722 | #ifdef __LITTLE_ENDIAN__ |
| 44536 | #define vcopy_lane_u64(__p0_30, __p1_30, __p2_30, __p3_30) __extension__ ({ \ | |
| 44537 | uint64x1_t __s0_30 = __p0_30; \ | |
| 44538 | uint64x1_t __s2_30 = __p2_30; \ | |
| 44539 | uint64x1_t __ret_30; \ | |
| 44540 | __ret_30 = vset_lane_u64(vget_lane_u64(__s2_30, __p3_30), __s0_30, __p1_30); \ | |
| 47723 | #define vcopyq_lane_s64(__p0_30, __p1_30, __p2_30, __p3_30) __extension__ ({ \ | |
| 47724 | int64x2_t __s0_30 = __p0_30; \ | |
| 47725 | int64x1_t __s2_30 = __p2_30; \ | |
| 47726 | int64x2_t __ret_30; \ | |
| 47727 | __ret_30 = vsetq_lane_s64(vget_lane_s64(__s2_30, __p3_30), __s0_30, __p1_30); \ | |
| 44541 | 47728 | __ret_30; \ |
| 44542 | 47729 | }) |
| 44543 | 47730 | #else |
| 44544 | #define vcopy_lane_u64(__p0_31, __p1_31, __p2_31, __p3_31) __extension__ ({ \ | |
| 44545 | uint64x1_t __s0_31 = __p0_31; \ | |
| 44546 | uint64x1_t __s2_31 = __p2_31; \ | |
| 44547 | uint64x1_t __ret_31; \ | |
| 44548 | __ret_31 = __noswap_vset_lane_u64(__noswap_vget_lane_u64(__s2_31, __p3_31), __s0_31, __p1_31); \ | |
| 47731 | #define vcopyq_lane_s64(__p0_31, __p1_31, __p2_31, __p3_31) __extension__ ({ \ | |
| 47732 | int64x2_t __s0_31 = __p0_31; \ | |
| 47733 | int64x1_t __s2_31 = __p2_31; \ | |
| 47734 | int64x2_t __rev0_31; __rev0_31 = __builtin_shufflevector(__s0_31, __s0_31, 1, 0); \ | |
| 47735 | int64x2_t __ret_31; \ | |
| 47736 | __ret_31 = __noswap_vsetq_lane_s64(__noswap_vget_lane_s64(__s2_31, __p3_31), __rev0_31, __p1_31); \ | |
| 47737 | __ret_31 = __builtin_shufflevector(__ret_31, __ret_31, 1, 0); \ | |
| 44549 | 47738 | __ret_31; \ |
| 44550 | 47739 | }) |
| 44551 | 47740 | #endif |
| 44552 | 47741 | |
| 44553 | 47742 | #ifdef __LITTLE_ENDIAN__ |
| 44554 | #define vcopy_lane_u16(__p0_32, __p1_32, __p2_32, __p3_32) __extension__ ({ \ | |
| 44555 | uint16x4_t __s0_32 = __p0_32; \ | |
| 44556 | uint16x4_t __s2_32 = __p2_32; \ | |
| 44557 | uint16x4_t __ret_32; \ | |
| 44558 | __ret_32 = vset_lane_u16(vget_lane_u16(__s2_32, __p3_32), __s0_32, __p1_32); \ | |
| 47743 | #define vcopyq_lane_s16(__p0_32, __p1_32, __p2_32, __p3_32) __extension__ ({ \ | |
| 47744 | int16x8_t __s0_32 = __p0_32; \ | |
| 47745 | int16x4_t __s2_32 = __p2_32; \ | |
| 47746 | int16x8_t __ret_32; \ | |
| 47747 | __ret_32 = vsetq_lane_s16(vget_lane_s16(__s2_32, __p3_32), __s0_32, __p1_32); \ | |
| 44559 | 47748 | __ret_32; \ |
| 44560 | 47749 | }) |
| 44561 | 47750 | #else |
| 44562 | #define vcopy_lane_u16(__p0_33, __p1_33, __p2_33, __p3_33) __extension__ ({ \ | |
| 44563 | uint16x4_t __s0_33 = __p0_33; \ | |
| 44564 | uint16x4_t __s2_33 = __p2_33; \ | |
| 44565 | uint16x4_t __rev0_33; __rev0_33 = __builtin_shufflevector(__s0_33, __s0_33, 3, 2, 1, 0); \ | |
| 44566 | uint16x4_t __rev2_33; __rev2_33 = __builtin_shufflevector(__s2_33, __s2_33, 3, 2, 1, 0); \ | |
| 44567 | uint16x4_t __ret_33; \ | |
| 44568 | __ret_33 = __noswap_vset_lane_u16(__noswap_vget_lane_u16(__rev2_33, __p3_33), __rev0_33, __p1_33); \ | |
| 44569 | __ret_33 = __builtin_shufflevector(__ret_33, __ret_33, 3, 2, 1, 0); \ | |
| 47751 | #define vcopyq_lane_s16(__p0_33, __p1_33, __p2_33, __p3_33) __extension__ ({ \ | |
| 47752 | int16x8_t __s0_33 = __p0_33; \ | |
| 47753 | int16x4_t __s2_33 = __p2_33; \ | |
| 47754 | int16x8_t __rev0_33; __rev0_33 = __builtin_shufflevector(__s0_33, __s0_33, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47755 | int16x4_t __rev2_33; __rev2_33 = __builtin_shufflevector(__s2_33, __s2_33, 3, 2, 1, 0); \ | |
| 47756 | int16x8_t __ret_33; \ | |
| 47757 | __ret_33 = __noswap_vsetq_lane_s16(__noswap_vget_lane_s16(__rev2_33, __p3_33), __rev0_33, __p1_33); \ | |
| 47758 | __ret_33 = __builtin_shufflevector(__ret_33, __ret_33, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44570 | 47759 | __ret_33; \ |
| 44571 | 47760 | }) |
| 44572 | 47761 | #endif |
| 44573 | 47762 | |
| 44574 | 47763 | #ifdef __LITTLE_ENDIAN__ |
| 44575 | #define vcopy_lane_s8(__p0_34, __p1_34, __p2_34, __p3_34) __extension__ ({ \ | |
| 44576 | int8x8_t __s0_34 = __p0_34; \ | |
| 44577 | int8x8_t __s2_34 = __p2_34; \ | |
| 44578 | int8x8_t __ret_34; \ | |
| 44579 | __ret_34 = vset_lane_s8(vget_lane_s8(__s2_34, __p3_34), __s0_34, __p1_34); \ | |
| 47764 | #define vcopy_lane_p8(__p0_34, __p1_34, __p2_34, __p3_34) __extension__ ({ \ | |
| 47765 | poly8x8_t __s0_34 = __p0_34; \ | |
| 47766 | poly8x8_t __s2_34 = __p2_34; \ | |
| 47767 | poly8x8_t __ret_34; \ | |
| 47768 | __ret_34 = vset_lane_p8(vget_lane_p8(__s2_34, __p3_34), __s0_34, __p1_34); \ | |
| 44580 | 47769 | __ret_34; \ |
| 44581 | 47770 | }) |
| 44582 | 47771 | #else |
| 44583 | #define vcopy_lane_s8(__p0_35, __p1_35, __p2_35, __p3_35) __extension__ ({ \ | |
| 44584 | int8x8_t __s0_35 = __p0_35; \ | |
| 44585 | int8x8_t __s2_35 = __p2_35; \ | |
| 44586 | int8x8_t __rev0_35; __rev0_35 = __builtin_shufflevector(__s0_35, __s0_35, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44587 | int8x8_t __rev2_35; __rev2_35 = __builtin_shufflevector(__s2_35, __s2_35, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44588 | int8x8_t __ret_35; \ | |
| 44589 | __ret_35 = __noswap_vset_lane_s8(__noswap_vget_lane_s8(__rev2_35, __p3_35), __rev0_35, __p1_35); \ | |
| 47772 | #define vcopy_lane_p8(__p0_35, __p1_35, __p2_35, __p3_35) __extension__ ({ \ | |
| 47773 | poly8x8_t __s0_35 = __p0_35; \ | |
| 47774 | poly8x8_t __s2_35 = __p2_35; \ | |
| 47775 | poly8x8_t __rev0_35; __rev0_35 = __builtin_shufflevector(__s0_35, __s0_35, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47776 | poly8x8_t __rev2_35; __rev2_35 = __builtin_shufflevector(__s2_35, __s2_35, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47777 | poly8x8_t __ret_35; \ | |
| 47778 | __ret_35 = __noswap_vset_lane_p8(__noswap_vget_lane_p8(__rev2_35, __p3_35), __rev0_35, __p1_35); \ | |
| 44590 | 47779 | __ret_35 = __builtin_shufflevector(__ret_35, __ret_35, 7, 6, 5, 4, 3, 2, 1, 0); \ |
| 44591 | 47780 | __ret_35; \ |
| 44592 | 47781 | }) |
| 44593 | 47782 | #endif |
| 44594 | 47783 | |
| 44595 | 47784 | #ifdef __LITTLE_ENDIAN__ |
| 44596 | #define vcopy_lane_f32(__p0_36, __p1_36, __p2_36, __p3_36) __extension__ ({ \ | |
| 44597 | float32x2_t __s0_36 = __p0_36; \ | |
| 44598 | float32x2_t __s2_36 = __p2_36; \ | |
| 44599 | float32x2_t __ret_36; \ | |
| 44600 | __ret_36 = vset_lane_f32(vget_lane_f32(__s2_36, __p3_36), __s0_36, __p1_36); \ | |
| 47785 | #define vcopy_lane_p16(__p0_36, __p1_36, __p2_36, __p3_36) __extension__ ({ \ | |
| 47786 | poly16x4_t __s0_36 = __p0_36; \ | |
| 47787 | poly16x4_t __s2_36 = __p2_36; \ | |
| 47788 | poly16x4_t __ret_36; \ | |
| 47789 | __ret_36 = vset_lane_p16(vget_lane_p16(__s2_36, __p3_36), __s0_36, __p1_36); \ | |
| 44601 | 47790 | __ret_36; \ |
| 44602 | 47791 | }) |
| 44603 | 47792 | #else |
| 44604 | #define vcopy_lane_f32(__p0_37, __p1_37, __p2_37, __p3_37) __extension__ ({ \ | |
| 44605 | float32x2_t __s0_37 = __p0_37; \ | |
| 44606 | float32x2_t __s2_37 = __p2_37; \ | |
| 44607 | float32x2_t __rev0_37; __rev0_37 = __builtin_shufflevector(__s0_37, __s0_37, 1, 0); \ | |
| 44608 | float32x2_t __rev2_37; __rev2_37 = __builtin_shufflevector(__s2_37, __s2_37, 1, 0); \ | |
| 44609 | float32x2_t __ret_37; \ | |
| 44610 | __ret_37 = __noswap_vset_lane_f32(__noswap_vget_lane_f32(__rev2_37, __p3_37), __rev0_37, __p1_37); \ | |
| 44611 | __ret_37 = __builtin_shufflevector(__ret_37, __ret_37, 1, 0); \ | |
| 47793 | #define vcopy_lane_p16(__p0_37, __p1_37, __p2_37, __p3_37) __extension__ ({ \ | |
| 47794 | poly16x4_t __s0_37 = __p0_37; \ | |
| 47795 | poly16x4_t __s2_37 = __p2_37; \ | |
| 47796 | poly16x4_t __rev0_37; __rev0_37 = __builtin_shufflevector(__s0_37, __s0_37, 3, 2, 1, 0); \ | |
| 47797 | poly16x4_t __rev2_37; __rev2_37 = __builtin_shufflevector(__s2_37, __s2_37, 3, 2, 1, 0); \ | |
| 47798 | poly16x4_t __ret_37; \ | |
| 47799 | __ret_37 = __noswap_vset_lane_p16(__noswap_vget_lane_p16(__rev2_37, __p3_37), __rev0_37, __p1_37); \ | |
| 47800 | __ret_37 = __builtin_shufflevector(__ret_37, __ret_37, 3, 2, 1, 0); \ | |
| 44612 | 47801 | __ret_37; \ |
| 44613 | 47802 | }) |
| 44614 | 47803 | #endif |
| 44615 | 47804 | |
| 44616 | 47805 | #ifdef __LITTLE_ENDIAN__ |
| 44617 | #define vcopy_lane_s32(__p0_38, __p1_38, __p2_38, __p3_38) __extension__ ({ \ | |
| 44618 | int32x2_t __s0_38 = __p0_38; \ | |
| 44619 | int32x2_t __s2_38 = __p2_38; \ | |
| 44620 | int32x2_t __ret_38; \ | |
| 44621 | __ret_38 = vset_lane_s32(vget_lane_s32(__s2_38, __p3_38), __s0_38, __p1_38); \ | |
| 47806 | #define vcopy_lane_u8(__p0_38, __p1_38, __p2_38, __p3_38) __extension__ ({ \ | |
| 47807 | uint8x8_t __s0_38 = __p0_38; \ | |
| 47808 | uint8x8_t __s2_38 = __p2_38; \ | |
| 47809 | uint8x8_t __ret_38; \ | |
| 47810 | __ret_38 = vset_lane_u8(vget_lane_u8(__s2_38, __p3_38), __s0_38, __p1_38); \ | |
| 44622 | 47811 | __ret_38; \ |
| 44623 | 47812 | }) |
| 44624 | 47813 | #else |
| 44625 | #define vcopy_lane_s32(__p0_39, __p1_39, __p2_39, __p3_39) __extension__ ({ \ | |
| 44626 | int32x2_t __s0_39 = __p0_39; \ | |
| 44627 | int32x2_t __s2_39 = __p2_39; \ | |
| 44628 | int32x2_t __rev0_39; __rev0_39 = __builtin_shufflevector(__s0_39, __s0_39, 1, 0); \ | |
| 44629 | int32x2_t __rev2_39; __rev2_39 = __builtin_shufflevector(__s2_39, __s2_39, 1, 0); \ | |
| 44630 | int32x2_t __ret_39; \ | |
| 44631 | __ret_39 = __noswap_vset_lane_s32(__noswap_vget_lane_s32(__rev2_39, __p3_39), __rev0_39, __p1_39); \ | |
| 44632 | __ret_39 = __builtin_shufflevector(__ret_39, __ret_39, 1, 0); \ | |
| 47814 | #define vcopy_lane_u8(__p0_39, __p1_39, __p2_39, __p3_39) __extension__ ({ \ | |
| 47815 | uint8x8_t __s0_39 = __p0_39; \ | |
| 47816 | uint8x8_t __s2_39 = __p2_39; \ | |
| 47817 | uint8x8_t __rev0_39; __rev0_39 = __builtin_shufflevector(__s0_39, __s0_39, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47818 | uint8x8_t __rev2_39; __rev2_39 = __builtin_shufflevector(__s2_39, __s2_39, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47819 | uint8x8_t __ret_39; \ | |
| 47820 | __ret_39 = __noswap_vset_lane_u8(__noswap_vget_lane_u8(__rev2_39, __p3_39), __rev0_39, __p1_39); \ | |
| 47821 | __ret_39 = __builtin_shufflevector(__ret_39, __ret_39, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44633 | 47822 | __ret_39; \ |
| 44634 | 47823 | }) |
| 44635 | 47824 | #endif |
| 44636 | 47825 | |
| 44637 | 47826 | #ifdef __LITTLE_ENDIAN__ |
| 44638 | #define vcopy_lane_s64(__p0_40, __p1_40, __p2_40, __p3_40) __extension__ ({ \ | |
| 44639 | int64x1_t __s0_40 = __p0_40; \ | |
| 44640 | int64x1_t __s2_40 = __p2_40; \ | |
| 44641 | int64x1_t __ret_40; \ | |
| 44642 | __ret_40 = vset_lane_s64(vget_lane_s64(__s2_40, __p3_40), __s0_40, __p1_40); \ | |
| 47827 | #define vcopy_lane_u32(__p0_40, __p1_40, __p2_40, __p3_40) __extension__ ({ \ | |
| 47828 | uint32x2_t __s0_40 = __p0_40; \ | |
| 47829 | uint32x2_t __s2_40 = __p2_40; \ | |
| 47830 | uint32x2_t __ret_40; \ | |
| 47831 | __ret_40 = vset_lane_u32(vget_lane_u32(__s2_40, __p3_40), __s0_40, __p1_40); \ | |
| 44643 | 47832 | __ret_40; \ |
| 44644 | 47833 | }) |
| 44645 | 47834 | #else |
| 44646 | #define vcopy_lane_s64(__p0_41, __p1_41, __p2_41, __p3_41) __extension__ ({ \ | |
| 44647 | int64x1_t __s0_41 = __p0_41; \ | |
| 44648 | int64x1_t __s2_41 = __p2_41; \ | |
| 44649 | int64x1_t __ret_41; \ | |
| 44650 | __ret_41 = __noswap_vset_lane_s64(__noswap_vget_lane_s64(__s2_41, __p3_41), __s0_41, __p1_41); \ | |
| 47835 | #define vcopy_lane_u32(__p0_41, __p1_41, __p2_41, __p3_41) __extension__ ({ \ | |
| 47836 | uint32x2_t __s0_41 = __p0_41; \ | |
| 47837 | uint32x2_t __s2_41 = __p2_41; \ | |
| 47838 | uint32x2_t __rev0_41; __rev0_41 = __builtin_shufflevector(__s0_41, __s0_41, 1, 0); \ | |
| 47839 | uint32x2_t __rev2_41; __rev2_41 = __builtin_shufflevector(__s2_41, __s2_41, 1, 0); \ | |
| 47840 | uint32x2_t __ret_41; \ | |
| 47841 | __ret_41 = __noswap_vset_lane_u32(__noswap_vget_lane_u32(__rev2_41, __p3_41), __rev0_41, __p1_41); \ | |
| 47842 | __ret_41 = __builtin_shufflevector(__ret_41, __ret_41, 1, 0); \ | |
| 44651 | 47843 | __ret_41; \ |
| 44652 | 47844 | }) |
| 44653 | 47845 | #endif |
| 44654 | 47846 | |
| 44655 | 47847 | #ifdef __LITTLE_ENDIAN__ |
| 44656 | #define vcopy_lane_s16(__p0_42, __p1_42, __p2_42, __p3_42) __extension__ ({ \ | |
| 44657 | int16x4_t __s0_42 = __p0_42; \ | |
| 44658 | int16x4_t __s2_42 = __p2_42; \ | |
| 44659 | int16x4_t __ret_42; \ | |
| 44660 | __ret_42 = vset_lane_s16(vget_lane_s16(__s2_42, __p3_42), __s0_42, __p1_42); \ | |
| 47848 | #define vcopy_lane_u64(__p0_42, __p1_42, __p2_42, __p3_42) __extension__ ({ \ | |
| 47849 | uint64x1_t __s0_42 = __p0_42; \ | |
| 47850 | uint64x1_t __s2_42 = __p2_42; \ | |
| 47851 | uint64x1_t __ret_42; \ | |
| 47852 | __ret_42 = vset_lane_u64(vget_lane_u64(__s2_42, __p3_42), __s0_42, __p1_42); \ | |
| 44661 | 47853 | __ret_42; \ |
| 44662 | 47854 | }) |
| 44663 | 47855 | #else |
| 44664 | #define vcopy_lane_s16(__p0_43, __p1_43, __p2_43, __p3_43) __extension__ ({ \ | |
| 44665 | int16x4_t __s0_43 = __p0_43; \ | |
| 44666 | int16x4_t __s2_43 = __p2_43; \ | |
| 44667 | int16x4_t __rev0_43; __rev0_43 = __builtin_shufflevector(__s0_43, __s0_43, 3, 2, 1, 0); \ | |
| 44668 | int16x4_t __rev2_43; __rev2_43 = __builtin_shufflevector(__s2_43, __s2_43, 3, 2, 1, 0); \ | |
| 44669 | int16x4_t __ret_43; \ | |
| 44670 | __ret_43 = __noswap_vset_lane_s16(__noswap_vget_lane_s16(__rev2_43, __p3_43), __rev0_43, __p1_43); \ | |
| 44671 | __ret_43 = __builtin_shufflevector(__ret_43, __ret_43, 3, 2, 1, 0); \ | |
| 47856 | #define vcopy_lane_u64(__p0_43, __p1_43, __p2_43, __p3_43) __extension__ ({ \ | |
| 47857 | uint64x1_t __s0_43 = __p0_43; \ | |
| 47858 | uint64x1_t __s2_43 = __p2_43; \ | |
| 47859 | uint64x1_t __ret_43; \ | |
| 47860 | __ret_43 = __noswap_vset_lane_u64(__noswap_vget_lane_u64(__s2_43, __p3_43), __s0_43, __p1_43); \ | |
| 44672 | 47861 | __ret_43; \ |
| 44673 | 47862 | }) |
| 44674 | 47863 | #endif |
| 44675 | 47864 | |
| 44676 | 47865 | #ifdef __LITTLE_ENDIAN__ |
| 44677 | #define vcopyq_laneq_p8(__p0_44, __p1_44, __p2_44, __p3_44) __extension__ ({ \ | |
| 44678 | poly8x16_t __s0_44 = __p0_44; \ | |
| 44679 | poly8x16_t __s2_44 = __p2_44; \ | |
| 44680 | poly8x16_t __ret_44; \ | |
| 44681 | __ret_44 = vsetq_lane_p8(vgetq_lane_p8(__s2_44, __p3_44), __s0_44, __p1_44); \ | |
| 47866 | #define vcopy_lane_u16(__p0_44, __p1_44, __p2_44, __p3_44) __extension__ ({ \ | |
| 47867 | uint16x4_t __s0_44 = __p0_44; \ | |
| 47868 | uint16x4_t __s2_44 = __p2_44; \ | |
| 47869 | uint16x4_t __ret_44; \ | |
| 47870 | __ret_44 = vset_lane_u16(vget_lane_u16(__s2_44, __p3_44), __s0_44, __p1_44); \ | |
| 44682 | 47871 | __ret_44; \ |
| 44683 | 47872 | }) |
| 44684 | 47873 | #else |
| 44685 | #define vcopyq_laneq_p8(__p0_45, __p1_45, __p2_45, __p3_45) __extension__ ({ \ | |
| 44686 | poly8x16_t __s0_45 = __p0_45; \ | |
| 44687 | poly8x16_t __s2_45 = __p2_45; \ | |
| 44688 | poly8x16_t __rev0_45; __rev0_45 = __builtin_shufflevector(__s0_45, __s0_45, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44689 | poly8x16_t __rev2_45; __rev2_45 = __builtin_shufflevector(__s2_45, __s2_45, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44690 | poly8x16_t __ret_45; \ | |
| 44691 | __ret_45 = __noswap_vsetq_lane_p8(__noswap_vgetq_lane_p8(__rev2_45, __p3_45), __rev0_45, __p1_45); \ | |
| 44692 | __ret_45 = __builtin_shufflevector(__ret_45, __ret_45, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47874 | #define vcopy_lane_u16(__p0_45, __p1_45, __p2_45, __p3_45) __extension__ ({ \ | |
| 47875 | uint16x4_t __s0_45 = __p0_45; \ | |
| 47876 | uint16x4_t __s2_45 = __p2_45; \ | |
| 47877 | uint16x4_t __rev0_45; __rev0_45 = __builtin_shufflevector(__s0_45, __s0_45, 3, 2, 1, 0); \ | |
| 47878 | uint16x4_t __rev2_45; __rev2_45 = __builtin_shufflevector(__s2_45, __s2_45, 3, 2, 1, 0); \ | |
| 47879 | uint16x4_t __ret_45; \ | |
| 47880 | __ret_45 = __noswap_vset_lane_u16(__noswap_vget_lane_u16(__rev2_45, __p3_45), __rev0_45, __p1_45); \ | |
| 47881 | __ret_45 = __builtin_shufflevector(__ret_45, __ret_45, 3, 2, 1, 0); \ | |
| 44693 | 47882 | __ret_45; \ |
| 44694 | 47883 | }) |
| 44695 | 47884 | #endif |
| 44696 | 47885 | |
| 44697 | 47886 | #ifdef __LITTLE_ENDIAN__ |
| 44698 | #define vcopyq_laneq_p16(__p0_46, __p1_46, __p2_46, __p3_46) __extension__ ({ \ | |
| 44699 | poly16x8_t __s0_46 = __p0_46; \ | |
| 44700 | poly16x8_t __s2_46 = __p2_46; \ | |
| 44701 | poly16x8_t __ret_46; \ | |
| 44702 | __ret_46 = vsetq_lane_p16(vgetq_lane_p16(__s2_46, __p3_46), __s0_46, __p1_46); \ | |
| 47887 | #define vcopy_lane_s8(__p0_46, __p1_46, __p2_46, __p3_46) __extension__ ({ \ | |
| 47888 | int8x8_t __s0_46 = __p0_46; \ | |
| 47889 | int8x8_t __s2_46 = __p2_46; \ | |
| 47890 | int8x8_t __ret_46; \ | |
| 47891 | __ret_46 = vset_lane_s8(vget_lane_s8(__s2_46, __p3_46), __s0_46, __p1_46); \ | |
| 44703 | 47892 | __ret_46; \ |
| 44704 | 47893 | }) |
| 44705 | 47894 | #else |
| 44706 | #define vcopyq_laneq_p16(__p0_47, __p1_47, __p2_47, __p3_47) __extension__ ({ \ | |
| 44707 | poly16x8_t __s0_47 = __p0_47; \ | |
| 44708 | poly16x8_t __s2_47 = __p2_47; \ | |
| 44709 | poly16x8_t __rev0_47; __rev0_47 = __builtin_shufflevector(__s0_47, __s0_47, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44710 | poly16x8_t __rev2_47; __rev2_47 = __builtin_shufflevector(__s2_47, __s2_47, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44711 | poly16x8_t __ret_47; \ | |
| 44712 | __ret_47 = __noswap_vsetq_lane_p16(__noswap_vgetq_lane_p16(__rev2_47, __p3_47), __rev0_47, __p1_47); \ | |
| 47895 | #define vcopy_lane_s8(__p0_47, __p1_47, __p2_47, __p3_47) __extension__ ({ \ | |
| 47896 | int8x8_t __s0_47 = __p0_47; \ | |
| 47897 | int8x8_t __s2_47 = __p2_47; \ | |
| 47898 | int8x8_t __rev0_47; __rev0_47 = __builtin_shufflevector(__s0_47, __s0_47, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47899 | int8x8_t __rev2_47; __rev2_47 = __builtin_shufflevector(__s2_47, __s2_47, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47900 | int8x8_t __ret_47; \ | |
| 47901 | __ret_47 = __noswap_vset_lane_s8(__noswap_vget_lane_s8(__rev2_47, __p3_47), __rev0_47, __p1_47); \ | |
| 44713 | 47902 | __ret_47 = __builtin_shufflevector(__ret_47, __ret_47, 7, 6, 5, 4, 3, 2, 1, 0); \ |
| 44714 | 47903 | __ret_47; \ |
| 44715 | 47904 | }) |
| 44716 | 47905 | #endif |
| 44717 | 47906 | |
| 44718 | 47907 | #ifdef __LITTLE_ENDIAN__ |
| 44719 | #define vcopyq_laneq_u8(__p0_48, __p1_48, __p2_48, __p3_48) __extension__ ({ \ | |
| 44720 | uint8x16_t __s0_48 = __p0_48; \ | |
| 44721 | uint8x16_t __s2_48 = __p2_48; \ | |
| 44722 | uint8x16_t __ret_48; \ | |
| 44723 | __ret_48 = vsetq_lane_u8(vgetq_lane_u8(__s2_48, __p3_48), __s0_48, __p1_48); \ | |
| 47908 | #define vcopy_lane_f32(__p0_48, __p1_48, __p2_48, __p3_48) __extension__ ({ \ | |
| 47909 | float32x2_t __s0_48 = __p0_48; \ | |
| 47910 | float32x2_t __s2_48 = __p2_48; \ | |
| 47911 | float32x2_t __ret_48; \ | |
| 47912 | __ret_48 = vset_lane_f32(vget_lane_f32(__s2_48, __p3_48), __s0_48, __p1_48); \ | |
| 44724 | 47913 | __ret_48; \ |
| 44725 | 47914 | }) |
| 44726 | 47915 | #else |
| 44727 | #define vcopyq_laneq_u8(__p0_49, __p1_49, __p2_49, __p3_49) __extension__ ({ \ | |
| 44728 | uint8x16_t __s0_49 = __p0_49; \ | |
| 44729 | uint8x16_t __s2_49 = __p2_49; \ | |
| 44730 | uint8x16_t __rev0_49; __rev0_49 = __builtin_shufflevector(__s0_49, __s0_49, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44731 | uint8x16_t __rev2_49; __rev2_49 = __builtin_shufflevector(__s2_49, __s2_49, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44732 | uint8x16_t __ret_49; \ | |
| 44733 | __ret_49 = __noswap_vsetq_lane_u8(__noswap_vgetq_lane_u8(__rev2_49, __p3_49), __rev0_49, __p1_49); \ | |
| 44734 | __ret_49 = __builtin_shufflevector(__ret_49, __ret_49, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47916 | #define vcopy_lane_f32(__p0_49, __p1_49, __p2_49, __p3_49) __extension__ ({ \ | |
| 47917 | float32x2_t __s0_49 = __p0_49; \ | |
| 47918 | float32x2_t __s2_49 = __p2_49; \ | |
| 47919 | float32x2_t __rev0_49; __rev0_49 = __builtin_shufflevector(__s0_49, __s0_49, 1, 0); \ | |
| 47920 | float32x2_t __rev2_49; __rev2_49 = __builtin_shufflevector(__s2_49, __s2_49, 1, 0); \ | |
| 47921 | float32x2_t __ret_49; \ | |
| 47922 | __ret_49 = __noswap_vset_lane_f32(__noswap_vget_lane_f32(__rev2_49, __p3_49), __rev0_49, __p1_49); \ | |
| 47923 | __ret_49 = __builtin_shufflevector(__ret_49, __ret_49, 1, 0); \ | |
| 44735 | 47924 | __ret_49; \ |
| 44736 | 47925 | }) |
| 44737 | 47926 | #endif |
| 44738 | 47927 | |
| 44739 | 47928 | #ifdef __LITTLE_ENDIAN__ |
| 44740 | #define vcopyq_laneq_u32(__p0_50, __p1_50, __p2_50, __p3_50) __extension__ ({ \ | |
| 44741 | uint32x4_t __s0_50 = __p0_50; \ | |
| 44742 | uint32x4_t __s2_50 = __p2_50; \ | |
| 44743 | uint32x4_t __ret_50; \ | |
| 44744 | __ret_50 = vsetq_lane_u32(vgetq_lane_u32(__s2_50, __p3_50), __s0_50, __p1_50); \ | |
| 47929 | #define vcopy_lane_s32(__p0_50, __p1_50, __p2_50, __p3_50) __extension__ ({ \ | |
| 47930 | int32x2_t __s0_50 = __p0_50; \ | |
| 47931 | int32x2_t __s2_50 = __p2_50; \ | |
| 47932 | int32x2_t __ret_50; \ | |
| 47933 | __ret_50 = vset_lane_s32(vget_lane_s32(__s2_50, __p3_50), __s0_50, __p1_50); \ | |
| 44745 | 47934 | __ret_50; \ |
| 44746 | 47935 | }) |
| 44747 | 47936 | #else |
| 44748 | #define vcopyq_laneq_u32(__p0_51, __p1_51, __p2_51, __p3_51) __extension__ ({ \ | |
| 44749 | uint32x4_t __s0_51 = __p0_51; \ | |
| 44750 | uint32x4_t __s2_51 = __p2_51; \ | |
| 44751 | uint32x4_t __rev0_51; __rev0_51 = __builtin_shufflevector(__s0_51, __s0_51, 3, 2, 1, 0); \ | |
| 44752 | uint32x4_t __rev2_51; __rev2_51 = __builtin_shufflevector(__s2_51, __s2_51, 3, 2, 1, 0); \ | |
| 44753 | uint32x4_t __ret_51; \ | |
| 44754 | __ret_51 = __noswap_vsetq_lane_u32(__noswap_vgetq_lane_u32(__rev2_51, __p3_51), __rev0_51, __p1_51); \ | |
| 44755 | __ret_51 = __builtin_shufflevector(__ret_51, __ret_51, 3, 2, 1, 0); \ | |
| 47937 | #define vcopy_lane_s32(__p0_51, __p1_51, __p2_51, __p3_51) __extension__ ({ \ | |
| 47938 | int32x2_t __s0_51 = __p0_51; \ | |
| 47939 | int32x2_t __s2_51 = __p2_51; \ | |
| 47940 | int32x2_t __rev0_51; __rev0_51 = __builtin_shufflevector(__s0_51, __s0_51, 1, 0); \ | |
| 47941 | int32x2_t __rev2_51; __rev2_51 = __builtin_shufflevector(__s2_51, __s2_51, 1, 0); \ | |
| 47942 | int32x2_t __ret_51; \ | |
| 47943 | __ret_51 = __noswap_vset_lane_s32(__noswap_vget_lane_s32(__rev2_51, __p3_51), __rev0_51, __p1_51); \ | |
| 47944 | __ret_51 = __builtin_shufflevector(__ret_51, __ret_51, 1, 0); \ | |
| 44756 | 47945 | __ret_51; \ |
| 44757 | 47946 | }) |
| 44758 | 47947 | #endif |
| 44759 | 47948 | |
| 44760 | 47949 | #ifdef __LITTLE_ENDIAN__ |
| 44761 | #define vcopyq_laneq_u64(__p0_52, __p1_52, __p2_52, __p3_52) __extension__ ({ \ | |
| 44762 | uint64x2_t __s0_52 = __p0_52; \ | |
| 44763 | uint64x2_t __s2_52 = __p2_52; \ | |
| 44764 | uint64x2_t __ret_52; \ | |
| 44765 | __ret_52 = vsetq_lane_u64(vgetq_lane_u64(__s2_52, __p3_52), __s0_52, __p1_52); \ | |
| 47950 | #define vcopy_lane_s64(__p0_52, __p1_52, __p2_52, __p3_52) __extension__ ({ \ | |
| 47951 | int64x1_t __s0_52 = __p0_52; \ | |
| 47952 | int64x1_t __s2_52 = __p2_52; \ | |
| 47953 | int64x1_t __ret_52; \ | |
| 47954 | __ret_52 = vset_lane_s64(vget_lane_s64(__s2_52, __p3_52), __s0_52, __p1_52); \ | |
| 44766 | 47955 | __ret_52; \ |
| 44767 | 47956 | }) |
| 44768 | 47957 | #else |
| 44769 | #define vcopyq_laneq_u64(__p0_53, __p1_53, __p2_53, __p3_53) __extension__ ({ \ | |
| 44770 | uint64x2_t __s0_53 = __p0_53; \ | |
| 44771 | uint64x2_t __s2_53 = __p2_53; \ | |
| 44772 | uint64x2_t __rev0_53; __rev0_53 = __builtin_shufflevector(__s0_53, __s0_53, 1, 0); \ | |
| 44773 | uint64x2_t __rev2_53; __rev2_53 = __builtin_shufflevector(__s2_53, __s2_53, 1, 0); \ | |
| 44774 | uint64x2_t __ret_53; \ | |
| 44775 | __ret_53 = __noswap_vsetq_lane_u64(__noswap_vgetq_lane_u64(__rev2_53, __p3_53), __rev0_53, __p1_53); \ | |
| 44776 | __ret_53 = __builtin_shufflevector(__ret_53, __ret_53, 1, 0); \ | |
| 47958 | #define vcopy_lane_s64(__p0_53, __p1_53, __p2_53, __p3_53) __extension__ ({ \ | |
| 47959 | int64x1_t __s0_53 = __p0_53; \ | |
| 47960 | int64x1_t __s2_53 = __p2_53; \ | |
| 47961 | int64x1_t __ret_53; \ | |
| 47962 | __ret_53 = __noswap_vset_lane_s64(__noswap_vget_lane_s64(__s2_53, __p3_53), __s0_53, __p1_53); \ | |
| 44777 | 47963 | __ret_53; \ |
| 44778 | 47964 | }) |
| 44779 | 47965 | #endif |
| 44780 | 47966 | |
| 44781 | 47967 | #ifdef __LITTLE_ENDIAN__ |
| 44782 | #define vcopyq_laneq_u16(__p0_54, __p1_54, __p2_54, __p3_54) __extension__ ({ \ | |
| 44783 | uint16x8_t __s0_54 = __p0_54; \ | |
| 44784 | uint16x8_t __s2_54 = __p2_54; \ | |
| 44785 | uint16x8_t __ret_54; \ | |
| 44786 | __ret_54 = vsetq_lane_u16(vgetq_lane_u16(__s2_54, __p3_54), __s0_54, __p1_54); \ | |
| 47968 | #define vcopy_lane_s16(__p0_54, __p1_54, __p2_54, __p3_54) __extension__ ({ \ | |
| 47969 | int16x4_t __s0_54 = __p0_54; \ | |
| 47970 | int16x4_t __s2_54 = __p2_54; \ | |
| 47971 | int16x4_t __ret_54; \ | |
| 47972 | __ret_54 = vset_lane_s16(vget_lane_s16(__s2_54, __p3_54), __s0_54, __p1_54); \ | |
| 44787 | 47973 | __ret_54; \ |
| 44788 | 47974 | }) |
| 44789 | 47975 | #else |
| 44790 | #define vcopyq_laneq_u16(__p0_55, __p1_55, __p2_55, __p3_55) __extension__ ({ \ | |
| 44791 | uint16x8_t __s0_55 = __p0_55; \ | |
| 44792 | uint16x8_t __s2_55 = __p2_55; \ | |
| 44793 | uint16x8_t __rev0_55; __rev0_55 = __builtin_shufflevector(__s0_55, __s0_55, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44794 | uint16x8_t __rev2_55; __rev2_55 = __builtin_shufflevector(__s2_55, __s2_55, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44795 | uint16x8_t __ret_55; \ | |
| 44796 | __ret_55 = __noswap_vsetq_lane_u16(__noswap_vgetq_lane_u16(__rev2_55, __p3_55), __rev0_55, __p1_55); \ | |
| 44797 | __ret_55 = __builtin_shufflevector(__ret_55, __ret_55, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 47976 | #define vcopy_lane_s16(__p0_55, __p1_55, __p2_55, __p3_55) __extension__ ({ \ | |
| 47977 | int16x4_t __s0_55 = __p0_55; \ | |
| 47978 | int16x4_t __s2_55 = __p2_55; \ | |
| 47979 | int16x4_t __rev0_55; __rev0_55 = __builtin_shufflevector(__s0_55, __s0_55, 3, 2, 1, 0); \ | |
| 47980 | int16x4_t __rev2_55; __rev2_55 = __builtin_shufflevector(__s2_55, __s2_55, 3, 2, 1, 0); \ | |
| 47981 | int16x4_t __ret_55; \ | |
| 47982 | __ret_55 = __noswap_vset_lane_s16(__noswap_vget_lane_s16(__rev2_55, __p3_55), __rev0_55, __p1_55); \ | |
| 47983 | __ret_55 = __builtin_shufflevector(__ret_55, __ret_55, 3, 2, 1, 0); \ | |
| 44798 | 47984 | __ret_55; \ |
| 44799 | 47985 | }) |
| 44800 | 47986 | #endif |
| 44801 | 47987 | |
| 44802 | 47988 | #ifdef __LITTLE_ENDIAN__ |
| 44803 | #define vcopyq_laneq_s8(__p0_56, __p1_56, __p2_56, __p3_56) __extension__ ({ \ | |
| 44804 | int8x16_t __s0_56 = __p0_56; \ | |
| 44805 | int8x16_t __s2_56 = __p2_56; \ | |
| 44806 | int8x16_t __ret_56; \ | |
| 44807 | __ret_56 = vsetq_lane_s8(vgetq_lane_s8(__s2_56, __p3_56), __s0_56, __p1_56); \ | |
| 47989 | #define vcopyq_laneq_p8(__p0_56, __p1_56, __p2_56, __p3_56) __extension__ ({ \ | |
| 47990 | poly8x16_t __s0_56 = __p0_56; \ | |
| 47991 | poly8x16_t __s2_56 = __p2_56; \ | |
| 47992 | poly8x16_t __ret_56; \ | |
| 47993 | __ret_56 = vsetq_lane_p8(vgetq_lane_p8(__s2_56, __p3_56), __s0_56, __p1_56); \ | |
| 44808 | 47994 | __ret_56; \ |
| 44809 | 47995 | }) |
| 44810 | 47996 | #else |
| 44811 | #define vcopyq_laneq_s8(__p0_57, __p1_57, __p2_57, __p3_57) __extension__ ({ \ | |
| 44812 | int8x16_t __s0_57 = __p0_57; \ | |
| 44813 | int8x16_t __s2_57 = __p2_57; \ | |
| 44814 | int8x16_t __rev0_57; __rev0_57 = __builtin_shufflevector(__s0_57, __s0_57, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44815 | int8x16_t __rev2_57; __rev2_57 = __builtin_shufflevector(__s2_57, __s2_57, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44816 | int8x16_t __ret_57; \ | |
| 44817 | __ret_57 = __noswap_vsetq_lane_s8(__noswap_vgetq_lane_s8(__rev2_57, __p3_57), __rev0_57, __p1_57); \ | |
| 47997 | #define vcopyq_laneq_p8(__p0_57, __p1_57, __p2_57, __p3_57) __extension__ ({ \ | |
| 47998 | poly8x16_t __s0_57 = __p0_57; \ | |
| 47999 | poly8x16_t __s2_57 = __p2_57; \ | |
| 48000 | poly8x16_t __rev0_57; __rev0_57 = __builtin_shufflevector(__s0_57, __s0_57, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48001 | poly8x16_t __rev2_57; __rev2_57 = __builtin_shufflevector(__s2_57, __s2_57, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48002 | poly8x16_t __ret_57; \ | |
| 48003 | __ret_57 = __noswap_vsetq_lane_p8(__noswap_vgetq_lane_p8(__rev2_57, __p3_57), __rev0_57, __p1_57); \ | |
| 44818 | 48004 | __ret_57 = __builtin_shufflevector(__ret_57, __ret_57, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ |
| 44819 | 48005 | __ret_57; \ |
| 44820 | 48006 | }) |
| 44821 | 48007 | #endif |
| 44822 | 48008 | |
| 44823 | 48009 | #ifdef __LITTLE_ENDIAN__ |
| 44824 | #define vcopyq_laneq_f32(__p0_58, __p1_58, __p2_58, __p3_58) __extension__ ({ \ | |
| 44825 | float32x4_t __s0_58 = __p0_58; \ | |
| 44826 | float32x4_t __s2_58 = __p2_58; \ | |
| 44827 | float32x4_t __ret_58; \ | |
| 44828 | __ret_58 = vsetq_lane_f32(vgetq_lane_f32(__s2_58, __p3_58), __s0_58, __p1_58); \ | |
| 48010 | #define vcopyq_laneq_p16(__p0_58, __p1_58, __p2_58, __p3_58) __extension__ ({ \ | |
| 48011 | poly16x8_t __s0_58 = __p0_58; \ | |
| 48012 | poly16x8_t __s2_58 = __p2_58; \ | |
| 48013 | poly16x8_t __ret_58; \ | |
| 48014 | __ret_58 = vsetq_lane_p16(vgetq_lane_p16(__s2_58, __p3_58), __s0_58, __p1_58); \ | |
| 44829 | 48015 | __ret_58; \ |
| 44830 | 48016 | }) |
| 44831 | 48017 | #else |
| 44832 | #define vcopyq_laneq_f32(__p0_59, __p1_59, __p2_59, __p3_59) __extension__ ({ \ | |
| 44833 | float32x4_t __s0_59 = __p0_59; \ | |
| 44834 | float32x4_t __s2_59 = __p2_59; \ | |
| 44835 | float32x4_t __rev0_59; __rev0_59 = __builtin_shufflevector(__s0_59, __s0_59, 3, 2, 1, 0); \ | |
| 44836 | float32x4_t __rev2_59; __rev2_59 = __builtin_shufflevector(__s2_59, __s2_59, 3, 2, 1, 0); \ | |
| 44837 | float32x4_t __ret_59; \ | |
| 44838 | __ret_59 = __noswap_vsetq_lane_f32(__noswap_vgetq_lane_f32(__rev2_59, __p3_59), __rev0_59, __p1_59); \ | |
| 44839 | __ret_59 = __builtin_shufflevector(__ret_59, __ret_59, 3, 2, 1, 0); \ | |
| 48018 | #define vcopyq_laneq_p16(__p0_59, __p1_59, __p2_59, __p3_59) __extension__ ({ \ | |
| 48019 | poly16x8_t __s0_59 = __p0_59; \ | |
| 48020 | poly16x8_t __s2_59 = __p2_59; \ | |
| 48021 | poly16x8_t __rev0_59; __rev0_59 = __builtin_shufflevector(__s0_59, __s0_59, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48022 | poly16x8_t __rev2_59; __rev2_59 = __builtin_shufflevector(__s2_59, __s2_59, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48023 | poly16x8_t __ret_59; \ | |
| 48024 | __ret_59 = __noswap_vsetq_lane_p16(__noswap_vgetq_lane_p16(__rev2_59, __p3_59), __rev0_59, __p1_59); \ | |
| 48025 | __ret_59 = __builtin_shufflevector(__ret_59, __ret_59, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44840 | 48026 | __ret_59; \ |
| 44841 | 48027 | }) |
| 44842 | 48028 | #endif |
| 44843 | 48029 | |
| 44844 | 48030 | #ifdef __LITTLE_ENDIAN__ |
| 44845 | #define vcopyq_laneq_s32(__p0_60, __p1_60, __p2_60, __p3_60) __extension__ ({ \ | |
| 44846 | int32x4_t __s0_60 = __p0_60; \ | |
| 44847 | int32x4_t __s2_60 = __p2_60; \ | |
| 44848 | int32x4_t __ret_60; \ | |
| 44849 | __ret_60 = vsetq_lane_s32(vgetq_lane_s32(__s2_60, __p3_60), __s0_60, __p1_60); \ | |
| 48031 | #define vcopyq_laneq_u8(__p0_60, __p1_60, __p2_60, __p3_60) __extension__ ({ \ | |
| 48032 | uint8x16_t __s0_60 = __p0_60; \ | |
| 48033 | uint8x16_t __s2_60 = __p2_60; \ | |
| 48034 | uint8x16_t __ret_60; \ | |
| 48035 | __ret_60 = vsetq_lane_u8(vgetq_lane_u8(__s2_60, __p3_60), __s0_60, __p1_60); \ | |
| 44850 | 48036 | __ret_60; \ |
| 44851 | 48037 | }) |
| 44852 | 48038 | #else |
| 44853 | #define vcopyq_laneq_s32(__p0_61, __p1_61, __p2_61, __p3_61) __extension__ ({ \ | |
| 44854 | int32x4_t __s0_61 = __p0_61; \ | |
| 44855 | int32x4_t __s2_61 = __p2_61; \ | |
| 44856 | int32x4_t __rev0_61; __rev0_61 = __builtin_shufflevector(__s0_61, __s0_61, 3, 2, 1, 0); \ | |
| 44857 | int32x4_t __rev2_61; __rev2_61 = __builtin_shufflevector(__s2_61, __s2_61, 3, 2, 1, 0); \ | |
| 44858 | int32x4_t __ret_61; \ | |
| 44859 | __ret_61 = __noswap_vsetq_lane_s32(__noswap_vgetq_lane_s32(__rev2_61, __p3_61), __rev0_61, __p1_61); \ | |
| 44860 | __ret_61 = __builtin_shufflevector(__ret_61, __ret_61, 3, 2, 1, 0); \ | |
| 48039 | #define vcopyq_laneq_u8(__p0_61, __p1_61, __p2_61, __p3_61) __extension__ ({ \ | |
| 48040 | uint8x16_t __s0_61 = __p0_61; \ | |
| 48041 | uint8x16_t __s2_61 = __p2_61; \ | |
| 48042 | uint8x16_t __rev0_61; __rev0_61 = __builtin_shufflevector(__s0_61, __s0_61, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48043 | uint8x16_t __rev2_61; __rev2_61 = __builtin_shufflevector(__s2_61, __s2_61, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48044 | uint8x16_t __ret_61; \ | |
| 48045 | __ret_61 = __noswap_vsetq_lane_u8(__noswap_vgetq_lane_u8(__rev2_61, __p3_61), __rev0_61, __p1_61); \ | |
| 48046 | __ret_61 = __builtin_shufflevector(__ret_61, __ret_61, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44861 | 48047 | __ret_61; \ |
| 44862 | 48048 | }) |
| 44863 | 48049 | #endif |
| 44864 | 48050 | |
| 44865 | 48051 | #ifdef __LITTLE_ENDIAN__ |
| 44866 | #define vcopyq_laneq_s64(__p0_62, __p1_62, __p2_62, __p3_62) __extension__ ({ \ | |
| 44867 | int64x2_t __s0_62 = __p0_62; \ | |
| 44868 | int64x2_t __s2_62 = __p2_62; \ | |
| 44869 | int64x2_t __ret_62; \ | |
| 44870 | __ret_62 = vsetq_lane_s64(vgetq_lane_s64(__s2_62, __p3_62), __s0_62, __p1_62); \ | |
| 48052 | #define vcopyq_laneq_u32(__p0_62, __p1_62, __p2_62, __p3_62) __extension__ ({ \ | |
| 48053 | uint32x4_t __s0_62 = __p0_62; \ | |
| 48054 | uint32x4_t __s2_62 = __p2_62; \ | |
| 48055 | uint32x4_t __ret_62; \ | |
| 48056 | __ret_62 = vsetq_lane_u32(vgetq_lane_u32(__s2_62, __p3_62), __s0_62, __p1_62); \ | |
| 44871 | 48057 | __ret_62; \ |
| 44872 | 48058 | }) |
| 44873 | 48059 | #else |
| 44874 | #define vcopyq_laneq_s64(__p0_63, __p1_63, __p2_63, __p3_63) __extension__ ({ \ | |
| 44875 | int64x2_t __s0_63 = __p0_63; \ | |
| 44876 | int64x2_t __s2_63 = __p2_63; \ | |
| 44877 | int64x2_t __rev0_63; __rev0_63 = __builtin_shufflevector(__s0_63, __s0_63, 1, 0); \ | |
| 44878 | int64x2_t __rev2_63; __rev2_63 = __builtin_shufflevector(__s2_63, __s2_63, 1, 0); \ | |
| 44879 | int64x2_t __ret_63; \ | |
| 44880 | __ret_63 = __noswap_vsetq_lane_s64(__noswap_vgetq_lane_s64(__rev2_63, __p3_63), __rev0_63, __p1_63); \ | |
| 44881 | __ret_63 = __builtin_shufflevector(__ret_63, __ret_63, 1, 0); \ | |
| 48060 | #define vcopyq_laneq_u32(__p0_63, __p1_63, __p2_63, __p3_63) __extension__ ({ \ | |
| 48061 | uint32x4_t __s0_63 = __p0_63; \ | |
| 48062 | uint32x4_t __s2_63 = __p2_63; \ | |
| 48063 | uint32x4_t __rev0_63; __rev0_63 = __builtin_shufflevector(__s0_63, __s0_63, 3, 2, 1, 0); \ | |
| 48064 | uint32x4_t __rev2_63; __rev2_63 = __builtin_shufflevector(__s2_63, __s2_63, 3, 2, 1, 0); \ | |
| 48065 | uint32x4_t __ret_63; \ | |
| 48066 | __ret_63 = __noswap_vsetq_lane_u32(__noswap_vgetq_lane_u32(__rev2_63, __p3_63), __rev0_63, __p1_63); \ | |
| 48067 | __ret_63 = __builtin_shufflevector(__ret_63, __ret_63, 3, 2, 1, 0); \ | |
| 44882 | 48068 | __ret_63; \ |
| 44883 | 48069 | }) |
| 44884 | 48070 | #endif |
| 44885 | 48071 | |
| 44886 | 48072 | #ifdef __LITTLE_ENDIAN__ |
| 44887 | #define vcopyq_laneq_s16(__p0_64, __p1_64, __p2_64, __p3_64) __extension__ ({ \ | |
| 44888 | int16x8_t __s0_64 = __p0_64; \ | |
| 44889 | int16x8_t __s2_64 = __p2_64; \ | |
| 44890 | int16x8_t __ret_64; \ | |
| 44891 | __ret_64 = vsetq_lane_s16(vgetq_lane_s16(__s2_64, __p3_64), __s0_64, __p1_64); \ | |
| 48073 | #define vcopyq_laneq_u64(__p0_64, __p1_64, __p2_64, __p3_64) __extension__ ({ \ | |
| 48074 | uint64x2_t __s0_64 = __p0_64; \ | |
| 48075 | uint64x2_t __s2_64 = __p2_64; \ | |
| 48076 | uint64x2_t __ret_64; \ | |
| 48077 | __ret_64 = vsetq_lane_u64(vgetq_lane_u64(__s2_64, __p3_64), __s0_64, __p1_64); \ | |
| 44892 | 48078 | __ret_64; \ |
| 44893 | 48079 | }) |
| 44894 | 48080 | #else |
| 44895 | #define vcopyq_laneq_s16(__p0_65, __p1_65, __p2_65, __p3_65) __extension__ ({ \ | |
| 44896 | int16x8_t __s0_65 = __p0_65; \ | |
| 44897 | int16x8_t __s2_65 = __p2_65; \ | |
| 44898 | int16x8_t __rev0_65; __rev0_65 = __builtin_shufflevector(__s0_65, __s0_65, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44899 | int16x8_t __rev2_65; __rev2_65 = __builtin_shufflevector(__s2_65, __s2_65, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44900 | int16x8_t __ret_65; \ | |
| 44901 | __ret_65 = __noswap_vsetq_lane_s16(__noswap_vgetq_lane_s16(__rev2_65, __p3_65), __rev0_65, __p1_65); \ | |
| 44902 | __ret_65 = __builtin_shufflevector(__ret_65, __ret_65, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48081 | #define vcopyq_laneq_u64(__p0_65, __p1_65, __p2_65, __p3_65) __extension__ ({ \ | |
| 48082 | uint64x2_t __s0_65 = __p0_65; \ | |
| 48083 | uint64x2_t __s2_65 = __p2_65; \ | |
| 48084 | uint64x2_t __rev0_65; __rev0_65 = __builtin_shufflevector(__s0_65, __s0_65, 1, 0); \ | |
| 48085 | uint64x2_t __rev2_65; __rev2_65 = __builtin_shufflevector(__s2_65, __s2_65, 1, 0); \ | |
| 48086 | uint64x2_t __ret_65; \ | |
| 48087 | __ret_65 = __noswap_vsetq_lane_u64(__noswap_vgetq_lane_u64(__rev2_65, __p3_65), __rev0_65, __p1_65); \ | |
| 48088 | __ret_65 = __builtin_shufflevector(__ret_65, __ret_65, 1, 0); \ | |
| 44903 | 48089 | __ret_65; \ |
| 44904 | 48090 | }) |
| 44905 | 48091 | #endif |
| 44906 | 48092 | |
| 44907 | 48093 | #ifdef __LITTLE_ENDIAN__ |
| 44908 | #define vcopy_laneq_p8(__p0_66, __p1_66, __p2_66, __p3_66) __extension__ ({ \ | |
| 44909 | poly8x8_t __s0_66 = __p0_66; \ | |
| 44910 | poly8x16_t __s2_66 = __p2_66; \ | |
| 44911 | poly8x8_t __ret_66; \ | |
| 44912 | __ret_66 = vset_lane_p8(vgetq_lane_p8(__s2_66, __p3_66), __s0_66, __p1_66); \ | |
| 48094 | #define vcopyq_laneq_u16(__p0_66, __p1_66, __p2_66, __p3_66) __extension__ ({ \ | |
| 48095 | uint16x8_t __s0_66 = __p0_66; \ | |
| 48096 | uint16x8_t __s2_66 = __p2_66; \ | |
| 48097 | uint16x8_t __ret_66; \ | |
| 48098 | __ret_66 = vsetq_lane_u16(vgetq_lane_u16(__s2_66, __p3_66), __s0_66, __p1_66); \ | |
| 44913 | 48099 | __ret_66; \ |
| 44914 | 48100 | }) |
| 44915 | 48101 | #else |
| 44916 | #define vcopy_laneq_p8(__p0_67, __p1_67, __p2_67, __p3_67) __extension__ ({ \ | |
| 44917 | poly8x8_t __s0_67 = __p0_67; \ | |
| 44918 | poly8x16_t __s2_67 = __p2_67; \ | |
| 44919 | poly8x8_t __rev0_67; __rev0_67 = __builtin_shufflevector(__s0_67, __s0_67, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44920 | poly8x16_t __rev2_67; __rev2_67 = __builtin_shufflevector(__s2_67, __s2_67, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44921 | poly8x8_t __ret_67; \ | |
| 44922 | __ret_67 = __noswap_vset_lane_p8(__noswap_vgetq_lane_p8(__rev2_67, __p3_67), __rev0_67, __p1_67); \ | |
| 48102 | #define vcopyq_laneq_u16(__p0_67, __p1_67, __p2_67, __p3_67) __extension__ ({ \ | |
| 48103 | uint16x8_t __s0_67 = __p0_67; \ | |
| 48104 | uint16x8_t __s2_67 = __p2_67; \ | |
| 48105 | uint16x8_t __rev0_67; __rev0_67 = __builtin_shufflevector(__s0_67, __s0_67, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48106 | uint16x8_t __rev2_67; __rev2_67 = __builtin_shufflevector(__s2_67, __s2_67, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48107 | uint16x8_t __ret_67; \ | |
| 48108 | __ret_67 = __noswap_vsetq_lane_u16(__noswap_vgetq_lane_u16(__rev2_67, __p3_67), __rev0_67, __p1_67); \ | |
| 44923 | 48109 | __ret_67 = __builtin_shufflevector(__ret_67, __ret_67, 7, 6, 5, 4, 3, 2, 1, 0); \ |
| 44924 | 48110 | __ret_67; \ |
| 44925 | 48111 | }) |
| 44926 | 48112 | #endif |
| 44927 | 48113 | |
| 44928 | 48114 | #ifdef __LITTLE_ENDIAN__ |
| 44929 | #define vcopy_laneq_p16(__p0_68, __p1_68, __p2_68, __p3_68) __extension__ ({ \ | |
| 44930 | poly16x4_t __s0_68 = __p0_68; \ | |
| 44931 | poly16x8_t __s2_68 = __p2_68; \ | |
| 44932 | poly16x4_t __ret_68; \ | |
| 44933 | __ret_68 = vset_lane_p16(vgetq_lane_p16(__s2_68, __p3_68), __s0_68, __p1_68); \ | |
| 48115 | #define vcopyq_laneq_s8(__p0_68, __p1_68, __p2_68, __p3_68) __extension__ ({ \ | |
| 48116 | int8x16_t __s0_68 = __p0_68; \ | |
| 48117 | int8x16_t __s2_68 = __p2_68; \ | |
| 48118 | int8x16_t __ret_68; \ | |
| 48119 | __ret_68 = vsetq_lane_s8(vgetq_lane_s8(__s2_68, __p3_68), __s0_68, __p1_68); \ | |
| 44934 | 48120 | __ret_68; \ |
| 44935 | 48121 | }) |
| 44936 | 48122 | #else |
| 44937 | #define vcopy_laneq_p16(__p0_69, __p1_69, __p2_69, __p3_69) __extension__ ({ \ | |
| 44938 | poly16x4_t __s0_69 = __p0_69; \ | |
| 44939 | poly16x8_t __s2_69 = __p2_69; \ | |
| 44940 | poly16x4_t __rev0_69; __rev0_69 = __builtin_shufflevector(__s0_69, __s0_69, 3, 2, 1, 0); \ | |
| 44941 | poly16x8_t __rev2_69; __rev2_69 = __builtin_shufflevector(__s2_69, __s2_69, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44942 | poly16x4_t __ret_69; \ | |
| 44943 | __ret_69 = __noswap_vset_lane_p16(__noswap_vgetq_lane_p16(__rev2_69, __p3_69), __rev0_69, __p1_69); \ | |
| 44944 | __ret_69 = __builtin_shufflevector(__ret_69, __ret_69, 3, 2, 1, 0); \ | |
| 48123 | #define vcopyq_laneq_s8(__p0_69, __p1_69, __p2_69, __p3_69) __extension__ ({ \ | |
| 48124 | int8x16_t __s0_69 = __p0_69; \ | |
| 48125 | int8x16_t __s2_69 = __p2_69; \ | |
| 48126 | int8x16_t __rev0_69; __rev0_69 = __builtin_shufflevector(__s0_69, __s0_69, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48127 | int8x16_t __rev2_69; __rev2_69 = __builtin_shufflevector(__s2_69, __s2_69, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48128 | int8x16_t __ret_69; \ | |
| 48129 | __ret_69 = __noswap_vsetq_lane_s8(__noswap_vgetq_lane_s8(__rev2_69, __p3_69), __rev0_69, __p1_69); \ | |
| 48130 | __ret_69 = __builtin_shufflevector(__ret_69, __ret_69, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44945 | 48131 | __ret_69; \ |
| 44946 | 48132 | }) |
| 44947 | 48133 | #endif |
| 44948 | 48134 | |
| 44949 | 48135 | #ifdef __LITTLE_ENDIAN__ |
| 44950 | #define vcopy_laneq_u8(__p0_70, __p1_70, __p2_70, __p3_70) __extension__ ({ \ | |
| 44951 | uint8x8_t __s0_70 = __p0_70; \ | |
| 44952 | uint8x16_t __s2_70 = __p2_70; \ | |
| 44953 | uint8x8_t __ret_70; \ | |
| 44954 | __ret_70 = vset_lane_u8(vgetq_lane_u8(__s2_70, __p3_70), __s0_70, __p1_70); \ | |
| 48136 | #define vcopyq_laneq_f32(__p0_70, __p1_70, __p2_70, __p3_70) __extension__ ({ \ | |
| 48137 | float32x4_t __s0_70 = __p0_70; \ | |
| 48138 | float32x4_t __s2_70 = __p2_70; \ | |
| 48139 | float32x4_t __ret_70; \ | |
| 48140 | __ret_70 = vsetq_lane_f32(vgetq_lane_f32(__s2_70, __p3_70), __s0_70, __p1_70); \ | |
| 44955 | 48141 | __ret_70; \ |
| 44956 | 48142 | }) |
| 44957 | 48143 | #else |
| 44958 | #define vcopy_laneq_u8(__p0_71, __p1_71, __p2_71, __p3_71) __extension__ ({ \ | |
| 44959 | uint8x8_t __s0_71 = __p0_71; \ | |
| 44960 | uint8x16_t __s2_71 = __p2_71; \ | |
| 44961 | uint8x8_t __rev0_71; __rev0_71 = __builtin_shufflevector(__s0_71, __s0_71, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44962 | uint8x16_t __rev2_71; __rev2_71 = __builtin_shufflevector(__s2_71, __s2_71, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 44963 | uint8x8_t __ret_71; \ | |
| 44964 | __ret_71 = __noswap_vset_lane_u8(__noswap_vgetq_lane_u8(__rev2_71, __p3_71), __rev0_71, __p1_71); \ | |
| 44965 | __ret_71 = __builtin_shufflevector(__ret_71, __ret_71, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48144 | #define vcopyq_laneq_f32(__p0_71, __p1_71, __p2_71, __p3_71) __extension__ ({ \ | |
| 48145 | float32x4_t __s0_71 = __p0_71; \ | |
| 48146 | float32x4_t __s2_71 = __p2_71; \ | |
| 48147 | float32x4_t __rev0_71; __rev0_71 = __builtin_shufflevector(__s0_71, __s0_71, 3, 2, 1, 0); \ | |
| 48148 | float32x4_t __rev2_71; __rev2_71 = __builtin_shufflevector(__s2_71, __s2_71, 3, 2, 1, 0); \ | |
| 48149 | float32x4_t __ret_71; \ | |
| 48150 | __ret_71 = __noswap_vsetq_lane_f32(__noswap_vgetq_lane_f32(__rev2_71, __p3_71), __rev0_71, __p1_71); \ | |
| 48151 | __ret_71 = __builtin_shufflevector(__ret_71, __ret_71, 3, 2, 1, 0); \ | |
| 44966 | 48152 | __ret_71; \ |
| 44967 | 48153 | }) |
| 44968 | 48154 | #endif |
| 44969 | 48155 | |
| 44970 | 48156 | #ifdef __LITTLE_ENDIAN__ |
| 44971 | #define vcopy_laneq_u32(__p0_72, __p1_72, __p2_72, __p3_72) __extension__ ({ \ | |
| 44972 | uint32x2_t __s0_72 = __p0_72; \ | |
| 44973 | uint32x4_t __s2_72 = __p2_72; \ | |
| 44974 | uint32x2_t __ret_72; \ | |
| 44975 | __ret_72 = vset_lane_u32(vgetq_lane_u32(__s2_72, __p3_72), __s0_72, __p1_72); \ | |
| 48157 | #define vcopyq_laneq_s32(__p0_72, __p1_72, __p2_72, __p3_72) __extension__ ({ \ | |
| 48158 | int32x4_t __s0_72 = __p0_72; \ | |
| 48159 | int32x4_t __s2_72 = __p2_72; \ | |
| 48160 | int32x4_t __ret_72; \ | |
| 48161 | __ret_72 = vsetq_lane_s32(vgetq_lane_s32(__s2_72, __p3_72), __s0_72, __p1_72); \ | |
| 44976 | 48162 | __ret_72; \ |
| 44977 | 48163 | }) |
| 44978 | 48164 | #else |
| 44979 | #define vcopy_laneq_u32(__p0_73, __p1_73, __p2_73, __p3_73) __extension__ ({ \ | |
| 44980 | uint32x2_t __s0_73 = __p0_73; \ | |
| 44981 | uint32x4_t __s2_73 = __p2_73; \ | |
| 44982 | uint32x2_t __rev0_73; __rev0_73 = __builtin_shufflevector(__s0_73, __s0_73, 1, 0); \ | |
| 44983 | uint32x4_t __rev2_73; __rev2_73 = __builtin_shufflevector(__s2_73, __s2_73, 3, 2, 1, 0); \ | |
| 44984 | uint32x2_t __ret_73; \ | |
| 44985 | __ret_73 = __noswap_vset_lane_u32(__noswap_vgetq_lane_u32(__rev2_73, __p3_73), __rev0_73, __p1_73); \ | |
| 44986 | __ret_73 = __builtin_shufflevector(__ret_73, __ret_73, 1, 0); \ | |
| 48165 | #define vcopyq_laneq_s32(__p0_73, __p1_73, __p2_73, __p3_73) __extension__ ({ \ | |
| 48166 | int32x4_t __s0_73 = __p0_73; \ | |
| 48167 | int32x4_t __s2_73 = __p2_73; \ | |
| 48168 | int32x4_t __rev0_73; __rev0_73 = __builtin_shufflevector(__s0_73, __s0_73, 3, 2, 1, 0); \ | |
| 48169 | int32x4_t __rev2_73; __rev2_73 = __builtin_shufflevector(__s2_73, __s2_73, 3, 2, 1, 0); \ | |
| 48170 | int32x4_t __ret_73; \ | |
| 48171 | __ret_73 = __noswap_vsetq_lane_s32(__noswap_vgetq_lane_s32(__rev2_73, __p3_73), __rev0_73, __p1_73); \ | |
| 48172 | __ret_73 = __builtin_shufflevector(__ret_73, __ret_73, 3, 2, 1, 0); \ | |
| 44987 | 48173 | __ret_73; \ |
| 44988 | 48174 | }) |
| 44989 | 48175 | #endif |
| 44990 | 48176 | |
| 44991 | 48177 | #ifdef __LITTLE_ENDIAN__ |
| 44992 | #define vcopy_laneq_u64(__p0_74, __p1_74, __p2_74, __p3_74) __extension__ ({ \ | |
| 44993 | uint64x1_t __s0_74 = __p0_74; \ | |
| 44994 | uint64x2_t __s2_74 = __p2_74; \ | |
| 44995 | uint64x1_t __ret_74; \ | |
| 44996 | __ret_74 = vset_lane_u64(vgetq_lane_u64(__s2_74, __p3_74), __s0_74, __p1_74); \ | |
| 48178 | #define vcopyq_laneq_s64(__p0_74, __p1_74, __p2_74, __p3_74) __extension__ ({ \ | |
| 48179 | int64x2_t __s0_74 = __p0_74; \ | |
| 48180 | int64x2_t __s2_74 = __p2_74; \ | |
| 48181 | int64x2_t __ret_74; \ | |
| 48182 | __ret_74 = vsetq_lane_s64(vgetq_lane_s64(__s2_74, __p3_74), __s0_74, __p1_74); \ | |
| 44997 | 48183 | __ret_74; \ |
| 44998 | 48184 | }) |
| 44999 | 48185 | #else |
| 45000 | #define vcopy_laneq_u64(__p0_75, __p1_75, __p2_75, __p3_75) __extension__ ({ \ | |
| 45001 | uint64x1_t __s0_75 = __p0_75; \ | |
| 45002 | uint64x2_t __s2_75 = __p2_75; \ | |
| 45003 | uint64x2_t __rev2_75; __rev2_75 = __builtin_shufflevector(__s2_75, __s2_75, 1, 0); \ | |
| 45004 | uint64x1_t __ret_75; \ | |
| 45005 | __ret_75 = __noswap_vset_lane_u64(__noswap_vgetq_lane_u64(__rev2_75, __p3_75), __s0_75, __p1_75); \ | |
| 48186 | #define vcopyq_laneq_s64(__p0_75, __p1_75, __p2_75, __p3_75) __extension__ ({ \ | |
| 48187 | int64x2_t __s0_75 = __p0_75; \ | |
| 48188 | int64x2_t __s2_75 = __p2_75; \ | |
| 48189 | int64x2_t __rev0_75; __rev0_75 = __builtin_shufflevector(__s0_75, __s0_75, 1, 0); \ | |
| 48190 | int64x2_t __rev2_75; __rev2_75 = __builtin_shufflevector(__s2_75, __s2_75, 1, 0); \ | |
| 48191 | int64x2_t __ret_75; \ | |
| 48192 | __ret_75 = __noswap_vsetq_lane_s64(__noswap_vgetq_lane_s64(__rev2_75, __p3_75), __rev0_75, __p1_75); \ | |
| 48193 | __ret_75 = __builtin_shufflevector(__ret_75, __ret_75, 1, 0); \ | |
| 45006 | 48194 | __ret_75; \ |
| 45007 | 48195 | }) |
| 45008 | 48196 | #endif |
| 45009 | 48197 | |
| 45010 | 48198 | #ifdef __LITTLE_ENDIAN__ |
| 45011 | #define vcopy_laneq_u16(__p0_76, __p1_76, __p2_76, __p3_76) __extension__ ({ \ | |
| 45012 | uint16x4_t __s0_76 = __p0_76; \ | |
| 45013 | uint16x8_t __s2_76 = __p2_76; \ | |
| 45014 | uint16x4_t __ret_76; \ | |
| 45015 | __ret_76 = vset_lane_u16(vgetq_lane_u16(__s2_76, __p3_76), __s0_76, __p1_76); \ | |
| 48199 | #define vcopyq_laneq_s16(__p0_76, __p1_76, __p2_76, __p3_76) __extension__ ({ \ | |
| 48200 | int16x8_t __s0_76 = __p0_76; \ | |
| 48201 | int16x8_t __s2_76 = __p2_76; \ | |
| 48202 | int16x8_t __ret_76; \ | |
| 48203 | __ret_76 = vsetq_lane_s16(vgetq_lane_s16(__s2_76, __p3_76), __s0_76, __p1_76); \ | |
| 45016 | 48204 | __ret_76; \ |
| 45017 | 48205 | }) |
| 45018 | 48206 | #else |
| 45019 | #define vcopy_laneq_u16(__p0_77, __p1_77, __p2_77, __p3_77) __extension__ ({ \ | |
| 45020 | uint16x4_t __s0_77 = __p0_77; \ | |
| 45021 | uint16x8_t __s2_77 = __p2_77; \ | |
| 45022 | uint16x4_t __rev0_77; __rev0_77 = __builtin_shufflevector(__s0_77, __s0_77, 3, 2, 1, 0); \ | |
| 45023 | uint16x8_t __rev2_77; __rev2_77 = __builtin_shufflevector(__s2_77, __s2_77, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 45024 | uint16x4_t __ret_77; \ | |
| 45025 | __ret_77 = __noswap_vset_lane_u16(__noswap_vgetq_lane_u16(__rev2_77, __p3_77), __rev0_77, __p1_77); \ | |
| 45026 | __ret_77 = __builtin_shufflevector(__ret_77, __ret_77, 3, 2, 1, 0); \ | |
| 48207 | #define vcopyq_laneq_s16(__p0_77, __p1_77, __p2_77, __p3_77) __extension__ ({ \ | |
| 48208 | int16x8_t __s0_77 = __p0_77; \ | |
| 48209 | int16x8_t __s2_77 = __p2_77; \ | |
| 48210 | int16x8_t __rev0_77; __rev0_77 = __builtin_shufflevector(__s0_77, __s0_77, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48211 | int16x8_t __rev2_77; __rev2_77 = __builtin_shufflevector(__s2_77, __s2_77, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48212 | int16x8_t __ret_77; \ | |
| 48213 | __ret_77 = __noswap_vsetq_lane_s16(__noswap_vgetq_lane_s16(__rev2_77, __p3_77), __rev0_77, __p1_77); \ | |
| 48214 | __ret_77 = __builtin_shufflevector(__ret_77, __ret_77, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 45027 | 48215 | __ret_77; \ |
| 45028 | 48216 | }) |
| 45029 | 48217 | #endif |
| 45030 | 48218 | |
| 45031 | 48219 | #ifdef __LITTLE_ENDIAN__ |
| 45032 | #define vcopy_laneq_s8(__p0_78, __p1_78, __p2_78, __p3_78) __extension__ ({ \ | |
| 45033 | int8x8_t __s0_78 = __p0_78; \ | |
| 45034 | int8x16_t __s2_78 = __p2_78; \ | |
| 45035 | int8x8_t __ret_78; \ | |
| 45036 | __ret_78 = vset_lane_s8(vgetq_lane_s8(__s2_78, __p3_78), __s0_78, __p1_78); \ | |
| 48220 | #define vcopy_laneq_p8(__p0_78, __p1_78, __p2_78, __p3_78) __extension__ ({ \ | |
| 48221 | poly8x8_t __s0_78 = __p0_78; \ | |
| 48222 | poly8x16_t __s2_78 = __p2_78; \ | |
| 48223 | poly8x8_t __ret_78; \ | |
| 48224 | __ret_78 = vset_lane_p8(vgetq_lane_p8(__s2_78, __p3_78), __s0_78, __p1_78); \ | |
| 45037 | 48225 | __ret_78; \ |
| 45038 | 48226 | }) |
| 45039 | 48227 | #else |
| 45040 | #define vcopy_laneq_s8(__p0_79, __p1_79, __p2_79, __p3_79) __extension__ ({ \ | |
| 45041 | int8x8_t __s0_79 = __p0_79; \ | |
| 45042 | int8x16_t __s2_79 = __p2_79; \ | |
| 45043 | int8x8_t __rev0_79; __rev0_79 = __builtin_shufflevector(__s0_79, __s0_79, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 45044 | int8x16_t __rev2_79; __rev2_79 = __builtin_shufflevector(__s2_79, __s2_79, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 45045 | int8x8_t __ret_79; \ | |
| 45046 | __ret_79 = __noswap_vset_lane_s8(__noswap_vgetq_lane_s8(__rev2_79, __p3_79), __rev0_79, __p1_79); \ | |
| 48228 | #define vcopy_laneq_p8(__p0_79, __p1_79, __p2_79, __p3_79) __extension__ ({ \ | |
| 48229 | poly8x8_t __s0_79 = __p0_79; \ | |
| 48230 | poly8x16_t __s2_79 = __p2_79; \ | |
| 48231 | poly8x8_t __rev0_79; __rev0_79 = __builtin_shufflevector(__s0_79, __s0_79, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48232 | poly8x16_t __rev2_79; __rev2_79 = __builtin_shufflevector(__s2_79, __s2_79, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48233 | poly8x8_t __ret_79; \ | |
| 48234 | __ret_79 = __noswap_vset_lane_p8(__noswap_vgetq_lane_p8(__rev2_79, __p3_79), __rev0_79, __p1_79); \ | |
| 45047 | 48235 | __ret_79 = __builtin_shufflevector(__ret_79, __ret_79, 7, 6, 5, 4, 3, 2, 1, 0); \ |
| 45048 | 48236 | __ret_79; \ |
| 45049 | 48237 | }) |
| 45050 | 48238 | #endif |
| 45051 | 48239 | |
| 45052 | 48240 | #ifdef __LITTLE_ENDIAN__ |
| 45053 | #define vcopy_laneq_f32(__p0_80, __p1_80, __p2_80, __p3_80) __extension__ ({ \ | |
| 45054 | float32x2_t __s0_80 = __p0_80; \ | |
| 45055 | float32x4_t __s2_80 = __p2_80; \ | |
| 45056 | float32x2_t __ret_80; \ | |
| 45057 | __ret_80 = vset_lane_f32(vgetq_lane_f32(__s2_80, __p3_80), __s0_80, __p1_80); \ | |
| 48241 | #define vcopy_laneq_p16(__p0_80, __p1_80, __p2_80, __p3_80) __extension__ ({ \ | |
| 48242 | poly16x4_t __s0_80 = __p0_80; \ | |
| 48243 | poly16x8_t __s2_80 = __p2_80; \ | |
| 48244 | poly16x4_t __ret_80; \ | |
| 48245 | __ret_80 = vset_lane_p16(vgetq_lane_p16(__s2_80, __p3_80), __s0_80, __p1_80); \ | |
| 45058 | 48246 | __ret_80; \ |
| 45059 | 48247 | }) |
| 45060 | 48248 | #else |
| 45061 | #define vcopy_laneq_f32(__p0_81, __p1_81, __p2_81, __p3_81) __extension__ ({ \ | |
| 45062 | float32x2_t __s0_81 = __p0_81; \ | |
| 45063 | float32x4_t __s2_81 = __p2_81; \ | |
| 45064 | float32x2_t __rev0_81; __rev0_81 = __builtin_shufflevector(__s0_81, __s0_81, 1, 0); \ | |
| 45065 | float32x4_t __rev2_81; __rev2_81 = __builtin_shufflevector(__s2_81, __s2_81, 3, 2, 1, 0); \ | |
| 45066 | float32x2_t __ret_81; \ | |
| 45067 | __ret_81 = __noswap_vset_lane_f32(__noswap_vgetq_lane_f32(__rev2_81, __p3_81), __rev0_81, __p1_81); \ | |
| 45068 | __ret_81 = __builtin_shufflevector(__ret_81, __ret_81, 1, 0); \ | |
| 48249 | #define vcopy_laneq_p16(__p0_81, __p1_81, __p2_81, __p3_81) __extension__ ({ \ | |
| 48250 | poly16x4_t __s0_81 = __p0_81; \ | |
| 48251 | poly16x8_t __s2_81 = __p2_81; \ | |
| 48252 | poly16x4_t __rev0_81; __rev0_81 = __builtin_shufflevector(__s0_81, __s0_81, 3, 2, 1, 0); \ | |
| 48253 | poly16x8_t __rev2_81; __rev2_81 = __builtin_shufflevector(__s2_81, __s2_81, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48254 | poly16x4_t __ret_81; \ | |
| 48255 | __ret_81 = __noswap_vset_lane_p16(__noswap_vgetq_lane_p16(__rev2_81, __p3_81), __rev0_81, __p1_81); \ | |
| 48256 | __ret_81 = __builtin_shufflevector(__ret_81, __ret_81, 3, 2, 1, 0); \ | |
| 45069 | 48257 | __ret_81; \ |
| 45070 | 48258 | }) |
| 45071 | 48259 | #endif |
| 45072 | 48260 | |
| 45073 | 48261 | #ifdef __LITTLE_ENDIAN__ |
| 45074 | #define vcopy_laneq_s32(__p0_82, __p1_82, __p2_82, __p3_82) __extension__ ({ \ | |
| 45075 | int32x2_t __s0_82 = __p0_82; \ | |
| 45076 | int32x4_t __s2_82 = __p2_82; \ | |
| 45077 | int32x2_t __ret_82; \ | |
| 45078 | __ret_82 = vset_lane_s32(vgetq_lane_s32(__s2_82, __p3_82), __s0_82, __p1_82); \ | |
| 48262 | #define vcopy_laneq_u8(__p0_82, __p1_82, __p2_82, __p3_82) __extension__ ({ \ | |
| 48263 | uint8x8_t __s0_82 = __p0_82; \ | |
| 48264 | uint8x16_t __s2_82 = __p2_82; \ | |
| 48265 | uint8x8_t __ret_82; \ | |
| 48266 | __ret_82 = vset_lane_u8(vgetq_lane_u8(__s2_82, __p3_82), __s0_82, __p1_82); \ | |
| 45079 | 48267 | __ret_82; \ |
| 45080 | 48268 | }) |
| 45081 | 48269 | #else |
| 45082 | #define vcopy_laneq_s32(__p0_83, __p1_83, __p2_83, __p3_83) __extension__ ({ \ | |
| 45083 | int32x2_t __s0_83 = __p0_83; \ | |
| 45084 | int32x4_t __s2_83 = __p2_83; \ | |
| 45085 | int32x2_t __rev0_83; __rev0_83 = __builtin_shufflevector(__s0_83, __s0_83, 1, 0); \ | |
| 45086 | int32x4_t __rev2_83; __rev2_83 = __builtin_shufflevector(__s2_83, __s2_83, 3, 2, 1, 0); \ | |
| 45087 | int32x2_t __ret_83; \ | |
| 45088 | __ret_83 = __noswap_vset_lane_s32(__noswap_vgetq_lane_s32(__rev2_83, __p3_83), __rev0_83, __p1_83); \ | |
| 45089 | __ret_83 = __builtin_shufflevector(__ret_83, __ret_83, 1, 0); \ | |
| 48270 | #define vcopy_laneq_u8(__p0_83, __p1_83, __p2_83, __p3_83) __extension__ ({ \ | |
| 48271 | uint8x8_t __s0_83 = __p0_83; \ | |
| 48272 | uint8x16_t __s2_83 = __p2_83; \ | |
| 48273 | uint8x8_t __rev0_83; __rev0_83 = __builtin_shufflevector(__s0_83, __s0_83, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48274 | uint8x16_t __rev2_83; __rev2_83 = __builtin_shufflevector(__s2_83, __s2_83, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48275 | uint8x8_t __ret_83; \ | |
| 48276 | __ret_83 = __noswap_vset_lane_u8(__noswap_vgetq_lane_u8(__rev2_83, __p3_83), __rev0_83, __p1_83); \ | |
| 48277 | __ret_83 = __builtin_shufflevector(__ret_83, __ret_83, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 45090 | 48278 | __ret_83; \ |
| 45091 | 48279 | }) |
| 45092 | 48280 | #endif |
| 45093 | 48281 | |
| 45094 | 48282 | #ifdef __LITTLE_ENDIAN__ |
| 45095 | #define vcopy_laneq_s64(__p0_84, __p1_84, __p2_84, __p3_84) __extension__ ({ \ | |
| 45096 | int64x1_t __s0_84 = __p0_84; \ | |
| 45097 | int64x2_t __s2_84 = __p2_84; \ | |
| 45098 | int64x1_t __ret_84; \ | |
| 45099 | __ret_84 = vset_lane_s64(vgetq_lane_s64(__s2_84, __p3_84), __s0_84, __p1_84); \ | |
| 48283 | #define vcopy_laneq_u32(__p0_84, __p1_84, __p2_84, __p3_84) __extension__ ({ \ | |
| 48284 | uint32x2_t __s0_84 = __p0_84; \ | |
| 48285 | uint32x4_t __s2_84 = __p2_84; \ | |
| 48286 | uint32x2_t __ret_84; \ | |
| 48287 | __ret_84 = vset_lane_u32(vgetq_lane_u32(__s2_84, __p3_84), __s0_84, __p1_84); \ | |
| 45100 | 48288 | __ret_84; \ |
| 45101 | 48289 | }) |
| 45102 | 48290 | #else |
| 45103 | #define vcopy_laneq_s64(__p0_85, __p1_85, __p2_85, __p3_85) __extension__ ({ \ | |
| 45104 | int64x1_t __s0_85 = __p0_85; \ | |
| 45105 | int64x2_t __s2_85 = __p2_85; \ | |
| 45106 | int64x2_t __rev2_85; __rev2_85 = __builtin_shufflevector(__s2_85, __s2_85, 1, 0); \ | |
| 45107 | int64x1_t __ret_85; \ | |
| 45108 | __ret_85 = __noswap_vset_lane_s64(__noswap_vgetq_lane_s64(__rev2_85, __p3_85), __s0_85, __p1_85); \ | |
| 48291 | #define vcopy_laneq_u32(__p0_85, __p1_85, __p2_85, __p3_85) __extension__ ({ \ | |
| 48292 | uint32x2_t __s0_85 = __p0_85; \ | |
| 48293 | uint32x4_t __s2_85 = __p2_85; \ | |
| 48294 | uint32x2_t __rev0_85; __rev0_85 = __builtin_shufflevector(__s0_85, __s0_85, 1, 0); \ | |
| 48295 | uint32x4_t __rev2_85; __rev2_85 = __builtin_shufflevector(__s2_85, __s2_85, 3, 2, 1, 0); \ | |
| 48296 | uint32x2_t __ret_85; \ | |
| 48297 | __ret_85 = __noswap_vset_lane_u32(__noswap_vgetq_lane_u32(__rev2_85, __p3_85), __rev0_85, __p1_85); \ | |
| 48298 | __ret_85 = __builtin_shufflevector(__ret_85, __ret_85, 1, 0); \ | |
| 45109 | 48299 | __ret_85; \ |
| 45110 | 48300 | }) |
| 45111 | 48301 | #endif |
| 45112 | 48302 | |
| 45113 | 48303 | #ifdef __LITTLE_ENDIAN__ |
| 45114 | #define vcopy_laneq_s16(__p0_86, __p1_86, __p2_86, __p3_86) __extension__ ({ \ | |
| 45115 | int16x4_t __s0_86 = __p0_86; \ | |
| 45116 | int16x8_t __s2_86 = __p2_86; \ | |
| 45117 | int16x4_t __ret_86; \ | |
| 45118 | __ret_86 = vset_lane_s16(vgetq_lane_s16(__s2_86, __p3_86), __s0_86, __p1_86); \ | |
| 48304 | #define vcopy_laneq_u64(__p0_86, __p1_86, __p2_86, __p3_86) __extension__ ({ \ | |
| 48305 | uint64x1_t __s0_86 = __p0_86; \ | |
| 48306 | uint64x2_t __s2_86 = __p2_86; \ | |
| 48307 | uint64x1_t __ret_86; \ | |
| 48308 | __ret_86 = vset_lane_u64(vgetq_lane_u64(__s2_86, __p3_86), __s0_86, __p1_86); \ | |
| 45119 | 48309 | __ret_86; \ |
| 45120 | 48310 | }) |
| 45121 | 48311 | #else |
| 45122 | #define vcopy_laneq_s16(__p0_87, __p1_87, __p2_87, __p3_87) __extension__ ({ \ | |
| 45123 | int16x4_t __s0_87 = __p0_87; \ | |
| 45124 | int16x8_t __s2_87 = __p2_87; \ | |
| 45125 | int16x4_t __rev0_87; __rev0_87 = __builtin_shufflevector(__s0_87, __s0_87, 3, 2, 1, 0); \ | |
| 45126 | int16x8_t __rev2_87; __rev2_87 = __builtin_shufflevector(__s2_87, __s2_87, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 45127 | int16x4_t __ret_87; \ | |
| 45128 | __ret_87 = __noswap_vset_lane_s16(__noswap_vgetq_lane_s16(__rev2_87, __p3_87), __rev0_87, __p1_87); \ | |
| 45129 | __ret_87 = __builtin_shufflevector(__ret_87, __ret_87, 3, 2, 1, 0); \ | |
| 48312 | #define vcopy_laneq_u64(__p0_87, __p1_87, __p2_87, __p3_87) __extension__ ({ \ | |
| 48313 | uint64x1_t __s0_87 = __p0_87; \ | |
| 48314 | uint64x2_t __s2_87 = __p2_87; \ | |
| 48315 | uint64x2_t __rev2_87; __rev2_87 = __builtin_shufflevector(__s2_87, __s2_87, 1, 0); \ | |
| 48316 | uint64x1_t __ret_87; \ | |
| 48317 | __ret_87 = __noswap_vset_lane_u64(__noswap_vgetq_lane_u64(__rev2_87, __p3_87), __s0_87, __p1_87); \ | |
| 45130 | 48318 | __ret_87; \ |
| 45131 | 48319 | }) |
| 45132 | 48320 | #endif |
| 45133 | 48321 | |
| 48322 | #ifdef __LITTLE_ENDIAN__ | |
| 48323 | #define vcopy_laneq_u16(__p0_88, __p1_88, __p2_88, __p3_88) __extension__ ({ \ | |
| 48324 | uint16x4_t __s0_88 = __p0_88; \ | |
| 48325 | uint16x8_t __s2_88 = __p2_88; \ | |
| 48326 | uint16x4_t __ret_88; \ | |
| 48327 | __ret_88 = vset_lane_u16(vgetq_lane_u16(__s2_88, __p3_88), __s0_88, __p1_88); \ | |
| 48328 | __ret_88; \ | |
| 48329 | }) | |
| 48330 | #else | |
| 48331 | #define vcopy_laneq_u16(__p0_89, __p1_89, __p2_89, __p3_89) __extension__ ({ \ | |
| 48332 | uint16x4_t __s0_89 = __p0_89; \ | |
| 48333 | uint16x8_t __s2_89 = __p2_89; \ | |
| 48334 | uint16x4_t __rev0_89; __rev0_89 = __builtin_shufflevector(__s0_89, __s0_89, 3, 2, 1, 0); \ | |
| 48335 | uint16x8_t __rev2_89; __rev2_89 = __builtin_shufflevector(__s2_89, __s2_89, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48336 | uint16x4_t __ret_89; \ | |
| 48337 | __ret_89 = __noswap_vset_lane_u16(__noswap_vgetq_lane_u16(__rev2_89, __p3_89), __rev0_89, __p1_89); \ | |
| 48338 | __ret_89 = __builtin_shufflevector(__ret_89, __ret_89, 3, 2, 1, 0); \ | |
| 48339 | __ret_89; \ | |
| 48340 | }) | |
| 48341 | #endif | |
| 48342 | ||
| 48343 | #ifdef __LITTLE_ENDIAN__ | |
| 48344 | #define vcopy_laneq_s8(__p0_90, __p1_90, __p2_90, __p3_90) __extension__ ({ \ | |
| 48345 | int8x8_t __s0_90 = __p0_90; \ | |
| 48346 | int8x16_t __s2_90 = __p2_90; \ | |
| 48347 | int8x8_t __ret_90; \ | |
| 48348 | __ret_90 = vset_lane_s8(vgetq_lane_s8(__s2_90, __p3_90), __s0_90, __p1_90); \ | |
| 48349 | __ret_90; \ | |
| 48350 | }) | |
| 48351 | #else | |
| 48352 | #define vcopy_laneq_s8(__p0_91, __p1_91, __p2_91, __p3_91) __extension__ ({ \ | |
| 48353 | int8x8_t __s0_91 = __p0_91; \ | |
| 48354 | int8x16_t __s2_91 = __p2_91; \ | |
| 48355 | int8x8_t __rev0_91; __rev0_91 = __builtin_shufflevector(__s0_91, __s0_91, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48356 | int8x16_t __rev2_91; __rev2_91 = __builtin_shufflevector(__s2_91, __s2_91, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48357 | int8x8_t __ret_91; \ | |
| 48358 | __ret_91 = __noswap_vset_lane_s8(__noswap_vgetq_lane_s8(__rev2_91, __p3_91), __rev0_91, __p1_91); \ | |
| 48359 | __ret_91 = __builtin_shufflevector(__ret_91, __ret_91, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48360 | __ret_91; \ | |
| 48361 | }) | |
| 48362 | #endif | |
| 48363 | ||
| 48364 | #ifdef __LITTLE_ENDIAN__ | |
| 48365 | #define vcopy_laneq_f32(__p0_92, __p1_92, __p2_92, __p3_92) __extension__ ({ \ | |
| 48366 | float32x2_t __s0_92 = __p0_92; \ | |
| 48367 | float32x4_t __s2_92 = __p2_92; \ | |
| 48368 | float32x2_t __ret_92; \ | |
| 48369 | __ret_92 = vset_lane_f32(vgetq_lane_f32(__s2_92, __p3_92), __s0_92, __p1_92); \ | |
| 48370 | __ret_92; \ | |
| 48371 | }) | |
| 48372 | #else | |
| 48373 | #define vcopy_laneq_f32(__p0_93, __p1_93, __p2_93, __p3_93) __extension__ ({ \ | |
| 48374 | float32x2_t __s0_93 = __p0_93; \ | |
| 48375 | float32x4_t __s2_93 = __p2_93; \ | |
| 48376 | float32x2_t __rev0_93; __rev0_93 = __builtin_shufflevector(__s0_93, __s0_93, 1, 0); \ | |
| 48377 | float32x4_t __rev2_93; __rev2_93 = __builtin_shufflevector(__s2_93, __s2_93, 3, 2, 1, 0); \ | |
| 48378 | float32x2_t __ret_93; \ | |
| 48379 | __ret_93 = __noswap_vset_lane_f32(__noswap_vgetq_lane_f32(__rev2_93, __p3_93), __rev0_93, __p1_93); \ | |
| 48380 | __ret_93 = __builtin_shufflevector(__ret_93, __ret_93, 1, 0); \ | |
| 48381 | __ret_93; \ | |
| 48382 | }) | |
| 48383 | #endif | |
| 48384 | ||
| 48385 | #ifdef __LITTLE_ENDIAN__ | |
| 48386 | #define vcopy_laneq_s32(__p0_94, __p1_94, __p2_94, __p3_94) __extension__ ({ \ | |
| 48387 | int32x2_t __s0_94 = __p0_94; \ | |
| 48388 | int32x4_t __s2_94 = __p2_94; \ | |
| 48389 | int32x2_t __ret_94; \ | |
| 48390 | __ret_94 = vset_lane_s32(vgetq_lane_s32(__s2_94, __p3_94), __s0_94, __p1_94); \ | |
| 48391 | __ret_94; \ | |
| 48392 | }) | |
| 48393 | #else | |
| 48394 | #define vcopy_laneq_s32(__p0_95, __p1_95, __p2_95, __p3_95) __extension__ ({ \ | |
| 48395 | int32x2_t __s0_95 = __p0_95; \ | |
| 48396 | int32x4_t __s2_95 = __p2_95; \ | |
| 48397 | int32x2_t __rev0_95; __rev0_95 = __builtin_shufflevector(__s0_95, __s0_95, 1, 0); \ | |
| 48398 | int32x4_t __rev2_95; __rev2_95 = __builtin_shufflevector(__s2_95, __s2_95, 3, 2, 1, 0); \ | |
| 48399 | int32x2_t __ret_95; \ | |
| 48400 | __ret_95 = __noswap_vset_lane_s32(__noswap_vgetq_lane_s32(__rev2_95, __p3_95), __rev0_95, __p1_95); \ | |
| 48401 | __ret_95 = __builtin_shufflevector(__ret_95, __ret_95, 1, 0); \ | |
| 48402 | __ret_95; \ | |
| 48403 | }) | |
| 48404 | #endif | |
| 48405 | ||
| 48406 | #ifdef __LITTLE_ENDIAN__ | |
| 48407 | #define vcopy_laneq_s64(__p0_96, __p1_96, __p2_96, __p3_96) __extension__ ({ \ | |
| 48408 | int64x1_t __s0_96 = __p0_96; \ | |
| 48409 | int64x2_t __s2_96 = __p2_96; \ | |
| 48410 | int64x1_t __ret_96; \ | |
| 48411 | __ret_96 = vset_lane_s64(vgetq_lane_s64(__s2_96, __p3_96), __s0_96, __p1_96); \ | |
| 48412 | __ret_96; \ | |
| 48413 | }) | |
| 48414 | #else | |
| 48415 | #define vcopy_laneq_s64(__p0_97, __p1_97, __p2_97, __p3_97) __extension__ ({ \ | |
| 48416 | int64x1_t __s0_97 = __p0_97; \ | |
| 48417 | int64x2_t __s2_97 = __p2_97; \ | |
| 48418 | int64x2_t __rev2_97; __rev2_97 = __builtin_shufflevector(__s2_97, __s2_97, 1, 0); \ | |
| 48419 | int64x1_t __ret_97; \ | |
| 48420 | __ret_97 = __noswap_vset_lane_s64(__noswap_vgetq_lane_s64(__rev2_97, __p3_97), __s0_97, __p1_97); \ | |
| 48421 | __ret_97; \ | |
| 48422 | }) | |
| 48423 | #endif | |
| 48424 | ||
| 48425 | #ifdef __LITTLE_ENDIAN__ | |
| 48426 | #define vcopy_laneq_s16(__p0_98, __p1_98, __p2_98, __p3_98) __extension__ ({ \ | |
| 48427 | int16x4_t __s0_98 = __p0_98; \ | |
| 48428 | int16x8_t __s2_98 = __p2_98; \ | |
| 48429 | int16x4_t __ret_98; \ | |
| 48430 | __ret_98 = vset_lane_s16(vgetq_lane_s16(__s2_98, __p3_98), __s0_98, __p1_98); \ | |
| 48431 | __ret_98; \ | |
| 48432 | }) | |
| 48433 | #else | |
| 48434 | #define vcopy_laneq_s16(__p0_99, __p1_99, __p2_99, __p3_99) __extension__ ({ \ | |
| 48435 | int16x4_t __s0_99 = __p0_99; \ | |
| 48436 | int16x8_t __s2_99 = __p2_99; \ | |
| 48437 | int16x4_t __rev0_99; __rev0_99 = __builtin_shufflevector(__s0_99, __s0_99, 3, 2, 1, 0); \ | |
| 48438 | int16x8_t __rev2_99; __rev2_99 = __builtin_shufflevector(__s2_99, __s2_99, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 48439 | int16x4_t __ret_99; \ | |
| 48440 | __ret_99 = __noswap_vset_lane_s16(__noswap_vgetq_lane_s16(__rev2_99, __p3_99), __rev0_99, __p1_99); \ | |
| 48441 | __ret_99 = __builtin_shufflevector(__ret_99, __ret_99, 3, 2, 1, 0); \ | |
| 48442 | __ret_99; \ | |
| 48443 | }) | |
| 48444 | #endif | |
| 48445 | ||
| 45134 | 48446 | #ifdef __LITTLE_ENDIAN__ |
| 45135 | 48447 | __ai poly64x1_t vcreate_p64(uint64_t __p0) { |
| 45136 | 48448 | poly64x1_t __ret; |
| ... | ... | @@ -47736,272 +51048,272 @@ __ai float64x1_t vfms_f64(float64x1_t __p0, float64x1_t __p1, float64x1_t __p2) |
| 47736 | 51048 | #endif |
| 47737 | 51049 | |
| 47738 | 51050 | #ifdef __LITTLE_ENDIAN__ |
| 47739 | #define vfmsd_lane_f64(__p0_88, __p1_88, __p2_88, __p3_88) __extension__ ({ \ | |
| 47740 | float64_t __s0_88 = __p0_88; \ | |
| 47741 | float64_t __s1_88 = __p1_88; \ | |
| 47742 | float64x1_t __s2_88 = __p2_88; \ | |
| 47743 | float64_t __ret_88; \ | |
| 47744 | __ret_88 = vfmad_lane_f64(__s0_88, -__s1_88, __s2_88, __p3_88); \ | |
| 47745 | __ret_88; \ | |
| 47746 | }) | |
| 47747 | #else | |
| 47748 | #define vfmsd_lane_f64(__p0_89, __p1_89, __p2_89, __p3_89) __extension__ ({ \ | |
| 47749 | float64_t __s0_89 = __p0_89; \ | |
| 47750 | float64_t __s1_89 = __p1_89; \ | |
| 47751 | float64x1_t __s2_89 = __p2_89; \ | |
| 47752 | float64_t __ret_89; \ | |
| 47753 | __ret_89 = __noswap_vfmad_lane_f64(__s0_89, -__s1_89, __s2_89, __p3_89); \ | |
| 47754 | __ret_89; \ | |
| 47755 | }) | |
| 47756 | #endif | |
| 47757 | ||
| 47758 | #ifdef __LITTLE_ENDIAN__ | |
| 47759 | #define vfmss_lane_f32(__p0_90, __p1_90, __p2_90, __p3_90) __extension__ ({ \ | |
| 47760 | float32_t __s0_90 = __p0_90; \ | |
| 47761 | float32_t __s1_90 = __p1_90; \ | |
| 47762 | float32x2_t __s2_90 = __p2_90; \ | |
| 47763 | float32_t __ret_90; \ | |
| 47764 | __ret_90 = vfmas_lane_f32(__s0_90, -__s1_90, __s2_90, __p3_90); \ | |
| 47765 | __ret_90; \ | |
| 47766 | }) | |
| 47767 | #else | |
| 47768 | #define vfmss_lane_f32(__p0_91, __p1_91, __p2_91, __p3_91) __extension__ ({ \ | |
| 47769 | float32_t __s0_91 = __p0_91; \ | |
| 47770 | float32_t __s1_91 = __p1_91; \ | |
| 47771 | float32x2_t __s2_91 = __p2_91; \ | |
| 47772 | float32x2_t __rev2_91; __rev2_91 = __builtin_shufflevector(__s2_91, __s2_91, 1, 0); \ | |
| 47773 | float32_t __ret_91; \ | |
| 47774 | __ret_91 = __noswap_vfmas_lane_f32(__s0_91, -__s1_91, __rev2_91, __p3_91); \ | |
| 47775 | __ret_91; \ | |
| 47776 | }) | |
| 47777 | #endif | |
| 47778 | ||
| 47779 | #ifdef __LITTLE_ENDIAN__ | |
| 47780 | #define vfmsq_lane_f64(__p0_92, __p1_92, __p2_92, __p3_92) __extension__ ({ \ | |
| 47781 | float64x2_t __s0_92 = __p0_92; \ | |
| 47782 | float64x2_t __s1_92 = __p1_92; \ | |
| 47783 | float64x1_t __s2_92 = __p2_92; \ | |
| 47784 | float64x2_t __ret_92; \ | |
| 47785 | __ret_92 = vfmaq_lane_f64(__s0_92, -__s1_92, __s2_92, __p3_92); \ | |
| 47786 | __ret_92; \ | |
| 47787 | }) | |
| 47788 | #else | |
| 47789 | #define vfmsq_lane_f64(__p0_93, __p1_93, __p2_93, __p3_93) __extension__ ({ \ | |
| 47790 | float64x2_t __s0_93 = __p0_93; \ | |
| 47791 | float64x2_t __s1_93 = __p1_93; \ | |
| 47792 | float64x1_t __s2_93 = __p2_93; \ | |
| 47793 | float64x2_t __rev0_93; __rev0_93 = __builtin_shufflevector(__s0_93, __s0_93, 1, 0); \ | |
| 47794 | float64x2_t __rev1_93; __rev1_93 = __builtin_shufflevector(__s1_93, __s1_93, 1, 0); \ | |
| 47795 | float64x2_t __ret_93; \ | |
| 47796 | __ret_93 = __noswap_vfmaq_lane_f64(__rev0_93, -__rev1_93, __s2_93, __p3_93); \ | |
| 47797 | __ret_93 = __builtin_shufflevector(__ret_93, __ret_93, 1, 0); \ | |
| 47798 | __ret_93; \ | |
| 47799 | }) | |
| 47800 | #endif | |
| 47801 | ||
| 47802 | #ifdef __LITTLE_ENDIAN__ | |
| 47803 | #define vfmsq_lane_f32(__p0_94, __p1_94, __p2_94, __p3_94) __extension__ ({ \ | |
| 47804 | float32x4_t __s0_94 = __p0_94; \ | |
| 47805 | float32x4_t __s1_94 = __p1_94; \ | |
| 47806 | float32x2_t __s2_94 = __p2_94; \ | |
| 47807 | float32x4_t __ret_94; \ | |
| 47808 | __ret_94 = vfmaq_lane_f32(__s0_94, -__s1_94, __s2_94, __p3_94); \ | |
| 47809 | __ret_94; \ | |
| 47810 | }) | |
| 47811 | #else | |
| 47812 | #define vfmsq_lane_f32(__p0_95, __p1_95, __p2_95, __p3_95) __extension__ ({ \ | |
| 47813 | float32x4_t __s0_95 = __p0_95; \ | |
| 47814 | float32x4_t __s1_95 = __p1_95; \ | |
| 47815 | float32x2_t __s2_95 = __p2_95; \ | |
| 47816 | float32x4_t __rev0_95; __rev0_95 = __builtin_shufflevector(__s0_95, __s0_95, 3, 2, 1, 0); \ | |
| 47817 | float32x4_t __rev1_95; __rev1_95 = __builtin_shufflevector(__s1_95, __s1_95, 3, 2, 1, 0); \ | |
| 47818 | float32x2_t __rev2_95; __rev2_95 = __builtin_shufflevector(__s2_95, __s2_95, 1, 0); \ | |
| 47819 | float32x4_t __ret_95; \ | |
| 47820 | __ret_95 = __noswap_vfmaq_lane_f32(__rev0_95, -__rev1_95, __rev2_95, __p3_95); \ | |
| 47821 | __ret_95 = __builtin_shufflevector(__ret_95, __ret_95, 3, 2, 1, 0); \ | |
| 47822 | __ret_95; \ | |
| 47823 | }) | |
| 47824 | #endif | |
| 47825 | ||
| 47826 | #ifdef __LITTLE_ENDIAN__ | |
| 47827 | #define vfms_lane_f64(__p0_96, __p1_96, __p2_96, __p3_96) __extension__ ({ \ | |
| 47828 | float64x1_t __s0_96 = __p0_96; \ | |
| 47829 | float64x1_t __s1_96 = __p1_96; \ | |
| 47830 | float64x1_t __s2_96 = __p2_96; \ | |
| 47831 | float64x1_t __ret_96; \ | |
| 47832 | __ret_96 = vfma_lane_f64(__s0_96, -__s1_96, __s2_96, __p3_96); \ | |
| 47833 | __ret_96; \ | |
| 47834 | }) | |
| 47835 | #else | |
| 47836 | #define vfms_lane_f64(__p0_97, __p1_97, __p2_97, __p3_97) __extension__ ({ \ | |
| 47837 | float64x1_t __s0_97 = __p0_97; \ | |
| 47838 | float64x1_t __s1_97 = __p1_97; \ | |
| 47839 | float64x1_t __s2_97 = __p2_97; \ | |
| 47840 | float64x1_t __ret_97; \ | |
| 47841 | __ret_97 = __noswap_vfma_lane_f64(__s0_97, -__s1_97, __s2_97, __p3_97); \ | |
| 47842 | __ret_97; \ | |
| 47843 | }) | |
| 47844 | #endif | |
| 47845 | ||
| 47846 | #ifdef __LITTLE_ENDIAN__ | |
| 47847 | #define vfms_lane_f32(__p0_98, __p1_98, __p2_98, __p3_98) __extension__ ({ \ | |
| 47848 | float32x2_t __s0_98 = __p0_98; \ | |
| 47849 | float32x2_t __s1_98 = __p1_98; \ | |
| 47850 | float32x2_t __s2_98 = __p2_98; \ | |
| 47851 | float32x2_t __ret_98; \ | |
| 47852 | __ret_98 = vfma_lane_f32(__s0_98, -__s1_98, __s2_98, __p3_98); \ | |
| 47853 | __ret_98; \ | |
| 47854 | }) | |
| 47855 | #else | |
| 47856 | #define vfms_lane_f32(__p0_99, __p1_99, __p2_99, __p3_99) __extension__ ({ \ | |
| 47857 | float32x2_t __s0_99 = __p0_99; \ | |
| 47858 | float32x2_t __s1_99 = __p1_99; \ | |
| 47859 | float32x2_t __s2_99 = __p2_99; \ | |
| 47860 | float32x2_t __rev0_99; __rev0_99 = __builtin_shufflevector(__s0_99, __s0_99, 1, 0); \ | |
| 47861 | float32x2_t __rev1_99; __rev1_99 = __builtin_shufflevector(__s1_99, __s1_99, 1, 0); \ | |
| 47862 | float32x2_t __rev2_99; __rev2_99 = __builtin_shufflevector(__s2_99, __s2_99, 1, 0); \ | |
| 47863 | float32x2_t __ret_99; \ | |
| 47864 | __ret_99 = __noswap_vfma_lane_f32(__rev0_99, -__rev1_99, __rev2_99, __p3_99); \ | |
| 47865 | __ret_99 = __builtin_shufflevector(__ret_99, __ret_99, 1, 0); \ | |
| 47866 | __ret_99; \ | |
| 47867 | }) | |
| 47868 | #endif | |
| 47869 | ||
| 47870 | #ifdef __LITTLE_ENDIAN__ | |
| 47871 | #define vfmsd_laneq_f64(__p0_100, __p1_100, __p2_100, __p3_100) __extension__ ({ \ | |
| 51051 | #define vfmsd_lane_f64(__p0_100, __p1_100, __p2_100, __p3_100) __extension__ ({ \ | |
| 47872 | 51052 | float64_t __s0_100 = __p0_100; \ |
| 47873 | 51053 | float64_t __s1_100 = __p1_100; \ |
| 47874 | float64x2_t __s2_100 = __p2_100; \ | |
| 51054 | float64x1_t __s2_100 = __p2_100; \ | |
| 47875 | 51055 | float64_t __ret_100; \ |
| 47876 | __ret_100 = vfmad_laneq_f64(__s0_100, -__s1_100, __s2_100, __p3_100); \ | |
| 51056 | __ret_100 = vfmad_lane_f64(__s0_100, -__s1_100, __s2_100, __p3_100); \ | |
| 47877 | 51057 | __ret_100; \ |
| 47878 | 51058 | }) |
| 47879 | 51059 | #else |
| 47880 | #define vfmsd_laneq_f64(__p0_101, __p1_101, __p2_101, __p3_101) __extension__ ({ \ | |
| 51060 | #define vfmsd_lane_f64(__p0_101, __p1_101, __p2_101, __p3_101) __extension__ ({ \ | |
| 47881 | 51061 | float64_t __s0_101 = __p0_101; \ |
| 47882 | 51062 | float64_t __s1_101 = __p1_101; \ |
| 47883 | float64x2_t __s2_101 = __p2_101; \ | |
| 47884 | float64x2_t __rev2_101; __rev2_101 = __builtin_shufflevector(__s2_101, __s2_101, 1, 0); \ | |
| 51063 | float64x1_t __s2_101 = __p2_101; \ | |
| 47885 | 51064 | float64_t __ret_101; \ |
| 47886 | __ret_101 = __noswap_vfmad_laneq_f64(__s0_101, -__s1_101, __rev2_101, __p3_101); \ | |
| 51065 | __ret_101 = __noswap_vfmad_lane_f64(__s0_101, -__s1_101, __s2_101, __p3_101); \ | |
| 47887 | 51066 | __ret_101; \ |
| 47888 | 51067 | }) |
| 47889 | 51068 | #endif |
| 47890 | 51069 | |
| 47891 | 51070 | #ifdef __LITTLE_ENDIAN__ |
| 47892 | #define vfmss_laneq_f32(__p0_102, __p1_102, __p2_102, __p3_102) __extension__ ({ \ | |
| 51071 | #define vfmss_lane_f32(__p0_102, __p1_102, __p2_102, __p3_102) __extension__ ({ \ | |
| 47893 | 51072 | float32_t __s0_102 = __p0_102; \ |
| 47894 | 51073 | float32_t __s1_102 = __p1_102; \ |
| 47895 | float32x4_t __s2_102 = __p2_102; \ | |
| 51074 | float32x2_t __s2_102 = __p2_102; \ | |
| 47896 | 51075 | float32_t __ret_102; \ |
| 47897 | __ret_102 = vfmas_laneq_f32(__s0_102, -__s1_102, __s2_102, __p3_102); \ | |
| 51076 | __ret_102 = vfmas_lane_f32(__s0_102, -__s1_102, __s2_102, __p3_102); \ | |
| 47898 | 51077 | __ret_102; \ |
| 47899 | 51078 | }) |
| 47900 | 51079 | #else |
| 47901 | #define vfmss_laneq_f32(__p0_103, __p1_103, __p2_103, __p3_103) __extension__ ({ \ | |
| 51080 | #define vfmss_lane_f32(__p0_103, __p1_103, __p2_103, __p3_103) __extension__ ({ \ | |
| 47902 | 51081 | float32_t __s0_103 = __p0_103; \ |
| 47903 | 51082 | float32_t __s1_103 = __p1_103; \ |
| 47904 | float32x4_t __s2_103 = __p2_103; \ | |
| 47905 | float32x4_t __rev2_103; __rev2_103 = __builtin_shufflevector(__s2_103, __s2_103, 3, 2, 1, 0); \ | |
| 51083 | float32x2_t __s2_103 = __p2_103; \ | |
| 51084 | float32x2_t __rev2_103; __rev2_103 = __builtin_shufflevector(__s2_103, __s2_103, 1, 0); \ | |
| 47906 | 51085 | float32_t __ret_103; \ |
| 47907 | __ret_103 = __noswap_vfmas_laneq_f32(__s0_103, -__s1_103, __rev2_103, __p3_103); \ | |
| 51086 | __ret_103 = __noswap_vfmas_lane_f32(__s0_103, -__s1_103, __rev2_103, __p3_103); \ | |
| 47908 | 51087 | __ret_103; \ |
| 47909 | 51088 | }) |
| 47910 | 51089 | #endif |
| 47911 | 51090 | |
| 47912 | 51091 | #ifdef __LITTLE_ENDIAN__ |
| 47913 | #define vfmsq_laneq_f64(__p0_104, __p1_104, __p2_104, __p3_104) __extension__ ({ \ | |
| 51092 | #define vfmsq_lane_f64(__p0_104, __p1_104, __p2_104, __p3_104) __extension__ ({ \ | |
| 47914 | 51093 | float64x2_t __s0_104 = __p0_104; \ |
| 47915 | 51094 | float64x2_t __s1_104 = __p1_104; \ |
| 47916 | float64x2_t __s2_104 = __p2_104; \ | |
| 51095 | float64x1_t __s2_104 = __p2_104; \ | |
| 47917 | 51096 | float64x2_t __ret_104; \ |
| 47918 | __ret_104 = vfmaq_laneq_f64(__s0_104, -__s1_104, __s2_104, __p3_104); \ | |
| 51097 | __ret_104 = vfmaq_lane_f64(__s0_104, -__s1_104, __s2_104, __p3_104); \ | |
| 47919 | 51098 | __ret_104; \ |
| 47920 | 51099 | }) |
| 47921 | 51100 | #else |
| 47922 | #define vfmsq_laneq_f64(__p0_105, __p1_105, __p2_105, __p3_105) __extension__ ({ \ | |
| 51101 | #define vfmsq_lane_f64(__p0_105, __p1_105, __p2_105, __p3_105) __extension__ ({ \ | |
| 47923 | 51102 | float64x2_t __s0_105 = __p0_105; \ |
| 47924 | 51103 | float64x2_t __s1_105 = __p1_105; \ |
| 47925 | float64x2_t __s2_105 = __p2_105; \ | |
| 51104 | float64x1_t __s2_105 = __p2_105; \ | |
| 47926 | 51105 | float64x2_t __rev0_105; __rev0_105 = __builtin_shufflevector(__s0_105, __s0_105, 1, 0); \ |
| 47927 | 51106 | float64x2_t __rev1_105; __rev1_105 = __builtin_shufflevector(__s1_105, __s1_105, 1, 0); \ |
| 47928 | float64x2_t __rev2_105; __rev2_105 = __builtin_shufflevector(__s2_105, __s2_105, 1, 0); \ | |
| 47929 | 51107 | float64x2_t __ret_105; \ |
| 47930 | __ret_105 = __noswap_vfmaq_laneq_f64(__rev0_105, -__rev1_105, __rev2_105, __p3_105); \ | |
| 51108 | __ret_105 = __noswap_vfmaq_lane_f64(__rev0_105, -__rev1_105, __s2_105, __p3_105); \ | |
| 47931 | 51109 | __ret_105 = __builtin_shufflevector(__ret_105, __ret_105, 1, 0); \ |
| 47932 | 51110 | __ret_105; \ |
| 47933 | 51111 | }) |
| 47934 | 51112 | #endif |
| 47935 | 51113 | |
| 47936 | 51114 | #ifdef __LITTLE_ENDIAN__ |
| 47937 | #define vfmsq_laneq_f32(__p0_106, __p1_106, __p2_106, __p3_106) __extension__ ({ \ | |
| 51115 | #define vfmsq_lane_f32(__p0_106, __p1_106, __p2_106, __p3_106) __extension__ ({ \ | |
| 47938 | 51116 | float32x4_t __s0_106 = __p0_106; \ |
| 47939 | 51117 | float32x4_t __s1_106 = __p1_106; \ |
| 47940 | float32x4_t __s2_106 = __p2_106; \ | |
| 51118 | float32x2_t __s2_106 = __p2_106; \ | |
| 47941 | 51119 | float32x4_t __ret_106; \ |
| 47942 | __ret_106 = vfmaq_laneq_f32(__s0_106, -__s1_106, __s2_106, __p3_106); \ | |
| 51120 | __ret_106 = vfmaq_lane_f32(__s0_106, -__s1_106, __s2_106, __p3_106); \ | |
| 47943 | 51121 | __ret_106; \ |
| 47944 | 51122 | }) |
| 47945 | 51123 | #else |
| 47946 | #define vfmsq_laneq_f32(__p0_107, __p1_107, __p2_107, __p3_107) __extension__ ({ \ | |
| 51124 | #define vfmsq_lane_f32(__p0_107, __p1_107, __p2_107, __p3_107) __extension__ ({ \ | |
| 47947 | 51125 | float32x4_t __s0_107 = __p0_107; \ |
| 47948 | 51126 | float32x4_t __s1_107 = __p1_107; \ |
| 47949 | float32x4_t __s2_107 = __p2_107; \ | |
| 51127 | float32x2_t __s2_107 = __p2_107; \ | |
| 47950 | 51128 | float32x4_t __rev0_107; __rev0_107 = __builtin_shufflevector(__s0_107, __s0_107, 3, 2, 1, 0); \ |
| 47951 | 51129 | float32x4_t __rev1_107; __rev1_107 = __builtin_shufflevector(__s1_107, __s1_107, 3, 2, 1, 0); \ |
| 47952 | float32x4_t __rev2_107; __rev2_107 = __builtin_shufflevector(__s2_107, __s2_107, 3, 2, 1, 0); \ | |
| 51130 | float32x2_t __rev2_107; __rev2_107 = __builtin_shufflevector(__s2_107, __s2_107, 1, 0); \ | |
| 47953 | 51131 | float32x4_t __ret_107; \ |
| 47954 | __ret_107 = __noswap_vfmaq_laneq_f32(__rev0_107, -__rev1_107, __rev2_107, __p3_107); \ | |
| 51132 | __ret_107 = __noswap_vfmaq_lane_f32(__rev0_107, -__rev1_107, __rev2_107, __p3_107); \ | |
| 47955 | 51133 | __ret_107 = __builtin_shufflevector(__ret_107, __ret_107, 3, 2, 1, 0); \ |
| 47956 | 51134 | __ret_107; \ |
| 47957 | 51135 | }) |
| 47958 | 51136 | #endif |
| 47959 | 51137 | |
| 47960 | 51138 | #ifdef __LITTLE_ENDIAN__ |
| 47961 | #define vfms_laneq_f64(__p0_108, __p1_108, __p2_108, __p3_108) __extension__ ({ \ | |
| 51139 | #define vfms_lane_f64(__p0_108, __p1_108, __p2_108, __p3_108) __extension__ ({ \ | |
| 47962 | 51140 | float64x1_t __s0_108 = __p0_108; \ |
| 47963 | 51141 | float64x1_t __s1_108 = __p1_108; \ |
| 47964 | float64x2_t __s2_108 = __p2_108; \ | |
| 51142 | float64x1_t __s2_108 = __p2_108; \ | |
| 47965 | 51143 | float64x1_t __ret_108; \ |
| 47966 | __ret_108 = vfma_laneq_f64(__s0_108, -__s1_108, __s2_108, __p3_108); \ | |
| 51144 | __ret_108 = vfma_lane_f64(__s0_108, -__s1_108, __s2_108, __p3_108); \ | |
| 47967 | 51145 | __ret_108; \ |
| 47968 | 51146 | }) |
| 47969 | 51147 | #else |
| 47970 | #define vfms_laneq_f64(__p0_109, __p1_109, __p2_109, __p3_109) __extension__ ({ \ | |
| 51148 | #define vfms_lane_f64(__p0_109, __p1_109, __p2_109, __p3_109) __extension__ ({ \ | |
| 47971 | 51149 | float64x1_t __s0_109 = __p0_109; \ |
| 47972 | 51150 | float64x1_t __s1_109 = __p1_109; \ |
| 47973 | float64x2_t __s2_109 = __p2_109; \ | |
| 47974 | float64x2_t __rev2_109; __rev2_109 = __builtin_shufflevector(__s2_109, __s2_109, 1, 0); \ | |
| 51151 | float64x1_t __s2_109 = __p2_109; \ | |
| 47975 | 51152 | float64x1_t __ret_109; \ |
| 47976 | __ret_109 = __noswap_vfma_laneq_f64(__s0_109, -__s1_109, __rev2_109, __p3_109); \ | |
| 51153 | __ret_109 = __noswap_vfma_lane_f64(__s0_109, -__s1_109, __s2_109, __p3_109); \ | |
| 47977 | 51154 | __ret_109; \ |
| 47978 | 51155 | }) |
| 47979 | 51156 | #endif |
| 47980 | 51157 | |
| 47981 | 51158 | #ifdef __LITTLE_ENDIAN__ |
| 47982 | #define vfms_laneq_f32(__p0_110, __p1_110, __p2_110, __p3_110) __extension__ ({ \ | |
| 51159 | #define vfms_lane_f32(__p0_110, __p1_110, __p2_110, __p3_110) __extension__ ({ \ | |
| 47983 | 51160 | float32x2_t __s0_110 = __p0_110; \ |
| 47984 | 51161 | float32x2_t __s1_110 = __p1_110; \ |
| 47985 | float32x4_t __s2_110 = __p2_110; \ | |
| 51162 | float32x2_t __s2_110 = __p2_110; \ | |
| 47986 | 51163 | float32x2_t __ret_110; \ |
| 47987 | __ret_110 = vfma_laneq_f32(__s0_110, -__s1_110, __s2_110, __p3_110); \ | |
| 51164 | __ret_110 = vfma_lane_f32(__s0_110, -__s1_110, __s2_110, __p3_110); \ | |
| 47988 | 51165 | __ret_110; \ |
| 47989 | 51166 | }) |
| 47990 | 51167 | #else |
| 47991 | #define vfms_laneq_f32(__p0_111, __p1_111, __p2_111, __p3_111) __extension__ ({ \ | |
| 51168 | #define vfms_lane_f32(__p0_111, __p1_111, __p2_111, __p3_111) __extension__ ({ \ | |
| 47992 | 51169 | float32x2_t __s0_111 = __p0_111; \ |
| 47993 | 51170 | float32x2_t __s1_111 = __p1_111; \ |
| 47994 | float32x4_t __s2_111 = __p2_111; \ | |
| 51171 | float32x2_t __s2_111 = __p2_111; \ | |
| 47995 | 51172 | float32x2_t __rev0_111; __rev0_111 = __builtin_shufflevector(__s0_111, __s0_111, 1, 0); \ |
| 47996 | 51173 | float32x2_t __rev1_111; __rev1_111 = __builtin_shufflevector(__s1_111, __s1_111, 1, 0); \ |
| 47997 | float32x4_t __rev2_111; __rev2_111 = __builtin_shufflevector(__s2_111, __s2_111, 3, 2, 1, 0); \ | |
| 51174 | float32x2_t __rev2_111; __rev2_111 = __builtin_shufflevector(__s2_111, __s2_111, 1, 0); \ | |
| 47998 | 51175 | float32x2_t __ret_111; \ |
| 47999 | __ret_111 = __noswap_vfma_laneq_f32(__rev0_111, -__rev1_111, __rev2_111, __p3_111); \ | |
| 51176 | __ret_111 = __noswap_vfma_lane_f32(__rev0_111, -__rev1_111, __rev2_111, __p3_111); \ | |
| 48000 | 51177 | __ret_111 = __builtin_shufflevector(__ret_111, __ret_111, 1, 0); \ |
| 48001 | 51178 | __ret_111; \ |
| 48002 | 51179 | }) |
| 48003 | 51180 | #endif |
| 48004 | 51181 | |
| 51182 | #ifdef __LITTLE_ENDIAN__ | |
| 51183 | #define vfmsd_laneq_f64(__p0_112, __p1_112, __p2_112, __p3_112) __extension__ ({ \ | |
| 51184 | float64_t __s0_112 = __p0_112; \ | |
| 51185 | float64_t __s1_112 = __p1_112; \ | |
| 51186 | float64x2_t __s2_112 = __p2_112; \ | |
| 51187 | float64_t __ret_112; \ | |
| 51188 | __ret_112 = vfmad_laneq_f64(__s0_112, -__s1_112, __s2_112, __p3_112); \ | |
| 51189 | __ret_112; \ | |
| 51190 | }) | |
| 51191 | #else | |
| 51192 | #define vfmsd_laneq_f64(__p0_113, __p1_113, __p2_113, __p3_113) __extension__ ({ \ | |
| 51193 | float64_t __s0_113 = __p0_113; \ | |
| 51194 | float64_t __s1_113 = __p1_113; \ | |
| 51195 | float64x2_t __s2_113 = __p2_113; \ | |
| 51196 | float64x2_t __rev2_113; __rev2_113 = __builtin_shufflevector(__s2_113, __s2_113, 1, 0); \ | |
| 51197 | float64_t __ret_113; \ | |
| 51198 | __ret_113 = __noswap_vfmad_laneq_f64(__s0_113, -__s1_113, __rev2_113, __p3_113); \ | |
| 51199 | __ret_113; \ | |
| 51200 | }) | |
| 51201 | #endif | |
| 51202 | ||
| 51203 | #ifdef __LITTLE_ENDIAN__ | |
| 51204 | #define vfmss_laneq_f32(__p0_114, __p1_114, __p2_114, __p3_114) __extension__ ({ \ | |
| 51205 | float32_t __s0_114 = __p0_114; \ | |
| 51206 | float32_t __s1_114 = __p1_114; \ | |
| 51207 | float32x4_t __s2_114 = __p2_114; \ | |
| 51208 | float32_t __ret_114; \ | |
| 51209 | __ret_114 = vfmas_laneq_f32(__s0_114, -__s1_114, __s2_114, __p3_114); \ | |
| 51210 | __ret_114; \ | |
| 51211 | }) | |
| 51212 | #else | |
| 51213 | #define vfmss_laneq_f32(__p0_115, __p1_115, __p2_115, __p3_115) __extension__ ({ \ | |
| 51214 | float32_t __s0_115 = __p0_115; \ | |
| 51215 | float32_t __s1_115 = __p1_115; \ | |
| 51216 | float32x4_t __s2_115 = __p2_115; \ | |
| 51217 | float32x4_t __rev2_115; __rev2_115 = __builtin_shufflevector(__s2_115, __s2_115, 3, 2, 1, 0); \ | |
| 51218 | float32_t __ret_115; \ | |
| 51219 | __ret_115 = __noswap_vfmas_laneq_f32(__s0_115, -__s1_115, __rev2_115, __p3_115); \ | |
| 51220 | __ret_115; \ | |
| 51221 | }) | |
| 51222 | #endif | |
| 51223 | ||
| 51224 | #ifdef __LITTLE_ENDIAN__ | |
| 51225 | #define vfmsq_laneq_f64(__p0_116, __p1_116, __p2_116, __p3_116) __extension__ ({ \ | |
| 51226 | float64x2_t __s0_116 = __p0_116; \ | |
| 51227 | float64x2_t __s1_116 = __p1_116; \ | |
| 51228 | float64x2_t __s2_116 = __p2_116; \ | |
| 51229 | float64x2_t __ret_116; \ | |
| 51230 | __ret_116 = vfmaq_laneq_f64(__s0_116, -__s1_116, __s2_116, __p3_116); \ | |
| 51231 | __ret_116; \ | |
| 51232 | }) | |
| 51233 | #else | |
| 51234 | #define vfmsq_laneq_f64(__p0_117, __p1_117, __p2_117, __p3_117) __extension__ ({ \ | |
| 51235 | float64x2_t __s0_117 = __p0_117; \ | |
| 51236 | float64x2_t __s1_117 = __p1_117; \ | |
| 51237 | float64x2_t __s2_117 = __p2_117; \ | |
| 51238 | float64x2_t __rev0_117; __rev0_117 = __builtin_shufflevector(__s0_117, __s0_117, 1, 0); \ | |
| 51239 | float64x2_t __rev1_117; __rev1_117 = __builtin_shufflevector(__s1_117, __s1_117, 1, 0); \ | |
| 51240 | float64x2_t __rev2_117; __rev2_117 = __builtin_shufflevector(__s2_117, __s2_117, 1, 0); \ | |
| 51241 | float64x2_t __ret_117; \ | |
| 51242 | __ret_117 = __noswap_vfmaq_laneq_f64(__rev0_117, -__rev1_117, __rev2_117, __p3_117); \ | |
| 51243 | __ret_117 = __builtin_shufflevector(__ret_117, __ret_117, 1, 0); \ | |
| 51244 | __ret_117; \ | |
| 51245 | }) | |
| 51246 | #endif | |
| 51247 | ||
| 51248 | #ifdef __LITTLE_ENDIAN__ | |
| 51249 | #define vfmsq_laneq_f32(__p0_118, __p1_118, __p2_118, __p3_118) __extension__ ({ \ | |
| 51250 | float32x4_t __s0_118 = __p0_118; \ | |
| 51251 | float32x4_t __s1_118 = __p1_118; \ | |
| 51252 | float32x4_t __s2_118 = __p2_118; \ | |
| 51253 | float32x4_t __ret_118; \ | |
| 51254 | __ret_118 = vfmaq_laneq_f32(__s0_118, -__s1_118, __s2_118, __p3_118); \ | |
| 51255 | __ret_118; \ | |
| 51256 | }) | |
| 51257 | #else | |
| 51258 | #define vfmsq_laneq_f32(__p0_119, __p1_119, __p2_119, __p3_119) __extension__ ({ \ | |
| 51259 | float32x4_t __s0_119 = __p0_119; \ | |
| 51260 | float32x4_t __s1_119 = __p1_119; \ | |
| 51261 | float32x4_t __s2_119 = __p2_119; \ | |
| 51262 | float32x4_t __rev0_119; __rev0_119 = __builtin_shufflevector(__s0_119, __s0_119, 3, 2, 1, 0); \ | |
| 51263 | float32x4_t __rev1_119; __rev1_119 = __builtin_shufflevector(__s1_119, __s1_119, 3, 2, 1, 0); \ | |
| 51264 | float32x4_t __rev2_119; __rev2_119 = __builtin_shufflevector(__s2_119, __s2_119, 3, 2, 1, 0); \ | |
| 51265 | float32x4_t __ret_119; \ | |
| 51266 | __ret_119 = __noswap_vfmaq_laneq_f32(__rev0_119, -__rev1_119, __rev2_119, __p3_119); \ | |
| 51267 | __ret_119 = __builtin_shufflevector(__ret_119, __ret_119, 3, 2, 1, 0); \ | |
| 51268 | __ret_119; \ | |
| 51269 | }) | |
| 51270 | #endif | |
| 51271 | ||
| 51272 | #ifdef __LITTLE_ENDIAN__ | |
| 51273 | #define vfms_laneq_f64(__p0_120, __p1_120, __p2_120, __p3_120) __extension__ ({ \ | |
| 51274 | float64x1_t __s0_120 = __p0_120; \ | |
| 51275 | float64x1_t __s1_120 = __p1_120; \ | |
| 51276 | float64x2_t __s2_120 = __p2_120; \ | |
| 51277 | float64x1_t __ret_120; \ | |
| 51278 | __ret_120 = vfma_laneq_f64(__s0_120, -__s1_120, __s2_120, __p3_120); \ | |
| 51279 | __ret_120; \ | |
| 51280 | }) | |
| 51281 | #else | |
| 51282 | #define vfms_laneq_f64(__p0_121, __p1_121, __p2_121, __p3_121) __extension__ ({ \ | |
| 51283 | float64x1_t __s0_121 = __p0_121; \ | |
| 51284 | float64x1_t __s1_121 = __p1_121; \ | |
| 51285 | float64x2_t __s2_121 = __p2_121; \ | |
| 51286 | float64x2_t __rev2_121; __rev2_121 = __builtin_shufflevector(__s2_121, __s2_121, 1, 0); \ | |
| 51287 | float64x1_t __ret_121; \ | |
| 51288 | __ret_121 = __noswap_vfma_laneq_f64(__s0_121, -__s1_121, __rev2_121, __p3_121); \ | |
| 51289 | __ret_121; \ | |
| 51290 | }) | |
| 51291 | #endif | |
| 51292 | ||
| 51293 | #ifdef __LITTLE_ENDIAN__ | |
| 51294 | #define vfms_laneq_f32(__p0_122, __p1_122, __p2_122, __p3_122) __extension__ ({ \ | |
| 51295 | float32x2_t __s0_122 = __p0_122; \ | |
| 51296 | float32x2_t __s1_122 = __p1_122; \ | |
| 51297 | float32x4_t __s2_122 = __p2_122; \ | |
| 51298 | float32x2_t __ret_122; \ | |
| 51299 | __ret_122 = vfma_laneq_f32(__s0_122, -__s1_122, __s2_122, __p3_122); \ | |
| 51300 | __ret_122; \ | |
| 51301 | }) | |
| 51302 | #else | |
| 51303 | #define vfms_laneq_f32(__p0_123, __p1_123, __p2_123, __p3_123) __extension__ ({ \ | |
| 51304 | float32x2_t __s0_123 = __p0_123; \ | |
| 51305 | float32x2_t __s1_123 = __p1_123; \ | |
| 51306 | float32x4_t __s2_123 = __p2_123; \ | |
| 51307 | float32x2_t __rev0_123; __rev0_123 = __builtin_shufflevector(__s0_123, __s0_123, 1, 0); \ | |
| 51308 | float32x2_t __rev1_123; __rev1_123 = __builtin_shufflevector(__s1_123, __s1_123, 1, 0); \ | |
| 51309 | float32x4_t __rev2_123; __rev2_123 = __builtin_shufflevector(__s2_123, __s2_123, 3, 2, 1, 0); \ | |
| 51310 | float32x2_t __ret_123; \ | |
| 51311 | __ret_123 = __noswap_vfma_laneq_f32(__rev0_123, -__rev1_123, __rev2_123, __p3_123); \ | |
| 51312 | __ret_123 = __builtin_shufflevector(__ret_123, __ret_123, 1, 0); \ | |
| 51313 | __ret_123; \ | |
| 51314 | }) | |
| 51315 | #endif | |
| 51316 | ||
| 48005 | 51317 | #ifdef __LITTLE_ENDIAN__ |
| 48006 | 51318 | __ai float64x2_t vfmsq_n_f64(float64x2_t __p0, float64x2_t __p1, float64_t __p2) { |
| 48007 | 51319 | float64x2_t __ret; |
| ... | ... | @@ -53521,146 +56833,146 @@ __ai float64x1_t vmov_n_f64(float64_t __p0) { |
| 53521 | 56833 | #endif |
| 53522 | 56834 | |
| 53523 | 56835 | #ifdef __LITTLE_ENDIAN__ |
| 53524 | __ai uint16x8_t vmovl_high_u8(uint8x16_t __p0_112) { | |
| 53525 | uint16x8_t __ret_112; | |
| 53526 | uint8x8_t __a1_112 = vget_high_u8(__p0_112); | |
| 53527 | __ret_112 = (uint16x8_t)(vshll_n_u8(__a1_112, 0)); | |
| 53528 | return __ret_112; | |
| 56836 | __ai uint16x8_t vmovl_high_u8(uint8x16_t __p0_124) { | |
| 56837 | uint16x8_t __ret_124; | |
| 56838 | uint8x8_t __a1_124 = vget_high_u8(__p0_124); | |
| 56839 | __ret_124 = (uint16x8_t)(vshll_n_u8(__a1_124, 0)); | |
| 56840 | return __ret_124; | |
| 53529 | 56841 | } |
| 53530 | 56842 | #else |
| 53531 | __ai uint16x8_t vmovl_high_u8(uint8x16_t __p0_113) { | |
| 53532 | uint8x16_t __rev0_113; __rev0_113 = __builtin_shufflevector(__p0_113, __p0_113, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 53533 | uint16x8_t __ret_113; | |
| 53534 | uint8x8_t __a1_113 = __noswap_vget_high_u8(__rev0_113); | |
| 53535 | __ret_113 = (uint16x8_t)(__noswap_vshll_n_u8(__a1_113, 0)); | |
| 53536 | __ret_113 = __builtin_shufflevector(__ret_113, __ret_113, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 53537 | return __ret_113; | |
| 56843 | __ai uint16x8_t vmovl_high_u8(uint8x16_t __p0_125) { | |
| 56844 | uint8x16_t __rev0_125; __rev0_125 = __builtin_shufflevector(__p0_125, __p0_125, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 56845 | uint16x8_t __ret_125; | |
| 56846 | uint8x8_t __a1_125 = __noswap_vget_high_u8(__rev0_125); | |
| 56847 | __ret_125 = (uint16x8_t)(__noswap_vshll_n_u8(__a1_125, 0)); | |
| 56848 | __ret_125 = __builtin_shufflevector(__ret_125, __ret_125, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 56849 | return __ret_125; | |
| 53538 | 56850 | } |
| 53539 | __ai uint16x8_t __noswap_vmovl_high_u8(uint8x16_t __p0_114) { | |
| 53540 | uint16x8_t __ret_114; | |
| 53541 | uint8x8_t __a1_114 = __noswap_vget_high_u8(__p0_114); | |
| 53542 | __ret_114 = (uint16x8_t)(__noswap_vshll_n_u8(__a1_114, 0)); | |
| 53543 | return __ret_114; | |
| 56851 | __ai uint16x8_t __noswap_vmovl_high_u8(uint8x16_t __p0_126) { | |
| 56852 | uint16x8_t __ret_126; | |
| 56853 | uint8x8_t __a1_126 = __noswap_vget_high_u8(__p0_126); | |
| 56854 | __ret_126 = (uint16x8_t)(__noswap_vshll_n_u8(__a1_126, 0)); | |
| 56855 | return __ret_126; | |
| 53544 | 56856 | } |
| 53545 | 56857 | #endif |
| 53546 | 56858 | |
| 53547 | 56859 | #ifdef __LITTLE_ENDIAN__ |
| 53548 | __ai uint64x2_t vmovl_high_u32(uint32x4_t __p0_115) { | |
| 53549 | uint64x2_t __ret_115; | |
| 53550 | uint32x2_t __a1_115 = vget_high_u32(__p0_115); | |
| 53551 | __ret_115 = (uint64x2_t)(vshll_n_u32(__a1_115, 0)); | |
| 53552 | return __ret_115; | |
| 56860 | __ai uint64x2_t vmovl_high_u32(uint32x4_t __p0_127) { | |
| 56861 | uint64x2_t __ret_127; | |
| 56862 | uint32x2_t __a1_127 = vget_high_u32(__p0_127); | |
| 56863 | __ret_127 = (uint64x2_t)(vshll_n_u32(__a1_127, 0)); | |
| 56864 | return __ret_127; | |
| 53553 | 56865 | } |
| 53554 | 56866 | #else |
| 53555 | __ai uint64x2_t vmovl_high_u32(uint32x4_t __p0_116) { | |
| 53556 | uint32x4_t __rev0_116; __rev0_116 = __builtin_shufflevector(__p0_116, __p0_116, 3, 2, 1, 0); | |
| 53557 | uint64x2_t __ret_116; | |
| 53558 | uint32x2_t __a1_116 = __noswap_vget_high_u32(__rev0_116); | |
| 53559 | __ret_116 = (uint64x2_t)(__noswap_vshll_n_u32(__a1_116, 0)); | |
| 53560 | __ret_116 = __builtin_shufflevector(__ret_116, __ret_116, 1, 0); | |
| 53561 | return __ret_116; | |
| 56867 | __ai uint64x2_t vmovl_high_u32(uint32x4_t __p0_128) { | |
| 56868 | uint32x4_t __rev0_128; __rev0_128 = __builtin_shufflevector(__p0_128, __p0_128, 3, 2, 1, 0); | |
| 56869 | uint64x2_t __ret_128; | |
| 56870 | uint32x2_t __a1_128 = __noswap_vget_high_u32(__rev0_128); | |
| 56871 | __ret_128 = (uint64x2_t)(__noswap_vshll_n_u32(__a1_128, 0)); | |
| 56872 | __ret_128 = __builtin_shufflevector(__ret_128, __ret_128, 1, 0); | |
| 56873 | return __ret_128; | |
| 53562 | 56874 | } |
| 53563 | __ai uint64x2_t __noswap_vmovl_high_u32(uint32x4_t __p0_117) { | |
| 53564 | uint64x2_t __ret_117; | |
| 53565 | uint32x2_t __a1_117 = __noswap_vget_high_u32(__p0_117); | |
| 53566 | __ret_117 = (uint64x2_t)(__noswap_vshll_n_u32(__a1_117, 0)); | |
| 53567 | return __ret_117; | |
| 56875 | __ai uint64x2_t __noswap_vmovl_high_u32(uint32x4_t __p0_129) { | |
| 56876 | uint64x2_t __ret_129; | |
| 56877 | uint32x2_t __a1_129 = __noswap_vget_high_u32(__p0_129); | |
| 56878 | __ret_129 = (uint64x2_t)(__noswap_vshll_n_u32(__a1_129, 0)); | |
| 56879 | return __ret_129; | |
| 53568 | 56880 | } |
| 53569 | 56881 | #endif |
| 53570 | 56882 | |
| 53571 | 56883 | #ifdef __LITTLE_ENDIAN__ |
| 53572 | __ai uint32x4_t vmovl_high_u16(uint16x8_t __p0_118) { | |
| 53573 | uint32x4_t __ret_118; | |
| 53574 | uint16x4_t __a1_118 = vget_high_u16(__p0_118); | |
| 53575 | __ret_118 = (uint32x4_t)(vshll_n_u16(__a1_118, 0)); | |
| 53576 | return __ret_118; | |
| 56884 | __ai uint32x4_t vmovl_high_u16(uint16x8_t __p0_130) { | |
| 56885 | uint32x4_t __ret_130; | |
| 56886 | uint16x4_t __a1_130 = vget_high_u16(__p0_130); | |
| 56887 | __ret_130 = (uint32x4_t)(vshll_n_u16(__a1_130, 0)); | |
| 56888 | return __ret_130; | |
| 53577 | 56889 | } |
| 53578 | 56890 | #else |
| 53579 | __ai uint32x4_t vmovl_high_u16(uint16x8_t __p0_119) { | |
| 53580 | uint16x8_t __rev0_119; __rev0_119 = __builtin_shufflevector(__p0_119, __p0_119, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 53581 | uint32x4_t __ret_119; | |
| 53582 | uint16x4_t __a1_119 = __noswap_vget_high_u16(__rev0_119); | |
| 53583 | __ret_119 = (uint32x4_t)(__noswap_vshll_n_u16(__a1_119, 0)); | |
| 53584 | __ret_119 = __builtin_shufflevector(__ret_119, __ret_119, 3, 2, 1, 0); | |
| 53585 | return __ret_119; | |
| 56891 | __ai uint32x4_t vmovl_high_u16(uint16x8_t __p0_131) { | |
| 56892 | uint16x8_t __rev0_131; __rev0_131 = __builtin_shufflevector(__p0_131, __p0_131, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 56893 | uint32x4_t __ret_131; | |
| 56894 | uint16x4_t __a1_131 = __noswap_vget_high_u16(__rev0_131); | |
| 56895 | __ret_131 = (uint32x4_t)(__noswap_vshll_n_u16(__a1_131, 0)); | |
| 56896 | __ret_131 = __builtin_shufflevector(__ret_131, __ret_131, 3, 2, 1, 0); | |
| 56897 | return __ret_131; | |
| 53586 | 56898 | } |
| 53587 | __ai uint32x4_t __noswap_vmovl_high_u16(uint16x8_t __p0_120) { | |
| 53588 | uint32x4_t __ret_120; | |
| 53589 | uint16x4_t __a1_120 = __noswap_vget_high_u16(__p0_120); | |
| 53590 | __ret_120 = (uint32x4_t)(__noswap_vshll_n_u16(__a1_120, 0)); | |
| 53591 | return __ret_120; | |
| 56899 | __ai uint32x4_t __noswap_vmovl_high_u16(uint16x8_t __p0_132) { | |
| 56900 | uint32x4_t __ret_132; | |
| 56901 | uint16x4_t __a1_132 = __noswap_vget_high_u16(__p0_132); | |
| 56902 | __ret_132 = (uint32x4_t)(__noswap_vshll_n_u16(__a1_132, 0)); | |
| 56903 | return __ret_132; | |
| 53592 | 56904 | } |
| 53593 | 56905 | #endif |
| 53594 | 56906 | |
| 53595 | 56907 | #ifdef __LITTLE_ENDIAN__ |
| 53596 | __ai int16x8_t vmovl_high_s8(int8x16_t __p0_121) { | |
| 53597 | int16x8_t __ret_121; | |
| 53598 | int8x8_t __a1_121 = vget_high_s8(__p0_121); | |
| 53599 | __ret_121 = (int16x8_t)(vshll_n_s8(__a1_121, 0)); | |
| 53600 | return __ret_121; | |
| 56908 | __ai int16x8_t vmovl_high_s8(int8x16_t __p0_133) { | |
| 56909 | int16x8_t __ret_133; | |
| 56910 | int8x8_t __a1_133 = vget_high_s8(__p0_133); | |
| 56911 | __ret_133 = (int16x8_t)(vshll_n_s8(__a1_133, 0)); | |
| 56912 | return __ret_133; | |
| 53601 | 56913 | } |
| 53602 | 56914 | #else |
| 53603 | __ai int16x8_t vmovl_high_s8(int8x16_t __p0_122) { | |
| 53604 | int8x16_t __rev0_122; __rev0_122 = __builtin_shufflevector(__p0_122, __p0_122, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 53605 | int16x8_t __ret_122; | |
| 53606 | int8x8_t __a1_122 = __noswap_vget_high_s8(__rev0_122); | |
| 53607 | __ret_122 = (int16x8_t)(__noswap_vshll_n_s8(__a1_122, 0)); | |
| 53608 | __ret_122 = __builtin_shufflevector(__ret_122, __ret_122, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 53609 | return __ret_122; | |
| 56915 | __ai int16x8_t vmovl_high_s8(int8x16_t __p0_134) { | |
| 56916 | int8x16_t __rev0_134; __rev0_134 = __builtin_shufflevector(__p0_134, __p0_134, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 56917 | int16x8_t __ret_134; | |
| 56918 | int8x8_t __a1_134 = __noswap_vget_high_s8(__rev0_134); | |
| 56919 | __ret_134 = (int16x8_t)(__noswap_vshll_n_s8(__a1_134, 0)); | |
| 56920 | __ret_134 = __builtin_shufflevector(__ret_134, __ret_134, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 56921 | return __ret_134; | |
| 53610 | 56922 | } |
| 53611 | __ai int16x8_t __noswap_vmovl_high_s8(int8x16_t __p0_123) { | |
| 53612 | int16x8_t __ret_123; | |
| 53613 | int8x8_t __a1_123 = __noswap_vget_high_s8(__p0_123); | |
| 53614 | __ret_123 = (int16x8_t)(__noswap_vshll_n_s8(__a1_123, 0)); | |
| 53615 | return __ret_123; | |
| 56923 | __ai int16x8_t __noswap_vmovl_high_s8(int8x16_t __p0_135) { | |
| 56924 | int16x8_t __ret_135; | |
| 56925 | int8x8_t __a1_135 = __noswap_vget_high_s8(__p0_135); | |
| 56926 | __ret_135 = (int16x8_t)(__noswap_vshll_n_s8(__a1_135, 0)); | |
| 56927 | return __ret_135; | |
| 53616 | 56928 | } |
| 53617 | 56929 | #endif |
| 53618 | 56930 | |
| 53619 | 56931 | #ifdef __LITTLE_ENDIAN__ |
| 53620 | __ai int64x2_t vmovl_high_s32(int32x4_t __p0_124) { | |
| 53621 | int64x2_t __ret_124; | |
| 53622 | int32x2_t __a1_124 = vget_high_s32(__p0_124); | |
| 53623 | __ret_124 = (int64x2_t)(vshll_n_s32(__a1_124, 0)); | |
| 53624 | return __ret_124; | |
| 56932 | __ai int64x2_t vmovl_high_s32(int32x4_t __p0_136) { | |
| 56933 | int64x2_t __ret_136; | |
| 56934 | int32x2_t __a1_136 = vget_high_s32(__p0_136); | |
| 56935 | __ret_136 = (int64x2_t)(vshll_n_s32(__a1_136, 0)); | |
| 56936 | return __ret_136; | |
| 53625 | 56937 | } |
| 53626 | 56938 | #else |
| 53627 | __ai int64x2_t vmovl_high_s32(int32x4_t __p0_125) { | |
| 53628 | int32x4_t __rev0_125; __rev0_125 = __builtin_shufflevector(__p0_125, __p0_125, 3, 2, 1, 0); | |
| 53629 | int64x2_t __ret_125; | |
| 53630 | int32x2_t __a1_125 = __noswap_vget_high_s32(__rev0_125); | |
| 53631 | __ret_125 = (int64x2_t)(__noswap_vshll_n_s32(__a1_125, 0)); | |
| 53632 | __ret_125 = __builtin_shufflevector(__ret_125, __ret_125, 1, 0); | |
| 53633 | return __ret_125; | |
| 56939 | __ai int64x2_t vmovl_high_s32(int32x4_t __p0_137) { | |
| 56940 | int32x4_t __rev0_137; __rev0_137 = __builtin_shufflevector(__p0_137, __p0_137, 3, 2, 1, 0); | |
| 56941 | int64x2_t __ret_137; | |
| 56942 | int32x2_t __a1_137 = __noswap_vget_high_s32(__rev0_137); | |
| 56943 | __ret_137 = (int64x2_t)(__noswap_vshll_n_s32(__a1_137, 0)); | |
| 56944 | __ret_137 = __builtin_shufflevector(__ret_137, __ret_137, 1, 0); | |
| 56945 | return __ret_137; | |
| 53634 | 56946 | } |
| 53635 | __ai int64x2_t __noswap_vmovl_high_s32(int32x4_t __p0_126) { | |
| 53636 | int64x2_t __ret_126; | |
| 53637 | int32x2_t __a1_126 = __noswap_vget_high_s32(__p0_126); | |
| 53638 | __ret_126 = (int64x2_t)(__noswap_vshll_n_s32(__a1_126, 0)); | |
| 53639 | return __ret_126; | |
| 56947 | __ai int64x2_t __noswap_vmovl_high_s32(int32x4_t __p0_138) { | |
| 56948 | int64x2_t __ret_138; | |
| 56949 | int32x2_t __a1_138 = __noswap_vget_high_s32(__p0_138); | |
| 56950 | __ret_138 = (int64x2_t)(__noswap_vshll_n_s32(__a1_138, 0)); | |
| 56951 | return __ret_138; | |
| 53640 | 56952 | } |
| 53641 | 56953 | #endif |
| 53642 | 56954 | |
| 53643 | 56955 | #ifdef __LITTLE_ENDIAN__ |
| 53644 | __ai int32x4_t vmovl_high_s16(int16x8_t __p0_127) { | |
| 53645 | int32x4_t __ret_127; | |
| 53646 | int16x4_t __a1_127 = vget_high_s16(__p0_127); | |
| 53647 | __ret_127 = (int32x4_t)(vshll_n_s16(__a1_127, 0)); | |
| 53648 | return __ret_127; | |
| 56956 | __ai int32x4_t vmovl_high_s16(int16x8_t __p0_139) { | |
| 56957 | int32x4_t __ret_139; | |
| 56958 | int16x4_t __a1_139 = vget_high_s16(__p0_139); | |
| 56959 | __ret_139 = (int32x4_t)(vshll_n_s16(__a1_139, 0)); | |
| 56960 | return __ret_139; | |
| 53649 | 56961 | } |
| 53650 | 56962 | #else |
| 53651 | __ai int32x4_t vmovl_high_s16(int16x8_t __p0_128) { | |
| 53652 | int16x8_t __rev0_128; __rev0_128 = __builtin_shufflevector(__p0_128, __p0_128, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 53653 | int32x4_t __ret_128; | |
| 53654 | int16x4_t __a1_128 = __noswap_vget_high_s16(__rev0_128); | |
| 53655 | __ret_128 = (int32x4_t)(__noswap_vshll_n_s16(__a1_128, 0)); | |
| 53656 | __ret_128 = __builtin_shufflevector(__ret_128, __ret_128, 3, 2, 1, 0); | |
| 53657 | return __ret_128; | |
| 56963 | __ai int32x4_t vmovl_high_s16(int16x8_t __p0_140) { | |
| 56964 | int16x8_t __rev0_140; __rev0_140 = __builtin_shufflevector(__p0_140, __p0_140, 7, 6, 5, 4, 3, 2, 1, 0); | |
| 56965 | int32x4_t __ret_140; | |
| 56966 | int16x4_t __a1_140 = __noswap_vget_high_s16(__rev0_140); | |
| 56967 | __ret_140 = (int32x4_t)(__noswap_vshll_n_s16(__a1_140, 0)); | |
| 56968 | __ret_140 = __builtin_shufflevector(__ret_140, __ret_140, 3, 2, 1, 0); | |
| 56969 | return __ret_140; | |
| 53658 | 56970 | } |
| 53659 | __ai int32x4_t __noswap_vmovl_high_s16(int16x8_t __p0_129) { | |
| 53660 | int32x4_t __ret_129; | |
| 53661 | int16x4_t __a1_129 = __noswap_vget_high_s16(__p0_129); | |
| 53662 | __ret_129 = (int32x4_t)(__noswap_vshll_n_s16(__a1_129, 0)); | |
| 53663 | return __ret_129; | |
| 56971 | __ai int32x4_t __noswap_vmovl_high_s16(int16x8_t __p0_141) { | |
| 56972 | int32x4_t __ret_141; | |
| 56973 | int16x4_t __a1_141 = __noswap_vget_high_s16(__p0_141); | |
| 56974 | __ret_141 = (int32x4_t)(__noswap_vshll_n_s16(__a1_141, 0)); | |
| 56975 | return __ret_141; | |
| 53664 | 56976 | } |
| 53665 | 56977 | #endif |
| 53666 | 56978 | |
| ... | ... | @@ -53798,39 +57110,39 @@ __ai float64x1_t vmul_f64(float64x1_t __p0, float64x1_t __p1) { |
| 53798 | 57110 | #endif |
| 53799 | 57111 | |
| 53800 | 57112 | #ifdef __LITTLE_ENDIAN__ |
| 53801 | #define vmuld_lane_f64(__p0_130, __p1_130, __p2_130) __extension__ ({ \ | |
| 53802 | float64_t __s0_130 = __p0_130; \ | |
| 53803 | float64x1_t __s1_130 = __p1_130; \ | |
| 53804 | float64_t __ret_130; \ | |
| 53805 | __ret_130 = __s0_130 * vget_lane_f64(__s1_130, __p2_130); \ | |
| 53806 | __ret_130; \ | |
| 57113 | #define vmuld_lane_f64(__p0_142, __p1_142, __p2_142) __extension__ ({ \ | |
| 57114 | float64_t __s0_142 = __p0_142; \ | |
| 57115 | float64x1_t __s1_142 = __p1_142; \ | |
| 57116 | float64_t __ret_142; \ | |
| 57117 | __ret_142 = __s0_142 * vget_lane_f64(__s1_142, __p2_142); \ | |
| 57118 | __ret_142; \ | |
| 53807 | 57119 | }) |
| 53808 | 57120 | #else |
| 53809 | #define vmuld_lane_f64(__p0_131, __p1_131, __p2_131) __extension__ ({ \ | |
| 53810 | float64_t __s0_131 = __p0_131; \ | |
| 53811 | float64x1_t __s1_131 = __p1_131; \ | |
| 53812 | float64_t __ret_131; \ | |
| 53813 | __ret_131 = __s0_131 * __noswap_vget_lane_f64(__s1_131, __p2_131); \ | |
| 53814 | __ret_131; \ | |
| 57121 | #define vmuld_lane_f64(__p0_143, __p1_143, __p2_143) __extension__ ({ \ | |
| 57122 | float64_t __s0_143 = __p0_143; \ | |
| 57123 | float64x1_t __s1_143 = __p1_143; \ | |
| 57124 | float64_t __ret_143; \ | |
| 57125 | __ret_143 = __s0_143 * __noswap_vget_lane_f64(__s1_143, __p2_143); \ | |
| 57126 | __ret_143; \ | |
| 53815 | 57127 | }) |
| 53816 | 57128 | #endif |
| 53817 | 57129 | |
| 53818 | 57130 | #ifdef __LITTLE_ENDIAN__ |
| 53819 | #define vmuls_lane_f32(__p0_132, __p1_132, __p2_132) __extension__ ({ \ | |
| 53820 | float32_t __s0_132 = __p0_132; \ | |
| 53821 | float32x2_t __s1_132 = __p1_132; \ | |
| 53822 | float32_t __ret_132; \ | |
| 53823 | __ret_132 = __s0_132 * vget_lane_f32(__s1_132, __p2_132); \ | |
| 53824 | __ret_132; \ | |
| 57131 | #define vmuls_lane_f32(__p0_144, __p1_144, __p2_144) __extension__ ({ \ | |
| 57132 | float32_t __s0_144 = __p0_144; \ | |
| 57133 | float32x2_t __s1_144 = __p1_144; \ | |
| 57134 | float32_t __ret_144; \ | |
| 57135 | __ret_144 = __s0_144 * vget_lane_f32(__s1_144, __p2_144); \ | |
| 57136 | __ret_144; \ | |
| 53825 | 57137 | }) |
| 53826 | 57138 | #else |
| 53827 | #define vmuls_lane_f32(__p0_133, __p1_133, __p2_133) __extension__ ({ \ | |
| 53828 | float32_t __s0_133 = __p0_133; \ | |
| 53829 | float32x2_t __s1_133 = __p1_133; \ | |
| 53830 | float32x2_t __rev1_133; __rev1_133 = __builtin_shufflevector(__s1_133, __s1_133, 1, 0); \ | |
| 53831 | float32_t __ret_133; \ | |
| 53832 | __ret_133 = __s0_133 * __noswap_vget_lane_f32(__rev1_133, __p2_133); \ | |
| 53833 | __ret_133; \ | |
| 57139 | #define vmuls_lane_f32(__p0_145, __p1_145, __p2_145) __extension__ ({ \ | |
| 57140 | float32_t __s0_145 = __p0_145; \ | |
| 57141 | float32x2_t __s1_145 = __p1_145; \ | |
| 57142 | float32x2_t __rev1_145; __rev1_145 = __builtin_shufflevector(__s1_145, __s1_145, 1, 0); \ | |
| 57143 | float32_t __ret_145; \ | |
| 57144 | __ret_145 = __s0_145 * __noswap_vget_lane_f32(__rev1_145, __p2_145); \ | |
| 57145 | __ret_145; \ | |
| 53834 | 57146 | }) |
| 53835 | 57147 | #endif |
| 53836 | 57148 | |
| ... | ... | @@ -53873,40 +57185,40 @@ __ai float64x1_t vmul_f64(float64x1_t __p0, float64x1_t __p1) { |
| 53873 | 57185 | #endif |
| 53874 | 57186 | |
| 53875 | 57187 | #ifdef __LITTLE_ENDIAN__ |
| 53876 | #define vmuld_laneq_f64(__p0_134, __p1_134, __p2_134) __extension__ ({ \ | |
| 53877 | float64_t __s0_134 = __p0_134; \ | |
| 53878 | float64x2_t __s1_134 = __p1_134; \ | |
| 53879 | float64_t __ret_134; \ | |
| 53880 | __ret_134 = __s0_134 * vgetq_lane_f64(__s1_134, __p2_134); \ | |
| 53881 | __ret_134; \ | |
| 57188 | #define vmuld_laneq_f64(__p0_146, __p1_146, __p2_146) __extension__ ({ \ | |
| 57189 | float64_t __s0_146 = __p0_146; \ | |
| 57190 | float64x2_t __s1_146 = __p1_146; \ | |
| 57191 | float64_t __ret_146; \ | |
| 57192 | __ret_146 = __s0_146 * vgetq_lane_f64(__s1_146, __p2_146); \ | |
| 57193 | __ret_146; \ | |
| 53882 | 57194 | }) |
| 53883 | 57195 | #else |
| 53884 | #define vmuld_laneq_f64(__p0_135, __p1_135, __p2_135) __extension__ ({ \ | |
| 53885 | float64_t __s0_135 = __p0_135; \ | |
| 53886 | float64x2_t __s1_135 = __p1_135; \ | |
| 53887 | float64x2_t __rev1_135; __rev1_135 = __builtin_shufflevector(__s1_135, __s1_135, 1, 0); \ | |
| 53888 | float64_t __ret_135; \ | |
| 53889 | __ret_135 = __s0_135 * __noswap_vgetq_lane_f64(__rev1_135, __p2_135); \ | |
| 53890 | __ret_135; \ | |
| 57196 | #define vmuld_laneq_f64(__p0_147, __p1_147, __p2_147) __extension__ ({ \ | |
| 57197 | float64_t __s0_147 = __p0_147; \ | |
| 57198 | float64x2_t __s1_147 = __p1_147; \ | |
| 57199 | float64x2_t __rev1_147; __rev1_147 = __builtin_shufflevector(__s1_147, __s1_147, 1, 0); \ | |
| 57200 | float64_t __ret_147; \ | |
| 57201 | __ret_147 = __s0_147 * __noswap_vgetq_lane_f64(__rev1_147, __p2_147); \ | |
| 57202 | __ret_147; \ | |
| 53891 | 57203 | }) |
| 53892 | 57204 | #endif |
| 53893 | 57205 | |
| 53894 | 57206 | #ifdef __LITTLE_ENDIAN__ |
| 53895 | #define vmuls_laneq_f32(__p0_136, __p1_136, __p2_136) __extension__ ({ \ | |
| 53896 | float32_t __s0_136 = __p0_136; \ | |
| 53897 | float32x4_t __s1_136 = __p1_136; \ | |
| 53898 | float32_t __ret_136; \ | |
| 53899 | __ret_136 = __s0_136 * vgetq_lane_f32(__s1_136, __p2_136); \ | |
| 53900 | __ret_136; \ | |
| 57207 | #define vmuls_laneq_f32(__p0_148, __p1_148, __p2_148) __extension__ ({ \ | |
| 57208 | float32_t __s0_148 = __p0_148; \ | |
| 57209 | float32x4_t __s1_148 = __p1_148; \ | |
| 57210 | float32_t __ret_148; \ | |
| 57211 | __ret_148 = __s0_148 * vgetq_lane_f32(__s1_148, __p2_148); \ | |
| 57212 | __ret_148; \ | |
| 53901 | 57213 | }) |
| 53902 | 57214 | #else |
| 53903 | #define vmuls_laneq_f32(__p0_137, __p1_137, __p2_137) __extension__ ({ \ | |
| 53904 | float32_t __s0_137 = __p0_137; \ | |
| 53905 | float32x4_t __s1_137 = __p1_137; \ | |
| 53906 | float32x4_t __rev1_137; __rev1_137 = __builtin_shufflevector(__s1_137, __s1_137, 3, 2, 1, 0); \ | |
| 53907 | float32_t __ret_137; \ | |
| 53908 | __ret_137 = __s0_137 * __noswap_vgetq_lane_f32(__rev1_137, __p2_137); \ | |
| 53909 | __ret_137; \ | |
| 57215 | #define vmuls_laneq_f32(__p0_149, __p1_149, __p2_149) __extension__ ({ \ | |
| 57216 | float32_t __s0_149 = __p0_149; \ | |
| 57217 | float32x4_t __s1_149 = __p1_149; \ | |
| 57218 | float32x4_t __rev1_149; __rev1_149 = __builtin_shufflevector(__s1_149, __s1_149, 3, 2, 1, 0); \ | |
| 57219 | float32_t __ret_149; \ | |
| 57220 | __ret_149 = __s0_149 * __noswap_vgetq_lane_f32(__rev1_149, __p2_149); \ | |
| 57221 | __ret_149; \ | |
| 53910 | 57222 | }) |
| 53911 | 57223 | #endif |
| 53912 | 57224 | |
| ... | ... | @@ -54779,39 +58091,39 @@ __ai float32_t __noswap_vmulxs_f32(float32_t __p0, float32_t __p1) { |
| 54779 | 58091 | #endif |
| 54780 | 58092 | |
| 54781 | 58093 | #ifdef __LITTLE_ENDIAN__ |
| 54782 | #define vmulxd_lane_f64(__p0_138, __p1_138, __p2_138) __extension__ ({ \ | |
| 54783 | float64_t __s0_138 = __p0_138; \ | |
| 54784 | float64x1_t __s1_138 = __p1_138; \ | |
| 54785 | float64_t __ret_138; \ | |
| 54786 | __ret_138 = vmulxd_f64(__s0_138, vget_lane_f64(__s1_138, __p2_138)); \ | |
| 54787 | __ret_138; \ | |
| 58094 | #define vmulxd_lane_f64(__p0_150, __p1_150, __p2_150) __extension__ ({ \ | |
| 58095 | float64_t __s0_150 = __p0_150; \ | |
| 58096 | float64x1_t __s1_150 = __p1_150; \ | |
| 58097 | float64_t __ret_150; \ | |
| 58098 | __ret_150 = vmulxd_f64(__s0_150, vget_lane_f64(__s1_150, __p2_150)); \ | |
| 58099 | __ret_150; \ | |
| 54788 | 58100 | }) |
| 54789 | 58101 | #else |
| 54790 | #define vmulxd_lane_f64(__p0_139, __p1_139, __p2_139) __extension__ ({ \ | |
| 54791 | float64_t __s0_139 = __p0_139; \ | |
| 54792 | float64x1_t __s1_139 = __p1_139; \ | |
| 54793 | float64_t __ret_139; \ | |
| 54794 | __ret_139 = __noswap_vmulxd_f64(__s0_139, __noswap_vget_lane_f64(__s1_139, __p2_139)); \ | |
| 54795 | __ret_139; \ | |
| 58102 | #define vmulxd_lane_f64(__p0_151, __p1_151, __p2_151) __extension__ ({ \ | |
| 58103 | float64_t __s0_151 = __p0_151; \ | |
| 58104 | float64x1_t __s1_151 = __p1_151; \ | |
| 58105 | float64_t __ret_151; \ | |
| 58106 | __ret_151 = __noswap_vmulxd_f64(__s0_151, __noswap_vget_lane_f64(__s1_151, __p2_151)); \ | |
| 58107 | __ret_151; \ | |
| 54796 | 58108 | }) |
| 54797 | 58109 | #endif |
| 54798 | 58110 | |
| 54799 | 58111 | #ifdef __LITTLE_ENDIAN__ |
| 54800 | #define vmulxs_lane_f32(__p0_140, __p1_140, __p2_140) __extension__ ({ \ | |
| 54801 | float32_t __s0_140 = __p0_140; \ | |
| 54802 | float32x2_t __s1_140 = __p1_140; \ | |
| 54803 | float32_t __ret_140; \ | |
| 54804 | __ret_140 = vmulxs_f32(__s0_140, vget_lane_f32(__s1_140, __p2_140)); \ | |
| 54805 | __ret_140; \ | |
| 58112 | #define vmulxs_lane_f32(__p0_152, __p1_152, __p2_152) __extension__ ({ \ | |
| 58113 | float32_t __s0_152 = __p0_152; \ | |
| 58114 | float32x2_t __s1_152 = __p1_152; \ | |
| 58115 | float32_t __ret_152; \ | |
| 58116 | __ret_152 = vmulxs_f32(__s0_152, vget_lane_f32(__s1_152, __p2_152)); \ | |
| 58117 | __ret_152; \ | |
| 54806 | 58118 | }) |
| 54807 | 58119 | #else |
| 54808 | #define vmulxs_lane_f32(__p0_141, __p1_141, __p2_141) __extension__ ({ \ | |
| 54809 | float32_t __s0_141 = __p0_141; \ | |
| 54810 | float32x2_t __s1_141 = __p1_141; \ | |
| 54811 | float32x2_t __rev1_141; __rev1_141 = __builtin_shufflevector(__s1_141, __s1_141, 1, 0); \ | |
| 54812 | float32_t __ret_141; \ | |
| 54813 | __ret_141 = __noswap_vmulxs_f32(__s0_141, __noswap_vget_lane_f32(__rev1_141, __p2_141)); \ | |
| 54814 | __ret_141; \ | |
| 58120 | #define vmulxs_lane_f32(__p0_153, __p1_153, __p2_153) __extension__ ({ \ | |
| 58121 | float32_t __s0_153 = __p0_153; \ | |
| 58122 | float32x2_t __s1_153 = __p1_153; \ | |
| 58123 | float32x2_t __rev1_153; __rev1_153 = __builtin_shufflevector(__s1_153, __s1_153, 1, 0); \ | |
| 58124 | float32_t __ret_153; \ | |
| 58125 | __ret_153 = __noswap_vmulxs_f32(__s0_153, __noswap_vget_lane_f32(__rev1_153, __p2_153)); \ | |
| 58126 | __ret_153; \ | |
| 54815 | 58127 | }) |
| 54816 | 58128 | #endif |
| 54817 | 58129 | |
| ... | ... | @@ -54878,40 +58190,40 @@ __ai float32_t __noswap_vmulxs_f32(float32_t __p0, float32_t __p1) { |
| 54878 | 58190 | #endif |
| 54879 | 58191 | |
| 54880 | 58192 | #ifdef __LITTLE_ENDIAN__ |
| 54881 | #define vmulxd_laneq_f64(__p0_142, __p1_142, __p2_142) __extension__ ({ \ | |
| 54882 | float64_t __s0_142 = __p0_142; \ | |
| 54883 | float64x2_t __s1_142 = __p1_142; \ | |
| 54884 | float64_t __ret_142; \ | |
| 54885 | __ret_142 = vmulxd_f64(__s0_142, vgetq_lane_f64(__s1_142, __p2_142)); \ | |
| 54886 | __ret_142; \ | |
| 58193 | #define vmulxd_laneq_f64(__p0_154, __p1_154, __p2_154) __extension__ ({ \ | |
| 58194 | float64_t __s0_154 = __p0_154; \ | |
| 58195 | float64x2_t __s1_154 = __p1_154; \ | |
| 58196 | float64_t __ret_154; \ | |
| 58197 | __ret_154 = vmulxd_f64(__s0_154, vgetq_lane_f64(__s1_154, __p2_154)); \ | |
| 58198 | __ret_154; \ | |
| 54887 | 58199 | }) |
| 54888 | 58200 | #else |
| 54889 | #define vmulxd_laneq_f64(__p0_143, __p1_143, __p2_143) __extension__ ({ \ | |
| 54890 | float64_t __s0_143 = __p0_143; \ | |
| 54891 | float64x2_t __s1_143 = __p1_143; \ | |
| 54892 | float64x2_t __rev1_143; __rev1_143 = __builtin_shufflevector(__s1_143, __s1_143, 1, 0); \ | |
| 54893 | float64_t __ret_143; \ | |
| 54894 | __ret_143 = __noswap_vmulxd_f64(__s0_143, __noswap_vgetq_lane_f64(__rev1_143, __p2_143)); \ | |
| 54895 | __ret_143; \ | |
| 58201 | #define vmulxd_laneq_f64(__p0_155, __p1_155, __p2_155) __extension__ ({ \ | |
| 58202 | float64_t __s0_155 = __p0_155; \ | |
| 58203 | float64x2_t __s1_155 = __p1_155; \ | |
| 58204 | float64x2_t __rev1_155; __rev1_155 = __builtin_shufflevector(__s1_155, __s1_155, 1, 0); \ | |
| 58205 | float64_t __ret_155; \ | |
| 58206 | __ret_155 = __noswap_vmulxd_f64(__s0_155, __noswap_vgetq_lane_f64(__rev1_155, __p2_155)); \ | |
| 58207 | __ret_155; \ | |
| 54896 | 58208 | }) |
| 54897 | 58209 | #endif |
| 54898 | 58210 | |
| 54899 | 58211 | #ifdef __LITTLE_ENDIAN__ |
| 54900 | #define vmulxs_laneq_f32(__p0_144, __p1_144, __p2_144) __extension__ ({ \ | |
| 54901 | float32_t __s0_144 = __p0_144; \ | |
| 54902 | float32x4_t __s1_144 = __p1_144; \ | |
| 54903 | float32_t __ret_144; \ | |
| 54904 | __ret_144 = vmulxs_f32(__s0_144, vgetq_lane_f32(__s1_144, __p2_144)); \ | |
| 54905 | __ret_144; \ | |
| 58212 | #define vmulxs_laneq_f32(__p0_156, __p1_156, __p2_156) __extension__ ({ \ | |
| 58213 | float32_t __s0_156 = __p0_156; \ | |
| 58214 | float32x4_t __s1_156 = __p1_156; \ | |
| 58215 | float32_t __ret_156; \ | |
| 58216 | __ret_156 = vmulxs_f32(__s0_156, vgetq_lane_f32(__s1_156, __p2_156)); \ | |
| 58217 | __ret_156; \ | |
| 54906 | 58218 | }) |
| 54907 | 58219 | #else |
| 54908 | #define vmulxs_laneq_f32(__p0_145, __p1_145, __p2_145) __extension__ ({ \ | |
| 54909 | float32_t __s0_145 = __p0_145; \ | |
| 54910 | float32x4_t __s1_145 = __p1_145; \ | |
| 54911 | float32x4_t __rev1_145; __rev1_145 = __builtin_shufflevector(__s1_145, __s1_145, 3, 2, 1, 0); \ | |
| 54912 | float32_t __ret_145; \ | |
| 54913 | __ret_145 = __noswap_vmulxs_f32(__s0_145, __noswap_vgetq_lane_f32(__rev1_145, __p2_145)); \ | |
| 54914 | __ret_145; \ | |
| 58220 | #define vmulxs_laneq_f32(__p0_157, __p1_157, __p2_157) __extension__ ({ \ | |
| 58221 | float32_t __s0_157 = __p0_157; \ | |
| 58222 | float32x4_t __s1_157 = __p1_157; \ | |
| 58223 | float32x4_t __rev1_157; __rev1_157 = __builtin_shufflevector(__s1_157, __s1_157, 3, 2, 1, 0); \ | |
| 58224 | float32_t __ret_157; \ | |
| 58225 | __ret_157 = __noswap_vmulxs_f32(__s0_157, __noswap_vgetq_lane_f32(__rev1_157, __p2_157)); \ | |
| 58226 | __ret_157; \ | |
| 54915 | 58227 | }) |
| 54916 | 58228 | #endif |
| 54917 | 58229 | |
| ... | ... | @@ -56675,78 +59987,78 @@ __ai int16_t __noswap_vqdmulhh_s16(int16_t __p0, int16_t __p1) { |
| 56675 | 59987 | #endif |
| 56676 | 59988 | |
| 56677 | 59989 | #ifdef __LITTLE_ENDIAN__ |
| 56678 | #define vqdmulhs_lane_s32(__p0_146, __p1_146, __p2_146) __extension__ ({ \ | |
| 56679 | int32_t __s0_146 = __p0_146; \ | |
| 56680 | int32x2_t __s1_146 = __p1_146; \ | |
| 56681 | int32_t __ret_146; \ | |
| 56682 | __ret_146 = vqdmulhs_s32(__s0_146, vget_lane_s32(__s1_146, __p2_146)); \ | |
| 56683 | __ret_146; \ | |
| 59990 | #define vqdmulhs_lane_s32(__p0_158, __p1_158, __p2_158) __extension__ ({ \ | |
| 59991 | int32_t __s0_158 = __p0_158; \ | |
| 59992 | int32x2_t __s1_158 = __p1_158; \ | |
| 59993 | int32_t __ret_158; \ | |
| 59994 | __ret_158 = vqdmulhs_s32(__s0_158, vget_lane_s32(__s1_158, __p2_158)); \ | |
| 59995 | __ret_158; \ | |
| 56684 | 59996 | }) |
| 56685 | 59997 | #else |
| 56686 | #define vqdmulhs_lane_s32(__p0_147, __p1_147, __p2_147) __extension__ ({ \ | |
| 56687 | int32_t __s0_147 = __p0_147; \ | |
| 56688 | int32x2_t __s1_147 = __p1_147; \ | |
| 56689 | int32x2_t __rev1_147; __rev1_147 = __builtin_shufflevector(__s1_147, __s1_147, 1, 0); \ | |
| 56690 | int32_t __ret_147; \ | |
| 56691 | __ret_147 = __noswap_vqdmulhs_s32(__s0_147, __noswap_vget_lane_s32(__rev1_147, __p2_147)); \ | |
| 56692 | __ret_147; \ | |
| 59998 | #define vqdmulhs_lane_s32(__p0_159, __p1_159, __p2_159) __extension__ ({ \ | |
| 59999 | int32_t __s0_159 = __p0_159; \ | |
| 60000 | int32x2_t __s1_159 = __p1_159; \ | |
| 60001 | int32x2_t __rev1_159; __rev1_159 = __builtin_shufflevector(__s1_159, __s1_159, 1, 0); \ | |
| 60002 | int32_t __ret_159; \ | |
| 60003 | __ret_159 = __noswap_vqdmulhs_s32(__s0_159, __noswap_vget_lane_s32(__rev1_159, __p2_159)); \ | |
| 60004 | __ret_159; \ | |
| 56693 | 60005 | }) |
| 56694 | 60006 | #endif |
| 56695 | 60007 | |
| 56696 | 60008 | #ifdef __LITTLE_ENDIAN__ |
| 56697 | #define vqdmulhh_lane_s16(__p0_148, __p1_148, __p2_148) __extension__ ({ \ | |
| 56698 | int16_t __s0_148 = __p0_148; \ | |
| 56699 | int16x4_t __s1_148 = __p1_148; \ | |
| 56700 | int16_t __ret_148; \ | |
| 56701 | __ret_148 = vqdmulhh_s16(__s0_148, vget_lane_s16(__s1_148, __p2_148)); \ | |
| 56702 | __ret_148; \ | |
| 60009 | #define vqdmulhh_lane_s16(__p0_160, __p1_160, __p2_160) __extension__ ({ \ | |
| 60010 | int16_t __s0_160 = __p0_160; \ | |
| 60011 | int16x4_t __s1_160 = __p1_160; \ | |
| 60012 | int16_t __ret_160; \ | |
| 60013 | __ret_160 = vqdmulhh_s16(__s0_160, vget_lane_s16(__s1_160, __p2_160)); \ | |
| 60014 | __ret_160; \ | |
| 56703 | 60015 | }) |
| 56704 | 60016 | #else |
| 56705 | #define vqdmulhh_lane_s16(__p0_149, __p1_149, __p2_149) __extension__ ({ \ | |
| 56706 | int16_t __s0_149 = __p0_149; \ | |
| 56707 | int16x4_t __s1_149 = __p1_149; \ | |
| 56708 | int16x4_t __rev1_149; __rev1_149 = __builtin_shufflevector(__s1_149, __s1_149, 3, 2, 1, 0); \ | |
| 56709 | int16_t __ret_149; \ | |
| 56710 | __ret_149 = __noswap_vqdmulhh_s16(__s0_149, __noswap_vget_lane_s16(__rev1_149, __p2_149)); \ | |
| 56711 | __ret_149; \ | |
| 60017 | #define vqdmulhh_lane_s16(__p0_161, __p1_161, __p2_161) __extension__ ({ \ | |
| 60018 | int16_t __s0_161 = __p0_161; \ | |
| 60019 | int16x4_t __s1_161 = __p1_161; \ | |
| 60020 | int16x4_t __rev1_161; __rev1_161 = __builtin_shufflevector(__s1_161, __s1_161, 3, 2, 1, 0); \ | |
| 60021 | int16_t __ret_161; \ | |
| 60022 | __ret_161 = __noswap_vqdmulhh_s16(__s0_161, __noswap_vget_lane_s16(__rev1_161, __p2_161)); \ | |
| 60023 | __ret_161; \ | |
| 56712 | 60024 | }) |
| 56713 | 60025 | #endif |
| 56714 | 60026 | |
| 56715 | 60027 | #ifdef __LITTLE_ENDIAN__ |
| 56716 | #define vqdmulhs_laneq_s32(__p0_150, __p1_150, __p2_150) __extension__ ({ \ | |
| 56717 | int32_t __s0_150 = __p0_150; \ | |
| 56718 | int32x4_t __s1_150 = __p1_150; \ | |
| 56719 | int32_t __ret_150; \ | |
| 56720 | __ret_150 = vqdmulhs_s32(__s0_150, vgetq_lane_s32(__s1_150, __p2_150)); \ | |
| 56721 | __ret_150; \ | |
| 60028 | #define vqdmulhs_laneq_s32(__p0_162, __p1_162, __p2_162) __extension__ ({ \ | |
| 60029 | int32_t __s0_162 = __p0_162; \ | |
| 60030 | int32x4_t __s1_162 = __p1_162; \ | |
| 60031 | int32_t __ret_162; \ | |
| 60032 | __ret_162 = vqdmulhs_s32(__s0_162, vgetq_lane_s32(__s1_162, __p2_162)); \ | |
| 60033 | __ret_162; \ | |
| 56722 | 60034 | }) |
| 56723 | 60035 | #else |
| 56724 | #define vqdmulhs_laneq_s32(__p0_151, __p1_151, __p2_151) __extension__ ({ \ | |
| 56725 | int32_t __s0_151 = __p0_151; \ | |
| 56726 | int32x4_t __s1_151 = __p1_151; \ | |
| 56727 | int32x4_t __rev1_151; __rev1_151 = __builtin_shufflevector(__s1_151, __s1_151, 3, 2, 1, 0); \ | |
| 56728 | int32_t __ret_151; \ | |
| 56729 | __ret_151 = __noswap_vqdmulhs_s32(__s0_151, __noswap_vgetq_lane_s32(__rev1_151, __p2_151)); \ | |
| 56730 | __ret_151; \ | |
| 60036 | #define vqdmulhs_laneq_s32(__p0_163, __p1_163, __p2_163) __extension__ ({ \ | |
| 60037 | int32_t __s0_163 = __p0_163; \ | |
| 60038 | int32x4_t __s1_163 = __p1_163; \ | |
| 60039 | int32x4_t __rev1_163; __rev1_163 = __builtin_shufflevector(__s1_163, __s1_163, 3, 2, 1, 0); \ | |
| 60040 | int32_t __ret_163; \ | |
| 60041 | __ret_163 = __noswap_vqdmulhs_s32(__s0_163, __noswap_vgetq_lane_s32(__rev1_163, __p2_163)); \ | |
| 60042 | __ret_163; \ | |
| 56731 | 60043 | }) |
| 56732 | 60044 | #endif |
| 56733 | 60045 | |
| 56734 | 60046 | #ifdef __LITTLE_ENDIAN__ |
| 56735 | #define vqdmulhh_laneq_s16(__p0_152, __p1_152, __p2_152) __extension__ ({ \ | |
| 56736 | int16_t __s0_152 = __p0_152; \ | |
| 56737 | int16x8_t __s1_152 = __p1_152; \ | |
| 56738 | int16_t __ret_152; \ | |
| 56739 | __ret_152 = vqdmulhh_s16(__s0_152, vgetq_lane_s16(__s1_152, __p2_152)); \ | |
| 56740 | __ret_152; \ | |
| 60047 | #define vqdmulhh_laneq_s16(__p0_164, __p1_164, __p2_164) __extension__ ({ \ | |
| 60048 | int16_t __s0_164 = __p0_164; \ | |
| 60049 | int16x8_t __s1_164 = __p1_164; \ | |
| 60050 | int16_t __ret_164; \ | |
| 60051 | __ret_164 = vqdmulhh_s16(__s0_164, vgetq_lane_s16(__s1_164, __p2_164)); \ | |
| 60052 | __ret_164; \ | |
| 56741 | 60053 | }) |
| 56742 | 60054 | #else |
| 56743 | #define vqdmulhh_laneq_s16(__p0_153, __p1_153, __p2_153) __extension__ ({ \ | |
| 56744 | int16_t __s0_153 = __p0_153; \ | |
| 56745 | int16x8_t __s1_153 = __p1_153; \ | |
| 56746 | int16x8_t __rev1_153; __rev1_153 = __builtin_shufflevector(__s1_153, __s1_153, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 56747 | int16_t __ret_153; \ | |
| 56748 | __ret_153 = __noswap_vqdmulhh_s16(__s0_153, __noswap_vgetq_lane_s16(__rev1_153, __p2_153)); \ | |
| 56749 | __ret_153; \ | |
| 60055 | #define vqdmulhh_laneq_s16(__p0_165, __p1_165, __p2_165) __extension__ ({ \ | |
| 60056 | int16_t __s0_165 = __p0_165; \ | |
| 60057 | int16x8_t __s1_165 = __p1_165; \ | |
| 60058 | int16x8_t __rev1_165; __rev1_165 = __builtin_shufflevector(__s1_165, __s1_165, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60059 | int16_t __ret_165; \ | |
| 60060 | __ret_165 = __noswap_vqdmulhh_s16(__s0_165, __noswap_vgetq_lane_s16(__rev1_165, __p2_165)); \ | |
| 60061 | __ret_165; \ | |
| 56750 | 60062 | }) |
| 56751 | 60063 | #endif |
| 56752 | 60064 | |
| ... | ... | @@ -57023,78 +60335,78 @@ __ai int32x4_t vqdmull_high_n_s16(int16x8_t __p0, int16_t __p1) { |
| 57023 | 60335 | #endif |
| 57024 | 60336 | |
| 57025 | 60337 | #ifdef __LITTLE_ENDIAN__ |
| 57026 | #define vqdmulls_lane_s32(__p0_154, __p1_154, __p2_154) __extension__ ({ \ | |
| 57027 | int32_t __s0_154 = __p0_154; \ | |
| 57028 | int32x2_t __s1_154 = __p1_154; \ | |
| 57029 | int64_t __ret_154; \ | |
| 57030 | __ret_154 = vqdmulls_s32(__s0_154, vget_lane_s32(__s1_154, __p2_154)); \ | |
| 57031 | __ret_154; \ | |
| 60338 | #define vqdmulls_lane_s32(__p0_166, __p1_166, __p2_166) __extension__ ({ \ | |
| 60339 | int32_t __s0_166 = __p0_166; \ | |
| 60340 | int32x2_t __s1_166 = __p1_166; \ | |
| 60341 | int64_t __ret_166; \ | |
| 60342 | __ret_166 = vqdmulls_s32(__s0_166, vget_lane_s32(__s1_166, __p2_166)); \ | |
| 60343 | __ret_166; \ | |
| 57032 | 60344 | }) |
| 57033 | 60345 | #else |
| 57034 | #define vqdmulls_lane_s32(__p0_155, __p1_155, __p2_155) __extension__ ({ \ | |
| 57035 | int32_t __s0_155 = __p0_155; \ | |
| 57036 | int32x2_t __s1_155 = __p1_155; \ | |
| 57037 | int32x2_t __rev1_155; __rev1_155 = __builtin_shufflevector(__s1_155, __s1_155, 1, 0); \ | |
| 57038 | int64_t __ret_155; \ | |
| 57039 | __ret_155 = __noswap_vqdmulls_s32(__s0_155, __noswap_vget_lane_s32(__rev1_155, __p2_155)); \ | |
| 57040 | __ret_155; \ | |
| 60346 | #define vqdmulls_lane_s32(__p0_167, __p1_167, __p2_167) __extension__ ({ \ | |
| 60347 | int32_t __s0_167 = __p0_167; \ | |
| 60348 | int32x2_t __s1_167 = __p1_167; \ | |
| 60349 | int32x2_t __rev1_167; __rev1_167 = __builtin_shufflevector(__s1_167, __s1_167, 1, 0); \ | |
| 60350 | int64_t __ret_167; \ | |
| 60351 | __ret_167 = __noswap_vqdmulls_s32(__s0_167, __noswap_vget_lane_s32(__rev1_167, __p2_167)); \ | |
| 60352 | __ret_167; \ | |
| 57041 | 60353 | }) |
| 57042 | 60354 | #endif |
| 57043 | 60355 | |
| 57044 | 60356 | #ifdef __LITTLE_ENDIAN__ |
| 57045 | #define vqdmullh_lane_s16(__p0_156, __p1_156, __p2_156) __extension__ ({ \ | |
| 57046 | int16_t __s0_156 = __p0_156; \ | |
| 57047 | int16x4_t __s1_156 = __p1_156; \ | |
| 57048 | int32_t __ret_156; \ | |
| 57049 | __ret_156 = vqdmullh_s16(__s0_156, vget_lane_s16(__s1_156, __p2_156)); \ | |
| 57050 | __ret_156; \ | |
| 60357 | #define vqdmullh_lane_s16(__p0_168, __p1_168, __p2_168) __extension__ ({ \ | |
| 60358 | int16_t __s0_168 = __p0_168; \ | |
| 60359 | int16x4_t __s1_168 = __p1_168; \ | |
| 60360 | int32_t __ret_168; \ | |
| 60361 | __ret_168 = vqdmullh_s16(__s0_168, vget_lane_s16(__s1_168, __p2_168)); \ | |
| 60362 | __ret_168; \ | |
| 57051 | 60363 | }) |
| 57052 | 60364 | #else |
| 57053 | #define vqdmullh_lane_s16(__p0_157, __p1_157, __p2_157) __extension__ ({ \ | |
| 57054 | int16_t __s0_157 = __p0_157; \ | |
| 57055 | int16x4_t __s1_157 = __p1_157; \ | |
| 57056 | int16x4_t __rev1_157; __rev1_157 = __builtin_shufflevector(__s1_157, __s1_157, 3, 2, 1, 0); \ | |
| 57057 | int32_t __ret_157; \ | |
| 57058 | __ret_157 = __noswap_vqdmullh_s16(__s0_157, __noswap_vget_lane_s16(__rev1_157, __p2_157)); \ | |
| 57059 | __ret_157; \ | |
| 60365 | #define vqdmullh_lane_s16(__p0_169, __p1_169, __p2_169) __extension__ ({ \ | |
| 60366 | int16_t __s0_169 = __p0_169; \ | |
| 60367 | int16x4_t __s1_169 = __p1_169; \ | |
| 60368 | int16x4_t __rev1_169; __rev1_169 = __builtin_shufflevector(__s1_169, __s1_169, 3, 2, 1, 0); \ | |
| 60369 | int32_t __ret_169; \ | |
| 60370 | __ret_169 = __noswap_vqdmullh_s16(__s0_169, __noswap_vget_lane_s16(__rev1_169, __p2_169)); \ | |
| 60371 | __ret_169; \ | |
| 57060 | 60372 | }) |
| 57061 | 60373 | #endif |
| 57062 | 60374 | |
| 57063 | 60375 | #ifdef __LITTLE_ENDIAN__ |
| 57064 | #define vqdmulls_laneq_s32(__p0_158, __p1_158, __p2_158) __extension__ ({ \ | |
| 57065 | int32_t __s0_158 = __p0_158; \ | |
| 57066 | int32x4_t __s1_158 = __p1_158; \ | |
| 57067 | int64_t __ret_158; \ | |
| 57068 | __ret_158 = vqdmulls_s32(__s0_158, vgetq_lane_s32(__s1_158, __p2_158)); \ | |
| 57069 | __ret_158; \ | |
| 60376 | #define vqdmulls_laneq_s32(__p0_170, __p1_170, __p2_170) __extension__ ({ \ | |
| 60377 | int32_t __s0_170 = __p0_170; \ | |
| 60378 | int32x4_t __s1_170 = __p1_170; \ | |
| 60379 | int64_t __ret_170; \ | |
| 60380 | __ret_170 = vqdmulls_s32(__s0_170, vgetq_lane_s32(__s1_170, __p2_170)); \ | |
| 60381 | __ret_170; \ | |
| 57070 | 60382 | }) |
| 57071 | 60383 | #else |
| 57072 | #define vqdmulls_laneq_s32(__p0_159, __p1_159, __p2_159) __extension__ ({ \ | |
| 57073 | int32_t __s0_159 = __p0_159; \ | |
| 57074 | int32x4_t __s1_159 = __p1_159; \ | |
| 57075 | int32x4_t __rev1_159; __rev1_159 = __builtin_shufflevector(__s1_159, __s1_159, 3, 2, 1, 0); \ | |
| 57076 | int64_t __ret_159; \ | |
| 57077 | __ret_159 = __noswap_vqdmulls_s32(__s0_159, __noswap_vgetq_lane_s32(__rev1_159, __p2_159)); \ | |
| 57078 | __ret_159; \ | |
| 60384 | #define vqdmulls_laneq_s32(__p0_171, __p1_171, __p2_171) __extension__ ({ \ | |
| 60385 | int32_t __s0_171 = __p0_171; \ | |
| 60386 | int32x4_t __s1_171 = __p1_171; \ | |
| 60387 | int32x4_t __rev1_171; __rev1_171 = __builtin_shufflevector(__s1_171, __s1_171, 3, 2, 1, 0); \ | |
| 60388 | int64_t __ret_171; \ | |
| 60389 | __ret_171 = __noswap_vqdmulls_s32(__s0_171, __noswap_vgetq_lane_s32(__rev1_171, __p2_171)); \ | |
| 60390 | __ret_171; \ | |
| 57079 | 60391 | }) |
| 57080 | 60392 | #endif |
| 57081 | 60393 | |
| 57082 | 60394 | #ifdef __LITTLE_ENDIAN__ |
| 57083 | #define vqdmullh_laneq_s16(__p0_160, __p1_160, __p2_160) __extension__ ({ \ | |
| 57084 | int16_t __s0_160 = __p0_160; \ | |
| 57085 | int16x8_t __s1_160 = __p1_160; \ | |
| 57086 | int32_t __ret_160; \ | |
| 57087 | __ret_160 = vqdmullh_s16(__s0_160, vgetq_lane_s16(__s1_160, __p2_160)); \ | |
| 57088 | __ret_160; \ | |
| 60395 | #define vqdmullh_laneq_s16(__p0_172, __p1_172, __p2_172) __extension__ ({ \ | |
| 60396 | int16_t __s0_172 = __p0_172; \ | |
| 60397 | int16x8_t __s1_172 = __p1_172; \ | |
| 60398 | int32_t __ret_172; \ | |
| 60399 | __ret_172 = vqdmullh_s16(__s0_172, vgetq_lane_s16(__s1_172, __p2_172)); \ | |
| 60400 | __ret_172; \ | |
| 57089 | 60401 | }) |
| 57090 | 60402 | #else |
| 57091 | #define vqdmullh_laneq_s16(__p0_161, __p1_161, __p2_161) __extension__ ({ \ | |
| 57092 | int16_t __s0_161 = __p0_161; \ | |
| 57093 | int16x8_t __s1_161 = __p1_161; \ | |
| 57094 | int16x8_t __rev1_161; __rev1_161 = __builtin_shufflevector(__s1_161, __s1_161, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 57095 | int32_t __ret_161; \ | |
| 57096 | __ret_161 = __noswap_vqdmullh_s16(__s0_161, __noswap_vgetq_lane_s16(__rev1_161, __p2_161)); \ | |
| 57097 | __ret_161; \ | |
| 60403 | #define vqdmullh_laneq_s16(__p0_173, __p1_173, __p2_173) __extension__ ({ \ | |
| 60404 | int16_t __s0_173 = __p0_173; \ | |
| 60405 | int16x8_t __s1_173 = __p1_173; \ | |
| 60406 | int16x8_t __rev1_173; __rev1_173 = __builtin_shufflevector(__s1_173, __s1_173, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60407 | int32_t __ret_173; \ | |
| 60408 | __ret_173 = __noswap_vqdmullh_s16(__s0_173, __noswap_vgetq_lane_s16(__rev1_173, __p2_173)); \ | |
| 60409 | __ret_173; \ | |
| 57098 | 60410 | }) |
| 57099 | 60411 | #endif |
| 57100 | 60412 | |
| ... | ... | @@ -57544,78 +60856,78 @@ __ai int16_t __noswap_vqrdmulhh_s16(int16_t __p0, int16_t __p1) { |
| 57544 | 60856 | #endif |
| 57545 | 60857 | |
| 57546 | 60858 | #ifdef __LITTLE_ENDIAN__ |
| 57547 | #define vqrdmulhs_lane_s32(__p0_162, __p1_162, __p2_162) __extension__ ({ \ | |
| 57548 | int32_t __s0_162 = __p0_162; \ | |
| 57549 | int32x2_t __s1_162 = __p1_162; \ | |
| 57550 | int32_t __ret_162; \ | |
| 57551 | __ret_162 = vqrdmulhs_s32(__s0_162, vget_lane_s32(__s1_162, __p2_162)); \ | |
| 57552 | __ret_162; \ | |
| 60859 | #define vqrdmulhs_lane_s32(__p0_174, __p1_174, __p2_174) __extension__ ({ \ | |
| 60860 | int32_t __s0_174 = __p0_174; \ | |
| 60861 | int32x2_t __s1_174 = __p1_174; \ | |
| 60862 | int32_t __ret_174; \ | |
| 60863 | __ret_174 = vqrdmulhs_s32(__s0_174, vget_lane_s32(__s1_174, __p2_174)); \ | |
| 60864 | __ret_174; \ | |
| 57553 | 60865 | }) |
| 57554 | 60866 | #else |
| 57555 | #define vqrdmulhs_lane_s32(__p0_163, __p1_163, __p2_163) __extension__ ({ \ | |
| 57556 | int32_t __s0_163 = __p0_163; \ | |
| 57557 | int32x2_t __s1_163 = __p1_163; \ | |
| 57558 | int32x2_t __rev1_163; __rev1_163 = __builtin_shufflevector(__s1_163, __s1_163, 1, 0); \ | |
| 57559 | int32_t __ret_163; \ | |
| 57560 | __ret_163 = __noswap_vqrdmulhs_s32(__s0_163, __noswap_vget_lane_s32(__rev1_163, __p2_163)); \ | |
| 57561 | __ret_163; \ | |
| 60867 | #define vqrdmulhs_lane_s32(__p0_175, __p1_175, __p2_175) __extension__ ({ \ | |
| 60868 | int32_t __s0_175 = __p0_175; \ | |
| 60869 | int32x2_t __s1_175 = __p1_175; \ | |
| 60870 | int32x2_t __rev1_175; __rev1_175 = __builtin_shufflevector(__s1_175, __s1_175, 1, 0); \ | |
| 60871 | int32_t __ret_175; \ | |
| 60872 | __ret_175 = __noswap_vqrdmulhs_s32(__s0_175, __noswap_vget_lane_s32(__rev1_175, __p2_175)); \ | |
| 60873 | __ret_175; \ | |
| 57562 | 60874 | }) |
| 57563 | 60875 | #endif |
| 57564 | 60876 | |
| 57565 | 60877 | #ifdef __LITTLE_ENDIAN__ |
| 57566 | #define vqrdmulhh_lane_s16(__p0_164, __p1_164, __p2_164) __extension__ ({ \ | |
| 57567 | int16_t __s0_164 = __p0_164; \ | |
| 57568 | int16x4_t __s1_164 = __p1_164; \ | |
| 57569 | int16_t __ret_164; \ | |
| 57570 | __ret_164 = vqrdmulhh_s16(__s0_164, vget_lane_s16(__s1_164, __p2_164)); \ | |
| 57571 | __ret_164; \ | |
| 60878 | #define vqrdmulhh_lane_s16(__p0_176, __p1_176, __p2_176) __extension__ ({ \ | |
| 60879 | int16_t __s0_176 = __p0_176; \ | |
| 60880 | int16x4_t __s1_176 = __p1_176; \ | |
| 60881 | int16_t __ret_176; \ | |
| 60882 | __ret_176 = vqrdmulhh_s16(__s0_176, vget_lane_s16(__s1_176, __p2_176)); \ | |
| 60883 | __ret_176; \ | |
| 57572 | 60884 | }) |
| 57573 | 60885 | #else |
| 57574 | #define vqrdmulhh_lane_s16(__p0_165, __p1_165, __p2_165) __extension__ ({ \ | |
| 57575 | int16_t __s0_165 = __p0_165; \ | |
| 57576 | int16x4_t __s1_165 = __p1_165; \ | |
| 57577 | int16x4_t __rev1_165; __rev1_165 = __builtin_shufflevector(__s1_165, __s1_165, 3, 2, 1, 0); \ | |
| 57578 | int16_t __ret_165; \ | |
| 57579 | __ret_165 = __noswap_vqrdmulhh_s16(__s0_165, __noswap_vget_lane_s16(__rev1_165, __p2_165)); \ | |
| 57580 | __ret_165; \ | |
| 60886 | #define vqrdmulhh_lane_s16(__p0_177, __p1_177, __p2_177) __extension__ ({ \ | |
| 60887 | int16_t __s0_177 = __p0_177; \ | |
| 60888 | int16x4_t __s1_177 = __p1_177; \ | |
| 60889 | int16x4_t __rev1_177; __rev1_177 = __builtin_shufflevector(__s1_177, __s1_177, 3, 2, 1, 0); \ | |
| 60890 | int16_t __ret_177; \ | |
| 60891 | __ret_177 = __noswap_vqrdmulhh_s16(__s0_177, __noswap_vget_lane_s16(__rev1_177, __p2_177)); \ | |
| 60892 | __ret_177; \ | |
| 57581 | 60893 | }) |
| 57582 | 60894 | #endif |
| 57583 | 60895 | |
| 57584 | 60896 | #ifdef __LITTLE_ENDIAN__ |
| 57585 | #define vqrdmulhs_laneq_s32(__p0_166, __p1_166, __p2_166) __extension__ ({ \ | |
| 57586 | int32_t __s0_166 = __p0_166; \ | |
| 57587 | int32x4_t __s1_166 = __p1_166; \ | |
| 57588 | int32_t __ret_166; \ | |
| 57589 | __ret_166 = vqrdmulhs_s32(__s0_166, vgetq_lane_s32(__s1_166, __p2_166)); \ | |
| 57590 | __ret_166; \ | |
| 60897 | #define vqrdmulhs_laneq_s32(__p0_178, __p1_178, __p2_178) __extension__ ({ \ | |
| 60898 | int32_t __s0_178 = __p0_178; \ | |
| 60899 | int32x4_t __s1_178 = __p1_178; \ | |
| 60900 | int32_t __ret_178; \ | |
| 60901 | __ret_178 = vqrdmulhs_s32(__s0_178, vgetq_lane_s32(__s1_178, __p2_178)); \ | |
| 60902 | __ret_178; \ | |
| 57591 | 60903 | }) |
| 57592 | 60904 | #else |
| 57593 | #define vqrdmulhs_laneq_s32(__p0_167, __p1_167, __p2_167) __extension__ ({ \ | |
| 57594 | int32_t __s0_167 = __p0_167; \ | |
| 57595 | int32x4_t __s1_167 = __p1_167; \ | |
| 57596 | int32x4_t __rev1_167; __rev1_167 = __builtin_shufflevector(__s1_167, __s1_167, 3, 2, 1, 0); \ | |
| 57597 | int32_t __ret_167; \ | |
| 57598 | __ret_167 = __noswap_vqrdmulhs_s32(__s0_167, __noswap_vgetq_lane_s32(__rev1_167, __p2_167)); \ | |
| 57599 | __ret_167; \ | |
| 60905 | #define vqrdmulhs_laneq_s32(__p0_179, __p1_179, __p2_179) __extension__ ({ \ | |
| 60906 | int32_t __s0_179 = __p0_179; \ | |
| 60907 | int32x4_t __s1_179 = __p1_179; \ | |
| 60908 | int32x4_t __rev1_179; __rev1_179 = __builtin_shufflevector(__s1_179, __s1_179, 3, 2, 1, 0); \ | |
| 60909 | int32_t __ret_179; \ | |
| 60910 | __ret_179 = __noswap_vqrdmulhs_s32(__s0_179, __noswap_vgetq_lane_s32(__rev1_179, __p2_179)); \ | |
| 60911 | __ret_179; \ | |
| 57600 | 60912 | }) |
| 57601 | 60913 | #endif |
| 57602 | 60914 | |
| 57603 | 60915 | #ifdef __LITTLE_ENDIAN__ |
| 57604 | #define vqrdmulhh_laneq_s16(__p0_168, __p1_168, __p2_168) __extension__ ({ \ | |
| 57605 | int16_t __s0_168 = __p0_168; \ | |
| 57606 | int16x8_t __s1_168 = __p1_168; \ | |
| 57607 | int16_t __ret_168; \ | |
| 57608 | __ret_168 = vqrdmulhh_s16(__s0_168, vgetq_lane_s16(__s1_168, __p2_168)); \ | |
| 57609 | __ret_168; \ | |
| 60916 | #define vqrdmulhh_laneq_s16(__p0_180, __p1_180, __p2_180) __extension__ ({ \ | |
| 60917 | int16_t __s0_180 = __p0_180; \ | |
| 60918 | int16x8_t __s1_180 = __p1_180; \ | |
| 60919 | int16_t __ret_180; \ | |
| 60920 | __ret_180 = vqrdmulhh_s16(__s0_180, vgetq_lane_s16(__s1_180, __p2_180)); \ | |
| 60921 | __ret_180; \ | |
| 57610 | 60922 | }) |
| 57611 | 60923 | #else |
| 57612 | #define vqrdmulhh_laneq_s16(__p0_169, __p1_169, __p2_169) __extension__ ({ \ | |
| 57613 | int16_t __s0_169 = __p0_169; \ | |
| 57614 | int16x8_t __s1_169 = __p1_169; \ | |
| 57615 | int16x8_t __rev1_169; __rev1_169 = __builtin_shufflevector(__s1_169, __s1_169, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 57616 | int16_t __ret_169; \ | |
| 57617 | __ret_169 = __noswap_vqrdmulhh_s16(__s0_169, __noswap_vgetq_lane_s16(__rev1_169, __p2_169)); \ | |
| 57618 | __ret_169; \ | |
| 60924 | #define vqrdmulhh_laneq_s16(__p0_181, __p1_181, __p2_181) __extension__ ({ \ | |
| 60925 | int16_t __s0_181 = __p0_181; \ | |
| 60926 | int16x8_t __s1_181 = __p1_181; \ | |
| 60927 | int16x8_t __rev1_181; __rev1_181 = __builtin_shufflevector(__s1_181, __s1_181, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60928 | int16_t __ret_181; \ | |
| 60929 | __ret_181 = __noswap_vqrdmulhh_s16(__s0_181, __noswap_vgetq_lane_s16(__rev1_181, __p2_181)); \ | |
| 60930 | __ret_181; \ | |
| 57619 | 60931 | }) |
| 57620 | 60932 | #endif |
| 57621 | 60933 | |
| ... | ... | @@ -57816,128 +61128,128 @@ __ai int16_t vqrshlh_s16(int16_t __p0, int16_t __p1) { |
| 57816 | 61128 | #endif |
| 57817 | 61129 | |
| 57818 | 61130 | #ifdef __LITTLE_ENDIAN__ |
| 57819 | #define vqrshrn_high_n_u32(__p0_170, __p1_170, __p2_170) __extension__ ({ \ | |
| 57820 | uint16x4_t __s0_170 = __p0_170; \ | |
| 57821 | uint32x4_t __s1_170 = __p1_170; \ | |
| 57822 | uint16x8_t __ret_170; \ | |
| 57823 | __ret_170 = (uint16x8_t)(vcombine_u16((uint16x4_t)(__s0_170), (uint16x4_t)(vqrshrn_n_u32(__s1_170, __p2_170)))); \ | |
| 57824 | __ret_170; \ | |
| 61131 | #define vqrshrn_high_n_u32(__p0_182, __p1_182, __p2_182) __extension__ ({ \ | |
| 61132 | uint16x4_t __s0_182 = __p0_182; \ | |
| 61133 | uint32x4_t __s1_182 = __p1_182; \ | |
| 61134 | uint16x8_t __ret_182; \ | |
| 61135 | __ret_182 = (uint16x8_t)(vcombine_u16((uint16x4_t)(__s0_182), (uint16x4_t)(vqrshrn_n_u32(__s1_182, __p2_182)))); \ | |
| 61136 | __ret_182; \ | |
| 57825 | 61137 | }) |
| 57826 | 61138 | #else |
| 57827 | #define vqrshrn_high_n_u32(__p0_171, __p1_171, __p2_171) __extension__ ({ \ | |
| 57828 | uint16x4_t __s0_171 = __p0_171; \ | |
| 57829 | uint32x4_t __s1_171 = __p1_171; \ | |
| 57830 | uint16x4_t __rev0_171; __rev0_171 = __builtin_shufflevector(__s0_171, __s0_171, 3, 2, 1, 0); \ | |
| 57831 | uint32x4_t __rev1_171; __rev1_171 = __builtin_shufflevector(__s1_171, __s1_171, 3, 2, 1, 0); \ | |
| 57832 | uint16x8_t __ret_171; \ | |
| 57833 | __ret_171 = (uint16x8_t)(__noswap_vcombine_u16((uint16x4_t)(__rev0_171), (uint16x4_t)(__noswap_vqrshrn_n_u32(__rev1_171, __p2_171)))); \ | |
| 57834 | __ret_171 = __builtin_shufflevector(__ret_171, __ret_171, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 57835 | __ret_171; \ | |
| 61139 | #define vqrshrn_high_n_u32(__p0_183, __p1_183, __p2_183) __extension__ ({ \ | |
| 61140 | uint16x4_t __s0_183 = __p0_183; \ | |
| 61141 | uint32x4_t __s1_183 = __p1_183; \ | |
| 61142 | uint16x4_t __rev0_183; __rev0_183 = __builtin_shufflevector(__s0_183, __s0_183, 3, 2, 1, 0); \ | |
| 61143 | uint32x4_t __rev1_183; __rev1_183 = __builtin_shufflevector(__s1_183, __s1_183, 3, 2, 1, 0); \ | |
| 61144 | uint16x8_t __ret_183; \ | |
| 61145 | __ret_183 = (uint16x8_t)(__noswap_vcombine_u16((uint16x4_t)(__rev0_183), (uint16x4_t)(__noswap_vqrshrn_n_u32(__rev1_183, __p2_183)))); \ | |
| 61146 | __ret_183 = __builtin_shufflevector(__ret_183, __ret_183, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61147 | __ret_183; \ | |
| 57836 | 61148 | }) |
| 57837 | 61149 | #endif |
| 57838 | 61150 | |
| 57839 | 61151 | #ifdef __LITTLE_ENDIAN__ |
| 57840 | #define vqrshrn_high_n_u64(__p0_172, __p1_172, __p2_172) __extension__ ({ \ | |
| 57841 | uint32x2_t __s0_172 = __p0_172; \ | |
| 57842 | uint64x2_t __s1_172 = __p1_172; \ | |
| 57843 | uint32x4_t __ret_172; \ | |
| 57844 | __ret_172 = (uint32x4_t)(vcombine_u32((uint32x2_t)(__s0_172), (uint32x2_t)(vqrshrn_n_u64(__s1_172, __p2_172)))); \ | |
| 57845 | __ret_172; \ | |
| 61152 | #define vqrshrn_high_n_u64(__p0_184, __p1_184, __p2_184) __extension__ ({ \ | |
| 61153 | uint32x2_t __s0_184 = __p0_184; \ | |
| 61154 | uint64x2_t __s1_184 = __p1_184; \ | |
| 61155 | uint32x4_t __ret_184; \ | |
| 61156 | __ret_184 = (uint32x4_t)(vcombine_u32((uint32x2_t)(__s0_184), (uint32x2_t)(vqrshrn_n_u64(__s1_184, __p2_184)))); \ | |
| 61157 | __ret_184; \ | |
| 57846 | 61158 | }) |
| 57847 | 61159 | #else |
| 57848 | #define vqrshrn_high_n_u64(__p0_173, __p1_173, __p2_173) __extension__ ({ \ | |
| 57849 | uint32x2_t __s0_173 = __p0_173; \ | |
| 57850 | uint64x2_t __s1_173 = __p1_173; \ | |
| 57851 | uint32x2_t __rev0_173; __rev0_173 = __builtin_shufflevector(__s0_173, __s0_173, 1, 0); \ | |
| 57852 | uint64x2_t __rev1_173; __rev1_173 = __builtin_shufflevector(__s1_173, __s1_173, 1, 0); \ | |
| 57853 | uint32x4_t __ret_173; \ | |
| 57854 | __ret_173 = (uint32x4_t)(__noswap_vcombine_u32((uint32x2_t)(__rev0_173), (uint32x2_t)(__noswap_vqrshrn_n_u64(__rev1_173, __p2_173)))); \ | |
| 57855 | __ret_173 = __builtin_shufflevector(__ret_173, __ret_173, 3, 2, 1, 0); \ | |
| 57856 | __ret_173; \ | |
| 61160 | #define vqrshrn_high_n_u64(__p0_185, __p1_185, __p2_185) __extension__ ({ \ | |
| 61161 | uint32x2_t __s0_185 = __p0_185; \ | |
| 61162 | uint64x2_t __s1_185 = __p1_185; \ | |
| 61163 | uint32x2_t __rev0_185; __rev0_185 = __builtin_shufflevector(__s0_185, __s0_185, 1, 0); \ | |
| 61164 | uint64x2_t __rev1_185; __rev1_185 = __builtin_shufflevector(__s1_185, __s1_185, 1, 0); \ | |
| 61165 | uint32x4_t __ret_185; \ | |
| 61166 | __ret_185 = (uint32x4_t)(__noswap_vcombine_u32((uint32x2_t)(__rev0_185), (uint32x2_t)(__noswap_vqrshrn_n_u64(__rev1_185, __p2_185)))); \ | |
| 61167 | __ret_185 = __builtin_shufflevector(__ret_185, __ret_185, 3, 2, 1, 0); \ | |
| 61168 | __ret_185; \ | |
| 57857 | 61169 | }) |
| 57858 | 61170 | #endif |
| 57859 | 61171 | |
| 57860 | 61172 | #ifdef __LITTLE_ENDIAN__ |
| 57861 | #define vqrshrn_high_n_u16(__p0_174, __p1_174, __p2_174) __extension__ ({ \ | |
| 57862 | uint8x8_t __s0_174 = __p0_174; \ | |
| 57863 | uint16x8_t __s1_174 = __p1_174; \ | |
| 57864 | uint8x16_t __ret_174; \ | |
| 57865 | __ret_174 = (uint8x16_t)(vcombine_u8((uint8x8_t)(__s0_174), (uint8x8_t)(vqrshrn_n_u16(__s1_174, __p2_174)))); \ | |
| 57866 | __ret_174; \ | |
| 61173 | #define vqrshrn_high_n_u16(__p0_186, __p1_186, __p2_186) __extension__ ({ \ | |
| 61174 | uint8x8_t __s0_186 = __p0_186; \ | |
| 61175 | uint16x8_t __s1_186 = __p1_186; \ | |
| 61176 | uint8x16_t __ret_186; \ | |
| 61177 | __ret_186 = (uint8x16_t)(vcombine_u8((uint8x8_t)(__s0_186), (uint8x8_t)(vqrshrn_n_u16(__s1_186, __p2_186)))); \ | |
| 61178 | __ret_186; \ | |
| 57867 | 61179 | }) |
| 57868 | 61180 | #else |
| 57869 | #define vqrshrn_high_n_u16(__p0_175, __p1_175, __p2_175) __extension__ ({ \ | |
| 57870 | uint8x8_t __s0_175 = __p0_175; \ | |
| 57871 | uint16x8_t __s1_175 = __p1_175; \ | |
| 57872 | uint8x8_t __rev0_175; __rev0_175 = __builtin_shufflevector(__s0_175, __s0_175, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 57873 | uint16x8_t __rev1_175; __rev1_175 = __builtin_shufflevector(__s1_175, __s1_175, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 57874 | uint8x16_t __ret_175; \ | |
| 57875 | __ret_175 = (uint8x16_t)(__noswap_vcombine_u8((uint8x8_t)(__rev0_175), (uint8x8_t)(__noswap_vqrshrn_n_u16(__rev1_175, __p2_175)))); \ | |
| 57876 | __ret_175 = __builtin_shufflevector(__ret_175, __ret_175, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 57877 | __ret_175; \ | |
| 61181 | #define vqrshrn_high_n_u16(__p0_187, __p1_187, __p2_187) __extension__ ({ \ | |
| 61182 | uint8x8_t __s0_187 = __p0_187; \ | |
| 61183 | uint16x8_t __s1_187 = __p1_187; \ | |
| 61184 | uint8x8_t __rev0_187; __rev0_187 = __builtin_shufflevector(__s0_187, __s0_187, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61185 | uint16x8_t __rev1_187; __rev1_187 = __builtin_shufflevector(__s1_187, __s1_187, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61186 | uint8x16_t __ret_187; \ | |
| 61187 | __ret_187 = (uint8x16_t)(__noswap_vcombine_u8((uint8x8_t)(__rev0_187), (uint8x8_t)(__noswap_vqrshrn_n_u16(__rev1_187, __p2_187)))); \ | |
| 61188 | __ret_187 = __builtin_shufflevector(__ret_187, __ret_187, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61189 | __ret_187; \ | |
| 57878 | 61190 | }) |
| 57879 | 61191 | #endif |
| 57880 | 61192 | |
| 57881 | 61193 | #ifdef __LITTLE_ENDIAN__ |
| 57882 | #define vqrshrn_high_n_s32(__p0_176, __p1_176, __p2_176) __extension__ ({ \ | |
| 57883 | int16x4_t __s0_176 = __p0_176; \ | |
| 57884 | int32x4_t __s1_176 = __p1_176; \ | |
| 57885 | int16x8_t __ret_176; \ | |
| 57886 | __ret_176 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_176), (int16x4_t)(vqrshrn_n_s32(__s1_176, __p2_176)))); \ | |
| 57887 | __ret_176; \ | |
| 61194 | #define vqrshrn_high_n_s32(__p0_188, __p1_188, __p2_188) __extension__ ({ \ | |
| 61195 | int16x4_t __s0_188 = __p0_188; \ | |
| 61196 | int32x4_t __s1_188 = __p1_188; \ | |
| 61197 | int16x8_t __ret_188; \ | |
| 61198 | __ret_188 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_188), (int16x4_t)(vqrshrn_n_s32(__s1_188, __p2_188)))); \ | |
| 61199 | __ret_188; \ | |
| 57888 | 61200 | }) |
| 57889 | 61201 | #else |
| 57890 | #define vqrshrn_high_n_s32(__p0_177, __p1_177, __p2_177) __extension__ ({ \ | |
| 57891 | int16x4_t __s0_177 = __p0_177; \ | |
| 57892 | int32x4_t __s1_177 = __p1_177; \ | |
| 57893 | int16x4_t __rev0_177; __rev0_177 = __builtin_shufflevector(__s0_177, __s0_177, 3, 2, 1, 0); \ | |
| 57894 | int32x4_t __rev1_177; __rev1_177 = __builtin_shufflevector(__s1_177, __s1_177, 3, 2, 1, 0); \ | |
| 57895 | int16x8_t __ret_177; \ | |
| 57896 | __ret_177 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_177), (int16x4_t)(__noswap_vqrshrn_n_s32(__rev1_177, __p2_177)))); \ | |
| 57897 | __ret_177 = __builtin_shufflevector(__ret_177, __ret_177, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 57898 | __ret_177; \ | |
| 61202 | #define vqrshrn_high_n_s32(__p0_189, __p1_189, __p2_189) __extension__ ({ \ | |
| 61203 | int16x4_t __s0_189 = __p0_189; \ | |
| 61204 | int32x4_t __s1_189 = __p1_189; \ | |
| 61205 | int16x4_t __rev0_189; __rev0_189 = __builtin_shufflevector(__s0_189, __s0_189, 3, 2, 1, 0); \ | |
| 61206 | int32x4_t __rev1_189; __rev1_189 = __builtin_shufflevector(__s1_189, __s1_189, 3, 2, 1, 0); \ | |
| 61207 | int16x8_t __ret_189; \ | |
| 61208 | __ret_189 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_189), (int16x4_t)(__noswap_vqrshrn_n_s32(__rev1_189, __p2_189)))); \ | |
| 61209 | __ret_189 = __builtin_shufflevector(__ret_189, __ret_189, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61210 | __ret_189; \ | |
| 57899 | 61211 | }) |
| 57900 | 61212 | #endif |
| 57901 | 61213 | |
| 57902 | 61214 | #ifdef __LITTLE_ENDIAN__ |
| 57903 | #define vqrshrn_high_n_s64(__p0_178, __p1_178, __p2_178) __extension__ ({ \ | |
| 57904 | int32x2_t __s0_178 = __p0_178; \ | |
| 57905 | int64x2_t __s1_178 = __p1_178; \ | |
| 57906 | int32x4_t __ret_178; \ | |
| 57907 | __ret_178 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_178), (int32x2_t)(vqrshrn_n_s64(__s1_178, __p2_178)))); \ | |
| 57908 | __ret_178; \ | |
| 61215 | #define vqrshrn_high_n_s64(__p0_190, __p1_190, __p2_190) __extension__ ({ \ | |
| 61216 | int32x2_t __s0_190 = __p0_190; \ | |
| 61217 | int64x2_t __s1_190 = __p1_190; \ | |
| 61218 | int32x4_t __ret_190; \ | |
| 61219 | __ret_190 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_190), (int32x2_t)(vqrshrn_n_s64(__s1_190, __p2_190)))); \ | |
| 61220 | __ret_190; \ | |
| 57909 | 61221 | }) |
| 57910 | 61222 | #else |
| 57911 | #define vqrshrn_high_n_s64(__p0_179, __p1_179, __p2_179) __extension__ ({ \ | |
| 57912 | int32x2_t __s0_179 = __p0_179; \ | |
| 57913 | int64x2_t __s1_179 = __p1_179; \ | |
| 57914 | int32x2_t __rev0_179; __rev0_179 = __builtin_shufflevector(__s0_179, __s0_179, 1, 0); \ | |
| 57915 | int64x2_t __rev1_179; __rev1_179 = __builtin_shufflevector(__s1_179, __s1_179, 1, 0); \ | |
| 57916 | int32x4_t __ret_179; \ | |
| 57917 | __ret_179 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_179), (int32x2_t)(__noswap_vqrshrn_n_s64(__rev1_179, __p2_179)))); \ | |
| 57918 | __ret_179 = __builtin_shufflevector(__ret_179, __ret_179, 3, 2, 1, 0); \ | |
| 57919 | __ret_179; \ | |
| 61223 | #define vqrshrn_high_n_s64(__p0_191, __p1_191, __p2_191) __extension__ ({ \ | |
| 61224 | int32x2_t __s0_191 = __p0_191; \ | |
| 61225 | int64x2_t __s1_191 = __p1_191; \ | |
| 61226 | int32x2_t __rev0_191; __rev0_191 = __builtin_shufflevector(__s0_191, __s0_191, 1, 0); \ | |
| 61227 | int64x2_t __rev1_191; __rev1_191 = __builtin_shufflevector(__s1_191, __s1_191, 1, 0); \ | |
| 61228 | int32x4_t __ret_191; \ | |
| 61229 | __ret_191 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_191), (int32x2_t)(__noswap_vqrshrn_n_s64(__rev1_191, __p2_191)))); \ | |
| 61230 | __ret_191 = __builtin_shufflevector(__ret_191, __ret_191, 3, 2, 1, 0); \ | |
| 61231 | __ret_191; \ | |
| 57920 | 61232 | }) |
| 57921 | 61233 | #endif |
| 57922 | 61234 | |
| 57923 | 61235 | #ifdef __LITTLE_ENDIAN__ |
| 57924 | #define vqrshrn_high_n_s16(__p0_180, __p1_180, __p2_180) __extension__ ({ \ | |
| 57925 | int8x8_t __s0_180 = __p0_180; \ | |
| 57926 | int16x8_t __s1_180 = __p1_180; \ | |
| 57927 | int8x16_t __ret_180; \ | |
| 57928 | __ret_180 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_180), (int8x8_t)(vqrshrn_n_s16(__s1_180, __p2_180)))); \ | |
| 57929 | __ret_180; \ | |
| 61236 | #define vqrshrn_high_n_s16(__p0_192, __p1_192, __p2_192) __extension__ ({ \ | |
| 61237 | int8x8_t __s0_192 = __p0_192; \ | |
| 61238 | int16x8_t __s1_192 = __p1_192; \ | |
| 61239 | int8x16_t __ret_192; \ | |
| 61240 | __ret_192 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_192), (int8x8_t)(vqrshrn_n_s16(__s1_192, __p2_192)))); \ | |
| 61241 | __ret_192; \ | |
| 57930 | 61242 | }) |
| 57931 | 61243 | #else |
| 57932 | #define vqrshrn_high_n_s16(__p0_181, __p1_181, __p2_181) __extension__ ({ \ | |
| 57933 | int8x8_t __s0_181 = __p0_181; \ | |
| 57934 | int16x8_t __s1_181 = __p1_181; \ | |
| 57935 | int8x8_t __rev0_181; __rev0_181 = __builtin_shufflevector(__s0_181, __s0_181, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 57936 | int16x8_t __rev1_181; __rev1_181 = __builtin_shufflevector(__s1_181, __s1_181, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 57937 | int8x16_t __ret_181; \ | |
| 57938 | __ret_181 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_181), (int8x8_t)(__noswap_vqrshrn_n_s16(__rev1_181, __p2_181)))); \ | |
| 57939 | __ret_181 = __builtin_shufflevector(__ret_181, __ret_181, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 57940 | __ret_181; \ | |
| 61244 | #define vqrshrn_high_n_s16(__p0_193, __p1_193, __p2_193) __extension__ ({ \ | |
| 61245 | int8x8_t __s0_193 = __p0_193; \ | |
| 61246 | int16x8_t __s1_193 = __p1_193; \ | |
| 61247 | int8x8_t __rev0_193; __rev0_193 = __builtin_shufflevector(__s0_193, __s0_193, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61248 | int16x8_t __rev1_193; __rev1_193 = __builtin_shufflevector(__s1_193, __s1_193, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61249 | int8x16_t __ret_193; \ | |
| 61250 | __ret_193 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_193), (int8x8_t)(__noswap_vqrshrn_n_s16(__rev1_193, __p2_193)))); \ | |
| 61251 | __ret_193 = __builtin_shufflevector(__ret_193, __ret_193, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61252 | __ret_193; \ | |
| 57941 | 61253 | }) |
| 57942 | 61254 | #endif |
| 57943 | 61255 | |
| ... | ... | @@ -58038,65 +61350,65 @@ __ai int16_t vqrshlh_s16(int16_t __p0, int16_t __p1) { |
| 58038 | 61350 | #endif |
| 58039 | 61351 | |
| 58040 | 61352 | #ifdef __LITTLE_ENDIAN__ |
| 58041 | #define vqrshrun_high_n_s32(__p0_182, __p1_182, __p2_182) __extension__ ({ \ | |
| 58042 | int16x4_t __s0_182 = __p0_182; \ | |
| 58043 | int32x4_t __s1_182 = __p1_182; \ | |
| 58044 | int16x8_t __ret_182; \ | |
| 58045 | __ret_182 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_182), (int16x4_t)(vqrshrun_n_s32(__s1_182, __p2_182)))); \ | |
| 58046 | __ret_182; \ | |
| 61353 | #define vqrshrun_high_n_s32(__p0_194, __p1_194, __p2_194) __extension__ ({ \ | |
| 61354 | int16x4_t __s0_194 = __p0_194; \ | |
| 61355 | int32x4_t __s1_194 = __p1_194; \ | |
| 61356 | int16x8_t __ret_194; \ | |
| 61357 | __ret_194 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_194), (int16x4_t)(vqrshrun_n_s32(__s1_194, __p2_194)))); \ | |
| 61358 | __ret_194; \ | |
| 58047 | 61359 | }) |
| 58048 | 61360 | #else |
| 58049 | #define vqrshrun_high_n_s32(__p0_183, __p1_183, __p2_183) __extension__ ({ \ | |
| 58050 | int16x4_t __s0_183 = __p0_183; \ | |
| 58051 | int32x4_t __s1_183 = __p1_183; \ | |
| 58052 | int16x4_t __rev0_183; __rev0_183 = __builtin_shufflevector(__s0_183, __s0_183, 3, 2, 1, 0); \ | |
| 58053 | int32x4_t __rev1_183; __rev1_183 = __builtin_shufflevector(__s1_183, __s1_183, 3, 2, 1, 0); \ | |
| 58054 | int16x8_t __ret_183; \ | |
| 58055 | __ret_183 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_183), (int16x4_t)(__noswap_vqrshrun_n_s32(__rev1_183, __p2_183)))); \ | |
| 58056 | __ret_183 = __builtin_shufflevector(__ret_183, __ret_183, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58057 | __ret_183; \ | |
| 61361 | #define vqrshrun_high_n_s32(__p0_195, __p1_195, __p2_195) __extension__ ({ \ | |
| 61362 | int16x4_t __s0_195 = __p0_195; \ | |
| 61363 | int32x4_t __s1_195 = __p1_195; \ | |
| 61364 | int16x4_t __rev0_195; __rev0_195 = __builtin_shufflevector(__s0_195, __s0_195, 3, 2, 1, 0); \ | |
| 61365 | int32x4_t __rev1_195; __rev1_195 = __builtin_shufflevector(__s1_195, __s1_195, 3, 2, 1, 0); \ | |
| 61366 | int16x8_t __ret_195; \ | |
| 61367 | __ret_195 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_195), (int16x4_t)(__noswap_vqrshrun_n_s32(__rev1_195, __p2_195)))); \ | |
| 61368 | __ret_195 = __builtin_shufflevector(__ret_195, __ret_195, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61369 | __ret_195; \ | |
| 58058 | 61370 | }) |
| 58059 | 61371 | #endif |
| 58060 | 61372 | |
| 58061 | 61373 | #ifdef __LITTLE_ENDIAN__ |
| 58062 | #define vqrshrun_high_n_s64(__p0_184, __p1_184, __p2_184) __extension__ ({ \ | |
| 58063 | int32x2_t __s0_184 = __p0_184; \ | |
| 58064 | int64x2_t __s1_184 = __p1_184; \ | |
| 58065 | int32x4_t __ret_184; \ | |
| 58066 | __ret_184 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_184), (int32x2_t)(vqrshrun_n_s64(__s1_184, __p2_184)))); \ | |
| 58067 | __ret_184; \ | |
| 61374 | #define vqrshrun_high_n_s64(__p0_196, __p1_196, __p2_196) __extension__ ({ \ | |
| 61375 | int32x2_t __s0_196 = __p0_196; \ | |
| 61376 | int64x2_t __s1_196 = __p1_196; \ | |
| 61377 | int32x4_t __ret_196; \ | |
| 61378 | __ret_196 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_196), (int32x2_t)(vqrshrun_n_s64(__s1_196, __p2_196)))); \ | |
| 61379 | __ret_196; \ | |
| 58068 | 61380 | }) |
| 58069 | 61381 | #else |
| 58070 | #define vqrshrun_high_n_s64(__p0_185, __p1_185, __p2_185) __extension__ ({ \ | |
| 58071 | int32x2_t __s0_185 = __p0_185; \ | |
| 58072 | int64x2_t __s1_185 = __p1_185; \ | |
| 58073 | int32x2_t __rev0_185; __rev0_185 = __builtin_shufflevector(__s0_185, __s0_185, 1, 0); \ | |
| 58074 | int64x2_t __rev1_185; __rev1_185 = __builtin_shufflevector(__s1_185, __s1_185, 1, 0); \ | |
| 58075 | int32x4_t __ret_185; \ | |
| 58076 | __ret_185 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_185), (int32x2_t)(__noswap_vqrshrun_n_s64(__rev1_185, __p2_185)))); \ | |
| 58077 | __ret_185 = __builtin_shufflevector(__ret_185, __ret_185, 3, 2, 1, 0); \ | |
| 58078 | __ret_185; \ | |
| 61382 | #define vqrshrun_high_n_s64(__p0_197, __p1_197, __p2_197) __extension__ ({ \ | |
| 61383 | int32x2_t __s0_197 = __p0_197; \ | |
| 61384 | int64x2_t __s1_197 = __p1_197; \ | |
| 61385 | int32x2_t __rev0_197; __rev0_197 = __builtin_shufflevector(__s0_197, __s0_197, 1, 0); \ | |
| 61386 | int64x2_t __rev1_197; __rev1_197 = __builtin_shufflevector(__s1_197, __s1_197, 1, 0); \ | |
| 61387 | int32x4_t __ret_197; \ | |
| 61388 | __ret_197 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_197), (int32x2_t)(__noswap_vqrshrun_n_s64(__rev1_197, __p2_197)))); \ | |
| 61389 | __ret_197 = __builtin_shufflevector(__ret_197, __ret_197, 3, 2, 1, 0); \ | |
| 61390 | __ret_197; \ | |
| 58079 | 61391 | }) |
| 58080 | 61392 | #endif |
| 58081 | 61393 | |
| 58082 | 61394 | #ifdef __LITTLE_ENDIAN__ |
| 58083 | #define vqrshrun_high_n_s16(__p0_186, __p1_186, __p2_186) __extension__ ({ \ | |
| 58084 | int8x8_t __s0_186 = __p0_186; \ | |
| 58085 | int16x8_t __s1_186 = __p1_186; \ | |
| 58086 | int8x16_t __ret_186; \ | |
| 58087 | __ret_186 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_186), (int8x8_t)(vqrshrun_n_s16(__s1_186, __p2_186)))); \ | |
| 58088 | __ret_186; \ | |
| 61395 | #define vqrshrun_high_n_s16(__p0_198, __p1_198, __p2_198) __extension__ ({ \ | |
| 61396 | int8x8_t __s0_198 = __p0_198; \ | |
| 61397 | int16x8_t __s1_198 = __p1_198; \ | |
| 61398 | int8x16_t __ret_198; \ | |
| 61399 | __ret_198 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_198), (int8x8_t)(vqrshrun_n_s16(__s1_198, __p2_198)))); \ | |
| 61400 | __ret_198; \ | |
| 58089 | 61401 | }) |
| 58090 | 61402 | #else |
| 58091 | #define vqrshrun_high_n_s16(__p0_187, __p1_187, __p2_187) __extension__ ({ \ | |
| 58092 | int8x8_t __s0_187 = __p0_187; \ | |
| 58093 | int16x8_t __s1_187 = __p1_187; \ | |
| 58094 | int8x8_t __rev0_187; __rev0_187 = __builtin_shufflevector(__s0_187, __s0_187, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58095 | int16x8_t __rev1_187; __rev1_187 = __builtin_shufflevector(__s1_187, __s1_187, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58096 | int8x16_t __ret_187; \ | |
| 58097 | __ret_187 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_187), (int8x8_t)(__noswap_vqrshrun_n_s16(__rev1_187, __p2_187)))); \ | |
| 58098 | __ret_187 = __builtin_shufflevector(__ret_187, __ret_187, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58099 | __ret_187; \ | |
| 61403 | #define vqrshrun_high_n_s16(__p0_199, __p1_199, __p2_199) __extension__ ({ \ | |
| 61404 | int8x8_t __s0_199 = __p0_199; \ | |
| 61405 | int16x8_t __s1_199 = __p1_199; \ | |
| 61406 | int8x8_t __rev0_199; __rev0_199 = __builtin_shufflevector(__s0_199, __s0_199, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61407 | int16x8_t __rev1_199; __rev1_199 = __builtin_shufflevector(__s1_199, __s1_199, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61408 | int8x16_t __ret_199; \ | |
| 61409 | __ret_199 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_199), (int8x8_t)(__noswap_vqrshrun_n_s16(__rev1_199, __p2_199)))); \ | |
| 61410 | __ret_199 = __builtin_shufflevector(__ret_199, __ret_199, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61411 | __ret_199; \ | |
| 58100 | 61412 | }) |
| 58101 | 61413 | #endif |
| 58102 | 61414 | |
| ... | ... | @@ -58453,128 +61765,128 @@ __ai int16_t vqshlh_s16(int16_t __p0, int16_t __p1) { |
| 58453 | 61765 | #endif |
| 58454 | 61766 | |
| 58455 | 61767 | #ifdef __LITTLE_ENDIAN__ |
| 58456 | #define vqshrn_high_n_u32(__p0_188, __p1_188, __p2_188) __extension__ ({ \ | |
| 58457 | uint16x4_t __s0_188 = __p0_188; \ | |
| 58458 | uint32x4_t __s1_188 = __p1_188; \ | |
| 58459 | uint16x8_t __ret_188; \ | |
| 58460 | __ret_188 = (uint16x8_t)(vcombine_u16((uint16x4_t)(__s0_188), (uint16x4_t)(vqshrn_n_u32(__s1_188, __p2_188)))); \ | |
| 58461 | __ret_188; \ | |
| 61768 | #define vqshrn_high_n_u32(__p0_200, __p1_200, __p2_200) __extension__ ({ \ | |
| 61769 | uint16x4_t __s0_200 = __p0_200; \ | |
| 61770 | uint32x4_t __s1_200 = __p1_200; \ | |
| 61771 | uint16x8_t __ret_200; \ | |
| 61772 | __ret_200 = (uint16x8_t)(vcombine_u16((uint16x4_t)(__s0_200), (uint16x4_t)(vqshrn_n_u32(__s1_200, __p2_200)))); \ | |
| 61773 | __ret_200; \ | |
| 58462 | 61774 | }) |
| 58463 | 61775 | #else |
| 58464 | #define vqshrn_high_n_u32(__p0_189, __p1_189, __p2_189) __extension__ ({ \ | |
| 58465 | uint16x4_t __s0_189 = __p0_189; \ | |
| 58466 | uint32x4_t __s1_189 = __p1_189; \ | |
| 58467 | uint16x4_t __rev0_189; __rev0_189 = __builtin_shufflevector(__s0_189, __s0_189, 3, 2, 1, 0); \ | |
| 58468 | uint32x4_t __rev1_189; __rev1_189 = __builtin_shufflevector(__s1_189, __s1_189, 3, 2, 1, 0); \ | |
| 58469 | uint16x8_t __ret_189; \ | |
| 58470 | __ret_189 = (uint16x8_t)(__noswap_vcombine_u16((uint16x4_t)(__rev0_189), (uint16x4_t)(__noswap_vqshrn_n_u32(__rev1_189, __p2_189)))); \ | |
| 58471 | __ret_189 = __builtin_shufflevector(__ret_189, __ret_189, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58472 | __ret_189; \ | |
| 61776 | #define vqshrn_high_n_u32(__p0_201, __p1_201, __p2_201) __extension__ ({ \ | |
| 61777 | uint16x4_t __s0_201 = __p0_201; \ | |
| 61778 | uint32x4_t __s1_201 = __p1_201; \ | |
| 61779 | uint16x4_t __rev0_201; __rev0_201 = __builtin_shufflevector(__s0_201, __s0_201, 3, 2, 1, 0); \ | |
| 61780 | uint32x4_t __rev1_201; __rev1_201 = __builtin_shufflevector(__s1_201, __s1_201, 3, 2, 1, 0); \ | |
| 61781 | uint16x8_t __ret_201; \ | |
| 61782 | __ret_201 = (uint16x8_t)(__noswap_vcombine_u16((uint16x4_t)(__rev0_201), (uint16x4_t)(__noswap_vqshrn_n_u32(__rev1_201, __p2_201)))); \ | |
| 61783 | __ret_201 = __builtin_shufflevector(__ret_201, __ret_201, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61784 | __ret_201; \ | |
| 58473 | 61785 | }) |
| 58474 | 61786 | #endif |
| 58475 | 61787 | |
| 58476 | 61788 | #ifdef __LITTLE_ENDIAN__ |
| 58477 | #define vqshrn_high_n_u64(__p0_190, __p1_190, __p2_190) __extension__ ({ \ | |
| 58478 | uint32x2_t __s0_190 = __p0_190; \ | |
| 58479 | uint64x2_t __s1_190 = __p1_190; \ | |
| 58480 | uint32x4_t __ret_190; \ | |
| 58481 | __ret_190 = (uint32x4_t)(vcombine_u32((uint32x2_t)(__s0_190), (uint32x2_t)(vqshrn_n_u64(__s1_190, __p2_190)))); \ | |
| 58482 | __ret_190; \ | |
| 61789 | #define vqshrn_high_n_u64(__p0_202, __p1_202, __p2_202) __extension__ ({ \ | |
| 61790 | uint32x2_t __s0_202 = __p0_202; \ | |
| 61791 | uint64x2_t __s1_202 = __p1_202; \ | |
| 61792 | uint32x4_t __ret_202; \ | |
| 61793 | __ret_202 = (uint32x4_t)(vcombine_u32((uint32x2_t)(__s0_202), (uint32x2_t)(vqshrn_n_u64(__s1_202, __p2_202)))); \ | |
| 61794 | __ret_202; \ | |
| 58483 | 61795 | }) |
| 58484 | 61796 | #else |
| 58485 | #define vqshrn_high_n_u64(__p0_191, __p1_191, __p2_191) __extension__ ({ \ | |
| 58486 | uint32x2_t __s0_191 = __p0_191; \ | |
| 58487 | uint64x2_t __s1_191 = __p1_191; \ | |
| 58488 | uint32x2_t __rev0_191; __rev0_191 = __builtin_shufflevector(__s0_191, __s0_191, 1, 0); \ | |
| 58489 | uint64x2_t __rev1_191; __rev1_191 = __builtin_shufflevector(__s1_191, __s1_191, 1, 0); \ | |
| 58490 | uint32x4_t __ret_191; \ | |
| 58491 | __ret_191 = (uint32x4_t)(__noswap_vcombine_u32((uint32x2_t)(__rev0_191), (uint32x2_t)(__noswap_vqshrn_n_u64(__rev1_191, __p2_191)))); \ | |
| 58492 | __ret_191 = __builtin_shufflevector(__ret_191, __ret_191, 3, 2, 1, 0); \ | |
| 58493 | __ret_191; \ | |
| 61797 | #define vqshrn_high_n_u64(__p0_203, __p1_203, __p2_203) __extension__ ({ \ | |
| 61798 | uint32x2_t __s0_203 = __p0_203; \ | |
| 61799 | uint64x2_t __s1_203 = __p1_203; \ | |
| 61800 | uint32x2_t __rev0_203; __rev0_203 = __builtin_shufflevector(__s0_203, __s0_203, 1, 0); \ | |
| 61801 | uint64x2_t __rev1_203; __rev1_203 = __builtin_shufflevector(__s1_203, __s1_203, 1, 0); \ | |
| 61802 | uint32x4_t __ret_203; \ | |
| 61803 | __ret_203 = (uint32x4_t)(__noswap_vcombine_u32((uint32x2_t)(__rev0_203), (uint32x2_t)(__noswap_vqshrn_n_u64(__rev1_203, __p2_203)))); \ | |
| 61804 | __ret_203 = __builtin_shufflevector(__ret_203, __ret_203, 3, 2, 1, 0); \ | |
| 61805 | __ret_203; \ | |
| 58494 | 61806 | }) |
| 58495 | 61807 | #endif |
| 58496 | 61808 | |
| 58497 | 61809 | #ifdef __LITTLE_ENDIAN__ |
| 58498 | #define vqshrn_high_n_u16(__p0_192, __p1_192, __p2_192) __extension__ ({ \ | |
| 58499 | uint8x8_t __s0_192 = __p0_192; \ | |
| 58500 | uint16x8_t __s1_192 = __p1_192; \ | |
| 58501 | uint8x16_t __ret_192; \ | |
| 58502 | __ret_192 = (uint8x16_t)(vcombine_u8((uint8x8_t)(__s0_192), (uint8x8_t)(vqshrn_n_u16(__s1_192, __p2_192)))); \ | |
| 58503 | __ret_192; \ | |
| 61810 | #define vqshrn_high_n_u16(__p0_204, __p1_204, __p2_204) __extension__ ({ \ | |
| 61811 | uint8x8_t __s0_204 = __p0_204; \ | |
| 61812 | uint16x8_t __s1_204 = __p1_204; \ | |
| 61813 | uint8x16_t __ret_204; \ | |
| 61814 | __ret_204 = (uint8x16_t)(vcombine_u8((uint8x8_t)(__s0_204), (uint8x8_t)(vqshrn_n_u16(__s1_204, __p2_204)))); \ | |
| 61815 | __ret_204; \ | |
| 58504 | 61816 | }) |
| 58505 | 61817 | #else |
| 58506 | #define vqshrn_high_n_u16(__p0_193, __p1_193, __p2_193) __extension__ ({ \ | |
| 58507 | uint8x8_t __s0_193 = __p0_193; \ | |
| 58508 | uint16x8_t __s1_193 = __p1_193; \ | |
| 58509 | uint8x8_t __rev0_193; __rev0_193 = __builtin_shufflevector(__s0_193, __s0_193, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58510 | uint16x8_t __rev1_193; __rev1_193 = __builtin_shufflevector(__s1_193, __s1_193, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58511 | uint8x16_t __ret_193; \ | |
| 58512 | __ret_193 = (uint8x16_t)(__noswap_vcombine_u8((uint8x8_t)(__rev0_193), (uint8x8_t)(__noswap_vqshrn_n_u16(__rev1_193, __p2_193)))); \ | |
| 58513 | __ret_193 = __builtin_shufflevector(__ret_193, __ret_193, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58514 | __ret_193; \ | |
| 61818 | #define vqshrn_high_n_u16(__p0_205, __p1_205, __p2_205) __extension__ ({ \ | |
| 61819 | uint8x8_t __s0_205 = __p0_205; \ | |
| 61820 | uint16x8_t __s1_205 = __p1_205; \ | |
| 61821 | uint8x8_t __rev0_205; __rev0_205 = __builtin_shufflevector(__s0_205, __s0_205, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61822 | uint16x8_t __rev1_205; __rev1_205 = __builtin_shufflevector(__s1_205, __s1_205, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61823 | uint8x16_t __ret_205; \ | |
| 61824 | __ret_205 = (uint8x16_t)(__noswap_vcombine_u8((uint8x8_t)(__rev0_205), (uint8x8_t)(__noswap_vqshrn_n_u16(__rev1_205, __p2_205)))); \ | |
| 61825 | __ret_205 = __builtin_shufflevector(__ret_205, __ret_205, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61826 | __ret_205; \ | |
| 58515 | 61827 | }) |
| 58516 | 61828 | #endif |
| 58517 | 61829 | |
| 58518 | 61830 | #ifdef __LITTLE_ENDIAN__ |
| 58519 | #define vqshrn_high_n_s32(__p0_194, __p1_194, __p2_194) __extension__ ({ \ | |
| 58520 | int16x4_t __s0_194 = __p0_194; \ | |
| 58521 | int32x4_t __s1_194 = __p1_194; \ | |
| 58522 | int16x8_t __ret_194; \ | |
| 58523 | __ret_194 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_194), (int16x4_t)(vqshrn_n_s32(__s1_194, __p2_194)))); \ | |
| 58524 | __ret_194; \ | |
| 61831 | #define vqshrn_high_n_s32(__p0_206, __p1_206, __p2_206) __extension__ ({ \ | |
| 61832 | int16x4_t __s0_206 = __p0_206; \ | |
| 61833 | int32x4_t __s1_206 = __p1_206; \ | |
| 61834 | int16x8_t __ret_206; \ | |
| 61835 | __ret_206 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_206), (int16x4_t)(vqshrn_n_s32(__s1_206, __p2_206)))); \ | |
| 61836 | __ret_206; \ | |
| 58525 | 61837 | }) |
| 58526 | 61838 | #else |
| 58527 | #define vqshrn_high_n_s32(__p0_195, __p1_195, __p2_195) __extension__ ({ \ | |
| 58528 | int16x4_t __s0_195 = __p0_195; \ | |
| 58529 | int32x4_t __s1_195 = __p1_195; \ | |
| 58530 | int16x4_t __rev0_195; __rev0_195 = __builtin_shufflevector(__s0_195, __s0_195, 3, 2, 1, 0); \ | |
| 58531 | int32x4_t __rev1_195; __rev1_195 = __builtin_shufflevector(__s1_195, __s1_195, 3, 2, 1, 0); \ | |
| 58532 | int16x8_t __ret_195; \ | |
| 58533 | __ret_195 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_195), (int16x4_t)(__noswap_vqshrn_n_s32(__rev1_195, __p2_195)))); \ | |
| 58534 | __ret_195 = __builtin_shufflevector(__ret_195, __ret_195, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58535 | __ret_195; \ | |
| 61839 | #define vqshrn_high_n_s32(__p0_207, __p1_207, __p2_207) __extension__ ({ \ | |
| 61840 | int16x4_t __s0_207 = __p0_207; \ | |
| 61841 | int32x4_t __s1_207 = __p1_207; \ | |
| 61842 | int16x4_t __rev0_207; __rev0_207 = __builtin_shufflevector(__s0_207, __s0_207, 3, 2, 1, 0); \ | |
| 61843 | int32x4_t __rev1_207; __rev1_207 = __builtin_shufflevector(__s1_207, __s1_207, 3, 2, 1, 0); \ | |
| 61844 | int16x8_t __ret_207; \ | |
| 61845 | __ret_207 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_207), (int16x4_t)(__noswap_vqshrn_n_s32(__rev1_207, __p2_207)))); \ | |
| 61846 | __ret_207 = __builtin_shufflevector(__ret_207, __ret_207, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61847 | __ret_207; \ | |
| 58536 | 61848 | }) |
| 58537 | 61849 | #endif |
| 58538 | 61850 | |
| 58539 | 61851 | #ifdef __LITTLE_ENDIAN__ |
| 58540 | #define vqshrn_high_n_s64(__p0_196, __p1_196, __p2_196) __extension__ ({ \ | |
| 58541 | int32x2_t __s0_196 = __p0_196; \ | |
| 58542 | int64x2_t __s1_196 = __p1_196; \ | |
| 58543 | int32x4_t __ret_196; \ | |
| 58544 | __ret_196 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_196), (int32x2_t)(vqshrn_n_s64(__s1_196, __p2_196)))); \ | |
| 58545 | __ret_196; \ | |
| 61852 | #define vqshrn_high_n_s64(__p0_208, __p1_208, __p2_208) __extension__ ({ \ | |
| 61853 | int32x2_t __s0_208 = __p0_208; \ | |
| 61854 | int64x2_t __s1_208 = __p1_208; \ | |
| 61855 | int32x4_t __ret_208; \ | |
| 61856 | __ret_208 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_208), (int32x2_t)(vqshrn_n_s64(__s1_208, __p2_208)))); \ | |
| 61857 | __ret_208; \ | |
| 58546 | 61858 | }) |
| 58547 | 61859 | #else |
| 58548 | #define vqshrn_high_n_s64(__p0_197, __p1_197, __p2_197) __extension__ ({ \ | |
| 58549 | int32x2_t __s0_197 = __p0_197; \ | |
| 58550 | int64x2_t __s1_197 = __p1_197; \ | |
| 58551 | int32x2_t __rev0_197; __rev0_197 = __builtin_shufflevector(__s0_197, __s0_197, 1, 0); \ | |
| 58552 | int64x2_t __rev1_197; __rev1_197 = __builtin_shufflevector(__s1_197, __s1_197, 1, 0); \ | |
| 58553 | int32x4_t __ret_197; \ | |
| 58554 | __ret_197 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_197), (int32x2_t)(__noswap_vqshrn_n_s64(__rev1_197, __p2_197)))); \ | |
| 58555 | __ret_197 = __builtin_shufflevector(__ret_197, __ret_197, 3, 2, 1, 0); \ | |
| 58556 | __ret_197; \ | |
| 61860 | #define vqshrn_high_n_s64(__p0_209, __p1_209, __p2_209) __extension__ ({ \ | |
| 61861 | int32x2_t __s0_209 = __p0_209; \ | |
| 61862 | int64x2_t __s1_209 = __p1_209; \ | |
| 61863 | int32x2_t __rev0_209; __rev0_209 = __builtin_shufflevector(__s0_209, __s0_209, 1, 0); \ | |
| 61864 | int64x2_t __rev1_209; __rev1_209 = __builtin_shufflevector(__s1_209, __s1_209, 1, 0); \ | |
| 61865 | int32x4_t __ret_209; \ | |
| 61866 | __ret_209 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_209), (int32x2_t)(__noswap_vqshrn_n_s64(__rev1_209, __p2_209)))); \ | |
| 61867 | __ret_209 = __builtin_shufflevector(__ret_209, __ret_209, 3, 2, 1, 0); \ | |
| 61868 | __ret_209; \ | |
| 58557 | 61869 | }) |
| 58558 | 61870 | #endif |
| 58559 | 61871 | |
| 58560 | 61872 | #ifdef __LITTLE_ENDIAN__ |
| 58561 | #define vqshrn_high_n_s16(__p0_198, __p1_198, __p2_198) __extension__ ({ \ | |
| 58562 | int8x8_t __s0_198 = __p0_198; \ | |
| 58563 | int16x8_t __s1_198 = __p1_198; \ | |
| 58564 | int8x16_t __ret_198; \ | |
| 58565 | __ret_198 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_198), (int8x8_t)(vqshrn_n_s16(__s1_198, __p2_198)))); \ | |
| 58566 | __ret_198; \ | |
| 61873 | #define vqshrn_high_n_s16(__p0_210, __p1_210, __p2_210) __extension__ ({ \ | |
| 61874 | int8x8_t __s0_210 = __p0_210; \ | |
| 61875 | int16x8_t __s1_210 = __p1_210; \ | |
| 61876 | int8x16_t __ret_210; \ | |
| 61877 | __ret_210 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_210), (int8x8_t)(vqshrn_n_s16(__s1_210, __p2_210)))); \ | |
| 61878 | __ret_210; \ | |
| 58567 | 61879 | }) |
| 58568 | 61880 | #else |
| 58569 | #define vqshrn_high_n_s16(__p0_199, __p1_199, __p2_199) __extension__ ({ \ | |
| 58570 | int8x8_t __s0_199 = __p0_199; \ | |
| 58571 | int16x8_t __s1_199 = __p1_199; \ | |
| 58572 | int8x8_t __rev0_199; __rev0_199 = __builtin_shufflevector(__s0_199, __s0_199, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58573 | int16x8_t __rev1_199; __rev1_199 = __builtin_shufflevector(__s1_199, __s1_199, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58574 | int8x16_t __ret_199; \ | |
| 58575 | __ret_199 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_199), (int8x8_t)(__noswap_vqshrn_n_s16(__rev1_199, __p2_199)))); \ | |
| 58576 | __ret_199 = __builtin_shufflevector(__ret_199, __ret_199, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58577 | __ret_199; \ | |
| 61881 | #define vqshrn_high_n_s16(__p0_211, __p1_211, __p2_211) __extension__ ({ \ | |
| 61882 | int8x8_t __s0_211 = __p0_211; \ | |
| 61883 | int16x8_t __s1_211 = __p1_211; \ | |
| 61884 | int8x8_t __rev0_211; __rev0_211 = __builtin_shufflevector(__s0_211, __s0_211, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61885 | int16x8_t __rev1_211; __rev1_211 = __builtin_shufflevector(__s1_211, __s1_211, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61886 | int8x16_t __ret_211; \ | |
| 61887 | __ret_211 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_211), (int8x8_t)(__noswap_vqshrn_n_s16(__rev1_211, __p2_211)))); \ | |
| 61888 | __ret_211 = __builtin_shufflevector(__ret_211, __ret_211, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61889 | __ret_211; \ | |
| 58578 | 61890 | }) |
| 58579 | 61891 | #endif |
| 58580 | 61892 | |
| ... | ... | @@ -58675,65 +61987,65 @@ __ai int16_t vqshlh_s16(int16_t __p0, int16_t __p1) { |
| 58675 | 61987 | #endif |
| 58676 | 61988 | |
| 58677 | 61989 | #ifdef __LITTLE_ENDIAN__ |
| 58678 | #define vqshrun_high_n_s32(__p0_200, __p1_200, __p2_200) __extension__ ({ \ | |
| 58679 | int16x4_t __s0_200 = __p0_200; \ | |
| 58680 | int32x4_t __s1_200 = __p1_200; \ | |
| 58681 | int16x8_t __ret_200; \ | |
| 58682 | __ret_200 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_200), (int16x4_t)(vqshrun_n_s32(__s1_200, __p2_200)))); \ | |
| 58683 | __ret_200; \ | |
| 61990 | #define vqshrun_high_n_s32(__p0_212, __p1_212, __p2_212) __extension__ ({ \ | |
| 61991 | int16x4_t __s0_212 = __p0_212; \ | |
| 61992 | int32x4_t __s1_212 = __p1_212; \ | |
| 61993 | int16x8_t __ret_212; \ | |
| 61994 | __ret_212 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_212), (int16x4_t)(vqshrun_n_s32(__s1_212, __p2_212)))); \ | |
| 61995 | __ret_212; \ | |
| 58684 | 61996 | }) |
| 58685 | 61997 | #else |
| 58686 | #define vqshrun_high_n_s32(__p0_201, __p1_201, __p2_201) __extension__ ({ \ | |
| 58687 | int16x4_t __s0_201 = __p0_201; \ | |
| 58688 | int32x4_t __s1_201 = __p1_201; \ | |
| 58689 | int16x4_t __rev0_201; __rev0_201 = __builtin_shufflevector(__s0_201, __s0_201, 3, 2, 1, 0); \ | |
| 58690 | int32x4_t __rev1_201; __rev1_201 = __builtin_shufflevector(__s1_201, __s1_201, 3, 2, 1, 0); \ | |
| 58691 | int16x8_t __ret_201; \ | |
| 58692 | __ret_201 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_201), (int16x4_t)(__noswap_vqshrun_n_s32(__rev1_201, __p2_201)))); \ | |
| 58693 | __ret_201 = __builtin_shufflevector(__ret_201, __ret_201, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58694 | __ret_201; \ | |
| 61998 | #define vqshrun_high_n_s32(__p0_213, __p1_213, __p2_213) __extension__ ({ \ | |
| 61999 | int16x4_t __s0_213 = __p0_213; \ | |
| 62000 | int32x4_t __s1_213 = __p1_213; \ | |
| 62001 | int16x4_t __rev0_213; __rev0_213 = __builtin_shufflevector(__s0_213, __s0_213, 3, 2, 1, 0); \ | |
| 62002 | int32x4_t __rev1_213; __rev1_213 = __builtin_shufflevector(__s1_213, __s1_213, 3, 2, 1, 0); \ | |
| 62003 | int16x8_t __ret_213; \ | |
| 62004 | __ret_213 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_213), (int16x4_t)(__noswap_vqshrun_n_s32(__rev1_213, __p2_213)))); \ | |
| 62005 | __ret_213 = __builtin_shufflevector(__ret_213, __ret_213, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 62006 | __ret_213; \ | |
| 58695 | 62007 | }) |
| 58696 | 62008 | #endif |
| 58697 | 62009 | |
| 58698 | 62010 | #ifdef __LITTLE_ENDIAN__ |
| 58699 | #define vqshrun_high_n_s64(__p0_202, __p1_202, __p2_202) __extension__ ({ \ | |
| 58700 | int32x2_t __s0_202 = __p0_202; \ | |
| 58701 | int64x2_t __s1_202 = __p1_202; \ | |
| 58702 | int32x4_t __ret_202; \ | |
| 58703 | __ret_202 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_202), (int32x2_t)(vqshrun_n_s64(__s1_202, __p2_202)))); \ | |
| 58704 | __ret_202; \ | |
| 62011 | #define vqshrun_high_n_s64(__p0_214, __p1_214, __p2_214) __extension__ ({ \ | |
| 62012 | int32x2_t __s0_214 = __p0_214; \ | |
| 62013 | int64x2_t __s1_214 = __p1_214; \ | |
| 62014 | int32x4_t __ret_214; \ | |
| 62015 | __ret_214 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_214), (int32x2_t)(vqshrun_n_s64(__s1_214, __p2_214)))); \ | |
| 62016 | __ret_214; \ | |
| 58705 | 62017 | }) |
| 58706 | 62018 | #else |
| 58707 | #define vqshrun_high_n_s64(__p0_203, __p1_203, __p2_203) __extension__ ({ \ | |
| 58708 | int32x2_t __s0_203 = __p0_203; \ | |
| 58709 | int64x2_t __s1_203 = __p1_203; \ | |
| 58710 | int32x2_t __rev0_203; __rev0_203 = __builtin_shufflevector(__s0_203, __s0_203, 1, 0); \ | |
| 58711 | int64x2_t __rev1_203; __rev1_203 = __builtin_shufflevector(__s1_203, __s1_203, 1, 0); \ | |
| 58712 | int32x4_t __ret_203; \ | |
| 58713 | __ret_203 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_203), (int32x2_t)(__noswap_vqshrun_n_s64(__rev1_203, __p2_203)))); \ | |
| 58714 | __ret_203 = __builtin_shufflevector(__ret_203, __ret_203, 3, 2, 1, 0); \ | |
| 58715 | __ret_203; \ | |
| 62019 | #define vqshrun_high_n_s64(__p0_215, __p1_215, __p2_215) __extension__ ({ \ | |
| 62020 | int32x2_t __s0_215 = __p0_215; \ | |
| 62021 | int64x2_t __s1_215 = __p1_215; \ | |
| 62022 | int32x2_t __rev0_215; __rev0_215 = __builtin_shufflevector(__s0_215, __s0_215, 1, 0); \ | |
| 62023 | int64x2_t __rev1_215; __rev1_215 = __builtin_shufflevector(__s1_215, __s1_215, 1, 0); \ | |
| 62024 | int32x4_t __ret_215; \ | |
| 62025 | __ret_215 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_215), (int32x2_t)(__noswap_vqshrun_n_s64(__rev1_215, __p2_215)))); \ | |
| 62026 | __ret_215 = __builtin_shufflevector(__ret_215, __ret_215, 3, 2, 1, 0); \ | |
| 62027 | __ret_215; \ | |
| 58716 | 62028 | }) |
| 58717 | 62029 | #endif |
| 58718 | 62030 | |
| 58719 | 62031 | #ifdef __LITTLE_ENDIAN__ |
| 58720 | #define vqshrun_high_n_s16(__p0_204, __p1_204, __p2_204) __extension__ ({ \ | |
| 58721 | int8x8_t __s0_204 = __p0_204; \ | |
| 58722 | int16x8_t __s1_204 = __p1_204; \ | |
| 58723 | int8x16_t __ret_204; \ | |
| 58724 | __ret_204 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_204), (int8x8_t)(vqshrun_n_s16(__s1_204, __p2_204)))); \ | |
| 58725 | __ret_204; \ | |
| 62032 | #define vqshrun_high_n_s16(__p0_216, __p1_216, __p2_216) __extension__ ({ \ | |
| 62033 | int8x8_t __s0_216 = __p0_216; \ | |
| 62034 | int16x8_t __s1_216 = __p1_216; \ | |
| 62035 | int8x16_t __ret_216; \ | |
| 62036 | __ret_216 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_216), (int8x8_t)(vqshrun_n_s16(__s1_216, __p2_216)))); \ | |
| 62037 | __ret_216; \ | |
| 58726 | 62038 | }) |
| 58727 | 62039 | #else |
| 58728 | #define vqshrun_high_n_s16(__p0_205, __p1_205, __p2_205) __extension__ ({ \ | |
| 58729 | int8x8_t __s0_205 = __p0_205; \ | |
| 58730 | int16x8_t __s1_205 = __p1_205; \ | |
| 58731 | int8x8_t __rev0_205; __rev0_205 = __builtin_shufflevector(__s0_205, __s0_205, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58732 | int16x8_t __rev1_205; __rev1_205 = __builtin_shufflevector(__s1_205, __s1_205, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58733 | int8x16_t __ret_205; \ | |
| 58734 | __ret_205 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_205), (int8x8_t)(__noswap_vqshrun_n_s16(__rev1_205, __p2_205)))); \ | |
| 58735 | __ret_205 = __builtin_shufflevector(__ret_205, __ret_205, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 58736 | __ret_205; \ | |
| 62040 | #define vqshrun_high_n_s16(__p0_217, __p1_217, __p2_217) __extension__ ({ \ | |
| 62041 | int8x8_t __s0_217 = __p0_217; \ | |
| 62042 | int16x8_t __s1_217 = __p1_217; \ | |
| 62043 | int8x8_t __rev0_217; __rev0_217 = __builtin_shufflevector(__s0_217, __s0_217, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 62044 | int16x8_t __rev1_217; __rev1_217 = __builtin_shufflevector(__s1_217, __s1_217, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 62045 | int8x16_t __ret_217; \ | |
| 62046 | __ret_217 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_217), (int8x8_t)(__noswap_vqshrun_n_s16(__rev1_217, __p2_217)))); \ | |
| 62047 | __ret_217 = __builtin_shufflevector(__ret_217, __ret_217, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 62048 | __ret_217; \ | |
| 58737 | 62049 | }) |
| 58738 | 62050 | #endif |
| 58739 | 62051 | |
| ... | ... | @@ -60265,128 +63577,128 @@ __ai int64_t vrshld_s64(int64_t __p0, int64_t __p1) { |
| 60265 | 63577 | #endif |
| 60266 | 63578 | |
| 60267 | 63579 | #ifdef __LITTLE_ENDIAN__ |
| 60268 | #define vrshrn_high_n_u32(__p0_206, __p1_206, __p2_206) __extension__ ({ \ | |
| 60269 | uint16x4_t __s0_206 = __p0_206; \ | |
| 60270 | uint32x4_t __s1_206 = __p1_206; \ | |
| 60271 | uint16x8_t __ret_206; \ | |
| 60272 | __ret_206 = (uint16x8_t)(vcombine_u16((uint16x4_t)(__s0_206), (uint16x4_t)(vrshrn_n_u32(__s1_206, __p2_206)))); \ | |
| 60273 | __ret_206; \ | |
| 63580 | #define vrshrn_high_n_u32(__p0_218, __p1_218, __p2_218) __extension__ ({ \ | |
| 63581 | uint16x4_t __s0_218 = __p0_218; \ | |
| 63582 | uint32x4_t __s1_218 = __p1_218; \ | |
| 63583 | uint16x8_t __ret_218; \ | |
| 63584 | __ret_218 = (uint16x8_t)(vcombine_u16((uint16x4_t)(__s0_218), (uint16x4_t)(vrshrn_n_u32(__s1_218, __p2_218)))); \ | |
| 63585 | __ret_218; \ | |
| 60274 | 63586 | }) |
| 60275 | 63587 | #else |
| 60276 | #define vrshrn_high_n_u32(__p0_207, __p1_207, __p2_207) __extension__ ({ \ | |
| 60277 | uint16x4_t __s0_207 = __p0_207; \ | |
| 60278 | uint32x4_t __s1_207 = __p1_207; \ | |
| 60279 | uint16x4_t __rev0_207; __rev0_207 = __builtin_shufflevector(__s0_207, __s0_207, 3, 2, 1, 0); \ | |
| 60280 | uint32x4_t __rev1_207; __rev1_207 = __builtin_shufflevector(__s1_207, __s1_207, 3, 2, 1, 0); \ | |
| 60281 | uint16x8_t __ret_207; \ | |
| 60282 | __ret_207 = (uint16x8_t)(__noswap_vcombine_u16((uint16x4_t)(__rev0_207), (uint16x4_t)(__noswap_vrshrn_n_u32(__rev1_207, __p2_207)))); \ | |
| 60283 | __ret_207 = __builtin_shufflevector(__ret_207, __ret_207, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60284 | __ret_207; \ | |
| 63588 | #define vrshrn_high_n_u32(__p0_219, __p1_219, __p2_219) __extension__ ({ \ | |
| 63589 | uint16x4_t __s0_219 = __p0_219; \ | |
| 63590 | uint32x4_t __s1_219 = __p1_219; \ | |
| 63591 | uint16x4_t __rev0_219; __rev0_219 = __builtin_shufflevector(__s0_219, __s0_219, 3, 2, 1, 0); \ | |
| 63592 | uint32x4_t __rev1_219; __rev1_219 = __builtin_shufflevector(__s1_219, __s1_219, 3, 2, 1, 0); \ | |
| 63593 | uint16x8_t __ret_219; \ | |
| 63594 | __ret_219 = (uint16x8_t)(__noswap_vcombine_u16((uint16x4_t)(__rev0_219), (uint16x4_t)(__noswap_vrshrn_n_u32(__rev1_219, __p2_219)))); \ | |
| 63595 | __ret_219 = __builtin_shufflevector(__ret_219, __ret_219, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 63596 | __ret_219; \ | |
| 60285 | 63597 | }) |
| 60286 | 63598 | #endif |
| 60287 | 63599 | |
| 60288 | 63600 | #ifdef __LITTLE_ENDIAN__ |
| 60289 | #define vrshrn_high_n_u64(__p0_208, __p1_208, __p2_208) __extension__ ({ \ | |
| 60290 | uint32x2_t __s0_208 = __p0_208; \ | |
| 60291 | uint64x2_t __s1_208 = __p1_208; \ | |
| 60292 | uint32x4_t __ret_208; \ | |
| 60293 | __ret_208 = (uint32x4_t)(vcombine_u32((uint32x2_t)(__s0_208), (uint32x2_t)(vrshrn_n_u64(__s1_208, __p2_208)))); \ | |
| 60294 | __ret_208; \ | |
| 63601 | #define vrshrn_high_n_u64(__p0_220, __p1_220, __p2_220) __extension__ ({ \ | |
| 63602 | uint32x2_t __s0_220 = __p0_220; \ | |
| 63603 | uint64x2_t __s1_220 = __p1_220; \ | |
| 63604 | uint32x4_t __ret_220; \ | |
| 63605 | __ret_220 = (uint32x4_t)(vcombine_u32((uint32x2_t)(__s0_220), (uint32x2_t)(vrshrn_n_u64(__s1_220, __p2_220)))); \ | |
| 63606 | __ret_220; \ | |
| 60295 | 63607 | }) |
| 60296 | 63608 | #else |
| 60297 | #define vrshrn_high_n_u64(__p0_209, __p1_209, __p2_209) __extension__ ({ \ | |
| 60298 | uint32x2_t __s0_209 = __p0_209; \ | |
| 60299 | uint64x2_t __s1_209 = __p1_209; \ | |
| 60300 | uint32x2_t __rev0_209; __rev0_209 = __builtin_shufflevector(__s0_209, __s0_209, 1, 0); \ | |
| 60301 | uint64x2_t __rev1_209; __rev1_209 = __builtin_shufflevector(__s1_209, __s1_209, 1, 0); \ | |
| 60302 | uint32x4_t __ret_209; \ | |
| 60303 | __ret_209 = (uint32x4_t)(__noswap_vcombine_u32((uint32x2_t)(__rev0_209), (uint32x2_t)(__noswap_vrshrn_n_u64(__rev1_209, __p2_209)))); \ | |
| 60304 | __ret_209 = __builtin_shufflevector(__ret_209, __ret_209, 3, 2, 1, 0); \ | |
| 60305 | __ret_209; \ | |
| 63609 | #define vrshrn_high_n_u64(__p0_221, __p1_221, __p2_221) __extension__ ({ \ | |
| 63610 | uint32x2_t __s0_221 = __p0_221; \ | |
| 63611 | uint64x2_t __s1_221 = __p1_221; \ | |
| 63612 | uint32x2_t __rev0_221; __rev0_221 = __builtin_shufflevector(__s0_221, __s0_221, 1, 0); \ | |
| 63613 | uint64x2_t __rev1_221; __rev1_221 = __builtin_shufflevector(__s1_221, __s1_221, 1, 0); \ | |
| 63614 | uint32x4_t __ret_221; \ | |
| 63615 | __ret_221 = (uint32x4_t)(__noswap_vcombine_u32((uint32x2_t)(__rev0_221), (uint32x2_t)(__noswap_vrshrn_n_u64(__rev1_221, __p2_221)))); \ | |
| 63616 | __ret_221 = __builtin_shufflevector(__ret_221, __ret_221, 3, 2, 1, 0); \ | |
| 63617 | __ret_221; \ | |
| 60306 | 63618 | }) |
| 60307 | 63619 | #endif |
| 60308 | 63620 | |
| 60309 | 63621 | #ifdef __LITTLE_ENDIAN__ |
| 60310 | #define vrshrn_high_n_u16(__p0_210, __p1_210, __p2_210) __extension__ ({ \ | |
| 60311 | uint8x8_t __s0_210 = __p0_210; \ | |
| 60312 | uint16x8_t __s1_210 = __p1_210; \ | |
| 60313 | uint8x16_t __ret_210; \ | |
| 60314 | __ret_210 = (uint8x16_t)(vcombine_u8((uint8x8_t)(__s0_210), (uint8x8_t)(vrshrn_n_u16(__s1_210, __p2_210)))); \ | |
| 60315 | __ret_210; \ | |
| 63622 | #define vrshrn_high_n_u16(__p0_222, __p1_222, __p2_222) __extension__ ({ \ | |
| 63623 | uint8x8_t __s0_222 = __p0_222; \ | |
| 63624 | uint16x8_t __s1_222 = __p1_222; \ | |
| 63625 | uint8x16_t __ret_222; \ | |
| 63626 | __ret_222 = (uint8x16_t)(vcombine_u8((uint8x8_t)(__s0_222), (uint8x8_t)(vrshrn_n_u16(__s1_222, __p2_222)))); \ | |
| 63627 | __ret_222; \ | |
| 60316 | 63628 | }) |
| 60317 | 63629 | #else |
| 60318 | #define vrshrn_high_n_u16(__p0_211, __p1_211, __p2_211) __extension__ ({ \ | |
| 60319 | uint8x8_t __s0_211 = __p0_211; \ | |
| 60320 | uint16x8_t __s1_211 = __p1_211; \ | |
| 60321 | uint8x8_t __rev0_211; __rev0_211 = __builtin_shufflevector(__s0_211, __s0_211, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60322 | uint16x8_t __rev1_211; __rev1_211 = __builtin_shufflevector(__s1_211, __s1_211, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60323 | uint8x16_t __ret_211; \ | |
| 60324 | __ret_211 = (uint8x16_t)(__noswap_vcombine_u8((uint8x8_t)(__rev0_211), (uint8x8_t)(__noswap_vrshrn_n_u16(__rev1_211, __p2_211)))); \ | |
| 60325 | __ret_211 = __builtin_shufflevector(__ret_211, __ret_211, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60326 | __ret_211; \ | |
| 63630 | #define vrshrn_high_n_u16(__p0_223, __p1_223, __p2_223) __extension__ ({ \ | |
| 63631 | uint8x8_t __s0_223 = __p0_223; \ | |
| 63632 | uint16x8_t __s1_223 = __p1_223; \ | |
| 63633 | uint8x8_t __rev0_223; __rev0_223 = __builtin_shufflevector(__s0_223, __s0_223, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 63634 | uint16x8_t __rev1_223; __rev1_223 = __builtin_shufflevector(__s1_223, __s1_223, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 63635 | uint8x16_t __ret_223; \ | |
| 63636 | __ret_223 = (uint8x16_t)(__noswap_vcombine_u8((uint8x8_t)(__rev0_223), (uint8x8_t)(__noswap_vrshrn_n_u16(__rev1_223, __p2_223)))); \ | |
| 63637 | __ret_223 = __builtin_shufflevector(__ret_223, __ret_223, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 63638 | __ret_223; \ | |
| 60327 | 63639 | }) |
| 60328 | 63640 | #endif |
| 60329 | 63641 | |
| 60330 | 63642 | #ifdef __LITTLE_ENDIAN__ |
| 60331 | #define vrshrn_high_n_s32(__p0_212, __p1_212, __p2_212) __extension__ ({ \ | |
| 60332 | int16x4_t __s0_212 = __p0_212; \ | |
| 60333 | int32x4_t __s1_212 = __p1_212; \ | |
| 60334 | int16x8_t __ret_212; \ | |
| 60335 | __ret_212 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_212), (int16x4_t)(vrshrn_n_s32(__s1_212, __p2_212)))); \ | |
| 60336 | __ret_212; \ | |
| 63643 | #define vrshrn_high_n_s32(__p0_224, __p1_224, __p2_224) __extension__ ({ \ | |
| 63644 | int16x4_t __s0_224 = __p0_224; \ | |
| 63645 | int32x4_t __s1_224 = __p1_224; \ | |
| 63646 | int16x8_t __ret_224; \ | |
| 63647 | __ret_224 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_224), (int16x4_t)(vrshrn_n_s32(__s1_224, __p2_224)))); \ | |
| 63648 | __ret_224; \ | |
| 60337 | 63649 | }) |
| 60338 | 63650 | #else |
| 60339 | #define vrshrn_high_n_s32(__p0_213, __p1_213, __p2_213) __extension__ ({ \ | |
| 60340 | int16x4_t __s0_213 = __p0_213; \ | |
| 60341 | int32x4_t __s1_213 = __p1_213; \ | |
| 60342 | int16x4_t __rev0_213; __rev0_213 = __builtin_shufflevector(__s0_213, __s0_213, 3, 2, 1, 0); \ | |
| 60343 | int32x4_t __rev1_213; __rev1_213 = __builtin_shufflevector(__s1_213, __s1_213, 3, 2, 1, 0); \ | |
| 60344 | int16x8_t __ret_213; \ | |
| 60345 | __ret_213 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_213), (int16x4_t)(__noswap_vrshrn_n_s32(__rev1_213, __p2_213)))); \ | |
| 60346 | __ret_213 = __builtin_shufflevector(__ret_213, __ret_213, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60347 | __ret_213; \ | |
| 63651 | #define vrshrn_high_n_s32(__p0_225, __p1_225, __p2_225) __extension__ ({ \ | |
| 63652 | int16x4_t __s0_225 = __p0_225; \ | |
| 63653 | int32x4_t __s1_225 = __p1_225; \ | |
| 63654 | int16x4_t __rev0_225; __rev0_225 = __builtin_shufflevector(__s0_225, __s0_225, 3, 2, 1, 0); \ | |
| 63655 | int32x4_t __rev1_225; __rev1_225 = __builtin_shufflevector(__s1_225, __s1_225, 3, 2, 1, 0); \ | |
| 63656 | int16x8_t __ret_225; \ | |
| 63657 | __ret_225 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_225), (int16x4_t)(__noswap_vrshrn_n_s32(__rev1_225, __p2_225)))); \ | |
| 63658 | __ret_225 = __builtin_shufflevector(__ret_225, __ret_225, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 63659 | __ret_225; \ | |
| 60348 | 63660 | }) |
| 60349 | 63661 | #endif |
| 60350 | 63662 | |
| 60351 | 63663 | #ifdef __LITTLE_ENDIAN__ |
| 60352 | #define vrshrn_high_n_s64(__p0_214, __p1_214, __p2_214) __extension__ ({ \ | |
| 60353 | int32x2_t __s0_214 = __p0_214; \ | |
| 60354 | int64x2_t __s1_214 = __p1_214; \ | |
| 60355 | int32x4_t __ret_214; \ | |
| 60356 | __ret_214 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_214), (int32x2_t)(vrshrn_n_s64(__s1_214, __p2_214)))); \ | |
| 60357 | __ret_214; \ | |
| 63664 | #define vrshrn_high_n_s64(__p0_226, __p1_226, __p2_226) __extension__ ({ \ | |
| 63665 | int32x2_t __s0_226 = __p0_226; \ | |
| 63666 | int64x2_t __s1_226 = __p1_226; \ | |
| 63667 | int32x4_t __ret_226; \ | |
| 63668 | __ret_226 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_226), (int32x2_t)(vrshrn_n_s64(__s1_226, __p2_226)))); \ | |
| 63669 | __ret_226; \ | |
| 60358 | 63670 | }) |
| 60359 | 63671 | #else |
| 60360 | #define vrshrn_high_n_s64(__p0_215, __p1_215, __p2_215) __extension__ ({ \ | |
| 60361 | int32x2_t __s0_215 = __p0_215; \ | |
| 60362 | int64x2_t __s1_215 = __p1_215; \ | |
| 60363 | int32x2_t __rev0_215; __rev0_215 = __builtin_shufflevector(__s0_215, __s0_215, 1, 0); \ | |
| 60364 | int64x2_t __rev1_215; __rev1_215 = __builtin_shufflevector(__s1_215, __s1_215, 1, 0); \ | |
| 60365 | int32x4_t __ret_215; \ | |
| 60366 | __ret_215 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_215), (int32x2_t)(__noswap_vrshrn_n_s64(__rev1_215, __p2_215)))); \ | |
| 60367 | __ret_215 = __builtin_shufflevector(__ret_215, __ret_215, 3, 2, 1, 0); \ | |
| 60368 | __ret_215; \ | |
| 63672 | #define vrshrn_high_n_s64(__p0_227, __p1_227, __p2_227) __extension__ ({ \ | |
| 63673 | int32x2_t __s0_227 = __p0_227; \ | |
| 63674 | int64x2_t __s1_227 = __p1_227; \ | |
| 63675 | int32x2_t __rev0_227; __rev0_227 = __builtin_shufflevector(__s0_227, __s0_227, 1, 0); \ | |
| 63676 | int64x2_t __rev1_227; __rev1_227 = __builtin_shufflevector(__s1_227, __s1_227, 1, 0); \ | |
| 63677 | int32x4_t __ret_227; \ | |
| 63678 | __ret_227 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_227), (int32x2_t)(__noswap_vrshrn_n_s64(__rev1_227, __p2_227)))); \ | |
| 63679 | __ret_227 = __builtin_shufflevector(__ret_227, __ret_227, 3, 2, 1, 0); \ | |
| 63680 | __ret_227; \ | |
| 60369 | 63681 | }) |
| 60370 | 63682 | #endif |
| 60371 | 63683 | |
| 60372 | 63684 | #ifdef __LITTLE_ENDIAN__ |
| 60373 | #define vrshrn_high_n_s16(__p0_216, __p1_216, __p2_216) __extension__ ({ \ | |
| 60374 | int8x8_t __s0_216 = __p0_216; \ | |
| 60375 | int16x8_t __s1_216 = __p1_216; \ | |
| 60376 | int8x16_t __ret_216; \ | |
| 60377 | __ret_216 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_216), (int8x8_t)(vrshrn_n_s16(__s1_216, __p2_216)))); \ | |
| 60378 | __ret_216; \ | |
| 63685 | #define vrshrn_high_n_s16(__p0_228, __p1_228, __p2_228) __extension__ ({ \ | |
| 63686 | int8x8_t __s0_228 = __p0_228; \ | |
| 63687 | int16x8_t __s1_228 = __p1_228; \ | |
| 63688 | int8x16_t __ret_228; \ | |
| 63689 | __ret_228 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_228), (int8x8_t)(vrshrn_n_s16(__s1_228, __p2_228)))); \ | |
| 63690 | __ret_228; \ | |
| 60379 | 63691 | }) |
| 60380 | 63692 | #else |
| 60381 | #define vrshrn_high_n_s16(__p0_217, __p1_217, __p2_217) __extension__ ({ \ | |
| 60382 | int8x8_t __s0_217 = __p0_217; \ | |
| 60383 | int16x8_t __s1_217 = __p1_217; \ | |
| 60384 | int8x8_t __rev0_217; __rev0_217 = __builtin_shufflevector(__s0_217, __s0_217, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60385 | int16x8_t __rev1_217; __rev1_217 = __builtin_shufflevector(__s1_217, __s1_217, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60386 | int8x16_t __ret_217; \ | |
| 60387 | __ret_217 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_217), (int8x8_t)(__noswap_vrshrn_n_s16(__rev1_217, __p2_217)))); \ | |
| 60388 | __ret_217 = __builtin_shufflevector(__ret_217, __ret_217, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60389 | __ret_217; \ | |
| 63693 | #define vrshrn_high_n_s16(__p0_229, __p1_229, __p2_229) __extension__ ({ \ | |
| 63694 | int8x8_t __s0_229 = __p0_229; \ | |
| 63695 | int16x8_t __s1_229 = __p1_229; \ | |
| 63696 | int8x8_t __rev0_229; __rev0_229 = __builtin_shufflevector(__s0_229, __s0_229, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 63697 | int16x8_t __rev1_229; __rev1_229 = __builtin_shufflevector(__s1_229, __s1_229, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 63698 | int8x16_t __ret_229; \ | |
| 63699 | __ret_229 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_229), (int8x8_t)(__noswap_vrshrn_n_s16(__rev1_229, __p2_229)))); \ | |
| 63700 | __ret_229 = __builtin_shufflevector(__ret_229, __ret_229, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 63701 | __ret_229; \ | |
| 60390 | 63702 | }) |
| 60391 | 63703 | #endif |
| 60392 | 63704 | |
| ... | ... | @@ -60816,110 +64128,110 @@ __ai int64_t vshld_s64(int64_t __p0, int64_t __p1) { |
| 60816 | 64128 | #endif |
| 60817 | 64129 | |
| 60818 | 64130 | #ifdef __LITTLE_ENDIAN__ |
| 60819 | #define vshll_high_n_u8(__p0_218, __p1_218) __extension__ ({ \ | |
| 60820 | uint8x16_t __s0_218 = __p0_218; \ | |
| 60821 | uint16x8_t __ret_218; \ | |
| 60822 | __ret_218 = (uint16x8_t)(vshll_n_u8(vget_high_u8(__s0_218), __p1_218)); \ | |
| 60823 | __ret_218; \ | |
| 64131 | #define vshll_high_n_u8(__p0_230, __p1_230) __extension__ ({ \ | |
| 64132 | uint8x16_t __s0_230 = __p0_230; \ | |
| 64133 | uint16x8_t __ret_230; \ | |
| 64134 | __ret_230 = (uint16x8_t)(vshll_n_u8(vget_high_u8(__s0_230), __p1_230)); \ | |
| 64135 | __ret_230; \ | |
| 60824 | 64136 | }) |
| 60825 | 64137 | #else |
| 60826 | #define vshll_high_n_u8(__p0_219, __p1_219) __extension__ ({ \ | |
| 60827 | uint8x16_t __s0_219 = __p0_219; \ | |
| 60828 | uint8x16_t __rev0_219; __rev0_219 = __builtin_shufflevector(__s0_219, __s0_219, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60829 | uint16x8_t __ret_219; \ | |
| 60830 | __ret_219 = (uint16x8_t)(__noswap_vshll_n_u8(__noswap_vget_high_u8(__rev0_219), __p1_219)); \ | |
| 60831 | __ret_219 = __builtin_shufflevector(__ret_219, __ret_219, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60832 | __ret_219; \ | |
| 64138 | #define vshll_high_n_u8(__p0_231, __p1_231) __extension__ ({ \ | |
| 64139 | uint8x16_t __s0_231 = __p0_231; \ | |
| 64140 | uint8x16_t __rev0_231; __rev0_231 = __builtin_shufflevector(__s0_231, __s0_231, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 64141 | uint16x8_t __ret_231; \ | |
| 64142 | __ret_231 = (uint16x8_t)(__noswap_vshll_n_u8(__noswap_vget_high_u8(__rev0_231), __p1_231)); \ | |
| 64143 | __ret_231 = __builtin_shufflevector(__ret_231, __ret_231, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 64144 | __ret_231; \ | |
| 60833 | 64145 | }) |
| 60834 | 64146 | #endif |
| 60835 | 64147 | |
| 60836 | 64148 | #ifdef __LITTLE_ENDIAN__ |
| 60837 | #define vshll_high_n_u32(__p0_220, __p1_220) __extension__ ({ \ | |
| 60838 | uint32x4_t __s0_220 = __p0_220; \ | |
| 60839 | uint64x2_t __ret_220; \ | |
| 60840 | __ret_220 = (uint64x2_t)(vshll_n_u32(vget_high_u32(__s0_220), __p1_220)); \ | |
| 60841 | __ret_220; \ | |
| 64149 | #define vshll_high_n_u32(__p0_232, __p1_232) __extension__ ({ \ | |
| 64150 | uint32x4_t __s0_232 = __p0_232; \ | |
| 64151 | uint64x2_t __ret_232; \ | |
| 64152 | __ret_232 = (uint64x2_t)(vshll_n_u32(vget_high_u32(__s0_232), __p1_232)); \ | |
| 64153 | __ret_232; \ | |
| 60842 | 64154 | }) |
| 60843 | 64155 | #else |
| 60844 | #define vshll_high_n_u32(__p0_221, __p1_221) __extension__ ({ \ | |
| 60845 | uint32x4_t __s0_221 = __p0_221; \ | |
| 60846 | uint32x4_t __rev0_221; __rev0_221 = __builtin_shufflevector(__s0_221, __s0_221, 3, 2, 1, 0); \ | |
| 60847 | uint64x2_t __ret_221; \ | |
| 60848 | __ret_221 = (uint64x2_t)(__noswap_vshll_n_u32(__noswap_vget_high_u32(__rev0_221), __p1_221)); \ | |
| 60849 | __ret_221 = __builtin_shufflevector(__ret_221, __ret_221, 1, 0); \ | |
| 60850 | __ret_221; \ | |
| 64156 | #define vshll_high_n_u32(__p0_233, __p1_233) __extension__ ({ \ | |
| 64157 | uint32x4_t __s0_233 = __p0_233; \ | |
| 64158 | uint32x4_t __rev0_233; __rev0_233 = __builtin_shufflevector(__s0_233, __s0_233, 3, 2, 1, 0); \ | |
| 64159 | uint64x2_t __ret_233; \ | |
| 64160 | __ret_233 = (uint64x2_t)(__noswap_vshll_n_u32(__noswap_vget_high_u32(__rev0_233), __p1_233)); \ | |
| 64161 | __ret_233 = __builtin_shufflevector(__ret_233, __ret_233, 1, 0); \ | |
| 64162 | __ret_233; \ | |
| 60851 | 64163 | }) |
| 60852 | 64164 | #endif |
| 60853 | 64165 | |
| 60854 | 64166 | #ifdef __LITTLE_ENDIAN__ |
| 60855 | #define vshll_high_n_u16(__p0_222, __p1_222) __extension__ ({ \ | |
| 60856 | uint16x8_t __s0_222 = __p0_222; \ | |
| 60857 | uint32x4_t __ret_222; \ | |
| 60858 | __ret_222 = (uint32x4_t)(vshll_n_u16(vget_high_u16(__s0_222), __p1_222)); \ | |
| 60859 | __ret_222; \ | |
| 64167 | #define vshll_high_n_u16(__p0_234, __p1_234) __extension__ ({ \ | |
| 64168 | uint16x8_t __s0_234 = __p0_234; \ | |
| 64169 | uint32x4_t __ret_234; \ | |
| 64170 | __ret_234 = (uint32x4_t)(vshll_n_u16(vget_high_u16(__s0_234), __p1_234)); \ | |
| 64171 | __ret_234; \ | |
| 60860 | 64172 | }) |
| 60861 | 64173 | #else |
| 60862 | #define vshll_high_n_u16(__p0_223, __p1_223) __extension__ ({ \ | |
| 60863 | uint16x8_t __s0_223 = __p0_223; \ | |
| 60864 | uint16x8_t __rev0_223; __rev0_223 = __builtin_shufflevector(__s0_223, __s0_223, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60865 | uint32x4_t __ret_223; \ | |
| 60866 | __ret_223 = (uint32x4_t)(__noswap_vshll_n_u16(__noswap_vget_high_u16(__rev0_223), __p1_223)); \ | |
| 60867 | __ret_223 = __builtin_shufflevector(__ret_223, __ret_223, 3, 2, 1, 0); \ | |
| 60868 | __ret_223; \ | |
| 64174 | #define vshll_high_n_u16(__p0_235, __p1_235) __extension__ ({ \ | |
| 64175 | uint16x8_t __s0_235 = __p0_235; \ | |
| 64176 | uint16x8_t __rev0_235; __rev0_235 = __builtin_shufflevector(__s0_235, __s0_235, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 64177 | uint32x4_t __ret_235; \ | |
| 64178 | __ret_235 = (uint32x4_t)(__noswap_vshll_n_u16(__noswap_vget_high_u16(__rev0_235), __p1_235)); \ | |
| 64179 | __ret_235 = __builtin_shufflevector(__ret_235, __ret_235, 3, 2, 1, 0); \ | |
| 64180 | __ret_235; \ | |
| 60869 | 64181 | }) |
| 60870 | 64182 | #endif |
| 60871 | 64183 | |
| 60872 | 64184 | #ifdef __LITTLE_ENDIAN__ |
| 60873 | #define vshll_high_n_s8(__p0_224, __p1_224) __extension__ ({ \ | |
| 60874 | int8x16_t __s0_224 = __p0_224; \ | |
| 60875 | int16x8_t __ret_224; \ | |
| 60876 | __ret_224 = (int16x8_t)(vshll_n_s8(vget_high_s8(__s0_224), __p1_224)); \ | |
| 60877 | __ret_224; \ | |
| 64185 | #define vshll_high_n_s8(__p0_236, __p1_236) __extension__ ({ \ | |
| 64186 | int8x16_t __s0_236 = __p0_236; \ | |
| 64187 | int16x8_t __ret_236; \ | |
| 64188 | __ret_236 = (int16x8_t)(vshll_n_s8(vget_high_s8(__s0_236), __p1_236)); \ | |
| 64189 | __ret_236; \ | |
| 60878 | 64190 | }) |
| 60879 | 64191 | #else |
| 60880 | #define vshll_high_n_s8(__p0_225, __p1_225) __extension__ ({ \ | |
| 60881 | int8x16_t __s0_225 = __p0_225; \ | |
| 60882 | int8x16_t __rev0_225; __rev0_225 = __builtin_shufflevector(__s0_225, __s0_225, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60883 | int16x8_t __ret_225; \ | |
| 60884 | __ret_225 = (int16x8_t)(__noswap_vshll_n_s8(__noswap_vget_high_s8(__rev0_225), __p1_225)); \ | |
| 60885 | __ret_225 = __builtin_shufflevector(__ret_225, __ret_225, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60886 | __ret_225; \ | |
| 64192 | #define vshll_high_n_s8(__p0_237, __p1_237) __extension__ ({ \ | |
| 64193 | int8x16_t __s0_237 = __p0_237; \ | |
| 64194 | int8x16_t __rev0_237; __rev0_237 = __builtin_shufflevector(__s0_237, __s0_237, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 64195 | int16x8_t __ret_237; \ | |
| 64196 | __ret_237 = (int16x8_t)(__noswap_vshll_n_s8(__noswap_vget_high_s8(__rev0_237), __p1_237)); \ | |
| 64197 | __ret_237 = __builtin_shufflevector(__ret_237, __ret_237, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 64198 | __ret_237; \ | |
| 60887 | 64199 | }) |
| 60888 | 64200 | #endif |
| 60889 | 64201 | |
| 60890 | 64202 | #ifdef __LITTLE_ENDIAN__ |
| 60891 | #define vshll_high_n_s32(__p0_226, __p1_226) __extension__ ({ \ | |
| 60892 | int32x4_t __s0_226 = __p0_226; \ | |
| 60893 | int64x2_t __ret_226; \ | |
| 60894 | __ret_226 = (int64x2_t)(vshll_n_s32(vget_high_s32(__s0_226), __p1_226)); \ | |
| 60895 | __ret_226; \ | |
| 64203 | #define vshll_high_n_s32(__p0_238, __p1_238) __extension__ ({ \ | |
| 64204 | int32x4_t __s0_238 = __p0_238; \ | |
| 64205 | int64x2_t __ret_238; \ | |
| 64206 | __ret_238 = (int64x2_t)(vshll_n_s32(vget_high_s32(__s0_238), __p1_238)); \ | |
| 64207 | __ret_238; \ | |
| 60896 | 64208 | }) |
| 60897 | 64209 | #else |
| 60898 | #define vshll_high_n_s32(__p0_227, __p1_227) __extension__ ({ \ | |
| 60899 | int32x4_t __s0_227 = __p0_227; \ | |
| 60900 | int32x4_t __rev0_227; __rev0_227 = __builtin_shufflevector(__s0_227, __s0_227, 3, 2, 1, 0); \ | |
| 60901 | int64x2_t __ret_227; \ | |
| 60902 | __ret_227 = (int64x2_t)(__noswap_vshll_n_s32(__noswap_vget_high_s32(__rev0_227), __p1_227)); \ | |
| 60903 | __ret_227 = __builtin_shufflevector(__ret_227, __ret_227, 1, 0); \ | |
| 60904 | __ret_227; \ | |
| 64210 | #define vshll_high_n_s32(__p0_239, __p1_239) __extension__ ({ \ | |
| 64211 | int32x4_t __s0_239 = __p0_239; \ | |
| 64212 | int32x4_t __rev0_239; __rev0_239 = __builtin_shufflevector(__s0_239, __s0_239, 3, 2, 1, 0); \ | |
| 64213 | int64x2_t __ret_239; \ | |
| 64214 | __ret_239 = (int64x2_t)(__noswap_vshll_n_s32(__noswap_vget_high_s32(__rev0_239), __p1_239)); \ | |
| 64215 | __ret_239 = __builtin_shufflevector(__ret_239, __ret_239, 1, 0); \ | |
| 64216 | __ret_239; \ | |
| 60905 | 64217 | }) |
| 60906 | 64218 | #endif |
| 60907 | 64219 | |
| 60908 | 64220 | #ifdef __LITTLE_ENDIAN__ |
| 60909 | #define vshll_high_n_s16(__p0_228, __p1_228) __extension__ ({ \ | |
| 60910 | int16x8_t __s0_228 = __p0_228; \ | |
| 60911 | int32x4_t __ret_228; \ | |
| 60912 | __ret_228 = (int32x4_t)(vshll_n_s16(vget_high_s16(__s0_228), __p1_228)); \ | |
| 60913 | __ret_228; \ | |
| 64221 | #define vshll_high_n_s16(__p0_240, __p1_240) __extension__ ({ \ | |
| 64222 | int16x8_t __s0_240 = __p0_240; \ | |
| 64223 | int32x4_t __ret_240; \ | |
| 64224 | __ret_240 = (int32x4_t)(vshll_n_s16(vget_high_s16(__s0_240), __p1_240)); \ | |
| 64225 | __ret_240; \ | |
| 60914 | 64226 | }) |
| 60915 | 64227 | #else |
| 60916 | #define vshll_high_n_s16(__p0_229, __p1_229) __extension__ ({ \ | |
| 60917 | int16x8_t __s0_229 = __p0_229; \ | |
| 60918 | int16x8_t __rev0_229; __rev0_229 = __builtin_shufflevector(__s0_229, __s0_229, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60919 | int32x4_t __ret_229; \ | |
| 60920 | __ret_229 = (int32x4_t)(__noswap_vshll_n_s16(__noswap_vget_high_s16(__rev0_229), __p1_229)); \ | |
| 60921 | __ret_229 = __builtin_shufflevector(__ret_229, __ret_229, 3, 2, 1, 0); \ | |
| 60922 | __ret_229; \ | |
| 64228 | #define vshll_high_n_s16(__p0_241, __p1_241) __extension__ ({ \ | |
| 64229 | int16x8_t __s0_241 = __p0_241; \ | |
| 64230 | int16x8_t __rev0_241; __rev0_241 = __builtin_shufflevector(__s0_241, __s0_241, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 64231 | int32x4_t __ret_241; \ | |
| 64232 | __ret_241 = (int32x4_t)(__noswap_vshll_n_s16(__noswap_vget_high_s16(__rev0_241), __p1_241)); \ | |
| 64233 | __ret_241 = __builtin_shufflevector(__ret_241, __ret_241, 3, 2, 1, 0); \ | |
| 64234 | __ret_241; \ | |
| 60923 | 64235 | }) |
| 60924 | 64236 | #endif |
| 60925 | 64237 | |
| ... | ... | @@ -60956,128 +64268,128 @@ __ai int64_t vshld_s64(int64_t __p0, int64_t __p1) { |
| 60956 | 64268 | #endif |
| 60957 | 64269 | |
| 60958 | 64270 | #ifdef __LITTLE_ENDIAN__ |
| 60959 | #define vshrn_high_n_u32(__p0_230, __p1_230, __p2_230) __extension__ ({ \ | |
| 60960 | uint16x4_t __s0_230 = __p0_230; \ | |
| 60961 | uint32x4_t __s1_230 = __p1_230; \ | |
| 60962 | uint16x8_t __ret_230; \ | |
| 60963 | __ret_230 = (uint16x8_t)(vcombine_u16((uint16x4_t)(__s0_230), (uint16x4_t)(vshrn_n_u32(__s1_230, __p2_230)))); \ | |
| 60964 | __ret_230; \ | |
| 64271 | #define vshrn_high_n_u32(__p0_242, __p1_242, __p2_242) __extension__ ({ \ | |
| 64272 | uint16x4_t __s0_242 = __p0_242; \ | |
| 64273 | uint32x4_t __s1_242 = __p1_242; \ | |
| 64274 | uint16x8_t __ret_242; \ | |
| 64275 | __ret_242 = (uint16x8_t)(vcombine_u16((uint16x4_t)(__s0_242), (uint16x4_t)(vshrn_n_u32(__s1_242, __p2_242)))); \ | |
| 64276 | __ret_242; \ | |
| 60965 | 64277 | }) |
| 60966 | 64278 | #else |
| 60967 | #define vshrn_high_n_u32(__p0_231, __p1_231, __p2_231) __extension__ ({ \ | |
| 60968 | uint16x4_t __s0_231 = __p0_231; \ | |
| 60969 | uint32x4_t __s1_231 = __p1_231; \ | |
| 60970 | uint16x4_t __rev0_231; __rev0_231 = __builtin_shufflevector(__s0_231, __s0_231, 3, 2, 1, 0); \ | |
| 60971 | uint32x4_t __rev1_231; __rev1_231 = __builtin_shufflevector(__s1_231, __s1_231, 3, 2, 1, 0); \ | |
| 60972 | uint16x8_t __ret_231; \ | |
| 60973 | __ret_231 = (uint16x8_t)(__noswap_vcombine_u16((uint16x4_t)(__rev0_231), (uint16x4_t)(__noswap_vshrn_n_u32(__rev1_231, __p2_231)))); \ | |
| 60974 | __ret_231 = __builtin_shufflevector(__ret_231, __ret_231, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 60975 | __ret_231; \ | |
| 64279 | #define vshrn_high_n_u32(__p0_243, __p1_243, __p2_243) __extension__ ({ \ | |
| 64280 | uint16x4_t __s0_243 = __p0_243; \ | |
| 64281 | uint32x4_t __s1_243 = __p1_243; \ | |
| 64282 | uint16x4_t __rev0_243; __rev0_243 = __builtin_shufflevector(__s0_243, __s0_243, 3, 2, 1, 0); \ | |
| 64283 | uint32x4_t __rev1_243; __rev1_243 = __builtin_shufflevector(__s1_243, __s1_243, 3, 2, 1, 0); \ | |
| 64284 | uint16x8_t __ret_243; \ | |
| 64285 | __ret_243 = (uint16x8_t)(__noswap_vcombine_u16((uint16x4_t)(__rev0_243), (uint16x4_t)(__noswap_vshrn_n_u32(__rev1_243, __p2_243)))); \ | |
| 64286 | __ret_243 = __builtin_shufflevector(__ret_243, __ret_243, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 64287 | __ret_243; \ | |
| 60976 | 64288 | }) |
| 60977 | 64289 | #endif |
| 60978 | 64290 | |
| 60979 | 64291 | #ifdef __LITTLE_ENDIAN__ |
| 60980 | #define vshrn_high_n_u64(__p0_232, __p1_232, __p2_232) __extension__ ({ \ | |
| 60981 | uint32x2_t __s0_232 = __p0_232; \ | |
| 60982 | uint64x2_t __s1_232 = __p1_232; \ | |
| 60983 | uint32x4_t __ret_232; \ | |
| 60984 | __ret_232 = (uint32x4_t)(vcombine_u32((uint32x2_t)(__s0_232), (uint32x2_t)(vshrn_n_u64(__s1_232, __p2_232)))); \ | |
| 60985 | __ret_232; \ | |
| 64292 | #define vshrn_high_n_u64(__p0_244, __p1_244, __p2_244) __extension__ ({ \ | |
| 64293 | uint32x2_t __s0_244 = __p0_244; \ | |
| 64294 | uint64x2_t __s1_244 = __p1_244; \ | |
| 64295 | uint32x4_t __ret_244; \ | |
| 64296 | __ret_244 = (uint32x4_t)(vcombine_u32((uint32x2_t)(__s0_244), (uint32x2_t)(vshrn_n_u64(__s1_244, __p2_244)))); \ | |
| 64297 | __ret_244; \ | |
| 60986 | 64298 | }) |
| 60987 | 64299 | #else |
| 60988 | #define vshrn_high_n_u64(__p0_233, __p1_233, __p2_233) __extension__ ({ \ | |
| 60989 | uint32x2_t __s0_233 = __p0_233; \ | |
| 60990 | uint64x2_t __s1_233 = __p1_233; \ | |
| 60991 | uint32x2_t __rev0_233; __rev0_233 = __builtin_shufflevector(__s0_233, __s0_233, 1, 0); \ | |
| 60992 | uint64x2_t __rev1_233; __rev1_233 = __builtin_shufflevector(__s1_233, __s1_233, 1, 0); \ | |
| 60993 | uint32x4_t __ret_233; \ | |
| 60994 | __ret_233 = (uint32x4_t)(__noswap_vcombine_u32((uint32x2_t)(__rev0_233), (uint32x2_t)(__noswap_vshrn_n_u64(__rev1_233, __p2_233)))); \ | |
| 60995 | __ret_233 = __builtin_shufflevector(__ret_233, __ret_233, 3, 2, 1, 0); \ | |
| 60996 | __ret_233; \ | |
| 64300 | #define vshrn_high_n_u64(__p0_245, __p1_245, __p2_245) __extension__ ({ \ | |
| 64301 | uint32x2_t __s0_245 = __p0_245; \ | |
| 64302 | uint64x2_t __s1_245 = __p1_245; \ | |
| 64303 | uint32x2_t __rev0_245; __rev0_245 = __builtin_shufflevector(__s0_245, __s0_245, 1, 0); \ | |
| 64304 | uint64x2_t __rev1_245; __rev1_245 = __builtin_shufflevector(__s1_245, __s1_245, 1, 0); \ | |
| 64305 | uint32x4_t __ret_245; \ | |
| 64306 | __ret_245 = (uint32x4_t)(__noswap_vcombine_u32((uint32x2_t)(__rev0_245), (uint32x2_t)(__noswap_vshrn_n_u64(__rev1_245, __p2_245)))); \ | |
| 64307 | __ret_245 = __builtin_shufflevector(__ret_245, __ret_245, 3, 2, 1, 0); \ | |
| 64308 | __ret_245; \ | |
| 60997 | 64309 | }) |
| 60998 | 64310 | #endif |
| 60999 | 64311 | |
| 61000 | 64312 | #ifdef __LITTLE_ENDIAN__ |
| 61001 | #define vshrn_high_n_u16(__p0_234, __p1_234, __p2_234) __extension__ ({ \ | |
| 61002 | uint8x8_t __s0_234 = __p0_234; \ | |
| 61003 | uint16x8_t __s1_234 = __p1_234; \ | |
| 61004 | uint8x16_t __ret_234; \ | |
| 61005 | __ret_234 = (uint8x16_t)(vcombine_u8((uint8x8_t)(__s0_234), (uint8x8_t)(vshrn_n_u16(__s1_234, __p2_234)))); \ | |
| 61006 | __ret_234; \ | |
| 64313 | #define vshrn_high_n_u16(__p0_246, __p1_246, __p2_246) __extension__ ({ \ | |
| 64314 | uint8x8_t __s0_246 = __p0_246; \ | |
| 64315 | uint16x8_t __s1_246 = __p1_246; \ | |
| 64316 | uint8x16_t __ret_246; \ | |
| 64317 | __ret_246 = (uint8x16_t)(vcombine_u8((uint8x8_t)(__s0_246), (uint8x8_t)(vshrn_n_u16(__s1_246, __p2_246)))); \ | |
| 64318 | __ret_246; \ | |
| 61007 | 64319 | }) |
| 61008 | 64320 | #else |
| 61009 | #define vshrn_high_n_u16(__p0_235, __p1_235, __p2_235) __extension__ ({ \ | |
| 61010 | uint8x8_t __s0_235 = __p0_235; \ | |
| 61011 | uint16x8_t __s1_235 = __p1_235; \ | |
| 61012 | uint8x8_t __rev0_235; __rev0_235 = __builtin_shufflevector(__s0_235, __s0_235, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61013 | uint16x8_t __rev1_235; __rev1_235 = __builtin_shufflevector(__s1_235, __s1_235, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61014 | uint8x16_t __ret_235; \ | |
| 61015 | __ret_235 = (uint8x16_t)(__noswap_vcombine_u8((uint8x8_t)(__rev0_235), (uint8x8_t)(__noswap_vshrn_n_u16(__rev1_235, __p2_235)))); \ | |
| 61016 | __ret_235 = __builtin_shufflevector(__ret_235, __ret_235, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61017 | __ret_235; \ | |
| 64321 | #define vshrn_high_n_u16(__p0_247, __p1_247, __p2_247) __extension__ ({ \ | |
| 64322 | uint8x8_t __s0_247 = __p0_247; \ | |
| 64323 | uint16x8_t __s1_247 = __p1_247; \ | |
| 64324 | uint8x8_t __rev0_247; __rev0_247 = __builtin_shufflevector(__s0_247, __s0_247, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 64325 | uint16x8_t __rev1_247; __rev1_247 = __builtin_shufflevector(__s1_247, __s1_247, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 64326 | uint8x16_t __ret_247; \ | |
| 64327 | __ret_247 = (uint8x16_t)(__noswap_vcombine_u8((uint8x8_t)(__rev0_247), (uint8x8_t)(__noswap_vshrn_n_u16(__rev1_247, __p2_247)))); \ | |
| 64328 | __ret_247 = __builtin_shufflevector(__ret_247, __ret_247, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 64329 | __ret_247; \ | |
| 61018 | 64330 | }) |
| 61019 | 64331 | #endif |
| 61020 | 64332 | |
| 61021 | 64333 | #ifdef __LITTLE_ENDIAN__ |
| 61022 | #define vshrn_high_n_s32(__p0_236, __p1_236, __p2_236) __extension__ ({ \ | |
| 61023 | int16x4_t __s0_236 = __p0_236; \ | |
| 61024 | int32x4_t __s1_236 = __p1_236; \ | |
| 61025 | int16x8_t __ret_236; \ | |
| 61026 | __ret_236 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_236), (int16x4_t)(vshrn_n_s32(__s1_236, __p2_236)))); \ | |
| 61027 | __ret_236; \ | |
| 64334 | #define vshrn_high_n_s32(__p0_248, __p1_248, __p2_248) __extension__ ({ \ | |
| 64335 | int16x4_t __s0_248 = __p0_248; \ | |
| 64336 | int32x4_t __s1_248 = __p1_248; \ | |
| 64337 | int16x8_t __ret_248; \ | |
| 64338 | __ret_248 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_248), (int16x4_t)(vshrn_n_s32(__s1_248, __p2_248)))); \ | |
| 64339 | __ret_248; \ | |
| 61028 | 64340 | }) |
| 61029 | 64341 | #else |
| 61030 | #define vshrn_high_n_s32(__p0_237, __p1_237, __p2_237) __extension__ ({ \ | |
| 61031 | int16x4_t __s0_237 = __p0_237; \ | |
| 61032 | int32x4_t __s1_237 = __p1_237; \ | |
| 61033 | int16x4_t __rev0_237; __rev0_237 = __builtin_shufflevector(__s0_237, __s0_237, 3, 2, 1, 0); \ | |
| 61034 | int32x4_t __rev1_237; __rev1_237 = __builtin_shufflevector(__s1_237, __s1_237, 3, 2, 1, 0); \ | |
| 61035 | int16x8_t __ret_237; \ | |
| 61036 | __ret_237 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_237), (int16x4_t)(__noswap_vshrn_n_s32(__rev1_237, __p2_237)))); \ | |
| 61037 | __ret_237 = __builtin_shufflevector(__ret_237, __ret_237, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61038 | __ret_237; \ | |
| 64342 | #define vshrn_high_n_s32(__p0_249, __p1_249, __p2_249) __extension__ ({ \ | |
| 64343 | int16x4_t __s0_249 = __p0_249; \ | |
| 64344 | int32x4_t __s1_249 = __p1_249; \ | |
| 64345 | int16x4_t __rev0_249; __rev0_249 = __builtin_shufflevector(__s0_249, __s0_249, 3, 2, 1, 0); \ | |
| 64346 | int32x4_t __rev1_249; __rev1_249 = __builtin_shufflevector(__s1_249, __s1_249, 3, 2, 1, 0); \ | |
| 64347 | int16x8_t __ret_249; \ | |
| 64348 | __ret_249 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_249), (int16x4_t)(__noswap_vshrn_n_s32(__rev1_249, __p2_249)))); \ | |
| 64349 | __ret_249 = __builtin_shufflevector(__ret_249, __ret_249, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 64350 | __ret_249; \ | |
| 61039 | 64351 | }) |
| 61040 | 64352 | #endif |
| 61041 | 64353 | |
| 61042 | 64354 | #ifdef __LITTLE_ENDIAN__ |
| 61043 | #define vshrn_high_n_s64(__p0_238, __p1_238, __p2_238) __extension__ ({ \ | |
| 61044 | int32x2_t __s0_238 = __p0_238; \ | |
| 61045 | int64x2_t __s1_238 = __p1_238; \ | |
| 61046 | int32x4_t __ret_238; \ | |
| 61047 | __ret_238 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_238), (int32x2_t)(vshrn_n_s64(__s1_238, __p2_238)))); \ | |
| 61048 | __ret_238; \ | |
| 64355 | #define vshrn_high_n_s64(__p0_250, __p1_250, __p2_250) __extension__ ({ \ | |
| 64356 | int32x2_t __s0_250 = __p0_250; \ | |
| 64357 | int64x2_t __s1_250 = __p1_250; \ | |
| 64358 | int32x4_t __ret_250; \ | |
| 64359 | __ret_250 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_250), (int32x2_t)(vshrn_n_s64(__s1_250, __p2_250)))); \ | |
| 64360 | __ret_250; \ | |
| 61049 | 64361 | }) |
| 61050 | 64362 | #else |
| 61051 | #define vshrn_high_n_s64(__p0_239, __p1_239, __p2_239) __extension__ ({ \ | |
| 61052 | int32x2_t __s0_239 = __p0_239; \ | |
| 61053 | int64x2_t __s1_239 = __p1_239; \ | |
| 61054 | int32x2_t __rev0_239; __rev0_239 = __builtin_shufflevector(__s0_239, __s0_239, 1, 0); \ | |
| 61055 | int64x2_t __rev1_239; __rev1_239 = __builtin_shufflevector(__s1_239, __s1_239, 1, 0); \ | |
| 61056 | int32x4_t __ret_239; \ | |
| 61057 | __ret_239 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_239), (int32x2_t)(__noswap_vshrn_n_s64(__rev1_239, __p2_239)))); \ | |
| 61058 | __ret_239 = __builtin_shufflevector(__ret_239, __ret_239, 3, 2, 1, 0); \ | |
| 61059 | __ret_239; \ | |
| 64363 | #define vshrn_high_n_s64(__p0_251, __p1_251, __p2_251) __extension__ ({ \ | |
| 64364 | int32x2_t __s0_251 = __p0_251; \ | |
| 64365 | int64x2_t __s1_251 = __p1_251; \ | |
| 64366 | int32x2_t __rev0_251; __rev0_251 = __builtin_shufflevector(__s0_251, __s0_251, 1, 0); \ | |
| 64367 | int64x2_t __rev1_251; __rev1_251 = __builtin_shufflevector(__s1_251, __s1_251, 1, 0); \ | |
| 64368 | int32x4_t __ret_251; \ | |
| 64369 | __ret_251 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_251), (int32x2_t)(__noswap_vshrn_n_s64(__rev1_251, __p2_251)))); \ | |
| 64370 | __ret_251 = __builtin_shufflevector(__ret_251, __ret_251, 3, 2, 1, 0); \ | |
| 64371 | __ret_251; \ | |
| 61060 | 64372 | }) |
| 61061 | 64373 | #endif |
| 61062 | 64374 | |
| 61063 | 64375 | #ifdef __LITTLE_ENDIAN__ |
| 61064 | #define vshrn_high_n_s16(__p0_240, __p1_240, __p2_240) __extension__ ({ \ | |
| 61065 | int8x8_t __s0_240 = __p0_240; \ | |
| 61066 | int16x8_t __s1_240 = __p1_240; \ | |
| 61067 | int8x16_t __ret_240; \ | |
| 61068 | __ret_240 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_240), (int8x8_t)(vshrn_n_s16(__s1_240, __p2_240)))); \ | |
| 61069 | __ret_240; \ | |
| 64376 | #define vshrn_high_n_s16(__p0_252, __p1_252, __p2_252) __extension__ ({ \ | |
| 64377 | int8x8_t __s0_252 = __p0_252; \ | |
| 64378 | int16x8_t __s1_252 = __p1_252; \ | |
| 64379 | int8x16_t __ret_252; \ | |
| 64380 | __ret_252 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_252), (int8x8_t)(vshrn_n_s16(__s1_252, __p2_252)))); \ | |
| 64381 | __ret_252; \ | |
| 61070 | 64382 | }) |
| 61071 | 64383 | #else |
| 61072 | #define vshrn_high_n_s16(__p0_241, __p1_241, __p2_241) __extension__ ({ \ | |
| 61073 | int8x8_t __s0_241 = __p0_241; \ | |
| 61074 | int16x8_t __s1_241 = __p1_241; \ | |
| 61075 | int8x8_t __rev0_241; __rev0_241 = __builtin_shufflevector(__s0_241, __s0_241, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61076 | int16x8_t __rev1_241; __rev1_241 = __builtin_shufflevector(__s1_241, __s1_241, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61077 | int8x16_t __ret_241; \ | |
| 61078 | __ret_241 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_241), (int8x8_t)(__noswap_vshrn_n_s16(__rev1_241, __p2_241)))); \ | |
| 61079 | __ret_241 = __builtin_shufflevector(__ret_241, __ret_241, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 61080 | __ret_241; \ | |
| 64384 | #define vshrn_high_n_s16(__p0_253, __p1_253, __p2_253) __extension__ ({ \ | |
| 64385 | int8x8_t __s0_253 = __p0_253; \ | |
| 64386 | int16x8_t __s1_253 = __p1_253; \ | |
| 64387 | int8x8_t __rev0_253; __rev0_253 = __builtin_shufflevector(__s0_253, __s0_253, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 64388 | int16x8_t __rev1_253; __rev1_253 = __builtin_shufflevector(__s1_253, __s1_253, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 64389 | int8x16_t __ret_253; \ | |
| 64390 | __ret_253 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_253), (int8x8_t)(__noswap_vshrn_n_s16(__rev1_253, __p2_253)))); \ | |
| 64391 | __ret_253 = __builtin_shufflevector(__ret_253, __ret_253, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 64392 | __ret_253; \ | |
| 61081 | 64393 | }) |
| 61082 | 64394 | #endif |
| 61083 | 64395 | |
| ... | ... | @@ -67149,44 +70461,60 @@ __ai int32x4_t vaddw_s16(int32x4_t __p0, int16x4_t __p1) { |
| 67149 | 70461 | #endif |
| 67150 | 70462 | |
| 67151 | 70463 | #ifdef __LITTLE_ENDIAN__ |
| 67152 | #define vget_lane_f16(__p0_242, __p1_242) __extension__ ({ \ | |
| 67153 | float16x4_t __s0_242 = __p0_242; \ | |
| 67154 | float16_t __ret_242; \ | |
| 67155 | float16x4_t __reint_242 = __s0_242; \ | |
| 67156 | int16_t __reint1_242 = vget_lane_s16(*(int16x4_t *) &__reint_242, __p1_242); \ | |
| 67157 | __ret_242 = *(float16_t *) &__reint1_242; \ | |
| 67158 | __ret_242; \ | |
| 70464 | #define vget_lane_f16(__p0_254, __p1_254) __extension__ ({ \ | |
| 70465 | float16x4_t __s0_254 = __p0_254; \ | |
| 70466 | float16_t __ret_254; \ | |
| 70467 | float16x4_t __reint_254 = __s0_254; \ | |
| 70468 | int16_t __reint1_254 = vget_lane_s16(*(int16x4_t *) &__reint_254, __p1_254); \ | |
| 70469 | __ret_254 = *(float16_t *) &__reint1_254; \ | |
| 70470 | __ret_254; \ | |
| 67159 | 70471 | }) |
| 67160 | 70472 | #else |
| 67161 | #define vget_lane_f16(__p0_243, __p1_243) __extension__ ({ \ | |
| 67162 | float16x4_t __s0_243 = __p0_243; \ | |
| 67163 | float16x4_t __rev0_243; __rev0_243 = __builtin_shufflevector(__s0_243, __s0_243, 3, 2, 1, 0); \ | |
| 67164 | float16_t __ret_243; \ | |
| 67165 | float16x4_t __reint_243 = __rev0_243; \ | |
| 67166 | int16_t __reint1_243 = __noswap_vget_lane_s16(*(int16x4_t *) &__reint_243, __p1_243); \ | |
| 67167 | __ret_243 = *(float16_t *) &__reint1_243; \ | |
| 67168 | __ret_243; \ | |
| 70473 | #define vget_lane_f16(__p0_255, __p1_255) __extension__ ({ \ | |
| 70474 | float16x4_t __s0_255 = __p0_255; \ | |
| 70475 | float16x4_t __rev0_255; __rev0_255 = __builtin_shufflevector(__s0_255, __s0_255, 3, 2, 1, 0); \ | |
| 70476 | float16_t __ret_255; \ | |
| 70477 | float16x4_t __reint_255 = __rev0_255; \ | |
| 70478 | int16_t __reint1_255 = __noswap_vget_lane_s16(*(int16x4_t *) &__reint_255, __p1_255); \ | |
| 70479 | __ret_255 = *(float16_t *) &__reint1_255; \ | |
| 70480 | __ret_255; \ | |
| 70481 | }) | |
| 70482 | #define __noswap_vget_lane_f16(__p0_256, __p1_256) __extension__ ({ \ | |
| 70483 | float16x4_t __s0_256 = __p0_256; \ | |
| 70484 | float16_t __ret_256; \ | |
| 70485 | float16x4_t __reint_256 = __s0_256; \ | |
| 70486 | int16_t __reint1_256 = __noswap_vget_lane_s16(*(int16x4_t *) &__reint_256, __p1_256); \ | |
| 70487 | __ret_256 = *(float16_t *) &__reint1_256; \ | |
| 70488 | __ret_256; \ | |
| 67169 | 70489 | }) |
| 67170 | 70490 | #endif |
| 67171 | 70491 | |
| 67172 | 70492 | #ifdef __LITTLE_ENDIAN__ |
| 67173 | #define vgetq_lane_f16(__p0_244, __p1_244) __extension__ ({ \ | |
| 67174 | float16x8_t __s0_244 = __p0_244; \ | |
| 67175 | float16_t __ret_244; \ | |
| 67176 | float16x8_t __reint_244 = __s0_244; \ | |
| 67177 | int16_t __reint1_244 = vgetq_lane_s16(*(int16x8_t *) &__reint_244, __p1_244); \ | |
| 67178 | __ret_244 = *(float16_t *) &__reint1_244; \ | |
| 67179 | __ret_244; \ | |
| 70493 | #define vgetq_lane_f16(__p0_257, __p1_257) __extension__ ({ \ | |
| 70494 | float16x8_t __s0_257 = __p0_257; \ | |
| 70495 | float16_t __ret_257; \ | |
| 70496 | float16x8_t __reint_257 = __s0_257; \ | |
| 70497 | int16_t __reint1_257 = vgetq_lane_s16(*(int16x8_t *) &__reint_257, __p1_257); \ | |
| 70498 | __ret_257 = *(float16_t *) &__reint1_257; \ | |
| 70499 | __ret_257; \ | |
| 67180 | 70500 | }) |
| 67181 | 70501 | #else |
| 67182 | #define vgetq_lane_f16(__p0_245, __p1_245) __extension__ ({ \ | |
| 67183 | float16x8_t __s0_245 = __p0_245; \ | |
| 67184 | float16x8_t __rev0_245; __rev0_245 = __builtin_shufflevector(__s0_245, __s0_245, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 67185 | float16_t __ret_245; \ | |
| 67186 | float16x8_t __reint_245 = __rev0_245; \ | |
| 67187 | int16_t __reint1_245 = __noswap_vgetq_lane_s16(*(int16x8_t *) &__reint_245, __p1_245); \ | |
| 67188 | __ret_245 = *(float16_t *) &__reint1_245; \ | |
| 67189 | __ret_245; \ | |
| 70502 | #define vgetq_lane_f16(__p0_258, __p1_258) __extension__ ({ \ | |
| 70503 | float16x8_t __s0_258 = __p0_258; \ | |
| 70504 | float16x8_t __rev0_258; __rev0_258 = __builtin_shufflevector(__s0_258, __s0_258, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 70505 | float16_t __ret_258; \ | |
| 70506 | float16x8_t __reint_258 = __rev0_258; \ | |
| 70507 | int16_t __reint1_258 = __noswap_vgetq_lane_s16(*(int16x8_t *) &__reint_258, __p1_258); \ | |
| 70508 | __ret_258 = *(float16_t *) &__reint1_258; \ | |
| 70509 | __ret_258; \ | |
| 70510 | }) | |
| 70511 | #define __noswap_vgetq_lane_f16(__p0_259, __p1_259) __extension__ ({ \ | |
| 70512 | float16x8_t __s0_259 = __p0_259; \ | |
| 70513 | float16_t __ret_259; \ | |
| 70514 | float16x8_t __reint_259 = __s0_259; \ | |
| 70515 | int16_t __reint1_259 = __noswap_vgetq_lane_s16(*(int16x8_t *) &__reint_259, __p1_259); \ | |
| 70516 | __ret_259 = *(float16_t *) &__reint1_259; \ | |
| 70517 | __ret_259; \ | |
| 67190 | 70518 | }) |
| 67191 | 70519 | #endif |
| 67192 | 70520 | |
| ... | ... | @@ -67835,57 +71163,97 @@ __ai int32x4_t __noswap_vmlsl_n_s16(int32x4_t __p0, int16x4_t __p1, int16_t __p2 |
| 67835 | 71163 | #endif |
| 67836 | 71164 | |
| 67837 | 71165 | #ifdef __LITTLE_ENDIAN__ |
| 67838 | #define vset_lane_f16(__p0_246, __p1_246, __p2_246) __extension__ ({ \ | |
| 67839 | float16_t __s0_246 = __p0_246; \ | |
| 67840 | float16x4_t __s1_246 = __p1_246; \ | |
| 67841 | float16x4_t __ret_246; \ | |
| 67842 | float16_t __reint_246 = __s0_246; \ | |
| 67843 | float16x4_t __reint1_246 = __s1_246; \ | |
| 67844 | int16x4_t __reint2_246 = vset_lane_s16(*(int16_t *) &__reint_246, *(int16x4_t *) &__reint1_246, __p2_246); \ | |
| 67845 | __ret_246 = *(float16x4_t *) &__reint2_246; \ | |
| 67846 | __ret_246; \ | |
| 71166 | #define vset_lane_f16(__p0_260, __p1_260, __p2_260) __extension__ ({ \ | |
| 71167 | float16_t __s0_260 = __p0_260; \ | |
| 71168 | float16x4_t __s1_260 = __p1_260; \ | |
| 71169 | float16x4_t __ret_260; \ | |
| 71170 | float16_t __reint_260 = __s0_260; \ | |
| 71171 | float16x4_t __reint1_260 = __s1_260; \ | |
| 71172 | int16x4_t __reint2_260 = vset_lane_s16(*(int16_t *) &__reint_260, *(int16x4_t *) &__reint1_260, __p2_260); \ | |
| 71173 | __ret_260 = *(float16x4_t *) &__reint2_260; \ | |
| 71174 | __ret_260; \ | |
| 67847 | 71175 | }) |
| 67848 | 71176 | #else |
| 67849 | #define vset_lane_f16(__p0_247, __p1_247, __p2_247) __extension__ ({ \ | |
| 67850 | float16_t __s0_247 = __p0_247; \ | |
| 67851 | float16x4_t __s1_247 = __p1_247; \ | |
| 67852 | float16x4_t __rev1_247; __rev1_247 = __builtin_shufflevector(__s1_247, __s1_247, 3, 2, 1, 0); \ | |
| 67853 | float16x4_t __ret_247; \ | |
| 67854 | float16_t __reint_247 = __s0_247; \ | |
| 67855 | float16x4_t __reint1_247 = __rev1_247; \ | |
| 67856 | int16x4_t __reint2_247 = __noswap_vset_lane_s16(*(int16_t *) &__reint_247, *(int16x4_t *) &__reint1_247, __p2_247); \ | |
| 67857 | __ret_247 = *(float16x4_t *) &__reint2_247; \ | |
| 67858 | __ret_247 = __builtin_shufflevector(__ret_247, __ret_247, 3, 2, 1, 0); \ | |
| 67859 | __ret_247; \ | |
| 71177 | #define vset_lane_f16(__p0_261, __p1_261, __p2_261) __extension__ ({ \ | |
| 71178 | float16_t __s0_261 = __p0_261; \ | |
| 71179 | float16x4_t __s1_261 = __p1_261; \ | |
| 71180 | float16x4_t __rev1_261; __rev1_261 = __builtin_shufflevector(__s1_261, __s1_261, 3, 2, 1, 0); \ | |
| 71181 | float16x4_t __ret_261; \ | |
| 71182 | float16_t __reint_261 = __s0_261; \ | |
| 71183 | float16x4_t __reint1_261 = __rev1_261; \ | |
| 71184 | int16x4_t __reint2_261 = __noswap_vset_lane_s16(*(int16_t *) &__reint_261, *(int16x4_t *) &__reint1_261, __p2_261); \ | |
| 71185 | __ret_261 = *(float16x4_t *) &__reint2_261; \ | |
| 71186 | __ret_261 = __builtin_shufflevector(__ret_261, __ret_261, 3, 2, 1, 0); \ | |
| 71187 | __ret_261; \ | |
| 67860 | 71188 | }) |
| 67861 | 71189 | #endif |
| 67862 | 71190 | |
| 67863 | 71191 | #ifdef __LITTLE_ENDIAN__ |
| 67864 | #define vsetq_lane_f16(__p0_248, __p1_248, __p2_248) __extension__ ({ \ | |
| 67865 | float16_t __s0_248 = __p0_248; \ | |
| 67866 | float16x8_t __s1_248 = __p1_248; \ | |
| 67867 | float16x8_t __ret_248; \ | |
| 67868 | float16_t __reint_248 = __s0_248; \ | |
| 67869 | float16x8_t __reint1_248 = __s1_248; \ | |
| 67870 | int16x8_t __reint2_248 = vsetq_lane_s16(*(int16_t *) &__reint_248, *(int16x8_t *) &__reint1_248, __p2_248); \ | |
| 67871 | __ret_248 = *(float16x8_t *) &__reint2_248; \ | |
| 67872 | __ret_248; \ | |
| 71192 | #define vsetq_lane_f16(__p0_262, __p1_262, __p2_262) __extension__ ({ \ | |
| 71193 | float16_t __s0_262 = __p0_262; \ | |
| 71194 | float16x8_t __s1_262 = __p1_262; \ | |
| 71195 | float16x8_t __ret_262; \ | |
| 71196 | float16_t __reint_262 = __s0_262; \ | |
| 71197 | float16x8_t __reint1_262 = __s1_262; \ | |
| 71198 | int16x8_t __reint2_262 = vsetq_lane_s16(*(int16_t *) &__reint_262, *(int16x8_t *) &__reint1_262, __p2_262); \ | |
| 71199 | __ret_262 = *(float16x8_t *) &__reint2_262; \ | |
| 71200 | __ret_262; \ | |
| 67873 | 71201 | }) |
| 67874 | 71202 | #else |
| 67875 | #define vsetq_lane_f16(__p0_249, __p1_249, __p2_249) __extension__ ({ \ | |
| 67876 | float16_t __s0_249 = __p0_249; \ | |
| 67877 | float16x8_t __s1_249 = __p1_249; \ | |
| 67878 | float16x8_t __rev1_249; __rev1_249 = __builtin_shufflevector(__s1_249, __s1_249, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 67879 | float16x8_t __ret_249; \ | |
| 67880 | float16_t __reint_249 = __s0_249; \ | |
| 67881 | float16x8_t __reint1_249 = __rev1_249; \ | |
| 67882 | int16x8_t __reint2_249 = __noswap_vsetq_lane_s16(*(int16_t *) &__reint_249, *(int16x8_t *) &__reint1_249, __p2_249); \ | |
| 67883 | __ret_249 = *(float16x8_t *) &__reint2_249; \ | |
| 67884 | __ret_249 = __builtin_shufflevector(__ret_249, __ret_249, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 67885 | __ret_249; \ | |
| 71203 | #define vsetq_lane_f16(__p0_263, __p1_263, __p2_263) __extension__ ({ \ | |
| 71204 | float16_t __s0_263 = __p0_263; \ | |
| 71205 | float16x8_t __s1_263 = __p1_263; \ | |
| 71206 | float16x8_t __rev1_263; __rev1_263 = __builtin_shufflevector(__s1_263, __s1_263, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 71207 | float16x8_t __ret_263; \ | |
| 71208 | float16_t __reint_263 = __s0_263; \ | |
| 71209 | float16x8_t __reint1_263 = __rev1_263; \ | |
| 71210 | int16x8_t __reint2_263 = __noswap_vsetq_lane_s16(*(int16_t *) &__reint_263, *(int16x8_t *) &__reint1_263, __p2_263); \ | |
| 71211 | __ret_263 = *(float16x8_t *) &__reint2_263; \ | |
| 71212 | __ret_263 = __builtin_shufflevector(__ret_263, __ret_263, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 71213 | __ret_263; \ | |
| 71214 | }) | |
| 71215 | #endif | |
| 71216 | ||
| 71217 | #if defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarch64__) | |
| 71218 | #ifdef __LITTLE_ENDIAN__ | |
| 71219 | #define vmulh_lane_f16(__p0_264, __p1_264, __p2_264) __extension__ ({ \ | |
| 71220 | float16_t __s0_264 = __p0_264; \ | |
| 71221 | float16x4_t __s1_264 = __p1_264; \ | |
| 71222 | float16_t __ret_264; \ | |
| 71223 | __ret_264 = __s0_264 * vget_lane_f16(__s1_264, __p2_264); \ | |
| 71224 | __ret_264; \ | |
| 71225 | }) | |
| 71226 | #else | |
| 71227 | #define vmulh_lane_f16(__p0_265, __p1_265, __p2_265) __extension__ ({ \ | |
| 71228 | float16_t __s0_265 = __p0_265; \ | |
| 71229 | float16x4_t __s1_265 = __p1_265; \ | |
| 71230 | float16x4_t __rev1_265; __rev1_265 = __builtin_shufflevector(__s1_265, __s1_265, 3, 2, 1, 0); \ | |
| 71231 | float16_t __ret_265; \ | |
| 71232 | __ret_265 = __s0_265 * __noswap_vget_lane_f16(__rev1_265, __p2_265); \ | |
| 71233 | __ret_265; \ | |
| 71234 | }) | |
| 71235 | #endif | |
| 71236 | ||
| 71237 | #ifdef __LITTLE_ENDIAN__ | |
| 71238 | #define vmulh_laneq_f16(__p0_266, __p1_266, __p2_266) __extension__ ({ \ | |
| 71239 | float16_t __s0_266 = __p0_266; \ | |
| 71240 | float16x8_t __s1_266 = __p1_266; \ | |
| 71241 | float16_t __ret_266; \ | |
| 71242 | __ret_266 = __s0_266 * vgetq_lane_f16(__s1_266, __p2_266); \ | |
| 71243 | __ret_266; \ | |
| 71244 | }) | |
| 71245 | #else | |
| 71246 | #define vmulh_laneq_f16(__p0_267, __p1_267, __p2_267) __extension__ ({ \ | |
| 71247 | float16_t __s0_267 = __p0_267; \ | |
| 71248 | float16x8_t __s1_267 = __p1_267; \ | |
| 71249 | float16x8_t __rev1_267; __rev1_267 = __builtin_shufflevector(__s1_267, __s1_267, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 71250 | float16_t __ret_267; \ | |
| 71251 | __ret_267 = __s0_267 * __noswap_vgetq_lane_f16(__rev1_267, __p2_267); \ | |
| 71252 | __ret_267; \ | |
| 67886 | 71253 | }) |
| 67887 | 71254 | #endif |
| 67888 | 71255 | |
| 71256 | #endif | |
| 67889 | 71257 | #if defined(__ARM_FEATURE_QRDMX) && defined(__aarch64__) |
| 67890 | 71258 | #ifdef __LITTLE_ENDIAN__ |
| 67891 | 71259 | __ai int32_t vqrdmlahs_s32(int32_t __p0, int32_t __p1, int32_t __p2) { |
| ... | ... | @@ -67916,86 +71284,86 @@ __ai int16_t vqrdmlahh_s16(int16_t __p0, int16_t __p1, int16_t __p2) { |
| 67916 | 71284 | #endif |
| 67917 | 71285 | |
| 67918 | 71286 | #ifdef __LITTLE_ENDIAN__ |
| 67919 | #define vqrdmlahs_lane_s32(__p0_250, __p1_250, __p2_250, __p3_250) __extension__ ({ \ | |
| 67920 | int32_t __s0_250 = __p0_250; \ | |
| 67921 | int32_t __s1_250 = __p1_250; \ | |
| 67922 | int32x2_t __s2_250 = __p2_250; \ | |
| 67923 | int32_t __ret_250; \ | |
| 67924 | __ret_250 = vqadds_s32(__s0_250, vqrdmulhs_s32(__s1_250, vget_lane_s32(__s2_250, __p3_250))); \ | |
| 67925 | __ret_250; \ | |
| 71287 | #define vqrdmlahs_lane_s32(__p0_268, __p1_268, __p2_268, __p3_268) __extension__ ({ \ | |
| 71288 | int32_t __s0_268 = __p0_268; \ | |
| 71289 | int32_t __s1_268 = __p1_268; \ | |
| 71290 | int32x2_t __s2_268 = __p2_268; \ | |
| 71291 | int32_t __ret_268; \ | |
| 71292 | __ret_268 = vqadds_s32(__s0_268, vqrdmulhs_s32(__s1_268, vget_lane_s32(__s2_268, __p3_268))); \ | |
| 71293 | __ret_268; \ | |
| 67926 | 71294 | }) |
| 67927 | 71295 | #else |
| 67928 | #define vqrdmlahs_lane_s32(__p0_251, __p1_251, __p2_251, __p3_251) __extension__ ({ \ | |
| 67929 | int32_t __s0_251 = __p0_251; \ | |
| 67930 | int32_t __s1_251 = __p1_251; \ | |
| 67931 | int32x2_t __s2_251 = __p2_251; \ | |
| 67932 | int32x2_t __rev2_251; __rev2_251 = __builtin_shufflevector(__s2_251, __s2_251, 1, 0); \ | |
| 67933 | int32_t __ret_251; \ | |
| 67934 | __ret_251 = __noswap_vqadds_s32(__s0_251, __noswap_vqrdmulhs_s32(__s1_251, __noswap_vget_lane_s32(__rev2_251, __p3_251))); \ | |
| 67935 | __ret_251; \ | |
| 71296 | #define vqrdmlahs_lane_s32(__p0_269, __p1_269, __p2_269, __p3_269) __extension__ ({ \ | |
| 71297 | int32_t __s0_269 = __p0_269; \ | |
| 71298 | int32_t __s1_269 = __p1_269; \ | |
| 71299 | int32x2_t __s2_269 = __p2_269; \ | |
| 71300 | int32x2_t __rev2_269; __rev2_269 = __builtin_shufflevector(__s2_269, __s2_269, 1, 0); \ | |
| 71301 | int32_t __ret_269; \ | |
| 71302 | __ret_269 = __noswap_vqadds_s32(__s0_269, __noswap_vqrdmulhs_s32(__s1_269, __noswap_vget_lane_s32(__rev2_269, __p3_269))); \ | |
| 71303 | __ret_269; \ | |
| 67936 | 71304 | }) |
| 67937 | 71305 | #endif |
| 67938 | 71306 | |
| 67939 | 71307 | #ifdef __LITTLE_ENDIAN__ |
| 67940 | #define vqrdmlahh_lane_s16(__p0_252, __p1_252, __p2_252, __p3_252) __extension__ ({ \ | |
| 67941 | int16_t __s0_252 = __p0_252; \ | |
| 67942 | int16_t __s1_252 = __p1_252; \ | |
| 67943 | int16x4_t __s2_252 = __p2_252; \ | |
| 67944 | int16_t __ret_252; \ | |
| 67945 | __ret_252 = vqaddh_s16(__s0_252, vqrdmulhh_s16(__s1_252, vget_lane_s16(__s2_252, __p3_252))); \ | |
| 67946 | __ret_252; \ | |
| 71308 | #define vqrdmlahh_lane_s16(__p0_270, __p1_270, __p2_270, __p3_270) __extension__ ({ \ | |
| 71309 | int16_t __s0_270 = __p0_270; \ | |
| 71310 | int16_t __s1_270 = __p1_270; \ | |
| 71311 | int16x4_t __s2_270 = __p2_270; \ | |
| 71312 | int16_t __ret_270; \ | |
| 71313 | __ret_270 = vqaddh_s16(__s0_270, vqrdmulhh_s16(__s1_270, vget_lane_s16(__s2_270, __p3_270))); \ | |
| 71314 | __ret_270; \ | |
| 67947 | 71315 | }) |
| 67948 | 71316 | #else |
| 67949 | #define vqrdmlahh_lane_s16(__p0_253, __p1_253, __p2_253, __p3_253) __extension__ ({ \ | |
| 67950 | int16_t __s0_253 = __p0_253; \ | |
| 67951 | int16_t __s1_253 = __p1_253; \ | |
| 67952 | int16x4_t __s2_253 = __p2_253; \ | |
| 67953 | int16x4_t __rev2_253; __rev2_253 = __builtin_shufflevector(__s2_253, __s2_253, 3, 2, 1, 0); \ | |
| 67954 | int16_t __ret_253; \ | |
| 67955 | __ret_253 = __noswap_vqaddh_s16(__s0_253, __noswap_vqrdmulhh_s16(__s1_253, __noswap_vget_lane_s16(__rev2_253, __p3_253))); \ | |
| 67956 | __ret_253; \ | |
| 71317 | #define vqrdmlahh_lane_s16(__p0_271, __p1_271, __p2_271, __p3_271) __extension__ ({ \ | |
| 71318 | int16_t __s0_271 = __p0_271; \ | |
| 71319 | int16_t __s1_271 = __p1_271; \ | |
| 71320 | int16x4_t __s2_271 = __p2_271; \ | |
| 71321 | int16x4_t __rev2_271; __rev2_271 = __builtin_shufflevector(__s2_271, __s2_271, 3, 2, 1, 0); \ | |
| 71322 | int16_t __ret_271; \ | |
| 71323 | __ret_271 = __noswap_vqaddh_s16(__s0_271, __noswap_vqrdmulhh_s16(__s1_271, __noswap_vget_lane_s16(__rev2_271, __p3_271))); \ | |
| 71324 | __ret_271; \ | |
| 67957 | 71325 | }) |
| 67958 | 71326 | #endif |
| 67959 | 71327 | |
| 67960 | 71328 | #ifdef __LITTLE_ENDIAN__ |
| 67961 | #define vqrdmlahs_laneq_s32(__p0_254, __p1_254, __p2_254, __p3_254) __extension__ ({ \ | |
| 67962 | int32_t __s0_254 = __p0_254; \ | |
| 67963 | int32_t __s1_254 = __p1_254; \ | |
| 67964 | int32x4_t __s2_254 = __p2_254; \ | |
| 67965 | int32_t __ret_254; \ | |
| 67966 | __ret_254 = vqadds_s32(__s0_254, vqrdmulhs_s32(__s1_254, vgetq_lane_s32(__s2_254, __p3_254))); \ | |
| 67967 | __ret_254; \ | |
| 71329 | #define vqrdmlahs_laneq_s32(__p0_272, __p1_272, __p2_272, __p3_272) __extension__ ({ \ | |
| 71330 | int32_t __s0_272 = __p0_272; \ | |
| 71331 | int32_t __s1_272 = __p1_272; \ | |
| 71332 | int32x4_t __s2_272 = __p2_272; \ | |
| 71333 | int32_t __ret_272; \ | |
| 71334 | __ret_272 = vqadds_s32(__s0_272, vqrdmulhs_s32(__s1_272, vgetq_lane_s32(__s2_272, __p3_272))); \ | |
| 71335 | __ret_272; \ | |
| 67968 | 71336 | }) |
| 67969 | 71337 | #else |
| 67970 | #define vqrdmlahs_laneq_s32(__p0_255, __p1_255, __p2_255, __p3_255) __extension__ ({ \ | |
| 67971 | int32_t __s0_255 = __p0_255; \ | |
| 67972 | int32_t __s1_255 = __p1_255; \ | |
| 67973 | int32x4_t __s2_255 = __p2_255; \ | |
| 67974 | int32x4_t __rev2_255; __rev2_255 = __builtin_shufflevector(__s2_255, __s2_255, 3, 2, 1, 0); \ | |
| 67975 | int32_t __ret_255; \ | |
| 67976 | __ret_255 = __noswap_vqadds_s32(__s0_255, __noswap_vqrdmulhs_s32(__s1_255, __noswap_vgetq_lane_s32(__rev2_255, __p3_255))); \ | |
| 67977 | __ret_255; \ | |
| 71338 | #define vqrdmlahs_laneq_s32(__p0_273, __p1_273, __p2_273, __p3_273) __extension__ ({ \ | |
| 71339 | int32_t __s0_273 = __p0_273; \ | |
| 71340 | int32_t __s1_273 = __p1_273; \ | |
| 71341 | int32x4_t __s2_273 = __p2_273; \ | |
| 71342 | int32x4_t __rev2_273; __rev2_273 = __builtin_shufflevector(__s2_273, __s2_273, 3, 2, 1, 0); \ | |
| 71343 | int32_t __ret_273; \ | |
| 71344 | __ret_273 = __noswap_vqadds_s32(__s0_273, __noswap_vqrdmulhs_s32(__s1_273, __noswap_vgetq_lane_s32(__rev2_273, __p3_273))); \ | |
| 71345 | __ret_273; \ | |
| 67978 | 71346 | }) |
| 67979 | 71347 | #endif |
| 67980 | 71348 | |
| 67981 | 71349 | #ifdef __LITTLE_ENDIAN__ |
| 67982 | #define vqrdmlahh_laneq_s16(__p0_256, __p1_256, __p2_256, __p3_256) __extension__ ({ \ | |
| 67983 | int16_t __s0_256 = __p0_256; \ | |
| 67984 | int16_t __s1_256 = __p1_256; \ | |
| 67985 | int16x8_t __s2_256 = __p2_256; \ | |
| 67986 | int16_t __ret_256; \ | |
| 67987 | __ret_256 = vqaddh_s16(__s0_256, vqrdmulhh_s16(__s1_256, vgetq_lane_s16(__s2_256, __p3_256))); \ | |
| 67988 | __ret_256; \ | |
| 71350 | #define vqrdmlahh_laneq_s16(__p0_274, __p1_274, __p2_274, __p3_274) __extension__ ({ \ | |
| 71351 | int16_t __s0_274 = __p0_274; \ | |
| 71352 | int16_t __s1_274 = __p1_274; \ | |
| 71353 | int16x8_t __s2_274 = __p2_274; \ | |
| 71354 | int16_t __ret_274; \ | |
| 71355 | __ret_274 = vqaddh_s16(__s0_274, vqrdmulhh_s16(__s1_274, vgetq_lane_s16(__s2_274, __p3_274))); \ | |
| 71356 | __ret_274; \ | |
| 67989 | 71357 | }) |
| 67990 | 71358 | #else |
| 67991 | #define vqrdmlahh_laneq_s16(__p0_257, __p1_257, __p2_257, __p3_257) __extension__ ({ \ | |
| 67992 | int16_t __s0_257 = __p0_257; \ | |
| 67993 | int16_t __s1_257 = __p1_257; \ | |
| 67994 | int16x8_t __s2_257 = __p2_257; \ | |
| 67995 | int16x8_t __rev2_257; __rev2_257 = __builtin_shufflevector(__s2_257, __s2_257, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 67996 | int16_t __ret_257; \ | |
| 67997 | __ret_257 = __noswap_vqaddh_s16(__s0_257, __noswap_vqrdmulhh_s16(__s1_257, __noswap_vgetq_lane_s16(__rev2_257, __p3_257))); \ | |
| 67998 | __ret_257; \ | |
| 71359 | #define vqrdmlahh_laneq_s16(__p0_275, __p1_275, __p2_275, __p3_275) __extension__ ({ \ | |
| 71360 | int16_t __s0_275 = __p0_275; \ | |
| 71361 | int16_t __s1_275 = __p1_275; \ | |
| 71362 | int16x8_t __s2_275 = __p2_275; \ | |
| 71363 | int16x8_t __rev2_275; __rev2_275 = __builtin_shufflevector(__s2_275, __s2_275, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 71364 | int16_t __ret_275; \ | |
| 71365 | __ret_275 = __noswap_vqaddh_s16(__s0_275, __noswap_vqrdmulhh_s16(__s1_275, __noswap_vgetq_lane_s16(__rev2_275, __p3_275))); \ | |
| 71366 | __ret_275; \ | |
| 67999 | 71367 | }) |
| 68000 | 71368 | #endif |
| 68001 | 71369 | |
| ... | ... | @@ -68028,86 +71396,86 @@ __ai int16_t vqrdmlshh_s16(int16_t __p0, int16_t __p1, int16_t __p2) { |
| 68028 | 71396 | #endif |
| 68029 | 71397 | |
| 68030 | 71398 | #ifdef __LITTLE_ENDIAN__ |
| 68031 | #define vqrdmlshs_lane_s32(__p0_258, __p1_258, __p2_258, __p3_258) __extension__ ({ \ | |
| 68032 | int32_t __s0_258 = __p0_258; \ | |
| 68033 | int32_t __s1_258 = __p1_258; \ | |
| 68034 | int32x2_t __s2_258 = __p2_258; \ | |
| 68035 | int32_t __ret_258; \ | |
| 68036 | __ret_258 = vqsubs_s32(__s0_258, vqrdmulhs_s32(__s1_258, vget_lane_s32(__s2_258, __p3_258))); \ | |
| 68037 | __ret_258; \ | |
| 71399 | #define vqrdmlshs_lane_s32(__p0_276, __p1_276, __p2_276, __p3_276) __extension__ ({ \ | |
| 71400 | int32_t __s0_276 = __p0_276; \ | |
| 71401 | int32_t __s1_276 = __p1_276; \ | |
| 71402 | int32x2_t __s2_276 = __p2_276; \ | |
| 71403 | int32_t __ret_276; \ | |
| 71404 | __ret_276 = vqsubs_s32(__s0_276, vqrdmulhs_s32(__s1_276, vget_lane_s32(__s2_276, __p3_276))); \ | |
| 71405 | __ret_276; \ | |
| 68038 | 71406 | }) |
| 68039 | 71407 | #else |
| 68040 | #define vqrdmlshs_lane_s32(__p0_259, __p1_259, __p2_259, __p3_259) __extension__ ({ \ | |
| 68041 | int32_t __s0_259 = __p0_259; \ | |
| 68042 | int32_t __s1_259 = __p1_259; \ | |
| 68043 | int32x2_t __s2_259 = __p2_259; \ | |
| 68044 | int32x2_t __rev2_259; __rev2_259 = __builtin_shufflevector(__s2_259, __s2_259, 1, 0); \ | |
| 68045 | int32_t __ret_259; \ | |
| 68046 | __ret_259 = __noswap_vqsubs_s32(__s0_259, __noswap_vqrdmulhs_s32(__s1_259, __noswap_vget_lane_s32(__rev2_259, __p3_259))); \ | |
| 68047 | __ret_259; \ | |
| 71408 | #define vqrdmlshs_lane_s32(__p0_277, __p1_277, __p2_277, __p3_277) __extension__ ({ \ | |
| 71409 | int32_t __s0_277 = __p0_277; \ | |
| 71410 | int32_t __s1_277 = __p1_277; \ | |
| 71411 | int32x2_t __s2_277 = __p2_277; \ | |
| 71412 | int32x2_t __rev2_277; __rev2_277 = __builtin_shufflevector(__s2_277, __s2_277, 1, 0); \ | |
| 71413 | int32_t __ret_277; \ | |
| 71414 | __ret_277 = __noswap_vqsubs_s32(__s0_277, __noswap_vqrdmulhs_s32(__s1_277, __noswap_vget_lane_s32(__rev2_277, __p3_277))); \ | |
| 71415 | __ret_277; \ | |
| 68048 | 71416 | }) |
| 68049 | 71417 | #endif |
| 68050 | 71418 | |
| 68051 | 71419 | #ifdef __LITTLE_ENDIAN__ |
| 68052 | #define vqrdmlshh_lane_s16(__p0_260, __p1_260, __p2_260, __p3_260) __extension__ ({ \ | |
| 68053 | int16_t __s0_260 = __p0_260; \ | |
| 68054 | int16_t __s1_260 = __p1_260; \ | |
| 68055 | int16x4_t __s2_260 = __p2_260; \ | |
| 68056 | int16_t __ret_260; \ | |
| 68057 | __ret_260 = vqsubh_s16(__s0_260, vqrdmulhh_s16(__s1_260, vget_lane_s16(__s2_260, __p3_260))); \ | |
| 68058 | __ret_260; \ | |
| 71420 | #define vqrdmlshh_lane_s16(__p0_278, __p1_278, __p2_278, __p3_278) __extension__ ({ \ | |
| 71421 | int16_t __s0_278 = __p0_278; \ | |
| 71422 | int16_t __s1_278 = __p1_278; \ | |
| 71423 | int16x4_t __s2_278 = __p2_278; \ | |
| 71424 | int16_t __ret_278; \ | |
| 71425 | __ret_278 = vqsubh_s16(__s0_278, vqrdmulhh_s16(__s1_278, vget_lane_s16(__s2_278, __p3_278))); \ | |
| 71426 | __ret_278; \ | |
| 68059 | 71427 | }) |
| 68060 | 71428 | #else |
| 68061 | #define vqrdmlshh_lane_s16(__p0_261, __p1_261, __p2_261, __p3_261) __extension__ ({ \ | |
| 68062 | int16_t __s0_261 = __p0_261; \ | |
| 68063 | int16_t __s1_261 = __p1_261; \ | |
| 68064 | int16x4_t __s2_261 = __p2_261; \ | |
| 68065 | int16x4_t __rev2_261; __rev2_261 = __builtin_shufflevector(__s2_261, __s2_261, 3, 2, 1, 0); \ | |
| 68066 | int16_t __ret_261; \ | |
| 68067 | __ret_261 = __noswap_vqsubh_s16(__s0_261, __noswap_vqrdmulhh_s16(__s1_261, __noswap_vget_lane_s16(__rev2_261, __p3_261))); \ | |
| 68068 | __ret_261; \ | |
| 71429 | #define vqrdmlshh_lane_s16(__p0_279, __p1_279, __p2_279, __p3_279) __extension__ ({ \ | |
| 71430 | int16_t __s0_279 = __p0_279; \ | |
| 71431 | int16_t __s1_279 = __p1_279; \ | |
| 71432 | int16x4_t __s2_279 = __p2_279; \ | |
| 71433 | int16x4_t __rev2_279; __rev2_279 = __builtin_shufflevector(__s2_279, __s2_279, 3, 2, 1, 0); \ | |
| 71434 | int16_t __ret_279; \ | |
| 71435 | __ret_279 = __noswap_vqsubh_s16(__s0_279, __noswap_vqrdmulhh_s16(__s1_279, __noswap_vget_lane_s16(__rev2_279, __p3_279))); \ | |
| 71436 | __ret_279; \ | |
| 68069 | 71437 | }) |
| 68070 | 71438 | #endif |
| 68071 | 71439 | |
| 68072 | 71440 | #ifdef __LITTLE_ENDIAN__ |
| 68073 | #define vqrdmlshs_laneq_s32(__p0_262, __p1_262, __p2_262, __p3_262) __extension__ ({ \ | |
| 68074 | int32_t __s0_262 = __p0_262; \ | |
| 68075 | int32_t __s1_262 = __p1_262; \ | |
| 68076 | int32x4_t __s2_262 = __p2_262; \ | |
| 68077 | int32_t __ret_262; \ | |
| 68078 | __ret_262 = vqsubs_s32(__s0_262, vqrdmulhs_s32(__s1_262, vgetq_lane_s32(__s2_262, __p3_262))); \ | |
| 68079 | __ret_262; \ | |
| 71441 | #define vqrdmlshs_laneq_s32(__p0_280, __p1_280, __p2_280, __p3_280) __extension__ ({ \ | |
| 71442 | int32_t __s0_280 = __p0_280; \ | |
| 71443 | int32_t __s1_280 = __p1_280; \ | |
| 71444 | int32x4_t __s2_280 = __p2_280; \ | |
| 71445 | int32_t __ret_280; \ | |
| 71446 | __ret_280 = vqsubs_s32(__s0_280, vqrdmulhs_s32(__s1_280, vgetq_lane_s32(__s2_280, __p3_280))); \ | |
| 71447 | __ret_280; \ | |
| 68080 | 71448 | }) |
| 68081 | 71449 | #else |
| 68082 | #define vqrdmlshs_laneq_s32(__p0_263, __p1_263, __p2_263, __p3_263) __extension__ ({ \ | |
| 68083 | int32_t __s0_263 = __p0_263; \ | |
| 68084 | int32_t __s1_263 = __p1_263; \ | |
| 68085 | int32x4_t __s2_263 = __p2_263; \ | |
| 68086 | int32x4_t __rev2_263; __rev2_263 = __builtin_shufflevector(__s2_263, __s2_263, 3, 2, 1, 0); \ | |
| 68087 | int32_t __ret_263; \ | |
| 68088 | __ret_263 = __noswap_vqsubs_s32(__s0_263, __noswap_vqrdmulhs_s32(__s1_263, __noswap_vgetq_lane_s32(__rev2_263, __p3_263))); \ | |
| 68089 | __ret_263; \ | |
| 71450 | #define vqrdmlshs_laneq_s32(__p0_281, __p1_281, __p2_281, __p3_281) __extension__ ({ \ | |
| 71451 | int32_t __s0_281 = __p0_281; \ | |
| 71452 | int32_t __s1_281 = __p1_281; \ | |
| 71453 | int32x4_t __s2_281 = __p2_281; \ | |
| 71454 | int32x4_t __rev2_281; __rev2_281 = __builtin_shufflevector(__s2_281, __s2_281, 3, 2, 1, 0); \ | |
| 71455 | int32_t __ret_281; \ | |
| 71456 | __ret_281 = __noswap_vqsubs_s32(__s0_281, __noswap_vqrdmulhs_s32(__s1_281, __noswap_vgetq_lane_s32(__rev2_281, __p3_281))); \ | |
| 71457 | __ret_281; \ | |
| 68090 | 71458 | }) |
| 68091 | 71459 | #endif |
| 68092 | 71460 | |
| 68093 | 71461 | #ifdef __LITTLE_ENDIAN__ |
| 68094 | #define vqrdmlshh_laneq_s16(__p0_264, __p1_264, __p2_264, __p3_264) __extension__ ({ \ | |
| 68095 | int16_t __s0_264 = __p0_264; \ | |
| 68096 | int16_t __s1_264 = __p1_264; \ | |
| 68097 | int16x8_t __s2_264 = __p2_264; \ | |
| 68098 | int16_t __ret_264; \ | |
| 68099 | __ret_264 = vqsubh_s16(__s0_264, vqrdmulhh_s16(__s1_264, vgetq_lane_s16(__s2_264, __p3_264))); \ | |
| 68100 | __ret_264; \ | |
| 71462 | #define vqrdmlshh_laneq_s16(__p0_282, __p1_282, __p2_282, __p3_282) __extension__ ({ \ | |
| 71463 | int16_t __s0_282 = __p0_282; \ | |
| 71464 | int16_t __s1_282 = __p1_282; \ | |
| 71465 | int16x8_t __s2_282 = __p2_282; \ | |
| 71466 | int16_t __ret_282; \ | |
| 71467 | __ret_282 = vqsubh_s16(__s0_282, vqrdmulhh_s16(__s1_282, vgetq_lane_s16(__s2_282, __p3_282))); \ | |
| 71468 | __ret_282; \ | |
| 68101 | 71469 | }) |
| 68102 | 71470 | #else |
| 68103 | #define vqrdmlshh_laneq_s16(__p0_265, __p1_265, __p2_265, __p3_265) __extension__ ({ \ | |
| 68104 | int16_t __s0_265 = __p0_265; \ | |
| 68105 | int16_t __s1_265 = __p1_265; \ | |
| 68106 | int16x8_t __s2_265 = __p2_265; \ | |
| 68107 | int16x8_t __rev2_265; __rev2_265 = __builtin_shufflevector(__s2_265, __s2_265, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 68108 | int16_t __ret_265; \ | |
| 68109 | __ret_265 = __noswap_vqsubh_s16(__s0_265, __noswap_vqrdmulhh_s16(__s1_265, __noswap_vgetq_lane_s16(__rev2_265, __p3_265))); \ | |
| 68110 | __ret_265; \ | |
| 71471 | #define vqrdmlshh_laneq_s16(__p0_283, __p1_283, __p2_283, __p3_283) __extension__ ({ \ | |
| 71472 | int16_t __s0_283 = __p0_283; \ | |
| 71473 | int16_t __s1_283 = __p1_283; \ | |
| 71474 | int16x8_t __s2_283 = __p2_283; \ | |
| 71475 | int16x8_t __rev2_283; __rev2_283 = __builtin_shufflevector(__s2_283, __s2_283, 7, 6, 5, 4, 3, 2, 1, 0); \ | |
| 71476 | int16_t __ret_283; \ | |
| 71477 | __ret_283 = __noswap_vqsubh_s16(__s0_283, __noswap_vqrdmulhh_s16(__s1_283, __noswap_vgetq_lane_s16(__rev2_283, __p3_283))); \ | |
| 71478 | __ret_283; \ | |
| 68111 | 71479 | }) |
| 68112 | 71480 | #endif |
| 68113 | 71481 | |
| ... | ... | @@ -68420,158 +71788,158 @@ __ai int32x4_t vaddw_high_s16(int32x4_t __p0, int16x8_t __p1) { |
| 68420 | 71788 | #endif |
| 68421 | 71789 | |
| 68422 | 71790 | #ifdef __LITTLE_ENDIAN__ |
| 68423 | #define vcopyq_lane_p64(__p0_266, __p1_266, __p2_266, __p3_266) __extension__ ({ \ | |
| 68424 | poly64x2_t __s0_266 = __p0_266; \ | |
| 68425 | poly64x1_t __s2_266 = __p2_266; \ | |
| 68426 | poly64x2_t __ret_266; \ | |
| 68427 | __ret_266 = vsetq_lane_p64(vget_lane_p64(__s2_266, __p3_266), __s0_266, __p1_266); \ | |
| 68428 | __ret_266; \ | |
| 71791 | #define vcopyq_lane_p64(__p0_284, __p1_284, __p2_284, __p3_284) __extension__ ({ \ | |
| 71792 | poly64x2_t __s0_284 = __p0_284; \ | |
| 71793 | poly64x1_t __s2_284 = __p2_284; \ | |
| 71794 | poly64x2_t __ret_284; \ | |
| 71795 | __ret_284 = vsetq_lane_p64(vget_lane_p64(__s2_284, __p3_284), __s0_284, __p1_284); \ | |
| 71796 | __ret_284; \ | |
| 68429 | 71797 | }) |
| 68430 | 71798 | #else |
| 68431 | #define vcopyq_lane_p64(__p0_267, __p1_267, __p2_267, __p3_267) __extension__ ({ \ | |
| 68432 | poly64x2_t __s0_267 = __p0_267; \ | |
| 68433 | poly64x1_t __s2_267 = __p2_267; \ | |
| 68434 | poly64x2_t __rev0_267; __rev0_267 = __builtin_shufflevector(__s0_267, __s0_267, 1, 0); \ | |
| 68435 | poly64x2_t __ret_267; \ | |
| 68436 | __ret_267 = __noswap_vsetq_lane_p64(__noswap_vget_lane_p64(__s2_267, __p3_267), __rev0_267, __p1_267); \ | |
| 68437 | __ret_267 = __builtin_shufflevector(__ret_267, __ret_267, 1, 0); \ | |
| 68438 | __ret_267; \ | |
| 71799 | #define vcopyq_lane_p64(__p0_285, __p1_285, __p2_285, __p3_285) __extension__ ({ \ | |
| 71800 | poly64x2_t __s0_285 = __p0_285; \ | |
| 71801 | poly64x1_t __s2_285 = __p2_285; \ | |
| 71802 | poly64x2_t __rev0_285; __rev0_285 = __builtin_shufflevector(__s0_285, __s0_285, 1, 0); \ | |
| 71803 | poly64x2_t __ret_285; \ | |
| 71804 | __ret_285 = __noswap_vsetq_lane_p64(__noswap_vget_lane_p64(__s2_285, __p3_285), __rev0_285, __p1_285); \ | |
| 71805 | __ret_285 = __builtin_shufflevector(__ret_285, __ret_285, 1, 0); \ | |
| 71806 | __ret_285; \ | |
| 68439 | 71807 | }) |
| 68440 | 71808 | #endif |
| 68441 | 71809 | |
| 68442 | 71810 | #ifdef __LITTLE_ENDIAN__ |
| 68443 | #define vcopyq_lane_f64(__p0_268, __p1_268, __p2_268, __p3_268) __extension__ ({ \ | |
| 68444 | float64x2_t __s0_268 = __p0_268; \ | |
| 68445 | float64x1_t __s2_268 = __p2_268; \ | |
| 68446 | float64x2_t __ret_268; \ | |
| 68447 | __ret_268 = vsetq_lane_f64(vget_lane_f64(__s2_268, __p3_268), __s0_268, __p1_268); \ | |
| 68448 | __ret_268; \ | |
| 71811 | #define vcopyq_lane_f64(__p0_286, __p1_286, __p2_286, __p3_286) __extension__ ({ \ | |
| 71812 | float64x2_t __s0_286 = __p0_286; \ | |
| 71813 | float64x1_t __s2_286 = __p2_286; \ | |
| 71814 | float64x2_t __ret_286; \ | |
| 71815 | __ret_286 = vsetq_lane_f64(vget_lane_f64(__s2_286, __p3_286), __s0_286, __p1_286); \ | |
| 71816 | __ret_286; \ | |
| 68449 | 71817 | }) |
| 68450 | 71818 | #else |
| 68451 | #define vcopyq_lane_f64(__p0_269, __p1_269, __p2_269, __p3_269) __extension__ ({ \ | |
| 68452 | float64x2_t __s0_269 = __p0_269; \ | |
| 68453 | float64x1_t __s2_269 = __p2_269; \ | |
| 68454 | float64x2_t __rev0_269; __rev0_269 = __builtin_shufflevector(__s0_269, __s0_269, 1, 0); \ | |
| 68455 | float64x2_t __ret_269; \ | |
| 68456 | __ret_269 = __noswap_vsetq_lane_f64(__noswap_vget_lane_f64(__s2_269, __p3_269), __rev0_269, __p1_269); \ | |
| 68457 | __ret_269 = __builtin_shufflevector(__ret_269, __ret_269, 1, 0); \ | |
| 68458 | __ret_269; \ | |
| 71819 | #define vcopyq_lane_f64(__p0_287, __p1_287, __p2_287, __p3_287) __extension__ ({ \ | |
| 71820 | float64x2_t __s0_287 = __p0_287; \ | |
| 71821 | float64x1_t __s2_287 = __p2_287; \ | |
| 71822 | float64x2_t __rev0_287; __rev0_287 = __builtin_shufflevector(__s0_287, __s0_287, 1, 0); \ | |
| 71823 | float64x2_t __ret_287; \ | |
| 71824 | __ret_287 = __noswap_vsetq_lane_f64(__noswap_vget_lane_f64(__s2_287, __p3_287), __rev0_287, __p1_287); \ | |
| 71825 | __ret_287 = __builtin_shufflevector(__ret_287, __ret_287, 1, 0); \ | |
| 71826 | __ret_287; \ | |
| 68459 | 71827 | }) |
| 68460 | 71828 | #endif |
| 68461 | 71829 | |
| 68462 | 71830 | #ifdef __LITTLE_ENDIAN__ |
| 68463 | #define vcopy_lane_p64(__p0_270, __p1_270, __p2_270, __p3_270) __extension__ ({ \ | |
| 68464 | poly64x1_t __s0_270 = __p0_270; \ | |
| 68465 | poly64x1_t __s2_270 = __p2_270; \ | |
| 68466 | poly64x1_t __ret_270; \ | |
| 68467 | __ret_270 = vset_lane_p64(vget_lane_p64(__s2_270, __p3_270), __s0_270, __p1_270); \ | |
| 68468 | __ret_270; \ | |
| 71831 | #define vcopy_lane_p64(__p0_288, __p1_288, __p2_288, __p3_288) __extension__ ({ \ | |
| 71832 | poly64x1_t __s0_288 = __p0_288; \ | |
| 71833 | poly64x1_t __s2_288 = __p2_288; \ | |
| 71834 | poly64x1_t __ret_288; \ | |
| 71835 | __ret_288 = vset_lane_p64(vget_lane_p64(__s2_288, __p3_288), __s0_288, __p1_288); \ | |
| 71836 | __ret_288; \ | |
| 68469 | 71837 | }) |
| 68470 | 71838 | #else |
| 68471 | #define vcopy_lane_p64(__p0_271, __p1_271, __p2_271, __p3_271) __extension__ ({ \ | |
| 68472 | poly64x1_t __s0_271 = __p0_271; \ | |
| 68473 | poly64x1_t __s2_271 = __p2_271; \ | |
| 68474 | poly64x1_t __ret_271; \ | |
| 68475 | __ret_271 = __noswap_vset_lane_p64(__noswap_vget_lane_p64(__s2_271, __p3_271), __s0_271, __p1_271); \ | |
| 68476 | __ret_271; \ | |
| 71839 | #define vcopy_lane_p64(__p0_289, __p1_289, __p2_289, __p3_289) __extension__ ({ \ | |
| 71840 | poly64x1_t __s0_289 = __p0_289; \ | |
| 71841 | poly64x1_t __s2_289 = __p2_289; \ | |
| 71842 | poly64x1_t __ret_289; \ | |
| 71843 | __ret_289 = __noswap_vset_lane_p64(__noswap_vget_lane_p64(__s2_289, __p3_289), __s0_289, __p1_289); \ | |
| 71844 | __ret_289; \ | |
| 68477 | 71845 | }) |
| 68478 | 71846 | #endif |
| 68479 | 71847 | |
| 68480 | 71848 | #ifdef __LITTLE_ENDIAN__ |
| 68481 | #define vcopy_lane_f64(__p0_272, __p1_272, __p2_272, __p3_272) __extension__ ({ \ | |
| 68482 | float64x1_t __s0_272 = __p0_272; \ | |
| 68483 | float64x1_t __s2_272 = __p2_272; \ | |
| 68484 | float64x1_t __ret_272; \ | |
| 68485 | __ret_272 = vset_lane_f64(vget_lane_f64(__s2_272, __p3_272), __s0_272, __p1_272); \ | |
| 68486 | __ret_272; \ | |
| 71849 | #define vcopy_lane_f64(__p0_290, __p1_290, __p2_290, __p3_290) __extension__ ({ \ | |
| 71850 | float64x1_t __s0_290 = __p0_290; \ | |
| 71851 | float64x1_t __s2_290 = __p2_290; \ | |
| 71852 | float64x1_t __ret_290; \ | |
| 71853 | __ret_290 = vset_lane_f64(vget_lane_f64(__s2_290, __p3_290), __s0_290, __p1_290); \ | |
| 71854 | __ret_290; \ | |
| 68487 | 71855 | }) |
| 68488 | 71856 | #else |
| 68489 | #define vcopy_lane_f64(__p0_273, __p1_273, __p2_273, __p3_273) __extension__ ({ \ | |
| 68490 | float64x1_t __s0_273 = __p0_273; \ | |
| 68491 | float64x1_t __s2_273 = __p2_273; \ | |
| 68492 | float64x1_t __ret_273; \ | |
| 68493 | __ret_273 = __noswap_vset_lane_f64(__noswap_vget_lane_f64(__s2_273, __p3_273), __s0_273, __p1_273); \ | |
| 68494 | __ret_273; \ | |
| 71857 | #define vcopy_lane_f64(__p0_291, __p1_291, __p2_291, __p3_291) __extension__ ({ \ | |
| 71858 | float64x1_t __s0_291 = __p0_291; \ | |
| 71859 | float64x1_t __s2_291 = __p2_291; \ | |
| 71860 | float64x1_t __ret_291; \ | |
| 71861 | __ret_291 = __noswap_vset_lane_f64(__noswap_vget_lane_f64(__s2_291, __p3_291), __s0_291, __p1_291); \ | |
| 71862 | __ret_291; \ | |
| 68495 | 71863 | }) |
| 68496 | 71864 | #endif |
| 68497 | 71865 | |
| 68498 | 71866 | #ifdef __LITTLE_ENDIAN__ |
| 68499 | #define vcopyq_laneq_p64(__p0_274, __p1_274, __p2_274, __p3_274) __extension__ ({ \ | |
| 68500 | poly64x2_t __s0_274 = __p0_274; \ | |
| 68501 | poly64x2_t __s2_274 = __p2_274; \ | |
| 68502 | poly64x2_t __ret_274; \ | |
| 68503 | __ret_274 = vsetq_lane_p64(vgetq_lane_p64(__s2_274, __p3_274), __s0_274, __p1_274); \ | |
| 68504 | __ret_274; \ | |
| 71867 | #define vcopyq_laneq_p64(__p0_292, __p1_292, __p2_292, __p3_292) __extension__ ({ \ | |
| 71868 | poly64x2_t __s0_292 = __p0_292; \ | |
| 71869 | poly64x2_t __s2_292 = __p2_292; \ | |
| 71870 | poly64x2_t __ret_292; \ | |
| 71871 | __ret_292 = vsetq_lane_p64(vgetq_lane_p64(__s2_292, __p3_292), __s0_292, __p1_292); \ | |
| 71872 | __ret_292; \ | |
| 68505 | 71873 | }) |
| 68506 | 71874 | #else |
| 68507 | #define vcopyq_laneq_p64(__p0_275, __p1_275, __p2_275, __p3_275) __extension__ ({ \ | |
| 68508 | poly64x2_t __s0_275 = __p0_275; \ | |
| 68509 | poly64x2_t __s2_275 = __p2_275; \ | |
| 68510 | poly64x2_t __rev0_275; __rev0_275 = __builtin_shufflevector(__s0_275, __s0_275, 1, 0); \ | |
| 68511 | poly64x2_t __rev2_275; __rev2_275 = __builtin_shufflevector(__s2_275, __s2_275, 1, 0); \ | |
| 68512 | poly64x2_t __ret_275; \ | |
| 68513 | __ret_275 = __noswap_vsetq_lane_p64(__noswap_vgetq_lane_p64(__rev2_275, __p3_275), __rev0_275, __p1_275); \ | |
| 68514 | __ret_275 = __builtin_shufflevector(__ret_275, __ret_275, 1, 0); \ | |
| 68515 | __ret_275; \ | |
| 71875 | #define vcopyq_laneq_p64(__p0_293, __p1_293, __p2_293, __p3_293) __extension__ ({ \ | |
| 71876 | poly64x2_t __s0_293 = __p0_293; \ | |
| 71877 | poly64x2_t __s2_293 = __p2_293; \ | |
| 71878 | poly64x2_t __rev0_293; __rev0_293 = __builtin_shufflevector(__s0_293, __s0_293, 1, 0); \ | |
| 71879 | poly64x2_t __rev2_293; __rev2_293 = __builtin_shufflevector(__s2_293, __s2_293, 1, 0); \ | |
| 71880 | poly64x2_t __ret_293; \ | |
| 71881 | __ret_293 = __noswap_vsetq_lane_p64(__noswap_vgetq_lane_p64(__rev2_293, __p3_293), __rev0_293, __p1_293); \ | |
| 71882 | __ret_293 = __builtin_shufflevector(__ret_293, __ret_293, 1, 0); \ | |
| 71883 | __ret_293; \ | |
| 68516 | 71884 | }) |
| 68517 | 71885 | #endif |
| 68518 | 71886 | |
| 68519 | 71887 | #ifdef __LITTLE_ENDIAN__ |
| 68520 | #define vcopyq_laneq_f64(__p0_276, __p1_276, __p2_276, __p3_276) __extension__ ({ \ | |
| 68521 | float64x2_t __s0_276 = __p0_276; \ | |
| 68522 | float64x2_t __s2_276 = __p2_276; \ | |
| 68523 | float64x2_t __ret_276; \ | |
| 68524 | __ret_276 = vsetq_lane_f64(vgetq_lane_f64(__s2_276, __p3_276), __s0_276, __p1_276); \ | |
| 68525 | __ret_276; \ | |
| 71888 | #define vcopyq_laneq_f64(__p0_294, __p1_294, __p2_294, __p3_294) __extension__ ({ \ | |
| 71889 | float64x2_t __s0_294 = __p0_294; \ | |
| 71890 | float64x2_t __s2_294 = __p2_294; \ | |
| 71891 | float64x2_t __ret_294; \ | |
| 71892 | __ret_294 = vsetq_lane_f64(vgetq_lane_f64(__s2_294, __p3_294), __s0_294, __p1_294); \ | |
| 71893 | __ret_294; \ | |
| 68526 | 71894 | }) |
| 68527 | 71895 | #else |
| 68528 | #define vcopyq_laneq_f64(__p0_277, __p1_277, __p2_277, __p3_277) __extension__ ({ \ | |
| 68529 | float64x2_t __s0_277 = __p0_277; \ | |
| 68530 | float64x2_t __s2_277 = __p2_277; \ | |
| 68531 | float64x2_t __rev0_277; __rev0_277 = __builtin_shufflevector(__s0_277, __s0_277, 1, 0); \ | |
| 68532 | float64x2_t __rev2_277; __rev2_277 = __builtin_shufflevector(__s2_277, __s2_277, 1, 0); \ | |
| 68533 | float64x2_t __ret_277; \ | |
| 68534 | __ret_277 = __noswap_vsetq_lane_f64(__noswap_vgetq_lane_f64(__rev2_277, __p3_277), __rev0_277, __p1_277); \ | |
| 68535 | __ret_277 = __builtin_shufflevector(__ret_277, __ret_277, 1, 0); \ | |
| 68536 | __ret_277; \ | |
| 71896 | #define vcopyq_laneq_f64(__p0_295, __p1_295, __p2_295, __p3_295) __extension__ ({ \ | |
| 71897 | float64x2_t __s0_295 = __p0_295; \ | |
| 71898 | float64x2_t __s2_295 = __p2_295; \ | |
| 71899 | float64x2_t __rev0_295; __rev0_295 = __builtin_shufflevector(__s0_295, __s0_295, 1, 0); \ | |
| 71900 | float64x2_t __rev2_295; __rev2_295 = __builtin_shufflevector(__s2_295, __s2_295, 1, 0); \ | |
| 71901 | float64x2_t __ret_295; \ | |
| 71902 | __ret_295 = __noswap_vsetq_lane_f64(__noswap_vgetq_lane_f64(__rev2_295, __p3_295), __rev0_295, __p1_295); \ | |
| 71903 | __ret_295 = __builtin_shufflevector(__ret_295, __ret_295, 1, 0); \ | |
| 71904 | __ret_295; \ | |
| 68537 | 71905 | }) |
| 68538 | 71906 | #endif |
| 68539 | 71907 | |
| 68540 | 71908 | #ifdef __LITTLE_ENDIAN__ |
| 68541 | #define vcopy_laneq_p64(__p0_278, __p1_278, __p2_278, __p3_278) __extension__ ({ \ | |
| 68542 | poly64x1_t __s0_278 = __p0_278; \ | |
| 68543 | poly64x2_t __s2_278 = __p2_278; \ | |
| 68544 | poly64x1_t __ret_278; \ | |
| 68545 | __ret_278 = vset_lane_p64(vgetq_lane_p64(__s2_278, __p3_278), __s0_278, __p1_278); \ | |
| 68546 | __ret_278; \ | |
| 71909 | #define vcopy_laneq_p64(__p0_296, __p1_296, __p2_296, __p3_296) __extension__ ({ \ | |
| 71910 | poly64x1_t __s0_296 = __p0_296; \ | |
| 71911 | poly64x2_t __s2_296 = __p2_296; \ | |
| 71912 | poly64x1_t __ret_296; \ | |
| 71913 | __ret_296 = vset_lane_p64(vgetq_lane_p64(__s2_296, __p3_296), __s0_296, __p1_296); \ | |
| 71914 | __ret_296; \ | |
| 68547 | 71915 | }) |
| 68548 | 71916 | #else |
| 68549 | #define vcopy_laneq_p64(__p0_279, __p1_279, __p2_279, __p3_279) __extension__ ({ \ | |
| 68550 | poly64x1_t __s0_279 = __p0_279; \ | |
| 68551 | poly64x2_t __s2_279 = __p2_279; \ | |
| 68552 | poly64x2_t __rev2_279; __rev2_279 = __builtin_shufflevector(__s2_279, __s2_279, 1, 0); \ | |
| 68553 | poly64x1_t __ret_279; \ | |
| 68554 | __ret_279 = __noswap_vset_lane_p64(__noswap_vgetq_lane_p64(__rev2_279, __p3_279), __s0_279, __p1_279); \ | |
| 68555 | __ret_279; \ | |
| 71917 | #define vcopy_laneq_p64(__p0_297, __p1_297, __p2_297, __p3_297) __extension__ ({ \ | |
| 71918 | poly64x1_t __s0_297 = __p0_297; \ | |
| 71919 | poly64x2_t __s2_297 = __p2_297; \ | |
| 71920 | poly64x2_t __rev2_297; __rev2_297 = __builtin_shufflevector(__s2_297, __s2_297, 1, 0); \ | |
| 71921 | poly64x1_t __ret_297; \ | |
| 71922 | __ret_297 = __noswap_vset_lane_p64(__noswap_vgetq_lane_p64(__rev2_297, __p3_297), __s0_297, __p1_297); \ | |
| 71923 | __ret_297; \ | |
| 68556 | 71924 | }) |
| 68557 | 71925 | #endif |
| 68558 | 71926 | |
| 68559 | 71927 | #ifdef __LITTLE_ENDIAN__ |
| 68560 | #define vcopy_laneq_f64(__p0_280, __p1_280, __p2_280, __p3_280) __extension__ ({ \ | |
| 68561 | float64x1_t __s0_280 = __p0_280; \ | |
| 68562 | float64x2_t __s2_280 = __p2_280; \ | |
| 68563 | float64x1_t __ret_280; \ | |
| 68564 | __ret_280 = vset_lane_f64(vgetq_lane_f64(__s2_280, __p3_280), __s0_280, __p1_280); \ | |
| 68565 | __ret_280; \ | |
| 71928 | #define vcopy_laneq_f64(__p0_298, __p1_298, __p2_298, __p3_298) __extension__ ({ \ | |
| 71929 | float64x1_t __s0_298 = __p0_298; \ | |
| 71930 | float64x2_t __s2_298 = __p2_298; \ | |
| 71931 | float64x1_t __ret_298; \ | |
| 71932 | __ret_298 = vset_lane_f64(vgetq_lane_f64(__s2_298, __p3_298), __s0_298, __p1_298); \ | |
| 71933 | __ret_298; \ | |
| 68566 | 71934 | }) |
| 68567 | 71935 | #else |
| 68568 | #define vcopy_laneq_f64(__p0_281, __p1_281, __p2_281, __p3_281) __extension__ ({ \ | |
| 68569 | float64x1_t __s0_281 = __p0_281; \ | |
| 68570 | float64x2_t __s2_281 = __p2_281; \ | |
| 68571 | float64x2_t __rev2_281; __rev2_281 = __builtin_shufflevector(__s2_281, __s2_281, 1, 0); \ | |
| 68572 | float64x1_t __ret_281; \ | |
| 68573 | __ret_281 = __noswap_vset_lane_f64(__noswap_vgetq_lane_f64(__rev2_281, __p3_281), __s0_281, __p1_281); \ | |
| 68574 | __ret_281; \ | |
| 71936 | #define vcopy_laneq_f64(__p0_299, __p1_299, __p2_299, __p3_299) __extension__ ({ \ | |
| 71937 | float64x1_t __s0_299 = __p0_299; \ | |
| 71938 | float64x2_t __s2_299 = __p2_299; \ | |
| 71939 | float64x2_t __rev2_299; __rev2_299 = __builtin_shufflevector(__s2_299, __s2_299, 1, 0); \ | |
| 71940 | float64x1_t __ret_299; \ | |
| 71941 | __ret_299 = __noswap_vset_lane_f64(__noswap_vgetq_lane_f64(__rev2_299, __p3_299), __s0_299, __p1_299); \ | |
| 71942 | __ret_299; \ | |
| 68575 | 71943 | }) |
| 68576 | 71944 | #endif |
| 68577 | 71945 | |
| ... | ... | @@ -68928,51 +72296,51 @@ __ai int32x4_t vmlsl_high_n_s16(int32x4_t __p0, int16x8_t __p1, int16_t __p2) { |
| 68928 | 72296 | #endif |
| 68929 | 72297 | |
| 68930 | 72298 | #ifdef __LITTLE_ENDIAN__ |
| 68931 | #define vmulx_lane_f64(__p0_282, __p1_282, __p2_282) __extension__ ({ \ | |
| 68932 | float64x1_t __s0_282 = __p0_282; \ | |
| 68933 | float64x1_t __s1_282 = __p1_282; \ | |
| 68934 | float64x1_t __ret_282; \ | |
| 68935 | float64_t __x_282 = vget_lane_f64(__s0_282, 0); \ | |
| 68936 | float64_t __y_282 = vget_lane_f64(__s1_282, __p2_282); \ | |
| 68937 | float64_t __z_282 = vmulxd_f64(__x_282, __y_282); \ | |
| 68938 | __ret_282 = vset_lane_f64(__z_282, __s0_282, __p2_282); \ | |
| 68939 | __ret_282; \ | |
| 72299 | #define vmulx_lane_f64(__p0_300, __p1_300, __p2_300) __extension__ ({ \ | |
| 72300 | float64x1_t __s0_300 = __p0_300; \ | |
| 72301 | float64x1_t __s1_300 = __p1_300; \ | |
| 72302 | float64x1_t __ret_300; \ | |
| 72303 | float64_t __x_300 = vget_lane_f64(__s0_300, 0); \ | |
| 72304 | float64_t __y_300 = vget_lane_f64(__s1_300, __p2_300); \ | |
| 72305 | float64_t __z_300 = vmulxd_f64(__x_300, __y_300); \ | |
| 72306 | __ret_300 = vset_lane_f64(__z_300, __s0_300, __p2_300); \ | |
| 72307 | __ret_300; \ | |
| 68940 | 72308 | }) |
| 68941 | 72309 | #else |
| 68942 | #define vmulx_lane_f64(__p0_283, __p1_283, __p2_283) __extension__ ({ \ | |
| 68943 | float64x1_t __s0_283 = __p0_283; \ | |
| 68944 | float64x1_t __s1_283 = __p1_283; \ | |
| 68945 | float64x1_t __ret_283; \ | |
| 68946 | float64_t __x_283 = __noswap_vget_lane_f64(__s0_283, 0); \ | |
| 68947 | float64_t __y_283 = __noswap_vget_lane_f64(__s1_283, __p2_283); \ | |
| 68948 | float64_t __z_283 = __noswap_vmulxd_f64(__x_283, __y_283); \ | |
| 68949 | __ret_283 = __noswap_vset_lane_f64(__z_283, __s0_283, __p2_283); \ | |
| 68950 | __ret_283; \ | |
| 72310 | #define vmulx_lane_f64(__p0_301, __p1_301, __p2_301) __extension__ ({ \ | |
| 72311 | float64x1_t __s0_301 = __p0_301; \ | |
| 72312 | float64x1_t __s1_301 = __p1_301; \ | |
| 72313 | float64x1_t __ret_301; \ | |
| 72314 | float64_t __x_301 = __noswap_vget_lane_f64(__s0_301, 0); \ | |
| 72315 | float64_t __y_301 = __noswap_vget_lane_f64(__s1_301, __p2_301); \ | |
| 72316 | float64_t __z_301 = __noswap_vmulxd_f64(__x_301, __y_301); \ | |
| 72317 | __ret_301 = __noswap_vset_lane_f64(__z_301, __s0_301, __p2_301); \ | |
| 72318 | __ret_301; \ | |
| 68951 | 72319 | }) |
| 68952 | 72320 | #endif |
| 68953 | 72321 | |
| 68954 | 72322 | #ifdef __LITTLE_ENDIAN__ |
| 68955 | #define vmulx_laneq_f64(__p0_284, __p1_284, __p2_284) __extension__ ({ \ | |
| 68956 | float64x1_t __s0_284 = __p0_284; \ | |
| 68957 | float64x2_t __s1_284 = __p1_284; \ | |
| 68958 | float64x1_t __ret_284; \ | |
| 68959 | float64_t __x_284 = vget_lane_f64(__s0_284, 0); \ | |
| 68960 | float64_t __y_284 = vgetq_lane_f64(__s1_284, __p2_284); \ | |
| 68961 | float64_t __z_284 = vmulxd_f64(__x_284, __y_284); \ | |
| 68962 | __ret_284 = vset_lane_f64(__z_284, __s0_284, 0); \ | |
| 68963 | __ret_284; \ | |
| 72323 | #define vmulx_laneq_f64(__p0_302, __p1_302, __p2_302) __extension__ ({ \ | |
| 72324 | float64x1_t __s0_302 = __p0_302; \ | |
| 72325 | float64x2_t __s1_302 = __p1_302; \ | |
| 72326 | float64x1_t __ret_302; \ | |
| 72327 | float64_t __x_302 = vget_lane_f64(__s0_302, 0); \ | |
| 72328 | float64_t __y_302 = vgetq_lane_f64(__s1_302, __p2_302); \ | |
| 72329 | float64_t __z_302 = vmulxd_f64(__x_302, __y_302); \ | |
| 72330 | __ret_302 = vset_lane_f64(__z_302, __s0_302, 0); \ | |
| 72331 | __ret_302; \ | |
| 68964 | 72332 | }) |
| 68965 | 72333 | #else |
| 68966 | #define vmulx_laneq_f64(__p0_285, __p1_285, __p2_285) __extension__ ({ \ | |
| 68967 | float64x1_t __s0_285 = __p0_285; \ | |
| 68968 | float64x2_t __s1_285 = __p1_285; \ | |
| 68969 | float64x2_t __rev1_285; __rev1_285 = __builtin_shufflevector(__s1_285, __s1_285, 1, 0); \ | |
| 68970 | float64x1_t __ret_285; \ | |
| 68971 | float64_t __x_285 = __noswap_vget_lane_f64(__s0_285, 0); \ | |
| 68972 | float64_t __y_285 = __noswap_vgetq_lane_f64(__rev1_285, __p2_285); \ | |
| 68973 | float64_t __z_285 = __noswap_vmulxd_f64(__x_285, __y_285); \ | |
| 68974 | __ret_285 = __noswap_vset_lane_f64(__z_285, __s0_285, 0); \ | |
| 68975 | __ret_285; \ | |
| 72334 | #define vmulx_laneq_f64(__p0_303, __p1_303, __p2_303) __extension__ ({ \ | |
| 72335 | float64x1_t __s0_303 = __p0_303; \ | |
| 72336 | float64x2_t __s1_303 = __p1_303; \ | |
| 72337 | float64x2_t __rev1_303; __rev1_303 = __builtin_shufflevector(__s1_303, __s1_303, 1, 0); \ | |
| 72338 | float64x1_t __ret_303; \ | |
| 72339 | float64_t __x_303 = __noswap_vget_lane_f64(__s0_303, 0); \ | |
| 72340 | float64_t __y_303 = __noswap_vgetq_lane_f64(__rev1_303, __p2_303); \ | |
| 72341 | float64_t __z_303 = __noswap_vmulxd_f64(__x_303, __y_303); \ | |
| 72342 | __ret_303 = __noswap_vset_lane_f64(__z_303, __s0_303, 0); \ | |
| 72343 | __ret_303; \ | |
| 68976 | 72344 | }) |
| 68977 | 72345 | #endif |
| 68978 | 72346 |
c_headers/avx2intrin.h+10-2| ... | ... | @@ -145,13 +145,21 @@ _mm256_andnot_si256(__m256i __a, __m256i __b) |
| 145 | 145 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 146 | 146 | _mm256_avg_epu8(__m256i __a, __m256i __b) |
| 147 | 147 | { |
| 148 | return (__m256i)__builtin_ia32_pavgb256((__v32qi)__a, (__v32qi)__b); | |
| 148 | typedef unsigned short __v32hu __attribute__((__vector_size__(64))); | |
| 149 | return (__m256i)__builtin_convertvector( | |
| 150 | ((__builtin_convertvector((__v32qu)__a, __v32hu) + | |
| 151 | __builtin_convertvector((__v32qu)__b, __v32hu)) + 1) | |
| 152 | >> 1, __v32qu); | |
| 149 | 153 | } |
| 150 | 154 | |
| 151 | 155 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 152 | 156 | _mm256_avg_epu16(__m256i __a, __m256i __b) |
| 153 | 157 | { |
| 154 | return (__m256i)__builtin_ia32_pavgw256((__v16hi)__a, (__v16hi)__b); | |
| 158 | typedef unsigned int __v16su __attribute__((__vector_size__(64))); | |
| 159 | return (__m256i)__builtin_convertvector( | |
| 160 | ((__builtin_convertvector((__v16hu)__a, __v16su) + | |
| 161 | __builtin_convertvector((__v16hu)__b, __v16su)) + 1) | |
| 162 | >> 1, __v16hu); | |
| 155 | 163 | } |
| 156 | 164 | |
| 157 | 165 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
c_headers/avx512bitalgintrin.h created+97| ... | ... | @@ -0,0 +1,97 @@ |
| 1 | /*===------------- avx512bitalgintrin.h - BITALG intrinsics ------------------=== | |
| 2 | * | |
| 3 | * | |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 5 | * of this software and associated documentation files (the "Software"), to deal | |
| 6 | * in the Software without restriction, including without limitation the rights | |
| 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 8 | * copies of the Software, and to permit persons to whom the Software is | |
| 9 | * furnished to do so, subject to the following conditions: | |
| 10 | * | |
| 11 | * The above copyright notice and this permission notice shall be included in | |
| 12 | * all copies or substantial portions of the Software. | |
| 13 | * | |
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 20 | * THE SOFTWARE. | |
| 21 | * | |
| 22 | *===-----------------------------------------------------------------------=== | |
| 23 | */ | |
| 24 | #ifndef __IMMINTRIN_H | |
| 25 | #error "Never use <avx512bitalgintrin.h> directly; include <immintrin.h> instead." | |
| 26 | #endif | |
| 27 | ||
| 28 | #ifndef __AVX512BITALGINTRIN_H | |
| 29 | #define __AVX512BITALGINTRIN_H | |
| 30 | ||
| 31 | /* Define the default attributes for the functions in this file. */ | |
| 32 | #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512bitalg"))) | |
| 33 | ||
| 34 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 35 | _mm512_popcnt_epi16(__m512i __A) | |
| 36 | { | |
| 37 | return (__m512i) __builtin_ia32_vpopcntw_512((__v32hi) __A); | |
| 38 | } | |
| 39 | ||
| 40 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 41 | _mm512_mask_popcnt_epi16(__m512i __A, __mmask32 __U, __m512i __B) | |
| 42 | { | |
| 43 | return (__m512i) __builtin_ia32_selectw_512((__mmask32) __U, | |
| 44 | (__v32hi) _mm512_popcnt_epi16(__B), | |
| 45 | (__v32hi) __A); | |
| 46 | } | |
| 47 | ||
| 48 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 49 | _mm512_maskz_popcnt_epi16(__mmask32 __U, __m512i __B) | |
| 50 | { | |
| 51 | return _mm512_mask_popcnt_epi16((__m512i) _mm512_setzero_hi(), | |
| 52 | __U, | |
| 53 | __B); | |
| 54 | } | |
| 55 | ||
| 56 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 57 | _mm512_popcnt_epi8(__m512i __A) | |
| 58 | { | |
| 59 | return (__m512i) __builtin_ia32_vpopcntb_512((__v64qi) __A); | |
| 60 | } | |
| 61 | ||
| 62 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 63 | _mm512_mask_popcnt_epi8(__m512i __A, __mmask64 __U, __m512i __B) | |
| 64 | { | |
| 65 | return (__m512i) __builtin_ia32_selectb_512((__mmask64) __U, | |
| 66 | (__v64qi) _mm512_popcnt_epi8(__B), | |
| 67 | (__v64qi) __A); | |
| 68 | } | |
| 69 | ||
| 70 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 71 | _mm512_maskz_popcnt_epi8(__mmask64 __U, __m512i __B) | |
| 72 | { | |
| 73 | return _mm512_mask_popcnt_epi8((__m512i) _mm512_setzero_qi(), | |
| 74 | __U, | |
| 75 | __B); | |
| 76 | } | |
| 77 | ||
| 78 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 79 | _mm512_mask_bitshuffle_epi64_mask(__mmask64 __U, __m512i __A, __m512i __B) | |
| 80 | { | |
| 81 | return (__mmask64) __builtin_ia32_vpshufbitqmb512_mask((__v64qi) __A, | |
| 82 | (__v64qi) __B, | |
| 83 | __U); | |
| 84 | } | |
| 85 | ||
| 86 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 87 | _mm512_bitshuffle_epi64_mask(__m512i __A, __m512i __B) | |
| 88 | { | |
| 89 | return _mm512_mask_bitshuffle_epi64_mask((__mmask64) -1, | |
| 90 | __A, | |
| 91 | __B); | |
| 92 | } | |
| 93 | ||
| 94 | ||
| 95 | #undef __DEFAULT_FN_ATTRS | |
| 96 | ||
| 97 | #endif |
c_headers/avx512bwintrin.h+182-380| ... | ... | @@ -56,293 +56,145 @@ _mm512_setzero_hi(void) { |
| 56 | 56 | |
| 57 | 57 | /* Integer compare */ |
| 58 | 58 | |
| 59 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 60 | _mm512_cmpeq_epi8_mask(__m512i __a, __m512i __b) { | |
| 61 | return (__mmask64)__builtin_ia32_pcmpeqb512_mask((__v64qi)__a, (__v64qi)__b, | |
| 62 | (__mmask64)-1); | |
| 63 | } | |
| 64 | ||
| 65 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 66 | _mm512_mask_cmpeq_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { | |
| 67 | return (__mmask64)__builtin_ia32_pcmpeqb512_mask((__v64qi)__a, (__v64qi)__b, | |
| 68 | __u); | |
| 69 | } | |
| 70 | ||
| 71 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 72 | _mm512_cmpeq_epu8_mask(__m512i __a, __m512i __b) { | |
| 73 | return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 0, | |
| 74 | (__mmask64)-1); | |
| 75 | } | |
| 76 | ||
| 77 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 78 | _mm512_mask_cmpeq_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { | |
| 79 | return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 0, | |
| 80 | __u); | |
| 81 | } | |
| 82 | ||
| 83 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 84 | _mm512_cmpeq_epi16_mask(__m512i __a, __m512i __b) { | |
| 85 | return (__mmask32)__builtin_ia32_pcmpeqw512_mask((__v32hi)__a, (__v32hi)__b, | |
| 86 | (__mmask32)-1); | |
| 87 | } | |
| 88 | ||
| 89 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 90 | _mm512_mask_cmpeq_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { | |
| 91 | return (__mmask32)__builtin_ia32_pcmpeqw512_mask((__v32hi)__a, (__v32hi)__b, | |
| 92 | __u); | |
| 93 | } | |
| 94 | ||
| 95 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 96 | _mm512_cmpeq_epu16_mask(__m512i __a, __m512i __b) { | |
| 97 | return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 0, | |
| 98 | (__mmask32)-1); | |
| 99 | } | |
| 100 | ||
| 101 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 102 | _mm512_mask_cmpeq_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { | |
| 103 | return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 0, | |
| 104 | __u); | |
| 105 | } | |
| 106 | ||
| 107 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 108 | _mm512_cmpge_epi8_mask(__m512i __a, __m512i __b) { | |
| 109 | return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 5, | |
| 110 | (__mmask64)-1); | |
| 111 | } | |
| 112 | ||
| 113 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 114 | _mm512_mask_cmpge_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { | |
| 115 | return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 5, | |
| 116 | __u); | |
| 117 | } | |
| 118 | ||
| 119 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 120 | _mm512_cmpge_epu8_mask(__m512i __a, __m512i __b) { | |
| 121 | return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 5, | |
| 122 | (__mmask64)-1); | |
| 123 | } | |
| 124 | ||
| 125 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 126 | _mm512_mask_cmpge_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { | |
| 127 | return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 5, | |
| 128 | __u); | |
| 129 | } | |
| 130 | ||
| 131 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 132 | _mm512_cmpge_epi16_mask(__m512i __a, __m512i __b) { | |
| 133 | return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 5, | |
| 134 | (__mmask32)-1); | |
| 135 | } | |
| 136 | ||
| 137 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 138 | _mm512_mask_cmpge_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { | |
| 139 | return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 5, | |
| 140 | __u); | |
| 141 | } | |
| 142 | ||
| 143 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 144 | _mm512_cmpge_epu16_mask(__m512i __a, __m512i __b) { | |
| 145 | return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 5, | |
| 146 | (__mmask32)-1); | |
| 147 | } | |
| 148 | ||
| 149 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 150 | _mm512_mask_cmpge_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { | |
| 151 | return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 5, | |
| 152 | __u); | |
| 153 | } | |
| 154 | ||
| 155 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 156 | _mm512_cmpgt_epi8_mask(__m512i __a, __m512i __b) { | |
| 157 | return (__mmask64)__builtin_ia32_pcmpgtb512_mask((__v64qi)__a, (__v64qi)__b, | |
| 158 | (__mmask64)-1); | |
| 159 | } | |
| 160 | ||
| 161 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 162 | _mm512_mask_cmpgt_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { | |
| 163 | return (__mmask64)__builtin_ia32_pcmpgtb512_mask((__v64qi)__a, (__v64qi)__b, | |
| 164 | __u); | |
| 165 | } | |
| 166 | ||
| 167 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 168 | _mm512_cmpgt_epu8_mask(__m512i __a, __m512i __b) { | |
| 169 | return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 6, | |
| 170 | (__mmask64)-1); | |
| 171 | } | |
| 172 | ||
| 173 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 174 | _mm512_mask_cmpgt_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { | |
| 175 | return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 6, | |
| 176 | __u); | |
| 177 | } | |
| 178 | ||
| 179 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 180 | _mm512_cmpgt_epi16_mask(__m512i __a, __m512i __b) { | |
| 181 | return (__mmask32)__builtin_ia32_pcmpgtw512_mask((__v32hi)__a, (__v32hi)__b, | |
| 182 | (__mmask32)-1); | |
| 183 | } | |
| 184 | ||
| 185 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 186 | _mm512_mask_cmpgt_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { | |
| 187 | return (__mmask32)__builtin_ia32_pcmpgtw512_mask((__v32hi)__a, (__v32hi)__b, | |
| 188 | __u); | |
| 189 | } | |
| 190 | ||
| 191 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 192 | _mm512_cmpgt_epu16_mask(__m512i __a, __m512i __b) { | |
| 193 | return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 6, | |
| 194 | (__mmask32)-1); | |
| 195 | } | |
| 196 | ||
| 197 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 198 | _mm512_mask_cmpgt_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { | |
| 199 | return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 6, | |
| 200 | __u); | |
| 201 | } | |
| 202 | ||
| 203 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 204 | _mm512_cmple_epi8_mask(__m512i __a, __m512i __b) { | |
| 205 | return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 2, | |
| 206 | (__mmask64)-1); | |
| 207 | } | |
| 208 | ||
| 209 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 210 | _mm512_mask_cmple_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { | |
| 211 | return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 2, | |
| 212 | __u); | |
| 213 | } | |
| 214 | ||
| 215 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 216 | _mm512_cmple_epu8_mask(__m512i __a, __m512i __b) { | |
| 217 | return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 2, | |
| 218 | (__mmask64)-1); | |
| 219 | } | |
| 220 | ||
| 221 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 222 | _mm512_mask_cmple_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { | |
| 223 | return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 2, | |
| 224 | __u); | |
| 225 | } | |
| 226 | ||
| 227 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 228 | _mm512_cmple_epi16_mask(__m512i __a, __m512i __b) { | |
| 229 | return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 2, | |
| 230 | (__mmask32)-1); | |
| 231 | } | |
| 232 | ||
| 233 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 234 | _mm512_mask_cmple_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { | |
| 235 | return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 2, | |
| 236 | __u); | |
| 237 | } | |
| 238 | ||
| 239 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 240 | _mm512_cmple_epu16_mask(__m512i __a, __m512i __b) { | |
| 241 | return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 2, | |
| 242 | (__mmask32)-1); | |
| 243 | } | |
| 244 | ||
| 245 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 246 | _mm512_mask_cmple_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { | |
| 247 | return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 2, | |
| 248 | __u); | |
| 249 | } | |
| 250 | ||
| 251 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 252 | _mm512_cmplt_epi8_mask(__m512i __a, __m512i __b) { | |
| 253 | return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 1, | |
| 254 | (__mmask64)-1); | |
| 255 | } | |
| 256 | ||
| 257 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 258 | _mm512_mask_cmplt_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { | |
| 259 | return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 1, | |
| 260 | __u); | |
| 261 | } | |
| 262 | ||
| 263 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 264 | _mm512_cmplt_epu8_mask(__m512i __a, __m512i __b) { | |
| 265 | return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 1, | |
| 266 | (__mmask64)-1); | |
| 267 | } | |
| 268 | ||
| 269 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 270 | _mm512_mask_cmplt_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { | |
| 271 | return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 1, | |
| 272 | __u); | |
| 273 | } | |
| 274 | ||
| 275 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 276 | _mm512_cmplt_epi16_mask(__m512i __a, __m512i __b) { | |
| 277 | return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 1, | |
| 278 | (__mmask32)-1); | |
| 279 | } | |
| 280 | ||
| 281 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 282 | _mm512_mask_cmplt_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { | |
| 283 | return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 1, | |
| 284 | __u); | |
| 285 | } | |
| 286 | ||
| 287 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 288 | _mm512_cmplt_epu16_mask(__m512i __a, __m512i __b) { | |
| 289 | return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 1, | |
| 290 | (__mmask32)-1); | |
| 291 | } | |
| 292 | ||
| 293 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 294 | _mm512_mask_cmplt_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { | |
| 295 | return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 1, | |
| 296 | __u); | |
| 297 | } | |
| 59 | #define _mm512_cmp_epi8_mask(a, b, p) __extension__ ({ \ | |
| 60 | (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)(__m512i)(a), \ | |
| 61 | (__v64qi)(__m512i)(b), (int)(p), \ | |
| 62 | (__mmask64)-1); }) | |
| 298 | 63 | |
| 299 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 300 | _mm512_cmpneq_epi8_mask(__m512i __a, __m512i __b) { | |
| 301 | return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 4, | |
| 302 | (__mmask64)-1); | |
| 303 | } | |
| 64 | #define _mm512_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ | |
| 65 | (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)(__m512i)(a), \ | |
| 66 | (__v64qi)(__m512i)(b), (int)(p), \ | |
| 67 | (__mmask64)(m)); }) | |
| 304 | 68 | |
| 305 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 306 | _mm512_mask_cmpneq_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { | |
| 307 | return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 4, | |
| 308 | __u); | |
| 309 | } | |
| 69 | #define _mm512_cmp_epu8_mask(a, b, p) __extension__ ({ \ | |
| 70 | (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)(__m512i)(a), \ | |
| 71 | (__v64qi)(__m512i)(b), (int)(p), \ | |
| 72 | (__mmask64)-1); }) | |
| 310 | 73 | |
| 311 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 312 | _mm512_cmpneq_epu8_mask(__m512i __a, __m512i __b) { | |
| 313 | return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 4, | |
| 314 | (__mmask64)-1); | |
| 315 | } | |
| 74 | #define _mm512_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ | |
| 75 | (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)(__m512i)(a), \ | |
| 76 | (__v64qi)(__m512i)(b), (int)(p), \ | |
| 77 | (__mmask64)(m)); }) | |
| 316 | 78 | |
| 317 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS | |
| 318 | _mm512_mask_cmpneq_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { | |
| 319 | return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 4, | |
| 320 | __u); | |
| 321 | } | |
| 79 | #define _mm512_cmp_epi16_mask(a, b, p) __extension__ ({ \ | |
| 80 | (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)(__m512i)(a), \ | |
| 81 | (__v32hi)(__m512i)(b), (int)(p), \ | |
| 82 | (__mmask32)-1); }) | |
| 322 | 83 | |
| 323 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 324 | _mm512_cmpneq_epi16_mask(__m512i __a, __m512i __b) { | |
| 325 | return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 4, | |
| 326 | (__mmask32)-1); | |
| 327 | } | |
| 84 | #define _mm512_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ | |
| 85 | (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)(__m512i)(a), \ | |
| 86 | (__v32hi)(__m512i)(b), (int)(p), \ | |
| 87 | (__mmask32)(m)); }) | |
| 328 | 88 | |
| 329 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 330 | _mm512_mask_cmpneq_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { | |
| 331 | return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 4, | |
| 332 | __u); | |
| 333 | } | |
| 89 | #define _mm512_cmp_epu16_mask(a, b, p) __extension__ ({ \ | |
| 90 | (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)(__m512i)(a), \ | |
| 91 | (__v32hi)(__m512i)(b), (int)(p), \ | |
| 92 | (__mmask32)-1); }) | |
| 334 | 93 | |
| 335 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 336 | _mm512_cmpneq_epu16_mask(__m512i __a, __m512i __b) { | |
| 337 | return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 4, | |
| 338 | (__mmask32)-1); | |
| 339 | } | |
| 94 | #define _mm512_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ | |
| 95 | (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)(__m512i)(a), \ | |
| 96 | (__v32hi)(__m512i)(b), (int)(p), \ | |
| 97 | (__mmask32)(m)); }) | |
| 340 | 98 | |
| 341 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 342 | _mm512_mask_cmpneq_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { | |
| 343 | return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 4, | |
| 344 | __u); | |
| 345 | } | |
| 99 | #define _mm512_cmpeq_epi8_mask(A, B) \ | |
| 100 | _mm512_cmp_epi8_mask((A), (B), _MM_CMPINT_EQ) | |
| 101 | #define _mm512_mask_cmpeq_epi8_mask(k, A, B) \ | |
| 102 | _mm512_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 103 | #define _mm512_cmpge_epi8_mask(A, B) \ | |
| 104 | _mm512_cmp_epi8_mask((A), (B), _MM_CMPINT_GE) | |
| 105 | #define _mm512_mask_cmpge_epi8_mask(k, A, B) \ | |
| 106 | _mm512_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 107 | #define _mm512_cmpgt_epi8_mask(A, B) \ | |
| 108 | _mm512_cmp_epi8_mask((A), (B), _MM_CMPINT_GT) | |
| 109 | #define _mm512_mask_cmpgt_epi8_mask(k, A, B) \ | |
| 110 | _mm512_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 111 | #define _mm512_cmple_epi8_mask(A, B) \ | |
| 112 | _mm512_cmp_epi8_mask((A), (B), _MM_CMPINT_LE) | |
| 113 | #define _mm512_mask_cmple_epi8_mask(k, A, B) \ | |
| 114 | _mm512_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 115 | #define _mm512_cmplt_epi8_mask(A, B) \ | |
| 116 | _mm512_cmp_epi8_mask((A), (B), _MM_CMPINT_LT) | |
| 117 | #define _mm512_mask_cmplt_epi8_mask(k, A, B) \ | |
| 118 | _mm512_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 119 | #define _mm512_cmpneq_epi8_mask(A, B) \ | |
| 120 | _mm512_cmp_epi8_mask((A), (B), _MM_CMPINT_NE) | |
| 121 | #define _mm512_mask_cmpneq_epi8_mask(k, A, B) \ | |
| 122 | _mm512_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 123 | ||
| 124 | #define _mm512_cmpeq_epu8_mask(A, B) \ | |
| 125 | _mm512_cmp_epu8_mask((A), (B), _MM_CMPINT_EQ) | |
| 126 | #define _mm512_mask_cmpeq_epu8_mask(k, A, B) \ | |
| 127 | _mm512_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 128 | #define _mm512_cmpge_epu8_mask(A, B) \ | |
| 129 | _mm512_cmp_epu8_mask((A), (B), _MM_CMPINT_GE) | |
| 130 | #define _mm512_mask_cmpge_epu8_mask(k, A, B) \ | |
| 131 | _mm512_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 132 | #define _mm512_cmpgt_epu8_mask(A, B) \ | |
| 133 | _mm512_cmp_epu8_mask((A), (B), _MM_CMPINT_GT) | |
| 134 | #define _mm512_mask_cmpgt_epu8_mask(k, A, B) \ | |
| 135 | _mm512_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 136 | #define _mm512_cmple_epu8_mask(A, B) \ | |
| 137 | _mm512_cmp_epu8_mask((A), (B), _MM_CMPINT_LE) | |
| 138 | #define _mm512_mask_cmple_epu8_mask(k, A, B) \ | |
| 139 | _mm512_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 140 | #define _mm512_cmplt_epu8_mask(A, B) \ | |
| 141 | _mm512_cmp_epu8_mask((A), (B), _MM_CMPINT_LT) | |
| 142 | #define _mm512_mask_cmplt_epu8_mask(k, A, B) \ | |
| 143 | _mm512_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 144 | #define _mm512_cmpneq_epu8_mask(A, B) \ | |
| 145 | _mm512_cmp_epu8_mask((A), (B), _MM_CMPINT_NE) | |
| 146 | #define _mm512_mask_cmpneq_epu8_mask(k, A, B) \ | |
| 147 | _mm512_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 148 | ||
| 149 | #define _mm512_cmpeq_epi16_mask(A, B) \ | |
| 150 | _mm512_cmp_epi16_mask((A), (B), _MM_CMPINT_EQ) | |
| 151 | #define _mm512_mask_cmpeq_epi16_mask(k, A, B) \ | |
| 152 | _mm512_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 153 | #define _mm512_cmpge_epi16_mask(A, B) \ | |
| 154 | _mm512_cmp_epi16_mask((A), (B), _MM_CMPINT_GE) | |
| 155 | #define _mm512_mask_cmpge_epi16_mask(k, A, B) \ | |
| 156 | _mm512_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 157 | #define _mm512_cmpgt_epi16_mask(A, B) \ | |
| 158 | _mm512_cmp_epi16_mask((A), (B), _MM_CMPINT_GT) | |
| 159 | #define _mm512_mask_cmpgt_epi16_mask(k, A, B) \ | |
| 160 | _mm512_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 161 | #define _mm512_cmple_epi16_mask(A, B) \ | |
| 162 | _mm512_cmp_epi16_mask((A), (B), _MM_CMPINT_LE) | |
| 163 | #define _mm512_mask_cmple_epi16_mask(k, A, B) \ | |
| 164 | _mm512_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 165 | #define _mm512_cmplt_epi16_mask(A, B) \ | |
| 166 | _mm512_cmp_epi16_mask((A), (B), _MM_CMPINT_LT) | |
| 167 | #define _mm512_mask_cmplt_epi16_mask(k, A, B) \ | |
| 168 | _mm512_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 169 | #define _mm512_cmpneq_epi16_mask(A, B) \ | |
| 170 | _mm512_cmp_epi16_mask((A), (B), _MM_CMPINT_NE) | |
| 171 | #define _mm512_mask_cmpneq_epi16_mask(k, A, B) \ | |
| 172 | _mm512_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 173 | ||
| 174 | #define _mm512_cmpeq_epu16_mask(A, B) \ | |
| 175 | _mm512_cmp_epu16_mask((A), (B), _MM_CMPINT_EQ) | |
| 176 | #define _mm512_mask_cmpeq_epu16_mask(k, A, B) \ | |
| 177 | _mm512_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 178 | #define _mm512_cmpge_epu16_mask(A, B) \ | |
| 179 | _mm512_cmp_epu16_mask((A), (B), _MM_CMPINT_GE) | |
| 180 | #define _mm512_mask_cmpge_epu16_mask(k, A, B) \ | |
| 181 | _mm512_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 182 | #define _mm512_cmpgt_epu16_mask(A, B) \ | |
| 183 | _mm512_cmp_epu16_mask((A), (B), _MM_CMPINT_GT) | |
| 184 | #define _mm512_mask_cmpgt_epu16_mask(k, A, B) \ | |
| 185 | _mm512_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 186 | #define _mm512_cmple_epu16_mask(A, B) \ | |
| 187 | _mm512_cmp_epu16_mask((A), (B), _MM_CMPINT_LE) | |
| 188 | #define _mm512_mask_cmple_epu16_mask(k, A, B) \ | |
| 189 | _mm512_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 190 | #define _mm512_cmplt_epu16_mask(A, B) \ | |
| 191 | _mm512_cmp_epu16_mask((A), (B), _MM_CMPINT_LT) | |
| 192 | #define _mm512_mask_cmplt_epu16_mask(k, A, B) \ | |
| 193 | _mm512_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 194 | #define _mm512_cmpneq_epu16_mask(A, B) \ | |
| 195 | _mm512_cmp_epu16_mask((A), (B), _MM_CMPINT_NE) | |
| 196 | #define _mm512_mask_cmpneq_epu16_mask(k, A, B) \ | |
| 197 | _mm512_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 346 | 198 | |
| 347 | 199 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 348 | 200 | _mm512_add_epi8 (__m512i __A, __m512i __B) { |
| ... | ... | @@ -706,57 +558,55 @@ _mm512_maskz_adds_epu16 (__mmask32 __U, __m512i __A, __m512i __B) |
| 706 | 558 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 707 | 559 | _mm512_avg_epu8 (__m512i __A, __m512i __B) |
| 708 | 560 | { |
| 709 | return (__m512i) __builtin_ia32_pavgb512_mask ((__v64qi) __A, | |
| 710 | (__v64qi) __B, | |
| 711 | (__v64qi) _mm512_setzero_qi(), | |
| 712 | (__mmask64) -1); | |
| 561 | typedef unsigned short __v64hu __attribute__((__vector_size__(128))); | |
| 562 | return (__m512i)__builtin_convertvector( | |
| 563 | ((__builtin_convertvector((__v64qu) __A, __v64hu) + | |
| 564 | __builtin_convertvector((__v64qu) __B, __v64hu)) + 1) | |
| 565 | >> 1, __v64qu); | |
| 713 | 566 | } |
| 714 | 567 | |
| 715 | 568 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 716 | 569 | _mm512_mask_avg_epu8 (__m512i __W, __mmask64 __U, __m512i __A, |
| 717 | 570 | __m512i __B) |
| 718 | 571 | { |
| 719 | return (__m512i) __builtin_ia32_pavgb512_mask ((__v64qi) __A, | |
| 720 | (__v64qi) __B, | |
| 721 | (__v64qi) __W, | |
| 722 | (__mmask64) __U); | |
| 572 | return (__m512i)__builtin_ia32_selectb_512((__mmask64)__U, | |
| 573 | (__v64qi)_mm512_avg_epu8(__A, __B), | |
| 574 | (__v64qi)__W); | |
| 723 | 575 | } |
| 724 | 576 | |
| 725 | 577 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 726 | 578 | _mm512_maskz_avg_epu8 (__mmask64 __U, __m512i __A, __m512i __B) |
| 727 | 579 | { |
| 728 | return (__m512i) __builtin_ia32_pavgb512_mask ((__v64qi) __A, | |
| 729 | (__v64qi) __B, | |
| 730 | (__v64qi) _mm512_setzero_qi(), | |
| 731 | (__mmask64) __U); | |
| 580 | return (__m512i)__builtin_ia32_selectb_512((__mmask64)__U, | |
| 581 | (__v64qi)_mm512_avg_epu8(__A, __B), | |
| 582 | (__v64qi)_mm512_setzero_qi()); | |
| 732 | 583 | } |
| 733 | 584 | |
| 734 | 585 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 735 | 586 | _mm512_avg_epu16 (__m512i __A, __m512i __B) |
| 736 | 587 | { |
| 737 | return (__m512i) __builtin_ia32_pavgw512_mask ((__v32hi) __A, | |
| 738 | (__v32hi) __B, | |
| 739 | (__v32hi) _mm512_setzero_hi(), | |
| 740 | (__mmask32) -1); | |
| 588 | typedef unsigned int __v32su __attribute__((__vector_size__(128))); | |
| 589 | return (__m512i)__builtin_convertvector( | |
| 590 | ((__builtin_convertvector((__v32hu) __A, __v32su) + | |
| 591 | __builtin_convertvector((__v32hu) __B, __v32su)) + 1) | |
| 592 | >> 1, __v32hu); | |
| 741 | 593 | } |
| 742 | 594 | |
| 743 | 595 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 744 | 596 | _mm512_mask_avg_epu16 (__m512i __W, __mmask32 __U, __m512i __A, |
| 745 | 597 | __m512i __B) |
| 746 | 598 | { |
| 747 | return (__m512i) __builtin_ia32_pavgw512_mask ((__v32hi) __A, | |
| 748 | (__v32hi) __B, | |
| 749 | (__v32hi) __W, | |
| 750 | (__mmask32) __U); | |
| 599 | return (__m512i)__builtin_ia32_selectw_512((__mmask32)__U, | |
| 600 | (__v32hi)_mm512_avg_epu16(__A, __B), | |
| 601 | (__v32hi)__W); | |
| 751 | 602 | } |
| 752 | 603 | |
| 753 | 604 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 754 | 605 | _mm512_maskz_avg_epu16 (__mmask32 __U, __m512i __A, __m512i __B) |
| 755 | 606 | { |
| 756 | return (__m512i) __builtin_ia32_pavgw512_mask ((__v32hi) __A, | |
| 757 | (__v32hi) __B, | |
| 758 | (__v32hi) _mm512_setzero_hi(), | |
| 759 | (__mmask32) __U); | |
| 607 | return (__m512i)__builtin_ia32_selectw_512((__mmask32)__U, | |
| 608 | (__v32hi)_mm512_avg_epu16(__A, __B), | |
| 609 | (__v32hi) _mm512_setzero_hi()); | |
| 760 | 610 | } |
| 761 | 611 | |
| 762 | 612 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| ... | ... | @@ -1543,46 +1393,6 @@ _mm512_maskz_cvtepu8_epi16(__mmask32 __U, __m256i __A) |
| 1543 | 1393 | } |
| 1544 | 1394 | |
| 1545 | 1395 | |
| 1546 | #define _mm512_cmp_epi8_mask(a, b, p) __extension__ ({ \ | |
| 1547 | (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)(__m512i)(a), \ | |
| 1548 | (__v64qi)(__m512i)(b), (int)(p), \ | |
| 1549 | (__mmask64)-1); }) | |
| 1550 | ||
| 1551 | #define _mm512_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ | |
| 1552 | (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)(__m512i)(a), \ | |
| 1553 | (__v64qi)(__m512i)(b), (int)(p), \ | |
| 1554 | (__mmask64)(m)); }) | |
| 1555 | ||
| 1556 | #define _mm512_cmp_epu8_mask(a, b, p) __extension__ ({ \ | |
| 1557 | (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)(__m512i)(a), \ | |
| 1558 | (__v64qi)(__m512i)(b), (int)(p), \ | |
| 1559 | (__mmask64)-1); }) | |
| 1560 | ||
| 1561 | #define _mm512_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ | |
| 1562 | (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)(__m512i)(a), \ | |
| 1563 | (__v64qi)(__m512i)(b), (int)(p), \ | |
| 1564 | (__mmask64)(m)); }) | |
| 1565 | ||
| 1566 | #define _mm512_cmp_epi16_mask(a, b, p) __extension__ ({ \ | |
| 1567 | (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)(__m512i)(a), \ | |
| 1568 | (__v32hi)(__m512i)(b), (int)(p), \ | |
| 1569 | (__mmask32)-1); }) | |
| 1570 | ||
| 1571 | #define _mm512_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ | |
| 1572 | (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)(__m512i)(a), \ | |
| 1573 | (__v32hi)(__m512i)(b), (int)(p), \ | |
| 1574 | (__mmask32)(m)); }) | |
| 1575 | ||
| 1576 | #define _mm512_cmp_epu16_mask(a, b, p) __extension__ ({ \ | |
| 1577 | (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)(__m512i)(a), \ | |
| 1578 | (__v32hi)(__m512i)(b), (int)(p), \ | |
| 1579 | (__mmask32)-1); }) | |
| 1580 | ||
| 1581 | #define _mm512_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ | |
| 1582 | (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)(__m512i)(a), \ | |
| 1583 | (__v32hi)(__m512i)(b), (int)(p), \ | |
| 1584 | (__mmask32)(m)); }) | |
| 1585 | ||
| 1586 | 1396 | #define _mm512_shufflehi_epi16(A, imm) __extension__ ({ \ |
| 1587 | 1397 | (__m512i)__builtin_shufflevector((__v32hi)(__m512i)(A), \ |
| 1588 | 1398 | (__v32hi)_mm512_undefined_epi32(), \ |
| ... | ... | @@ -2028,32 +1838,29 @@ _mm512_maskz_mov_epi8 (__mmask64 __U, __m512i __A) |
| 2028 | 1838 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 2029 | 1839 | _mm512_mask_set1_epi8 (__m512i __O, __mmask64 __M, char __A) |
| 2030 | 1840 | { |
| 2031 | return (__m512i) __builtin_ia32_pbroadcastb512_gpr_mask (__A, | |
| 2032 | (__v64qi) __O, | |
| 2033 | __M); | |
| 1841 | return (__m512i) __builtin_ia32_selectb_512(__M, | |
| 1842 | (__v64qi)_mm512_set1_epi8(__A), | |
| 1843 | (__v64qi) __O); | |
| 2034 | 1844 | } |
| 2035 | 1845 | |
| 2036 | 1846 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 2037 | 1847 | _mm512_maskz_set1_epi8 (__mmask64 __M, char __A) |
| 2038 | 1848 | { |
| 2039 | return (__m512i) __builtin_ia32_pbroadcastb512_gpr_mask (__A, | |
| 2040 | (__v64qi) | |
| 2041 | _mm512_setzero_qi(), | |
| 2042 | __M); | |
| 1849 | return (__m512i) __builtin_ia32_selectb_512(__M, | |
| 1850 | (__v64qi) _mm512_set1_epi8(__A), | |
| 1851 | (__v64qi) _mm512_setzero_si512()); | |
| 2043 | 1852 | } |
| 2044 | 1853 | |
| 2045 | 1854 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS |
| 2046 | 1855 | _mm512_kunpackd (__mmask64 __A, __mmask64 __B) |
| 2047 | 1856 | { |
| 2048 | return (__mmask64) __builtin_ia32_kunpckdi ((__mmask64) __A, | |
| 2049 | (__mmask64) __B); | |
| 1857 | return (__mmask64) (( __A & 0xFFFFFFFF) | ( __B << 32)); | |
| 2050 | 1858 | } |
| 2051 | 1859 | |
| 2052 | 1860 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS |
| 2053 | 1861 | _mm512_kunpackw (__mmask32 __A, __mmask32 __B) |
| 2054 | 1862 | { |
| 2055 | return (__mmask32) __builtin_ia32_kunpcksi ((__mmask32) __A, | |
| 2056 | (__mmask32) __B); | |
| 1863 | return (__mmask32) (( __A & 0xFFFF) | ( __B << 16)); | |
| 2057 | 1864 | } |
| 2058 | 1865 | |
| 2059 | 1866 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| ... | ... | @@ -2108,61 +1915,56 @@ _mm512_mask_storeu_epi8 (void *__P, __mmask64 __U, __m512i __A) |
| 2108 | 1915 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS |
| 2109 | 1916 | _mm512_test_epi8_mask (__m512i __A, __m512i __B) |
| 2110 | 1917 | { |
| 2111 | return (__mmask64) __builtin_ia32_ptestmb512 ((__v64qi) __A, | |
| 2112 | (__v64qi) __B, | |
| 2113 | (__mmask64) -1); | |
| 1918 | return _mm512_cmpneq_epi8_mask (_mm512_and_epi32 (__A, __B), | |
| 1919 | _mm512_setzero_qi()); | |
| 2114 | 1920 | } |
| 2115 | 1921 | |
| 2116 | 1922 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS |
| 2117 | 1923 | _mm512_mask_test_epi8_mask (__mmask64 __U, __m512i __A, __m512i __B) |
| 2118 | 1924 | { |
| 2119 | return (__mmask64) __builtin_ia32_ptestmb512 ((__v64qi) __A, | |
| 2120 | (__v64qi) __B, __U); | |
| 1925 | return _mm512_mask_cmpneq_epi8_mask (__U, _mm512_and_epi32 (__A, __B), | |
| 1926 | _mm512_setzero_qi()); | |
| 2121 | 1927 | } |
| 2122 | 1928 | |
| 2123 | 1929 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS |
| 2124 | 1930 | _mm512_test_epi16_mask (__m512i __A, __m512i __B) |
| 2125 | 1931 | { |
| 2126 | return (__mmask32) __builtin_ia32_ptestmw512 ((__v32hi) __A, | |
| 2127 | (__v32hi) __B, | |
| 2128 | (__mmask32) -1); | |
| 1932 | return _mm512_cmpneq_epi16_mask (_mm512_and_epi32 (__A, __B), | |
| 1933 | _mm512_setzero_qi()); | |
| 2129 | 1934 | } |
| 2130 | 1935 | |
| 2131 | 1936 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS |
| 2132 | 1937 | _mm512_mask_test_epi16_mask (__mmask32 __U, __m512i __A, __m512i __B) |
| 2133 | 1938 | { |
| 2134 | return (__mmask32) __builtin_ia32_ptestmw512 ((__v32hi) __A, | |
| 2135 | (__v32hi) __B, __U); | |
| 1939 | return _mm512_mask_cmpneq_epi16_mask (__U, _mm512_and_epi32 (__A, __B), | |
| 1940 | _mm512_setzero_qi()); | |
| 2136 | 1941 | } |
| 2137 | 1942 | |
| 2138 | 1943 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS |
| 2139 | 1944 | _mm512_testn_epi8_mask (__m512i __A, __m512i __B) |
| 2140 | 1945 | { |
| 2141 | return (__mmask64) __builtin_ia32_ptestnmb512 ((__v64qi) __A, | |
| 2142 | (__v64qi) __B, | |
| 2143 | (__mmask64) -1); | |
| 1946 | return _mm512_cmpeq_epi8_mask (_mm512_and_epi32 (__A, __B), _mm512_setzero_qi()); | |
| 2144 | 1947 | } |
| 2145 | 1948 | |
| 2146 | 1949 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS |
| 2147 | 1950 | _mm512_mask_testn_epi8_mask (__mmask64 __U, __m512i __A, __m512i __B) |
| 2148 | 1951 | { |
| 2149 | return (__mmask64) __builtin_ia32_ptestnmb512 ((__v64qi) __A, | |
| 2150 | (__v64qi) __B, __U); | |
| 1952 | return _mm512_mask_cmpeq_epi8_mask (__U, _mm512_and_epi32 (__A, __B), | |
| 1953 | _mm512_setzero_qi()); | |
| 2151 | 1954 | } |
| 2152 | 1955 | |
| 2153 | 1956 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS |
| 2154 | 1957 | _mm512_testn_epi16_mask (__m512i __A, __m512i __B) |
| 2155 | 1958 | { |
| 2156 | return (__mmask32) __builtin_ia32_ptestnmw512 ((__v32hi) __A, | |
| 2157 | (__v32hi) __B, | |
| 2158 | (__mmask32) -1); | |
| 1959 | return _mm512_cmpeq_epi16_mask (_mm512_and_epi32 (__A, __B), | |
| 1960 | _mm512_setzero_qi()); | |
| 2159 | 1961 | } |
| 2160 | 1962 | |
| 2161 | 1963 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS |
| 2162 | 1964 | _mm512_mask_testn_epi16_mask (__mmask32 __U, __m512i __A, __m512i __B) |
| 2163 | 1965 | { |
| 2164 | return (__mmask32) __builtin_ia32_ptestnmw512 ((__v32hi) __A, | |
| 2165 | (__v32hi) __B, __U); | |
| 1966 | return _mm512_mask_cmpeq_epi16_mask (__U, _mm512_and_epi32 (__A, __B), | |
| 1967 | _mm512_setzero_qi()); | |
| 2166 | 1968 | } |
| 2167 | 1969 | |
| 2168 | 1970 | static __inline__ __mmask64 __DEFAULT_FN_ATTRS |
| ... | ... | @@ -2219,17 +2021,17 @@ _mm512_maskz_broadcastb_epi8 (__mmask64 __M, __m128i __A) |
| 2219 | 2021 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 2220 | 2022 | _mm512_mask_set1_epi16 (__m512i __O, __mmask32 __M, short __A) |
| 2221 | 2023 | { |
| 2222 | return (__m512i) __builtin_ia32_pbroadcastw512_gpr_mask (__A, | |
| 2223 | (__v32hi) __O, | |
| 2224 | __M); | |
| 2024 | return (__m512i) __builtin_ia32_selectw_512(__M, | |
| 2025 | (__v32hi) _mm512_set1_epi16(__A), | |
| 2026 | (__v32hi) __O); | |
| 2225 | 2027 | } |
| 2226 | 2028 | |
| 2227 | 2029 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 2228 | 2030 | _mm512_maskz_set1_epi16 (__mmask32 __M, short __A) |
| 2229 | 2031 | { |
| 2230 | return (__m512i) __builtin_ia32_pbroadcastw512_gpr_mask (__A, | |
| 2231 | (__v32hi) _mm512_setzero_hi(), | |
| 2232 | __M); | |
| 2032 | return (__m512i) __builtin_ia32_selectw_512(__M, | |
| 2033 | (__v32hi) _mm512_set1_epi16(__A), | |
| 2034 | (__v32hi) _mm512_setzero_si512()); | |
| 2233 | 2035 | } |
| 2234 | 2036 | |
| 2235 | 2037 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
c_headers/avx512cdintrin.h+3-2| ... | ... | @@ -130,13 +130,14 @@ _mm512_maskz_lzcnt_epi64 (__mmask8 __U, __m512i __A) |
| 130 | 130 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 131 | 131 | _mm512_broadcastmb_epi64 (__mmask8 __A) |
| 132 | 132 | { |
| 133 | return (__m512i) __builtin_ia32_broadcastmb512 (__A); | |
| 133 | return (__m512i) _mm512_set1_epi64((long long) __A); | |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | 136 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 137 | 137 | _mm512_broadcastmw_epi32 (__mmask16 __A) |
| 138 | 138 | { |
| 139 | return (__m512i) __builtin_ia32_broadcastmw512 (__A); | |
| 139 | return (__m512i) _mm512_set1_epi32((int) __A); | |
| 140 | ||
| 140 | 141 | } |
| 141 | 142 | |
| 142 | 143 | #undef __DEFAULT_FN_ATTRS |
c_headers/avx512dqintrin.h+20-18| ... | ... | @@ -973,25 +973,26 @@ _mm512_movepi64_mask (__m512i __A) |
| 973 | 973 | static __inline__ __m512 __DEFAULT_FN_ATTRS |
| 974 | 974 | _mm512_broadcast_f32x2 (__m128 __A) |
| 975 | 975 | { |
| 976 | return (__m512) __builtin_ia32_broadcastf32x2_512_mask ((__v4sf) __A, | |
| 977 | (__v16sf)_mm512_undefined_ps(), | |
| 978 | (__mmask16) -1); | |
| 976 | return (__m512)__builtin_shufflevector((__v4sf)__A, | |
| 977 | (__v4sf)_mm_undefined_ps(), | |
| 978 | 0, 1, 0, 1, 0, 1, 0, 1, | |
| 979 | 0, 1, 0, 1, 0, 1, 0, 1); | |
| 979 | 980 | } |
| 980 | 981 | |
| 981 | 982 | static __inline__ __m512 __DEFAULT_FN_ATTRS |
| 982 | 983 | _mm512_mask_broadcast_f32x2 (__m512 __O, __mmask16 __M, __m128 __A) |
| 983 | 984 | { |
| 984 | return (__m512) __builtin_ia32_broadcastf32x2_512_mask ((__v4sf) __A, | |
| 985 | (__v16sf) | |
| 986 | __O, __M); | |
| 985 | return (__m512)__builtin_ia32_selectps_512((__mmask16)__M, | |
| 986 | (__v16sf)_mm512_broadcast_f32x2(__A), | |
| 987 | (__v16sf)__O); | |
| 987 | 988 | } |
| 988 | 989 | |
| 989 | 990 | static __inline__ __m512 __DEFAULT_FN_ATTRS |
| 990 | 991 | _mm512_maskz_broadcast_f32x2 (__mmask16 __M, __m128 __A) |
| 991 | 992 | { |
| 992 | return (__m512) __builtin_ia32_broadcastf32x2_512_mask ((__v4sf) __A, | |
| 993 | (__v16sf)_mm512_setzero_ps (), | |
| 994 | __M); | |
| 993 | return (__m512)__builtin_ia32_selectps_512((__mmask16)__M, | |
| 994 | (__v16sf)_mm512_broadcast_f32x2(__A), | |
| 995 | (__v16sf)_mm512_setzero_ps()); | |
| 995 | 996 | } |
| 996 | 997 | |
| 997 | 998 | static __inline__ __m512 __DEFAULT_FN_ATTRS |
| ... | ... | @@ -1044,25 +1045,26 @@ _mm512_maskz_broadcast_f64x2(__mmask8 __M, __m128d __A) |
| 1044 | 1045 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 1045 | 1046 | _mm512_broadcast_i32x2 (__m128i __A) |
| 1046 | 1047 | { |
| 1047 | return (__m512i) __builtin_ia32_broadcasti32x2_512_mask ((__v4si) __A, | |
| 1048 | (__v16si)_mm512_setzero_si512(), | |
| 1049 | (__mmask16) -1); | |
| 1048 | return (__m512i)__builtin_shufflevector((__v4si)__A, | |
| 1049 | (__v4si)_mm_undefined_si128(), | |
| 1050 | 0, 1, 0, 1, 0, 1, 0, 1, | |
| 1051 | 0, 1, 0, 1, 0, 1, 0, 1); | |
| 1050 | 1052 | } |
| 1051 | 1053 | |
| 1052 | 1054 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 1053 | 1055 | _mm512_mask_broadcast_i32x2 (__m512i __O, __mmask16 __M, __m128i __A) |
| 1054 | 1056 | { |
| 1055 | return (__m512i) __builtin_ia32_broadcasti32x2_512_mask ((__v4si) __A, | |
| 1056 | (__v16si) | |
| 1057 | __O, __M); | |
| 1057 | return (__m512i)__builtin_ia32_selectd_512((__mmask16)__M, | |
| 1058 | (__v16si)_mm512_broadcast_i32x2(__A), | |
| 1059 | (__v16si)__O); | |
| 1058 | 1060 | } |
| 1059 | 1061 | |
| 1060 | 1062 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 1061 | 1063 | _mm512_maskz_broadcast_i32x2 (__mmask16 __M, __m128i __A) |
| 1062 | 1064 | { |
| 1063 | return (__m512i) __builtin_ia32_broadcasti32x2_512_mask ((__v4si) __A, | |
| 1064 | (__v16si)_mm512_setzero_si512 (), | |
| 1065 | __M); | |
| 1065 | return (__m512i)__builtin_ia32_selectd_512((__mmask16)__M, | |
| 1066 | (__v16si)_mm512_broadcast_i32x2(__A), | |
| 1067 | (__v16si)_mm512_setzero_si512()); | |
| 1066 | 1068 | } |
| 1067 | 1069 | |
| 1068 | 1070 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
c_headers/avx512fintrin.h+255-420| ... | ... | @@ -258,25 +258,6 @@ _mm512_maskz_broadcastq_epi64 (__mmask8 __M, __m128i __A) |
| 258 | 258 | (__v8di) _mm512_setzero_si512()); |
| 259 | 259 | } |
| 260 | 260 | |
| 261 | static __inline __m512i __DEFAULT_FN_ATTRS | |
| 262 | _mm512_maskz_set1_epi32(__mmask16 __M, int __A) | |
| 263 | { | |
| 264 | return (__m512i) __builtin_ia32_pbroadcastd512_gpr_mask (__A, | |
| 265 | (__v16si) | |
| 266 | _mm512_setzero_si512 (), | |
| 267 | __M); | |
| 268 | } | |
| 269 | ||
| 270 | #ifdef __x86_64__ | |
| 271 | static __inline __m512i __DEFAULT_FN_ATTRS | |
| 272 | _mm512_maskz_set1_epi64(__mmask8 __M, long long __A) | |
| 273 | { | |
| 274 | return (__m512i) __builtin_ia32_pbroadcastq512_gpr_mask (__A, | |
| 275 | (__v8di) | |
| 276 | _mm512_setzero_si512 (), | |
| 277 | __M); | |
| 278 | } | |
| 279 | #endif | |
| 280 | 261 | |
| 281 | 262 | static __inline __m512 __DEFAULT_FN_ATTRS |
| 282 | 263 | _mm512_setzero_ps(void) |
| ... | ... | @@ -335,12 +316,30 @@ _mm512_set1_epi32(int __s) |
| 335 | 316 | __s, __s, __s, __s, __s, __s, __s, __s }; |
| 336 | 317 | } |
| 337 | 318 | |
| 319 | static __inline __m512i __DEFAULT_FN_ATTRS | |
| 320 | _mm512_maskz_set1_epi32(__mmask16 __M, int __A) | |
| 321 | { | |
| 322 | return (__m512i)__builtin_ia32_selectd_512(__M, | |
| 323 | (__v16si)_mm512_set1_epi32(__A), | |
| 324 | (__v16si)_mm512_setzero_si512()); | |
| 325 | } | |
| 326 | ||
| 338 | 327 | static __inline __m512i __DEFAULT_FN_ATTRS |
| 339 | 328 | _mm512_set1_epi64(long long __d) |
| 340 | 329 | { |
| 341 | 330 | return (__m512i)(__v8di){ __d, __d, __d, __d, __d, __d, __d, __d }; |
| 342 | 331 | } |
| 343 | 332 | |
| 333 | #ifdef __x86_64__ | |
| 334 | static __inline __m512i __DEFAULT_FN_ATTRS | |
| 335 | _mm512_maskz_set1_epi64(__mmask8 __M, long long __A) | |
| 336 | { | |
| 337 | return (__m512i)__builtin_ia32_selectq_512(__M, | |
| 338 | (__v8di)_mm512_set1_epi64(__A), | |
| 339 | (__v8di)_mm512_setzero_si512()); | |
| 340 | } | |
| 341 | #endif | |
| 342 | ||
| 344 | 343 | static __inline__ __m512 __DEFAULT_FN_ATTRS |
| 345 | 344 | _mm512_broadcastss_ps(__m128 __A) |
| 346 | 345 | { |
| ... | ... | @@ -4544,37 +4543,6 @@ _mm512_maskz_unpacklo_epi64 (__mmask8 __U, __m512i __A, __m512i __B) |
| 4544 | 4543 | (__v8di)_mm512_setzero_si512()); |
| 4545 | 4544 | } |
| 4546 | 4545 | |
| 4547 | /* Bit Test */ | |
| 4548 | ||
| 4549 | static __inline __mmask16 __DEFAULT_FN_ATTRS | |
| 4550 | _mm512_test_epi32_mask(__m512i __A, __m512i __B) | |
| 4551 | { | |
| 4552 | return (__mmask16) __builtin_ia32_ptestmd512 ((__v16si) __A, | |
| 4553 | (__v16si) __B, | |
| 4554 | (__mmask16) -1); | |
| 4555 | } | |
| 4556 | ||
| 4557 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4558 | _mm512_mask_test_epi32_mask (__mmask16 __U, __m512i __A, __m512i __B) | |
| 4559 | { | |
| 4560 | return (__mmask16) __builtin_ia32_ptestmd512 ((__v16si) __A, | |
| 4561 | (__v16si) __B, __U); | |
| 4562 | } | |
| 4563 | ||
| 4564 | static __inline __mmask8 __DEFAULT_FN_ATTRS | |
| 4565 | _mm512_test_epi64_mask(__m512i __A, __m512i __B) | |
| 4566 | { | |
| 4567 | return (__mmask8) __builtin_ia32_ptestmq512 ((__v8di) __A, | |
| 4568 | (__v8di) __B, | |
| 4569 | (__mmask8) -1); | |
| 4570 | } | |
| 4571 | ||
| 4572 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 4573 | _mm512_mask_test_epi64_mask (__mmask8 __U, __m512i __A, __m512i __B) | |
| 4574 | { | |
| 4575 | return (__mmask8) __builtin_ia32_ptestmq512 ((__v8di) __A, (__v8di) __B, __U); | |
| 4576 | } | |
| 4577 | ||
| 4578 | 4546 | |
| 4579 | 4547 | /* SIMD load ops */ |
| 4580 | 4548 | |
| ... | ... | @@ -4845,293 +4813,105 @@ _mm512_knot(__mmask16 __M) |
| 4845 | 4813 | |
| 4846 | 4814 | /* Integer compare */ |
| 4847 | 4815 | |
| 4848 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4849 | _mm512_cmpeq_epi32_mask(__m512i __a, __m512i __b) { | |
| 4850 | return (__mmask16)__builtin_ia32_pcmpeqd512_mask((__v16si)__a, (__v16si)__b, | |
| 4851 | (__mmask16)-1); | |
| 4852 | } | |
| 4853 | ||
| 4854 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4855 | _mm512_mask_cmpeq_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { | |
| 4856 | return (__mmask16)__builtin_ia32_pcmpeqd512_mask((__v16si)__a, (__v16si)__b, | |
| 4857 | __u); | |
| 4858 | } | |
| 4859 | ||
| 4860 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4861 | _mm512_cmpeq_epu32_mask(__m512i __a, __m512i __b) { | |
| 4862 | return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 0, | |
| 4863 | (__mmask16)-1); | |
| 4864 | } | |
| 4865 | ||
| 4866 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4867 | _mm512_mask_cmpeq_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { | |
| 4868 | return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 0, | |
| 4869 | __u); | |
| 4870 | } | |
| 4871 | ||
| 4872 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 4873 | _mm512_mask_cmpeq_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { | |
| 4874 | return (__mmask8)__builtin_ia32_pcmpeqq512_mask((__v8di)__a, (__v8di)__b, | |
| 4875 | __u); | |
| 4876 | } | |
| 4877 | ||
| 4878 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 4879 | _mm512_cmpeq_epi64_mask(__m512i __a, __m512i __b) { | |
| 4880 | return (__mmask8)__builtin_ia32_pcmpeqq512_mask((__v8di)__a, (__v8di)__b, | |
| 4881 | (__mmask8)-1); | |
| 4882 | } | |
| 4883 | ||
| 4884 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 4885 | _mm512_cmpeq_epu64_mask(__m512i __a, __m512i __b) { | |
| 4886 | return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 0, | |
| 4887 | (__mmask8)-1); | |
| 4888 | } | |
| 4889 | ||
| 4890 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 4891 | _mm512_mask_cmpeq_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { | |
| 4892 | return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 0, | |
| 4893 | __u); | |
| 4894 | } | |
| 4895 | ||
| 4896 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4897 | _mm512_cmpge_epi32_mask(__m512i __a, __m512i __b) { | |
| 4898 | return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 5, | |
| 4899 | (__mmask16)-1); | |
| 4900 | } | |
| 4901 | ||
| 4902 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4903 | _mm512_mask_cmpge_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { | |
| 4904 | return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 5, | |
| 4905 | __u); | |
| 4906 | } | |
| 4907 | ||
| 4908 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4909 | _mm512_cmpge_epu32_mask(__m512i __a, __m512i __b) { | |
| 4910 | return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 5, | |
| 4911 | (__mmask16)-1); | |
| 4912 | } | |
| 4913 | ||
| 4914 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4915 | _mm512_mask_cmpge_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { | |
| 4916 | return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 5, | |
| 4917 | __u); | |
| 4918 | } | |
| 4919 | ||
| 4920 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 4921 | _mm512_cmpge_epi64_mask(__m512i __a, __m512i __b) { | |
| 4922 | return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 5, | |
| 4923 | (__mmask8)-1); | |
| 4924 | } | |
| 4925 | ||
| 4926 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 4927 | _mm512_mask_cmpge_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { | |
| 4928 | return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 5, | |
| 4929 | __u); | |
| 4930 | } | |
| 4931 | ||
| 4932 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 4933 | _mm512_cmpge_epu64_mask(__m512i __a, __m512i __b) { | |
| 4934 | return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 5, | |
| 4935 | (__mmask8)-1); | |
| 4936 | } | |
| 4937 | ||
| 4938 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 4939 | _mm512_mask_cmpge_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { | |
| 4940 | return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 5, | |
| 4941 | __u); | |
| 4942 | } | |
| 4943 | ||
| 4944 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4945 | _mm512_cmpgt_epi32_mask(__m512i __a, __m512i __b) { | |
| 4946 | return (__mmask16)__builtin_ia32_pcmpgtd512_mask((__v16si)__a, (__v16si)__b, | |
| 4947 | (__mmask16)-1); | |
| 4948 | } | |
| 4949 | ||
| 4950 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4951 | _mm512_mask_cmpgt_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { | |
| 4952 | return (__mmask16)__builtin_ia32_pcmpgtd512_mask((__v16si)__a, (__v16si)__b, | |
| 4953 | __u); | |
| 4954 | } | |
| 4955 | ||
| 4956 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4957 | _mm512_cmpgt_epu32_mask(__m512i __a, __m512i __b) { | |
| 4958 | return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 6, | |
| 4959 | (__mmask16)-1); | |
| 4960 | } | |
| 4961 | ||
| 4962 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4963 | _mm512_mask_cmpgt_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { | |
| 4964 | return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 6, | |
| 4965 | __u); | |
| 4966 | } | |
| 4967 | ||
| 4968 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 4969 | _mm512_mask_cmpgt_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { | |
| 4970 | return (__mmask8)__builtin_ia32_pcmpgtq512_mask((__v8di)__a, (__v8di)__b, | |
| 4971 | __u); | |
| 4972 | } | |
| 4973 | ||
| 4974 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 4975 | _mm512_cmpgt_epi64_mask(__m512i __a, __m512i __b) { | |
| 4976 | return (__mmask8)__builtin_ia32_pcmpgtq512_mask((__v8di)__a, (__v8di)__b, | |
| 4977 | (__mmask8)-1); | |
| 4978 | } | |
| 4979 | ||
| 4980 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 4981 | _mm512_cmpgt_epu64_mask(__m512i __a, __m512i __b) { | |
| 4982 | return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 6, | |
| 4983 | (__mmask8)-1); | |
| 4984 | } | |
| 4985 | ||
| 4986 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 4987 | _mm512_mask_cmpgt_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { | |
| 4988 | return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 6, | |
| 4989 | __u); | |
| 4990 | } | |
| 4991 | ||
| 4992 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4993 | _mm512_cmple_epi32_mask(__m512i __a, __m512i __b) { | |
| 4994 | return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 2, | |
| 4995 | (__mmask16)-1); | |
| 4996 | } | |
| 4997 | ||
| 4998 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 4999 | _mm512_mask_cmple_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { | |
| 5000 | return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 2, | |
| 5001 | __u); | |
| 5002 | } | |
| 5003 | ||
| 5004 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 5005 | _mm512_cmple_epu32_mask(__m512i __a, __m512i __b) { | |
| 5006 | return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 2, | |
| 5007 | (__mmask16)-1); | |
| 5008 | } | |
| 5009 | ||
| 5010 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 5011 | _mm512_mask_cmple_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { | |
| 5012 | return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 2, | |
| 5013 | __u); | |
| 5014 | } | |
| 5015 | ||
| 5016 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 5017 | _mm512_cmple_epi64_mask(__m512i __a, __m512i __b) { | |
| 5018 | return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 2, | |
| 5019 | (__mmask8)-1); | |
| 5020 | } | |
| 5021 | ||
| 5022 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 5023 | _mm512_mask_cmple_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { | |
| 5024 | return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 2, | |
| 5025 | __u); | |
| 5026 | } | |
| 5027 | ||
| 5028 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 5029 | _mm512_cmple_epu64_mask(__m512i __a, __m512i __b) { | |
| 5030 | return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 2, | |
| 5031 | (__mmask8)-1); | |
| 5032 | } | |
| 5033 | ||
| 5034 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 5035 | _mm512_mask_cmple_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { | |
| 5036 | return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 2, | |
| 5037 | __u); | |
| 5038 | } | |
| 5039 | ||
| 5040 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 5041 | _mm512_cmplt_epi32_mask(__m512i __a, __m512i __b) { | |
| 5042 | return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 1, | |
| 5043 | (__mmask16)-1); | |
| 5044 | } | |
| 5045 | ||
| 5046 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 5047 | _mm512_mask_cmplt_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { | |
| 5048 | return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 1, | |
| 5049 | __u); | |
| 5050 | } | |
| 5051 | ||
| 5052 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 5053 | _mm512_cmplt_epu32_mask(__m512i __a, __m512i __b) { | |
| 5054 | return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 1, | |
| 5055 | (__mmask16)-1); | |
| 5056 | } | |
| 5057 | ||
| 5058 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 5059 | _mm512_mask_cmplt_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { | |
| 5060 | return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 1, | |
| 5061 | __u); | |
| 5062 | } | |
| 5063 | ||
| 5064 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 5065 | _mm512_cmplt_epi64_mask(__m512i __a, __m512i __b) { | |
| 5066 | return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 1, | |
| 5067 | (__mmask8)-1); | |
| 5068 | } | |
| 5069 | ||
| 5070 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 5071 | _mm512_mask_cmplt_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { | |
| 5072 | return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 1, | |
| 5073 | __u); | |
| 5074 | } | |
| 5075 | ||
| 5076 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 5077 | _mm512_cmplt_epu64_mask(__m512i __a, __m512i __b) { | |
| 5078 | return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 1, | |
| 5079 | (__mmask8)-1); | |
| 5080 | } | |
| 5081 | ||
| 5082 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 5083 | _mm512_mask_cmplt_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { | |
| 5084 | return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 1, | |
| 5085 | __u); | |
| 5086 | } | |
| 5087 | ||
| 5088 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 5089 | _mm512_cmpneq_epi32_mask(__m512i __a, __m512i __b) { | |
| 5090 | return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 4, | |
| 5091 | (__mmask16)-1); | |
| 5092 | } | |
| 5093 | ||
| 5094 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 5095 | _mm512_mask_cmpneq_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { | |
| 5096 | return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 4, | |
| 5097 | __u); | |
| 5098 | } | |
| 5099 | ||
| 5100 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 5101 | _mm512_cmpneq_epu32_mask(__m512i __a, __m512i __b) { | |
| 5102 | return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 4, | |
| 5103 | (__mmask16)-1); | |
| 5104 | } | |
| 5105 | ||
| 5106 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 5107 | _mm512_mask_cmpneq_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { | |
| 5108 | return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 4, | |
| 5109 | __u); | |
| 5110 | } | |
| 5111 | ||
| 5112 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 5113 | _mm512_cmpneq_epi64_mask(__m512i __a, __m512i __b) { | |
| 5114 | return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 4, | |
| 5115 | (__mmask8)-1); | |
| 5116 | } | |
| 5117 | ||
| 5118 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 5119 | _mm512_mask_cmpneq_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { | |
| 5120 | return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 4, | |
| 5121 | __u); | |
| 5122 | } | |
| 5123 | ||
| 5124 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 5125 | _mm512_cmpneq_epu64_mask(__m512i __a, __m512i __b) { | |
| 5126 | return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 4, | |
| 5127 | (__mmask8)-1); | |
| 5128 | } | |
| 5129 | ||
| 5130 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 5131 | _mm512_mask_cmpneq_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { | |
| 5132 | return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 4, | |
| 5133 | __u); | |
| 5134 | } | |
| 4816 | #define _mm512_cmpeq_epi32_mask(A, B) \ | |
| 4817 | _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_EQ) | |
| 4818 | #define _mm512_mask_cmpeq_epi32_mask(k, A, B) \ | |
| 4819 | _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 4820 | #define _mm512_cmpge_epi32_mask(A, B) \ | |
| 4821 | _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_GE) | |
| 4822 | #define _mm512_mask_cmpge_epi32_mask(k, A, B) \ | |
| 4823 | _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 4824 | #define _mm512_cmpgt_epi32_mask(A, B) \ | |
| 4825 | _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_GT) | |
| 4826 | #define _mm512_mask_cmpgt_epi32_mask(k, A, B) \ | |
| 4827 | _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 4828 | #define _mm512_cmple_epi32_mask(A, B) \ | |
| 4829 | _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_LE) | |
| 4830 | #define _mm512_mask_cmple_epi32_mask(k, A, B) \ | |
| 4831 | _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 4832 | #define _mm512_cmplt_epi32_mask(A, B) \ | |
| 4833 | _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_LT) | |
| 4834 | #define _mm512_mask_cmplt_epi32_mask(k, A, B) \ | |
| 4835 | _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 4836 | #define _mm512_cmpneq_epi32_mask(A, B) \ | |
| 4837 | _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_NE) | |
| 4838 | #define _mm512_mask_cmpneq_epi32_mask(k, A, B) \ | |
| 4839 | _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 4840 | ||
| 4841 | #define _mm512_cmpeq_epu32_mask(A, B) \ | |
| 4842 | _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_EQ) | |
| 4843 | #define _mm512_mask_cmpeq_epu32_mask(k, A, B) \ | |
| 4844 | _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 4845 | #define _mm512_cmpge_epu32_mask(A, B) \ | |
| 4846 | _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_GE) | |
| 4847 | #define _mm512_mask_cmpge_epu32_mask(k, A, B) \ | |
| 4848 | _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 4849 | #define _mm512_cmpgt_epu32_mask(A, B) \ | |
| 4850 | _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_GT) | |
| 4851 | #define _mm512_mask_cmpgt_epu32_mask(k, A, B) \ | |
| 4852 | _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 4853 | #define _mm512_cmple_epu32_mask(A, B) \ | |
| 4854 | _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_LE) | |
| 4855 | #define _mm512_mask_cmple_epu32_mask(k, A, B) \ | |
| 4856 | _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 4857 | #define _mm512_cmplt_epu32_mask(A, B) \ | |
| 4858 | _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_LT) | |
| 4859 | #define _mm512_mask_cmplt_epu32_mask(k, A, B) \ | |
| 4860 | _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 4861 | #define _mm512_cmpneq_epu32_mask(A, B) \ | |
| 4862 | _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_NE) | |
| 4863 | #define _mm512_mask_cmpneq_epu32_mask(k, A, B) \ | |
| 4864 | _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 4865 | ||
| 4866 | #define _mm512_cmpeq_epi64_mask(A, B) \ | |
| 4867 | _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_EQ) | |
| 4868 | #define _mm512_mask_cmpeq_epi64_mask(k, A, B) \ | |
| 4869 | _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 4870 | #define _mm512_cmpge_epi64_mask(A, B) \ | |
| 4871 | _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_GE) | |
| 4872 | #define _mm512_mask_cmpge_epi64_mask(k, A, B) \ | |
| 4873 | _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 4874 | #define _mm512_cmpgt_epi64_mask(A, B) \ | |
| 4875 | _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_GT) | |
| 4876 | #define _mm512_mask_cmpgt_epi64_mask(k, A, B) \ | |
| 4877 | _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 4878 | #define _mm512_cmple_epi64_mask(A, B) \ | |
| 4879 | _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_LE) | |
| 4880 | #define _mm512_mask_cmple_epi64_mask(k, A, B) \ | |
| 4881 | _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 4882 | #define _mm512_cmplt_epi64_mask(A, B) \ | |
| 4883 | _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_LT) | |
| 4884 | #define _mm512_mask_cmplt_epi64_mask(k, A, B) \ | |
| 4885 | _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 4886 | #define _mm512_cmpneq_epi64_mask(A, B) \ | |
| 4887 | _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_NE) | |
| 4888 | #define _mm512_mask_cmpneq_epi64_mask(k, A, B) \ | |
| 4889 | _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 4890 | ||
| 4891 | #define _mm512_cmpeq_epu64_mask(A, B) \ | |
| 4892 | _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_EQ) | |
| 4893 | #define _mm512_mask_cmpeq_epu64_mask(k, A, B) \ | |
| 4894 | _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 4895 | #define _mm512_cmpge_epu64_mask(A, B) \ | |
| 4896 | _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_GE) | |
| 4897 | #define _mm512_mask_cmpge_epu64_mask(k, A, B) \ | |
| 4898 | _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 4899 | #define _mm512_cmpgt_epu64_mask(A, B) \ | |
| 4900 | _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_GT) | |
| 4901 | #define _mm512_mask_cmpgt_epu64_mask(k, A, B) \ | |
| 4902 | _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 4903 | #define _mm512_cmple_epu64_mask(A, B) \ | |
| 4904 | _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_LE) | |
| 4905 | #define _mm512_mask_cmple_epu64_mask(k, A, B) \ | |
| 4906 | _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 4907 | #define _mm512_cmplt_epu64_mask(A, B) \ | |
| 4908 | _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_LT) | |
| 4909 | #define _mm512_mask_cmplt_epu64_mask(k, A, B) \ | |
| 4910 | _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 4911 | #define _mm512_cmpneq_epu64_mask(A, B) \ | |
| 4912 | _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_NE) | |
| 4913 | #define _mm512_mask_cmpneq_epu64_mask(k, A, B) \ | |
| 4914 | _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 5135 | 4915 | |
| 5136 | 4916 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 5137 | 4917 | _mm512_cvtepi8_epi32(__m128i __A) |
| ... | ... | @@ -6798,35 +6578,6 @@ _mm512_maskz_permutex2var_ps (__mmask16 __U, __m512 __A, __m512i __I, |
| 6798 | 6578 | (__mmask16) __U); |
| 6799 | 6579 | } |
| 6800 | 6580 | |
| 6801 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 6802 | _mm512_testn_epi32_mask (__m512i __A, __m512i __B) | |
| 6803 | { | |
| 6804 | return (__mmask16) __builtin_ia32_ptestnmd512 ((__v16si) __A, | |
| 6805 | (__v16si) __B, | |
| 6806 | (__mmask16) -1); | |
| 6807 | } | |
| 6808 | ||
| 6809 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 6810 | _mm512_mask_testn_epi32_mask (__mmask16 __U, __m512i __A, __m512i __B) | |
| 6811 | { | |
| 6812 | return (__mmask16) __builtin_ia32_ptestnmd512 ((__v16si) __A, | |
| 6813 | (__v16si) __B, __U); | |
| 6814 | } | |
| 6815 | ||
| 6816 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 6817 | _mm512_testn_epi64_mask (__m512i __A, __m512i __B) | |
| 6818 | { | |
| 6819 | return (__mmask8) __builtin_ia32_ptestnmq512 ((__v8di) __A, | |
| 6820 | (__v8di) __B, | |
| 6821 | (__mmask8) -1); | |
| 6822 | } | |
| 6823 | ||
| 6824 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 6825 | _mm512_mask_testn_epi64_mask (__mmask8 __U, __m512i __A, __m512i __B) | |
| 6826 | { | |
| 6827 | return (__mmask8) __builtin_ia32_ptestnmq512 ((__v8di) __A, | |
| 6828 | (__v8di) __B, __U); | |
| 6829 | } | |
| 6830 | 6581 | |
| 6831 | 6582 | #define _mm512_cvtt_roundpd_epu32(A, R) __extension__ ({ \ |
| 6832 | 6583 | (__m256i)__builtin_ia32_cvttpd2udq512_mask((__v8df)(__m512d)(A), \ |
| ... | ... | @@ -7195,76 +6946,100 @@ _mm512_maskz_srai_epi64(__mmask8 __U, __m512i __A, int __B) |
| 7195 | 6946 | } |
| 7196 | 6947 | |
| 7197 | 6948 | #define _mm512_shuffle_f32x4(A, B, imm) __extension__ ({ \ |
| 7198 | (__m512)__builtin_ia32_shuf_f32x4_mask((__v16sf)(__m512)(A), \ | |
| 7199 | (__v16sf)(__m512)(B), (int)(imm), \ | |
| 7200 | (__v16sf)_mm512_undefined_ps(), \ | |
| 7201 | (__mmask16)-1); }) | |
| 6949 | (__m512)__builtin_shufflevector((__v16sf)(__m512)(A), \ | |
| 6950 | (__v16sf)(__m512)(B), \ | |
| 6951 | 0 + ((((imm) >> 0) & 0x3) * 4), \ | |
| 6952 | 1 + ((((imm) >> 0) & 0x3) * 4), \ | |
| 6953 | 2 + ((((imm) >> 0) & 0x3) * 4), \ | |
| 6954 | 3 + ((((imm) >> 0) & 0x3) * 4), \ | |
| 6955 | 0 + ((((imm) >> 2) & 0x3) * 4), \ | |
| 6956 | 1 + ((((imm) >> 2) & 0x3) * 4), \ | |
| 6957 | 2 + ((((imm) >> 2) & 0x3) * 4), \ | |
| 6958 | 3 + ((((imm) >> 2) & 0x3) * 4), \ | |
| 6959 | 16 + ((((imm) >> 4) & 0x3) * 4), \ | |
| 6960 | 17 + ((((imm) >> 4) & 0x3) * 4), \ | |
| 6961 | 18 + ((((imm) >> 4) & 0x3) * 4), \ | |
| 6962 | 19 + ((((imm) >> 4) & 0x3) * 4), \ | |
| 6963 | 16 + ((((imm) >> 6) & 0x3) * 4), \ | |
| 6964 | 17 + ((((imm) >> 6) & 0x3) * 4), \ | |
| 6965 | 18 + ((((imm) >> 6) & 0x3) * 4), \ | |
| 6966 | 19 + ((((imm) >> 6) & 0x3) * 4)); }) | |
| 7202 | 6967 | |
| 7203 | 6968 | #define _mm512_mask_shuffle_f32x4(W, U, A, B, imm) __extension__ ({ \ |
| 7204 | (__m512)__builtin_ia32_shuf_f32x4_mask((__v16sf)(__m512)(A), \ | |
| 7205 | (__v16sf)(__m512)(B), (int)(imm), \ | |
| 7206 | (__v16sf)(__m512)(W), \ | |
| 7207 | (__mmask16)(U)); }) | |
| 6969 | (__m512)__builtin_ia32_selectps_512((__mmask16)(U), \ | |
| 6970 | (__v16sf)_mm512_shuffle_f32x4((A), (B), (imm)), \ | |
| 6971 | (__v16sf)(__m512)(W)); }) | |
| 7208 | 6972 | |
| 7209 | 6973 | #define _mm512_maskz_shuffle_f32x4(U, A, B, imm) __extension__ ({ \ |
| 7210 | (__m512)__builtin_ia32_shuf_f32x4_mask((__v16sf)(__m512)(A), \ | |
| 7211 | (__v16sf)(__m512)(B), (int)(imm), \ | |
| 7212 | (__v16sf)_mm512_setzero_ps(), \ | |
| 7213 | (__mmask16)(U)); }) | |
| 6974 | (__m512)__builtin_ia32_selectps_512((__mmask16)(U), \ | |
| 6975 | (__v16sf)_mm512_shuffle_f32x4((A), (B), (imm)), \ | |
| 6976 | (__v16sf)_mm512_setzero_ps()); }) | |
| 7214 | 6977 | |
| 7215 | 6978 | #define _mm512_shuffle_f64x2(A, B, imm) __extension__ ({ \ |
| 7216 | (__m512d)__builtin_ia32_shuf_f64x2_mask((__v8df)(__m512d)(A), \ | |
| 7217 | (__v8df)(__m512d)(B), (int)(imm), \ | |
| 7218 | (__v8df)_mm512_undefined_pd(), \ | |
| 7219 | (__mmask8)-1); }) | |
| 6979 | (__m512d)__builtin_shufflevector((__v8df)(__m512d)(A), \ | |
| 6980 | (__v8df)(__m512d)(B), \ | |
| 6981 | 0 + ((((imm) >> 0) & 0x3) * 2), \ | |
| 6982 | 1 + ((((imm) >> 0) & 0x3) * 2), \ | |
| 6983 | 0 + ((((imm) >> 2) & 0x3) * 2), \ | |
| 6984 | 1 + ((((imm) >> 2) & 0x3) * 2), \ | |
| 6985 | 8 + ((((imm) >> 4) & 0x3) * 2), \ | |
| 6986 | 9 + ((((imm) >> 4) & 0x3) * 2), \ | |
| 6987 | 8 + ((((imm) >> 6) & 0x3) * 2), \ | |
| 6988 | 9 + ((((imm) >> 6) & 0x3) * 2)); }) | |
| 7220 | 6989 | |
| 7221 | 6990 | #define _mm512_mask_shuffle_f64x2(W, U, A, B, imm) __extension__ ({ \ |
| 7222 | (__m512d)__builtin_ia32_shuf_f64x2_mask((__v8df)(__m512d)(A), \ | |
| 7223 | (__v8df)(__m512d)(B), (int)(imm), \ | |
| 7224 | (__v8df)(__m512d)(W), \ | |
| 7225 | (__mmask8)(U)); }) | |
| 6991 | (__m512d)__builtin_ia32_selectpd_512((__mmask8)(U), \ | |
| 6992 | (__v8df)_mm512_shuffle_f64x2((A), (B), (imm)), \ | |
| 6993 | (__v8df)(__m512d)(W)); }) | |
| 7226 | 6994 | |
| 7227 | 6995 | #define _mm512_maskz_shuffle_f64x2(U, A, B, imm) __extension__ ({ \ |
| 7228 | (__m512d)__builtin_ia32_shuf_f64x2_mask((__v8df)(__m512d)(A), \ | |
| 7229 | (__v8df)(__m512d)(B), (int)(imm), \ | |
| 7230 | (__v8df)_mm512_setzero_pd(), \ | |
| 7231 | (__mmask8)(U)); }) | |
| 6996 | (__m512d)__builtin_ia32_selectpd_512((__mmask8)(U), \ | |
| 6997 | (__v8df)_mm512_shuffle_f64x2((A), (B), (imm)), \ | |
| 6998 | (__v8df)_mm512_setzero_pd()); }) | |
| 7232 | 6999 | |
| 7233 | 7000 | #define _mm512_shuffle_i32x4(A, B, imm) __extension__ ({ \ |
| 7234 | (__m512i)__builtin_ia32_shuf_i32x4_mask((__v16si)(__m512i)(A), \ | |
| 7235 | (__v16si)(__m512i)(B), (int)(imm), \ | |
| 7236 | (__v16si)_mm512_setzero_si512(), \ | |
| 7237 | (__mmask16)-1); }) | |
| 7001 | (__m512i)__builtin_shufflevector((__v8di)(__m512i)(A), \ | |
| 7002 | (__v8di)(__m512i)(B), \ | |
| 7003 | 0 + ((((imm) >> 0) & 0x3) * 2), \ | |
| 7004 | 1 + ((((imm) >> 0) & 0x3) * 2), \ | |
| 7005 | 0 + ((((imm) >> 2) & 0x3) * 2), \ | |
| 7006 | 1 + ((((imm) >> 2) & 0x3) * 2), \ | |
| 7007 | 8 + ((((imm) >> 4) & 0x3) * 2), \ | |
| 7008 | 9 + ((((imm) >> 4) & 0x3) * 2), \ | |
| 7009 | 8 + ((((imm) >> 6) & 0x3) * 2), \ | |
| 7010 | 9 + ((((imm) >> 6) & 0x3) * 2)); }) | |
| 7238 | 7011 | |
| 7239 | 7012 | #define _mm512_mask_shuffle_i32x4(W, U, A, B, imm) __extension__ ({ \ |
| 7240 | (__m512i)__builtin_ia32_shuf_i32x4_mask((__v16si)(__m512i)(A), \ | |
| 7241 | (__v16si)(__m512i)(B), (int)(imm), \ | |
| 7242 | (__v16si)(__m512i)(W), \ | |
| 7243 | (__mmask16)(U)); }) | |
| 7013 | (__m512i)__builtin_ia32_selectd_512((__mmask16)(U), \ | |
| 7014 | (__v16si)_mm512_shuffle_i32x4((A), (B), (imm)), \ | |
| 7015 | (__v16si)(__m512i)(W)); }) | |
| 7244 | 7016 | |
| 7245 | 7017 | #define _mm512_maskz_shuffle_i32x4(U, A, B, imm) __extension__ ({ \ |
| 7246 | (__m512i)__builtin_ia32_shuf_i32x4_mask((__v16si)(__m512i)(A), \ | |
| 7247 | (__v16si)(__m512i)(B), (int)(imm), \ | |
| 7248 | (__v16si)_mm512_setzero_si512(), \ | |
| 7249 | (__mmask16)(U)); }) | |
| 7018 | (__m512i)__builtin_ia32_selectd_512((__mmask16)(U), \ | |
| 7019 | (__v16si)_mm512_shuffle_i32x4((A), (B), (imm)), \ | |
| 7020 | (__v16si)_mm512_setzero_si512()); }) | |
| 7250 | 7021 | |
| 7251 | 7022 | #define _mm512_shuffle_i64x2(A, B, imm) __extension__ ({ \ |
| 7252 | (__m512i)__builtin_ia32_shuf_i64x2_mask((__v8di)(__m512i)(A), \ | |
| 7253 | (__v8di)(__m512i)(B), (int)(imm), \ | |
| 7254 | (__v8di)_mm512_setzero_si512(), \ | |
| 7255 | (__mmask8)-1); }) | |
| 7023 | (__m512i)__builtin_shufflevector((__v8di)(__m512i)(A), \ | |
| 7024 | (__v8di)(__m512i)(B), \ | |
| 7025 | 0 + ((((imm) >> 0) & 0x3) * 2), \ | |
| 7026 | 1 + ((((imm) >> 0) & 0x3) * 2), \ | |
| 7027 | 0 + ((((imm) >> 2) & 0x3) * 2), \ | |
| 7028 | 1 + ((((imm) >> 2) & 0x3) * 2), \ | |
| 7029 | 8 + ((((imm) >> 4) & 0x3) * 2), \ | |
| 7030 | 9 + ((((imm) >> 4) & 0x3) * 2), \ | |
| 7031 | 8 + ((((imm) >> 6) & 0x3) * 2), \ | |
| 7032 | 9 + ((((imm) >> 6) & 0x3) * 2)); }) | |
| 7256 | 7033 | |
| 7257 | 7034 | #define _mm512_mask_shuffle_i64x2(W, U, A, B, imm) __extension__ ({ \ |
| 7258 | (__m512i)__builtin_ia32_shuf_i64x2_mask((__v8di)(__m512i)(A), \ | |
| 7259 | (__v8di)(__m512i)(B), (int)(imm), \ | |
| 7260 | (__v8di)(__m512i)(W), \ | |
| 7261 | (__mmask8)(U)); }) | |
| 7035 | (__m512i)__builtin_ia32_selectq_512((__mmask8)(U), \ | |
| 7036 | (__v8di)_mm512_shuffle_i64x2((A), (B), (imm)), \ | |
| 7037 | (__v8di)(__m512i)(W)); }) | |
| 7262 | 7038 | |
| 7263 | 7039 | #define _mm512_maskz_shuffle_i64x2(U, A, B, imm) __extension__ ({ \ |
| 7264 | (__m512i)__builtin_ia32_shuf_i64x2_mask((__v8di)(__m512i)(A), \ | |
| 7265 | (__v8di)(__m512i)(B), (int)(imm), \ | |
| 7266 | (__v8di)_mm512_setzero_si512(), \ | |
| 7267 | (__mmask8)(U)); }) | |
| 7040 | (__m512i)__builtin_ia32_selectq_512((__mmask8)(U), \ | |
| 7041 | (__v8di)_mm512_shuffle_i64x2((A), (B), (imm)), \ | |
| 7042 | (__v8di)_mm512_setzero_si512()); }) | |
| 7268 | 7043 | |
| 7269 | 7044 | #define _mm512_shuffle_pd(A, B, M) __extension__ ({ \ |
| 7270 | 7045 | (__m512d)__builtin_shufflevector((__v8df)(__m512d)(A), \ |
| ... | ... | @@ -9012,7 +8787,7 @@ _mm512_kortestz (__mmask16 __A, __mmask16 __B) |
| 9012 | 8787 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS |
| 9013 | 8788 | _mm512_kunpackb (__mmask16 __A, __mmask16 __B) |
| 9014 | 8789 | { |
| 9015 | return (__mmask16) __builtin_ia32_kunpckhi ((__mmask16) __A, (__mmask16) __B); | |
| 8790 | return (__mmask16) (( __A & 0xFF) | ( __B << 8)); | |
| 9016 | 8791 | } |
| 9017 | 8792 | |
| 9018 | 8793 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS |
| ... | ... | @@ -9035,7 +8810,7 @@ _mm512_stream_si512 (__m512i * __P, __m512i __A) |
| 9035 | 8810 | } |
| 9036 | 8811 | |
| 9037 | 8812 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 9038 | _mm512_stream_load_si512 (void *__P) | |
| 8813 | _mm512_stream_load_si512 (void const *__P) | |
| 9039 | 8814 | { |
| 9040 | 8815 | typedef __v8di __v8di_aligned __attribute__((aligned(64))); |
| 9041 | 8816 | return (__m512i) __builtin_nontemporal_load((const __v8di_aligned *)__P); |
| ... | ... | @@ -9167,6 +8942,64 @@ _mm512_maskz_compress_epi32 (__mmask16 __U, __m512i __A) |
| 9167 | 8942 | (__mmask8)(M), \ |
| 9168 | 8943 | _MM_FROUND_CUR_DIRECTION); }) |
| 9169 | 8944 | |
| 8945 | /* Bit Test */ | |
| 8946 | ||
| 8947 | static __inline __mmask16 __DEFAULT_FN_ATTRS | |
| 8948 | _mm512_test_epi32_mask (__m512i __A, __m512i __B) | |
| 8949 | { | |
| 8950 | return _mm512_cmpneq_epi32_mask (_mm512_and_epi32(__A, __B), | |
| 8951 | _mm512_setzero_epi32()); | |
| 8952 | } | |
| 8953 | ||
| 8954 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 8955 | _mm512_mask_test_epi32_mask (__mmask16 __U, __m512i __A, __m512i __B) | |
| 8956 | { | |
| 8957 | return _mm512_mask_cmpneq_epi32_mask (__U, _mm512_and_epi32 (__A, __B), | |
| 8958 | _mm512_setzero_epi32()); | |
| 8959 | } | |
| 8960 | ||
| 8961 | static __inline __mmask8 __DEFAULT_FN_ATTRS | |
| 8962 | _mm512_test_epi64_mask (__m512i __A, __m512i __B) | |
| 8963 | { | |
| 8964 | return _mm512_cmpneq_epi64_mask (_mm512_and_epi32 (__A, __B), | |
| 8965 | _mm512_setzero_epi32()); | |
| 8966 | } | |
| 8967 | ||
| 8968 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 8969 | _mm512_mask_test_epi64_mask (__mmask8 __U, __m512i __A, __m512i __B) | |
| 8970 | { | |
| 8971 | return _mm512_mask_cmpneq_epi64_mask (__U, _mm512_and_epi32 (__A, __B), | |
| 8972 | _mm512_setzero_epi32()); | |
| 8973 | } | |
| 8974 | ||
| 8975 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 8976 | _mm512_testn_epi32_mask (__m512i __A, __m512i __B) | |
| 8977 | { | |
| 8978 | return _mm512_cmpeq_epi32_mask (_mm512_and_epi32 (__A, __B), | |
| 8979 | _mm512_setzero_epi32()); | |
| 8980 | } | |
| 8981 | ||
| 8982 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 8983 | _mm512_mask_testn_epi32_mask (__mmask16 __U, __m512i __A, __m512i __B) | |
| 8984 | { | |
| 8985 | return _mm512_mask_cmpeq_epi32_mask (__U, _mm512_and_epi32 (__A, __B), | |
| 8986 | _mm512_setzero_epi32()); | |
| 8987 | } | |
| 8988 | ||
| 8989 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 8990 | _mm512_testn_epi64_mask (__m512i __A, __m512i __B) | |
| 8991 | { | |
| 8992 | return _mm512_cmpeq_epi64_mask (_mm512_and_epi32 (__A, __B), | |
| 8993 | _mm512_setzero_epi32()); | |
| 8994 | } | |
| 8995 | ||
| 8996 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 8997 | _mm512_mask_testn_epi64_mask (__mmask8 __U, __m512i __A, __m512i __B) | |
| 8998 | { | |
| 8999 | return _mm512_mask_cmpeq_epi64_mask (__U, _mm512_and_epi32 (__A, __B), | |
| 9000 | _mm512_setzero_epi32()); | |
| 9001 | } | |
| 9002 | ||
| 9170 | 9003 | static __inline__ __m512 __DEFAULT_FN_ATTRS |
| 9171 | 9004 | _mm512_movehdup_ps (__m512 __A) |
| 9172 | 9005 | { |
| ... | ... | @@ -9737,16 +9570,18 @@ _mm_cvtu64_ss (__m128 __A, unsigned long long __B) |
| 9737 | 9570 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 9738 | 9571 | _mm512_mask_set1_epi32 (__m512i __O, __mmask16 __M, int __A) |
| 9739 | 9572 | { |
| 9740 | return (__m512i) __builtin_ia32_pbroadcastd512_gpr_mask (__A, (__v16si) __O, | |
| 9741 | __M); | |
| 9573 | return (__m512i) __builtin_ia32_selectd_512(__M, | |
| 9574 | (__v16si) _mm512_set1_epi32(__A), | |
| 9575 | (__v16si) __O); | |
| 9742 | 9576 | } |
| 9743 | 9577 | |
| 9744 | 9578 | #ifdef __x86_64__ |
| 9745 | 9579 | static __inline__ __m512i __DEFAULT_FN_ATTRS |
| 9746 | 9580 | _mm512_mask_set1_epi64 (__m512i __O, __mmask8 __M, long long __A) |
| 9747 | 9581 | { |
| 9748 | return (__m512i) __builtin_ia32_pbroadcastq512_gpr_mask (__A, (__v8di) __O, | |
| 9749 | __M); | |
| 9582 | return (__m512i) __builtin_ia32_selectq_512(__M, | |
| 9583 | (__v8di) _mm512_set1_epi64(__A), | |
| 9584 | (__v8di) __O); | |
| 9750 | 9585 | } |
| 9751 | 9586 | #endif |
| 9752 | 9587 |
c_headers/avx512vbmi2intrin.h created+391| ... | ... | @@ -0,0 +1,391 @@ |
| 1 | /*===------------- avx512vbmi2intrin.h - VBMI2 intrinsics ------------------=== | |
| 2 | * | |
| 3 | * | |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 5 | * of this software and associated documentation files (the "Software"), to deal | |
| 6 | * in the Software without restriction, including without limitation the rights | |
| 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 8 | * copies of the Software, and to permit persons to whom the Software is | |
| 9 | * furnished to do so, subject to the following conditions: | |
| 10 | * | |
| 11 | * The above copyright notice and this permission notice shall be included in | |
| 12 | * all copies or substantial portions of the Software. | |
| 13 | * | |
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 20 | * THE SOFTWARE. | |
| 21 | * | |
| 22 | *===-----------------------------------------------------------------------=== | |
| 23 | */ | |
| 24 | #ifndef __IMMINTRIN_H | |
| 25 | #error "Never use <avx512vbmi2intrin.h> directly; include <immintrin.h> instead." | |
| 26 | #endif | |
| 27 | ||
| 28 | #ifndef __AVX512VBMI2INTRIN_H | |
| 29 | #define __AVX512VBMI2INTRIN_H | |
| 30 | ||
| 31 | /* Define the default attributes for the functions in this file. */ | |
| 32 | #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512vbmi2"))) | |
| 33 | ||
| 34 | ||
| 35 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 36 | _mm512_mask_compress_epi16(__m512i __S, __mmask32 __U, __m512i __D) | |
| 37 | { | |
| 38 | return (__m512i) __builtin_ia32_compresshi512_mask ((__v32hi) __D, | |
| 39 | (__v32hi) __S, | |
| 40 | __U); | |
| 41 | } | |
| 42 | ||
| 43 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 44 | _mm512_maskz_compress_epi16(__mmask32 __U, __m512i __D) | |
| 45 | { | |
| 46 | return (__m512i) __builtin_ia32_compresshi512_mask ((__v32hi) __D, | |
| 47 | (__v32hi) _mm512_setzero_hi(), | |
| 48 | __U); | |
| 49 | } | |
| 50 | ||
| 51 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 52 | _mm512_mask_compress_epi8(__m512i __S, __mmask64 __U, __m512i __D) | |
| 53 | { | |
| 54 | return (__m512i) __builtin_ia32_compressqi512_mask ((__v64qi) __D, | |
| 55 | (__v64qi) __S, | |
| 56 | __U); | |
| 57 | } | |
| 58 | ||
| 59 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 60 | _mm512_maskz_compress_epi8(__mmask64 __U, __m512i __D) | |
| 61 | { | |
| 62 | return (__m512i) __builtin_ia32_compressqi512_mask ((__v64qi) __D, | |
| 63 | (__v64qi) _mm512_setzero_qi(), | |
| 64 | __U); | |
| 65 | } | |
| 66 | ||
| 67 | static __inline__ void __DEFAULT_FN_ATTRS | |
| 68 | _mm512_mask_compressstoreu_epi16(void *__P, __mmask32 __U, __m512i __D) | |
| 69 | { | |
| 70 | __builtin_ia32_compressstorehi512_mask ((__v32hi *) __P, (__v32hi) __D, | |
| 71 | __U); | |
| 72 | } | |
| 73 | ||
| 74 | static __inline__ void __DEFAULT_FN_ATTRS | |
| 75 | _mm512_mask_compressstoreu_epi8(void *__P, __mmask64 __U, __m512i __D) | |
| 76 | { | |
| 77 | __builtin_ia32_compressstoreqi512_mask ((__v64qi *) __P, (__v64qi) __D, | |
| 78 | __U); | |
| 79 | } | |
| 80 | ||
| 81 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 82 | _mm512_mask_expand_epi16(__m512i __S, __mmask32 __U, __m512i __D) | |
| 83 | { | |
| 84 | return (__m512i) __builtin_ia32_expandhi512_mask ((__v32hi) __D, | |
| 85 | (__v32hi) __S, | |
| 86 | __U); | |
| 87 | } | |
| 88 | ||
| 89 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 90 | _mm512_maskz_expand_epi16(__mmask32 __U, __m512i __D) | |
| 91 | { | |
| 92 | return (__m512i) __builtin_ia32_expandhi512_mask ((__v32hi) __D, | |
| 93 | (__v32hi) _mm512_setzero_hi(), | |
| 94 | __U); | |
| 95 | } | |
| 96 | ||
| 97 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 98 | _mm512_mask_expand_epi8(__m512i __S, __mmask64 __U, __m512i __D) | |
| 99 | { | |
| 100 | return (__m512i) __builtin_ia32_expandqi512_mask ((__v64qi) __D, | |
| 101 | (__v64qi) __S, | |
| 102 | __U); | |
| 103 | } | |
| 104 | ||
| 105 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 106 | _mm512_maskz_expand_epi8(__mmask64 __U, __m512i __D) | |
| 107 | { | |
| 108 | return (__m512i) __builtin_ia32_expandqi512_mask ((__v64qi) __D, | |
| 109 | (__v64qi) _mm512_setzero_qi(), | |
| 110 | __U); | |
| 111 | } | |
| 112 | ||
| 113 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 114 | _mm512_mask_expandloadu_epi16(__m512i __S, __mmask32 __U, void const *__P) | |
| 115 | { | |
| 116 | return (__m512i) __builtin_ia32_expandloadhi512_mask ((const __v32hi *)__P, | |
| 117 | (__v32hi) __S, | |
| 118 | __U); | |
| 119 | } | |
| 120 | ||
| 121 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 122 | _mm512_maskz_expandloadu_epi16(__mmask32 __U, void const *__P) | |
| 123 | { | |
| 124 | return (__m512i) __builtin_ia32_expandloadhi512_mask ((const __v32hi *)__P, | |
| 125 | (__v32hi) _mm512_setzero_hi(), | |
| 126 | __U); | |
| 127 | } | |
| 128 | ||
| 129 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 130 | _mm512_mask_expandloadu_epi8(__m512i __S, __mmask64 __U, void const *__P) | |
| 131 | { | |
| 132 | return (__m512i) __builtin_ia32_expandloadqi512_mask ((const __v64qi *)__P, | |
| 133 | (__v64qi) __S, | |
| 134 | __U); | |
| 135 | } | |
| 136 | ||
| 137 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 138 | _mm512_maskz_expandloadu_epi8(__mmask64 __U, void const *__P) | |
| 139 | { | |
| 140 | return (__m512i) __builtin_ia32_expandloadqi512_mask ((const __v64qi *)__P, | |
| 141 | (__v64qi) _mm512_setzero_qi(), | |
| 142 | __U); | |
| 143 | } | |
| 144 | ||
| 145 | #define _mm512_mask_shldi_epi64(S, U, A, B, I) __extension__ ({ \ | |
| 146 | (__m512i)__builtin_ia32_vpshldq512_mask((__v8di)(A), \ | |
| 147 | (__v8di)(B), \ | |
| 148 | (int)(I), \ | |
| 149 | (__v8di)(S), \ | |
| 150 | (__mmask8)(U)); }) | |
| 151 | ||
| 152 | #define _mm512_maskz_shldi_epi64(U, A, B, I) \ | |
| 153 | _mm512_mask_shldi_epi64(_mm512_setzero_hi(), (U), (A), (B), (I)) | |
| 154 | ||
| 155 | #define _mm512_shldi_epi64(A, B, I) \ | |
| 156 | _mm512_mask_shldi_epi64(_mm512_undefined(), (__mmask8)(-1), (A), (B), (I)) | |
| 157 | ||
| 158 | #define _mm512_mask_shldi_epi32(S, U, A, B, I) __extension__ ({ \ | |
| 159 | (__m512i)__builtin_ia32_vpshldd512_mask((__v16si)(A), \ | |
| 160 | (__v16si)(B), \ | |
| 161 | (int)(I), \ | |
| 162 | (__v16si)(S), \ | |
| 163 | (__mmask16)(U)); }) | |
| 164 | ||
| 165 | #define _mm512_maskz_shldi_epi32(U, A, B, I) \ | |
| 166 | _mm512_mask_shldi_epi32(_mm512_setzero_hi(), (U), (A), (B), (I)) | |
| 167 | ||
| 168 | #define _mm512_shldi_epi32(A, B, I) \ | |
| 169 | _mm512_mask_shldi_epi32(_mm512_undefined(), (__mmask16)(-1), (A), (B), (I)) | |
| 170 | ||
| 171 | #define _mm512_mask_shldi_epi16(S, U, A, B, I) __extension__ ({ \ | |
| 172 | (__m512i)__builtin_ia32_vpshldw512_mask((__v32hi)(A), \ | |
| 173 | (__v32hi)(B), \ | |
| 174 | (int)(I), \ | |
| 175 | (__v32hi)(S), \ | |
| 176 | (__mmask32)(U)); }) | |
| 177 | ||
| 178 | #define _mm512_maskz_shldi_epi16(U, A, B, I) \ | |
| 179 | _mm512_mask_shldi_epi16(_mm512_setzero_hi(), (U), (A), (B), (I)) | |
| 180 | ||
| 181 | #define _mm512_shldi_epi16(A, B, I) \ | |
| 182 | _mm512_mask_shldi_epi16(_mm512_undefined(), (__mmask32)(-1), (A), (B), (I)) | |
| 183 | ||
| 184 | #define _mm512_mask_shrdi_epi64(S, U, A, B, I) __extension__ ({ \ | |
| 185 | (__m512i)__builtin_ia32_vpshrdq512_mask((__v8di)(A), \ | |
| 186 | (__v8di)(B), \ | |
| 187 | (int)(I), \ | |
| 188 | (__v8di)(S), \ | |
| 189 | (__mmask8)(U)); }) | |
| 190 | ||
| 191 | #define _mm512_maskz_shrdi_epi64(U, A, B, I) \ | |
| 192 | _mm512_mask_shrdi_epi64(_mm512_setzero_hi(), (U), (A), (B), (I)) | |
| 193 | ||
| 194 | #define _mm512_shrdi_epi64(A, B, I) \ | |
| 195 | _mm512_mask_shrdi_epi64(_mm512_undefined(), (__mmask8)(-1), (A), (B), (I)) | |
| 196 | ||
| 197 | #define _mm512_mask_shrdi_epi32(S, U, A, B, I) __extension__ ({ \ | |
| 198 | (__m512i)__builtin_ia32_vpshrdd512_mask((__v16si)(A), \ | |
| 199 | (__v16si)(B), \ | |
| 200 | (int)(I), \ | |
| 201 | (__v16si)(S), \ | |
| 202 | (__mmask16)(U)); }) | |
| 203 | ||
| 204 | #define _mm512_maskz_shrdi_epi32(U, A, B, I) \ | |
| 205 | _mm512_mask_shrdi_epi32(_mm512_setzero_hi(), (U), (A), (B), (I)) | |
| 206 | ||
| 207 | #define _mm512_shrdi_epi32(A, B, I) \ | |
| 208 | _mm512_mask_shrdi_epi32(_mm512_undefined(), (__mmask16)(-1), (A), (B), (I)) | |
| 209 | ||
| 210 | #define _mm512_mask_shrdi_epi16(S, U, A, B, I) __extension__ ({ \ | |
| 211 | (__m512i)__builtin_ia32_vpshrdw512_mask((__v32hi)(A), \ | |
| 212 | (__v32hi)(B), \ | |
| 213 | (int)(I), \ | |
| 214 | (__v32hi)(S), \ | |
| 215 | (__mmask32)(U)); }) | |
| 216 | ||
| 217 | #define _mm512_maskz_shrdi_epi16(U, A, B, I) \ | |
| 218 | _mm512_mask_shrdi_epi16(_mm512_setzero_hi(), (U), (A), (B), (I)) | |
| 219 | ||
| 220 | #define _mm512_shrdi_epi16(A, B, I) \ | |
| 221 | _mm512_mask_shrdi_epi16(_mm512_undefined(), (__mmask32)(-1), (A), (B), (I)) | |
| 222 | ||
| 223 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 224 | _mm512_mask_shldv_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) | |
| 225 | { | |
| 226 | return (__m512i) __builtin_ia32_vpshldvq512_mask ((__v8di) __S, | |
| 227 | (__v8di) __A, | |
| 228 | (__v8di) __B, | |
| 229 | __U); | |
| 230 | } | |
| 231 | ||
| 232 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 233 | _mm512_maskz_shldv_epi64(__mmask8 __U, __m512i __S, __m512i __A, __m512i __B) | |
| 234 | { | |
| 235 | return (__m512i) __builtin_ia32_vpshldvq512_maskz ((__v8di) __S, | |
| 236 | (__v8di) __A, | |
| 237 | (__v8di) __B, | |
| 238 | __U); | |
| 239 | } | |
| 240 | ||
| 241 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 242 | _mm512_shldv_epi64(__m512i __S, __m512i __A, __m512i __B) | |
| 243 | { | |
| 244 | return (__m512i) __builtin_ia32_vpshldvq512_mask ((__v8di) __S, | |
| 245 | (__v8di) __A, | |
| 246 | (__v8di) __B, | |
| 247 | (__mmask8) -1); | |
| 248 | } | |
| 249 | ||
| 250 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 251 | _mm512_mask_shldv_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) | |
| 252 | { | |
| 253 | return (__m512i) __builtin_ia32_vpshldvd512_mask ((__v16si) __S, | |
| 254 | (__v16si) __A, | |
| 255 | (__v16si) __B, | |
| 256 | __U); | |
| 257 | } | |
| 258 | ||
| 259 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 260 | _mm512_maskz_shldv_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B) | |
| 261 | { | |
| 262 | return (__m512i) __builtin_ia32_vpshldvd512_maskz ((__v16si) __S, | |
| 263 | (__v16si) __A, | |
| 264 | (__v16si) __B, | |
| 265 | __U); | |
| 266 | } | |
| 267 | ||
| 268 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 269 | _mm512_shldv_epi32(__m512i __S, __m512i __A, __m512i __B) | |
| 270 | { | |
| 271 | return (__m512i) __builtin_ia32_vpshldvd512_mask ((__v16si) __S, | |
| 272 | (__v16si) __A, | |
| 273 | (__v16si) __B, | |
| 274 | (__mmask16) -1); | |
| 275 | } | |
| 276 | ||
| 277 | ||
| 278 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 279 | _mm512_mask_shldv_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B) | |
| 280 | { | |
| 281 | return (__m512i) __builtin_ia32_vpshldvw512_mask ((__v32hi) __S, | |
| 282 | (__v32hi) __A, | |
| 283 | (__v32hi) __B, | |
| 284 | __U); | |
| 285 | } | |
| 286 | ||
| 287 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 288 | _mm512_maskz_shldv_epi16(__mmask32 __U, __m512i __S, __m512i __A, __m512i __B) | |
| 289 | { | |
| 290 | return (__m512i) __builtin_ia32_vpshldvw512_maskz ((__v32hi) __S, | |
| 291 | (__v32hi) __A, | |
| 292 | (__v32hi) __B, | |
| 293 | __U); | |
| 294 | } | |
| 295 | ||
| 296 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 297 | _mm512_shldv_epi16(__m512i __S, __m512i __A, __m512i __B) | |
| 298 | { | |
| 299 | return (__m512i) __builtin_ia32_vpshldvw512_mask ((__v32hi) __S, | |
| 300 | (__v32hi) __A, | |
| 301 | (__v32hi) __B, | |
| 302 | (__mmask32) -1); | |
| 303 | } | |
| 304 | ||
| 305 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 306 | _mm512_mask_shrdv_epi64(__m512i __S, __mmask8 __U, __m512i __A, __m512i __B) | |
| 307 | { | |
| 308 | return (__m512i) __builtin_ia32_vpshrdvq512_mask ((__v8di) __S, | |
| 309 | (__v8di) __A, | |
| 310 | (__v8di) __B, | |
| 311 | __U); | |
| 312 | } | |
| 313 | ||
| 314 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 315 | _mm512_maskz_shrdv_epi64(__mmask8 __U, __m512i __S, __m512i __A, __m512i __B) | |
| 316 | { | |
| 317 | return (__m512i) __builtin_ia32_vpshrdvq512_maskz ((__v8di) __S, | |
| 318 | (__v8di) __A, | |
| 319 | (__v8di) __B, | |
| 320 | __U); | |
| 321 | } | |
| 322 | ||
| 323 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 324 | _mm512_shrdv_epi64(__m512i __S, __m512i __A, __m512i __B) | |
| 325 | { | |
| 326 | return (__m512i) __builtin_ia32_vpshrdvq512_mask ((__v8di) __S, | |
| 327 | (__v8di) __A, | |
| 328 | (__v8di) __B, | |
| 329 | (__mmask8) -1); | |
| 330 | } | |
| 331 | ||
| 332 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 333 | _mm512_mask_shrdv_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) | |
| 334 | { | |
| 335 | return (__m512i) __builtin_ia32_vpshrdvd512_mask ((__v16si) __S, | |
| 336 | (__v16si) __A, | |
| 337 | (__v16si) __B, | |
| 338 | __U); | |
| 339 | } | |
| 340 | ||
| 341 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 342 | _mm512_maskz_shrdv_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B) | |
| 343 | { | |
| 344 | return (__m512i) __builtin_ia32_vpshrdvd512_maskz ((__v16si) __S, | |
| 345 | (__v16si) __A, | |
| 346 | (__v16si) __B, | |
| 347 | __U); | |
| 348 | } | |
| 349 | ||
| 350 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 351 | _mm512_shrdv_epi32(__m512i __S, __m512i __A, __m512i __B) | |
| 352 | { | |
| 353 | return (__m512i) __builtin_ia32_vpshrdvd512_mask ((__v16si) __S, | |
| 354 | (__v16si) __A, | |
| 355 | (__v16si) __B, | |
| 356 | (__mmask16) -1); | |
| 357 | } | |
| 358 | ||
| 359 | ||
| 360 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 361 | _mm512_mask_shrdv_epi16(__m512i __S, __mmask32 __U, __m512i __A, __m512i __B) | |
| 362 | { | |
| 363 | return (__m512i) __builtin_ia32_vpshrdvw512_mask ((__v32hi) __S, | |
| 364 | (__v32hi) __A, | |
| 365 | (__v32hi) __B, | |
| 366 | __U); | |
| 367 | } | |
| 368 | ||
| 369 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 370 | _mm512_maskz_shrdv_epi16(__mmask32 __U, __m512i __S, __m512i __A, __m512i __B) | |
| 371 | { | |
| 372 | return (__m512i) __builtin_ia32_vpshrdvw512_maskz ((__v32hi) __S, | |
| 373 | (__v32hi) __A, | |
| 374 | (__v32hi) __B, | |
| 375 | __U); | |
| 376 | } | |
| 377 | ||
| 378 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 379 | _mm512_shrdv_epi16(__m512i __S, __m512i __A, __m512i __B) | |
| 380 | { | |
| 381 | return (__m512i) __builtin_ia32_vpshrdvw512_mask ((__v32hi) __S, | |
| 382 | (__v32hi) __A, | |
| 383 | (__v32hi) __B, | |
| 384 | (__mmask32) -1); | |
| 385 | } | |
| 386 | ||
| 387 | ||
| 388 | #undef __DEFAULT_FN_ATTRS | |
| 389 | ||
| 390 | #endif | |
| 391 |
c_headers/avx512vlbitalgintrin.h created+157| ... | ... | @@ -0,0 +1,157 @@ |
| 1 | /*===------------- avx512vlbitalgintrin.h - BITALG intrinsics ------------------=== | |
| 2 | * | |
| 3 | * | |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 5 | * of this software and associated documentation files (the "Software"), to deal | |
| 6 | * in the Software without restriction, including without limitation the rights | |
| 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 8 | * copies of the Software, and to permit persons to whom the Software is | |
| 9 | * furnished to do so, subject to the following conditions: | |
| 10 | * | |
| 11 | * The above copyright notice and this permission notice shall be included in | |
| 12 | * all copies or substantial portions of the Software. | |
| 13 | * | |
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 20 | * THE SOFTWARE. | |
| 21 | * | |
| 22 | *===-----------------------------------------------------------------------=== | |
| 23 | */ | |
| 24 | #ifndef __IMMINTRIN_H | |
| 25 | #error "Never use <avx512vlbitalgintrin.h> directly; include <immintrin.h> instead." | |
| 26 | #endif | |
| 27 | ||
| 28 | #ifndef __AVX512VLBITALGINTRIN_H | |
| 29 | #define __AVX512VLBITALGINTRIN_H | |
| 30 | ||
| 31 | /* Define the default attributes for the functions in this file. */ | |
| 32 | #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512vl,avx512bitalg"))) | |
| 33 | ||
| 34 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 35 | _mm256_popcnt_epi16(__m256i __A) | |
| 36 | { | |
| 37 | return (__m256i) __builtin_ia32_vpopcntw_256((__v16hi) __A); | |
| 38 | } | |
| 39 | ||
| 40 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 41 | _mm256_mask_popcnt_epi16(__m256i __A, __mmask16 __U, __m256i __B) | |
| 42 | { | |
| 43 | return (__m256i) __builtin_ia32_selectw_256((__mmask16) __U, | |
| 44 | (__v16hi) _mm256_popcnt_epi16(__B), | |
| 45 | (__v16hi) __A); | |
| 46 | } | |
| 47 | ||
| 48 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 49 | _mm256_maskz_popcnt_epi16(__mmask16 __U, __m256i __B) | |
| 50 | { | |
| 51 | return _mm256_mask_popcnt_epi16((__m256i) _mm256_setzero_si256(), | |
| 52 | __U, | |
| 53 | __B); | |
| 54 | } | |
| 55 | ||
| 56 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 57 | _mm128_popcnt_epi16(__m128i __A) | |
| 58 | { | |
| 59 | return (__m128i) __builtin_ia32_vpopcntw_128((__v8hi) __A); | |
| 60 | } | |
| 61 | ||
| 62 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 63 | _mm128_mask_popcnt_epi16(__m128i __A, __mmask8 __U, __m128i __B) | |
| 64 | { | |
| 65 | return (__m128i) __builtin_ia32_selectw_128((__mmask8) __U, | |
| 66 | (__v8hi) _mm128_popcnt_epi16(__B), | |
| 67 | (__v8hi) __A); | |
| 68 | } | |
| 69 | ||
| 70 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 71 | _mm128_maskz_popcnt_epi16(__mmask8 __U, __m128i __B) | |
| 72 | { | |
| 73 | return _mm128_mask_popcnt_epi16((__m128i) _mm_setzero_si128(), | |
| 74 | __U, | |
| 75 | __B); | |
| 76 | } | |
| 77 | ||
| 78 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 79 | _mm256_popcnt_epi8(__m256i __A) | |
| 80 | { | |
| 81 | return (__m256i) __builtin_ia32_vpopcntb_256((__v32qi) __A); | |
| 82 | } | |
| 83 | ||
| 84 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 85 | _mm256_mask_popcnt_epi8(__m256i __A, __mmask32 __U, __m256i __B) | |
| 86 | { | |
| 87 | return (__m256i) __builtin_ia32_selectb_256((__mmask32) __U, | |
| 88 | (__v32qi) _mm256_popcnt_epi8(__B), | |
| 89 | (__v32qi) __A); | |
| 90 | } | |
| 91 | ||
| 92 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 93 | _mm256_maskz_popcnt_epi8(__mmask32 __U, __m256i __B) | |
| 94 | { | |
| 95 | return _mm256_mask_popcnt_epi8((__m256i) _mm256_setzero_si256(), | |
| 96 | __U, | |
| 97 | __B); | |
| 98 | } | |
| 99 | ||
| 100 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 101 | _mm128_popcnt_epi8(__m128i __A) | |
| 102 | { | |
| 103 | return (__m128i) __builtin_ia32_vpopcntb_128((__v16qi) __A); | |
| 104 | } | |
| 105 | ||
| 106 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 107 | _mm128_mask_popcnt_epi8(__m128i __A, __mmask16 __U, __m128i __B) | |
| 108 | { | |
| 109 | return (__m128i) __builtin_ia32_selectb_128((__mmask16) __U, | |
| 110 | (__v16qi) _mm128_popcnt_epi8(__B), | |
| 111 | (__v16qi) __A); | |
| 112 | } | |
| 113 | ||
| 114 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 115 | _mm128_maskz_popcnt_epi8(__mmask16 __U, __m128i __B) | |
| 116 | { | |
| 117 | return _mm128_mask_popcnt_epi8((__m128i) _mm_setzero_si128(), | |
| 118 | __U, | |
| 119 | __B); | |
| 120 | } | |
| 121 | ||
| 122 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 123 | _mm256_mask_bitshuffle_epi32_mask(__mmask32 __U, __m256i __A, __m256i __B) | |
| 124 | { | |
| 125 | return (__mmask32) __builtin_ia32_vpshufbitqmb256_mask((__v32qi) __A, | |
| 126 | (__v32qi) __B, | |
| 127 | __U); | |
| 128 | } | |
| 129 | ||
| 130 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 131 | _mm256_bitshuffle_epi32_mask(__m256i __A, __m256i __B) | |
| 132 | { | |
| 133 | return _mm256_mask_bitshuffle_epi32_mask((__mmask32) -1, | |
| 134 | __A, | |
| 135 | __B); | |
| 136 | } | |
| 137 | ||
| 138 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 139 | _mm128_mask_bitshuffle_epi16_mask(__mmask16 __U, __m128i __A, __m128i __B) | |
| 140 | { | |
| 141 | return (__mmask16) __builtin_ia32_vpshufbitqmb128_mask((__v16qi) __A, | |
| 142 | (__v16qi) __B, | |
| 143 | __U); | |
| 144 | } | |
| 145 | ||
| 146 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 147 | _mm128_bitshuffle_epi16_mask(__m128i __A, __m128i __B) | |
| 148 | { | |
| 149 | return _mm128_mask_bitshuffle_epi16_mask((__mmask16) -1, | |
| 150 | __A, | |
| 151 | __B); | |
| 152 | } | |
| 153 | ||
| 154 | ||
| 155 | #undef __DEFAULT_FN_ATTRS | |
| 156 | ||
| 157 | #endif |
c_headers/avx512vlbwintrin.h+314-705| ... | ... | @@ -38,581 +38,285 @@ _mm_setzero_hi(void){ |
| 38 | 38 | |
| 39 | 39 | /* Integer compare */ |
| 40 | 40 | |
| 41 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 42 | _mm_cmpeq_epi8_mask(__m128i __a, __m128i __b) { | |
| 43 | return (__mmask16)__builtin_ia32_pcmpeqb128_mask((__v16qi)__a, (__v16qi)__b, | |
| 44 | (__mmask16)-1); | |
| 45 | } | |
| 46 | ||
| 47 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 48 | _mm_mask_cmpeq_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { | |
| 49 | return (__mmask16)__builtin_ia32_pcmpeqb128_mask((__v16qi)__a, (__v16qi)__b, | |
| 50 | __u); | |
| 51 | } | |
| 52 | ||
| 53 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 54 | _mm_cmpeq_epu8_mask(__m128i __a, __m128i __b) { | |
| 55 | return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 0, | |
| 56 | (__mmask16)-1); | |
| 57 | } | |
| 58 | ||
| 59 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 60 | _mm_mask_cmpeq_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { | |
| 61 | return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 0, | |
| 62 | __u); | |
| 63 | } | |
| 64 | ||
| 65 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 66 | _mm256_cmpeq_epi8_mask(__m256i __a, __m256i __b) { | |
| 67 | return (__mmask32)__builtin_ia32_pcmpeqb256_mask((__v32qi)__a, (__v32qi)__b, | |
| 68 | (__mmask32)-1); | |
| 69 | } | |
| 70 | ||
| 71 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 72 | _mm256_mask_cmpeq_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { | |
| 73 | return (__mmask32)__builtin_ia32_pcmpeqb256_mask((__v32qi)__a, (__v32qi)__b, | |
| 74 | __u); | |
| 75 | } | |
| 76 | ||
| 77 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 78 | _mm256_cmpeq_epu8_mask(__m256i __a, __m256i __b) { | |
| 79 | return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 0, | |
| 80 | (__mmask32)-1); | |
| 81 | } | |
| 82 | ||
| 83 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 84 | _mm256_mask_cmpeq_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { | |
| 85 | return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 0, | |
| 86 | __u); | |
| 87 | } | |
| 88 | ||
| 89 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 90 | _mm_cmpeq_epi16_mask(__m128i __a, __m128i __b) { | |
| 91 | return (__mmask8)__builtin_ia32_pcmpeqw128_mask((__v8hi)__a, (__v8hi)__b, | |
| 92 | (__mmask8)-1); | |
| 93 | } | |
| 94 | ||
| 95 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 96 | _mm_mask_cmpeq_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 97 | return (__mmask8)__builtin_ia32_pcmpeqw128_mask((__v8hi)__a, (__v8hi)__b, | |
| 98 | __u); | |
| 99 | } | |
| 100 | ||
| 101 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 102 | _mm_cmpeq_epu16_mask(__m128i __a, __m128i __b) { | |
| 103 | return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 0, | |
| 104 | (__mmask8)-1); | |
| 105 | } | |
| 106 | ||
| 107 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 108 | _mm_mask_cmpeq_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 109 | return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 0, | |
| 110 | __u); | |
| 111 | } | |
| 112 | ||
| 113 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 114 | _mm256_cmpeq_epi16_mask(__m256i __a, __m256i __b) { | |
| 115 | return (__mmask16)__builtin_ia32_pcmpeqw256_mask((__v16hi)__a, (__v16hi)__b, | |
| 116 | (__mmask16)-1); | |
| 117 | } | |
| 118 | ||
| 119 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 120 | _mm256_mask_cmpeq_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { | |
| 121 | return (__mmask16)__builtin_ia32_pcmpeqw256_mask((__v16hi)__a, (__v16hi)__b, | |
| 122 | __u); | |
| 123 | } | |
| 124 | ||
| 125 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 126 | _mm256_cmpeq_epu16_mask(__m256i __a, __m256i __b) { | |
| 127 | return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 0, | |
| 128 | (__mmask16)-1); | |
| 129 | } | |
| 130 | ||
| 131 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 132 | _mm256_mask_cmpeq_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { | |
| 133 | return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 0, | |
| 134 | __u); | |
| 135 | } | |
| 136 | ||
| 137 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 138 | _mm_cmpge_epi8_mask(__m128i __a, __m128i __b) { | |
| 139 | return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 5, | |
| 140 | (__mmask16)-1); | |
| 141 | } | |
| 142 | ||
| 143 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 144 | _mm_mask_cmpge_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { | |
| 145 | return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 5, | |
| 146 | __u); | |
| 147 | } | |
| 148 | ||
| 149 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 150 | _mm_cmpge_epu8_mask(__m128i __a, __m128i __b) { | |
| 151 | return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 5, | |
| 152 | (__mmask16)-1); | |
| 153 | } | |
| 154 | ||
| 155 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 156 | _mm_mask_cmpge_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { | |
| 157 | return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 5, | |
| 158 | __u); | |
| 159 | } | |
| 160 | ||
| 161 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 162 | _mm256_cmpge_epi8_mask(__m256i __a, __m256i __b) { | |
| 163 | return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 5, | |
| 164 | (__mmask32)-1); | |
| 165 | } | |
| 166 | ||
| 167 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 168 | _mm256_mask_cmpge_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { | |
| 169 | return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 5, | |
| 170 | __u); | |
| 171 | } | |
| 172 | ||
| 173 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 174 | _mm256_cmpge_epu8_mask(__m256i __a, __m256i __b) { | |
| 175 | return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 5, | |
| 176 | (__mmask32)-1); | |
| 177 | } | |
| 178 | ||
| 179 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 180 | _mm256_mask_cmpge_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { | |
| 181 | return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 5, | |
| 182 | __u); | |
| 183 | } | |
| 184 | ||
| 185 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 186 | _mm_cmpge_epi16_mask(__m128i __a, __m128i __b) { | |
| 187 | return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 5, | |
| 188 | (__mmask8)-1); | |
| 189 | } | |
| 190 | ||
| 191 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 192 | _mm_mask_cmpge_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 193 | return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 5, | |
| 194 | __u); | |
| 195 | } | |
| 196 | ||
| 197 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 198 | _mm_cmpge_epu16_mask(__m128i __a, __m128i __b) { | |
| 199 | return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 5, | |
| 200 | (__mmask8)-1); | |
| 201 | } | |
| 202 | ||
| 203 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 204 | _mm_mask_cmpge_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 205 | return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 5, | |
| 206 | __u); | |
| 207 | } | |
| 208 | ||
| 209 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 210 | _mm256_cmpge_epi16_mask(__m256i __a, __m256i __b) { | |
| 211 | return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 5, | |
| 212 | (__mmask16)-1); | |
| 213 | } | |
| 214 | ||
| 215 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 216 | _mm256_mask_cmpge_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { | |
| 217 | return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 5, | |
| 218 | __u); | |
| 219 | } | |
| 220 | ||
| 221 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 222 | _mm256_cmpge_epu16_mask(__m256i __a, __m256i __b) { | |
| 223 | return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 5, | |
| 224 | (__mmask16)-1); | |
| 225 | } | |
| 226 | ||
| 227 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 228 | _mm256_mask_cmpge_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { | |
| 229 | return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 5, | |
| 230 | __u); | |
| 231 | } | |
| 232 | ||
| 233 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 234 | _mm_cmpgt_epi8_mask(__m128i __a, __m128i __b) { | |
| 235 | return (__mmask16)__builtin_ia32_pcmpgtb128_mask((__v16qi)__a, (__v16qi)__b, | |
| 236 | (__mmask16)-1); | |
| 237 | } | |
| 238 | ||
| 239 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 240 | _mm_mask_cmpgt_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { | |
| 241 | return (__mmask16)__builtin_ia32_pcmpgtb128_mask((__v16qi)__a, (__v16qi)__b, | |
| 242 | __u); | |
| 243 | } | |
| 244 | ||
| 245 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 246 | _mm_cmpgt_epu8_mask(__m128i __a, __m128i __b) { | |
| 247 | return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 6, | |
| 248 | (__mmask16)-1); | |
| 249 | } | |
| 250 | ||
| 251 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 252 | _mm_mask_cmpgt_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { | |
| 253 | return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 6, | |
| 254 | __u); | |
| 255 | } | |
| 256 | ||
| 257 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 258 | _mm256_cmpgt_epi8_mask(__m256i __a, __m256i __b) { | |
| 259 | return (__mmask32)__builtin_ia32_pcmpgtb256_mask((__v32qi)__a, (__v32qi)__b, | |
| 260 | (__mmask32)-1); | |
| 261 | } | |
| 262 | ||
| 263 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 264 | _mm256_mask_cmpgt_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { | |
| 265 | return (__mmask32)__builtin_ia32_pcmpgtb256_mask((__v32qi)__a, (__v32qi)__b, | |
| 266 | __u); | |
| 267 | } | |
| 268 | ||
| 269 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 270 | _mm256_cmpgt_epu8_mask(__m256i __a, __m256i __b) { | |
| 271 | return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 6, | |
| 272 | (__mmask32)-1); | |
| 273 | } | |
| 274 | ||
| 275 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 276 | _mm256_mask_cmpgt_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { | |
| 277 | return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 6, | |
| 278 | __u); | |
| 279 | } | |
| 280 | ||
| 281 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 282 | _mm_cmpgt_epi16_mask(__m128i __a, __m128i __b) { | |
| 283 | return (__mmask8)__builtin_ia32_pcmpgtw128_mask((__v8hi)__a, (__v8hi)__b, | |
| 284 | (__mmask8)-1); | |
| 285 | } | |
| 286 | ||
| 287 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 288 | _mm_mask_cmpgt_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 289 | return (__mmask8)__builtin_ia32_pcmpgtw128_mask((__v8hi)__a, (__v8hi)__b, | |
| 290 | __u); | |
| 291 | } | |
| 292 | ||
| 293 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 294 | _mm_cmpgt_epu16_mask(__m128i __a, __m128i __b) { | |
| 295 | return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 6, | |
| 296 | (__mmask8)-1); | |
| 297 | } | |
| 298 | ||
| 299 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 300 | _mm_mask_cmpgt_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 301 | return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 6, | |
| 302 | __u); | |
| 303 | } | |
| 304 | ||
| 305 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 306 | _mm256_cmpgt_epi16_mask(__m256i __a, __m256i __b) { | |
| 307 | return (__mmask16)__builtin_ia32_pcmpgtw256_mask((__v16hi)__a, (__v16hi)__b, | |
| 308 | (__mmask16)-1); | |
| 309 | } | |
| 310 | ||
| 311 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 312 | _mm256_mask_cmpgt_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { | |
| 313 | return (__mmask16)__builtin_ia32_pcmpgtw256_mask((__v16hi)__a, (__v16hi)__b, | |
| 314 | __u); | |
| 315 | } | |
| 316 | ||
| 317 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 318 | _mm256_cmpgt_epu16_mask(__m256i __a, __m256i __b) { | |
| 319 | return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 6, | |
| 320 | (__mmask16)-1); | |
| 321 | } | |
| 322 | ||
| 323 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 324 | _mm256_mask_cmpgt_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { | |
| 325 | return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 6, | |
| 326 | __u); | |
| 327 | } | |
| 328 | ||
| 329 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 330 | _mm_cmple_epi8_mask(__m128i __a, __m128i __b) { | |
| 331 | return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 2, | |
| 332 | (__mmask16)-1); | |
| 333 | } | |
| 334 | ||
| 335 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 336 | _mm_mask_cmple_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { | |
| 337 | return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 2, | |
| 338 | __u); | |
| 339 | } | |
| 340 | ||
| 341 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 342 | _mm_cmple_epu8_mask(__m128i __a, __m128i __b) { | |
| 343 | return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 2, | |
| 344 | (__mmask16)-1); | |
| 345 | } | |
| 346 | ||
| 347 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 348 | _mm_mask_cmple_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { | |
| 349 | return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 2, | |
| 350 | __u); | |
| 351 | } | |
| 352 | ||
| 353 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 354 | _mm256_cmple_epi8_mask(__m256i __a, __m256i __b) { | |
| 355 | return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 2, | |
| 356 | (__mmask32)-1); | |
| 357 | } | |
| 358 | ||
| 359 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 360 | _mm256_mask_cmple_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { | |
| 361 | return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 2, | |
| 362 | __u); | |
| 363 | } | |
| 364 | ||
| 365 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 366 | _mm256_cmple_epu8_mask(__m256i __a, __m256i __b) { | |
| 367 | return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 2, | |
| 368 | (__mmask32)-1); | |
| 369 | } | |
| 370 | ||
| 371 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 372 | _mm256_mask_cmple_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { | |
| 373 | return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 2, | |
| 374 | __u); | |
| 375 | } | |
| 376 | ||
| 377 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 378 | _mm_cmple_epi16_mask(__m128i __a, __m128i __b) { | |
| 379 | return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 2, | |
| 380 | (__mmask8)-1); | |
| 381 | } | |
| 382 | ||
| 383 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 384 | _mm_mask_cmple_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 385 | return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 2, | |
| 386 | __u); | |
| 387 | } | |
| 388 | ||
| 389 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 390 | _mm_cmple_epu16_mask(__m128i __a, __m128i __b) { | |
| 391 | return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 2, | |
| 392 | (__mmask8)-1); | |
| 393 | } | |
| 394 | ||
| 395 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 396 | _mm_mask_cmple_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 397 | return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 2, | |
| 398 | __u); | |
| 399 | } | |
| 400 | ||
| 401 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 402 | _mm256_cmple_epi16_mask(__m256i __a, __m256i __b) { | |
| 403 | return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 2, | |
| 404 | (__mmask16)-1); | |
| 405 | } | |
| 406 | ||
| 407 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 408 | _mm256_mask_cmple_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { | |
| 409 | return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 2, | |
| 410 | __u); | |
| 411 | } | |
| 412 | ||
| 413 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 414 | _mm256_cmple_epu16_mask(__m256i __a, __m256i __b) { | |
| 415 | return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 2, | |
| 416 | (__mmask16)-1); | |
| 417 | } | |
| 418 | ||
| 419 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 420 | _mm256_mask_cmple_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { | |
| 421 | return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 2, | |
| 422 | __u); | |
| 423 | } | |
| 424 | ||
| 425 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 426 | _mm_cmplt_epi8_mask(__m128i __a, __m128i __b) { | |
| 427 | return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 1, | |
| 428 | (__mmask16)-1); | |
| 429 | } | |
| 430 | ||
| 431 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 432 | _mm_mask_cmplt_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { | |
| 433 | return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 1, | |
| 434 | __u); | |
| 435 | } | |
| 436 | ||
| 437 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 438 | _mm_cmplt_epu8_mask(__m128i __a, __m128i __b) { | |
| 439 | return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 1, | |
| 440 | (__mmask16)-1); | |
| 441 | } | |
| 442 | ||
| 443 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 444 | _mm_mask_cmplt_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { | |
| 445 | return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 1, | |
| 446 | __u); | |
| 447 | } | |
| 448 | ||
| 449 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 450 | _mm256_cmplt_epi8_mask(__m256i __a, __m256i __b) { | |
| 451 | return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 1, | |
| 452 | (__mmask32)-1); | |
| 453 | } | |
| 454 | ||
| 455 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 456 | _mm256_mask_cmplt_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { | |
| 457 | return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 1, | |
| 458 | __u); | |
| 459 | } | |
| 460 | ||
| 461 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 462 | _mm256_cmplt_epu8_mask(__m256i __a, __m256i __b) { | |
| 463 | return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 1, | |
| 464 | (__mmask32)-1); | |
| 465 | } | |
| 466 | ||
| 467 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 468 | _mm256_mask_cmplt_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { | |
| 469 | return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 1, | |
| 470 | __u); | |
| 471 | } | |
| 472 | ||
| 473 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 474 | _mm_cmplt_epi16_mask(__m128i __a, __m128i __b) { | |
| 475 | return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 1, | |
| 476 | (__mmask8)-1); | |
| 477 | } | |
| 478 | ||
| 479 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 480 | _mm_mask_cmplt_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 481 | return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 1, | |
| 482 | __u); | |
| 483 | } | |
| 484 | ||
| 485 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 486 | _mm_cmplt_epu16_mask(__m128i __a, __m128i __b) { | |
| 487 | return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 1, | |
| 488 | (__mmask8)-1); | |
| 489 | } | |
| 490 | ||
| 491 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 492 | _mm_mask_cmplt_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 493 | return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 1, | |
| 494 | __u); | |
| 495 | } | |
| 496 | ||
| 497 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 498 | _mm256_cmplt_epi16_mask(__m256i __a, __m256i __b) { | |
| 499 | return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 1, | |
| 500 | (__mmask16)-1); | |
| 501 | } | |
| 502 | ||
| 503 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 504 | _mm256_mask_cmplt_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { | |
| 505 | return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 1, | |
| 506 | __u); | |
| 507 | } | |
| 508 | ||
| 509 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 510 | _mm256_cmplt_epu16_mask(__m256i __a, __m256i __b) { | |
| 511 | return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 1, | |
| 512 | (__mmask16)-1); | |
| 513 | } | |
| 514 | ||
| 515 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 516 | _mm256_mask_cmplt_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { | |
| 517 | return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 1, | |
| 518 | __u); | |
| 519 | } | |
| 41 | #define _mm_cmp_epi8_mask(a, b, p) __extension__ ({ \ | |
| 42 | (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)(__m128i)(a), \ | |
| 43 | (__v16qi)(__m128i)(b), (int)(p), \ | |
| 44 | (__mmask16)-1); }) | |
| 520 | 45 | |
| 521 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 522 | _mm_cmpneq_epi8_mask(__m128i __a, __m128i __b) { | |
| 523 | return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 4, | |
| 524 | (__mmask16)-1); | |
| 525 | } | |
| 46 | #define _mm_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ | |
| 47 | (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)(__m128i)(a), \ | |
| 48 | (__v16qi)(__m128i)(b), (int)(p), \ | |
| 49 | (__mmask16)(m)); }) | |
| 526 | 50 | |
| 527 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 528 | _mm_mask_cmpneq_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { | |
| 529 | return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 4, | |
| 530 | __u); | |
| 531 | } | |
| 51 | #define _mm_cmp_epu8_mask(a, b, p) __extension__ ({ \ | |
| 52 | (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)(__m128i)(a), \ | |
| 53 | (__v16qi)(__m128i)(b), (int)(p), \ | |
| 54 | (__mmask16)-1); }) | |
| 532 | 55 | |
| 533 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 534 | _mm_cmpneq_epu8_mask(__m128i __a, __m128i __b) { | |
| 535 | return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 4, | |
| 536 | (__mmask16)-1); | |
| 537 | } | |
| 56 | #define _mm_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ | |
| 57 | (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)(__m128i)(a), \ | |
| 58 | (__v16qi)(__m128i)(b), (int)(p), \ | |
| 59 | (__mmask16)(m)); }) | |
| 538 | 60 | |
| 539 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 540 | _mm_mask_cmpneq_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { | |
| 541 | return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 4, | |
| 542 | __u); | |
| 543 | } | |
| 61 | #define _mm256_cmp_epi8_mask(a, b, p) __extension__ ({ \ | |
| 62 | (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)(__m256i)(a), \ | |
| 63 | (__v32qi)(__m256i)(b), (int)(p), \ | |
| 64 | (__mmask32)-1); }) | |
| 544 | 65 | |
| 545 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 546 | _mm256_cmpneq_epi8_mask(__m256i __a, __m256i __b) { | |
| 547 | return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 4, | |
| 548 | (__mmask32)-1); | |
| 549 | } | |
| 66 | #define _mm256_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ | |
| 67 | (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)(__m256i)(a), \ | |
| 68 | (__v32qi)(__m256i)(b), (int)(p), \ | |
| 69 | (__mmask32)(m)); }) | |
| 550 | 70 | |
| 551 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 552 | _mm256_mask_cmpneq_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { | |
| 553 | return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 4, | |
| 554 | __u); | |
| 555 | } | |
| 71 | #define _mm256_cmp_epu8_mask(a, b, p) __extension__ ({ \ | |
| 72 | (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)(__m256i)(a), \ | |
| 73 | (__v32qi)(__m256i)(b), (int)(p), \ | |
| 74 | (__mmask32)-1); }) | |
| 556 | 75 | |
| 557 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 558 | _mm256_cmpneq_epu8_mask(__m256i __a, __m256i __b) { | |
| 559 | return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 4, | |
| 560 | (__mmask32)-1); | |
| 561 | } | |
| 76 | #define _mm256_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ | |
| 77 | (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)(__m256i)(a), \ | |
| 78 | (__v32qi)(__m256i)(b), (int)(p), \ | |
| 79 | (__mmask32)(m)); }) | |
| 562 | 80 | |
| 563 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS | |
| 564 | _mm256_mask_cmpneq_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { | |
| 565 | return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 4, | |
| 566 | __u); | |
| 567 | } | |
| 81 | #define _mm_cmp_epi16_mask(a, b, p) __extension__ ({ \ | |
| 82 | (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)(__m128i)(a), \ | |
| 83 | (__v8hi)(__m128i)(b), (int)(p), \ | |
| 84 | (__mmask8)-1); }) | |
| 568 | 85 | |
| 569 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 570 | _mm_cmpneq_epi16_mask(__m128i __a, __m128i __b) { | |
| 571 | return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 4, | |
| 572 | (__mmask8)-1); | |
| 573 | } | |
| 86 | #define _mm_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ | |
| 87 | (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)(__m128i)(a), \ | |
| 88 | (__v8hi)(__m128i)(b), (int)(p), \ | |
| 89 | (__mmask8)(m)); }) | |
| 574 | 90 | |
| 575 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 576 | _mm_mask_cmpneq_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 577 | return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 4, | |
| 578 | __u); | |
| 579 | } | |
| 91 | #define _mm_cmp_epu16_mask(a, b, p) __extension__ ({ \ | |
| 92 | (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)(__m128i)(a), \ | |
| 93 | (__v8hi)(__m128i)(b), (int)(p), \ | |
| 94 | (__mmask8)-1); }) | |
| 580 | 95 | |
| 581 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 582 | _mm_cmpneq_epu16_mask(__m128i __a, __m128i __b) { | |
| 583 | return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 4, | |
| 584 | (__mmask8)-1); | |
| 585 | } | |
| 96 | #define _mm_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ | |
| 97 | (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)(__m128i)(a), \ | |
| 98 | (__v8hi)(__m128i)(b), (int)(p), \ | |
| 99 | (__mmask8)(m)); }) | |
| 586 | 100 | |
| 587 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 588 | _mm_mask_cmpneq_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 589 | return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 4, | |
| 590 | __u); | |
| 591 | } | |
| 101 | #define _mm256_cmp_epi16_mask(a, b, p) __extension__ ({ \ | |
| 102 | (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)(__m256i)(a), \ | |
| 103 | (__v16hi)(__m256i)(b), (int)(p), \ | |
| 104 | (__mmask16)-1); }) | |
| 592 | 105 | |
| 593 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 594 | _mm256_cmpneq_epi16_mask(__m256i __a, __m256i __b) { | |
| 595 | return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 4, | |
| 596 | (__mmask16)-1); | |
| 597 | } | |
| 106 | #define _mm256_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ | |
| 107 | (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)(__m256i)(a), \ | |
| 108 | (__v16hi)(__m256i)(b), (int)(p), \ | |
| 109 | (__mmask16)(m)); }) | |
| 598 | 110 | |
| 599 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 600 | _mm256_mask_cmpneq_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { | |
| 601 | return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 4, | |
| 602 | __u); | |
| 603 | } | |
| 111 | #define _mm256_cmp_epu16_mask(a, b, p) __extension__ ({ \ | |
| 112 | (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)(__m256i)(a), \ | |
| 113 | (__v16hi)(__m256i)(b), (int)(p), \ | |
| 114 | (__mmask16)-1); }) | |
| 604 | 115 | |
| 605 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 606 | _mm256_cmpneq_epu16_mask(__m256i __a, __m256i __b) { | |
| 607 | return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 4, | |
| 608 | (__mmask16)-1); | |
| 609 | } | |
| 116 | #define _mm256_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ | |
| 117 | (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)(__m256i)(a), \ | |
| 118 | (__v16hi)(__m256i)(b), (int)(p), \ | |
| 119 | (__mmask16)(m)); }) | |
| 610 | 120 | |
| 611 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS | |
| 612 | _mm256_mask_cmpneq_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { | |
| 613 | return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 4, | |
| 614 | __u); | |
| 615 | } | |
| 121 | #define _mm_cmpeq_epi8_mask(A, B) \ | |
| 122 | _mm_cmp_epi8_mask((A), (B), _MM_CMPINT_EQ) | |
| 123 | #define _mm_mask_cmpeq_epi8_mask(k, A, B) \ | |
| 124 | _mm_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 125 | #define _mm_cmpge_epi8_mask(A, B) \ | |
| 126 | _mm_cmp_epi8_mask((A), (B), _MM_CMPINT_GE) | |
| 127 | #define _mm_mask_cmpge_epi8_mask(k, A, B) \ | |
| 128 | _mm_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 129 | #define _mm_cmpgt_epi8_mask(A, B) \ | |
| 130 | _mm_cmp_epi8_mask((A), (B), _MM_CMPINT_GT) | |
| 131 | #define _mm_mask_cmpgt_epi8_mask(k, A, B) \ | |
| 132 | _mm_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 133 | #define _mm_cmple_epi8_mask(A, B) \ | |
| 134 | _mm_cmp_epi8_mask((A), (B), _MM_CMPINT_LE) | |
| 135 | #define _mm_mask_cmple_epi8_mask(k, A, B) \ | |
| 136 | _mm_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 137 | #define _mm_cmplt_epi8_mask(A, B) \ | |
| 138 | _mm_cmp_epi8_mask((A), (B), _MM_CMPINT_LT) | |
| 139 | #define _mm_mask_cmplt_epi8_mask(k, A, B) \ | |
| 140 | _mm_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 141 | #define _mm_cmpneq_epi8_mask(A, B) \ | |
| 142 | _mm_cmp_epi8_mask((A), (B), _MM_CMPINT_NE) | |
| 143 | #define _mm_mask_cmpneq_epi8_mask(k, A, B) \ | |
| 144 | _mm_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 145 | ||
| 146 | #define _mm256_cmpeq_epi8_mask(A, B) \ | |
| 147 | _mm256_cmp_epi8_mask((A), (B), _MM_CMPINT_EQ) | |
| 148 | #define _mm256_mask_cmpeq_epi8_mask(k, A, B) \ | |
| 149 | _mm256_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 150 | #define _mm256_cmpge_epi8_mask(A, B) \ | |
| 151 | _mm256_cmp_epi8_mask((A), (B), _MM_CMPINT_GE) | |
| 152 | #define _mm256_mask_cmpge_epi8_mask(k, A, B) \ | |
| 153 | _mm256_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 154 | #define _mm256_cmpgt_epi8_mask(A, B) \ | |
| 155 | _mm256_cmp_epi8_mask((A), (B), _MM_CMPINT_GT) | |
| 156 | #define _mm256_mask_cmpgt_epi8_mask(k, A, B) \ | |
| 157 | _mm256_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 158 | #define _mm256_cmple_epi8_mask(A, B) \ | |
| 159 | _mm256_cmp_epi8_mask((A), (B), _MM_CMPINT_LE) | |
| 160 | #define _mm256_mask_cmple_epi8_mask(k, A, B) \ | |
| 161 | _mm256_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 162 | #define _mm256_cmplt_epi8_mask(A, B) \ | |
| 163 | _mm256_cmp_epi8_mask((A), (B), _MM_CMPINT_LT) | |
| 164 | #define _mm256_mask_cmplt_epi8_mask(k, A, B) \ | |
| 165 | _mm256_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 166 | #define _mm256_cmpneq_epi8_mask(A, B) \ | |
| 167 | _mm256_cmp_epi8_mask((A), (B), _MM_CMPINT_NE) | |
| 168 | #define _mm256_mask_cmpneq_epi8_mask(k, A, B) \ | |
| 169 | _mm256_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 170 | ||
| 171 | #define _mm_cmpeq_epu8_mask(A, B) \ | |
| 172 | _mm_cmp_epu8_mask((A), (B), _MM_CMPINT_EQ) | |
| 173 | #define _mm_mask_cmpeq_epu8_mask(k, A, B) \ | |
| 174 | _mm_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 175 | #define _mm_cmpge_epu8_mask(A, B) \ | |
| 176 | _mm_cmp_epu8_mask((A), (B), _MM_CMPINT_GE) | |
| 177 | #define _mm_mask_cmpge_epu8_mask(k, A, B) \ | |
| 178 | _mm_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 179 | #define _mm_cmpgt_epu8_mask(A, B) \ | |
| 180 | _mm_cmp_epu8_mask((A), (B), _MM_CMPINT_GT) | |
| 181 | #define _mm_mask_cmpgt_epu8_mask(k, A, B) \ | |
| 182 | _mm_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 183 | #define _mm_cmple_epu8_mask(A, B) \ | |
| 184 | _mm_cmp_epu8_mask((A), (B), _MM_CMPINT_LE) | |
| 185 | #define _mm_mask_cmple_epu8_mask(k, A, B) \ | |
| 186 | _mm_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 187 | #define _mm_cmplt_epu8_mask(A, B) \ | |
| 188 | _mm_cmp_epu8_mask((A), (B), _MM_CMPINT_LT) | |
| 189 | #define _mm_mask_cmplt_epu8_mask(k, A, B) \ | |
| 190 | _mm_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 191 | #define _mm_cmpneq_epu8_mask(A, B) \ | |
| 192 | _mm_cmp_epu8_mask((A), (B), _MM_CMPINT_NE) | |
| 193 | #define _mm_mask_cmpneq_epu8_mask(k, A, B) \ | |
| 194 | _mm_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 195 | ||
| 196 | #define _mm256_cmpeq_epu8_mask(A, B) \ | |
| 197 | _mm256_cmp_epu8_mask((A), (B), _MM_CMPINT_EQ) | |
| 198 | #define _mm256_mask_cmpeq_epu8_mask(k, A, B) \ | |
| 199 | _mm256_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 200 | #define _mm256_cmpge_epu8_mask(A, B) \ | |
| 201 | _mm256_cmp_epu8_mask((A), (B), _MM_CMPINT_GE) | |
| 202 | #define _mm256_mask_cmpge_epu8_mask(k, A, B) \ | |
| 203 | _mm256_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 204 | #define _mm256_cmpgt_epu8_mask(A, B) \ | |
| 205 | _mm256_cmp_epu8_mask((A), (B), _MM_CMPINT_GT) | |
| 206 | #define _mm256_mask_cmpgt_epu8_mask(k, A, B) \ | |
| 207 | _mm256_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 208 | #define _mm256_cmple_epu8_mask(A, B) \ | |
| 209 | _mm256_cmp_epu8_mask((A), (B), _MM_CMPINT_LE) | |
| 210 | #define _mm256_mask_cmple_epu8_mask(k, A, B) \ | |
| 211 | _mm256_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 212 | #define _mm256_cmplt_epu8_mask(A, B) \ | |
| 213 | _mm256_cmp_epu8_mask((A), (B), _MM_CMPINT_LT) | |
| 214 | #define _mm256_mask_cmplt_epu8_mask(k, A, B) \ | |
| 215 | _mm256_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 216 | #define _mm256_cmpneq_epu8_mask(A, B) \ | |
| 217 | _mm256_cmp_epu8_mask((A), (B), _MM_CMPINT_NE) | |
| 218 | #define _mm256_mask_cmpneq_epu8_mask(k, A, B) \ | |
| 219 | _mm256_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 220 | ||
| 221 | #define _mm_cmpeq_epi16_mask(A, B) \ | |
| 222 | _mm_cmp_epi16_mask((A), (B), _MM_CMPINT_EQ) | |
| 223 | #define _mm_mask_cmpeq_epi16_mask(k, A, B) \ | |
| 224 | _mm_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 225 | #define _mm_cmpge_epi16_mask(A, B) \ | |
| 226 | _mm_cmp_epi16_mask((A), (B), _MM_CMPINT_GE) | |
| 227 | #define _mm_mask_cmpge_epi16_mask(k, A, B) \ | |
| 228 | _mm_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 229 | #define _mm_cmpgt_epi16_mask(A, B) \ | |
| 230 | _mm_cmp_epi16_mask((A), (B), _MM_CMPINT_GT) | |
| 231 | #define _mm_mask_cmpgt_epi16_mask(k, A, B) \ | |
| 232 | _mm_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 233 | #define _mm_cmple_epi16_mask(A, B) \ | |
| 234 | _mm_cmp_epi16_mask((A), (B), _MM_CMPINT_LE) | |
| 235 | #define _mm_mask_cmple_epi16_mask(k, A, B) \ | |
| 236 | _mm_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 237 | #define _mm_cmplt_epi16_mask(A, B) \ | |
| 238 | _mm_cmp_epi16_mask((A), (B), _MM_CMPINT_LT) | |
| 239 | #define _mm_mask_cmplt_epi16_mask(k, A, B) \ | |
| 240 | _mm_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 241 | #define _mm_cmpneq_epi16_mask(A, B) \ | |
| 242 | _mm_cmp_epi16_mask((A), (B), _MM_CMPINT_NE) | |
| 243 | #define _mm_mask_cmpneq_epi16_mask(k, A, B) \ | |
| 244 | _mm_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 245 | ||
| 246 | #define _mm256_cmpeq_epi16_mask(A, B) \ | |
| 247 | _mm256_cmp_epi16_mask((A), (B), _MM_CMPINT_EQ) | |
| 248 | #define _mm256_mask_cmpeq_epi16_mask(k, A, B) \ | |
| 249 | _mm256_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 250 | #define _mm256_cmpge_epi16_mask(A, B) \ | |
| 251 | _mm256_cmp_epi16_mask((A), (B), _MM_CMPINT_GE) | |
| 252 | #define _mm256_mask_cmpge_epi16_mask(k, A, B) \ | |
| 253 | _mm256_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 254 | #define _mm256_cmpgt_epi16_mask(A, B) \ | |
| 255 | _mm256_cmp_epi16_mask((A), (B), _MM_CMPINT_GT) | |
| 256 | #define _mm256_mask_cmpgt_epi16_mask(k, A, B) \ | |
| 257 | _mm256_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 258 | #define _mm256_cmple_epi16_mask(A, B) \ | |
| 259 | _mm256_cmp_epi16_mask((A), (B), _MM_CMPINT_LE) | |
| 260 | #define _mm256_mask_cmple_epi16_mask(k, A, B) \ | |
| 261 | _mm256_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 262 | #define _mm256_cmplt_epi16_mask(A, B) \ | |
| 263 | _mm256_cmp_epi16_mask((A), (B), _MM_CMPINT_LT) | |
| 264 | #define _mm256_mask_cmplt_epi16_mask(k, A, B) \ | |
| 265 | _mm256_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 266 | #define _mm256_cmpneq_epi16_mask(A, B) \ | |
| 267 | _mm256_cmp_epi16_mask((A), (B), _MM_CMPINT_NE) | |
| 268 | #define _mm256_mask_cmpneq_epi16_mask(k, A, B) \ | |
| 269 | _mm256_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 270 | ||
| 271 | #define _mm_cmpeq_epu16_mask(A, B) \ | |
| 272 | _mm_cmp_epu16_mask((A), (B), _MM_CMPINT_EQ) | |
| 273 | #define _mm_mask_cmpeq_epu16_mask(k, A, B) \ | |
| 274 | _mm_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 275 | #define _mm_cmpge_epu16_mask(A, B) \ | |
| 276 | _mm_cmp_epu16_mask((A), (B), _MM_CMPINT_GE) | |
| 277 | #define _mm_mask_cmpge_epu16_mask(k, A, B) \ | |
| 278 | _mm_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 279 | #define _mm_cmpgt_epu16_mask(A, B) \ | |
| 280 | _mm_cmp_epu16_mask((A), (B), _MM_CMPINT_GT) | |
| 281 | #define _mm_mask_cmpgt_epu16_mask(k, A, B) \ | |
| 282 | _mm_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 283 | #define _mm_cmple_epu16_mask(A, B) \ | |
| 284 | _mm_cmp_epu16_mask((A), (B), _MM_CMPINT_LE) | |
| 285 | #define _mm_mask_cmple_epu16_mask(k, A, B) \ | |
| 286 | _mm_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 287 | #define _mm_cmplt_epu16_mask(A, B) \ | |
| 288 | _mm_cmp_epu16_mask((A), (B), _MM_CMPINT_LT) | |
| 289 | #define _mm_mask_cmplt_epu16_mask(k, A, B) \ | |
| 290 | _mm_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 291 | #define _mm_cmpneq_epu16_mask(A, B) \ | |
| 292 | _mm_cmp_epu16_mask((A), (B), _MM_CMPINT_NE) | |
| 293 | #define _mm_mask_cmpneq_epu16_mask(k, A, B) \ | |
| 294 | _mm_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 295 | ||
| 296 | #define _mm256_cmpeq_epu16_mask(A, B) \ | |
| 297 | _mm256_cmp_epu16_mask((A), (B), _MM_CMPINT_EQ) | |
| 298 | #define _mm256_mask_cmpeq_epu16_mask(k, A, B) \ | |
| 299 | _mm256_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 300 | #define _mm256_cmpge_epu16_mask(A, B) \ | |
| 301 | _mm256_cmp_epu16_mask((A), (B), _MM_CMPINT_GE) | |
| 302 | #define _mm256_mask_cmpge_epu16_mask(k, A, B) \ | |
| 303 | _mm256_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 304 | #define _mm256_cmpgt_epu16_mask(A, B) \ | |
| 305 | _mm256_cmp_epu16_mask((A), (B), _MM_CMPINT_GT) | |
| 306 | #define _mm256_mask_cmpgt_epu16_mask(k, A, B) \ | |
| 307 | _mm256_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 308 | #define _mm256_cmple_epu16_mask(A, B) \ | |
| 309 | _mm256_cmp_epu16_mask((A), (B), _MM_CMPINT_LE) | |
| 310 | #define _mm256_mask_cmple_epu16_mask(k, A, B) \ | |
| 311 | _mm256_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 312 | #define _mm256_cmplt_epu16_mask(A, B) \ | |
| 313 | _mm256_cmp_epu16_mask((A), (B), _MM_CMPINT_LT) | |
| 314 | #define _mm256_mask_cmplt_epu16_mask(k, A, B) \ | |
| 315 | _mm256_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 316 | #define _mm256_cmpneq_epu16_mask(A, B) \ | |
| 317 | _mm256_cmp_epu16_mask((A), (B), _MM_CMPINT_NE) | |
| 318 | #define _mm256_mask_cmpneq_epu16_mask(k, A, B) \ | |
| 319 | _mm256_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 616 | 320 | |
| 617 | 321 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 618 | 322 | _mm256_mask_add_epi8(__m256i __W, __mmask32 __U, __m256i __A, __m256i __B){ |
| ... | ... | @@ -2146,86 +1850,6 @@ _mm256_maskz_cvtepu8_epi16 (__mmask16 __U, __m128i __A) |
| 2146 | 1850 | } |
| 2147 | 1851 | |
| 2148 | 1852 | |
| 2149 | #define _mm_cmp_epi8_mask(a, b, p) __extension__ ({ \ | |
| 2150 | (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)(__m128i)(a), \ | |
| 2151 | (__v16qi)(__m128i)(b), (int)(p), \ | |
| 2152 | (__mmask16)-1); }) | |
| 2153 | ||
| 2154 | #define _mm_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ | |
| 2155 | (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)(__m128i)(a), \ | |
| 2156 | (__v16qi)(__m128i)(b), (int)(p), \ | |
| 2157 | (__mmask16)(m)); }) | |
| 2158 | ||
| 2159 | #define _mm_cmp_epu8_mask(a, b, p) __extension__ ({ \ | |
| 2160 | (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)(__m128i)(a), \ | |
| 2161 | (__v16qi)(__m128i)(b), (int)(p), \ | |
| 2162 | (__mmask16)-1); }) | |
| 2163 | ||
| 2164 | #define _mm_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ | |
| 2165 | (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)(__m128i)(a), \ | |
| 2166 | (__v16qi)(__m128i)(b), (int)(p), \ | |
| 2167 | (__mmask16)(m)); }) | |
| 2168 | ||
| 2169 | #define _mm256_cmp_epi8_mask(a, b, p) __extension__ ({ \ | |
| 2170 | (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)(__m256i)(a), \ | |
| 2171 | (__v32qi)(__m256i)(b), (int)(p), \ | |
| 2172 | (__mmask32)-1); }) | |
| 2173 | ||
| 2174 | #define _mm256_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ | |
| 2175 | (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)(__m256i)(a), \ | |
| 2176 | (__v32qi)(__m256i)(b), (int)(p), \ | |
| 2177 | (__mmask32)(m)); }) | |
| 2178 | ||
| 2179 | #define _mm256_cmp_epu8_mask(a, b, p) __extension__ ({ \ | |
| 2180 | (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)(__m256i)(a), \ | |
| 2181 | (__v32qi)(__m256i)(b), (int)(p), \ | |
| 2182 | (__mmask32)-1); }) | |
| 2183 | ||
| 2184 | #define _mm256_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ | |
| 2185 | (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)(__m256i)(a), \ | |
| 2186 | (__v32qi)(__m256i)(b), (int)(p), \ | |
| 2187 | (__mmask32)(m)); }) | |
| 2188 | ||
| 2189 | #define _mm_cmp_epi16_mask(a, b, p) __extension__ ({ \ | |
| 2190 | (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)(__m128i)(a), \ | |
| 2191 | (__v8hi)(__m128i)(b), (int)(p), \ | |
| 2192 | (__mmask8)-1); }) | |
| 2193 | ||
| 2194 | #define _mm_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ | |
| 2195 | (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)(__m128i)(a), \ | |
| 2196 | (__v8hi)(__m128i)(b), (int)(p), \ | |
| 2197 | (__mmask8)(m)); }) | |
| 2198 | ||
| 2199 | #define _mm_cmp_epu16_mask(a, b, p) __extension__ ({ \ | |
| 2200 | (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)(__m128i)(a), \ | |
| 2201 | (__v8hi)(__m128i)(b), (int)(p), \ | |
| 2202 | (__mmask8)-1); }) | |
| 2203 | ||
| 2204 | #define _mm_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ | |
| 2205 | (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)(__m128i)(a), \ | |
| 2206 | (__v8hi)(__m128i)(b), (int)(p), \ | |
| 2207 | (__mmask8)(m)); }) | |
| 2208 | ||
| 2209 | #define _mm256_cmp_epi16_mask(a, b, p) __extension__ ({ \ | |
| 2210 | (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)(__m256i)(a), \ | |
| 2211 | (__v16hi)(__m256i)(b), (int)(p), \ | |
| 2212 | (__mmask16)-1); }) | |
| 2213 | ||
| 2214 | #define _mm256_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ | |
| 2215 | (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)(__m256i)(a), \ | |
| 2216 | (__v16hi)(__m256i)(b), (int)(p), \ | |
| 2217 | (__mmask16)(m)); }) | |
| 2218 | ||
| 2219 | #define _mm256_cmp_epu16_mask(a, b, p) __extension__ ({ \ | |
| 2220 | (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)(__m256i)(a), \ | |
| 2221 | (__v16hi)(__m256i)(b), (int)(p), \ | |
| 2222 | (__mmask16)-1); }) | |
| 2223 | ||
| 2224 | #define _mm256_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ | |
| 2225 | (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)(__m256i)(a), \ | |
| 2226 | (__v16hi)(__m256i)(b), (int)(p), \ | |
| 2227 | (__mmask16)(m)); }) | |
| 2228 | ||
| 2229 | 1853 | #define _mm_mask_shufflehi_epi16(W, U, A, imm) __extension__ ({ \ |
| 2230 | 1854 | (__m128i)__builtin_ia32_selectw_128((__mmask8)(U), \ |
| 2231 | 1855 | (__v8hi)_mm_shufflehi_epi16((A), (imm)), \ |
| ... | ... | @@ -2660,35 +2284,33 @@ _mm256_maskz_mov_epi8 (__mmask32 __U, __m256i __A) |
| 2660 | 2284 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| 2661 | 2285 | _mm_mask_set1_epi8 (__m128i __O, __mmask16 __M, char __A) |
| 2662 | 2286 | { |
| 2663 | return (__m128i) __builtin_ia32_pbroadcastb128_gpr_mask (__A, | |
| 2664 | (__v16qi) __O, | |
| 2665 | __M); | |
| 2287 | return (__m128i) __builtin_ia32_selectb_128(__M, | |
| 2288 | (__v16qi) _mm_set1_epi8(__A), | |
| 2289 | (__v16qi) __O); | |
| 2666 | 2290 | } |
| 2667 | 2291 | |
| 2668 | 2292 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| 2669 | 2293 | _mm_maskz_set1_epi8 (__mmask16 __M, char __A) |
| 2670 | 2294 | { |
| 2671 | return (__m128i) __builtin_ia32_pbroadcastb128_gpr_mask (__A, | |
| 2672 | (__v16qi) | |
| 2673 | _mm_setzero_si128 (), | |
| 2674 | __M); | |
| 2295 | return (__m128i) __builtin_ia32_selectb_128(__M, | |
| 2296 | (__v16qi) _mm_set1_epi8(__A), | |
| 2297 | (__v16qi) _mm_setzero_si128()); | |
| 2675 | 2298 | } |
| 2676 | 2299 | |
| 2677 | 2300 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 2678 | 2301 | _mm256_mask_set1_epi8 (__m256i __O, __mmask32 __M, char __A) |
| 2679 | 2302 | { |
| 2680 | return (__m256i) __builtin_ia32_pbroadcastb256_gpr_mask (__A, | |
| 2681 | (__v32qi) __O, | |
| 2682 | __M); | |
| 2303 | return (__m256i) __builtin_ia32_selectb_256(__M, | |
| 2304 | (__v32qi) _mm256_set1_epi8(__A), | |
| 2305 | (__v32qi) __O); | |
| 2683 | 2306 | } |
| 2684 | 2307 | |
| 2685 | 2308 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 2686 | 2309 | _mm256_maskz_set1_epi8 (__mmask32 __M, char __A) |
| 2687 | 2310 | { |
| 2688 | return (__m256i) __builtin_ia32_pbroadcastb256_gpr_mask (__A, | |
| 2689 | (__v32qi) | |
| 2690 | _mm256_setzero_si256 (), | |
| 2691 | __M); | |
| 2311 | return (__m256i) __builtin_ia32_selectb_256(__M, | |
| 2312 | (__v32qi) _mm256_set1_epi8(__A), | |
| 2313 | (__v32qi) _mm256_setzero_si256()); | |
| 2692 | 2314 | } |
| 2693 | 2315 | |
| 2694 | 2316 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| ... | ... | @@ -2793,121 +2415,108 @@ _mm256_mask_storeu_epi8 (void *__P, __mmask32 __U, __m256i __A) |
| 2793 | 2415 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS |
| 2794 | 2416 | _mm_test_epi8_mask (__m128i __A, __m128i __B) |
| 2795 | 2417 | { |
| 2796 | return (__mmask16) __builtin_ia32_ptestmb128 ((__v16qi) __A, | |
| 2797 | (__v16qi) __B, | |
| 2798 | (__mmask16) -1); | |
| 2418 | return _mm_cmpneq_epi8_mask (_mm_and_si128(__A, __B), _mm_setzero_hi()); | |
| 2799 | 2419 | } |
| 2800 | 2420 | |
| 2801 | 2421 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS |
| 2802 | 2422 | _mm_mask_test_epi8_mask (__mmask16 __U, __m128i __A, __m128i __B) |
| 2803 | 2423 | { |
| 2804 | return (__mmask16) __builtin_ia32_ptestmb128 ((__v16qi) __A, | |
| 2805 | (__v16qi) __B, __U); | |
| 2424 | return _mm_mask_cmpneq_epi8_mask (__U, _mm_and_si128 (__A, __B), | |
| 2425 | _mm_setzero_hi()); | |
| 2806 | 2426 | } |
| 2807 | 2427 | |
| 2808 | 2428 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS |
| 2809 | 2429 | _mm256_test_epi8_mask (__m256i __A, __m256i __B) |
| 2810 | 2430 | { |
| 2811 | return (__mmask32) __builtin_ia32_ptestmb256 ((__v32qi) __A, | |
| 2812 | (__v32qi) __B, | |
| 2813 | (__mmask32) -1); | |
| 2431 | return _mm256_cmpneq_epi8_mask (_mm256_and_si256(__A, __B), | |
| 2432 | _mm256_setzero_si256()); | |
| 2814 | 2433 | } |
| 2815 | 2434 | |
| 2816 | 2435 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS |
| 2817 | 2436 | _mm256_mask_test_epi8_mask (__mmask32 __U, __m256i __A, __m256i __B) |
| 2818 | 2437 | { |
| 2819 | return (__mmask32) __builtin_ia32_ptestmb256 ((__v32qi) __A, | |
| 2820 | (__v32qi) __B, __U); | |
| 2438 | return _mm256_mask_cmpneq_epi8_mask (__U, _mm256_and_si256(__A, __B), | |
| 2439 | _mm256_setzero_si256()); | |
| 2821 | 2440 | } |
| 2822 | 2441 | |
| 2823 | 2442 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 2824 | 2443 | _mm_test_epi16_mask (__m128i __A, __m128i __B) |
| 2825 | 2444 | { |
| 2826 | return (__mmask8) __builtin_ia32_ptestmw128 ((__v8hi) __A, | |
| 2827 | (__v8hi) __B, | |
| 2828 | (__mmask8) -1); | |
| 2445 | return _mm_cmpneq_epi16_mask (_mm_and_si128 (__A, __B), _mm_setzero_hi()); | |
| 2829 | 2446 | } |
| 2830 | 2447 | |
| 2831 | 2448 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 2832 | 2449 | _mm_mask_test_epi16_mask (__mmask8 __U, __m128i __A, __m128i __B) |
| 2833 | 2450 | { |
| 2834 | return (__mmask8) __builtin_ia32_ptestmw128 ((__v8hi) __A, | |
| 2835 | (__v8hi) __B, __U); | |
| 2451 | return _mm_mask_cmpneq_epi16_mask (__U, _mm_and_si128 (__A, __B), | |
| 2452 | _mm_setzero_hi()); | |
| 2836 | 2453 | } |
| 2837 | 2454 | |
| 2838 | 2455 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS |
| 2839 | 2456 | _mm256_test_epi16_mask (__m256i __A, __m256i __B) |
| 2840 | 2457 | { |
| 2841 | return (__mmask16) __builtin_ia32_ptestmw256 ((__v16hi) __A, | |
| 2842 | (__v16hi) __B, | |
| 2843 | (__mmask16) -1); | |
| 2458 | return _mm256_cmpneq_epi16_mask (_mm256_and_si256 (__A, __B), | |
| 2459 | _mm256_setzero_si256 ()); | |
| 2844 | 2460 | } |
| 2845 | 2461 | |
| 2846 | 2462 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS |
| 2847 | 2463 | _mm256_mask_test_epi16_mask (__mmask16 __U, __m256i __A, __m256i __B) |
| 2848 | 2464 | { |
| 2849 | return (__mmask16) __builtin_ia32_ptestmw256 ((__v16hi) __A, | |
| 2850 | (__v16hi) __B, __U); | |
| 2465 | return _mm256_mask_cmpneq_epi16_mask (__U, _mm256_and_si256(__A, __B), | |
| 2466 | _mm256_setzero_si256()); | |
| 2851 | 2467 | } |
| 2852 | 2468 | |
| 2853 | 2469 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS |
| 2854 | 2470 | _mm_testn_epi8_mask (__m128i __A, __m128i __B) |
| 2855 | 2471 | { |
| 2856 | return (__mmask16) __builtin_ia32_ptestnmb128 ((__v16qi) __A, | |
| 2857 | (__v16qi) __B, | |
| 2858 | (__mmask16) -1); | |
| 2472 | return _mm_cmpeq_epi8_mask (_mm_and_si128 (__A, __B), _mm_setzero_hi()); | |
| 2859 | 2473 | } |
| 2860 | 2474 | |
| 2861 | 2475 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS |
| 2862 | 2476 | _mm_mask_testn_epi8_mask (__mmask16 __U, __m128i __A, __m128i __B) |
| 2863 | 2477 | { |
| 2864 | return (__mmask16) __builtin_ia32_ptestnmb128 ((__v16qi) __A, | |
| 2865 | (__v16qi) __B, __U); | |
| 2478 | return _mm_mask_cmpeq_epi8_mask (__U, _mm_and_si128 (__A, __B), | |
| 2479 | _mm_setzero_hi()); | |
| 2866 | 2480 | } |
| 2867 | 2481 | |
| 2868 | 2482 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS |
| 2869 | 2483 | _mm256_testn_epi8_mask (__m256i __A, __m256i __B) |
| 2870 | 2484 | { |
| 2871 | return (__mmask32) __builtin_ia32_ptestnmb256 ((__v32qi) __A, | |
| 2872 | (__v32qi) __B, | |
| 2873 | (__mmask32) -1); | |
| 2485 | return _mm256_cmpeq_epi8_mask (_mm256_and_si256 (__A, __B), | |
| 2486 | _mm256_setzero_si256()); | |
| 2874 | 2487 | } |
| 2875 | 2488 | |
| 2876 | 2489 | static __inline__ __mmask32 __DEFAULT_FN_ATTRS |
| 2877 | 2490 | _mm256_mask_testn_epi8_mask (__mmask32 __U, __m256i __A, __m256i __B) |
| 2878 | 2491 | { |
| 2879 | return (__mmask32) __builtin_ia32_ptestnmb256 ((__v32qi) __A, | |
| 2880 | (__v32qi) __B, __U); | |
| 2492 | return _mm256_mask_cmpeq_epi8_mask (__U, _mm256_and_si256 (__A, __B), | |
| 2493 | _mm256_setzero_si256()); | |
| 2881 | 2494 | } |
| 2882 | 2495 | |
| 2883 | 2496 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 2884 | 2497 | _mm_testn_epi16_mask (__m128i __A, __m128i __B) |
| 2885 | 2498 | { |
| 2886 | return (__mmask8) __builtin_ia32_ptestnmw128 ((__v8hi) __A, | |
| 2887 | (__v8hi) __B, | |
| 2888 | (__mmask8) -1); | |
| 2499 | return _mm_cmpeq_epi16_mask (_mm_and_si128 (__A, __B), _mm_setzero_hi()); | |
| 2889 | 2500 | } |
| 2890 | 2501 | |
| 2891 | 2502 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 2892 | 2503 | _mm_mask_testn_epi16_mask (__mmask8 __U, __m128i __A, __m128i __B) |
| 2893 | 2504 | { |
| 2894 | return (__mmask8) __builtin_ia32_ptestnmw128 ((__v8hi) __A, | |
| 2895 | (__v8hi) __B, __U); | |
| 2505 | return _mm_mask_cmpeq_epi16_mask (__U, _mm_and_si128(__A, __B), _mm_setzero_hi()); | |
| 2896 | 2506 | } |
| 2897 | 2507 | |
| 2898 | 2508 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS |
| 2899 | 2509 | _mm256_testn_epi16_mask (__m256i __A, __m256i __B) |
| 2900 | 2510 | { |
| 2901 | return (__mmask16) __builtin_ia32_ptestnmw256 ((__v16hi) __A, | |
| 2902 | (__v16hi) __B, | |
| 2903 | (__mmask16) -1); | |
| 2511 | return _mm256_cmpeq_epi16_mask (_mm256_and_si256(__A, __B), | |
| 2512 | _mm256_setzero_si256()); | |
| 2904 | 2513 | } |
| 2905 | 2514 | |
| 2906 | 2515 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS |
| 2907 | 2516 | _mm256_mask_testn_epi16_mask (__mmask16 __U, __m256i __A, __m256i __B) |
| 2908 | 2517 | { |
| 2909 | return (__mmask16) __builtin_ia32_ptestnmw256 ((__v16hi) __A, | |
| 2910 | (__v16hi) __B, __U); | |
| 2518 | return _mm256_mask_cmpeq_epi16_mask (__U, _mm256_and_si256 (__A, __B), | |
| 2519 | _mm256_setzero_si256()); | |
| 2911 | 2520 | } |
| 2912 | 2521 | |
| 2913 | 2522 | static __inline__ __mmask16 __DEFAULT_FN_ATTRS |
| ... | ... | @@ -3025,33 +2634,33 @@ _mm256_maskz_broadcastw_epi16 (__mmask16 __M, __m128i __A) |
| 3025 | 2634 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 3026 | 2635 | _mm256_mask_set1_epi16 (__m256i __O, __mmask16 __M, short __A) |
| 3027 | 2636 | { |
| 3028 | return (__m256i) __builtin_ia32_pbroadcastw256_gpr_mask (__A, | |
| 3029 | (__v16hi) __O, | |
| 3030 | __M); | |
| 2637 | return (__m256i) __builtin_ia32_selectw_256 (__M, | |
| 2638 | (__v16hi) _mm256_set1_epi16(__A), | |
| 2639 | (__v16hi) __O); | |
| 3031 | 2640 | } |
| 3032 | 2641 | |
| 3033 | 2642 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 3034 | 2643 | _mm256_maskz_set1_epi16 (__mmask16 __M, short __A) |
| 3035 | 2644 | { |
| 3036 | return (__m256i) __builtin_ia32_pbroadcastw256_gpr_mask (__A, | |
| 3037 | (__v16hi) _mm256_setzero_si256 (), | |
| 3038 | __M); | |
| 2645 | return (__m256i) __builtin_ia32_selectw_256(__M, | |
| 2646 | (__v16hi)_mm256_set1_epi16(__A), | |
| 2647 | (__v16hi) _mm256_setzero_si256()); | |
| 3039 | 2648 | } |
| 3040 | 2649 | |
| 3041 | 2650 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| 3042 | 2651 | _mm_mask_set1_epi16 (__m128i __O, __mmask8 __M, short __A) |
| 3043 | 2652 | { |
| 3044 | return (__m128i) __builtin_ia32_pbroadcastw128_gpr_mask (__A, | |
| 3045 | (__v8hi) __O, | |
| 3046 | __M); | |
| 2653 | return (__m128i) __builtin_ia32_selectw_128(__M, | |
| 2654 | (__v8hi) _mm_set1_epi16(__A), | |
| 2655 | (__v8hi) __O); | |
| 3047 | 2656 | } |
| 3048 | 2657 | |
| 3049 | 2658 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| 3050 | 2659 | _mm_maskz_set1_epi16 (__mmask8 __M, short __A) |
| 3051 | 2660 | { |
| 3052 | return (__m128i) __builtin_ia32_pbroadcastw128_gpr_mask (__A, | |
| 3053 | (__v8hi) _mm_setzero_si128 (), | |
| 3054 | __M); | |
| 2661 | return (__m128i) __builtin_ia32_selectw_128(__M, | |
| 2662 | (__v8hi) _mm_set1_epi16(__A), | |
| 2663 | (__v8hi) _mm_setzero_si128()); | |
| 3055 | 2664 | } |
| 3056 | 2665 | |
| 3057 | 2666 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
c_headers/avx512vlcdintrin.h+5-5| ... | ... | @@ -33,26 +33,26 @@ |
| 33 | 33 | |
| 34 | 34 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| 35 | 35 | _mm_broadcastmb_epi64 (__mmask8 __A) |
| 36 | { | |
| 37 | return (__m128i) __builtin_ia32_broadcastmb128 (__A); | |
| 36 | { | |
| 37 | return (__m128i) _mm_set1_epi64x((long long) __A); | |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | 40 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 41 | 41 | _mm256_broadcastmb_epi64 (__mmask8 __A) |
| 42 | 42 | { |
| 43 | return (__m256i) __builtin_ia32_broadcastmb256 (__A); | |
| 43 | return (__m256i) _mm256_set1_epi64x((long long)__A); | |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | 46 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| 47 | 47 | _mm_broadcastmw_epi32 (__mmask16 __A) |
| 48 | 48 | { |
| 49 | return (__m128i) __builtin_ia32_broadcastmw128 (__A); | |
| 49 | return (__m128i) _mm_set1_epi32((int)__A); | |
| 50 | 50 | } |
| 51 | 51 | |
| 52 | 52 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 53 | 53 | _mm256_broadcastmw_epi32 (__mmask16 __A) |
| 54 | 54 | { |
| 55 | return (__m256i) __builtin_ia32_broadcastmw256 (__A); | |
| 55 | return (__m256i) _mm256_set1_epi32((int)__A); | |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 |
c_headers/avx512vldqintrin.h+27-27| ... | ... | @@ -978,25 +978,25 @@ _mm256_movepi64_mask (__m256i __A) |
| 978 | 978 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| 979 | 979 | _mm256_broadcast_f32x2 (__m128 __A) |
| 980 | 980 | { |
| 981 | return (__m256) __builtin_ia32_broadcastf32x2_256_mask ((__v4sf) __A, | |
| 982 | (__v8sf)_mm256_undefined_ps(), | |
| 983 | (__mmask8) -1); | |
| 981 | return (__m256)__builtin_shufflevector((__v4sf)__A, | |
| 982 | (__v4sf)_mm_undefined_ps(), | |
| 983 | 0, 1, 0, 1, 0, 1, 0, 1); | |
| 984 | 984 | } |
| 985 | 985 | |
| 986 | 986 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| 987 | 987 | _mm256_mask_broadcast_f32x2 (__m256 __O, __mmask8 __M, __m128 __A) |
| 988 | 988 | { |
| 989 | return (__m256) __builtin_ia32_broadcastf32x2_256_mask ((__v4sf) __A, | |
| 990 | (__v8sf) __O, | |
| 991 | __M); | |
| 989 | return (__m256)__builtin_ia32_selectps_256((__mmask8)__M, | |
| 990 | (__v8sf)_mm256_broadcast_f32x2(__A), | |
| 991 | (__v8sf)__O); | |
| 992 | 992 | } |
| 993 | 993 | |
| 994 | 994 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| 995 | 995 | _mm256_maskz_broadcast_f32x2 (__mmask8 __M, __m128 __A) |
| 996 | 996 | { |
| 997 | return (__m256) __builtin_ia32_broadcastf32x2_256_mask ((__v4sf) __A, | |
| 998 | (__v8sf) _mm256_setzero_ps (), | |
| 999 | __M); | |
| 997 | return (__m256)__builtin_ia32_selectps_256((__mmask8)__M, | |
| 998 | (__v8sf)_mm256_broadcast_f32x2(__A), | |
| 999 | (__v8sf)_mm256_setzero_ps()); | |
| 1000 | 1000 | } |
| 1001 | 1001 | |
| 1002 | 1002 | static __inline__ __m256d __DEFAULT_FN_ATTRS |
| ... | ... | @@ -1025,49 +1025,49 @@ _mm256_maskz_broadcast_f64x2 (__mmask8 __M, __m128d __A) |
| 1025 | 1025 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| 1026 | 1026 | _mm_broadcast_i32x2 (__m128i __A) |
| 1027 | 1027 | { |
| 1028 | return (__m128i) __builtin_ia32_broadcasti32x2_128_mask ((__v4si) __A, | |
| 1029 | (__v4si)_mm_undefined_si128(), | |
| 1030 | (__mmask8) -1); | |
| 1028 | return (__m128i)__builtin_shufflevector((__v4si)__A, | |
| 1029 | (__v4si)_mm_undefined_si128(), | |
| 1030 | 0, 1, 0, 1); | |
| 1031 | 1031 | } |
| 1032 | 1032 | |
| 1033 | 1033 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| 1034 | 1034 | _mm_mask_broadcast_i32x2 (__m128i __O, __mmask8 __M, __m128i __A) |
| 1035 | 1035 | { |
| 1036 | return (__m128i) __builtin_ia32_broadcasti32x2_128_mask ((__v4si) __A, | |
| 1037 | (__v4si) __O, | |
| 1038 | __M); | |
| 1036 | return (__m128i)__builtin_ia32_selectd_128((__mmask8)__M, | |
| 1037 | (__v4si)_mm_broadcast_i32x2(__A), | |
| 1038 | (__v4si)__O); | |
| 1039 | 1039 | } |
| 1040 | 1040 | |
| 1041 | 1041 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| 1042 | 1042 | _mm_maskz_broadcast_i32x2 (__mmask8 __M, __m128i __A) |
| 1043 | 1043 | { |
| 1044 | return (__m128i) __builtin_ia32_broadcasti32x2_128_mask ((__v4si) __A, | |
| 1045 | (__v4si) _mm_setzero_si128 (), | |
| 1046 | __M); | |
| 1044 | return (__m128i)__builtin_ia32_selectd_128((__mmask8)__M, | |
| 1045 | (__v4si)_mm_broadcast_i32x2(__A), | |
| 1046 | (__v4si)_mm_setzero_si128()); | |
| 1047 | 1047 | } |
| 1048 | 1048 | |
| 1049 | 1049 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 1050 | 1050 | _mm256_broadcast_i32x2 (__m128i __A) |
| 1051 | 1051 | { |
| 1052 | return (__m256i) __builtin_ia32_broadcasti32x2_256_mask ((__v4si) __A, | |
| 1053 | (__v8si)_mm256_undefined_si256(), | |
| 1054 | (__mmask8) -1); | |
| 1052 | return (__m256i)__builtin_shufflevector((__v4si)__A, | |
| 1053 | (__v4si)_mm_undefined_si128(), | |
| 1054 | 0, 1, 0, 1, 0, 1, 0, 1); | |
| 1055 | 1055 | } |
| 1056 | 1056 | |
| 1057 | 1057 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 1058 | 1058 | _mm256_mask_broadcast_i32x2 (__m256i __O, __mmask8 __M, __m128i __A) |
| 1059 | 1059 | { |
| 1060 | return (__m256i) __builtin_ia32_broadcasti32x2_256_mask ((__v4si) __A, | |
| 1061 | (__v8si) __O, | |
| 1062 | __M); | |
| 1060 | return (__m256i)__builtin_ia32_selectd_256((__mmask8)__M, | |
| 1061 | (__v8si)_mm256_broadcast_i32x2(__A), | |
| 1062 | (__v8si)__O); | |
| 1063 | 1063 | } |
| 1064 | 1064 | |
| 1065 | 1065 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 1066 | 1066 | _mm256_maskz_broadcast_i32x2 (__mmask8 __M, __m128i __A) |
| 1067 | 1067 | { |
| 1068 | return (__m256i) __builtin_ia32_broadcasti32x2_256_mask ((__v4si) __A, | |
| 1069 | (__v8si) _mm256_setzero_si256 (), | |
| 1070 | __M); | |
| 1068 | return (__m256i)__builtin_ia32_selectd_256((__mmask8)__M, | |
| 1069 | (__v8si)_mm256_broadcast_i32x2(__A), | |
| 1070 | (__v8si)_mm256_setzero_si256()); | |
| 1071 | 1071 | } |
| 1072 | 1072 | |
| 1073 | 1073 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
c_headers/avx512vlintrin.h+321-703| ... | ... | @@ -38,582 +38,205 @@ _mm_setzero_di(void) { |
| 38 | 38 | |
| 39 | 39 | /* Integer compare */ |
| 40 | 40 | |
| 41 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 42 | _mm_cmpeq_epi32_mask(__m128i __a, __m128i __b) { | |
| 43 | return (__mmask8)__builtin_ia32_pcmpeqd128_mask((__v4si)__a, (__v4si)__b, | |
| 44 | (__mmask8)-1); | |
| 45 | } | |
| 46 | ||
| 47 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 48 | _mm_mask_cmpeq_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 49 | return (__mmask8)__builtin_ia32_pcmpeqd128_mask((__v4si)__a, (__v4si)__b, | |
| 50 | __u); | |
| 51 | } | |
| 52 | ||
| 53 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 54 | _mm_cmpeq_epu32_mask(__m128i __a, __m128i __b) { | |
| 55 | return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 0, | |
| 56 | (__mmask8)-1); | |
| 57 | } | |
| 58 | ||
| 59 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 60 | _mm_mask_cmpeq_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 61 | return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 0, | |
| 62 | __u); | |
| 63 | } | |
| 64 | ||
| 65 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 66 | _mm256_cmpeq_epi32_mask(__m256i __a, __m256i __b) { | |
| 67 | return (__mmask8)__builtin_ia32_pcmpeqd256_mask((__v8si)__a, (__v8si)__b, | |
| 68 | (__mmask8)-1); | |
| 69 | } | |
| 70 | ||
| 71 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 72 | _mm256_mask_cmpeq_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 73 | return (__mmask8)__builtin_ia32_pcmpeqd256_mask((__v8si)__a, (__v8si)__b, | |
| 74 | __u); | |
| 75 | } | |
| 76 | ||
| 77 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 78 | _mm256_cmpeq_epu32_mask(__m256i __a, __m256i __b) { | |
| 79 | return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 0, | |
| 80 | (__mmask8)-1); | |
| 81 | } | |
| 82 | ||
| 83 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 84 | _mm256_mask_cmpeq_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 85 | return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 0, | |
| 86 | __u); | |
| 87 | } | |
| 88 | ||
| 89 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 90 | _mm_cmpeq_epi64_mask(__m128i __a, __m128i __b) { | |
| 91 | return (__mmask8)__builtin_ia32_pcmpeqq128_mask((__v2di)__a, (__v2di)__b, | |
| 92 | (__mmask8)-1); | |
| 93 | } | |
| 94 | ||
| 95 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 96 | _mm_mask_cmpeq_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 97 | return (__mmask8)__builtin_ia32_pcmpeqq128_mask((__v2di)__a, (__v2di)__b, | |
| 98 | __u); | |
| 99 | } | |
| 100 | ||
| 101 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 102 | _mm_cmpeq_epu64_mask(__m128i __a, __m128i __b) { | |
| 103 | return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 0, | |
| 104 | (__mmask8)-1); | |
| 105 | } | |
| 106 | ||
| 107 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 108 | _mm_mask_cmpeq_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 109 | return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 0, | |
| 110 | __u); | |
| 111 | } | |
| 112 | ||
| 113 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 114 | _mm256_cmpeq_epi64_mask(__m256i __a, __m256i __b) { | |
| 115 | return (__mmask8)__builtin_ia32_pcmpeqq256_mask((__v4di)__a, (__v4di)__b, | |
| 116 | (__mmask8)-1); | |
| 117 | } | |
| 118 | ||
| 119 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 120 | _mm256_mask_cmpeq_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 121 | return (__mmask8)__builtin_ia32_pcmpeqq256_mask((__v4di)__a, (__v4di)__b, | |
| 122 | __u); | |
| 123 | } | |
| 124 | ||
| 125 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 126 | _mm256_cmpeq_epu64_mask(__m256i __a, __m256i __b) { | |
| 127 | return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 0, | |
| 128 | (__mmask8)-1); | |
| 129 | } | |
| 130 | ||
| 131 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 132 | _mm256_mask_cmpeq_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 133 | return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 0, | |
| 134 | __u); | |
| 135 | } | |
| 136 | ||
| 137 | ||
| 138 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 139 | _mm_cmpge_epi32_mask(__m128i __a, __m128i __b) { | |
| 140 | return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 5, | |
| 141 | (__mmask8)-1); | |
| 142 | } | |
| 143 | ||
| 144 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 145 | _mm_mask_cmpge_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 146 | return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 5, | |
| 147 | __u); | |
| 148 | } | |
| 149 | ||
| 150 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 151 | _mm_cmpge_epu32_mask(__m128i __a, __m128i __b) { | |
| 152 | return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 5, | |
| 153 | (__mmask8)-1); | |
| 154 | } | |
| 155 | ||
| 156 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 157 | _mm_mask_cmpge_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 158 | return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 5, | |
| 159 | __u); | |
| 160 | } | |
| 161 | ||
| 162 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 163 | _mm256_cmpge_epi32_mask(__m256i __a, __m256i __b) { | |
| 164 | return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 5, | |
| 165 | (__mmask8)-1); | |
| 166 | } | |
| 167 | ||
| 168 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 169 | _mm256_mask_cmpge_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 170 | return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 5, | |
| 171 | __u); | |
| 172 | } | |
| 173 | ||
| 174 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 175 | _mm256_cmpge_epu32_mask(__m256i __a, __m256i __b) { | |
| 176 | return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 5, | |
| 177 | (__mmask8)-1); | |
| 178 | } | |
| 179 | ||
| 180 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 181 | _mm256_mask_cmpge_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 182 | return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 5, | |
| 183 | __u); | |
| 184 | } | |
| 185 | ||
| 186 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 187 | _mm_cmpge_epi64_mask(__m128i __a, __m128i __b) { | |
| 188 | return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 5, | |
| 189 | (__mmask8)-1); | |
| 190 | } | |
| 191 | ||
| 192 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 193 | _mm_mask_cmpge_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 194 | return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 5, | |
| 195 | __u); | |
| 196 | } | |
| 197 | ||
| 198 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 199 | _mm_cmpge_epu64_mask(__m128i __a, __m128i __b) { | |
| 200 | return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 5, | |
| 201 | (__mmask8)-1); | |
| 202 | } | |
| 203 | ||
| 204 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 205 | _mm_mask_cmpge_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 206 | return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 5, | |
| 207 | __u); | |
| 208 | } | |
| 209 | ||
| 210 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 211 | _mm256_cmpge_epi64_mask(__m256i __a, __m256i __b) { | |
| 212 | return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 5, | |
| 213 | (__mmask8)-1); | |
| 214 | } | |
| 215 | ||
| 216 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 217 | _mm256_mask_cmpge_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 218 | return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 5, | |
| 219 | __u); | |
| 220 | } | |
| 221 | ||
| 222 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 223 | _mm256_cmpge_epu64_mask(__m256i __a, __m256i __b) { | |
| 224 | return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 5, | |
| 225 | (__mmask8)-1); | |
| 226 | } | |
| 227 | ||
| 228 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 229 | _mm256_mask_cmpge_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 230 | return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 5, | |
| 231 | __u); | |
| 232 | } | |
| 233 | ||
| 234 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 235 | _mm_cmpgt_epi32_mask(__m128i __a, __m128i __b) { | |
| 236 | return (__mmask8)__builtin_ia32_pcmpgtd128_mask((__v4si)__a, (__v4si)__b, | |
| 237 | (__mmask8)-1); | |
| 238 | } | |
| 239 | ||
| 240 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 241 | _mm_mask_cmpgt_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 242 | return (__mmask8)__builtin_ia32_pcmpgtd128_mask((__v4si)__a, (__v4si)__b, | |
| 243 | __u); | |
| 244 | } | |
| 245 | ||
| 246 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 247 | _mm_cmpgt_epu32_mask(__m128i __a, __m128i __b) { | |
| 248 | return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 6, | |
| 249 | (__mmask8)-1); | |
| 250 | } | |
| 251 | ||
| 252 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 253 | _mm_mask_cmpgt_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 254 | return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 6, | |
| 255 | __u); | |
| 256 | } | |
| 257 | ||
| 258 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 259 | _mm256_cmpgt_epi32_mask(__m256i __a, __m256i __b) { | |
| 260 | return (__mmask8)__builtin_ia32_pcmpgtd256_mask((__v8si)__a, (__v8si)__b, | |
| 261 | (__mmask8)-1); | |
| 262 | } | |
| 263 | ||
| 264 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 265 | _mm256_mask_cmpgt_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 266 | return (__mmask8)__builtin_ia32_pcmpgtd256_mask((__v8si)__a, (__v8si)__b, | |
| 267 | __u); | |
| 268 | } | |
| 269 | ||
| 270 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 271 | _mm256_cmpgt_epu32_mask(__m256i __a, __m256i __b) { | |
| 272 | return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 6, | |
| 273 | (__mmask8)-1); | |
| 274 | } | |
| 275 | ||
| 276 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 277 | _mm256_mask_cmpgt_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 278 | return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 6, | |
| 279 | __u); | |
| 280 | } | |
| 281 | ||
| 282 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 283 | _mm_cmpgt_epi64_mask(__m128i __a, __m128i __b) { | |
| 284 | return (__mmask8)__builtin_ia32_pcmpgtq128_mask((__v2di)__a, (__v2di)__b, | |
| 285 | (__mmask8)-1); | |
| 286 | } | |
| 287 | ||
| 288 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 289 | _mm_mask_cmpgt_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 290 | return (__mmask8)__builtin_ia32_pcmpgtq128_mask((__v2di)__a, (__v2di)__b, | |
| 291 | __u); | |
| 292 | } | |
| 293 | ||
| 294 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 295 | _mm_cmpgt_epu64_mask(__m128i __a, __m128i __b) { | |
| 296 | return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 6, | |
| 297 | (__mmask8)-1); | |
| 298 | } | |
| 299 | ||
| 300 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 301 | _mm_mask_cmpgt_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 302 | return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 6, | |
| 303 | __u); | |
| 304 | } | |
| 305 | ||
| 306 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 307 | _mm256_cmpgt_epi64_mask(__m256i __a, __m256i __b) { | |
| 308 | return (__mmask8)__builtin_ia32_pcmpgtq256_mask((__v4di)__a, (__v4di)__b, | |
| 309 | (__mmask8)-1); | |
| 310 | } | |
| 311 | ||
| 312 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 313 | _mm256_mask_cmpgt_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 314 | return (__mmask8)__builtin_ia32_pcmpgtq256_mask((__v4di)__a, (__v4di)__b, | |
| 315 | __u); | |
| 316 | } | |
| 317 | ||
| 318 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 319 | _mm256_cmpgt_epu64_mask(__m256i __a, __m256i __b) { | |
| 320 | return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 6, | |
| 321 | (__mmask8)-1); | |
| 322 | } | |
| 323 | ||
| 324 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 325 | _mm256_mask_cmpgt_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 326 | return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 6, | |
| 327 | __u); | |
| 328 | } | |
| 329 | ||
| 330 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 331 | _mm_cmple_epi32_mask(__m128i __a, __m128i __b) { | |
| 332 | return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 2, | |
| 333 | (__mmask8)-1); | |
| 334 | } | |
| 335 | ||
| 336 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 337 | _mm_mask_cmple_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 338 | return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 2, | |
| 339 | __u); | |
| 340 | } | |
| 341 | ||
| 342 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 343 | _mm_cmple_epu32_mask(__m128i __a, __m128i __b) { | |
| 344 | return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 2, | |
| 345 | (__mmask8)-1); | |
| 346 | } | |
| 347 | ||
| 348 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 349 | _mm_mask_cmple_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 350 | return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 2, | |
| 351 | __u); | |
| 352 | } | |
| 353 | ||
| 354 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 355 | _mm256_cmple_epi32_mask(__m256i __a, __m256i __b) { | |
| 356 | return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 2, | |
| 357 | (__mmask8)-1); | |
| 358 | } | |
| 359 | ||
| 360 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 361 | _mm256_mask_cmple_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 362 | return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 2, | |
| 363 | __u); | |
| 364 | } | |
| 365 | ||
| 366 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 367 | _mm256_cmple_epu32_mask(__m256i __a, __m256i __b) { | |
| 368 | return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 2, | |
| 369 | (__mmask8)-1); | |
| 370 | } | |
| 371 | ||
| 372 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 373 | _mm256_mask_cmple_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 374 | return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 2, | |
| 375 | __u); | |
| 376 | } | |
| 377 | ||
| 378 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 379 | _mm_cmple_epi64_mask(__m128i __a, __m128i __b) { | |
| 380 | return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 2, | |
| 381 | (__mmask8)-1); | |
| 382 | } | |
| 383 | ||
| 384 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 385 | _mm_mask_cmple_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 386 | return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 2, | |
| 387 | __u); | |
| 388 | } | |
| 389 | ||
| 390 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 391 | _mm_cmple_epu64_mask(__m128i __a, __m128i __b) { | |
| 392 | return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 2, | |
| 393 | (__mmask8)-1); | |
| 394 | } | |
| 395 | ||
| 396 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 397 | _mm_mask_cmple_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 398 | return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 2, | |
| 399 | __u); | |
| 400 | } | |
| 401 | ||
| 402 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 403 | _mm256_cmple_epi64_mask(__m256i __a, __m256i __b) { | |
| 404 | return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 2, | |
| 405 | (__mmask8)-1); | |
| 406 | } | |
| 407 | ||
| 408 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 409 | _mm256_mask_cmple_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 410 | return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 2, | |
| 411 | __u); | |
| 412 | } | |
| 413 | ||
| 414 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 415 | _mm256_cmple_epu64_mask(__m256i __a, __m256i __b) { | |
| 416 | return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 2, | |
| 417 | (__mmask8)-1); | |
| 418 | } | |
| 419 | ||
| 420 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 421 | _mm256_mask_cmple_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 422 | return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 2, | |
| 423 | __u); | |
| 424 | } | |
| 425 | ||
| 426 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 427 | _mm_cmplt_epi32_mask(__m128i __a, __m128i __b) { | |
| 428 | return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 1, | |
| 429 | (__mmask8)-1); | |
| 430 | } | |
| 431 | ||
| 432 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 433 | _mm_mask_cmplt_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 434 | return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 1, | |
| 435 | __u); | |
| 436 | } | |
| 437 | ||
| 438 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 439 | _mm_cmplt_epu32_mask(__m128i __a, __m128i __b) { | |
| 440 | return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 1, | |
| 441 | (__mmask8)-1); | |
| 442 | } | |
| 443 | ||
| 444 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 445 | _mm_mask_cmplt_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 446 | return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 1, | |
| 447 | __u); | |
| 448 | } | |
| 449 | ||
| 450 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 451 | _mm256_cmplt_epi32_mask(__m256i __a, __m256i __b) { | |
| 452 | return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 1, | |
| 453 | (__mmask8)-1); | |
| 454 | } | |
| 455 | ||
| 456 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 457 | _mm256_mask_cmplt_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 458 | return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 1, | |
| 459 | __u); | |
| 460 | } | |
| 461 | ||
| 462 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 463 | _mm256_cmplt_epu32_mask(__m256i __a, __m256i __b) { | |
| 464 | return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 1, | |
| 465 | (__mmask8)-1); | |
| 466 | } | |
| 467 | ||
| 468 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 469 | _mm256_mask_cmplt_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 470 | return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 1, | |
| 471 | __u); | |
| 472 | } | |
| 473 | ||
| 474 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 475 | _mm_cmplt_epi64_mask(__m128i __a, __m128i __b) { | |
| 476 | return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 1, | |
| 477 | (__mmask8)-1); | |
| 478 | } | |
| 479 | ||
| 480 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 481 | _mm_mask_cmplt_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 482 | return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 1, | |
| 483 | __u); | |
| 484 | } | |
| 485 | ||
| 486 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 487 | _mm_cmplt_epu64_mask(__m128i __a, __m128i __b) { | |
| 488 | return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 1, | |
| 489 | (__mmask8)-1); | |
| 490 | } | |
| 491 | ||
| 492 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 493 | _mm_mask_cmplt_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 494 | return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 1, | |
| 495 | __u); | |
| 496 | } | |
| 497 | ||
| 498 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 499 | _mm256_cmplt_epi64_mask(__m256i __a, __m256i __b) { | |
| 500 | return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 1, | |
| 501 | (__mmask8)-1); | |
| 502 | } | |
| 503 | ||
| 504 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 505 | _mm256_mask_cmplt_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 506 | return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 1, | |
| 507 | __u); | |
| 508 | } | |
| 509 | ||
| 510 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 511 | _mm256_cmplt_epu64_mask(__m256i __a, __m256i __b) { | |
| 512 | return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 1, | |
| 513 | (__mmask8)-1); | |
| 514 | } | |
| 515 | ||
| 516 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 517 | _mm256_mask_cmplt_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 518 | return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 1, | |
| 519 | __u); | |
| 520 | } | |
| 521 | ||
| 522 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 523 | _mm_cmpneq_epi32_mask(__m128i __a, __m128i __b) { | |
| 524 | return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 4, | |
| 525 | (__mmask8)-1); | |
| 526 | } | |
| 527 | ||
| 528 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 529 | _mm_mask_cmpneq_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 530 | return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 4, | |
| 531 | __u); | |
| 532 | } | |
| 533 | ||
| 534 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 535 | _mm_cmpneq_epu32_mask(__m128i __a, __m128i __b) { | |
| 536 | return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 4, | |
| 537 | (__mmask8)-1); | |
| 538 | } | |
| 539 | ||
| 540 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 541 | _mm_mask_cmpneq_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 542 | return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 4, | |
| 543 | __u); | |
| 544 | } | |
| 545 | ||
| 546 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 547 | _mm256_cmpneq_epi32_mask(__m256i __a, __m256i __b) { | |
| 548 | return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 4, | |
| 549 | (__mmask8)-1); | |
| 550 | } | |
| 551 | ||
| 552 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 553 | _mm256_mask_cmpneq_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 554 | return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 4, | |
| 555 | __u); | |
| 556 | } | |
| 557 | ||
| 558 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 559 | _mm256_cmpneq_epu32_mask(__m256i __a, __m256i __b) { | |
| 560 | return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 4, | |
| 561 | (__mmask8)-1); | |
| 562 | } | |
| 563 | ||
| 564 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 565 | _mm256_mask_cmpneq_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 566 | return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 4, | |
| 567 | __u); | |
| 568 | } | |
| 569 | ||
| 570 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 571 | _mm_cmpneq_epi64_mask(__m128i __a, __m128i __b) { | |
| 572 | return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 4, | |
| 573 | (__mmask8)-1); | |
| 574 | } | |
| 575 | ||
| 576 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 577 | _mm_mask_cmpneq_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 578 | return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 4, | |
| 579 | __u); | |
| 580 | } | |
| 581 | ||
| 582 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 583 | _mm_cmpneq_epu64_mask(__m128i __a, __m128i __b) { | |
| 584 | return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 4, | |
| 585 | (__mmask8)-1); | |
| 586 | } | |
| 587 | ||
| 588 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 589 | _mm_mask_cmpneq_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { | |
| 590 | return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 4, | |
| 591 | __u); | |
| 592 | } | |
| 593 | ||
| 594 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 595 | _mm256_cmpneq_epi64_mask(__m256i __a, __m256i __b) { | |
| 596 | return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 4, | |
| 597 | (__mmask8)-1); | |
| 598 | } | |
| 599 | ||
| 600 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 601 | _mm256_mask_cmpneq_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 602 | return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 4, | |
| 603 | __u); | |
| 604 | } | |
| 605 | ||
| 606 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 607 | _mm256_cmpneq_epu64_mask(__m256i __a, __m256i __b) { | |
| 608 | return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 4, | |
| 609 | (__mmask8)-1); | |
| 610 | } | |
| 611 | ||
| 612 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS | |
| 613 | _mm256_mask_cmpneq_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { | |
| 614 | return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 4, | |
| 615 | __u); | |
| 616 | } | |
| 41 | #define _mm_cmpeq_epi32_mask(A, B) \ | |
| 42 | _mm_cmp_epi32_mask((A), (B), _MM_CMPINT_EQ) | |
| 43 | #define _mm_mask_cmpeq_epi32_mask(k, A, B) \ | |
| 44 | _mm_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 45 | #define _mm_cmpge_epi32_mask(A, B) \ | |
| 46 | _mm_cmp_epi32_mask((A), (B), _MM_CMPINT_GE) | |
| 47 | #define _mm_mask_cmpge_epi32_mask(k, A, B) \ | |
| 48 | _mm_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 49 | #define _mm_cmpgt_epi32_mask(A, B) \ | |
| 50 | _mm_cmp_epi32_mask((A), (B), _MM_CMPINT_GT) | |
| 51 | #define _mm_mask_cmpgt_epi32_mask(k, A, B) \ | |
| 52 | _mm_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 53 | #define _mm_cmple_epi32_mask(A, B) \ | |
| 54 | _mm_cmp_epi32_mask((A), (B), _MM_CMPINT_LE) | |
| 55 | #define _mm_mask_cmple_epi32_mask(k, A, B) \ | |
| 56 | _mm_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 57 | #define _mm_cmplt_epi32_mask(A, B) \ | |
| 58 | _mm_cmp_epi32_mask((A), (B), _MM_CMPINT_LT) | |
| 59 | #define _mm_mask_cmplt_epi32_mask(k, A, B) \ | |
| 60 | _mm_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 61 | #define _mm_cmpneq_epi32_mask(A, B) \ | |
| 62 | _mm_cmp_epi32_mask((A), (B), _MM_CMPINT_NE) | |
| 63 | #define _mm_mask_cmpneq_epi32_mask(k, A, B) \ | |
| 64 | _mm_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 65 | ||
| 66 | #define _mm256_cmpeq_epi32_mask(A, B) \ | |
| 67 | _mm256_cmp_epi32_mask((A), (B), _MM_CMPINT_EQ) | |
| 68 | #define _mm256_mask_cmpeq_epi32_mask(k, A, B) \ | |
| 69 | _mm256_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 70 | #define _mm256_cmpge_epi32_mask(A, B) \ | |
| 71 | _mm256_cmp_epi32_mask((A), (B), _MM_CMPINT_GE) | |
| 72 | #define _mm256_mask_cmpge_epi32_mask(k, A, B) \ | |
| 73 | _mm256_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 74 | #define _mm256_cmpgt_epi32_mask(A, B) \ | |
| 75 | _mm256_cmp_epi32_mask((A), (B), _MM_CMPINT_GT) | |
| 76 | #define _mm256_mask_cmpgt_epi32_mask(k, A, B) \ | |
| 77 | _mm256_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 78 | #define _mm256_cmple_epi32_mask(A, B) \ | |
| 79 | _mm256_cmp_epi32_mask((A), (B), _MM_CMPINT_LE) | |
| 80 | #define _mm256_mask_cmple_epi32_mask(k, A, B) \ | |
| 81 | _mm256_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 82 | #define _mm256_cmplt_epi32_mask(A, B) \ | |
| 83 | _mm256_cmp_epi32_mask((A), (B), _MM_CMPINT_LT) | |
| 84 | #define _mm256_mask_cmplt_epi32_mask(k, A, B) \ | |
| 85 | _mm256_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 86 | #define _mm256_cmpneq_epi32_mask(A, B) \ | |
| 87 | _mm256_cmp_epi32_mask((A), (B), _MM_CMPINT_NE) | |
| 88 | #define _mm256_mask_cmpneq_epi32_mask(k, A, B) \ | |
| 89 | _mm256_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 90 | ||
| 91 | #define _mm_cmpeq_epu32_mask(A, B) \ | |
| 92 | _mm_cmp_epu32_mask((A), (B), _MM_CMPINT_EQ) | |
| 93 | #define _mm_mask_cmpeq_epu32_mask(k, A, B) \ | |
| 94 | _mm_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 95 | #define _mm_cmpge_epu32_mask(A, B) \ | |
| 96 | _mm_cmp_epu32_mask((A), (B), _MM_CMPINT_GE) | |
| 97 | #define _mm_mask_cmpge_epu32_mask(k, A, B) \ | |
| 98 | _mm_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 99 | #define _mm_cmpgt_epu32_mask(A, B) \ | |
| 100 | _mm_cmp_epu32_mask((A), (B), _MM_CMPINT_GT) | |
| 101 | #define _mm_mask_cmpgt_epu32_mask(k, A, B) \ | |
| 102 | _mm_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 103 | #define _mm_cmple_epu32_mask(A, B) \ | |
| 104 | _mm_cmp_epu32_mask((A), (B), _MM_CMPINT_LE) | |
| 105 | #define _mm_mask_cmple_epu32_mask(k, A, B) \ | |
| 106 | _mm_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 107 | #define _mm_cmplt_epu32_mask(A, B) \ | |
| 108 | _mm_cmp_epu32_mask((A), (B), _MM_CMPINT_LT) | |
| 109 | #define _mm_mask_cmplt_epu32_mask(k, A, B) \ | |
| 110 | _mm_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 111 | #define _mm_cmpneq_epu32_mask(A, B) \ | |
| 112 | _mm_cmp_epu32_mask((A), (B), _MM_CMPINT_NE) | |
| 113 | #define _mm_mask_cmpneq_epu32_mask(k, A, B) \ | |
| 114 | _mm_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 115 | ||
| 116 | #define _mm256_cmpeq_epu32_mask(A, B) \ | |
| 117 | _mm256_cmp_epu32_mask((A), (B), _MM_CMPINT_EQ) | |
| 118 | #define _mm256_mask_cmpeq_epu32_mask(k, A, B) \ | |
| 119 | _mm256_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 120 | #define _mm256_cmpge_epu32_mask(A, B) \ | |
| 121 | _mm256_cmp_epu32_mask((A), (B), _MM_CMPINT_GE) | |
| 122 | #define _mm256_mask_cmpge_epu32_mask(k, A, B) \ | |
| 123 | _mm256_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 124 | #define _mm256_cmpgt_epu32_mask(A, B) \ | |
| 125 | _mm256_cmp_epu32_mask((A), (B), _MM_CMPINT_GT) | |
| 126 | #define _mm256_mask_cmpgt_epu32_mask(k, A, B) \ | |
| 127 | _mm256_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 128 | #define _mm256_cmple_epu32_mask(A, B) \ | |
| 129 | _mm256_cmp_epu32_mask((A), (B), _MM_CMPINT_LE) | |
| 130 | #define _mm256_mask_cmple_epu32_mask(k, A, B) \ | |
| 131 | _mm256_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 132 | #define _mm256_cmplt_epu32_mask(A, B) \ | |
| 133 | _mm256_cmp_epu32_mask((A), (B), _MM_CMPINT_LT) | |
| 134 | #define _mm256_mask_cmplt_epu32_mask(k, A, B) \ | |
| 135 | _mm256_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 136 | #define _mm256_cmpneq_epu32_mask(A, B) \ | |
| 137 | _mm256_cmp_epu32_mask((A), (B), _MM_CMPINT_NE) | |
| 138 | #define _mm256_mask_cmpneq_epu32_mask(k, A, B) \ | |
| 139 | _mm256_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 140 | ||
| 141 | #define _mm_cmpeq_epi64_mask(A, B) \ | |
| 142 | _mm_cmp_epi64_mask((A), (B), _MM_CMPINT_EQ) | |
| 143 | #define _mm_mask_cmpeq_epi64_mask(k, A, B) \ | |
| 144 | _mm_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 145 | #define _mm_cmpge_epi64_mask(A, B) \ | |
| 146 | _mm_cmp_epi64_mask((A), (B), _MM_CMPINT_GE) | |
| 147 | #define _mm_mask_cmpge_epi64_mask(k, A, B) \ | |
| 148 | _mm_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 149 | #define _mm_cmpgt_epi64_mask(A, B) \ | |
| 150 | _mm_cmp_epi64_mask((A), (B), _MM_CMPINT_GT) | |
| 151 | #define _mm_mask_cmpgt_epi64_mask(k, A, B) \ | |
| 152 | _mm_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 153 | #define _mm_cmple_epi64_mask(A, B) \ | |
| 154 | _mm_cmp_epi64_mask((A), (B), _MM_CMPINT_LE) | |
| 155 | #define _mm_mask_cmple_epi64_mask(k, A, B) \ | |
| 156 | _mm_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 157 | #define _mm_cmplt_epi64_mask(A, B) \ | |
| 158 | _mm_cmp_epi64_mask((A), (B), _MM_CMPINT_LT) | |
| 159 | #define _mm_mask_cmplt_epi64_mask(k, A, B) \ | |
| 160 | _mm_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 161 | #define _mm_cmpneq_epi64_mask(A, B) \ | |
| 162 | _mm_cmp_epi64_mask((A), (B), _MM_CMPINT_NE) | |
| 163 | #define _mm_mask_cmpneq_epi64_mask(k, A, B) \ | |
| 164 | _mm_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 165 | ||
| 166 | #define _mm256_cmpeq_epi64_mask(A, B) \ | |
| 167 | _mm256_cmp_epi64_mask((A), (B), _MM_CMPINT_EQ) | |
| 168 | #define _mm256_mask_cmpeq_epi64_mask(k, A, B) \ | |
| 169 | _mm256_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 170 | #define _mm256_cmpge_epi64_mask(A, B) \ | |
| 171 | _mm256_cmp_epi64_mask((A), (B), _MM_CMPINT_GE) | |
| 172 | #define _mm256_mask_cmpge_epi64_mask(k, A, B) \ | |
| 173 | _mm256_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 174 | #define _mm256_cmpgt_epi64_mask(A, B) \ | |
| 175 | _mm256_cmp_epi64_mask((A), (B), _MM_CMPINT_GT) | |
| 176 | #define _mm256_mask_cmpgt_epi64_mask(k, A, B) \ | |
| 177 | _mm256_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 178 | #define _mm256_cmple_epi64_mask(A, B) \ | |
| 179 | _mm256_cmp_epi64_mask((A), (B), _MM_CMPINT_LE) | |
| 180 | #define _mm256_mask_cmple_epi64_mask(k, A, B) \ | |
| 181 | _mm256_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 182 | #define _mm256_cmplt_epi64_mask(A, B) \ | |
| 183 | _mm256_cmp_epi64_mask((A), (B), _MM_CMPINT_LT) | |
| 184 | #define _mm256_mask_cmplt_epi64_mask(k, A, B) \ | |
| 185 | _mm256_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 186 | #define _mm256_cmpneq_epi64_mask(A, B) \ | |
| 187 | _mm256_cmp_epi64_mask((A), (B), _MM_CMPINT_NE) | |
| 188 | #define _mm256_mask_cmpneq_epi64_mask(k, A, B) \ | |
| 189 | _mm256_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 190 | ||
| 191 | #define _mm_cmpeq_epu64_mask(A, B) \ | |
| 192 | _mm_cmp_epu64_mask((A), (B), _MM_CMPINT_EQ) | |
| 193 | #define _mm_mask_cmpeq_epu64_mask(k, A, B) \ | |
| 194 | _mm_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 195 | #define _mm_cmpge_epu64_mask(A, B) \ | |
| 196 | _mm_cmp_epu64_mask((A), (B), _MM_CMPINT_GE) | |
| 197 | #define _mm_mask_cmpge_epu64_mask(k, A, B) \ | |
| 198 | _mm_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 199 | #define _mm_cmpgt_epu64_mask(A, B) \ | |
| 200 | _mm_cmp_epu64_mask((A), (B), _MM_CMPINT_GT) | |
| 201 | #define _mm_mask_cmpgt_epu64_mask(k, A, B) \ | |
| 202 | _mm_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 203 | #define _mm_cmple_epu64_mask(A, B) \ | |
| 204 | _mm_cmp_epu64_mask((A), (B), _MM_CMPINT_LE) | |
| 205 | #define _mm_mask_cmple_epu64_mask(k, A, B) \ | |
| 206 | _mm_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 207 | #define _mm_cmplt_epu64_mask(A, B) \ | |
| 208 | _mm_cmp_epu64_mask((A), (B), _MM_CMPINT_LT) | |
| 209 | #define _mm_mask_cmplt_epu64_mask(k, A, B) \ | |
| 210 | _mm_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 211 | #define _mm_cmpneq_epu64_mask(A, B) \ | |
| 212 | _mm_cmp_epu64_mask((A), (B), _MM_CMPINT_NE) | |
| 213 | #define _mm_mask_cmpneq_epu64_mask(k, A, B) \ | |
| 214 | _mm_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 215 | ||
| 216 | #define _mm256_cmpeq_epu64_mask(A, B) \ | |
| 217 | _mm256_cmp_epu64_mask((A), (B), _MM_CMPINT_EQ) | |
| 218 | #define _mm256_mask_cmpeq_epu64_mask(k, A, B) \ | |
| 219 | _mm256_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_EQ) | |
| 220 | #define _mm256_cmpge_epu64_mask(A, B) \ | |
| 221 | _mm256_cmp_epu64_mask((A), (B), _MM_CMPINT_GE) | |
| 222 | #define _mm256_mask_cmpge_epu64_mask(k, A, B) \ | |
| 223 | _mm256_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_GE) | |
| 224 | #define _mm256_cmpgt_epu64_mask(A, B) \ | |
| 225 | _mm256_cmp_epu64_mask((A), (B), _MM_CMPINT_GT) | |
| 226 | #define _mm256_mask_cmpgt_epu64_mask(k, A, B) \ | |
| 227 | _mm256_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_GT) | |
| 228 | #define _mm256_cmple_epu64_mask(A, B) \ | |
| 229 | _mm256_cmp_epu64_mask((A), (B), _MM_CMPINT_LE) | |
| 230 | #define _mm256_mask_cmple_epu64_mask(k, A, B) \ | |
| 231 | _mm256_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_LE) | |
| 232 | #define _mm256_cmplt_epu64_mask(A, B) \ | |
| 233 | _mm256_cmp_epu64_mask((A), (B), _MM_CMPINT_LT) | |
| 234 | #define _mm256_mask_cmplt_epu64_mask(k, A, B) \ | |
| 235 | _mm256_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_LT) | |
| 236 | #define _mm256_cmpneq_epu64_mask(A, B) \ | |
| 237 | _mm256_cmp_epu64_mask((A), (B), _MM_CMPINT_NE) | |
| 238 | #define _mm256_mask_cmpneq_epu64_mask(k, A, B) \ | |
| 239 | _mm256_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_NE) | |
| 617 | 240 | |
| 618 | 241 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 619 | 242 | _mm256_mask_add_epi32(__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) |
| ... | ... | @@ -5723,59 +5346,72 @@ _mm256_maskz_movedup_pd (__mmask8 __U, __m256d __A) |
| 5723 | 5346 | (__v4df)_mm256_setzero_pd()); |
| 5724 | 5347 | } |
| 5725 | 5348 | |
| 5349 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 5350 | _mm_mask_set1_epi32(__m128i __O, __mmask8 __M, int __A) | |
| 5351 | { | |
| 5352 | return (__m128i)__builtin_ia32_selectd_128(__M, | |
| 5353 | (__v4si) _mm_set1_epi32(__A), | |
| 5354 | (__v4si)__O); | |
| 5355 | } | |
| 5726 | 5356 | |
| 5727 | #define _mm_mask_set1_epi32(O, M, A) __extension__ ({ \ | |
| 5728 | (__m128i)__builtin_ia32_pbroadcastd128_gpr_mask((int)(A), \ | |
| 5729 | (__v4si)(__m128i)(O), \ | |
| 5730 | (__mmask8)(M)); }) | |
| 5357 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 5358 | _mm_maskz_set1_epi32( __mmask8 __M, int __A) | |
| 5359 | { | |
| 5360 | return (__m128i)__builtin_ia32_selectd_128(__M, | |
| 5361 | (__v4si) _mm_set1_epi32(__A), | |
| 5362 | (__v4si)_mm_setzero_si128()); | |
| 5363 | } | |
| 5731 | 5364 | |
| 5732 | #define _mm_maskz_set1_epi32(M, A) __extension__ ({ \ | |
| 5733 | (__m128i)__builtin_ia32_pbroadcastd128_gpr_mask((int)(A), \ | |
| 5734 | (__v4si)_mm_setzero_si128(), \ | |
| 5735 | (__mmask8)(M)); }) | |
| 5365 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 5366 | _mm256_mask_set1_epi32(__m256i __O, __mmask8 __M, int __A) | |
| 5367 | { | |
| 5368 | return (__m256i)__builtin_ia32_selectd_256(__M, | |
| 5369 | (__v8si) _mm256_set1_epi32(__A), | |
| 5370 | (__v8si)__O); | |
| 5371 | } | |
| 5736 | 5372 | |
| 5737 | #define _mm256_mask_set1_epi32(O, M, A) __extension__ ({ \ | |
| 5738 | (__m256i)__builtin_ia32_pbroadcastd256_gpr_mask((int)(A), \ | |
| 5739 | (__v8si)(__m256i)(O), \ | |
| 5740 | (__mmask8)(M)); }) | |
| 5373 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 5374 | _mm256_maskz_set1_epi32( __mmask8 __M, int __A) | |
| 5375 | { | |
| 5376 | return (__m256i)__builtin_ia32_selectd_256(__M, | |
| 5377 | (__v8si) _mm256_set1_epi32(__A), | |
| 5378 | (__v8si)_mm256_setzero_si256()); | |
| 5379 | } | |
| 5741 | 5380 | |
| 5742 | #define _mm256_maskz_set1_epi32(M, A) __extension__ ({ \ | |
| 5743 | (__m256i)__builtin_ia32_pbroadcastd256_gpr_mask((int)(A), \ | |
| 5744 | (__v8si)_mm256_setzero_si256(), \ | |
| 5745 | (__mmask8)(M)); }) | |
| 5746 | 5381 | |
| 5747 | 5382 | #ifdef __x86_64__ |
| 5748 | 5383 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| 5749 | 5384 | _mm_mask_set1_epi64 (__m128i __O, __mmask8 __M, long long __A) |
| 5750 | 5385 | { |
| 5751 | return (__m128i) __builtin_ia32_pbroadcastq128_gpr_mask (__A, (__v2di) __O, | |
| 5752 | __M); | |
| 5386 | return (__m128i) __builtin_ia32_selectq_128(__M, | |
| 5387 | (__v2di) _mm_set1_epi64x(__A), | |
| 5388 | (__v2di) __O); | |
| 5753 | 5389 | } |
| 5754 | 5390 | |
| 5755 | 5391 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| 5756 | 5392 | _mm_maskz_set1_epi64 (__mmask8 __M, long long __A) |
| 5757 | 5393 | { |
| 5758 | return (__m128i) __builtin_ia32_pbroadcastq128_gpr_mask (__A, | |
| 5759 | (__v2di) | |
| 5760 | _mm_setzero_si128 (), | |
| 5761 | __M); | |
| 5394 | return (__m128i) __builtin_ia32_selectq_128(__M, | |
| 5395 | (__v2di) _mm_set1_epi64x(__A), | |
| 5396 | (__v2di) _mm_setzero_si128()); | |
| 5762 | 5397 | } |
| 5763 | 5398 | |
| 5764 | 5399 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 5765 | 5400 | _mm256_mask_set1_epi64 (__m256i __O, __mmask8 __M, long long __A) |
| 5766 | 5401 | { |
| 5767 | return (__m256i) __builtin_ia32_pbroadcastq256_gpr_mask (__A, (__v4di) __O, | |
| 5768 | __M); | |
| 5402 | return (__m256i) __builtin_ia32_selectq_256(__M, | |
| 5403 | (__v4di) _mm256_set1_epi64x(__A), | |
| 5404 | (__v4di) __O) ; | |
| 5769 | 5405 | } |
| 5770 | 5406 | |
| 5771 | 5407 | static __inline__ __m256i __DEFAULT_FN_ATTRS |
| 5772 | 5408 | _mm256_maskz_set1_epi64 (__mmask8 __M, long long __A) |
| 5773 | 5409 | { |
| 5774 | return (__m256i) __builtin_ia32_pbroadcastq256_gpr_mask (__A, | |
| 5775 | (__v4di) | |
| 5776 | _mm256_setzero_si256 (), | |
| 5777 | __M); | |
| 5410 | return (__m256i) __builtin_ia32_selectq_256(__M, | |
| 5411 | (__v4di) _mm256_set1_epi64x(__A), | |
| 5412 | (__v4di) _mm256_setzero_si256()); | |
| 5778 | 5413 | } |
| 5414 | ||
| 5779 | 5415 | #endif |
| 5780 | 5416 | |
| 5781 | 5417 | #define _mm_fixupimm_pd(A, B, C, imm) __extension__ ({ \ |
| ... | ... | @@ -6490,125 +6126,111 @@ _mm256_maskz_permutevar_ps(__mmask8 __U, __m256 __A, __m256i __C) |
| 6490 | 6126 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6491 | 6127 | _mm_test_epi32_mask (__m128i __A, __m128i __B) |
| 6492 | 6128 | { |
| 6493 | return (__mmask8) __builtin_ia32_ptestmd128 ((__v4si) __A, | |
| 6494 | (__v4si) __B, | |
| 6495 | (__mmask8) -1); | |
| 6129 | return _mm_cmpneq_epi32_mask (_mm_and_si128 (__A, __B), _mm_setzero_di()); | |
| 6496 | 6130 | } |
| 6497 | 6131 | |
| 6498 | 6132 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6499 | 6133 | _mm_mask_test_epi32_mask (__mmask8 __U, __m128i __A, __m128i __B) |
| 6500 | 6134 | { |
| 6501 | return (__mmask8) __builtin_ia32_ptestmd128 ((__v4si) __A, | |
| 6502 | (__v4si) __B, __U); | |
| 6135 | return _mm_mask_cmpneq_epi32_mask (__U, _mm_and_si128 (__A, __B), | |
| 6136 | _mm_setzero_di()); | |
| 6503 | 6137 | } |
| 6504 | 6138 | |
| 6505 | 6139 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6506 | 6140 | _mm256_test_epi32_mask (__m256i __A, __m256i __B) |
| 6507 | 6141 | { |
| 6508 | return (__mmask8) __builtin_ia32_ptestmd256 ((__v8si) __A, | |
| 6509 | (__v8si) __B, | |
| 6510 | (__mmask8) -1); | |
| 6142 | return _mm256_cmpneq_epi32_mask (_mm256_and_si256 (__A, __B), | |
| 6143 | _mm256_setzero_si256()); | |
| 6511 | 6144 | } |
| 6512 | 6145 | |
| 6513 | 6146 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6514 | 6147 | _mm256_mask_test_epi32_mask (__mmask8 __U, __m256i __A, __m256i __B) |
| 6515 | 6148 | { |
| 6516 | return (__mmask8) __builtin_ia32_ptestmd256 ((__v8si) __A, | |
| 6517 | (__v8si) __B, __U); | |
| 6149 | return _mm256_mask_cmpneq_epi32_mask (__U, _mm256_and_si256 (__A, __B), | |
| 6150 | _mm256_setzero_si256()); | |
| 6518 | 6151 | } |
| 6519 | 6152 | |
| 6520 | 6153 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6521 | 6154 | _mm_test_epi64_mask (__m128i __A, __m128i __B) |
| 6522 | 6155 | { |
| 6523 | return (__mmask8) __builtin_ia32_ptestmq128 ((__v2di) __A, | |
| 6524 | (__v2di) __B, | |
| 6525 | (__mmask8) -1); | |
| 6156 | return _mm_cmpneq_epi64_mask (_mm_and_si128 (__A, __B), _mm_setzero_di()); | |
| 6526 | 6157 | } |
| 6527 | 6158 | |
| 6528 | 6159 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6529 | 6160 | _mm_mask_test_epi64_mask (__mmask8 __U, __m128i __A, __m128i __B) |
| 6530 | 6161 | { |
| 6531 | return (__mmask8) __builtin_ia32_ptestmq128 ((__v2di) __A, | |
| 6532 | (__v2di) __B, __U); | |
| 6162 | return _mm_mask_cmpneq_epi64_mask (__U, _mm_and_si128 (__A, __B), | |
| 6163 | _mm_setzero_di()); | |
| 6533 | 6164 | } |
| 6534 | 6165 | |
| 6535 | 6166 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6536 | 6167 | _mm256_test_epi64_mask (__m256i __A, __m256i __B) |
| 6537 | 6168 | { |
| 6538 | return (__mmask8) __builtin_ia32_ptestmq256 ((__v4di) __A, | |
| 6539 | (__v4di) __B, | |
| 6540 | (__mmask8) -1); | |
| 6169 | return _mm256_cmpneq_epi64_mask (_mm256_and_si256 (__A, __B), | |
| 6170 | _mm256_setzero_si256()); | |
| 6541 | 6171 | } |
| 6542 | 6172 | |
| 6543 | 6173 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6544 | 6174 | _mm256_mask_test_epi64_mask (__mmask8 __U, __m256i __A, __m256i __B) |
| 6545 | 6175 | { |
| 6546 | return (__mmask8) __builtin_ia32_ptestmq256 ((__v4di) __A, | |
| 6547 | (__v4di) __B, __U); | |
| 6176 | return _mm256_mask_cmpneq_epi64_mask (__U, _mm256_and_si256 (__A, __B), | |
| 6177 | _mm256_setzero_si256()); | |
| 6548 | 6178 | } |
| 6549 | 6179 | |
| 6550 | 6180 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6551 | 6181 | _mm_testn_epi32_mask (__m128i __A, __m128i __B) |
| 6552 | 6182 | { |
| 6553 | return (__mmask8) __builtin_ia32_ptestnmd128 ((__v4si) __A, | |
| 6554 | (__v4si) __B, | |
| 6555 | (__mmask8) -1); | |
| 6183 | return _mm_cmpeq_epi32_mask (_mm_and_si128 (__A, __B), _mm_setzero_di()); | |
| 6556 | 6184 | } |
| 6557 | 6185 | |
| 6558 | 6186 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6559 | 6187 | _mm_mask_testn_epi32_mask (__mmask8 __U, __m128i __A, __m128i __B) |
| 6560 | 6188 | { |
| 6561 | return (__mmask8) __builtin_ia32_ptestnmd128 ((__v4si) __A, | |
| 6562 | (__v4si) __B, __U); | |
| 6189 | return _mm_mask_cmpeq_epi32_mask (__U, _mm_and_si128 (__A, __B), | |
| 6190 | _mm_setzero_di()); | |
| 6563 | 6191 | } |
| 6564 | 6192 | |
| 6565 | 6193 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6566 | 6194 | _mm256_testn_epi32_mask (__m256i __A, __m256i __B) |
| 6567 | 6195 | { |
| 6568 | return (__mmask8) __builtin_ia32_ptestnmd256 ((__v8si) __A, | |
| 6569 | (__v8si) __B, | |
| 6570 | (__mmask8) -1); | |
| 6196 | return _mm256_cmpeq_epi32_mask (_mm256_and_si256 (__A, __B), | |
| 6197 | _mm256_setzero_si256()); | |
| 6571 | 6198 | } |
| 6572 | 6199 | |
| 6573 | 6200 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6574 | 6201 | _mm256_mask_testn_epi32_mask (__mmask8 __U, __m256i __A, __m256i __B) |
| 6575 | 6202 | { |
| 6576 | return (__mmask8) __builtin_ia32_ptestnmd256 ((__v8si) __A, | |
| 6577 | (__v8si) __B, __U); | |
| 6203 | return _mm256_mask_cmpeq_epi32_mask (__U, _mm256_and_si256 (__A, __B), | |
| 6204 | _mm256_setzero_si256()); | |
| 6578 | 6205 | } |
| 6579 | 6206 | |
| 6580 | 6207 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6581 | 6208 | _mm_testn_epi64_mask (__m128i __A, __m128i __B) |
| 6582 | 6209 | { |
| 6583 | return (__mmask8) __builtin_ia32_ptestnmq128 ((__v2di) __A, | |
| 6584 | (__v2di) __B, | |
| 6585 | (__mmask8) -1); | |
| 6210 | return _mm_cmpeq_epi64_mask (_mm_and_si128 (__A, __B), _mm_setzero_di()); | |
| 6586 | 6211 | } |
| 6587 | 6212 | |
| 6588 | 6213 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6589 | 6214 | _mm_mask_testn_epi64_mask (__mmask8 __U, __m128i __A, __m128i __B) |
| 6590 | 6215 | { |
| 6591 | return (__mmask8) __builtin_ia32_ptestnmq128 ((__v2di) __A, | |
| 6592 | (__v2di) __B, __U); | |
| 6216 | return _mm_mask_cmpeq_epi64_mask (__U, _mm_and_si128 (__A, __B), | |
| 6217 | _mm_setzero_di()); | |
| 6593 | 6218 | } |
| 6594 | 6219 | |
| 6595 | 6220 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6596 | 6221 | _mm256_testn_epi64_mask (__m256i __A, __m256i __B) |
| 6597 | 6222 | { |
| 6598 | return (__mmask8) __builtin_ia32_ptestnmq256 ((__v4di) __A, | |
| 6599 | (__v4di) __B, | |
| 6600 | (__mmask8) -1); | |
| 6223 | return _mm256_cmpeq_epi64_mask (_mm256_and_si256 (__A, __B), | |
| 6224 | _mm256_setzero_si256()); | |
| 6601 | 6225 | } |
| 6602 | 6226 | |
| 6603 | 6227 | static __inline__ __mmask8 __DEFAULT_FN_ATTRS |
| 6604 | 6228 | _mm256_mask_testn_epi64_mask (__mmask8 __U, __m256i __A, __m256i __B) |
| 6605 | 6229 | { |
| 6606 | return (__mmask8) __builtin_ia32_ptestnmq256 ((__v4di) __A, | |
| 6607 | (__v4di) __B, __U); | |
| 6230 | return _mm256_mask_cmpeq_epi64_mask (__U, _mm256_and_si256 (__A, __B), | |
| 6231 | _mm256_setzero_si256()); | |
| 6608 | 6232 | } |
| 6609 | 6233 | |
| 6610 | ||
| 6611 | ||
| 6612 | 6234 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| 6613 | 6235 | _mm_mask_unpackhi_epi32(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) |
| 6614 | 6236 | { |
| ... | ... | @@ -6964,85 +6586,81 @@ _mm256_maskz_srai_epi64(__mmask8 __U, __m256i __A, int __imm) |
| 6964 | 6586 | |
| 6965 | 6587 | |
| 6966 | 6588 | #define _mm256_shuffle_f32x4(A, B, imm) __extension__ ({ \ |
| 6967 | (__m256)__builtin_ia32_shuf_f32x4_256_mask((__v8sf)(__m256)(A), \ | |
| 6968 | (__v8sf)(__m256)(B), (int)(imm), \ | |
| 6969 | (__v8sf)_mm256_setzero_ps(), \ | |
| 6970 | (__mmask8)-1); }) | |
| 6589 | (__m256)__builtin_shufflevector((__v8sf)(__m256)(A), \ | |
| 6590 | (__v8sf)(__m256)(B), \ | |
| 6591 | 0 + ((((imm) >> 0) & 0x1) * 4), \ | |
| 6592 | 1 + ((((imm) >> 0) & 0x1) * 4), \ | |
| 6593 | 2 + ((((imm) >> 0) & 0x1) * 4), \ | |
| 6594 | 3 + ((((imm) >> 0) & 0x1) * 4), \ | |
| 6595 | 8 + ((((imm) >> 1) & 0x1) * 4), \ | |
| 6596 | 9 + ((((imm) >> 1) & 0x1) * 4), \ | |
| 6597 | 10 + ((((imm) >> 1) & 0x1) * 4), \ | |
| 6598 | 11 + ((((imm) >> 1) & 0x1) * 4)); }) | |
| 6971 | 6599 | |
| 6972 | 6600 | #define _mm256_mask_shuffle_f32x4(W, U, A, B, imm) __extension__ ({ \ |
| 6973 | (__m256)__builtin_ia32_shuf_f32x4_256_mask((__v8sf)(__m256)(A), \ | |
| 6974 | (__v8sf)(__m256)(B), (int)(imm), \ | |
| 6975 | (__v8sf)(__m256)(W), \ | |
| 6976 | (__mmask8)(U)); }) | |
| 6601 | (__m256)__builtin_ia32_selectps_256((__mmask8)(U), \ | |
| 6602 | (__v8sf)_mm256_shuffle_f32x4((A), (B), (imm)), \ | |
| 6603 | (__v8sf)(__m256)(W)); }) | |
| 6977 | 6604 | |
| 6978 | 6605 | #define _mm256_maskz_shuffle_f32x4(U, A, B, imm) __extension__ ({ \ |
| 6979 | (__m256)__builtin_ia32_shuf_f32x4_256_mask((__v8sf)(__m256)(A), \ | |
| 6980 | (__v8sf)(__m256)(B), (int)(imm), \ | |
| 6981 | (__v8sf)_mm256_setzero_ps(), \ | |
| 6982 | (__mmask8)(U)); }) | |
| 6606 | (__m256)__builtin_ia32_selectps_256((__mmask8)(U), \ | |
| 6607 | (__v8sf)_mm256_shuffle_f32x4((A), (B), (imm)), \ | |
| 6608 | (__v8sf)_mm256_setzero_ps()); }) | |
| 6983 | 6609 | |
| 6984 | 6610 | #define _mm256_shuffle_f64x2(A, B, imm) __extension__ ({ \ |
| 6985 | (__m256d)__builtin_ia32_shuf_f64x2_256_mask((__v4df)(__m256d)(A), \ | |
| 6986 | (__v4df)(__m256d)(B), \ | |
| 6987 | (int)(imm), \ | |
| 6988 | (__v4df)_mm256_setzero_pd(), \ | |
| 6989 | (__mmask8)-1); }) | |
| 6611 | (__m256d)__builtin_shufflevector((__v4df)(__m256d)(A), \ | |
| 6612 | (__v4df)(__m256d)(B), \ | |
| 6613 | 0 + ((((imm) >> 0) & 0x1) * 2), \ | |
| 6614 | 1 + ((((imm) >> 0) & 0x1) * 2), \ | |
| 6615 | 4 + ((((imm) >> 1) & 0x1) * 2), \ | |
| 6616 | 5 + ((((imm) >> 1) & 0x1) * 2)); }) | |
| 6990 | 6617 | |
| 6991 | 6618 | #define _mm256_mask_shuffle_f64x2(W, U, A, B, imm) __extension__ ({ \ |
| 6992 | (__m256d)__builtin_ia32_shuf_f64x2_256_mask((__v4df)(__m256d)(A), \ | |
| 6993 | (__v4df)(__m256d)(B), \ | |
| 6994 | (int)(imm), \ | |
| 6995 | (__v4df)(__m256d)(W), \ | |
| 6996 | (__mmask8)(U)); }) | |
| 6619 | (__m256d)__builtin_ia32_selectpd_256((__mmask8)(U), \ | |
| 6620 | (__v4df)_mm256_shuffle_f64x2((A), (B), (imm)), \ | |
| 6621 | (__v4df)(__m256)(W)); }) | |
| 6997 | 6622 | |
| 6998 | 6623 | #define _mm256_maskz_shuffle_f64x2(U, A, B, imm) __extension__ ({ \ |
| 6999 | (__m256d)__builtin_ia32_shuf_f64x2_256_mask((__v4df)(__m256d)(A), \ | |
| 7000 | (__v4df)(__m256d)(B), \ | |
| 7001 | (int)(imm), \ | |
| 7002 | (__v4df)_mm256_setzero_pd(), \ | |
| 7003 | (__mmask8)(U)); }) | |
| 6624 | (__m256d)__builtin_ia32_selectpd_256((__mmask8)(U), \ | |
| 6625 | (__v4df)_mm256_shuffle_f64x2((A), (B), (imm)), \ | |
| 6626 | (__v4df)_mm256_setzero_pd()); }) | |
| 7004 | 6627 | |
| 7005 | 6628 | #define _mm256_shuffle_i32x4(A, B, imm) __extension__ ({ \ |
| 7006 | (__m256i)__builtin_ia32_shuf_i32x4_256_mask((__v8si)(__m256i)(A), \ | |
| 7007 | (__v8si)(__m256i)(B), \ | |
| 7008 | (int)(imm), \ | |
| 7009 | (__v8si)_mm256_setzero_si256(), \ | |
| 7010 | (__mmask8)-1); }) | |
| 6629 | (__m256i)__builtin_shufflevector((__v4di)(__m256i)(A), \ | |
| 6630 | (__v4di)(__m256i)(B), \ | |
| 6631 | 0 + ((((imm) >> 0) & 0x1) * 2), \ | |
| 6632 | 1 + ((((imm) >> 0) & 0x1) * 2), \ | |
| 6633 | 4 + ((((imm) >> 1) & 0x1) * 2), \ | |
| 6634 | 5 + ((((imm) >> 1) & 0x1) * 2)); }) | |
| 7011 | 6635 | |
| 7012 | 6636 | #define _mm256_mask_shuffle_i32x4(W, U, A, B, imm) __extension__ ({ \ |
| 7013 | (__m256i)__builtin_ia32_shuf_i32x4_256_mask((__v8si)(__m256i)(A), \ | |
| 7014 | (__v8si)(__m256i)(B), \ | |
| 7015 | (int)(imm), \ | |
| 7016 | (__v8si)(__m256i)(W), \ | |
| 7017 | (__mmask8)(U)); }) | |
| 6637 | (__m256i)__builtin_ia32_selectd_256((__mmask8)(U), \ | |
| 6638 | (__v8si)_mm256_shuffle_i32x4((A), (B), (imm)), \ | |
| 6639 | (__v8si)(__m256)(W)); }) | |
| 7018 | 6640 | |
| 7019 | 6641 | #define _mm256_maskz_shuffle_i32x4(U, A, B, imm) __extension__ ({ \ |
| 7020 | (__m256i)__builtin_ia32_shuf_i32x4_256_mask((__v8si)(__m256i)(A), \ | |
| 7021 | (__v8si)(__m256i)(B), \ | |
| 7022 | (int)(imm), \ | |
| 7023 | (__v8si)_mm256_setzero_si256(), \ | |
| 7024 | (__mmask8)(U)); }) | |
| 6642 | (__m256i)__builtin_ia32_selectd_256((__mmask8)(U), \ | |
| 6643 | (__v8si)_mm256_shuffle_i32x4((A), (B), (imm)), \ | |
| 6644 | (__v8si)_mm256_setzero_si256()); }) | |
| 7025 | 6645 | |
| 7026 | 6646 | #define _mm256_shuffle_i64x2(A, B, imm) __extension__ ({ \ |
| 7027 | (__m256i)__builtin_ia32_shuf_i64x2_256_mask((__v4di)(__m256i)(A), \ | |
| 7028 | (__v4di)(__m256i)(B), \ | |
| 7029 | (int)(imm), \ | |
| 7030 | (__v4di)_mm256_setzero_si256(), \ | |
| 7031 | (__mmask8)-1); }) | |
| 6647 | (__m256i)__builtin_shufflevector((__v4di)(__m256i)(A), \ | |
| 6648 | (__v4di)(__m256i)(B), \ | |
| 6649 | 0 + ((((imm) >> 0) & 0x1) * 2), \ | |
| 6650 | 1 + ((((imm) >> 0) & 0x1) * 2), \ | |
| 6651 | 4 + ((((imm) >> 1) & 0x1) * 2), \ | |
| 6652 | 5 + ((((imm) >> 1) & 0x1) * 2)); }) | |
| 7032 | 6653 | |
| 7033 | 6654 | #define _mm256_mask_shuffle_i64x2(W, U, A, B, imm) __extension__ ({ \ |
| 7034 | (__m256i)__builtin_ia32_shuf_i64x2_256_mask((__v4di)(__m256i)(A), \ | |
| 7035 | (__v4di)(__m256i)(B), \ | |
| 7036 | (int)(imm), \ | |
| 7037 | (__v4di)(__m256i)(W), \ | |
| 7038 | (__mmask8)(U)); }) | |
| 6655 | (__m256i)__builtin_ia32_selectq_256((__mmask8)(U), \ | |
| 6656 | (__v4di)_mm256_shuffle_i64x2((A), (B), (imm)), \ | |
| 6657 | (__v4di)(__m256)(W)); }) | |
| 6658 | ||
| 7039 | 6659 | |
| 7040 | 6660 | #define _mm256_maskz_shuffle_i64x2(U, A, B, imm) __extension__ ({ \ |
| 7041 | (__m256i)__builtin_ia32_shuf_i64x2_256_mask((__v4di)(__m256i)(A), \ | |
| 7042 | (__v4di)(__m256i)(B), \ | |
| 7043 | (int)(imm), \ | |
| 7044 | (__v4di)_mm256_setzero_si256(), \ | |
| 7045 | (__mmask8)(U)); }) | |
| 6661 | (__m256i)__builtin_ia32_selectq_256((__mmask8)(U), \ | |
| 6662 | (__v4di)_mm256_shuffle_i64x2((A), (B), (imm)), \ | |
| 6663 | (__v4di)_mm256_setzero_si256()); }) | |
| 7046 | 6664 | |
| 7047 | 6665 | #define _mm_mask_shuffle_pd(W, U, A, B, M) __extension__ ({ \ |
| 7048 | 6666 | (__m128d)__builtin_ia32_selectpd_128((__mmask8)(U), \ |
c_headers/avx512vlvbmi2intrin.h created+748| ... | ... | @@ -0,0 +1,748 @@ |
| 1 | /*===------------- avx512vlvbmi2intrin.h - VBMI2 intrinsics -----------------=== | |
| 2 | * | |
| 3 | * | |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 5 | * of this software and associated documentation files (the "Software"), to deal | |
| 6 | * in the Software without restriction, including without limitation the rights | |
| 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 8 | * copies of the Software, and to permit persons to whom the Software is | |
| 9 | * furnished to do so, subject to the following conditions: | |
| 10 | * | |
| 11 | * The above copyright notice and this permission notice shall be included in | |
| 12 | * all copies or substantial portions of the Software. | |
| 13 | * | |
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 20 | * THE SOFTWARE. | |
| 21 | * | |
| 22 | *===-----------------------------------------------------------------------=== | |
| 23 | */ | |
| 24 | #ifndef __IMMINTRIN_H | |
| 25 | #error "Never use <avx512vlvbmi2intrin.h> directly; include <immintrin.h> instead." | |
| 26 | #endif | |
| 27 | ||
| 28 | #ifndef __AVX512VLVBMI2INTRIN_H | |
| 29 | #define __AVX512VLVBMI2INTRIN_H | |
| 30 | ||
| 31 | /* Define the default attributes for the functions in this file. */ | |
| 32 | #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512vl,avx512vbmi2"))) | |
| 33 | ||
| 34 | static __inline __m128i __DEFAULT_FN_ATTRS | |
| 35 | _mm128_setzero_hi(void) { | |
| 36 | return (__m128i)(__v8hi){ 0, 0, 0, 0, 0, 0, 0, 0 }; | |
| 37 | } | |
| 38 | ||
| 39 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 40 | _mm128_mask_compress_epi16(__m128i __S, __mmask8 __U, __m128i __D) | |
| 41 | { | |
| 42 | return (__m128i) __builtin_ia32_compresshi128_mask ((__v8hi) __D, | |
| 43 | (__v8hi) __S, | |
| 44 | __U); | |
| 45 | } | |
| 46 | ||
| 47 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 48 | _mm128_maskz_compress_epi16(__mmask8 __U, __m128i __D) | |
| 49 | { | |
| 50 | return (__m128i) __builtin_ia32_compresshi128_mask ((__v8hi) __D, | |
| 51 | (__v8hi) _mm128_setzero_hi(), | |
| 52 | __U); | |
| 53 | } | |
| 54 | ||
| 55 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 56 | _mm128_mask_compress_epi8(__m128i __S, __mmask16 __U, __m128i __D) | |
| 57 | { | |
| 58 | return (__m128i) __builtin_ia32_compressqi128_mask ((__v16qi) __D, | |
| 59 | (__v16qi) __S, | |
| 60 | __U); | |
| 61 | } | |
| 62 | ||
| 63 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 64 | _mm128_maskz_compress_epi8(__mmask16 __U, __m128i __D) | |
| 65 | { | |
| 66 | return (__m128i) __builtin_ia32_compressqi128_mask ((__v16qi) __D, | |
| 67 | (__v16qi) _mm128_setzero_hi(), | |
| 68 | __U); | |
| 69 | } | |
| 70 | ||
| 71 | static __inline__ void __DEFAULT_FN_ATTRS | |
| 72 | _mm128_mask_compressstoreu_epi16(void *__P, __mmask8 __U, __m128i __D) | |
| 73 | { | |
| 74 | __builtin_ia32_compressstorehi128_mask ((__v8hi *) __P, (__v8hi) __D, | |
| 75 | __U); | |
| 76 | } | |
| 77 | ||
| 78 | static __inline__ void __DEFAULT_FN_ATTRS | |
| 79 | _mm128_mask_compressstoreu_epi8(void *__P, __mmask16 __U, __m128i __D) | |
| 80 | { | |
| 81 | __builtin_ia32_compressstoreqi128_mask ((__v16qi *) __P, (__v16qi) __D, | |
| 82 | __U); | |
| 83 | } | |
| 84 | ||
| 85 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 86 | _mm128_mask_expand_epi16(__m128i __S, __mmask8 __U, __m128i __D) | |
| 87 | { | |
| 88 | return (__m128i) __builtin_ia32_expandhi128_mask ((__v8hi) __D, | |
| 89 | (__v8hi) __S, | |
| 90 | __U); | |
| 91 | } | |
| 92 | ||
| 93 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 94 | _mm128_maskz_expand_epi16(__mmask8 __U, __m128i __D) | |
| 95 | { | |
| 96 | return (__m128i) __builtin_ia32_expandhi128_mask ((__v8hi) __D, | |
| 97 | (__v8hi) _mm128_setzero_hi(), | |
| 98 | __U); | |
| 99 | } | |
| 100 | ||
| 101 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 102 | _mm128_mask_expand_epi8(__m128i __S, __mmask16 __U, __m128i __D) | |
| 103 | { | |
| 104 | return (__m128i) __builtin_ia32_expandqi128_mask ((__v16qi) __D, | |
| 105 | (__v16qi) __S, | |
| 106 | __U); | |
| 107 | } | |
| 108 | ||
| 109 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 110 | _mm128_maskz_expand_epi8(__mmask16 __U, __m128i __D) | |
| 111 | { | |
| 112 | return (__m128i) __builtin_ia32_expandqi128_mask ((__v16qi) __D, | |
| 113 | (__v16qi) _mm128_setzero_hi(), | |
| 114 | __U); | |
| 115 | } | |
| 116 | ||
| 117 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 118 | _mm128_mask_expandloadu_epi16(__m128i __S, __mmask8 __U, void const *__P) | |
| 119 | { | |
| 120 | return (__m128i) __builtin_ia32_expandloadhi128_mask ((const __v8hi *)__P, | |
| 121 | (__v8hi) __S, | |
| 122 | __U); | |
| 123 | } | |
| 124 | ||
| 125 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 126 | _mm128_maskz_expandloadu_epi16(__mmask8 __U, void const *__P) | |
| 127 | { | |
| 128 | return (__m128i) __builtin_ia32_expandloadhi128_mask ((const __v8hi *)__P, | |
| 129 | (__v8hi) _mm128_setzero_hi(), | |
| 130 | __U); | |
| 131 | } | |
| 132 | ||
| 133 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 134 | _mm128_mask_expandloadu_epi8(__m128i __S, __mmask16 __U, void const *__P) | |
| 135 | { | |
| 136 | return (__m128i) __builtin_ia32_expandloadqi128_mask ((const __v16qi *)__P, | |
| 137 | (__v16qi) __S, | |
| 138 | __U); | |
| 139 | } | |
| 140 | ||
| 141 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 142 | _mm128_maskz_expandloadu_epi8(__mmask16 __U, void const *__P) | |
| 143 | { | |
| 144 | return (__m128i) __builtin_ia32_expandloadqi128_mask ((const __v16qi *)__P, | |
| 145 | (__v16qi) _mm128_setzero_hi(), | |
| 146 | __U); | |
| 147 | } | |
| 148 | ||
| 149 | static __inline __m256i __DEFAULT_FN_ATTRS | |
| 150 | _mm256_setzero_hi(void) { | |
| 151 | return (__m256i)(__v16hi){ 0, 0, 0, 0, 0, 0, 0, 0, | |
| 152 | 0, 0, 0, 0, 0, 0, 0, 0 }; | |
| 153 | } | |
| 154 | ||
| 155 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 156 | _mm256_mask_compress_epi16(__m256i __S, __mmask16 __U, __m256i __D) | |
| 157 | { | |
| 158 | return (__m256i) __builtin_ia32_compresshi256_mask ((__v16hi) __D, | |
| 159 | (__v16hi) __S, | |
| 160 | __U); | |
| 161 | } | |
| 162 | ||
| 163 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 164 | _mm256_maskz_compress_epi16(__mmask16 __U, __m256i __D) | |
| 165 | { | |
| 166 | return (__m256i) __builtin_ia32_compresshi256_mask ((__v16hi) __D, | |
| 167 | (__v16hi) _mm256_setzero_hi(), | |
| 168 | __U); | |
| 169 | } | |
| 170 | ||
| 171 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 172 | _mm256_mask_compress_epi8(__m256i __S, __mmask32 __U, __m256i __D) | |
| 173 | { | |
| 174 | return (__m256i) __builtin_ia32_compressqi256_mask ((__v32qi) __D, | |
| 175 | (__v32qi) __S, | |
| 176 | __U); | |
| 177 | } | |
| 178 | ||
| 179 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 180 | _mm256_maskz_compress_epi8(__mmask32 __U, __m256i __D) | |
| 181 | { | |
| 182 | return (__m256i) __builtin_ia32_compressqi256_mask ((__v32qi) __D, | |
| 183 | (__v32qi) _mm256_setzero_hi(), | |
| 184 | __U); | |
| 185 | } | |
| 186 | ||
| 187 | static __inline__ void __DEFAULT_FN_ATTRS | |
| 188 | _mm256_mask_compressstoreu_epi16(void *__P, __mmask16 __U, __m256i __D) | |
| 189 | { | |
| 190 | __builtin_ia32_compressstorehi256_mask ((__v16hi *) __P, (__v16hi) __D, | |
| 191 | __U); | |
| 192 | } | |
| 193 | ||
| 194 | static __inline__ void __DEFAULT_FN_ATTRS | |
| 195 | _mm256_mask_compressstoreu_epi8(void *__P, __mmask32 __U, __m256i __D) | |
| 196 | { | |
| 197 | __builtin_ia32_compressstoreqi256_mask ((__v32qi *) __P, (__v32qi) __D, | |
| 198 | __U); | |
| 199 | } | |
| 200 | ||
| 201 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 202 | _mm256_mask_expand_epi16(__m256i __S, __mmask16 __U, __m256i __D) | |
| 203 | { | |
| 204 | return (__m256i) __builtin_ia32_expandhi256_mask ((__v16hi) __D, | |
| 205 | (__v16hi) __S, | |
| 206 | __U); | |
| 207 | } | |
| 208 | ||
| 209 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 210 | _mm256_maskz_expand_epi16(__mmask16 __U, __m256i __D) | |
| 211 | { | |
| 212 | return (__m256i) __builtin_ia32_expandhi256_mask ((__v16hi) __D, | |
| 213 | (__v16hi) _mm256_setzero_hi(), | |
| 214 | __U); | |
| 215 | } | |
| 216 | ||
| 217 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 218 | _mm256_mask_expand_epi8(__m256i __S, __mmask32 __U, __m256i __D) | |
| 219 | { | |
| 220 | return (__m256i) __builtin_ia32_expandqi256_mask ((__v32qi) __D, | |
| 221 | (__v32qi) __S, | |
| 222 | __U); | |
| 223 | } | |
| 224 | ||
| 225 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 226 | _mm256_maskz_expand_epi8(__mmask32 __U, __m256i __D) | |
| 227 | { | |
| 228 | return (__m256i) __builtin_ia32_expandqi256_mask ((__v32qi) __D, | |
| 229 | (__v32qi) _mm256_setzero_hi(), | |
| 230 | __U); | |
| 231 | } | |
| 232 | ||
| 233 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 234 | _mm256_mask_expandloadu_epi16(__m256i __S, __mmask16 __U, void const *__P) | |
| 235 | { | |
| 236 | return (__m256i) __builtin_ia32_expandloadhi256_mask ((const __v16hi *)__P, | |
| 237 | (__v16hi) __S, | |
| 238 | __U); | |
| 239 | } | |
| 240 | ||
| 241 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 242 | _mm256_maskz_expandloadu_epi16(__mmask16 __U, void const *__P) | |
| 243 | { | |
| 244 | return (__m256i) __builtin_ia32_expandloadhi256_mask ((const __v16hi *)__P, | |
| 245 | (__v16hi) _mm256_setzero_hi(), | |
| 246 | __U); | |
| 247 | } | |
| 248 | ||
| 249 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 250 | _mm256_mask_expandloadu_epi8(__m256i __S, __mmask32 __U, void const *__P) | |
| 251 | { | |
| 252 | return (__m256i) __builtin_ia32_expandloadqi256_mask ((const __v32qi *)__P, | |
| 253 | (__v32qi) __S, | |
| 254 | __U); | |
| 255 | } | |
| 256 | ||
| 257 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 258 | _mm256_maskz_expandloadu_epi8(__mmask32 __U, void const *__P) | |
| 259 | { | |
| 260 | return (__m256i) __builtin_ia32_expandloadqi256_mask ((const __v32qi *)__P, | |
| 261 | (__v32qi) _mm256_setzero_hi(), | |
| 262 | __U); | |
| 263 | } | |
| 264 | ||
| 265 | #define _mm256_mask_shldi_epi64(S, U, A, B, I) __extension__ ({ \ | |
| 266 | (__m256i)__builtin_ia32_vpshldq256_mask((__v4di)(A), \ | |
| 267 | (__v4di)(B), \ | |
| 268 | (int)(I), \ | |
| 269 | (__v4di)(S), \ | |
| 270 | (__mmask8)(U)); }) | |
| 271 | ||
| 272 | #define _mm256_maskz_shldi_epi64(U, A, B, I) \ | |
| 273 | _mm256_mask_shldi_epi64(_mm256_setzero_hi(), (U), (A), (B), (I)) | |
| 274 | ||
| 275 | #define _mm256_shldi_epi64(A, B, I) \ | |
| 276 | _mm256_mask_shldi_epi64(_mm256_undefined_si256(), (__mmask8)(-1), (A), (B), (I)) | |
| 277 | ||
| 278 | #define _mm128_mask_shldi_epi64(S, U, A, B, I) __extension__ ({ \ | |
| 279 | (__m128i)__builtin_ia32_vpshldq128_mask((__v2di)(A), \ | |
| 280 | (__v2di)(B), \ | |
| 281 | (int)(I), \ | |
| 282 | (__v2di)(S), \ | |
| 283 | (__mmask8)(U)); }) | |
| 284 | ||
| 285 | #define _mm128_maskz_shldi_epi64(U, A, B, I) \ | |
| 286 | _mm128_mask_shldi_epi64(_mm128_setzero_hi(), (U), (A), (B), (I)) | |
| 287 | ||
| 288 | #define _mm128_shldi_epi64(A, B, I) \ | |
| 289 | _mm128_mask_shldi_epi64(_mm_undefined_si128(), (__mmask8)(-1), (A), (B), (I)) | |
| 290 | ||
| 291 | #define _mm256_mask_shldi_epi32(S, U, A, B, I) __extension__ ({ \ | |
| 292 | (__m256i)__builtin_ia32_vpshldd256_mask((__v8si)(A), \ | |
| 293 | (__v8si)(B), \ | |
| 294 | (int)(I), \ | |
| 295 | (__v8si)(S), \ | |
| 296 | (__mmask8)(U)); }) | |
| 297 | ||
| 298 | #define _mm256_maskz_shldi_epi32(U, A, B, I) \ | |
| 299 | _mm256_mask_shldi_epi32(_mm256_setzero_hi(), (U), (A), (B), (I)) | |
| 300 | ||
| 301 | #define _mm256_shldi_epi32(A, B, I) \ | |
| 302 | _mm256_mask_shldi_epi32(_mm256_undefined_si256(), (__mmask8)(-1), (A), (B), (I)) | |
| 303 | ||
| 304 | #define _mm128_mask_shldi_epi32(S, U, A, B, I) __extension__ ({ \ | |
| 305 | (__m128i)__builtin_ia32_vpshldd128_mask((__v4si)(A), \ | |
| 306 | (__v4si)(B), \ | |
| 307 | (int)(I), \ | |
| 308 | (__v4si)(S), \ | |
| 309 | (__mmask8)(U)); }) | |
| 310 | ||
| 311 | #define _mm128_maskz_shldi_epi32(U, A, B, I) \ | |
| 312 | _mm128_mask_shldi_epi32(_mm128_setzero_hi(), (U), (A), (B), (I)) | |
| 313 | ||
| 314 | #define _mm128_shldi_epi32(A, B, I) \ | |
| 315 | _mm128_mask_shldi_epi32(_mm_undefined_si128(), (__mmask8)(-1), (A), (B), (I)) | |
| 316 | ||
| 317 | #define _mm256_mask_shldi_epi16(S, U, A, B, I) __extension__ ({ \ | |
| 318 | (__m256i)__builtin_ia32_vpshldw256_mask((__v16hi)(A), \ | |
| 319 | (__v16hi)(B), \ | |
| 320 | (int)(I), \ | |
| 321 | (__v16hi)(S), \ | |
| 322 | (__mmask16)(U)); }) | |
| 323 | ||
| 324 | #define _mm256_maskz_shldi_epi16(U, A, B, I) \ | |
| 325 | _mm256_mask_shldi_epi16(_mm256_setzero_hi(), (U), (A), (B), (I)) | |
| 326 | ||
| 327 | #define _mm256_shldi_epi16(A, B, I) \ | |
| 328 | _mm256_mask_shldi_epi16(_mm256_undefined_si256(), (__mmask8)(-1), (A), (B), (I)) | |
| 329 | ||
| 330 | #define _mm128_mask_shldi_epi16(S, U, A, B, I) __extension__ ({ \ | |
| 331 | (__m128i)__builtin_ia32_vpshldw128_mask((__v8hi)(A), \ | |
| 332 | (__v8hi)(B), \ | |
| 333 | (int)(I), \ | |
| 334 | (__v8hi)(S), \ | |
| 335 | (__mmask8)(U)); }) | |
| 336 | ||
| 337 | #define _mm128_maskz_shldi_epi16(U, A, B, I) \ | |
| 338 | _mm128_mask_shldi_epi16(_mm128_setzero_hi(), (U), (A), (B), (I)) | |
| 339 | ||
| 340 | #define _mm128_shldi_epi16(A, B, I) \ | |
| 341 | _mm128_mask_shldi_epi16(_mm_undefined_si128(), (__mmask8)(-1), (A), (B), (I)) | |
| 342 | ||
| 343 | #define _mm256_mask_shrdi_epi64(S, U, A, B, I) __extension__ ({ \ | |
| 344 | (__m256i)__builtin_ia32_vpshrdq256_mask((__v4di)(A), \ | |
| 345 | (__v4di)(B), \ | |
| 346 | (int)(I), \ | |
| 347 | (__v4di)(S), \ | |
| 348 | (__mmask8)(U)); }) | |
| 349 | ||
| 350 | #define _mm256_maskz_shrdi_epi64(U, A, B, I) \ | |
| 351 | _mm256_mask_shrdi_epi64(_mm256_setzero_hi(), (U), (A), (B), (I)) | |
| 352 | ||
| 353 | #define _mm256_shrdi_epi64(A, B, I) \ | |
| 354 | _mm256_mask_shrdi_epi64(_mm256_undefined_si256(), (__mmask8)(-1), (A), (B), (I)) | |
| 355 | ||
| 356 | #define _mm128_mask_shrdi_epi64(S, U, A, B, I) __extension__ ({ \ | |
| 357 | (__m128i)__builtin_ia32_vpshrdq128_mask((__v2di)(A), \ | |
| 358 | (__v2di)(B), \ | |
| 359 | (int)(I), \ | |
| 360 | (__v2di)(S), \ | |
| 361 | (__mmask8)(U)); }) | |
| 362 | ||
| 363 | #define _mm128_maskz_shrdi_epi64(U, A, B, I) \ | |
| 364 | _mm128_mask_shrdi_epi64(_mm128_setzero_hi(), (U), (A), (B), (I)) | |
| 365 | ||
| 366 | #define _mm128_shrdi_epi64(A, B, I) \ | |
| 367 | _mm128_mask_shrdi_epi64(_mm_undefined_si128(), (__mmask8)(-1), (A), (B), (I)) | |
| 368 | ||
| 369 | #define _mm256_mask_shrdi_epi32(S, U, A, B, I) __extension__ ({ \ | |
| 370 | (__m256i)__builtin_ia32_vpshrdd256_mask((__v8si)(A), \ | |
| 371 | (__v8si)(B), \ | |
| 372 | (int)(I), \ | |
| 373 | (__v8si)(S), \ | |
| 374 | (__mmask8)(U)); }) | |
| 375 | ||
| 376 | #define _mm256_maskz_shrdi_epi32(U, A, B, I) \ | |
| 377 | _mm256_mask_shrdi_epi32(_mm256_setzero_hi(), (U), (A), (B), (I)) | |
| 378 | ||
| 379 | #define _mm256_shrdi_epi32(A, B, I) \ | |
| 380 | _mm256_mask_shrdi_epi32(_mm256_undefined_si256(), (__mmask8)(-1), (A), (B), (I)) | |
| 381 | ||
| 382 | #define _mm128_mask_shrdi_epi32(S, U, A, B, I) __extension__ ({ \ | |
| 383 | (__m128i)__builtin_ia32_vpshrdd128_mask((__v4si)(A), \ | |
| 384 | (__v4si)(B), \ | |
| 385 | (int)(I), \ | |
| 386 | (__v4si)(S), \ | |
| 387 | (__mmask8)(U)); }) | |
| 388 | ||
| 389 | #define _mm128_maskz_shrdi_epi32(U, A, B, I) \ | |
| 390 | _mm128_mask_shrdi_epi32(_mm128_setzero_hi(), (U), (A), (B), (I)) | |
| 391 | ||
| 392 | #define _mm128_shrdi_epi32(A, B, I) \ | |
| 393 | _mm128_mask_shrdi_epi32(_mm_undefined_si128(), (__mmask8)(-1), (A), (B), (I)) | |
| 394 | ||
| 395 | #define _mm256_mask_shrdi_epi16(S, U, A, B, I) __extension__ ({ \ | |
| 396 | (__m256i)__builtin_ia32_vpshrdw256_mask((__v16hi)(A), \ | |
| 397 | (__v16hi)(B), \ | |
| 398 | (int)(I), \ | |
| 399 | (__v16hi)(S), \ | |
| 400 | (__mmask16)(U)); }) | |
| 401 | ||
| 402 | #define _mm256_maskz_shrdi_epi16(U, A, B, I) \ | |
| 403 | _mm256_mask_shrdi_epi16(_mm256_setzero_hi(), (U), (A), (B), (I)) | |
| 404 | ||
| 405 | #define _mm256_shrdi_epi16(A, B, I) \ | |
| 406 | _mm256_mask_shrdi_epi16(_mm256_undefined_si256(), (__mmask8)(-1), (A), (B), (I)) | |
| 407 | ||
| 408 | #define _mm128_mask_shrdi_epi16(S, U, A, B, I) __extension__ ({ \ | |
| 409 | (__m128i)__builtin_ia32_vpshrdw128_mask((__v8hi)(A), \ | |
| 410 | (__v8hi)(B), \ | |
| 411 | (int)(I), \ | |
| 412 | (__v8hi)(S), \ | |
| 413 | (__mmask8)(U)); }) | |
| 414 | ||
| 415 | #define _mm128_maskz_shrdi_epi16(U, A, B, I) \ | |
| 416 | _mm128_mask_shrdi_epi16(_mm128_setzero_hi(), (U), (A), (B), (I)) | |
| 417 | ||
| 418 | #define _mm128_shrdi_epi16(A, B, I) \ | |
| 419 | _mm128_mask_shrdi_epi16(_mm_undefined_si128(), (__mmask8)(-1), (A), (B), (I)) | |
| 420 | ||
| 421 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 422 | _mm256_mask_shldv_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) | |
| 423 | { | |
| 424 | return (__m256i) __builtin_ia32_vpshldvq256_mask ((__v4di) __S, | |
| 425 | (__v4di) __A, | |
| 426 | (__v4di) __B, | |
| 427 | __U); | |
| 428 | } | |
| 429 | ||
| 430 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 431 | _mm256_maskz_shldv_epi64(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) | |
| 432 | { | |
| 433 | return (__m256i) __builtin_ia32_vpshldvq256_maskz ((__v4di) __S, | |
| 434 | (__v4di) __A, | |
| 435 | (__v4di) __B, | |
| 436 | __U); | |
| 437 | } | |
| 438 | ||
| 439 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 440 | _mm256_shldv_epi64(__m256i __S, __m256i __A, __m256i __B) | |
| 441 | { | |
| 442 | return (__m256i) __builtin_ia32_vpshldvq256_mask ((__v4di) __S, | |
| 443 | (__v4di) __A, | |
| 444 | (__v4di) __B, | |
| 445 | (__mmask8) -1); | |
| 446 | } | |
| 447 | ||
| 448 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 449 | _mm128_mask_shldv_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) | |
| 450 | { | |
| 451 | return (__m128i) __builtin_ia32_vpshldvq128_mask ((__v2di) __S, | |
| 452 | (__v2di) __A, | |
| 453 | (__v2di) __B, | |
| 454 | __U); | |
| 455 | } | |
| 456 | ||
| 457 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 458 | _mm128_maskz_shldv_epi64(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) | |
| 459 | { | |
| 460 | return (__m128i) __builtin_ia32_vpshldvq128_maskz ((__v2di) __S, | |
| 461 | (__v2di) __A, | |
| 462 | (__v2di) __B, | |
| 463 | __U); | |
| 464 | } | |
| 465 | ||
| 466 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 467 | _mm128_shldv_epi64(__m128i __S, __m128i __A, __m128i __B) | |
| 468 | { | |
| 469 | return (__m128i) __builtin_ia32_vpshldvq128_mask ((__v2di) __S, | |
| 470 | (__v2di) __A, | |
| 471 | (__v2di) __B, | |
| 472 | (__mmask8) -1); | |
| 473 | } | |
| 474 | ||
| 475 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 476 | _mm256_mask_shldv_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) | |
| 477 | { | |
| 478 | return (__m256i) __builtin_ia32_vpshldvd256_mask ((__v8si) __S, | |
| 479 | (__v8si) __A, | |
| 480 | (__v8si) __B, | |
| 481 | __U); | |
| 482 | } | |
| 483 | ||
| 484 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 485 | _mm256_maskz_shldv_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) | |
| 486 | { | |
| 487 | return (__m256i) __builtin_ia32_vpshldvd256_maskz ((__v8si) __S, | |
| 488 | (__v8si) __A, | |
| 489 | (__v8si) __B, | |
| 490 | __U); | |
| 491 | } | |
| 492 | ||
| 493 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 494 | _mm256_shldv_epi32(__m256i __S, __m256i __A, __m256i __B) | |
| 495 | { | |
| 496 | return (__m256i) __builtin_ia32_vpshldvd256_mask ((__v8si) __S, | |
| 497 | (__v8si) __A, | |
| 498 | (__v8si) __B, | |
| 499 | (__mmask8) -1); | |
| 500 | } | |
| 501 | ||
| 502 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 503 | _mm128_mask_shldv_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) | |
| 504 | { | |
| 505 | return (__m128i) __builtin_ia32_vpshldvd128_mask ((__v4si) __S, | |
| 506 | (__v4si) __A, | |
| 507 | (__v4si) __B, | |
| 508 | __U); | |
| 509 | } | |
| 510 | ||
| 511 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 512 | _mm128_maskz_shldv_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) | |
| 513 | { | |
| 514 | return (__m128i) __builtin_ia32_vpshldvd128_maskz ((__v4si) __S, | |
| 515 | (__v4si) __A, | |
| 516 | (__v4si) __B, | |
| 517 | __U); | |
| 518 | } | |
| 519 | ||
| 520 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 521 | _mm128_shldv_epi32(__m128i __S, __m128i __A, __m128i __B) | |
| 522 | { | |
| 523 | return (__m128i) __builtin_ia32_vpshldvd128_mask ((__v4si) __S, | |
| 524 | (__v4si) __A, | |
| 525 | (__v4si) __B, | |
| 526 | (__mmask8) -1); | |
| 527 | } | |
| 528 | ||
| 529 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 530 | _mm256_mask_shldv_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B) | |
| 531 | { | |
| 532 | return (__m256i) __builtin_ia32_vpshldvw256_mask ((__v16hi) __S, | |
| 533 | (__v16hi) __A, | |
| 534 | (__v16hi) __B, | |
| 535 | __U); | |
| 536 | } | |
| 537 | ||
| 538 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 539 | _mm256_maskz_shldv_epi16(__mmask16 __U, __m256i __S, __m256i __A, __m256i __B) | |
| 540 | { | |
| 541 | return (__m256i) __builtin_ia32_vpshldvw256_maskz ((__v16hi) __S, | |
| 542 | (__v16hi) __A, | |
| 543 | (__v16hi) __B, | |
| 544 | __U); | |
| 545 | } | |
| 546 | ||
| 547 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 548 | _mm256_shldv_epi16(__m256i __S, __m256i __A, __m256i __B) | |
| 549 | { | |
| 550 | return (__m256i) __builtin_ia32_vpshldvw256_mask ((__v16hi) __S, | |
| 551 | (__v16hi) __A, | |
| 552 | (__v16hi) __B, | |
| 553 | (__mmask16) -1); | |
| 554 | } | |
| 555 | ||
| 556 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 557 | _mm128_mask_shldv_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) | |
| 558 | { | |
| 559 | return (__m128i) __builtin_ia32_vpshldvw128_mask ((__v8hi) __S, | |
| 560 | (__v8hi) __A, | |
| 561 | (__v8hi) __B, | |
| 562 | __U); | |
| 563 | } | |
| 564 | ||
| 565 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 566 | _mm128_maskz_shldv_epi16(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) | |
| 567 | { | |
| 568 | return (__m128i) __builtin_ia32_vpshldvw128_maskz ((__v8hi) __S, | |
| 569 | (__v8hi) __A, | |
| 570 | (__v8hi) __B, | |
| 571 | __U); | |
| 572 | } | |
| 573 | ||
| 574 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 575 | _mm128_shldv_epi16(__m128i __S, __m128i __A, __m128i __B) | |
| 576 | { | |
| 577 | return (__m128i) __builtin_ia32_vpshldvw128_mask ((__v8hi) __S, | |
| 578 | (__v8hi) __A, | |
| 579 | (__v8hi) __B, | |
| 580 | (__mmask8) -1); | |
| 581 | } | |
| 582 | ||
| 583 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 584 | _mm256_mask_shrdv_epi64(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) | |
| 585 | { | |
| 586 | return (__m256i) __builtin_ia32_vpshrdvq256_mask ((__v4di) __S, | |
| 587 | (__v4di) __A, | |
| 588 | (__v4di) __B, | |
| 589 | __U); | |
| 590 | } | |
| 591 | ||
| 592 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 593 | _mm256_maskz_shrdv_epi64(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) | |
| 594 | { | |
| 595 | return (__m256i) __builtin_ia32_vpshrdvq256_maskz ((__v4di) __S, | |
| 596 | (__v4di) __A, | |
| 597 | (__v4di) __B, | |
| 598 | __U); | |
| 599 | } | |
| 600 | ||
| 601 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 602 | _mm256_shrdv_epi64(__m256i __S, __m256i __A, __m256i __B) | |
| 603 | { | |
| 604 | return (__m256i) __builtin_ia32_vpshrdvq256_mask ((__v4di) __S, | |
| 605 | (__v4di) __A, | |
| 606 | (__v4di) __B, | |
| 607 | (__mmask8) -1); | |
| 608 | } | |
| 609 | ||
| 610 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 611 | _mm128_mask_shrdv_epi64(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) | |
| 612 | { | |
| 613 | return (__m128i) __builtin_ia32_vpshrdvq128_mask ((__v2di) __S, | |
| 614 | (__v2di) __A, | |
| 615 | (__v2di) __B, | |
| 616 | __U); | |
| 617 | } | |
| 618 | ||
| 619 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 620 | _mm128_maskz_shrdv_epi64(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) | |
| 621 | { | |
| 622 | return (__m128i) __builtin_ia32_vpshrdvq128_maskz ((__v2di) __S, | |
| 623 | (__v2di) __A, | |
| 624 | (__v2di) __B, | |
| 625 | __U); | |
| 626 | } | |
| 627 | ||
| 628 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 629 | _mm128_shrdv_epi64(__m128i __S, __m128i __A, __m128i __B) | |
| 630 | { | |
| 631 | return (__m128i) __builtin_ia32_vpshrdvq128_mask ((__v2di) __S, | |
| 632 | (__v2di) __A, | |
| 633 | (__v2di) __B, | |
| 634 | (__mmask8) -1); | |
| 635 | } | |
| 636 | ||
| 637 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 638 | _mm256_mask_shrdv_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) | |
| 639 | { | |
| 640 | return (__m256i) __builtin_ia32_vpshrdvd256_mask ((__v8si) __S, | |
| 641 | (__v8si) __A, | |
| 642 | (__v8si) __B, | |
| 643 | __U); | |
| 644 | } | |
| 645 | ||
| 646 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 647 | _mm256_maskz_shrdv_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) | |
| 648 | { | |
| 649 | return (__m256i) __builtin_ia32_vpshrdvd256_maskz ((__v8si) __S, | |
| 650 | (__v8si) __A, | |
| 651 | (__v8si) __B, | |
| 652 | __U); | |
| 653 | } | |
| 654 | ||
| 655 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 656 | _mm256_shrdv_epi32(__m256i __S, __m256i __A, __m256i __B) | |
| 657 | { | |
| 658 | return (__m256i) __builtin_ia32_vpshrdvd256_mask ((__v8si) __S, | |
| 659 | (__v8si) __A, | |
| 660 | (__v8si) __B, | |
| 661 | (__mmask8) -1); | |
| 662 | } | |
| 663 | ||
| 664 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 665 | _mm128_mask_shrdv_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) | |
| 666 | { | |
| 667 | return (__m128i) __builtin_ia32_vpshrdvd128_mask ((__v4si) __S, | |
| 668 | (__v4si) __A, | |
| 669 | (__v4si) __B, | |
| 670 | __U); | |
| 671 | } | |
| 672 | ||
| 673 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 674 | _mm128_maskz_shrdv_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) | |
| 675 | { | |
| 676 | return (__m128i) __builtin_ia32_vpshrdvd128_maskz ((__v4si) __S, | |
| 677 | (__v4si) __A, | |
| 678 | (__v4si) __B, | |
| 679 | __U); | |
| 680 | } | |
| 681 | ||
| 682 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 683 | _mm128_shrdv_epi32(__m128i __S, __m128i __A, __m128i __B) | |
| 684 | { | |
| 685 | return (__m128i) __builtin_ia32_vpshrdvd128_mask ((__v4si) __S, | |
| 686 | (__v4si) __A, | |
| 687 | (__v4si) __B, | |
| 688 | (__mmask8) -1); | |
| 689 | } | |
| 690 | ||
| 691 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 692 | _mm256_mask_shrdv_epi16(__m256i __S, __mmask16 __U, __m256i __A, __m256i __B) | |
| 693 | { | |
| 694 | return (__m256i) __builtin_ia32_vpshrdvw256_mask ((__v16hi) __S, | |
| 695 | (__v16hi) __A, | |
| 696 | (__v16hi) __B, | |
| 697 | __U); | |
| 698 | } | |
| 699 | ||
| 700 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 701 | _mm256_maskz_shrdv_epi16(__mmask16 __U, __m256i __S, __m256i __A, __m256i __B) | |
| 702 | { | |
| 703 | return (__m256i) __builtin_ia32_vpshrdvw256_maskz ((__v16hi) __S, | |
| 704 | (__v16hi) __A, | |
| 705 | (__v16hi) __B, | |
| 706 | __U); | |
| 707 | } | |
| 708 | ||
| 709 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 710 | _mm256_shrdv_epi16(__m256i __S, __m256i __A, __m256i __B) | |
| 711 | { | |
| 712 | return (__m256i) __builtin_ia32_vpshrdvw256_mask ((__v16hi) __S, | |
| 713 | (__v16hi) __A, | |
| 714 | (__v16hi) __B, | |
| 715 | (__mmask16) -1); | |
| 716 | } | |
| 717 | ||
| 718 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 719 | _mm128_mask_shrdv_epi16(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) | |
| 720 | { | |
| 721 | return (__m128i) __builtin_ia32_vpshrdvw128_mask ((__v8hi) __S, | |
| 722 | (__v8hi) __A, | |
| 723 | (__v8hi) __B, | |
| 724 | __U); | |
| 725 | } | |
| 726 | ||
| 727 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 728 | _mm128_maskz_shrdv_epi16(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) | |
| 729 | { | |
| 730 | return (__m128i) __builtin_ia32_vpshrdvw128_maskz ((__v8hi) __S, | |
| 731 | (__v8hi) __A, | |
| 732 | (__v8hi) __B, | |
| 733 | __U); | |
| 734 | } | |
| 735 | ||
| 736 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 737 | _mm128_shrdv_epi16(__m128i __S, __m128i __A, __m128i __B) | |
| 738 | { | |
| 739 | return (__m128i) __builtin_ia32_vpshrdvw128_mask ((__v8hi) __S, | |
| 740 | (__v8hi) __A, | |
| 741 | (__v8hi) __B, | |
| 742 | (__mmask8) -1); | |
| 743 | } | |
| 744 | ||
| 745 | ||
| 746 | #undef __DEFAULT_FN_ATTRS | |
| 747 | ||
| 748 | #endif |
c_headers/avx512vlvnniintrin.h created+254| ... | ... | @@ -0,0 +1,254 @@ |
| 1 | /*===------------- avx512vlvnniintrin.h - VNNI intrinsics ------------------=== | |
| 2 | * | |
| 3 | * | |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 5 | * of this software and associated documentation files (the "Software"), to deal | |
| 6 | * in the Software without restriction, including without limitation the rights | |
| 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 8 | * copies of the Software, and to permit persons to whom the Software is | |
| 9 | * furnished to do so, subject to the following conditions: | |
| 10 | * | |
| 11 | * The above copyright notice and this permission notice shall be included in | |
| 12 | * all copies or substantial portions of the Software. | |
| 13 | * | |
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 20 | * THE SOFTWARE. | |
| 21 | * | |
| 22 | *===-----------------------------------------------------------------------=== | |
| 23 | */ | |
| 24 | #ifndef __IMMINTRIN_H | |
| 25 | #error "Never use <avx512vlvnniintrin.h> directly; include <immintrin.h> instead." | |
| 26 | #endif | |
| 27 | ||
| 28 | #ifndef __AVX512VLVNNIINTRIN_H | |
| 29 | #define __AVX512VLVNNIINTRIN_H | |
| 30 | ||
| 31 | /* Define the default attributes for the functions in this file. */ | |
| 32 | #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512vl,avx512vnni"))) | |
| 33 | ||
| 34 | ||
| 35 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 36 | _mm256_mask_dpbusd_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) | |
| 37 | { | |
| 38 | return (__m256i) __builtin_ia32_vpdpbusd256_mask ((__v8si) __S, | |
| 39 | (__v8si) __A, | |
| 40 | (__v8si) __B, | |
| 41 | (__mmask8) __U); | |
| 42 | } | |
| 43 | ||
| 44 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 45 | _mm256_maskz_dpbusd_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) | |
| 46 | { | |
| 47 | return (__m256i) __builtin_ia32_vpdpbusd256_maskz ((__v8si) __S, | |
| 48 | (__v8si) __A, | |
| 49 | (__v8si) __B, | |
| 50 | (__mmask8) __U); | |
| 51 | } | |
| 52 | ||
| 53 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 54 | _mm256_dpbusd_epi32(__m256i __S, __m256i __A, __m256i __B) | |
| 55 | { | |
| 56 | return (__m256i) __builtin_ia32_vpdpbusd256_mask ((__v8si) __S, | |
| 57 | (__v8si) __A, | |
| 58 | (__v8si) __B, | |
| 59 | (__mmask8) -1); | |
| 60 | } | |
| 61 | ||
| 62 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 63 | _mm256_mask_dpbusds_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) | |
| 64 | { | |
| 65 | return (__m256i) __builtin_ia32_vpdpbusds256_mask ((__v8si) __S, | |
| 66 | (__v8si) __A, | |
| 67 | (__v8si) __B, | |
| 68 | (__mmask8) __U); | |
| 69 | } | |
| 70 | ||
| 71 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 72 | _mm256_maskz_dpbusds_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) | |
| 73 | { | |
| 74 | return (__m256i) __builtin_ia32_vpdpbusds256_maskz ((__v8si) __S, | |
| 75 | (__v8si) __A, | |
| 76 | (__v8si) __B, | |
| 77 | (__mmask8) __U); | |
| 78 | } | |
| 79 | ||
| 80 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 81 | _mm256_dpbusds_epi32(__m256i __S, __m256i __A, __m256i __B) | |
| 82 | { | |
| 83 | return (__m256i) __builtin_ia32_vpdpbusds256_mask ((__v8si) __S, | |
| 84 | (__v8si) __A, | |
| 85 | (__v8si) __B, | |
| 86 | (__mmask8) -1); | |
| 87 | } | |
| 88 | ||
| 89 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 90 | _mm256_mask_dpwssd_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) | |
| 91 | { | |
| 92 | return (__m256i) __builtin_ia32_vpdpwssd256_mask ((__v8si) __S, | |
| 93 | (__v8si) __A, | |
| 94 | (__v8si) __B, | |
| 95 | (__mmask8) __U); | |
| 96 | } | |
| 97 | ||
| 98 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 99 | _mm256_maskz_dpwssd_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) | |
| 100 | { | |
| 101 | return (__m256i) __builtin_ia32_vpdpwssd256_maskz ((__v8si) __S, | |
| 102 | (__v8si) __A, | |
| 103 | (__v8si) __B, | |
| 104 | (__mmask8) __U); | |
| 105 | } | |
| 106 | ||
| 107 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 108 | _mm256_dpwssd_epi32(__m256i __S, __m256i __A, __m256i __B) | |
| 109 | { | |
| 110 | return (__m256i) __builtin_ia32_vpdpwssd256_mask ((__v8si) __S, | |
| 111 | (__v8si) __A, | |
| 112 | (__v8si) __B, | |
| 113 | (__mmask8) -1); | |
| 114 | } | |
| 115 | ||
| 116 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 117 | _mm256_mask_dpwssds_epi32(__m256i __S, __mmask8 __U, __m256i __A, __m256i __B) | |
| 118 | { | |
| 119 | return (__m256i) __builtin_ia32_vpdpwssds256_mask ((__v8si) __S, | |
| 120 | (__v8si) __A, | |
| 121 | (__v8si) __B, | |
| 122 | (__mmask8) __U); | |
| 123 | } | |
| 124 | ||
| 125 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 126 | _mm256_maskz_dpwssds_epi32(__mmask8 __U, __m256i __S, __m256i __A, __m256i __B) | |
| 127 | { | |
| 128 | return (__m256i) __builtin_ia32_vpdpwssds256_maskz ((__v8si) __S, | |
| 129 | (__v8si) __A, | |
| 130 | (__v8si) __B, | |
| 131 | (__mmask8) __U); | |
| 132 | } | |
| 133 | ||
| 134 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 135 | _mm256_dpwssds_epi32(__m256i __S, __m256i __A, __m256i __B) | |
| 136 | { | |
| 137 | return (__m256i) __builtin_ia32_vpdpwssds256_mask ((__v8si) __S, | |
| 138 | (__v8si) __A, | |
| 139 | (__v8si) __B, | |
| 140 | (__mmask8) -1); | |
| 141 | } | |
| 142 | ||
| 143 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 144 | _mm128_mask_dpbusd_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) | |
| 145 | { | |
| 146 | return (__m128i) __builtin_ia32_vpdpbusd128_mask ((__v4si) __S, | |
| 147 | (__v4si) __A, | |
| 148 | (__v4si) __B, | |
| 149 | (__mmask8) __U); | |
| 150 | } | |
| 151 | ||
| 152 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 153 | _mm128_maskz_dpbusd_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) | |
| 154 | { | |
| 155 | return (__m128i) __builtin_ia32_vpdpbusd128_maskz ((__v4si) __S, | |
| 156 | (__v4si) __A, | |
| 157 | (__v4si) __B, | |
| 158 | (__mmask8) __U); | |
| 159 | } | |
| 160 | ||
| 161 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 162 | _mm128_dpbusd_epi32(__m128i __S, __m128i __A, __m128i __B) | |
| 163 | { | |
| 164 | return (__m128i) __builtin_ia32_vpdpbusd128_mask ((__v4si) __S, | |
| 165 | (__v4si) __A, | |
| 166 | (__v4si) __B, | |
| 167 | (__mmask8) -1); | |
| 168 | } | |
| 169 | ||
| 170 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 171 | _mm128_mask_dpbusds_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) | |
| 172 | { | |
| 173 | return (__m128i) __builtin_ia32_vpdpbusds128_mask ((__v4si) __S, | |
| 174 | (__v4si) __A, | |
| 175 | (__v4si) __B, | |
| 176 | (__mmask8) __U); | |
| 177 | } | |
| 178 | ||
| 179 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 180 | _mm128_maskz_dpbusds_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) | |
| 181 | { | |
| 182 | return (__m128i) __builtin_ia32_vpdpbusds128_maskz ((__v4si) __S, | |
| 183 | (__v4si) __A, | |
| 184 | (__v4si) __B, | |
| 185 | (__mmask8) __U); | |
| 186 | } | |
| 187 | ||
| 188 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 189 | _mm128_dpbusds_epi32(__m128i __S, __m128i __A, __m128i __B) | |
| 190 | { | |
| 191 | return (__m128i) __builtin_ia32_vpdpbusds128_mask ((__v4si) __S, | |
| 192 | (__v4si) __A, | |
| 193 | (__v4si) __B, | |
| 194 | (__mmask8) -1); | |
| 195 | } | |
| 196 | ||
| 197 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 198 | _mm128_mask_dpwssd_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) | |
| 199 | { | |
| 200 | return (__m128i) __builtin_ia32_vpdpwssd128_mask ((__v4si) __S, | |
| 201 | (__v4si) __A, | |
| 202 | (__v4si) __B, | |
| 203 | (__mmask8) __U); | |
| 204 | } | |
| 205 | ||
| 206 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 207 | _mm128_maskz_dpwssd_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) | |
| 208 | { | |
| 209 | return (__m128i) __builtin_ia32_vpdpwssd128_maskz ((__v4si) __S, | |
| 210 | (__v4si) __A, | |
| 211 | (__v4si) __B, | |
| 212 | (__mmask8) __U); | |
| 213 | } | |
| 214 | ||
| 215 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 216 | _mm128_dpwssd_epi32(__m128i __S, __m128i __A, __m128i __B) | |
| 217 | { | |
| 218 | return (__m128i) __builtin_ia32_vpdpwssd128_mask ((__v4si) __S, | |
| 219 | (__v4si) __A, | |
| 220 | (__v4si) __B, | |
| 221 | (__mmask8) -1); | |
| 222 | } | |
| 223 | ||
| 224 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 225 | _mm128_mask_dpwssds_epi32(__m128i __S, __mmask8 __U, __m128i __A, __m128i __B) | |
| 226 | { | |
| 227 | return (__m128i) __builtin_ia32_vpdpwssds128_mask ((__v4si) __S, | |
| 228 | (__v4si) __A, | |
| 229 | (__v4si) __B, | |
| 230 | (__mmask8) __U); | |
| 231 | } | |
| 232 | ||
| 233 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 234 | _mm128_maskz_dpwssds_epi32(__mmask8 __U, __m128i __S, __m128i __A, __m128i __B) | |
| 235 | { | |
| 236 | return (__m128i) __builtin_ia32_vpdpwssds128_maskz ((__v4si) __S, | |
| 237 | (__v4si) __A, | |
| 238 | (__v4si) __B, | |
| 239 | (__mmask8) __U); | |
| 240 | } | |
| 241 | ||
| 242 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 243 | _mm128_dpwssds_epi32(__m128i __S, __m128i __A, __m128i __B) | |
| 244 | { | |
| 245 | return (__m128i) __builtin_ia32_vpdpwssds128_mask ((__v4si) __S, | |
| 246 | (__v4si) __A, | |
| 247 | (__v4si) __B, | |
| 248 | (__mmask8) -1); | |
| 249 | } | |
| 250 | ||
| 251 | ||
| 252 | #undef __DEFAULT_FN_ATTRS | |
| 253 | ||
| 254 | #endif |
c_headers/avx512vnniintrin.h created+146| ... | ... | @@ -0,0 +1,146 @@ |
| 1 | /*===------------- avx512vnniintrin.h - VNNI intrinsics ------------------=== | |
| 2 | * | |
| 3 | * | |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 5 | * of this software and associated documentation files (the "Software"), to deal | |
| 6 | * in the Software without restriction, including without limitation the rights | |
| 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 8 | * copies of the Software, and to permit persons to whom the Software is | |
| 9 | * furnished to do so, subject to the following conditions: | |
| 10 | * | |
| 11 | * The above copyright notice and this permission notice shall be included in | |
| 12 | * all copies or substantial portions of the Software. | |
| 13 | * | |
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 20 | * THE SOFTWARE. | |
| 21 | * | |
| 22 | *===-----------------------------------------------------------------------=== | |
| 23 | */ | |
| 24 | #ifndef __IMMINTRIN_H | |
| 25 | #error "Never use <avx512vnniintrin.h> directly; include <immintrin.h> instead." | |
| 26 | #endif | |
| 27 | ||
| 28 | #ifndef __AVX512VNNIINTRIN_H | |
| 29 | #define __AVX512VNNIINTRIN_H | |
| 30 | ||
| 31 | /* Define the default attributes for the functions in this file. */ | |
| 32 | #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512vnni"))) | |
| 33 | ||
| 34 | ||
| 35 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 36 | _mm512_mask_dpbusd_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) | |
| 37 | { | |
| 38 | return (__m512i) __builtin_ia32_vpdpbusd512_mask ((__v16si) __S, | |
| 39 | (__v16si) __A, | |
| 40 | (__v16si) __B, | |
| 41 | (__mmask16) __U); | |
| 42 | } | |
| 43 | ||
| 44 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 45 | _mm512_maskz_dpbusd_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B) | |
| 46 | { | |
| 47 | return (__m512i) __builtin_ia32_vpdpbusd512_maskz ((__v16si) __S, | |
| 48 | (__v16si) __A, | |
| 49 | (__v16si) __B, | |
| 50 | (__mmask16) __U); | |
| 51 | } | |
| 52 | ||
| 53 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 54 | _mm512_dpbusd_epi32(__m512i __S, __m512i __A, __m512i __B) | |
| 55 | { | |
| 56 | return (__m512i) __builtin_ia32_vpdpbusd512_mask ((__v16si) __S, | |
| 57 | (__v16si) __A, | |
| 58 | (__v16si) __B, | |
| 59 | (__mmask16) -1); | |
| 60 | } | |
| 61 | ||
| 62 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 63 | _mm512_mask_dpbusds_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) | |
| 64 | { | |
| 65 | return (__m512i) __builtin_ia32_vpdpbusds512_mask ((__v16si) __S, | |
| 66 | (__v16si) __A, | |
| 67 | (__v16si) __B, | |
| 68 | (__mmask16) __U); | |
| 69 | } | |
| 70 | ||
| 71 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 72 | _mm512_maskz_dpbusds_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B) | |
| 73 | { | |
| 74 | return (__m512i) __builtin_ia32_vpdpbusds512_maskz ((__v16si) __S, | |
| 75 | (__v16si) __A, | |
| 76 | (__v16si) __B, | |
| 77 | (__mmask16) __U); | |
| 78 | } | |
| 79 | ||
| 80 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 81 | _mm512_dpbusds_epi32(__m512i __S, __m512i __A, __m512i __B) | |
| 82 | { | |
| 83 | return (__m512i) __builtin_ia32_vpdpbusds512_mask ((__v16si) __S, | |
| 84 | (__v16si) __A, | |
| 85 | (__v16si) __B, | |
| 86 | (__mmask16) -1); | |
| 87 | } | |
| 88 | ||
| 89 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 90 | _mm512_mask_dpwssd_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) | |
| 91 | { | |
| 92 | return (__m512i) __builtin_ia32_vpdpwssd512_mask ((__v16si) __S, | |
| 93 | (__v16si) __A, | |
| 94 | (__v16si) __B, | |
| 95 | (__mmask16) __U); | |
| 96 | } | |
| 97 | ||
| 98 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 99 | _mm512_maskz_dpwssd_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B) | |
| 100 | { | |
| 101 | return (__m512i) __builtin_ia32_vpdpwssd512_maskz ((__v16si) __S, | |
| 102 | (__v16si) __A, | |
| 103 | (__v16si) __B, | |
| 104 | (__mmask16) __U); | |
| 105 | } | |
| 106 | ||
| 107 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 108 | _mm512_dpwssd_epi32(__m512i __S, __m512i __A, __m512i __B) | |
| 109 | { | |
| 110 | return (__m512i) __builtin_ia32_vpdpwssd512_mask ((__v16si) __S, | |
| 111 | (__v16si) __A, | |
| 112 | (__v16si) __B, | |
| 113 | (__mmask16) -1); | |
| 114 | } | |
| 115 | ||
| 116 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 117 | _mm512_mask_dpwssds_epi32(__m512i __S, __mmask16 __U, __m512i __A, __m512i __B) | |
| 118 | { | |
| 119 | return (__m512i) __builtin_ia32_vpdpwssds512_mask ((__v16si) __S, | |
| 120 | (__v16si) __A, | |
| 121 | (__v16si) __B, | |
| 122 | (__mmask16) __U); | |
| 123 | } | |
| 124 | ||
| 125 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 126 | _mm512_maskz_dpwssds_epi32(__mmask16 __U, __m512i __S, __m512i __A, __m512i __B) | |
| 127 | { | |
| 128 | return (__m512i) __builtin_ia32_vpdpwssds512_maskz ((__v16si) __S, | |
| 129 | (__v16si) __A, | |
| 130 | (__v16si) __B, | |
| 131 | (__mmask16) __U); | |
| 132 | } | |
| 133 | ||
| 134 | static __inline__ __m512i __DEFAULT_FN_ATTRS | |
| 135 | _mm512_dpwssds_epi32(__m512i __S, __m512i __A, __m512i __B) | |
| 136 | { | |
| 137 | return (__m512i) __builtin_ia32_vpdpwssds512_mask ((__v16si) __S, | |
| 138 | (__v16si) __A, | |
| 139 | (__v16si) __B, | |
| 140 | (__mmask16) -1); | |
| 141 | } | |
| 142 | ||
| 143 | ||
| 144 | #undef __DEFAULT_FN_ATTRS | |
| 145 | ||
| 146 | #endif |
c_headers/avx512vpopcntdqvlintrin.h created+99| ... | ... | @@ -0,0 +1,99 @@ |
| 1 | /*===------------- avx512vpopcntdqintrin.h - AVX512VPOPCNTDQ intrinsics | |
| 2 | *------------------=== | |
| 3 | * | |
| 4 | * | |
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 6 | * of this software and associated documentation files (the "Software"), to deal | |
| 7 | * in the Software without restriction, including without limitation the rights | |
| 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 9 | * copies of the Software, and to permit persons to whom the Software is | |
| 10 | * furnished to do so, subject to the following conditions: | |
| 11 | * | |
| 12 | * The above copyright notice and this permission notice shall be included in | |
| 13 | * all copies or substantial portions of the Software. | |
| 14 | * | |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 21 | * THE SOFTWARE. | |
| 22 | * | |
| 23 | *===-----------------------------------------------------------------------=== | |
| 24 | */ | |
| 25 | #ifndef __IMMINTRIN_H | |
| 26 | #error \ | |
| 27 | "Never use <avx512vpopcntdqvlintrin.h> directly; include <immintrin.h> instead." | |
| 28 | #endif | |
| 29 | ||
| 30 | #ifndef __AVX512VPOPCNTDQVLINTRIN_H | |
| 31 | #define __AVX512VPOPCNTDQVLINTRIN_H | |
| 32 | ||
| 33 | /* Define the default attributes for the functions in this file. */ | |
| 34 | #define __DEFAULT_FN_ATTRS \ | |
| 35 | __attribute__((__always_inline__, __nodebug__, __target__("avx512vpopcntdq,avx512vl"))) | |
| 36 | ||
| 37 | static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_popcnt_epi64(__m128i __A) { | |
| 38 | return (__m128i)__builtin_ia32_vpopcntq_128((__v2di)__A); | |
| 39 | } | |
| 40 | ||
| 41 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 42 | _mm_mask_popcnt_epi64(__m128i __W, __mmask8 __U, __m128i __A) { | |
| 43 | return (__m128i)__builtin_ia32_selectq_128( | |
| 44 | (__mmask8)__U, (__v2di)_mm_popcnt_epi64(__A), (__v2di)__W); | |
| 45 | } | |
| 46 | ||
| 47 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 48 | _mm_maskz_popcnt_epi64(__mmask8 __U, __m128i __A) { | |
| 49 | return _mm_mask_popcnt_epi64((__m128i)_mm_setzero_si128(), __U, __A); | |
| 50 | } | |
| 51 | ||
| 52 | static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_popcnt_epi32(__m128i __A) { | |
| 53 | return (__m128i)__builtin_ia32_vpopcntd_128((__v4si)__A); | |
| 54 | } | |
| 55 | ||
| 56 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 57 | _mm_mask_popcnt_epi32(__m128i __W, __mmask8 __U, __m128i __A) { | |
| 58 | return (__m128i)__builtin_ia32_selectd_128( | |
| 59 | (__mmask8)__U, (__v4si)_mm_popcnt_epi32(__A), (__v4si)__W); | |
| 60 | } | |
| 61 | ||
| 62 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 63 | _mm_maskz_popcnt_epi32(__mmask8 __U, __m128i __A) { | |
| 64 | return _mm_mask_popcnt_epi32((__m128i)_mm_setzero_si128(), __U, __A); | |
| 65 | } | |
| 66 | ||
| 67 | static __inline__ __m256i __DEFAULT_FN_ATTRS _mm256_popcnt_epi64(__m256i __A) { | |
| 68 | return (__m256i)__builtin_ia32_vpopcntq_256((__v4di)__A); | |
| 69 | } | |
| 70 | ||
| 71 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 72 | _mm256_mask_popcnt_epi64(__m256i __W, __mmask8 __U, __m256i __A) { | |
| 73 | return (__m256i)__builtin_ia32_selectq_256( | |
| 74 | (__mmask8)__U, (__v4di)_mm256_popcnt_epi64(__A), (__v4di)__W); | |
| 75 | } | |
| 76 | ||
| 77 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 78 | _mm256_maskz_popcnt_epi64(__mmask8 __U, __m256i __A) { | |
| 79 | return _mm256_mask_popcnt_epi64((__m256i)_mm256_setzero_si256(), __U, __A); | |
| 80 | } | |
| 81 | ||
| 82 | static __inline__ __m256i __DEFAULT_FN_ATTRS _mm256_popcnt_epi32(__m256i __A) { | |
| 83 | return (__m256i)__builtin_ia32_vpopcntd_256((__v8si)__A); | |
| 84 | } | |
| 85 | ||
| 86 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 87 | _mm256_mask_popcnt_epi32(__m256i __W, __mmask8 __U, __m256i __A) { | |
| 88 | return (__m256i)__builtin_ia32_selectd_256( | |
| 89 | (__mmask8)__U, (__v8si)_mm256_popcnt_epi32(__A), (__v8si)__W); | |
| 90 | } | |
| 91 | ||
| 92 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 93 | _mm256_maskz_popcnt_epi32(__mmask8 __U, __m256i __A) { | |
| 94 | return _mm256_mask_popcnt_epi32((__m256i)_mm256_setzero_si256(), __U, __A); | |
| 95 | } | |
| 96 | ||
| 97 | #undef __DEFAULT_FN_ATTRS | |
| 98 | ||
| 99 | #endif |
c_headers/cetintrin.h created+93| ... | ... | @@ -0,0 +1,93 @@ |
| 1 | /*===---- cetintrin.h - CET intrinsic ------------------------------------=== | |
| 2 | * | |
| 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 4 | * of this software and associated documentation files (the "Software"), to deal | |
| 5 | * in the Software without restriction, including without limitation the rights | |
| 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 7 | * copies of the Software, and to permit persons to whom the Software is | |
| 8 | * furnished to do so, subject to the following conditions: | |
| 9 | * | |
| 10 | * The above copyright notice and this permission notice shall be included in | |
| 11 | * all copies or substantial portions of the Software. | |
| 12 | * | |
| 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 19 | * THE SOFTWARE. | |
| 20 | * | |
| 21 | *===-----------------------------------------------------------------------=== | |
| 22 | */ | |
| 23 | ||
| 24 | #ifndef __IMMINTRIN_H | |
| 25 | #error "Never use <cetintrin.h> directly; include <immintrin.h> instead." | |
| 26 | #endif | |
| 27 | ||
| 28 | #ifndef __CETINTRIN_H | |
| 29 | #define __CETINTRIN_H | |
| 30 | ||
| 31 | /* Define the default attributes for the functions in this file. */ | |
| 32 | #define __DEFAULT_FN_ATTRS \ | |
| 33 | __attribute__((__always_inline__, __nodebug__, __target__("shstk"))) | |
| 34 | ||
| 35 | static __inline__ void __DEFAULT_FN_ATTRS _incsspd(int __a) { | |
| 36 | __builtin_ia32_incsspd(__a); | |
| 37 | } | |
| 38 | ||
| 39 | #ifdef __x86_64__ | |
| 40 | static __inline__ void __DEFAULT_FN_ATTRS _incsspq(unsigned long long __a) { | |
| 41 | __builtin_ia32_incsspq(__a); | |
| 42 | } | |
| 43 | #endif /* __x86_64__ */ | |
| 44 | ||
| 45 | static __inline__ unsigned int __DEFAULT_FN_ATTRS _rdsspd(unsigned int __a) { | |
| 46 | return __builtin_ia32_rdsspd(__a); | |
| 47 | } | |
| 48 | ||
| 49 | #ifdef __x86_64__ | |
| 50 | static __inline__ unsigned long long __DEFAULT_FN_ATTRS _rdsspq(unsigned long long __a) { | |
| 51 | return __builtin_ia32_rdsspq(__a); | |
| 52 | } | |
| 53 | #endif /* __x86_64__ */ | |
| 54 | ||
| 55 | static __inline__ void __DEFAULT_FN_ATTRS _saveprevssp() { | |
| 56 | __builtin_ia32_saveprevssp(); | |
| 57 | } | |
| 58 | ||
| 59 | static __inline__ void __DEFAULT_FN_ATTRS _rstorssp(void * __p) { | |
| 60 | __builtin_ia32_rstorssp(__p); | |
| 61 | } | |
| 62 | ||
| 63 | static __inline__ void __DEFAULT_FN_ATTRS _wrssd(unsigned int __a, void * __p) { | |
| 64 | __builtin_ia32_wrssd(__a, __p); | |
| 65 | } | |
| 66 | ||
| 67 | #ifdef __x86_64__ | |
| 68 | static __inline__ void __DEFAULT_FN_ATTRS _wrssq(unsigned long long __a, void * __p) { | |
| 69 | __builtin_ia32_wrssq(__a, __p); | |
| 70 | } | |
| 71 | #endif /* __x86_64__ */ | |
| 72 | ||
| 73 | static __inline__ void __DEFAULT_FN_ATTRS _wrussd(unsigned int __a, void * __p) { | |
| 74 | __builtin_ia32_wrussd(__a, __p); | |
| 75 | } | |
| 76 | ||
| 77 | #ifdef __x86_64__ | |
| 78 | static __inline__ void __DEFAULT_FN_ATTRS _wrussq(unsigned long long __a, void * __p) { | |
| 79 | __builtin_ia32_wrussq(__a, __p); | |
| 80 | } | |
| 81 | #endif /* __x86_64__ */ | |
| 82 | ||
| 83 | static __inline__ void __DEFAULT_FN_ATTRS _setssbsy() { | |
| 84 | __builtin_ia32_setssbsy(); | |
| 85 | } | |
| 86 | ||
| 87 | static __inline__ void __DEFAULT_FN_ATTRS _clrssbsy(void * __p) { | |
| 88 | __builtin_ia32_clrssbsy(__p); | |
| 89 | } | |
| 90 | ||
| 91 | #undef __DEFAULT_FN_ATTRS | |
| 92 | ||
| 93 | #endif /* __CETINTRIN_H */ |
c_headers/clflushoptintrin.h+1-1| ... | ... | @@ -32,7 +32,7 @@ |
| 32 | 32 | #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("clflushopt"))) |
| 33 | 33 | |
| 34 | 34 | static __inline__ void __DEFAULT_FN_ATTRS |
| 35 | _mm_clflushopt(char * __m) { | |
| 35 | _mm_clflushopt(void const * __m) { | |
| 36 | 36 | __builtin_ia32_clflushopt(__m); |
| 37 | 37 | } |
| 38 | 38 |
c_headers/clwbintrin.h created+52| ... | ... | @@ -0,0 +1,52 @@ |
| 1 | /*===---- clwbintrin.h - CLWB intrinsic ------------------------------------=== | |
| 2 | * | |
| 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 4 | * of this software and associated documentation files (the "Software"), to deal | |
| 5 | * in the Software without restriction, including without limitation the rights | |
| 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 7 | * copies of the Software, and to permit persons to whom the Software is | |
| 8 | * furnished to do so, subject to the following conditions: | |
| 9 | * | |
| 10 | * The above copyright notice and this permission notice shall be included in | |
| 11 | * all copies or substantial portions of the Software. | |
| 12 | * | |
| 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 19 | * THE SOFTWARE. | |
| 20 | * | |
| 21 | *===-----------------------------------------------------------------------=== | |
| 22 | */ | |
| 23 | ||
| 24 | #ifndef __IMMINTRIN_H | |
| 25 | #error "Never use <clwbintrin.h> directly; include <immintrin.h> instead." | |
| 26 | #endif | |
| 27 | ||
| 28 | #ifndef __CLWBINTRIN_H | |
| 29 | #define __CLWBINTRIN_H | |
| 30 | ||
| 31 | /* Define the default attributes for the functions in this file. */ | |
| 32 | #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("clwb"))) | |
| 33 | ||
| 34 | /// \brief Writes back to memory the cache line (if modified) that contains the | |
| 35 | /// linear address specified in \a __p from any level of the cache hierarchy in | |
| 36 | /// the cache coherence domain | |
| 37 | /// | |
| 38 | /// \headerfile <immintrin.h> | |
| 39 | /// | |
| 40 | /// This intrinsic corresponds to the <c> CLWB </c> instruction. | |
| 41 | /// | |
| 42 | /// \param __p | |
| 43 | /// A pointer to the memory location used to identify the cache line to be | |
| 44 | /// written back. | |
| 45 | static __inline__ void __DEFAULT_FN_ATTRS | |
| 46 | _mm_clwb(void const *__p) { | |
| 47 | __builtin_ia32_clwb(__p); | |
| 48 | } | |
| 49 | ||
| 50 | #undef __DEFAULT_FN_ATTRS | |
| 51 | ||
| 52 | #endif |
c_headers/cpuid.h+14-5| ... | ... | @@ -173,16 +173,24 @@ |
| 173 | 173 | #define bit_AVX512VL 0x80000000 |
| 174 | 174 | |
| 175 | 175 | /* Features in %ecx for leaf 7 sub-leaf 0 */ |
| 176 | #define bit_PREFTCHWT1 0x00000001 | |
| 177 | #define bit_AVX512VBMI 0x00000002 | |
| 178 | #define bit_PKU 0x00000004 | |
| 179 | #define bit_OSPKE 0x00000010 | |
| 176 | #define bit_PREFTCHWT1 0x00000001 | |
| 177 | #define bit_AVX512VBMI 0x00000002 | |
| 178 | #define bit_PKU 0x00000004 | |
| 179 | #define bit_OSPKE 0x00000010 | |
| 180 | #define bit_AVX512VBMI2 0x00000040 | |
| 181 | #define bit_SHSTK 0x00000080 | |
| 182 | #define bit_GFNI 0x00000100 | |
| 183 | #define bit_VAES 0x00000200 | |
| 184 | #define bit_VPCLMULQDQ 0x00000400 | |
| 185 | #define bit_AVX512VNNI 0x00000800 | |
| 186 | #define bit_AVX512BITALG 0x00001000 | |
| 180 | 187 | #define bit_AVX512VPOPCNTDQ 0x00004000 |
| 181 | #define bit_RDPID 0x00400000 | |
| 188 | #define bit_RDPID 0x00400000 | |
| 182 | 189 | |
| 183 | 190 | /* Features in %edx for leaf 7 sub-leaf 0 */ |
| 184 | 191 | #define bit_AVX5124VNNIW 0x00000004 |
| 185 | 192 | #define bit_AVX5124FMAPS 0x00000008 |
| 193 | #define bit_IBT 0x00100000 | |
| 186 | 194 | |
| 187 | 195 | /* Features in %eax for leaf 13 sub-leaf 1 */ |
| 188 | 196 | #define bit_XSAVEOPT 0x00000001 |
| ... | ... | @@ -192,6 +200,7 @@ |
| 192 | 200 | /* Features in %ecx for leaf 0x80000001 */ |
| 193 | 201 | #define bit_LAHF_LM 0x00000001 |
| 194 | 202 | #define bit_ABM 0x00000020 |
| 203 | #define bit_LZCNT bit_ABM /* for gcc compat */ | |
| 195 | 204 | #define bit_SSE4a 0x00000040 |
| 196 | 205 | #define bit_PRFCHW 0x00000100 |
| 197 | 206 | #define bit_XOP 0x00000800 |
c_headers/cuda_wrappers/algorithm+1-1| ... | ... | @@ -80,7 +80,7 @@ min(const __T &__a, const __T &__b, __Cmp __cmp) { |
| 80 | 80 | template <class __T> |
| 81 | 81 | inline __device__ const __T & |
| 82 | 82 | min(const __T &__a, const __T &__b) { |
| 83 | return __a < __b ? __b : __a; | |
| 83 | return __a < __b ? __a : __b; | |
| 84 | 84 | } |
| 85 | 85 | |
| 86 | 86 | #ifdef _LIBCPP_END_NAMESPACE_STD |
c_headers/cuda_wrappers/new+50-1| ... | ... | @@ -26,7 +26,6 @@ |
| 26 | 26 | |
| 27 | 27 | #include_next <new> |
| 28 | 28 | |
| 29 | // Device overrides for placement new and delete. | |
| 30 | 29 | #pragma push_macro("CUDA_NOEXCEPT") |
| 31 | 30 | #if __cplusplus >= 201103L |
| 32 | 31 | #define CUDA_NOEXCEPT noexcept |
| ... | ... | @@ -34,6 +33,55 @@ |
| 34 | 33 | #define CUDA_NOEXCEPT |
| 35 | 34 | #endif |
| 36 | 35 | |
| 36 | // Device overrides for non-placement new and delete. | |
| 37 | __device__ inline void *operator new(__SIZE_TYPE__ size) { | |
| 38 | if (size == 0) { | |
| 39 | size = 1; | |
| 40 | } | |
| 41 | return ::malloc(size); | |
| 42 | } | |
| 43 | __device__ inline void *operator new(__SIZE_TYPE__ size, | |
| 44 | const std::nothrow_t &) CUDA_NOEXCEPT { | |
| 45 | return ::operator new(size); | |
| 46 | } | |
| 47 | ||
| 48 | __device__ inline void *operator new[](__SIZE_TYPE__ size) { | |
| 49 | return ::operator new(size); | |
| 50 | } | |
| 51 | __device__ inline void *operator new[](__SIZE_TYPE__ size, | |
| 52 | const std::nothrow_t &) { | |
| 53 | return ::operator new(size); | |
| 54 | } | |
| 55 | ||
| 56 | __device__ inline void operator delete(void* ptr) CUDA_NOEXCEPT { | |
| 57 | if (ptr) { | |
| 58 | ::free(ptr); | |
| 59 | } | |
| 60 | } | |
| 61 | __device__ inline void operator delete(void *ptr, | |
| 62 | const std::nothrow_t &) CUDA_NOEXCEPT { | |
| 63 | ::operator delete(ptr); | |
| 64 | } | |
| 65 | ||
| 66 | __device__ inline void operator delete[](void* ptr) CUDA_NOEXCEPT { | |
| 67 | ::operator delete(ptr); | |
| 68 | } | |
| 69 | __device__ inline void operator delete[](void *ptr, | |
| 70 | const std::nothrow_t &) CUDA_NOEXCEPT { | |
| 71 | ::operator delete(ptr); | |
| 72 | } | |
| 73 | ||
| 74 | // Sized delete, C++14 only. | |
| 75 | #if __cplusplus >= 201402L | |
| 76 | __device__ void operator delete(void *ptr, __SIZE_TYPE__ size) CUDA_NOEXCEPT { | |
| 77 | ::operator delete(ptr); | |
| 78 | } | |
| 79 | __device__ void operator delete[](void *ptr, __SIZE_TYPE__ size) CUDA_NOEXCEPT { | |
| 80 | ::operator delete(ptr); | |
| 81 | } | |
| 82 | #endif | |
| 83 | ||
| 84 | // Device overrides for placement new and delete. | |
| 37 | 85 | __device__ inline void *operator new(__SIZE_TYPE__, void *__ptr) CUDA_NOEXCEPT { |
| 38 | 86 | return __ptr; |
| 39 | 87 | } |
| ... | ... | @@ -42,6 +90,7 @@ __device__ inline void *operator new[](__SIZE_TYPE__, void *__ptr) CUDA_NOEXCEPT |
| 42 | 90 | } |
| 43 | 91 | __device__ inline void operator delete(void *, void *) CUDA_NOEXCEPT {} |
| 44 | 92 | __device__ inline void operator delete[](void *, void *) CUDA_NOEXCEPT {} |
| 93 | ||
| 45 | 94 | #pragma pop_macro("CUDA_NOEXCEPT") |
| 46 | 95 | |
| 47 | 96 | #endif // include guard |
c_headers/emmintrin.h+73-50| ... | ... | @@ -217,8 +217,8 @@ _mm_div_pd(__m128d __a, __m128d __b) |
| 217 | 217 | |
| 218 | 218 | /// \brief Calculates the square root of the lower double-precision value of |
| 219 | 219 | /// the second operand and returns it in the lower 64 bits of the result. |
| 220 | /// The upper 64 bits of the result are copied from the upper double- | |
| 221 | /// precision value of the first operand. | |
| 220 | /// The upper 64 bits of the result are copied from the upper | |
| 221 | /// double-precision value of the first operand. | |
| 222 | 222 | /// |
| 223 | 223 | /// \headerfile <x86intrin.h> |
| 224 | 224 | /// |
| ... | ... | @@ -260,8 +260,8 @@ _mm_sqrt_pd(__m128d __a) |
| 260 | 260 | |
| 261 | 261 | /// \brief Compares lower 64-bit double-precision values of both operands, and |
| 262 | 262 | /// returns the lesser of the pair of values in the lower 64-bits of the |
| 263 | /// result. The upper 64 bits of the result are copied from the upper double- | |
| 264 | /// precision value of the first operand. | |
| 263 | /// result. The upper 64 bits of the result are copied from the upper | |
| 264 | /// double-precision value of the first operand. | |
| 265 | 265 | /// |
| 266 | 266 | /// \headerfile <x86intrin.h> |
| 267 | 267 | /// |
| ... | ... | @@ -304,8 +304,8 @@ _mm_min_pd(__m128d __a, __m128d __b) |
| 304 | 304 | |
| 305 | 305 | /// \brief Compares lower 64-bit double-precision values of both operands, and |
| 306 | 306 | /// returns the greater of the pair of values in the lower 64-bits of the |
| 307 | /// result. The upper 64 bits of the result are copied from the upper double- | |
| 308 | /// precision value of the first operand. | |
| 307 | /// result. The upper 64 bits of the result are copied from the upper | |
| 308 | /// double-precision value of the first operand. | |
| 309 | 309 | /// |
| 310 | 310 | /// \headerfile <x86intrin.h> |
| 311 | 311 | /// |
| ... | ... | @@ -983,8 +983,10 @@ _mm_cmpnge_sd(__m128d __a, __m128d __b) |
| 983 | 983 | } |
| 984 | 984 | |
| 985 | 985 | /// \brief Compares the lower double-precision floating-point values in each of |
| 986 | /// the two 128-bit floating-point vectors of [2 x double] for equality. The | |
| 987 | /// comparison yields 0 for false, 1 for true. | |
| 986 | /// the two 128-bit floating-point vectors of [2 x double] for equality. | |
| 987 | /// | |
| 988 | /// The comparison yields 0 for false, 1 for true. If either of the two | |
| 989 | /// lower double-precision values is NaN, 0 is returned. | |
| 988 | 990 | /// |
| 989 | 991 | /// \headerfile <x86intrin.h> |
| 990 | 992 | /// |
| ... | ... | @@ -996,7 +998,8 @@ _mm_cmpnge_sd(__m128d __a, __m128d __b) |
| 996 | 998 | /// \param __b |
| 997 | 999 | /// A 128-bit vector of [2 x double]. The lower double-precision value is |
| 998 | 1000 | /// compared to the lower double-precision value of \a __a. |
| 999 | /// \returns An integer containing the comparison results. | |
| 1001 | /// \returns An integer containing the comparison results. If either of the two | |
| 1002 | /// lower double-precision values is NaN, 0 is returned. | |
| 1000 | 1003 | static __inline__ int __DEFAULT_FN_ATTRS |
| 1001 | 1004 | _mm_comieq_sd(__m128d __a, __m128d __b) |
| 1002 | 1005 | { |
| ... | ... | @@ -1008,7 +1011,8 @@ _mm_comieq_sd(__m128d __a, __m128d __b) |
| 1008 | 1011 | /// the value in the first parameter is less than the corresponding value in |
| 1009 | 1012 | /// the second parameter. |
| 1010 | 1013 | /// |
| 1011 | /// The comparison yields 0 for false, 1 for true. | |
| 1014 | /// The comparison yields 0 for false, 1 for true. If either of the two | |
| 1015 | /// lower double-precision values is NaN, 0 is returned. | |
| 1012 | 1016 | /// |
| 1013 | 1017 | /// \headerfile <x86intrin.h> |
| 1014 | 1018 | /// |
| ... | ... | @@ -1020,7 +1024,8 @@ _mm_comieq_sd(__m128d __a, __m128d __b) |
| 1020 | 1024 | /// \param __b |
| 1021 | 1025 | /// A 128-bit vector of [2 x double]. The lower double-precision value is |
| 1022 | 1026 | /// compared to the lower double-precision value of \a __a. |
| 1023 | /// \returns An integer containing the comparison results. | |
| 1027 | /// \returns An integer containing the comparison results. If either of the two | |
| 1028 | /// lower double-precision values is NaN, 0 is returned. | |
| 1024 | 1029 | static __inline__ int __DEFAULT_FN_ATTRS |
| 1025 | 1030 | _mm_comilt_sd(__m128d __a, __m128d __b) |
| 1026 | 1031 | { |
| ... | ... | @@ -1032,7 +1037,8 @@ _mm_comilt_sd(__m128d __a, __m128d __b) |
| 1032 | 1037 | /// the value in the first parameter is less than or equal to the |
| 1033 | 1038 | /// corresponding value in the second parameter. |
| 1034 | 1039 | /// |
| 1035 | /// The comparison yields 0 for false, 1 for true. | |
| 1040 | /// The comparison yields 0 for false, 1 for true. If either of the two | |
| 1041 | /// lower double-precision values is NaN, 0 is returned. | |
| 1036 | 1042 | /// |
| 1037 | 1043 | /// \headerfile <x86intrin.h> |
| 1038 | 1044 | /// |
| ... | ... | @@ -1044,7 +1050,8 @@ _mm_comilt_sd(__m128d __a, __m128d __b) |
| 1044 | 1050 | /// \param __b |
| 1045 | 1051 | /// A 128-bit vector of [2 x double]. The lower double-precision value is |
| 1046 | 1052 | /// compared to the lower double-precision value of \a __a. |
| 1047 | /// \returns An integer containing the comparison results. | |
| 1053 | /// \returns An integer containing the comparison results. If either of the two | |
| 1054 | /// lower double-precision values is NaN, 0 is returned. | |
| 1048 | 1055 | static __inline__ int __DEFAULT_FN_ATTRS |
| 1049 | 1056 | _mm_comile_sd(__m128d __a, __m128d __b) |
| 1050 | 1057 | { |
| ... | ... | @@ -1056,7 +1063,8 @@ _mm_comile_sd(__m128d __a, __m128d __b) |
| 1056 | 1063 | /// the value in the first parameter is greater than the corresponding value |
| 1057 | 1064 | /// in the second parameter. |
| 1058 | 1065 | /// |
| 1059 | /// The comparison yields 0 for false, 1 for true. | |
| 1066 | /// The comparison yields 0 for false, 1 for true. If either of the two | |
| 1067 | /// lower double-precision values is NaN, 0 is returned. | |
| 1060 | 1068 | /// |
| 1061 | 1069 | /// \headerfile <x86intrin.h> |
| 1062 | 1070 | /// |
| ... | ... | @@ -1068,7 +1076,8 @@ _mm_comile_sd(__m128d __a, __m128d __b) |
| 1068 | 1076 | /// \param __b |
| 1069 | 1077 | /// A 128-bit vector of [2 x double]. The lower double-precision value is |
| 1070 | 1078 | /// compared to the lower double-precision value of \a __a. |
| 1071 | /// \returns An integer containing the comparison results. | |
| 1079 | /// \returns An integer containing the comparison results. If either of the two | |
| 1080 | /// lower double-precision values is NaN, 0 is returned. | |
| 1072 | 1081 | static __inline__ int __DEFAULT_FN_ATTRS |
| 1073 | 1082 | _mm_comigt_sd(__m128d __a, __m128d __b) |
| 1074 | 1083 | { |
| ... | ... | @@ -1080,7 +1089,8 @@ _mm_comigt_sd(__m128d __a, __m128d __b) |
| 1080 | 1089 | /// the value in the first parameter is greater than or equal to the |
| 1081 | 1090 | /// corresponding value in the second parameter. |
| 1082 | 1091 | /// |
| 1083 | /// The comparison yields 0 for false, 1 for true. | |
| 1092 | /// The comparison yields 0 for false, 1 for true. If either of the two | |
| 1093 | /// lower double-precision values is NaN, 0 is returned. | |
| 1084 | 1094 | /// |
| 1085 | 1095 | /// \headerfile <x86intrin.h> |
| 1086 | 1096 | /// |
| ... | ... | @@ -1092,7 +1102,8 @@ _mm_comigt_sd(__m128d __a, __m128d __b) |
| 1092 | 1102 | /// \param __b |
| 1093 | 1103 | /// A 128-bit vector of [2 x double]. The lower double-precision value is |
| 1094 | 1104 | /// compared to the lower double-precision value of \a __a. |
| 1095 | /// \returns An integer containing the comparison results. | |
| 1105 | /// \returns An integer containing the comparison results. If either of the two | |
| 1106 | /// lower double-precision values is NaN, 0 is returned. | |
| 1096 | 1107 | static __inline__ int __DEFAULT_FN_ATTRS |
| 1097 | 1108 | _mm_comige_sd(__m128d __a, __m128d __b) |
| 1098 | 1109 | { |
| ... | ... | @@ -1104,7 +1115,8 @@ _mm_comige_sd(__m128d __a, __m128d __b) |
| 1104 | 1115 | /// the value in the first parameter is unequal to the corresponding value in |
| 1105 | 1116 | /// the second parameter. |
| 1106 | 1117 | /// |
| 1107 | /// The comparison yields 0 for false, 1 for true. | |
| 1118 | /// The comparison yields 0 for false, 1 for true. If either of the two | |
| 1119 | /// lower double-precision values is NaN, 1 is returned. | |
| 1108 | 1120 | /// |
| 1109 | 1121 | /// \headerfile <x86intrin.h> |
| 1110 | 1122 | /// |
| ... | ... | @@ -1116,7 +1128,8 @@ _mm_comige_sd(__m128d __a, __m128d __b) |
| 1116 | 1128 | /// \param __b |
| 1117 | 1129 | /// A 128-bit vector of [2 x double]. The lower double-precision value is |
| 1118 | 1130 | /// compared to the lower double-precision value of \a __a. |
| 1119 | /// \returns An integer containing the comparison results. | |
| 1131 | /// \returns An integer containing the comparison results. If either of the two | |
| 1132 | /// lower double-precision values is NaN, 1 is returned. | |
| 1120 | 1133 | static __inline__ int __DEFAULT_FN_ATTRS |
| 1121 | 1134 | _mm_comineq_sd(__m128d __a, __m128d __b) |
| 1122 | 1135 | { |
| ... | ... | @@ -1127,7 +1140,7 @@ _mm_comineq_sd(__m128d __a, __m128d __b) |
| 1127 | 1140 | /// the two 128-bit floating-point vectors of [2 x double] for equality. The |
| 1128 | 1141 | /// comparison yields 0 for false, 1 for true. |
| 1129 | 1142 | /// |
| 1130 | /// If either of the two lower double-precision values is NaN, 1 is returned. | |
| 1143 | /// If either of the two lower double-precision values is NaN, 0 is returned. | |
| 1131 | 1144 | /// |
| 1132 | 1145 | /// \headerfile <x86intrin.h> |
| 1133 | 1146 | /// |
| ... | ... | @@ -1140,7 +1153,7 @@ _mm_comineq_sd(__m128d __a, __m128d __b) |
| 1140 | 1153 | /// A 128-bit vector of [2 x double]. The lower double-precision value is |
| 1141 | 1154 | /// compared to the lower double-precision value of \a __a. |
| 1142 | 1155 | /// \returns An integer containing the comparison results. If either of the two |
| 1143 | /// lower double-precision values is NaN, 1 is returned. | |
| 1156 | /// lower double-precision values is NaN, 0 is returned. | |
| 1144 | 1157 | static __inline__ int __DEFAULT_FN_ATTRS |
| 1145 | 1158 | _mm_ucomieq_sd(__m128d __a, __m128d __b) |
| 1146 | 1159 | { |
| ... | ... | @@ -1153,7 +1166,7 @@ _mm_ucomieq_sd(__m128d __a, __m128d __b) |
| 1153 | 1166 | /// the second parameter. |
| 1154 | 1167 | /// |
| 1155 | 1168 | /// The comparison yields 0 for false, 1 for true. If either of the two lower |
| 1156 | /// double-precision values is NaN, 1 is returned. | |
| 1169 | /// double-precision values is NaN, 0 is returned. | |
| 1157 | 1170 | /// |
| 1158 | 1171 | /// \headerfile <x86intrin.h> |
| 1159 | 1172 | /// |
| ... | ... | @@ -1166,7 +1179,7 @@ _mm_ucomieq_sd(__m128d __a, __m128d __b) |
| 1166 | 1179 | /// A 128-bit vector of [2 x double]. The lower double-precision value is |
| 1167 | 1180 | /// compared to the lower double-precision value of \a __a. |
| 1168 | 1181 | /// \returns An integer containing the comparison results. If either of the two |
| 1169 | /// lower double-precision values is NaN, 1 is returned. | |
| 1182 | /// lower double-precision values is NaN, 0 is returned. | |
| 1170 | 1183 | static __inline__ int __DEFAULT_FN_ATTRS |
| 1171 | 1184 | _mm_ucomilt_sd(__m128d __a, __m128d __b) |
| 1172 | 1185 | { |
| ... | ... | @@ -1179,7 +1192,7 @@ _mm_ucomilt_sd(__m128d __a, __m128d __b) |
| 1179 | 1192 | /// corresponding value in the second parameter. |
| 1180 | 1193 | /// |
| 1181 | 1194 | /// The comparison yields 0 for false, 1 for true. If either of the two lower |
| 1182 | /// double-precision values is NaN, 1 is returned. | |
| 1195 | /// double-precision values is NaN, 0 is returned. | |
| 1183 | 1196 | /// |
| 1184 | 1197 | /// \headerfile <x86intrin.h> |
| 1185 | 1198 | /// |
| ... | ... | @@ -1192,7 +1205,7 @@ _mm_ucomilt_sd(__m128d __a, __m128d __b) |
| 1192 | 1205 | /// A 128-bit vector of [2 x double]. The lower double-precision value is |
| 1193 | 1206 | /// compared to the lower double-precision value of \a __a. |
| 1194 | 1207 | /// \returns An integer containing the comparison results. If either of the two |
| 1195 | /// lower double-precision values is NaN, 1 is returned. | |
| 1208 | /// lower double-precision values is NaN, 0 is returned. | |
| 1196 | 1209 | static __inline__ int __DEFAULT_FN_ATTRS |
| 1197 | 1210 | _mm_ucomile_sd(__m128d __a, __m128d __b) |
| 1198 | 1211 | { |
| ... | ... | @@ -1257,7 +1270,7 @@ _mm_ucomige_sd(__m128d __a, __m128d __b) |
| 1257 | 1270 | /// the second parameter. |
| 1258 | 1271 | /// |
| 1259 | 1272 | /// The comparison yields 0 for false, 1 for true. If either of the two lower |
| 1260 | /// double-precision values is NaN, 0 is returned. | |
| 1273 | /// double-precision values is NaN, 1 is returned. | |
| 1261 | 1274 | /// |
| 1262 | 1275 | /// \headerfile <x86intrin.h> |
| 1263 | 1276 | /// |
| ... | ... | @@ -1270,7 +1283,7 @@ _mm_ucomige_sd(__m128d __a, __m128d __b) |
| 1270 | 1283 | /// A 128-bit vector of [2 x double]. The lower double-precision value is |
| 1271 | 1284 | /// compared to the lower double-precision value of \a __a. |
| 1272 | 1285 | /// \returns An integer containing the comparison result. If either of the two |
| 1273 | /// lower double-precision values is NaN, 0 is returned. | |
| 1286 | /// lower double-precision values is NaN, 1 is returned. | |
| 1274 | 1287 | static __inline__ int __DEFAULT_FN_ATTRS |
| 1275 | 1288 | _mm_ucomineq_sd(__m128d __a, __m128d __b) |
| 1276 | 1289 | { |
| ... | ... | @@ -1935,14 +1948,15 @@ _mm_store_pd(double *__dp, __m128d __a) |
| 1935 | 1948 | /// |
| 1936 | 1949 | /// \headerfile <x86intrin.h> |
| 1937 | 1950 | /// |
| 1938 | /// This intrinsic corresponds to the <c>VMOVDDUP + VMOVAPD / MOVLHPS + MOVAPS </c> instruction. | |
| 1951 | /// This intrinsic corresponds to the | |
| 1952 | /// <c> VMOVDDUP + VMOVAPD / MOVLHPS + MOVAPS </c> instruction. | |
| 1939 | 1953 | /// |
| 1940 | 1954 | /// \param __dp |
| 1941 | 1955 | /// A pointer to a memory location that can store two double-precision |
| 1942 | 1956 | /// values. |
| 1943 | 1957 | /// \param __a |
| 1944 | 1958 | /// A 128-bit vector of [2 x double] whose lower 64 bits are copied to each |
| 1945 | /// of the values in \a dp. | |
| 1959 | /// of the values in \a __dp. | |
| 1946 | 1960 | static __inline__ void __DEFAULT_FN_ATTRS |
| 1947 | 1961 | _mm_store1_pd(double *__dp, __m128d __a) |
| 1948 | 1962 | { |
| ... | ... | @@ -1950,18 +1964,20 @@ _mm_store1_pd(double *__dp, __m128d __a) |
| 1950 | 1964 | _mm_store_pd(__dp, __a); |
| 1951 | 1965 | } |
| 1952 | 1966 | |
| 1953 | /// \brief Stores a 128-bit vector of [2 x double] into an aligned memory | |
| 1954 | /// location. | |
| 1967 | /// \brief Moves the lower 64 bits of a 128-bit vector of [2 x double] twice to | |
| 1968 | /// the upper and lower 64 bits of a memory location. | |
| 1955 | 1969 | /// |
| 1956 | 1970 | /// \headerfile <x86intrin.h> |
| 1957 | 1971 | /// |
| 1958 | /// This intrinsic corresponds to the <c> VMOVAPD / MOVAPD </c> instruction. | |
| 1972 | /// This intrinsic corresponds to the | |
| 1973 | /// <c> VMOVDDUP + VMOVAPD / MOVLHPS + MOVAPS </c> instruction. | |
| 1959 | 1974 | /// |
| 1960 | 1975 | /// \param __dp |
| 1961 | /// A pointer to a 128-bit memory location. The address of the memory | |
| 1962 | /// location has to be 16-byte aligned. | |
| 1976 | /// A pointer to a memory location that can store two double-precision | |
| 1977 | /// values. | |
| 1963 | 1978 | /// \param __a |
| 1964 | /// A 128-bit vector of [2 x double] containing the values to be stored. | |
| 1979 | /// A 128-bit vector of [2 x double] whose lower 64 bits are copied to each | |
| 1980 | /// of the values in \a __dp. | |
| 1965 | 1981 | static __inline__ void __DEFAULT_FN_ATTRS |
| 1966 | 1982 | _mm_store_pd1(double *__dp, __m128d __a) |
| 1967 | 1983 | { |
| ... | ... | @@ -2258,7 +2274,11 @@ _mm_adds_epu16(__m128i __a, __m128i __b) |
| 2258 | 2274 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| 2259 | 2275 | _mm_avg_epu8(__m128i __a, __m128i __b) |
| 2260 | 2276 | { |
| 2261 | return (__m128i)__builtin_ia32_pavgb128((__v16qi)__a, (__v16qi)__b); | |
| 2277 | typedef unsigned short __v16hu __attribute__ ((__vector_size__ (32))); | |
| 2278 | return (__m128i)__builtin_convertvector( | |
| 2279 | ((__builtin_convertvector((__v16qu)__a, __v16hu) + | |
| 2280 | __builtin_convertvector((__v16qu)__b, __v16hu)) + 1) | |
| 2281 | >> 1, __v16qu); | |
| 2262 | 2282 | } |
| 2263 | 2283 | |
| 2264 | 2284 | /// \brief Computes the rounded avarages of corresponding elements of two |
| ... | ... | @@ -2278,7 +2298,11 @@ _mm_avg_epu8(__m128i __a, __m128i __b) |
| 2278 | 2298 | static __inline__ __m128i __DEFAULT_FN_ATTRS |
| 2279 | 2299 | _mm_avg_epu16(__m128i __a, __m128i __b) |
| 2280 | 2300 | { |
| 2281 | return (__m128i)__builtin_ia32_pavgw128((__v8hi)__a, (__v8hi)__b); | |
| 2301 | typedef unsigned int __v8su __attribute__ ((__vector_size__ (32))); | |
| 2302 | return (__m128i)__builtin_convertvector( | |
| 2303 | ((__builtin_convertvector((__v8hu)__a, __v8su) + | |
| 2304 | __builtin_convertvector((__v8hu)__b, __v8su)) + 1) | |
| 2305 | >> 1, __v8hu); | |
| 2282 | 2306 | } |
| 2283 | 2307 | |
| 2284 | 2308 | /// \brief Multiplies the corresponding elements of two 128-bit signed [8 x i16] |
| ... | ... | @@ -3838,8 +3862,7 @@ _mm_set1_epi8(char __b) |
| 3838 | 3862 | /// |
| 3839 | 3863 | /// \headerfile <x86intrin.h> |
| 3840 | 3864 | /// |
| 3841 | /// This intrinsic corresponds to the <c> VPUNPCKLQDQ / PUNPCKLQDQ </c> | |
| 3842 | /// instruction. | |
| 3865 | /// This intrinsic does not correspond to a specific instruction. | |
| 3843 | 3866 | /// |
| 3844 | 3867 | /// \param __q0 |
| 3845 | 3868 | /// A 64-bit integral value used to initialize the lower 64 bits of the |
| ... | ... | @@ -4010,7 +4033,7 @@ _mm_storeu_si128(__m128i *__p, __m128i __b) |
| 4010 | 4033 | /// specified unaligned memory location. When a mask bit is 1, the |
| 4011 | 4034 | /// corresponding byte is written, otherwise it is not written. |
| 4012 | 4035 | /// |
| 4013 | /// To minimize caching, the date is flagged as non-temporal (unlikely to be | |
| 4036 | /// To minimize caching, the data is flagged as non-temporal (unlikely to be | |
| 4014 | 4037 | /// used again soon). Exception and trap behavior for elements not selected |
| 4015 | 4038 | /// for storage to memory are implementation dependent. |
| 4016 | 4039 | /// |
| ... | ... | @@ -4524,8 +4547,8 @@ _mm_unpackhi_epi32(__m128i __a, __m128i __b) |
| 4524 | 4547 | return (__m128i)__builtin_shufflevector((__v4si)__a, (__v4si)__b, 2, 4+2, 3, 4+3); |
| 4525 | 4548 | } |
| 4526 | 4549 | |
| 4527 | /// \brief Unpacks the high-order (odd-indexed) values from two 128-bit vectors | |
| 4528 | /// of [2 x i64] and interleaves them into a 128-bit vector of [2 x i64]. | |
| 4550 | /// \brief Unpacks the high-order 64-bit elements from two 128-bit vectors of | |
| 4551 | /// [2 x i64] and interleaves them into a 128-bit vector of [2 x i64]. | |
| 4529 | 4552 | /// |
| 4530 | 4553 | /// \headerfile <x86intrin.h> |
| 4531 | 4554 | /// |
| ... | ... | @@ -4657,7 +4680,7 @@ _mm_unpacklo_epi64(__m128i __a, __m128i __b) |
| 4657 | 4680 | /// |
| 4658 | 4681 | /// \headerfile <x86intrin.h> |
| 4659 | 4682 | /// |
| 4660 | /// This intrinsic has no corresponding instruction. | |
| 4683 | /// This intrinsic corresponds to the <c> MOVDQ2Q </c> instruction. | |
| 4661 | 4684 | /// |
| 4662 | 4685 | /// \param __a |
| 4663 | 4686 | /// A 128-bit integer vector operand. The lower 64 bits are moved to the |
| ... | ... | @@ -4674,7 +4697,7 @@ _mm_movepi64_pi64(__m128i __a) |
| 4674 | 4697 | /// |
| 4675 | 4698 | /// \headerfile <x86intrin.h> |
| 4676 | 4699 | /// |
| 4677 | /// This intrinsic corresponds to the <c> VMOVQ / MOVQ / MOVD </c> instruction. | |
| 4700 | /// This intrinsic corresponds to the <c> MOVD+VMOVQ </c> instruction. | |
| 4678 | 4701 | /// |
| 4679 | 4702 | /// \param __a |
| 4680 | 4703 | /// A 64-bit value. |
| ... | ... | @@ -4704,8 +4727,8 @@ _mm_move_epi64(__m128i __a) |
| 4704 | 4727 | return __builtin_shufflevector((__v2di)__a, (__m128i){ 0 }, 0, 2); |
| 4705 | 4728 | } |
| 4706 | 4729 | |
| 4707 | /// \brief Unpacks the high-order (odd-indexed) values from two 128-bit vectors | |
| 4708 | /// of [2 x double] and interleaves them into a 128-bit vector of [2 x | |
| 4730 | /// \brief Unpacks the high-order 64-bit elements from two 128-bit vectors of | |
| 4731 | /// [2 x double] and interleaves them into a 128-bit vector of [2 x | |
| 4709 | 4732 | /// double]. |
| 4710 | 4733 | /// |
| 4711 | 4734 | /// \headerfile <x86intrin.h> |
| ... | ... | @@ -4725,7 +4748,7 @@ _mm_unpackhi_pd(__m128d __a, __m128d __b) |
| 4725 | 4748 | return __builtin_shufflevector((__v2df)__a, (__v2df)__b, 1, 2+1); |
| 4726 | 4749 | } |
| 4727 | 4750 | |
| 4728 | /// \brief Unpacks the low-order (even-indexed) values from two 128-bit vectors | |
| 4751 | /// \brief Unpacks the low-order 64-bit elements from two 128-bit vectors | |
| 4729 | 4752 | /// of [2 x double] and interleaves them into a 128-bit vector of [2 x |
| 4730 | 4753 | /// double]. |
| 4731 | 4754 | /// |
| ... | ... | @@ -4784,9 +4807,9 @@ _mm_movemask_pd(__m128d __a) |
| 4784 | 4807 | /// A 128-bit vector of [2 x double]. |
| 4785 | 4808 | /// \param i |
| 4786 | 4809 | /// An 8-bit immediate value. The least significant two bits specify which |
| 4787 | /// elements to copy from a and b: \n | |
| 4788 | /// Bit[0] = 0: lower element of a copied to lower element of result. \n | |
| 4789 | /// Bit[0] = 1: upper element of a copied to lower element of result. \n | |
| 4810 | /// elements to copy from \a a and \a b: \n | |
| 4811 | /// Bit[0] = 0: lower element of \a a copied to lower element of result. \n | |
| 4812 | /// Bit[0] = 1: upper element of \a a copied to lower element of result. \n | |
| 4790 | 4813 | /// Bit[1] = 0: lower element of \a b copied to upper element of result. \n |
| 4791 | 4814 | /// Bit[1] = 1: upper element of \a b copied to upper element of result. \n |
| 4792 | 4815 | /// \returns A 128-bit vector of [2 x double] containing the shuffled values. |
c_headers/float.h+14| ... | ... | @@ -143,4 +143,18 @@ |
| 143 | 143 | # define LDBL_DECIMAL_DIG __LDBL_DECIMAL_DIG__ |
| 144 | 144 | #endif |
| 145 | 145 | |
| 146 | #ifdef __STDC_WANT_IEC_60559_TYPES_EXT__ | |
| 147 | # define FLT16_MANT_DIG __FLT16_MANT_DIG__ | |
| 148 | # define FLT16_DECIMAL_DIG __FLT16_DECIMAL_DIG__ | |
| 149 | # define FLT16_DIG __FLT16_DIG__ | |
| 150 | # define FLT16_MIN_EXP __FLT16_MIN_EXP__ | |
| 151 | # define FLT16_MIN_10_EXP __FLT16_MIN_10_EXP__ | |
| 152 | # define FLT16_MAX_EXP __FLT16_MAX_EXP__ | |
| 153 | # define FLT16_MAX_10_EXP __FLT16_MAX_10_EXP__ | |
| 154 | # define FLT16_MAX __FLT16_MAX__ | |
| 155 | # define FLT16_EPSILON __FLT16_EPSILON__ | |
| 156 | # define FLT16_MIN __FLT16_MIN__ | |
| 157 | # define FLT16_TRUE_MIN __FLT16_TRUE_MIN__ | |
| 158 | #endif /* __STDC_WANT_IEC_60559_TYPES_EXT__ */ | |
| 159 | ||
| 146 | 160 | #endif /* __FLOAT_H */ |
c_headers/fma4intrin.h+22-22| ... | ... | @@ -60,73 +60,73 @@ _mm_macc_sd(__m128d __A, __m128d __B, __m128d __C) |
| 60 | 60 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 61 | 61 | _mm_msub_ps(__m128 __A, __m128 __B, __m128 __C) |
| 62 | 62 | { |
| 63 | return (__m128)__builtin_ia32_vfmsubps((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 63 | return (__m128)__builtin_ia32_vfmaddps((__v4sf)__A, (__v4sf)__B, -(__v4sf)__C); | |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | 66 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 67 | 67 | _mm_msub_pd(__m128d __A, __m128d __B, __m128d __C) |
| 68 | 68 | { |
| 69 | return (__m128d)__builtin_ia32_vfmsubpd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 69 | return (__m128d)__builtin_ia32_vfmaddpd((__v2df)__A, (__v2df)__B, -(__v2df)__C); | |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | 72 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 73 | 73 | _mm_msub_ss(__m128 __A, __m128 __B, __m128 __C) |
| 74 | 74 | { |
| 75 | return (__m128)__builtin_ia32_vfmsubss((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 75 | return (__m128)__builtin_ia32_vfmaddss((__v4sf)__A, (__v4sf)__B, -(__v4sf)__C); | |
| 76 | 76 | } |
| 77 | 77 | |
| 78 | 78 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 79 | 79 | _mm_msub_sd(__m128d __A, __m128d __B, __m128d __C) |
| 80 | 80 | { |
| 81 | return (__m128d)__builtin_ia32_vfmsubsd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 81 | return (__m128d)__builtin_ia32_vfmaddsd((__v2df)__A, (__v2df)__B, -(__v2df)__C); | |
| 82 | 82 | } |
| 83 | 83 | |
| 84 | 84 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 85 | 85 | _mm_nmacc_ps(__m128 __A, __m128 __B, __m128 __C) |
| 86 | 86 | { |
| 87 | return (__m128)__builtin_ia32_vfnmaddps((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 87 | return (__m128)__builtin_ia32_vfmaddps(-(__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | 90 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 91 | 91 | _mm_nmacc_pd(__m128d __A, __m128d __B, __m128d __C) |
| 92 | 92 | { |
| 93 | return (__m128d)__builtin_ia32_vfnmaddpd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 93 | return (__m128d)__builtin_ia32_vfmaddpd(-(__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | 96 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 97 | 97 | _mm_nmacc_ss(__m128 __A, __m128 __B, __m128 __C) |
| 98 | 98 | { |
| 99 | return (__m128)__builtin_ia32_vfnmaddss((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 99 | return (__m128)__builtin_ia32_vfmaddss(-(__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | 102 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 103 | 103 | _mm_nmacc_sd(__m128d __A, __m128d __B, __m128d __C) |
| 104 | 104 | { |
| 105 | return (__m128d)__builtin_ia32_vfnmaddsd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 105 | return (__m128d)__builtin_ia32_vfmaddsd(-(__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | 108 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 109 | 109 | _mm_nmsub_ps(__m128 __A, __m128 __B, __m128 __C) |
| 110 | 110 | { |
| 111 | return (__m128)__builtin_ia32_vfnmsubps((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 111 | return (__m128)__builtin_ia32_vfmaddps(-(__v4sf)__A, (__v4sf)__B, -(__v4sf)__C); | |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | 114 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 115 | 115 | _mm_nmsub_pd(__m128d __A, __m128d __B, __m128d __C) |
| 116 | 116 | { |
| 117 | return (__m128d)__builtin_ia32_vfnmsubpd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 117 | return (__m128d)__builtin_ia32_vfmaddpd(-(__v2df)__A, (__v2df)__B, -(__v2df)__C); | |
| 118 | 118 | } |
| 119 | 119 | |
| 120 | 120 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 121 | 121 | _mm_nmsub_ss(__m128 __A, __m128 __B, __m128 __C) |
| 122 | 122 | { |
| 123 | return (__m128)__builtin_ia32_vfnmsubss((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 123 | return (__m128)__builtin_ia32_vfmaddss(-(__v4sf)__A, (__v4sf)__B, -(__v4sf)__C); | |
| 124 | 124 | } |
| 125 | 125 | |
| 126 | 126 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 127 | 127 | _mm_nmsub_sd(__m128d __A, __m128d __B, __m128d __C) |
| 128 | 128 | { |
| 129 | return (__m128d)__builtin_ia32_vfnmsubsd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 129 | return (__m128d)__builtin_ia32_vfmaddsd(-(__v2df)__A, (__v2df)__B, -(__v2df)__C); | |
| 130 | 130 | } |
| 131 | 131 | |
| 132 | 132 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| ... | ... | @@ -144,13 +144,13 @@ _mm_maddsub_pd(__m128d __A, __m128d __B, __m128d __C) |
| 144 | 144 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 145 | 145 | _mm_msubadd_ps(__m128 __A, __m128 __B, __m128 __C) |
| 146 | 146 | { |
| 147 | return (__m128)__builtin_ia32_vfmsubaddps((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 147 | return (__m128)__builtin_ia32_vfmaddsubps((__v4sf)__A, (__v4sf)__B, -(__v4sf)__C); | |
| 148 | 148 | } |
| 149 | 149 | |
| 150 | 150 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 151 | 151 | _mm_msubadd_pd(__m128d __A, __m128d __B, __m128d __C) |
| 152 | 152 | { |
| 153 | return (__m128d)__builtin_ia32_vfmsubaddpd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 153 | return (__m128d)__builtin_ia32_vfmaddsubpd((__v2df)__A, (__v2df)__B, -(__v2df)__C); | |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | 156 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| ... | ... | @@ -168,37 +168,37 @@ _mm256_macc_pd(__m256d __A, __m256d __B, __m256d __C) |
| 168 | 168 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| 169 | 169 | _mm256_msub_ps(__m256 __A, __m256 __B, __m256 __C) |
| 170 | 170 | { |
| 171 | return (__m256)__builtin_ia32_vfmsubps256((__v8sf)__A, (__v8sf)__B, (__v8sf)__C); | |
| 171 | return (__m256)__builtin_ia32_vfmaddps256((__v8sf)__A, (__v8sf)__B, -(__v8sf)__C); | |
| 172 | 172 | } |
| 173 | 173 | |
| 174 | 174 | static __inline__ __m256d __DEFAULT_FN_ATTRS |
| 175 | 175 | _mm256_msub_pd(__m256d __A, __m256d __B, __m256d __C) |
| 176 | 176 | { |
| 177 | return (__m256d)__builtin_ia32_vfmsubpd256((__v4df)__A, (__v4df)__B, (__v4df)__C); | |
| 177 | return (__m256d)__builtin_ia32_vfmaddpd256((__v4df)__A, (__v4df)__B, -(__v4df)__C); | |
| 178 | 178 | } |
| 179 | 179 | |
| 180 | 180 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| 181 | 181 | _mm256_nmacc_ps(__m256 __A, __m256 __B, __m256 __C) |
| 182 | 182 | { |
| 183 | return (__m256)__builtin_ia32_vfnmaddps256((__v8sf)__A, (__v8sf)__B, (__v8sf)__C); | |
| 183 | return (__m256)__builtin_ia32_vfmaddps256(-(__v8sf)__A, (__v8sf)__B, (__v8sf)__C); | |
| 184 | 184 | } |
| 185 | 185 | |
| 186 | 186 | static __inline__ __m256d __DEFAULT_FN_ATTRS |
| 187 | 187 | _mm256_nmacc_pd(__m256d __A, __m256d __B, __m256d __C) |
| 188 | 188 | { |
| 189 | return (__m256d)__builtin_ia32_vfnmaddpd256((__v4df)__A, (__v4df)__B, (__v4df)__C); | |
| 189 | return (__m256d)__builtin_ia32_vfmaddpd256(-(__v4df)__A, (__v4df)__B, (__v4df)__C); | |
| 190 | 190 | } |
| 191 | 191 | |
| 192 | 192 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| 193 | 193 | _mm256_nmsub_ps(__m256 __A, __m256 __B, __m256 __C) |
| 194 | 194 | { |
| 195 | return (__m256)__builtin_ia32_vfnmsubps256((__v8sf)__A, (__v8sf)__B, (__v8sf)__C); | |
| 195 | return (__m256)__builtin_ia32_vfmaddps256(-(__v8sf)__A, (__v8sf)__B, -(__v8sf)__C); | |
| 196 | 196 | } |
| 197 | 197 | |
| 198 | 198 | static __inline__ __m256d __DEFAULT_FN_ATTRS |
| 199 | 199 | _mm256_nmsub_pd(__m256d __A, __m256d __B, __m256d __C) |
| 200 | 200 | { |
| 201 | return (__m256d)__builtin_ia32_vfnmsubpd256((__v4df)__A, (__v4df)__B, (__v4df)__C); | |
| 201 | return (__m256d)__builtin_ia32_vfmaddpd256(-(__v4df)__A, (__v4df)__B, -(__v4df)__C); | |
| 202 | 202 | } |
| 203 | 203 | |
| 204 | 204 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| ... | ... | @@ -216,13 +216,13 @@ _mm256_maddsub_pd(__m256d __A, __m256d __B, __m256d __C) |
| 216 | 216 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| 217 | 217 | _mm256_msubadd_ps(__m256 __A, __m256 __B, __m256 __C) |
| 218 | 218 | { |
| 219 | return (__m256)__builtin_ia32_vfmsubaddps256((__v8sf)__A, (__v8sf)__B, (__v8sf)__C); | |
| 219 | return (__m256)__builtin_ia32_vfmaddsubps256((__v8sf)__A, (__v8sf)__B, -(__v8sf)__C); | |
| 220 | 220 | } |
| 221 | 221 | |
| 222 | 222 | static __inline__ __m256d __DEFAULT_FN_ATTRS |
| 223 | 223 | _mm256_msubadd_pd(__m256d __A, __m256d __B, __m256d __C) |
| 224 | 224 | { |
| 225 | return (__m256d)__builtin_ia32_vfmsubaddpd256((__v4df)__A, (__v4df)__B, (__v4df)__C); | |
| 225 | return (__m256d)__builtin_ia32_vfmaddsubpd256((__v4df)__A, (__v4df)__B, -(__v4df)__C); | |
| 226 | 226 | } |
| 227 | 227 | |
| 228 | 228 | #undef __DEFAULT_FN_ATTRS |
c_headers/fmaintrin.h+24-24| ... | ... | @@ -46,85 +46,85 @@ _mm_fmadd_pd(__m128d __A, __m128d __B, __m128d __C) |
| 46 | 46 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 47 | 47 | _mm_fmadd_ss(__m128 __A, __m128 __B, __m128 __C) |
| 48 | 48 | { |
| 49 | return (__m128)__builtin_ia32_vfmaddss((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 49 | return (__m128)__builtin_ia32_vfmaddss3((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 50 | 50 | } |
| 51 | 51 | |
| 52 | 52 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 53 | 53 | _mm_fmadd_sd(__m128d __A, __m128d __B, __m128d __C) |
| 54 | 54 | { |
| 55 | return (__m128d)__builtin_ia32_vfmaddsd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 55 | return (__m128d)__builtin_ia32_vfmaddsd3((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 59 | 59 | _mm_fmsub_ps(__m128 __A, __m128 __B, __m128 __C) |
| 60 | 60 | { |
| 61 | return (__m128)__builtin_ia32_vfmsubps((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 61 | return (__m128)__builtin_ia32_vfmaddps((__v4sf)__A, (__v4sf)__B, -(__v4sf)__C); | |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | 64 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 65 | 65 | _mm_fmsub_pd(__m128d __A, __m128d __B, __m128d __C) |
| 66 | 66 | { |
| 67 | return (__m128d)__builtin_ia32_vfmsubpd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 67 | return (__m128d)__builtin_ia32_vfmaddpd((__v2df)__A, (__v2df)__B, -(__v2df)__C); | |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | 70 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 71 | 71 | _mm_fmsub_ss(__m128 __A, __m128 __B, __m128 __C) |
| 72 | 72 | { |
| 73 | return (__m128)__builtin_ia32_vfmsubss((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 73 | return (__m128)__builtin_ia32_vfmaddss3((__v4sf)__A, (__v4sf)__B, -(__v4sf)__C); | |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | 76 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 77 | 77 | _mm_fmsub_sd(__m128d __A, __m128d __B, __m128d __C) |
| 78 | 78 | { |
| 79 | return (__m128d)__builtin_ia32_vfmsubsd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 79 | return (__m128d)__builtin_ia32_vfmaddsd3((__v2df)__A, (__v2df)__B, -(__v2df)__C); | |
| 80 | 80 | } |
| 81 | 81 | |
| 82 | 82 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 83 | 83 | _mm_fnmadd_ps(__m128 __A, __m128 __B, __m128 __C) |
| 84 | 84 | { |
| 85 | return (__m128)__builtin_ia32_vfnmaddps((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 85 | return (__m128)__builtin_ia32_vfmaddps(-(__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 86 | 86 | } |
| 87 | 87 | |
| 88 | 88 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 89 | 89 | _mm_fnmadd_pd(__m128d __A, __m128d __B, __m128d __C) |
| 90 | 90 | { |
| 91 | return (__m128d)__builtin_ia32_vfnmaddpd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 91 | return (__m128d)__builtin_ia32_vfmaddpd(-(__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 92 | 92 | } |
| 93 | 93 | |
| 94 | 94 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 95 | 95 | _mm_fnmadd_ss(__m128 __A, __m128 __B, __m128 __C) |
| 96 | 96 | { |
| 97 | return (__m128)__builtin_ia32_vfnmaddss((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 97 | return (__m128)__builtin_ia32_vfmaddss3((__v4sf)__A, -(__v4sf)__B, (__v4sf)__C); | |
| 98 | 98 | } |
| 99 | 99 | |
| 100 | 100 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 101 | 101 | _mm_fnmadd_sd(__m128d __A, __m128d __B, __m128d __C) |
| 102 | 102 | { |
| 103 | return (__m128d)__builtin_ia32_vfnmaddsd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 103 | return (__m128d)__builtin_ia32_vfmaddsd3((__v2df)__A, -(__v2df)__B, (__v2df)__C); | |
| 104 | 104 | } |
| 105 | 105 | |
| 106 | 106 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 107 | 107 | _mm_fnmsub_ps(__m128 __A, __m128 __B, __m128 __C) |
| 108 | 108 | { |
| 109 | return (__m128)__builtin_ia32_vfnmsubps((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 109 | return (__m128)__builtin_ia32_vfmaddps(-(__v4sf)__A, (__v4sf)__B, -(__v4sf)__C); | |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | 112 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 113 | 113 | _mm_fnmsub_pd(__m128d __A, __m128d __B, __m128d __C) |
| 114 | 114 | { |
| 115 | return (__m128d)__builtin_ia32_vfnmsubpd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 115 | return (__m128d)__builtin_ia32_vfmaddpd(-(__v2df)__A, (__v2df)__B, -(__v2df)__C); | |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | 118 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 119 | 119 | _mm_fnmsub_ss(__m128 __A, __m128 __B, __m128 __C) |
| 120 | 120 | { |
| 121 | return (__m128)__builtin_ia32_vfnmsubss((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 121 | return (__m128)__builtin_ia32_vfmaddss3((__v4sf)__A, -(__v4sf)__B, -(__v4sf)__C); | |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | 124 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 125 | 125 | _mm_fnmsub_sd(__m128d __A, __m128d __B, __m128d __C) |
| 126 | 126 | { |
| 127 | return (__m128d)__builtin_ia32_vfnmsubsd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 127 | return (__m128d)__builtin_ia32_vfmaddsd3((__v2df)__A, -(__v2df)__B, -(__v2df)__C); | |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | 130 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| ... | ... | @@ -142,13 +142,13 @@ _mm_fmaddsub_pd(__m128d __A, __m128d __B, __m128d __C) |
| 142 | 142 | static __inline__ __m128 __DEFAULT_FN_ATTRS |
| 143 | 143 | _mm_fmsubadd_ps(__m128 __A, __m128 __B, __m128 __C) |
| 144 | 144 | { |
| 145 | return (__m128)__builtin_ia32_vfmsubaddps((__v4sf)__A, (__v4sf)__B, (__v4sf)__C); | |
| 145 | return (__m128)__builtin_ia32_vfmaddsubps((__v4sf)__A, (__v4sf)__B, -(__v4sf)__C); | |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | 148 | static __inline__ __m128d __DEFAULT_FN_ATTRS |
| 149 | 149 | _mm_fmsubadd_pd(__m128d __A, __m128d __B, __m128d __C) |
| 150 | 150 | { |
| 151 | return (__m128d)__builtin_ia32_vfmsubaddpd((__v2df)__A, (__v2df)__B, (__v2df)__C); | |
| 151 | return (__m128d)__builtin_ia32_vfmaddsubpd((__v2df)__A, (__v2df)__B, -(__v2df)__C); | |
| 152 | 152 | } |
| 153 | 153 | |
| 154 | 154 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| ... | ... | @@ -166,37 +166,37 @@ _mm256_fmadd_pd(__m256d __A, __m256d __B, __m256d __C) |
| 166 | 166 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| 167 | 167 | _mm256_fmsub_ps(__m256 __A, __m256 __B, __m256 __C) |
| 168 | 168 | { |
| 169 | return (__m256)__builtin_ia32_vfmsubps256((__v8sf)__A, (__v8sf)__B, (__v8sf)__C); | |
| 169 | return (__m256)__builtin_ia32_vfmaddps256((__v8sf)__A, (__v8sf)__B, -(__v8sf)__C); | |
| 170 | 170 | } |
| 171 | 171 | |
| 172 | 172 | static __inline__ __m256d __DEFAULT_FN_ATTRS |
| 173 | 173 | _mm256_fmsub_pd(__m256d __A, __m256d __B, __m256d __C) |
| 174 | 174 | { |
| 175 | return (__m256d)__builtin_ia32_vfmsubpd256((__v4df)__A, (__v4df)__B, (__v4df)__C); | |
| 175 | return (__m256d)__builtin_ia32_vfmaddpd256((__v4df)__A, (__v4df)__B, -(__v4df)__C); | |
| 176 | 176 | } |
| 177 | 177 | |
| 178 | 178 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| 179 | 179 | _mm256_fnmadd_ps(__m256 __A, __m256 __B, __m256 __C) |
| 180 | 180 | { |
| 181 | return (__m256)__builtin_ia32_vfnmaddps256((__v8sf)__A, (__v8sf)__B, (__v8sf)__C); | |
| 181 | return (__m256)__builtin_ia32_vfmaddps256(-(__v8sf)__A, (__v8sf)__B, (__v8sf)__C); | |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | 184 | static __inline__ __m256d __DEFAULT_FN_ATTRS |
| 185 | 185 | _mm256_fnmadd_pd(__m256d __A, __m256d __B, __m256d __C) |
| 186 | 186 | { |
| 187 | return (__m256d)__builtin_ia32_vfnmaddpd256((__v4df)__A, (__v4df)__B, (__v4df)__C); | |
| 187 | return (__m256d)__builtin_ia32_vfmaddpd256(-(__v4df)__A, (__v4df)__B, (__v4df)__C); | |
| 188 | 188 | } |
| 189 | 189 | |
| 190 | 190 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| 191 | 191 | _mm256_fnmsub_ps(__m256 __A, __m256 __B, __m256 __C) |
| 192 | 192 | { |
| 193 | return (__m256)__builtin_ia32_vfnmsubps256((__v8sf)__A, (__v8sf)__B, (__v8sf)__C); | |
| 193 | return (__m256)__builtin_ia32_vfmaddps256(-(__v8sf)__A, (__v8sf)__B, -(__v8sf)__C); | |
| 194 | 194 | } |
| 195 | 195 | |
| 196 | 196 | static __inline__ __m256d __DEFAULT_FN_ATTRS |
| 197 | 197 | _mm256_fnmsub_pd(__m256d __A, __m256d __B, __m256d __C) |
| 198 | 198 | { |
| 199 | return (__m256d)__builtin_ia32_vfnmsubpd256((__v4df)__A, (__v4df)__B, (__v4df)__C); | |
| 199 | return (__m256d)__builtin_ia32_vfmaddpd256(-(__v4df)__A, (__v4df)__B, -(__v4df)__C); | |
| 200 | 200 | } |
| 201 | 201 | |
| 202 | 202 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| ... | ... | @@ -214,13 +214,13 @@ _mm256_fmaddsub_pd(__m256d __A, __m256d __B, __m256d __C) |
| 214 | 214 | static __inline__ __m256 __DEFAULT_FN_ATTRS |
| 215 | 215 | _mm256_fmsubadd_ps(__m256 __A, __m256 __B, __m256 __C) |
| 216 | 216 | { |
| 217 | return (__m256)__builtin_ia32_vfmsubaddps256((__v8sf)__A, (__v8sf)__B, (__v8sf)__C); | |
| 217 | return (__m256)__builtin_ia32_vfmaddsubps256((__v8sf)__A, (__v8sf)__B, -(__v8sf)__C); | |
| 218 | 218 | } |
| 219 | 219 | |
| 220 | 220 | static __inline__ __m256d __DEFAULT_FN_ATTRS |
| 221 | 221 | _mm256_fmsubadd_pd(__m256d __A, __m256d __B, __m256d __C) |
| 222 | 222 | { |
| 223 | return (__m256d)__builtin_ia32_vfmsubaddpd256((__v4df)__A, (__v4df)__B, (__v4df)__C); | |
| 223 | return (__m256d)__builtin_ia32_vfmaddsubpd256((__v4df)__A, (__v4df)__B, -(__v4df)__C); | |
| 224 | 224 | } |
| 225 | 225 | |
| 226 | 226 | #undef __DEFAULT_FN_ATTRS |
c_headers/gfniintrin.h created+202| ... | ... | @@ -0,0 +1,202 @@ |
| 1 | /*===----------------- gfniintrin.h - GFNI intrinsics ----------------------=== | |
| 2 | * | |
| 3 | * | |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 5 | * of this software and associated documentation files (the "Software"), to deal | |
| 6 | * in the Software without restriction, including without limitation the rights | |
| 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 8 | * copies of the Software, and to permit persons to whom the Software is | |
| 9 | * furnished to do so, subject to the following conditions: | |
| 10 | * | |
| 11 | * The above copyright notice and this permission notice shall be included in | |
| 12 | * all copies or substantial portions of the Software. | |
| 13 | * | |
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 20 | * THE SOFTWARE. | |
| 21 | * | |
| 22 | *===-----------------------------------------------------------------------=== | |
| 23 | */ | |
| 24 | #ifndef __IMMINTRIN_H | |
| 25 | #error "Never use <gfniintrin.h> directly; include <immintrin.h> instead." | |
| 26 | #endif | |
| 27 | ||
| 28 | #ifndef __GFNIINTRIN_H | |
| 29 | #define __GFNIINTRIN_H | |
| 30 | ||
| 31 | ||
| 32 | #define _mm_gf2p8affineinv_epi64_epi8(A, B, I) __extension__ ({ \ | |
| 33 | (__m128i)__builtin_ia32_vgf2p8affineinvqb_v16qi((__v16qi)(__m128i)(A), \ | |
| 34 | (__v16qi)(__m128i)(B), \ | |
| 35 | (char)(I)); }) | |
| 36 | ||
| 37 | #define _mm_mask_gf2p8affineinv_epi64_epi8(S, U, A, B, I) __extension__ ({ \ | |
| 38 | (__m128i)__builtin_ia32_selectb_128((__mmask16)(U), \ | |
| 39 | (__v16qi)_mm_gf2p8affineinv_epi64_epi8(A, B, I), \ | |
| 40 | (__v16qi)(__m128i)(S)); }) | |
| 41 | ||
| 42 | ||
| 43 | #define _mm_maskz_gf2p8affineinv_epi64_epi8(U, A, B, I) __extension__ ({ \ | |
| 44 | (__m128i)_mm_mask_gf2p8affineinv_epi64_epi8((__m128i)_mm_setzero_si128(), \ | |
| 45 | U, A, B, I); }) | |
| 46 | ||
| 47 | ||
| 48 | #define _mm256_gf2p8affineinv_epi64_epi8(A, B, I) __extension__ ({ \ | |
| 49 | (__m256i)__builtin_ia32_vgf2p8affineinvqb_v32qi((__v32qi)(__m256i)(A), \ | |
| 50 | (__v32qi)(__m256i)(B), \ | |
| 51 | (char)(I)); }) | |
| 52 | ||
| 53 | #define _mm256_mask_gf2p8affineinv_epi64_epi8(S, U, A, B, I) __extension__ ({ \ | |
| 54 | (__m256i)__builtin_ia32_selectb_256((__mmask32)(U), \ | |
| 55 | (__v32qi)_mm256_gf2p8affineinv_epi64_epi8(A, B, I), \ | |
| 56 | (__v32qi)(__m256i)(S)); }) | |
| 57 | ||
| 58 | #define _mm256_maskz_gf2p8affineinv_epi64_epi8(U, A, B, I) __extension__ ({ \ | |
| 59 | (__m256i)_mm256_mask_gf2p8affineinv_epi64_epi8((__m256i)_mm256_setzero_si256(), \ | |
| 60 | U, A, B, I); }) | |
| 61 | ||
| 62 | ||
| 63 | #define _mm512_gf2p8affineinv_epi64_epi8(A, B, I) __extension__ ({ \ | |
| 64 | (__m512i)__builtin_ia32_vgf2p8affineinvqb_v64qi((__v64qi)(__m512i)(A), \ | |
| 65 | (__v64qi)(__m512i)(B), \ | |
| 66 | (char)(I)); }) | |
| 67 | ||
| 68 | #define _mm512_mask_gf2p8affineinv_epi64_epi8(S, U, A, B, I) __extension__ ({ \ | |
| 69 | (__m512i)__builtin_ia32_selectb_512((__mmask64)(U), \ | |
| 70 | (__v64qi)_mm512_gf2p8affineinv_epi64_epi8(A, B, I), \ | |
| 71 | (__v64qi)(__m512i)(S)); }) | |
| 72 | ||
| 73 | #define _mm512_maskz_gf2p8affineinv_epi64_epi8(U, A, B, I) __extension__ ({ \ | |
| 74 | (__m512i)_mm512_mask_gf2p8affineinv_epi64_epi8((__m512i)_mm512_setzero_qi(), \ | |
| 75 | U, A, B, I); }) | |
| 76 | ||
| 77 | #define _mm_gf2p8affine_epi64_epi8(A, B, I) __extension__ ({ \ | |
| 78 | (__m128i)__builtin_ia32_vgf2p8affineqb_v16qi((__v16qi)(__m128i)(A), \ | |
| 79 | (__v16qi)(__m128i)(B), \ | |
| 80 | (char)(I)); }) | |
| 81 | ||
| 82 | #define _mm_mask_gf2p8affine_epi64_epi8(S, U, A, B, I) __extension__ ({ \ | |
| 83 | (__m128i)__builtin_ia32_selectb_128((__mmask16)(U), \ | |
| 84 | (__v16qi)_mm_gf2p8affine_epi64_epi8(A, B, I), \ | |
| 85 | (__v16qi)(__m128i)(S)); }) | |
| 86 | ||
| 87 | ||
| 88 | #define _mm_maskz_gf2p8affine_epi64_epi8(U, A, B, I) __extension__ ({ \ | |
| 89 | (__m128i)_mm_mask_gf2p8affine_epi64_epi8((__m128i)_mm_setzero_si128(), \ | |
| 90 | U, A, B, I); }) | |
| 91 | ||
| 92 | ||
| 93 | #define _mm256_gf2p8affine_epi64_epi8(A, B, I) __extension__ ({ \ | |
| 94 | (__m256i)__builtin_ia32_vgf2p8affineqb_v32qi((__v32qi)(__m256i)(A), \ | |
| 95 | (__v32qi)(__m256i)(B), \ | |
| 96 | (char)(I)); }) | |
| 97 | ||
| 98 | #define _mm256_mask_gf2p8affine_epi64_epi8(S, U, A, B, I) __extension__ ({ \ | |
| 99 | (__m256i)__builtin_ia32_selectb_256((__mmask32)(U), \ | |
| 100 | (__v32qi)_mm256_gf2p8affine_epi64_epi8(A, B, I), \ | |
| 101 | (__v32qi)(__m256i)(S)); }) | |
| 102 | ||
| 103 | #define _mm256_maskz_gf2p8affine_epi64_epi8(U, A, B, I) __extension__ ({ \ | |
| 104 | (__m256i)_mm256_mask_gf2p8affine_epi64_epi8((__m256i)_mm256_setzero_si256(), \ | |
| 105 | U, A, B, I); }) | |
| 106 | ||
| 107 | ||
| 108 | #define _mm512_gf2p8affine_epi64_epi8(A, B, I) __extension__ ({ \ | |
| 109 | (__m512i)__builtin_ia32_vgf2p8affineqb_v64qi((__v64qi)(__m512i)(A), \ | |
| 110 | (__v64qi)(__m512i)(B), \ | |
| 111 | (char)(I)); }) | |
| 112 | ||
| 113 | #define _mm512_mask_gf2p8affine_epi64_epi8(S, U, A, B, I) __extension__ ({ \ | |
| 114 | (__m512i)__builtin_ia32_selectb_512((__mmask64)(U), \ | |
| 115 | (__v64qi)_mm512_gf2p8affine_epi64_epi8(A, B, I), \ | |
| 116 | (__v64qi)(__m512i)(S)); }) | |
| 117 | ||
| 118 | #define _mm512_maskz_gf2p8affine_epi64_epi8(U, A, B, I) __extension__ ({ \ | |
| 119 | (__m512i)_mm512_mask_gf2p8affine_epi64_epi8((__m512i)_mm512_setzero_qi(), \ | |
| 120 | U, A, B, I); }) | |
| 121 | ||
| 122 | /* Default attributes for simple form (no masking). */ | |
| 123 | #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("gfni"))) | |
| 124 | ||
| 125 | /* Default attributes for ZMM forms. */ | |
| 126 | #define __DEFAULT_FN_ATTRS_F __attribute__((__always_inline__, __nodebug__, __target__("avx512bw,gfni"))) | |
| 127 | ||
| 128 | /* Default attributes for VLX forms. */ | |
| 129 | #define __DEFAULT_FN_ATTRS_VL __attribute__((__always_inline__, __nodebug__, __target__("avx512bw,avx512vl,gfni"))) | |
| 130 | ||
| 131 | static __inline__ __m128i __DEFAULT_FN_ATTRS | |
| 132 | _mm_gf2p8mul_epi8(__m128i __A, __m128i __B) | |
| 133 | { | |
| 134 | return (__m128i) __builtin_ia32_vgf2p8mulb_v16qi((__v16qi) __A, | |
| 135 | (__v16qi) __B); | |
| 136 | } | |
| 137 | ||
| 138 | static __inline__ __m128i __DEFAULT_FN_ATTRS_VL | |
| 139 | _mm_mask_gf2p8mul_epi8(__m128i __S, __mmask16 __U, __m128i __A, __m128i __B) | |
| 140 | { | |
| 141 | return (__m128i) __builtin_ia32_selectb_128(__U, | |
| 142 | (__v16qi) _mm_gf2p8mul_epi8(__A, __B), | |
| 143 | (__v16qi) __S); | |
| 144 | } | |
| 145 | ||
| 146 | static __inline__ __m128i __DEFAULT_FN_ATTRS_VL | |
| 147 | _mm_maskz_gf2p8mul_epi8(__mmask16 __U, __m128i __A, __m128i __B) | |
| 148 | { | |
| 149 | return _mm_mask_gf2p8mul_epi8((__m128i)_mm_setzero_si128(), | |
| 150 | __U, __A, __B); | |
| 151 | } | |
| 152 | ||
| 153 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 154 | _mm256_gf2p8mul_epi8(__m256i __A, __m256i __B) | |
| 155 | { | |
| 156 | return (__m256i) __builtin_ia32_vgf2p8mulb_v32qi((__v32qi) __A, | |
| 157 | (__v32qi) __B); | |
| 158 | } | |
| 159 | ||
| 160 | static __inline__ __m256i __DEFAULT_FN_ATTRS_VL | |
| 161 | _mm256_mask_gf2p8mul_epi8(__m256i __S, __mmask32 __U, __m256i __A, __m256i __B) | |
| 162 | { | |
| 163 | return (__m256i) __builtin_ia32_selectb_256(__U, | |
| 164 | (__v32qi) _mm256_gf2p8mul_epi8(__A, __B), | |
| 165 | (__v32qi) __S); | |
| 166 | } | |
| 167 | ||
| 168 | static __inline__ __m256i __DEFAULT_FN_ATTRS_VL | |
| 169 | _mm256_maskz_gf2p8mul_epi8(__mmask32 __U, __m256i __A, __m256i __B) | |
| 170 | { | |
| 171 | return _mm256_mask_gf2p8mul_epi8((__m256i)_mm256_setzero_si256(), | |
| 172 | __U, __A, __B); | |
| 173 | } | |
| 174 | ||
| 175 | static __inline__ __m512i __DEFAULT_FN_ATTRS_F | |
| 176 | _mm512_gf2p8mul_epi8(__m512i __A, __m512i __B) | |
| 177 | { | |
| 178 | return (__m512i) __builtin_ia32_vgf2p8mulb_v64qi((__v64qi) __A, | |
| 179 | (__v64qi) __B); | |
| 180 | } | |
| 181 | ||
| 182 | static __inline__ __m512i __DEFAULT_FN_ATTRS_F | |
| 183 | _mm512_mask_gf2p8mul_epi8(__m512i __S, __mmask64 __U, __m512i __A, __m512i __B) | |
| 184 | { | |
| 185 | return (__m512i) __builtin_ia32_selectb_512(__U, | |
| 186 | (__v64qi) _mm512_gf2p8mul_epi8(__A, __B), | |
| 187 | (__v64qi) __S); | |
| 188 | } | |
| 189 | ||
| 190 | static __inline__ __m512i __DEFAULT_FN_ATTRS_F | |
| 191 | _mm512_maskz_gf2p8mul_epi8(__mmask64 __U, __m512i __A, __m512i __B) | |
| 192 | { | |
| 193 | return _mm512_mask_gf2p8mul_epi8((__m512i)_mm512_setzero_qi(), | |
| 194 | __U, __A, __B); | |
| 195 | } | |
| 196 | ||
| 197 | #undef __DEFAULT_FN_ATTRS | |
| 198 | #undef __DEFAULT_FN_ATTRS_F | |
| 199 | #undef __DEFAULT_FN_ATTRS_VL | |
| 200 | ||
| 201 | #endif // __GFNIINTRIN_H | |
| 202 |
c_headers/immintrin.h+52| ... | ... | @@ -58,6 +58,10 @@ |
| 58 | 58 | #include <clflushoptintrin.h> |
| 59 | 59 | #endif |
| 60 | 60 | |
| 61 | #if !defined(_MSC_VER) || __has_feature(modules) || defined(__CLWB__) | |
| 62 | #include <clwbintrin.h> | |
| 63 | #endif | |
| 64 | ||
| 61 | 65 | #if !defined(_MSC_VER) || __has_feature(modules) || defined(__AVX__) |
| 62 | 66 | #include <avxintrin.h> |
| 63 | 67 | #endif |
| ... | ... | @@ -114,6 +118,10 @@ _mm256_cvtph_ps(__m128i __a) |
| 114 | 118 | } |
| 115 | 119 | #endif /* __AVX2__ */ |
| 116 | 120 | |
| 121 | #if !defined(_MSC_VER) || __has_feature(modules) || defined(__VPCLMULQDQ__) | |
| 122 | #include <vpclmulqdqintrin.h> | |
| 123 | #endif | |
| 124 | ||
| 117 | 125 | #if !defined(_MSC_VER) || __has_feature(modules) || defined(__BMI__) |
| 118 | 126 | #include <bmiintrin.h> |
| 119 | 127 | #endif |
| ... | ... | @@ -142,6 +150,10 @@ _mm256_cvtph_ps(__m128i __a) |
| 142 | 150 | #include <avx512bwintrin.h> |
| 143 | 151 | #endif |
| 144 | 152 | |
| 153 | #if !defined(_MSC_VER) || __has_feature(modules) || defined(__AVX512BITALG__) | |
| 154 | #include <avx512bitalgintrin.h> | |
| 155 | #endif | |
| 156 | ||
| 145 | 157 | #if !defined(_MSC_VER) || __has_feature(modules) || defined(__AVX512CD__) |
| 146 | 158 | #include <avx512cdintrin.h> |
| 147 | 159 | #endif |
| ... | ... | @@ -150,10 +162,29 @@ _mm256_cvtph_ps(__m128i __a) |
| 150 | 162 | #include <avx512vpopcntdqintrin.h> |
| 151 | 163 | #endif |
| 152 | 164 | |
| 165 | #if !defined(_MSC_VER) || __has_feature(modules) || \ | |
| 166 | (defined(__AVX512VL__) && defined(__AVX512VPOPCNTDQ__)) | |
| 167 | #include <avx512vpopcntdqvlintrin.h> | |
| 168 | #endif | |
| 169 | ||
| 170 | #if !defined(_MSC_VER) || __has_feature(modules) || defined(__AVX512VNNI__) | |
| 171 | #include <avx512vnniintrin.h> | |
| 172 | #endif | |
| 173 | ||
| 174 | #if !defined(_MSC_VER) || __has_feature(modules) || \ | |
| 175 | (defined(__AVX512VL__) && defined(__AVX512VNNI__)) | |
| 176 | #include <avx512vlvnniintrin.h> | |
| 177 | #endif | |
| 178 | ||
| 153 | 179 | #if !defined(_MSC_VER) || __has_feature(modules) || defined(__AVX512DQ__) |
| 154 | 180 | #include <avx512dqintrin.h> |
| 155 | 181 | #endif |
| 156 | 182 | |
| 183 | #if !defined(_MSC_VER) || __has_feature(modules) || \ | |
| 184 | (defined(__AVX512VL__) && defined(__AVX512BITALG__)) | |
| 185 | #include <avx512vlbitalgintrin.h> | |
| 186 | #endif | |
| 187 | ||
| 157 | 188 | #if !defined(_MSC_VER) || __has_feature(modules) || \ |
| 158 | 189 | (defined(__AVX512VL__) && defined(__AVX512BW__)) |
| 159 | 190 | #include <avx512vlbwintrin.h> |
| ... | ... | @@ -191,6 +222,15 @@ _mm256_cvtph_ps(__m128i __a) |
| 191 | 222 | #include <avx512vbmivlintrin.h> |
| 192 | 223 | #endif |
| 193 | 224 | |
| 225 | #if !defined(_MSC_VER) || __has_feature(modules) || defined(__AVX512VBMI2__) | |
| 226 | #include <avx512vbmi2intrin.h> | |
| 227 | #endif | |
| 228 | ||
| 229 | #if !defined(_MSC_VER) || __has_feature(modules) || \ | |
| 230 | (defined(__AVX512VBMI2__) && defined(__AVX512VL__)) | |
| 231 | #include <avx512vlvbmi2intrin.h> | |
| 232 | #endif | |
| 233 | ||
| 194 | 234 | #if !defined(_MSC_VER) || __has_feature(modules) || defined(__AVX512PF__) |
| 195 | 235 | #include <avx512pfintrin.h> |
| 196 | 236 | #endif |
| ... | ... | @@ -199,6 +239,14 @@ _mm256_cvtph_ps(__m128i __a) |
| 199 | 239 | #include <pkuintrin.h> |
| 200 | 240 | #endif |
| 201 | 241 | |
| 242 | #if !defined(_MSC_VER) || __has_feature(modules) || defined(__VAES__) | |
| 243 | #include <vaesintrin.h> | |
| 244 | #endif | |
| 245 | ||
| 246 | #if !defined(_MSC_VER) || __has_feature(modules) || defined(__GFNI__) | |
| 247 | #include <gfniintrin.h> | |
| 248 | #endif | |
| 249 | ||
| 202 | 250 | #if !defined(_MSC_VER) || __has_feature(modules) || defined(__RDRND__) |
| 203 | 251 | static __inline__ int __attribute__((__always_inline__, __nodebug__, __target__("rdrnd"))) |
| 204 | 252 | _rdrand16_step(unsigned short *__p) |
| ... | ... | @@ -315,6 +363,10 @@ _writegsbase_u64(unsigned long long __V) |
| 315 | 363 | #include <xsavesintrin.h> |
| 316 | 364 | #endif |
| 317 | 365 | |
| 366 | #if !defined(_MSC_VER) || __has_feature(modules) || defined(__SHSTK__) | |
| 367 | #include <cetintrin.h> | |
| 368 | #endif | |
| 369 | ||
| 318 | 370 | /* Some intrinsics inside adxintrin.h are available only on processors with ADX, |
| 319 | 371 | * whereas others are also available at all times. */ |
| 320 | 372 | #include <adxintrin.h> |
c_headers/intrin.h+5-1| ... | ... | @@ -38,6 +38,10 @@ |
| 38 | 38 | #include <armintr.h> |
| 39 | 39 | #endif |
| 40 | 40 | |
| 41 | #if defined(_M_ARM64) | |
| 42 | #include <arm64intr.h> | |
| 43 | #endif | |
| 44 | ||
| 41 | 45 | /* For the definition of jmp_buf. */ |
| 42 | 46 | #if __STDC_HOSTED__ |
| 43 | 47 | #include <setjmp.h> |
| ... | ... | @@ -828,7 +832,7 @@ _InterlockedCompareExchange_nf(long volatile *_Destination, |
| 828 | 832 | __ATOMIC_SEQ_CST, __ATOMIC_RELAXED); |
| 829 | 833 | return _Comparand; |
| 830 | 834 | } |
| 831 | static __inline__ short __DEFAULT_FN_ATTRS | |
| 835 | static __inline__ long __DEFAULT_FN_ATTRS | |
| 832 | 836 | _InterlockedCompareExchange_rel(long volatile *_Destination, |
| 833 | 837 | long _Exchange, long _Comparand) { |
| 834 | 838 | __atomic_compare_exchange(_Destination, &_Comparand, &_Exchange, 0, |
c_headers/opencl-c.h+330-336| ... | ... | @@ -11381,6 +11381,8 @@ half16 __ovld __cnfn bitselect(half16 a, half16 b, half16 c); |
| 11381 | 11381 | * For each component of a vector type, |
| 11382 | 11382 | * result[i] = if MSB of c[i] is set ? b[i] : a[i]. |
| 11383 | 11383 | * For a scalar type, result = c ? b : a. |
| 11384 | * b and a must have the same type. | |
| 11385 | * c must have the same number of elements and bits as a. | |
| 11384 | 11386 | */ |
| 11385 | 11387 | char __ovld __cnfn select(char a, char b, char c); |
| 11386 | 11388 | uchar __ovld __cnfn select(uchar a, uchar b, char c); |
| ... | ... | @@ -11394,60 +11396,7 @@ char8 __ovld __cnfn select(char8 a, char8 b, char8 c); |
| 11394 | 11396 | uchar8 __ovld __cnfn select(uchar8 a, uchar8 b, char8 c); |
| 11395 | 11397 | char16 __ovld __cnfn select(char16 a, char16 b, char16 c); |
| 11396 | 11398 | uchar16 __ovld __cnfn select(uchar16 a, uchar16 b, char16 c); |
| 11397 | short __ovld __cnfn select(short a, short b, char c); | |
| 11398 | ushort __ovld __cnfn select(ushort a, ushort b, char c); | |
| 11399 | short2 __ovld __cnfn select(short2 a, short2 b, char2 c); | |
| 11400 | ushort2 __ovld __cnfn select(ushort2 a, ushort2 b, char2 c); | |
| 11401 | short3 __ovld __cnfn select(short3 a, short3 b, char3 c); | |
| 11402 | ushort3 __ovld __cnfn select(ushort3 a, ushort3 b, char3 c); | |
| 11403 | short4 __ovld __cnfn select(short4 a, short4 b, char4 c); | |
| 11404 | ushort4 __ovld __cnfn select(ushort4 a, ushort4 b, char4 c); | |
| 11405 | short8 __ovld __cnfn select(short8 a, short8 b, char8 c); | |
| 11406 | ushort8 __ovld __cnfn select(ushort8 a, ushort8 b, char8 c); | |
| 11407 | short16 __ovld __cnfn select(short16 a, short16 b, char16 c); | |
| 11408 | ushort16 __ovld __cnfn select(ushort16 a, ushort16 b, char16 c); | |
| 11409 | int __ovld __cnfn select(int a, int b, char c); | |
| 11410 | uint __ovld __cnfn select(uint a, uint b, char c); | |
| 11411 | int2 __ovld __cnfn select(int2 a, int2 b, char2 c); | |
| 11412 | uint2 __ovld __cnfn select(uint2 a, uint2 b, char2 c); | |
| 11413 | int3 __ovld __cnfn select(int3 a, int3 b, char3 c); | |
| 11414 | uint3 __ovld __cnfn select(uint3 a, uint3 b, char3 c); | |
| 11415 | int4 __ovld __cnfn select(int4 a, int4 b, char4 c); | |
| 11416 | uint4 __ovld __cnfn select(uint4 a, uint4 b, char4 c); | |
| 11417 | int8 __ovld __cnfn select(int8 a, int8 b, char8 c); | |
| 11418 | uint8 __ovld __cnfn select(uint8 a, uint8 b, char8 c); | |
| 11419 | int16 __ovld __cnfn select(int16 a, int16 b, char16 c); | |
| 11420 | uint16 __ovld __cnfn select(uint16 a, uint16 b, char16 c); | |
| 11421 | long __ovld __cnfn select(long a, long b, char c); | |
| 11422 | ulong __ovld __cnfn select(ulong a, ulong b, char c); | |
| 11423 | long2 __ovld __cnfn select(long2 a, long2 b, char2 c); | |
| 11424 | ulong2 __ovld __cnfn select(ulong2 a, ulong2 b, char2 c); | |
| 11425 | long3 __ovld __cnfn select(long3 a, long3 b, char3 c); | |
| 11426 | ulong3 __ovld __cnfn select(ulong3 a, ulong3 b, char3 c); | |
| 11427 | long4 __ovld __cnfn select(long4 a, long4 b, char4 c); | |
| 11428 | ulong4 __ovld __cnfn select(ulong4 a, ulong4 b, char4 c); | |
| 11429 | long8 __ovld __cnfn select(long8 a, long8 b, char8 c); | |
| 11430 | ulong8 __ovld __cnfn select(ulong8 a, ulong8 b, char8 c); | |
| 11431 | long16 __ovld __cnfn select(long16 a, long16 b, char16 c); | |
| 11432 | ulong16 __ovld __cnfn select(ulong16 a, ulong16 b, char16 c); | |
| 11433 | float __ovld __cnfn select(float a, float b, char c); | |
| 11434 | float2 __ovld __cnfn select(float2 a, float2 b, char2 c); | |
| 11435 | float3 __ovld __cnfn select(float3 a, float3 b, char3 c); | |
| 11436 | float4 __ovld __cnfn select(float4 a, float4 b, char4 c); | |
| 11437 | float8 __ovld __cnfn select(float8 a, float8 b, char8 c); | |
| 11438 | float16 __ovld __cnfn select(float16 a, float16 b, char16 c); | |
| 11439 | char __ovld __cnfn select(char a, char b, short c); | |
| 11440 | uchar __ovld __cnfn select(uchar a, uchar b, short c); | |
| 11441 | char2 __ovld __cnfn select(char2 a, char2 b, short2 c); | |
| 11442 | uchar2 __ovld __cnfn select(uchar2 a, uchar2 b, short2 c); | |
| 11443 | char3 __ovld __cnfn select(char3 a, char3 b, short3 c); | |
| 11444 | uchar3 __ovld __cnfn select(uchar3 a, uchar3 b, short3 c); | |
| 11445 | char4 __ovld __cnfn select(char4 a, char4 b, short4 c); | |
| 11446 | uchar4 __ovld __cnfn select(uchar4 a, uchar4 b, short4 c); | |
| 11447 | char8 __ovld __cnfn select(char8 a, char8 b, short8 c); | |
| 11448 | uchar8 __ovld __cnfn select(uchar8 a, uchar8 b, short8 c); | |
| 11449 | char16 __ovld __cnfn select(char16 a, char16 b, short16 c); | |
| 11450 | uchar16 __ovld __cnfn select(uchar16 a, uchar16 b, short16 c); | |
| 11399 | ||
| 11451 | 11400 | short __ovld __cnfn select(short a, short b, short c); |
| 11452 | 11401 | ushort __ovld __cnfn select(ushort a, ushort b, short c); |
| 11453 | 11402 | short2 __ovld __cnfn select(short2 a, short2 b, short2 c); |
| ... | ... | @@ -11460,60 +11409,7 @@ short8 __ovld __cnfn select(short8 a, short8 b, short8 c); |
| 11460 | 11409 | ushort8 __ovld __cnfn select(ushort8 a, ushort8 b, short8 c); |
| 11461 | 11410 | short16 __ovld __cnfn select(short16 a, short16 b, short16 c); |
| 11462 | 11411 | ushort16 __ovld __cnfn select(ushort16 a, ushort16 b, short16 c); |
| 11463 | int __ovld __cnfn select(int a, int b, short c); | |
| 11464 | uint __ovld __cnfn select(uint a, uint b, short c); | |
| 11465 | int2 __ovld __cnfn select(int2 a, int2 b, short2 c); | |
| 11466 | uint2 __ovld __cnfn select(uint2 a, uint2 b, short2 c); | |
| 11467 | int3 __ovld __cnfn select(int3 a, int3 b, short3 c); | |
| 11468 | uint3 __ovld __cnfn select(uint3 a, uint3 b, short3 c); | |
| 11469 | int4 __ovld __cnfn select(int4 a, int4 b, short4 c); | |
| 11470 | uint4 __ovld __cnfn select(uint4 a, uint4 b, short4 c); | |
| 11471 | int8 __ovld __cnfn select(int8 a, int8 b, short8 c); | |
| 11472 | uint8 __ovld __cnfn select(uint8 a, uint8 b, short8 c); | |
| 11473 | int16 __ovld __cnfn select(int16 a, int16 b, short16 c); | |
| 11474 | uint16 __ovld __cnfn select(uint16 a, uint16 b, short16 c); | |
| 11475 | long __ovld __cnfn select(long a, long b, short c); | |
| 11476 | ulong __ovld __cnfn select(ulong a, ulong b, short c); | |
| 11477 | long2 __ovld __cnfn select(long2 a, long2 b, short2 c); | |
| 11478 | ulong2 __ovld __cnfn select(ulong2 a, ulong2 b, short2 c); | |
| 11479 | long3 __ovld __cnfn select(long3 a, long3 b, short3 c); | |
| 11480 | ulong3 __ovld __cnfn select(ulong3 a, ulong3 b, short3 c); | |
| 11481 | long4 __ovld __cnfn select(long4 a, long4 b, short4 c); | |
| 11482 | ulong4 __ovld __cnfn select(ulong4 a, ulong4 b, short4 c); | |
| 11483 | long8 __ovld __cnfn select(long8 a, long8 b, short8 c); | |
| 11484 | ulong8 __ovld __cnfn select(ulong8 a, ulong8 b, short8 c); | |
| 11485 | long16 __ovld __cnfn select(long16 a, long16 b, short16 c); | |
| 11486 | ulong16 __ovld __cnfn select(ulong16 a, ulong16 b, short16 c); | |
| 11487 | float __ovld __cnfn select(float a, float b, short c); | |
| 11488 | float2 __ovld __cnfn select(float2 a, float2 b, short2 c); | |
| 11489 | float3 __ovld __cnfn select(float3 a, float3 b, short3 c); | |
| 11490 | float4 __ovld __cnfn select(float4 a, float4 b, short4 c); | |
| 11491 | float8 __ovld __cnfn select(float8 a, float8 b, short8 c); | |
| 11492 | float16 __ovld __cnfn select(float16 a, float16 b, short16 c); | |
| 11493 | char __ovld __cnfn select(char a, char b, int c); | |
| 11494 | uchar __ovld __cnfn select(uchar a, uchar b, int c); | |
| 11495 | char2 __ovld __cnfn select(char2 a, char2 b, int2 c); | |
| 11496 | uchar2 __ovld __cnfn select(uchar2 a, uchar2 b, int2 c); | |
| 11497 | char3 __ovld __cnfn select(char3 a, char3 b, int3 c); | |
| 11498 | uchar3 __ovld __cnfn select(uchar3 a, uchar3 b, int3 c); | |
| 11499 | char4 __ovld __cnfn select(char4 a, char4 b, int4 c); | |
| 11500 | uchar4 __ovld __cnfn select(uchar4 a, uchar4 b, int4 c); | |
| 11501 | char8 __ovld __cnfn select(char8 a, char8 b, int8 c); | |
| 11502 | uchar8 __ovld __cnfn select(uchar8 a, uchar8 b, int8 c); | |
| 11503 | char16 __ovld __cnfn select(char16 a, char16 b, int16 c); | |
| 11504 | uchar16 __ovld __cnfn select(uchar16 a, uchar16 b, int16 c); | |
| 11505 | short __ovld __cnfn select(short a, short b, int c); | |
| 11506 | ushort __ovld __cnfn select(ushort a, ushort b, int c); | |
| 11507 | short2 __ovld __cnfn select(short2 a, short2 b, int2 c); | |
| 11508 | ushort2 __ovld __cnfn select(ushort2 a, ushort2 b, int2 c); | |
| 11509 | short3 __ovld __cnfn select(short3 a, short3 b, int3 c); | |
| 11510 | ushort3 __ovld __cnfn select(ushort3 a, ushort3 b, int3 c); | |
| 11511 | short4 __ovld __cnfn select(short4 a, short4 b, int4 c); | |
| 11512 | ushort4 __ovld __cnfn select(ushort4 a, ushort4 b, int4 c); | |
| 11513 | short8 __ovld __cnfn select(short8 a, short8 b, int8 c); | |
| 11514 | ushort8 __ovld __cnfn select(ushort8 a, ushort8 b, int8 c); | |
| 11515 | short16 __ovld __cnfn select(short16 a, short16 b, int16 c); | |
| 11516 | ushort16 __ovld __cnfn select(ushort16 a, ushort16 b, int16 c); | |
| 11412 | ||
| 11517 | 11413 | int __ovld __cnfn select(int a, int b, int c); |
| 11518 | 11414 | uint __ovld __cnfn select(uint a, uint b, int c); |
| 11519 | 11415 | int2 __ovld __cnfn select(int2 a, int2 b, int2 c); |
| ... | ... | @@ -11526,60 +11422,13 @@ int8 __ovld __cnfn select(int8 a, int8 b, int8 c); |
| 11526 | 11422 | uint8 __ovld __cnfn select(uint8 a, uint8 b, int8 c); |
| 11527 | 11423 | int16 __ovld __cnfn select(int16 a, int16 b, int16 c); |
| 11528 | 11424 | uint16 __ovld __cnfn select(uint16 a, uint16 b, int16 c); |
| 11529 | long __ovld __cnfn select(long a, long b, int c); | |
| 11530 | ulong __ovld __cnfn select(ulong a, ulong b, int c); | |
| 11531 | long2 __ovld __cnfn select(long2 a, long2 b, int2 c); | |
| 11532 | ulong2 __ovld __cnfn select(ulong2 a, ulong2 b, int2 c); | |
| 11533 | long3 __ovld __cnfn select(long3 a, long3 b, int3 c); | |
| 11534 | ulong3 __ovld __cnfn select(ulong3 a, ulong3 b, int3 c); | |
| 11535 | long4 __ovld __cnfn select(long4 a, long4 b, int4 c); | |
| 11536 | ulong4 __ovld __cnfn select(ulong4 a, ulong4 b, int4 c); | |
| 11537 | long8 __ovld __cnfn select(long8 a, long8 b, int8 c); | |
| 11538 | ulong8 __ovld __cnfn select(ulong8 a, ulong8 b, int8 c); | |
| 11539 | long16 __ovld __cnfn select(long16 a, long16 b, int16 c); | |
| 11540 | ulong16 __ovld __cnfn select(ulong16 a, ulong16 b, int16 c); | |
| 11541 | 11425 | float __ovld __cnfn select(float a, float b, int c); |
| 11542 | 11426 | float2 __ovld __cnfn select(float2 a, float2 b, int2 c); |
| 11543 | 11427 | float3 __ovld __cnfn select(float3 a, float3 b, int3 c); |
| 11544 | 11428 | float4 __ovld __cnfn select(float4 a, float4 b, int4 c); |
| 11545 | 11429 | float8 __ovld __cnfn select(float8 a, float8 b, int8 c); |
| 11546 | 11430 | float16 __ovld __cnfn select(float16 a, float16 b, int16 c); |
| 11547 | char __ovld __cnfn select(char a, char b, long c); | |
| 11548 | uchar __ovld __cnfn select(uchar a, uchar b, long c); | |
| 11549 | char2 __ovld __cnfn select(char2 a, char2 b, long2 c); | |
| 11550 | uchar2 __ovld __cnfn select(uchar2 a, uchar2 b, long2 c); | |
| 11551 | char3 __ovld __cnfn select(char3 a, char3 b, long3 c); | |
| 11552 | uchar3 __ovld __cnfn select(uchar3 a, uchar3 b, long3 c); | |
| 11553 | char4 __ovld __cnfn select(char4 a, char4 b, long4 c); | |
| 11554 | uchar4 __ovld __cnfn select(uchar4 a, uchar4 b, long4 c); | |
| 11555 | char8 __ovld __cnfn select(char8 a, char8 b, long8 c); | |
| 11556 | uchar8 __ovld __cnfn select(uchar8 a, uchar8 b, long8 c); | |
| 11557 | char16 __ovld __cnfn select(char16 a, char16 b, long16 c); | |
| 11558 | uchar16 __ovld __cnfn select(uchar16 a, uchar16 b, long16 c); | |
| 11559 | short __ovld __cnfn select(short a, short b, long c); | |
| 11560 | ushort __ovld __cnfn select(ushort a, ushort b, long c); | |
| 11561 | short2 __ovld __cnfn select(short2 a, short2 b, long2 c); | |
| 11562 | ushort2 __ovld __cnfn select(ushort2 a, ushort2 b, long2 c); | |
| 11563 | short3 __ovld __cnfn select(short3 a, short3 b, long3 c); | |
| 11564 | ushort3 __ovld __cnfn select(ushort3 a, ushort3 b, long3 c); | |
| 11565 | short4 __ovld __cnfn select(short4 a, short4 b, long4 c); | |
| 11566 | ushort4 __ovld __cnfn select(ushort4 a, ushort4 b, long4 c); | |
| 11567 | short8 __ovld __cnfn select(short8 a, short8 b, long8 c); | |
| 11568 | ushort8 __ovld __cnfn select(ushort8 a, ushort8 b, long8 c); | |
| 11569 | short16 __ovld __cnfn select(short16 a, short16 b, long16 c); | |
| 11570 | ushort16 __ovld __cnfn select(ushort16 a, ushort16 b, long16 c); | |
| 11571 | int __ovld __cnfn select(int a, int b, long c); | |
| 11572 | uint __ovld __cnfn select(uint a, uint b, long c); | |
| 11573 | int2 __ovld __cnfn select(int2 a, int2 b, long2 c); | |
| 11574 | uint2 __ovld __cnfn select(uint2 a, uint2 b, long2 c); | |
| 11575 | int3 __ovld __cnfn select(int3 a, int3 b, long3 c); | |
| 11576 | uint3 __ovld __cnfn select(uint3 a, uint3 b, long3 c); | |
| 11577 | int4 __ovld __cnfn select(int4 a, int4 b, long4 c); | |
| 11578 | uint4 __ovld __cnfn select(uint4 a, uint4 b, long4 c); | |
| 11579 | int8 __ovld __cnfn select(int8 a, int8 b, long8 c); | |
| 11580 | uint8 __ovld __cnfn select(uint8 a, uint8 b, long8 c); | |
| 11581 | int16 __ovld __cnfn select(int16 a, int16 b, long16 c); | |
| 11582 | uint16 __ovld __cnfn select(uint16 a, uint16 b, long16 c); | |
| 11431 | ||
| 11583 | 11432 | long __ovld __cnfn select(long a, long b, long c); |
| 11584 | 11433 | ulong __ovld __cnfn select(ulong a, ulong b, long c); |
| 11585 | 11434 | long2 __ovld __cnfn select(long2 a, long2 b, long2 c); |
| ... | ... | @@ -11592,12 +11441,7 @@ long8 __ovld __cnfn select(long8 a, long8 b, long8 c); |
| 11592 | 11441 | ulong8 __ovld __cnfn select(ulong8 a, ulong8 b, long8 c); |
| 11593 | 11442 | long16 __ovld __cnfn select(long16 a, long16 b, long16 c); |
| 11594 | 11443 | ulong16 __ovld __cnfn select(ulong16 a, ulong16 b, long16 c); |
| 11595 | float __ovld __cnfn select(float a, float b, long c); | |
| 11596 | float2 __ovld __cnfn select(float2 a, float2 b, long2 c); | |
| 11597 | float3 __ovld __cnfn select(float3 a, float3 b, long3 c); | |
| 11598 | float4 __ovld __cnfn select(float4 a, float4 b, long4 c); | |
| 11599 | float8 __ovld __cnfn select(float8 a, float8 b, long8 c); | |
| 11600 | float16 __ovld __cnfn select(float16 a, float16 b, long16 c); | |
| 11444 | ||
| 11601 | 11445 | char __ovld __cnfn select(char a, char b, uchar c); |
| 11602 | 11446 | uchar __ovld __cnfn select(uchar a, uchar b, uchar c); |
| 11603 | 11447 | char2 __ovld __cnfn select(char2 a, char2 b, uchar2 c); |
| ... | ... | @@ -11610,60 +11454,7 @@ char8 __ovld __cnfn select(char8 a, char8 b, uchar8 c); |
| 11610 | 11454 | uchar8 __ovld __cnfn select(uchar8 a, uchar8 b, uchar8 c); |
| 11611 | 11455 | char16 __ovld __cnfn select(char16 a, char16 b, uchar16 c); |
| 11612 | 11456 | uchar16 __ovld __cnfn select(uchar16 a, uchar16 b, uchar16 c); |
| 11613 | short __ovld __cnfn select(short a, short b, uchar c); | |
| 11614 | ushort __ovld __cnfn select(ushort a, ushort b, uchar c); | |
| 11615 | short2 __ovld __cnfn select(short2 a, short2 b, uchar2 c); | |
| 11616 | ushort2 __ovld __cnfn select(ushort2 a, ushort2 b, uchar2 c); | |
| 11617 | short3 __ovld __cnfn select(short3 a, short3 b, uchar3 c); | |
| 11618 | ushort3 __ovld __cnfn select(ushort3 a, ushort3 b, uchar3 c); | |
| 11619 | short4 __ovld __cnfn select(short4 a, short4 b, uchar4 c); | |
| 11620 | ushort4 __ovld __cnfn select(ushort4 a, ushort4 b, uchar4 c); | |
| 11621 | short8 __ovld __cnfn select(short8 a, short8 b, uchar8 c); | |
| 11622 | ushort8 __ovld __cnfn select(ushort8 a, ushort8 b, uchar8 c); | |
| 11623 | short16 __ovld __cnfn select(short16 a, short16 b, uchar16 c); | |
| 11624 | ushort16 __ovld __cnfn select(ushort16 a, ushort16 b, uchar16 c); | |
| 11625 | int __ovld __cnfn select(int a, int b, uchar c); | |
| 11626 | uint __ovld __cnfn select(uint a, uint b, uchar c); | |
| 11627 | int2 __ovld __cnfn select(int2 a, int2 b, uchar2 c); | |
| 11628 | uint2 __ovld __cnfn select(uint2 a, uint2 b, uchar2 c); | |
| 11629 | int3 __ovld __cnfn select(int3 a, int3 b, uchar3 c); | |
| 11630 | uint3 __ovld __cnfn select(uint3 a, uint3 b, uchar3 c); | |
| 11631 | int4 __ovld __cnfn select(int4 a, int4 b, uchar4 c); | |
| 11632 | uint4 __ovld __cnfn select(uint4 a, uint4 b, uchar4 c); | |
| 11633 | int8 __ovld __cnfn select(int8 a, int8 b, uchar8 c); | |
| 11634 | uint8 __ovld __cnfn select(uint8 a, uint8 b, uchar8 c); | |
| 11635 | int16 __ovld __cnfn select(int16 a, int16 b, uchar16 c); | |
| 11636 | uint16 __ovld __cnfn select(uint16 a, uint16 b, uchar16 c); | |
| 11637 | long __ovld __cnfn select(long a, long b, uchar c); | |
| 11638 | ulong __ovld __cnfn select(ulong a, ulong b, uchar c); | |
| 11639 | long2 __ovld __cnfn select(long2 a, long2 b, uchar2 c); | |
| 11640 | ulong2 __ovld __cnfn select(ulong2 a, ulong2 b, uchar2 c); | |
| 11641 | long3 __ovld __cnfn select(long3 a, long3 b, uchar3 c); | |
| 11642 | ulong3 __ovld __cnfn select(ulong3 a, ulong3 b, uchar3 c); | |
| 11643 | long4 __ovld __cnfn select(long4 a, long4 b, uchar4 c); | |
| 11644 | ulong4 __ovld __cnfn select(ulong4 a, ulong4 b, uchar4 c); | |
| 11645 | long8 __ovld __cnfn select(long8 a, long8 b, uchar8 c); | |
| 11646 | ulong8 __ovld __cnfn select(ulong8 a, ulong8 b, uchar8 c); | |
| 11647 | long16 __ovld __cnfn select(long16 a, long16 b, uchar16 c); | |
| 11648 | ulong16 __ovld __cnfn select(ulong16 a, ulong16 b, uchar16 c); | |
| 11649 | float __ovld __cnfn select(float a, float b, uchar c); | |
| 11650 | float2 __ovld __cnfn select(float2 a, float2 b, uchar2 c); | |
| 11651 | float3 __ovld __cnfn select(float3 a, float3 b, uchar3 c); | |
| 11652 | float4 __ovld __cnfn select(float4 a, float4 b, uchar4 c); | |
| 11653 | float8 __ovld __cnfn select(float8 a, float8 b, uchar8 c); | |
| 11654 | float16 __ovld __cnfn select(float16 a, float16 b, uchar16 c); | |
| 11655 | char __ovld __cnfn select(char a, char b, ushort c); | |
| 11656 | uchar __ovld __cnfn select(uchar a, uchar b, ushort c); | |
| 11657 | char2 __ovld __cnfn select(char2 a, char2 b, ushort2 c); | |
| 11658 | uchar2 __ovld __cnfn select(uchar2 a, uchar2 b, ushort2 c); | |
| 11659 | char3 __ovld __cnfn select(char3 a, char3 b, ushort3 c); | |
| 11660 | uchar3 __ovld __cnfn select(uchar3 a, uchar3 b, ushort3 c); | |
| 11661 | char4 __ovld __cnfn select(char4 a, char4 b, ushort4 c); | |
| 11662 | uchar4 __ovld __cnfn select(uchar4 a, uchar4 b, ushort4 c); | |
| 11663 | char8 __ovld __cnfn select(char8 a, char8 b, ushort8 c); | |
| 11664 | uchar8 __ovld __cnfn select(uchar8 a, uchar8 b, ushort8 c); | |
| 11665 | char16 __ovld __cnfn select(char16 a, char16 b, ushort16 c); | |
| 11666 | uchar16 __ovld __cnfn select(uchar16 a, uchar16 b, ushort16 c); | |
| 11457 | ||
| 11667 | 11458 | short __ovld __cnfn select(short a, short b, ushort c); |
| 11668 | 11459 | ushort __ovld __cnfn select(ushort a, ushort b, ushort c); |
| 11669 | 11460 | short2 __ovld __cnfn select(short2 a, short2 b, ushort2 c); |
| ... | ... | @@ -11676,60 +11467,7 @@ short8 __ovld __cnfn select(short8 a, short8 b, ushort8 c); |
| 11676 | 11467 | ushort8 __ovld __cnfn select(ushort8 a, ushort8 b, ushort8 c); |
| 11677 | 11468 | short16 __ovld __cnfn select(short16 a, short16 b, ushort16 c); |
| 11678 | 11469 | ushort16 __ovld __cnfn select(ushort16 a, ushort16 b, ushort16 c); |
| 11679 | int __ovld __cnfn select(int a, int b, ushort c); | |
| 11680 | uint __ovld __cnfn select(uint a, uint b, ushort c); | |
| 11681 | int2 __ovld __cnfn select(int2 a, int2 b, ushort2 c); | |
| 11682 | uint2 __ovld __cnfn select(uint2 a, uint2 b, ushort2 c); | |
| 11683 | int3 __ovld __cnfn select(int3 a, int3 b, ushort3 c); | |
| 11684 | uint3 __ovld __cnfn select(uint3 a, uint3 b, ushort3 c); | |
| 11685 | int4 __ovld __cnfn select(int4 a, int4 b, ushort4 c); | |
| 11686 | uint4 __ovld __cnfn select(uint4 a, uint4 b, ushort4 c); | |
| 11687 | int8 __ovld __cnfn select(int8 a, int8 b, ushort8 c); | |
| 11688 | uint8 __ovld __cnfn select(uint8 a, uint8 b, ushort8 c); | |
| 11689 | int16 __ovld __cnfn select(int16 a, int16 b, ushort16 c); | |
| 11690 | uint16 __ovld __cnfn select(uint16 a, uint16 b, ushort16 c); | |
| 11691 | long __ovld __cnfn select(long a, long b, ushort c); | |
| 11692 | ulong __ovld __cnfn select(ulong a, ulong b, ushort c); | |
| 11693 | long2 __ovld __cnfn select(long2 a, long2 b, ushort2 c); | |
| 11694 | ulong2 __ovld __cnfn select(ulong2 a, ulong2 b, ushort2 c); | |
| 11695 | long3 __ovld __cnfn select(long3 a, long3 b, ushort3 c); | |
| 11696 | ulong3 __ovld __cnfn select(ulong3 a, ulong3 b, ushort3 c); | |
| 11697 | long4 __ovld __cnfn select(long4 a, long4 b, ushort4 c); | |
| 11698 | ulong4 __ovld __cnfn select(ulong4 a, ulong4 b, ushort4 c); | |
| 11699 | long8 __ovld __cnfn select(long8 a, long8 b, ushort8 c); | |
| 11700 | ulong8 __ovld __cnfn select(ulong8 a, ulong8 b, ushort8 c); | |
| 11701 | long16 __ovld __cnfn select(long16 a, long16 b, ushort16 c); | |
| 11702 | ulong16 __ovld __cnfn select(ulong16 a, ulong16 b, ushort16 c); | |
| 11703 | float __ovld __cnfn select(float a, float b, ushort c); | |
| 11704 | float2 __ovld __cnfn select(float2 a, float2 b, ushort2 c); | |
| 11705 | float3 __ovld __cnfn select(float3 a, float3 b, ushort3 c); | |
| 11706 | float4 __ovld __cnfn select(float4 a, float4 b, ushort4 c); | |
| 11707 | float8 __ovld __cnfn select(float8 a, float8 b, ushort8 c); | |
| 11708 | float16 __ovld __cnfn select(float16 a, float16 b, ushort16 c); | |
| 11709 | char __ovld __cnfn select(char a, char b, uint c); | |
| 11710 | uchar __ovld __cnfn select(uchar a, uchar b, uint c); | |
| 11711 | char2 __ovld __cnfn select(char2 a, char2 b, uint2 c); | |
| 11712 | uchar2 __ovld __cnfn select(uchar2 a, uchar2 b, uint2 c); | |
| 11713 | char3 __ovld __cnfn select(char3 a, char3 b, uint3 c); | |
| 11714 | uchar3 __ovld __cnfn select(uchar3 a, uchar3 b, uint3 c); | |
| 11715 | char4 __ovld __cnfn select(char4 a, char4 b, uint4 c); | |
| 11716 | uchar4 __ovld __cnfn select(uchar4 a, uchar4 b, uint4 c); | |
| 11717 | char8 __ovld __cnfn select(char8 a, char8 b, uint8 c); | |
| 11718 | uchar8 __ovld __cnfn select(uchar8 a, uchar8 b, uint8 c); | |
| 11719 | char16 __ovld __cnfn select(char16 a, char16 b, uint16 c); | |
| 11720 | uchar16 __ovld __cnfn select(uchar16 a, uchar16 b, uint16 c); | |
| 11721 | short __ovld __cnfn select(short a, short b, uint c); | |
| 11722 | ushort __ovld __cnfn select(ushort a, ushort b, uint c); | |
| 11723 | short2 __ovld __cnfn select(short2 a, short2 b, uint2 c); | |
| 11724 | ushort2 __ovld __cnfn select(ushort2 a, ushort2 b, uint2 c); | |
| 11725 | short3 __ovld __cnfn select(short3 a, short3 b, uint3 c); | |
| 11726 | ushort3 __ovld __cnfn select(ushort3 a, ushort3 b, uint3 c); | |
| 11727 | short4 __ovld __cnfn select(short4 a, short4 b, uint4 c); | |
| 11728 | ushort4 __ovld __cnfn select(ushort4 a, ushort4 b, uint4 c); | |
| 11729 | short8 __ovld __cnfn select(short8 a, short8 b, uint8 c); | |
| 11730 | ushort8 __ovld __cnfn select(ushort8 a, ushort8 b, uint8 c); | |
| 11731 | short16 __ovld __cnfn select(short16 a, short16 b, uint16 c); | |
| 11732 | ushort16 __ovld __cnfn select(ushort16 a, ushort16 b, uint16 c); | |
| 11470 | ||
| 11733 | 11471 | int __ovld __cnfn select(int a, int b, uint c); |
| 11734 | 11472 | uint __ovld __cnfn select(uint a, uint b, uint c); |
| 11735 | 11473 | int2 __ovld __cnfn select(int2 a, int2 b, uint2 c); |
| ... | ... | @@ -11742,60 +11480,13 @@ int8 __ovld __cnfn select(int8 a, int8 b, uint8 c); |
| 11742 | 11480 | uint8 __ovld __cnfn select(uint8 a, uint8 b, uint8 c); |
| 11743 | 11481 | int16 __ovld __cnfn select(int16 a, int16 b, uint16 c); |
| 11744 | 11482 | uint16 __ovld __cnfn select(uint16 a, uint16 b, uint16 c); |
| 11745 | long __ovld __cnfn select(long a, long b, uint c); | |
| 11746 | ulong __ovld __cnfn select(ulong a, ulong b, uint c); | |
| 11747 | long2 __ovld __cnfn select(long2 a, long2 b, uint2 c); | |
| 11748 | ulong2 __ovld __cnfn select(ulong2 a, ulong2 b, uint2 c); | |
| 11749 | long3 __ovld __cnfn select(long3 a, long3 b, uint3 c); | |
| 11750 | ulong3 __ovld __cnfn select(ulong3 a, ulong3 b, uint3 c); | |
| 11751 | long4 __ovld __cnfn select(long4 a, long4 b, uint4 c); | |
| 11752 | ulong4 __ovld __cnfn select(ulong4 a, ulong4 b, uint4 c); | |
| 11753 | long8 __ovld __cnfn select(long8 a, long8 b, uint8 c); | |
| 11754 | ulong8 __ovld __cnfn select(ulong8 a, ulong8 b, uint8 c); | |
| 11755 | long16 __ovld __cnfn select(long16 a, long16 b, uint16 c); | |
| 11756 | ulong16 __ovld __cnfn select(ulong16 a, ulong16 b, uint16 c); | |
| 11757 | 11483 | float __ovld __cnfn select(float a, float b, uint c); |
| 11758 | 11484 | float2 __ovld __cnfn select(float2 a, float2 b, uint2 c); |
| 11759 | 11485 | float3 __ovld __cnfn select(float3 a, float3 b, uint3 c); |
| 11760 | 11486 | float4 __ovld __cnfn select(float4 a, float4 b, uint4 c); |
| 11761 | 11487 | float8 __ovld __cnfn select(float8 a, float8 b, uint8 c); |
| 11762 | 11488 | float16 __ovld __cnfn select(float16 a, float16 b, uint16 c); |
| 11763 | char __ovld __cnfn select(char a, char b, ulong c); | |
| 11764 | uchar __ovld __cnfn select(uchar a, uchar b, ulong c); | |
| 11765 | char2 __ovld __cnfn select(char2 a, char2 b, ulong2 c); | |
| 11766 | uchar2 __ovld __cnfn select(uchar2 a, uchar2 b, ulong2 c); | |
| 11767 | char3 __ovld __cnfn select(char3 a, char3 b, ulong3 c); | |
| 11768 | uchar3 __ovld __cnfn select(uchar3 a, uchar3 b, ulong3 c); | |
| 11769 | char4 __ovld __cnfn select(char4 a, char4 b, ulong4 c); | |
| 11770 | uchar4 __ovld __cnfn select(uchar4 a, uchar4 b, ulong4 c); | |
| 11771 | char8 __ovld __cnfn select(char8 a, char8 b, ulong8 c); | |
| 11772 | uchar8 __ovld __cnfn select(uchar8 a, uchar8 b, ulong8 c); | |
| 11773 | char16 __ovld __cnfn select(char16 a, char16 b, ulong16 c); | |
| 11774 | uchar16 __ovld __cnfn select(uchar16 a, uchar16 b, ulong16 c); | |
| 11775 | short __ovld __cnfn select(short a, short b, ulong c); | |
| 11776 | ushort __ovld __cnfn select(ushort a, ushort b, ulong c); | |
| 11777 | short2 __ovld __cnfn select(short2 a, short2 b, ulong2 c); | |
| 11778 | ushort2 __ovld __cnfn select(ushort2 a, ushort2 b, ulong2 c); | |
| 11779 | short3 __ovld __cnfn select(short3 a, short3 b, ulong3 c); | |
| 11780 | ushort3 __ovld __cnfn select(ushort3 a, ushort3 b, ulong3 c); | |
| 11781 | short4 __ovld __cnfn select(short4 a, short4 b, ulong4 c); | |
| 11782 | ushort4 __ovld __cnfn select(ushort4 a, ushort4 b, ulong4 c); | |
| 11783 | short8 __ovld __cnfn select(short8 a, short8 b, ulong8 c); | |
| 11784 | ushort8 __ovld __cnfn select(ushort8 a, ushort8 b, ulong8 c); | |
| 11785 | short16 __ovld __cnfn select(short16 a, short16 b, ulong16 c); | |
| 11786 | ushort16 __ovld __cnfn select(ushort16 a, ushort16 b, ulong16 c); | |
| 11787 | int __ovld __cnfn select(int a, int b, ulong c); | |
| 11788 | uint __ovld __cnfn select(uint a, uint b, ulong c); | |
| 11789 | int2 __ovld __cnfn select(int2 a, int2 b, ulong2 c); | |
| 11790 | uint2 __ovld __cnfn select(uint2 a, uint2 b, ulong2 c); | |
| 11791 | int3 __ovld __cnfn select(int3 a, int3 b, ulong3 c); | |
| 11792 | uint3 __ovld __cnfn select(uint3 a, uint3 b, ulong3 c); | |
| 11793 | int4 __ovld __cnfn select(int4 a, int4 b, ulong4 c); | |
| 11794 | uint4 __ovld __cnfn select(uint4 a, uint4 b, ulong4 c); | |
| 11795 | int8 __ovld __cnfn select(int8 a, int8 b, ulong8 c); | |
| 11796 | uint8 __ovld __cnfn select(uint8 a, uint8 b, ulong8 c); | |
| 11797 | int16 __ovld __cnfn select(int16 a, int16 b, ulong16 c); | |
| 11798 | uint16 __ovld __cnfn select(uint16 a, uint16 b, ulong16 c); | |
| 11489 | ||
| 11799 | 11490 | long __ovld __cnfn select(long a, long b, ulong c); |
| 11800 | 11491 | ulong __ovld __cnfn select(ulong a, ulong b, ulong c); |
| 11801 | 11492 | long2 __ovld __cnfn select(long2 a, long2 b, ulong2 c); |
| ... | ... | @@ -11808,12 +11499,7 @@ long8 __ovld __cnfn select(long8 a, long8 b, ulong8 c); |
| 11808 | 11499 | ulong8 __ovld __cnfn select(ulong8 a, ulong8 b, ulong8 c); |
| 11809 | 11500 | long16 __ovld __cnfn select(long16 a, long16 b, ulong16 c); |
| 11810 | 11501 | ulong16 __ovld __cnfn select(ulong16 a, ulong16 b, ulong16 c); |
| 11811 | float __ovld __cnfn select(float a, float b, ulong c); | |
| 11812 | float2 __ovld __cnfn select(float2 a, float2 b, ulong2 c); | |
| 11813 | float3 __ovld __cnfn select(float3 a, float3 b, ulong3 c); | |
| 11814 | float4 __ovld __cnfn select(float4 a, float4 b, ulong4 c); | |
| 11815 | float8 __ovld __cnfn select(float8 a, float8 b, ulong8 c); | |
| 11816 | float16 __ovld __cnfn select(float16 a, float16 b, ulong16 c); | |
| 11502 | ||
| 11817 | 11503 | #ifdef cl_khr_fp64 |
| 11818 | 11504 | double __ovld __cnfn select(double a, double b, long c); |
| 11819 | 11505 | double2 __ovld __cnfn select(double2 a, double2 b, long2 c); |
| ... | ... | @@ -13141,13 +12827,14 @@ void __ovld __conv barrier(cl_mem_fence_flags flags); |
| 13141 | 12827 | |
| 13142 | 12828 | #if __OPENCL_C_VERSION__ >= CL_VERSION_2_0 |
| 13143 | 12829 | |
| 13144 | typedef enum memory_scope | |
| 13145 | { | |
| 13146 | memory_scope_work_item, | |
| 13147 | memory_scope_work_group, | |
| 13148 | memory_scope_device, | |
| 13149 | memory_scope_all_svm_devices, | |
| 13150 | memory_scope_sub_group | |
| 12830 | typedef enum memory_scope { | |
| 12831 | memory_scope_work_item = __OPENCL_MEMORY_SCOPE_WORK_ITEM, | |
| 12832 | memory_scope_work_group = __OPENCL_MEMORY_SCOPE_WORK_GROUP, | |
| 12833 | memory_scope_device = __OPENCL_MEMORY_SCOPE_DEVICE, | |
| 12834 | memory_scope_all_svm_devices = __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES, | |
| 12835 | #if defined(cl_intel_subgroups) || defined(cl_khr_subgroups) | |
| 12836 | memory_scope_sub_group = __OPENCL_MEMORY_SCOPE_SUB_GROUP | |
| 12837 | #endif | |
| 13151 | 12838 | } memory_scope; |
| 13152 | 12839 | |
| 13153 | 12840 | void __ovld __conv work_group_barrier(cl_mem_fence_flags flags, memory_scope scope); |
| ... | ... | @@ -13952,11 +13639,11 @@ unsigned long __ovld atom_xor(volatile __local unsigned long *p, unsigned long v |
| 13952 | 13639 | // enum values aligned with what clang uses in EmitAtomicExpr() |
| 13953 | 13640 | typedef enum memory_order |
| 13954 | 13641 | { |
| 13955 | memory_order_relaxed, | |
| 13956 | memory_order_acquire, | |
| 13957 | memory_order_release, | |
| 13958 | memory_order_acq_rel, | |
| 13959 | memory_order_seq_cst | |
| 13642 | memory_order_relaxed = __ATOMIC_RELAXED, | |
| 13643 | memory_order_acquire = __ATOMIC_ACQUIRE, | |
| 13644 | memory_order_release = __ATOMIC_RELEASE, | |
| 13645 | memory_order_acq_rel = __ATOMIC_ACQ_REL, | |
| 13646 | memory_order_seq_cst = __ATOMIC_SEQ_CST | |
| 13960 | 13647 | } memory_order; |
| 13961 | 13648 | |
| 13962 | 13649 | // double atomics support requires extensions cl_khr_int64_base_atomics and cl_khr_int64_extended_atomics |
| ... | ... | @@ -16199,6 +15886,313 @@ double __ovld __conv sub_group_scan_inclusive_max(double x); |
| 16199 | 15886 | |
| 16200 | 15887 | #endif //cl_khr_subgroups cl_intel_subgroups |
| 16201 | 15888 | |
| 15889 | #if defined(cl_intel_subgroups) | |
| 15890 | // Intel-Specific Sub Group Functions | |
| 15891 | float __ovld __conv intel_sub_group_shuffle( float x, uint c ); | |
| 15892 | float2 __ovld __conv intel_sub_group_shuffle( float2 x, uint c ); | |
| 15893 | float3 __ovld __conv intel_sub_group_shuffle( float3 x, uint c ); | |
| 15894 | float4 __ovld __conv intel_sub_group_shuffle( float4 x, uint c ); | |
| 15895 | float8 __ovld __conv intel_sub_group_shuffle( float8 x, uint c ); | |
| 15896 | float16 __ovld __conv intel_sub_group_shuffle( float16 x, uint c ); | |
| 15897 | ||
| 15898 | int __ovld __conv intel_sub_group_shuffle( int x, uint c ); | |
| 15899 | int2 __ovld __conv intel_sub_group_shuffle( int2 x, uint c ); | |
| 15900 | int3 __ovld __conv intel_sub_group_shuffle( int3 x, uint c ); | |
| 15901 | int4 __ovld __conv intel_sub_group_shuffle( int4 x, uint c ); | |
| 15902 | int8 __ovld __conv intel_sub_group_shuffle( int8 x, uint c ); | |
| 15903 | int16 __ovld __conv intel_sub_group_shuffle( int16 x, uint c ); | |
| 15904 | ||
| 15905 | uint __ovld __conv intel_sub_group_shuffle( uint x, uint c ); | |
| 15906 | uint2 __ovld __conv intel_sub_group_shuffle( uint2 x, uint c ); | |
| 15907 | uint3 __ovld __conv intel_sub_group_shuffle( uint3 x, uint c ); | |
| 15908 | uint4 __ovld __conv intel_sub_group_shuffle( uint4 x, uint c ); | |
| 15909 | uint8 __ovld __conv intel_sub_group_shuffle( uint8 x, uint c ); | |
| 15910 | uint16 __ovld __conv intel_sub_group_shuffle( uint16 x, uint c ); | |
| 15911 | ||
| 15912 | long __ovld __conv intel_sub_group_shuffle( long x, uint c ); | |
| 15913 | ulong __ovld __conv intel_sub_group_shuffle( ulong x, uint c ); | |
| 15914 | ||
| 15915 | float __ovld __conv intel_sub_group_shuffle_down( float cur, float next, uint c ); | |
| 15916 | float2 __ovld __conv intel_sub_group_shuffle_down( float2 cur, float2 next, uint c ); | |
| 15917 | float3 __ovld __conv intel_sub_group_shuffle_down( float3 cur, float3 next, uint c ); | |
| 15918 | float4 __ovld __conv intel_sub_group_shuffle_down( float4 cur, float4 next, uint c ); | |
| 15919 | float8 __ovld __conv intel_sub_group_shuffle_down( float8 cur, float8 next, uint c ); | |
| 15920 | float16 __ovld __conv intel_sub_group_shuffle_down( float16 cur, float16 next, uint c ); | |
| 15921 | ||
| 15922 | int __ovld __conv intel_sub_group_shuffle_down( int cur, int next, uint c ); | |
| 15923 | int2 __ovld __conv intel_sub_group_shuffle_down( int2 cur, int2 next, uint c ); | |
| 15924 | int3 __ovld __conv intel_sub_group_shuffle_down( int3 cur, int3 next, uint c ); | |
| 15925 | int4 __ovld __conv intel_sub_group_shuffle_down( int4 cur, int4 next, uint c ); | |
| 15926 | int8 __ovld __conv intel_sub_group_shuffle_down( int8 cur, int8 next, uint c ); | |
| 15927 | int16 __ovld __conv intel_sub_group_shuffle_down( int16 cur, int16 next, uint c ); | |
| 15928 | ||
| 15929 | uint __ovld __conv intel_sub_group_shuffle_down( uint cur, uint next, uint c ); | |
| 15930 | uint2 __ovld __conv intel_sub_group_shuffle_down( uint2 cur, uint2 next, uint c ); | |
| 15931 | uint3 __ovld __conv intel_sub_group_shuffle_down( uint3 cur, uint3 next, uint c ); | |
| 15932 | uint4 __ovld __conv intel_sub_group_shuffle_down( uint4 cur, uint4 next, uint c ); | |
| 15933 | uint8 __ovld __conv intel_sub_group_shuffle_down( uint8 cur, uint8 next, uint c ); | |
| 15934 | uint16 __ovld __conv intel_sub_group_shuffle_down( uint16 cur, uint16 next, uint c ); | |
| 15935 | ||
| 15936 | long __ovld __conv intel_sub_group_shuffle_down( long prev, long cur, uint c ); | |
| 15937 | ulong __ovld __conv intel_sub_group_shuffle_down( ulong prev, ulong cur, uint c ); | |
| 15938 | ||
| 15939 | float __ovld __conv intel_sub_group_shuffle_up( float prev, float cur, uint c ); | |
| 15940 | float2 __ovld __conv intel_sub_group_shuffle_up( float2 prev, float2 cur, uint c ); | |
| 15941 | float3 __ovld __conv intel_sub_group_shuffle_up( float3 prev, float3 cur, uint c ); | |
| 15942 | float4 __ovld __conv intel_sub_group_shuffle_up( float4 prev, float4 cur, uint c ); | |
| 15943 | float8 __ovld __conv intel_sub_group_shuffle_up( float8 prev, float8 cur, uint c ); | |
| 15944 | float16 __ovld __conv intel_sub_group_shuffle_up( float16 prev, float16 cur, uint c ); | |
| 15945 | ||
| 15946 | int __ovld __conv intel_sub_group_shuffle_up( int prev, int cur, uint c ); | |
| 15947 | int2 __ovld __conv intel_sub_group_shuffle_up( int2 prev, int2 cur, uint c ); | |
| 15948 | int3 __ovld __conv intel_sub_group_shuffle_up( int3 prev, int3 cur, uint c ); | |
| 15949 | int4 __ovld __conv intel_sub_group_shuffle_up( int4 prev, int4 cur, uint c ); | |
| 15950 | int8 __ovld __conv intel_sub_group_shuffle_up( int8 prev, int8 cur, uint c ); | |
| 15951 | int16 __ovld __conv intel_sub_group_shuffle_up( int16 prev, int16 cur, uint c ); | |
| 15952 | ||
| 15953 | uint __ovld __conv intel_sub_group_shuffle_up( uint prev, uint cur, uint c ); | |
| 15954 | uint2 __ovld __conv intel_sub_group_shuffle_up( uint2 prev, uint2 cur, uint c ); | |
| 15955 | uint3 __ovld __conv intel_sub_group_shuffle_up( uint3 prev, uint3 cur, uint c ); | |
| 15956 | uint4 __ovld __conv intel_sub_group_shuffle_up( uint4 prev, uint4 cur, uint c ); | |
| 15957 | uint8 __ovld __conv intel_sub_group_shuffle_up( uint8 prev, uint8 cur, uint c ); | |
| 15958 | uint16 __ovld __conv intel_sub_group_shuffle_up( uint16 prev, uint16 cur, uint c ); | |
| 15959 | ||
| 15960 | long __ovld __conv intel_sub_group_shuffle_up( long prev, long cur, uint c ); | |
| 15961 | ulong __ovld __conv intel_sub_group_shuffle_up( ulong prev, ulong cur, uint c ); | |
| 15962 | ||
| 15963 | float __ovld __conv intel_sub_group_shuffle_xor( float x, uint c ); | |
| 15964 | float2 __ovld __conv intel_sub_group_shuffle_xor( float2 x, uint c ); | |
| 15965 | float3 __ovld __conv intel_sub_group_shuffle_xor( float3 x, uint c ); | |
| 15966 | float4 __ovld __conv intel_sub_group_shuffle_xor( float4 x, uint c ); | |
| 15967 | float8 __ovld __conv intel_sub_group_shuffle_xor( float8 x, uint c ); | |
| 15968 | float16 __ovld __conv intel_sub_group_shuffle_xor( float16 x, uint c ); | |
| 15969 | ||
| 15970 | int __ovld __conv intel_sub_group_shuffle_xor( int x, uint c ); | |
| 15971 | int2 __ovld __conv intel_sub_group_shuffle_xor( int2 x, uint c ); | |
| 15972 | int3 __ovld __conv intel_sub_group_shuffle_xor( int3 x, uint c ); | |
| 15973 | int4 __ovld __conv intel_sub_group_shuffle_xor( int4 x, uint c ); | |
| 15974 | int8 __ovld __conv intel_sub_group_shuffle_xor( int8 x, uint c ); | |
| 15975 | int16 __ovld __conv intel_sub_group_shuffle_xor( int16 x, uint c ); | |
| 15976 | ||
| 15977 | uint __ovld __conv intel_sub_group_shuffle_xor( uint x, uint c ); | |
| 15978 | uint2 __ovld __conv intel_sub_group_shuffle_xor( uint2 x, uint c ); | |
| 15979 | uint3 __ovld __conv intel_sub_group_shuffle_xor( uint3 x, uint c ); | |
| 15980 | uint4 __ovld __conv intel_sub_group_shuffle_xor( uint4 x, uint c ); | |
| 15981 | uint8 __ovld __conv intel_sub_group_shuffle_xor( uint8 x, uint c ); | |
| 15982 | uint16 __ovld __conv intel_sub_group_shuffle_xor( uint16 x, uint c ); | |
| 15983 | ||
| 15984 | long __ovld __conv intel_sub_group_shuffle_xor( long x, uint c ); | |
| 15985 | ulong __ovld __conv intel_sub_group_shuffle_xor( ulong x, uint c ); | |
| 15986 | ||
| 15987 | uint __ovld __conv intel_sub_group_block_read( read_only image2d_t image, int2 coord ); | |
| 15988 | uint2 __ovld __conv intel_sub_group_block_read2( read_only image2d_t image, int2 coord ); | |
| 15989 | uint4 __ovld __conv intel_sub_group_block_read4( read_only image2d_t image, int2 coord ); | |
| 15990 | uint8 __ovld __conv intel_sub_group_block_read8( read_only image2d_t image, int2 coord ); | |
| 15991 | ||
| 15992 | #if (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) | |
| 15993 | uint __ovld __conv intel_sub_group_block_read(read_write image2d_t image, int2 coord); | |
| 15994 | uint2 __ovld __conv intel_sub_group_block_read2(read_write image2d_t image, int2 coord); | |
| 15995 | uint4 __ovld __conv intel_sub_group_block_read4(read_write image2d_t image, int2 coord); | |
| 15996 | uint8 __ovld __conv intel_sub_group_block_read8(read_write image2d_t image, int2 coord); | |
| 15997 | #endif // (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) | |
| 15998 | ||
| 15999 | uint __ovld __conv intel_sub_group_block_read( const __global uint* p ); | |
| 16000 | uint2 __ovld __conv intel_sub_group_block_read2( const __global uint* p ); | |
| 16001 | uint4 __ovld __conv intel_sub_group_block_read4( const __global uint* p ); | |
| 16002 | uint8 __ovld __conv intel_sub_group_block_read8( const __global uint* p ); | |
| 16003 | ||
| 16004 | void __ovld __conv intel_sub_group_block_write(write_only image2d_t image, int2 coord, uint data); | |
| 16005 | void __ovld __conv intel_sub_group_block_write2(write_only image2d_t image, int2 coord, uint2 data); | |
| 16006 | void __ovld __conv intel_sub_group_block_write4(write_only image2d_t image, int2 coord, uint4 data); | |
| 16007 | void __ovld __conv intel_sub_group_block_write8(write_only image2d_t image, int2 coord, uint8 data); | |
| 16008 | ||
| 16009 | #if (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) | |
| 16010 | void __ovld __conv intel_sub_group_block_write(read_write image2d_t image, int2 coord, uint data); | |
| 16011 | void __ovld __conv intel_sub_group_block_write2(read_write image2d_t image, int2 coord, uint2 data); | |
| 16012 | void __ovld __conv intel_sub_group_block_write4(read_write image2d_t image, int2 coord, uint4 data); | |
| 16013 | void __ovld __conv intel_sub_group_block_write8(read_write image2d_t image, int2 coord, uint8 data); | |
| 16014 | #endif // (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) | |
| 16015 | ||
| 16016 | void __ovld __conv intel_sub_group_block_write( __global uint* p, uint data ); | |
| 16017 | void __ovld __conv intel_sub_group_block_write2( __global uint* p, uint2 data ); | |
| 16018 | void __ovld __conv intel_sub_group_block_write4( __global uint* p, uint4 data ); | |
| 16019 | void __ovld __conv intel_sub_group_block_write8( __global uint* p, uint8 data ); | |
| 16020 | ||
| 16021 | #ifdef cl_khr_fp16 | |
| 16022 | half __ovld __conv intel_sub_group_shuffle( half x, uint c ); | |
| 16023 | half __ovld __conv intel_sub_group_shuffle_down( half prev, half cur, uint c ); | |
| 16024 | half __ovld __conv intel_sub_group_shuffle_up( half prev, half cur, uint c ); | |
| 16025 | half __ovld __conv intel_sub_group_shuffle_xor( half x, uint c ); | |
| 16026 | #endif | |
| 16027 | ||
| 16028 | #if defined(cl_khr_fp64) | |
| 16029 | double __ovld __conv intel_sub_group_shuffle( double x, uint c ); | |
| 16030 | double __ovld __conv intel_sub_group_shuffle_down( double prev, double cur, uint c ); | |
| 16031 | double __ovld __conv intel_sub_group_shuffle_up( double prev, double cur, uint c ); | |
| 16032 | double __ovld __conv intel_sub_group_shuffle_xor( double x, uint c ); | |
| 16033 | #endif | |
| 16034 | ||
| 16035 | #endif //cl_intel_subgroups | |
| 16036 | ||
| 16037 | #if defined(cl_intel_subgroups_short) | |
| 16038 | short __ovld __conv intel_sub_group_broadcast( short x, uint sub_group_local_id ); | |
| 16039 | short2 __ovld __conv intel_sub_group_broadcast( short2 x, uint sub_group_local_id ); | |
| 16040 | short3 __ovld __conv intel_sub_group_broadcast( short3 x, uint sub_group_local_id ); | |
| 16041 | short4 __ovld __conv intel_sub_group_broadcast( short4 x, uint sub_group_local_id ); | |
| 16042 | short8 __ovld __conv intel_sub_group_broadcast( short8 x, uint sub_group_local_id ); | |
| 16043 | ||
| 16044 | ushort __ovld __conv intel_sub_group_broadcast( ushort x, uint sub_group_local_id ); | |
| 16045 | ushort2 __ovld __conv intel_sub_group_broadcast( ushort2 x, uint sub_group_local_id ); | |
| 16046 | ushort3 __ovld __conv intel_sub_group_broadcast( ushort3 x, uint sub_group_local_id ); | |
| 16047 | ushort4 __ovld __conv intel_sub_group_broadcast( ushort4 x, uint sub_group_local_id ); | |
| 16048 | ushort8 __ovld __conv intel_sub_group_broadcast( ushort8 x, uint sub_group_local_id ); | |
| 16049 | ||
| 16050 | short __ovld __conv intel_sub_group_shuffle( short x, uint c ); | |
| 16051 | short2 __ovld __conv intel_sub_group_shuffle( short2 x, uint c ); | |
| 16052 | short3 __ovld __conv intel_sub_group_shuffle( short3 x, uint c ); | |
| 16053 | short4 __ovld __conv intel_sub_group_shuffle( short4 x, uint c ); | |
| 16054 | short8 __ovld __conv intel_sub_group_shuffle( short8 x, uint c ); | |
| 16055 | short16 __ovld __conv intel_sub_group_shuffle( short16 x, uint c); | |
| 16056 | ||
| 16057 | ushort __ovld __conv intel_sub_group_shuffle( ushort x, uint c ); | |
| 16058 | ushort2 __ovld __conv intel_sub_group_shuffle( ushort2 x, uint c ); | |
| 16059 | ushort3 __ovld __conv intel_sub_group_shuffle( ushort3 x, uint c ); | |
| 16060 | ushort4 __ovld __conv intel_sub_group_shuffle( ushort4 x, uint c ); | |
| 16061 | ushort8 __ovld __conv intel_sub_group_shuffle( ushort8 x, uint c ); | |
| 16062 | ushort16 __ovld __conv intel_sub_group_shuffle( ushort16 x, uint c ); | |
| 16063 | ||
| 16064 | short __ovld __conv intel_sub_group_shuffle_down( short cur, short next, uint c ); | |
| 16065 | short2 __ovld __conv intel_sub_group_shuffle_down( short2 cur, short2 next, uint c ); | |
| 16066 | short3 __ovld __conv intel_sub_group_shuffle_down( short3 cur, short3 next, uint c ); | |
| 16067 | short4 __ovld __conv intel_sub_group_shuffle_down( short4 cur, short4 next, uint c ); | |
| 16068 | short8 __ovld __conv intel_sub_group_shuffle_down( short8 cur, short8 next, uint c ); | |
| 16069 | short16 __ovld __conv intel_sub_group_shuffle_down( short16 cur, short16 next, uint c ); | |
| 16070 | ||
| 16071 | ushort __ovld __conv intel_sub_group_shuffle_down( ushort cur, ushort next, uint c ); | |
| 16072 | ushort2 __ovld __conv intel_sub_group_shuffle_down( ushort2 cur, ushort2 next, uint c ); | |
| 16073 | ushort3 __ovld __conv intel_sub_group_shuffle_down( ushort3 cur, ushort3 next, uint c ); | |
| 16074 | ushort4 __ovld __conv intel_sub_group_shuffle_down( ushort4 cur, ushort4 next, uint c ); | |
| 16075 | ushort8 __ovld __conv intel_sub_group_shuffle_down( ushort8 cur, ushort8 next, uint c ); | |
| 16076 | ushort16 __ovld __conv intel_sub_group_shuffle_down( ushort16 cur, ushort16 next, uint c ); | |
| 16077 | ||
| 16078 | short __ovld __conv intel_sub_group_shuffle_up( short cur, short next, uint c ); | |
| 16079 | short2 __ovld __conv intel_sub_group_shuffle_up( short2 cur, short2 next, uint c ); | |
| 16080 | short3 __ovld __conv intel_sub_group_shuffle_up( short3 cur, short3 next, uint c ); | |
| 16081 | short4 __ovld __conv intel_sub_group_shuffle_up( short4 cur, short4 next, uint c ); | |
| 16082 | short8 __ovld __conv intel_sub_group_shuffle_up( short8 cur, short8 next, uint c ); | |
| 16083 | short16 __ovld __conv intel_sub_group_shuffle_up( short16 cur, short16 next, uint c ); | |
| 16084 | ||
| 16085 | ushort __ovld __conv intel_sub_group_shuffle_up( ushort cur, ushort next, uint c ); | |
| 16086 | ushort2 __ovld __conv intel_sub_group_shuffle_up( ushort2 cur, ushort2 next, uint c ); | |
| 16087 | ushort3 __ovld __conv intel_sub_group_shuffle_up( ushort3 cur, ushort3 next, uint c ); | |
| 16088 | ushort4 __ovld __conv intel_sub_group_shuffle_up( ushort4 cur, ushort4 next, uint c ); | |
| 16089 | ushort8 __ovld __conv intel_sub_group_shuffle_up( ushort8 cur, ushort8 next, uint c ); | |
| 16090 | ushort16 __ovld __conv intel_sub_group_shuffle_up( ushort16 cur, ushort16 next, uint c ); | |
| 16091 | ||
| 16092 | short __ovld __conv intel_sub_group_shuffle_xor( short x, uint c ); | |
| 16093 | short2 __ovld __conv intel_sub_group_shuffle_xor( short2 x, uint c ); | |
| 16094 | short3 __ovld __conv intel_sub_group_shuffle_xor( short3 x, uint c ); | |
| 16095 | short4 __ovld __conv intel_sub_group_shuffle_xor( short4 x, uint c ); | |
| 16096 | short8 __ovld __conv intel_sub_group_shuffle_xor( short8 x, uint c ); | |
| 16097 | short16 __ovld __conv intel_sub_group_shuffle_xor( short16 x, uint c ); | |
| 16098 | ||
| 16099 | ushort __ovld __conv intel_sub_group_shuffle_xor( ushort x, uint c ); | |
| 16100 | ushort2 __ovld __conv intel_sub_group_shuffle_xor( ushort2 x, uint c ); | |
| 16101 | ushort3 __ovld __conv intel_sub_group_shuffle_xor( ushort3 x, uint c ); | |
| 16102 | ushort4 __ovld __conv intel_sub_group_shuffle_xor( ushort4 x, uint c ); | |
| 16103 | ushort8 __ovld __conv intel_sub_group_shuffle_xor( ushort8 x, uint c ); | |
| 16104 | ushort16 __ovld __conv intel_sub_group_shuffle_xor( ushort16 x, uint c ); | |
| 16105 | ||
| 16106 | short __ovld __conv intel_sub_group_reduce_add( short x ); | |
| 16107 | ushort __ovld __conv intel_sub_group_reduce_add( ushort x ); | |
| 16108 | short __ovld __conv intel_sub_group_reduce_min( short x ); | |
| 16109 | ushort __ovld __conv intel_sub_group_reduce_min( ushort x ); | |
| 16110 | short __ovld __conv intel_sub_group_reduce_max( short x ); | |
| 16111 | ushort __ovld __conv intel_sub_group_reduce_max( ushort x ); | |
| 16112 | ||
| 16113 | short __ovld __conv intel_sub_group_scan_exclusive_add( short x ); | |
| 16114 | ushort __ovld __conv intel_sub_group_scan_exclusive_add( ushort x ); | |
| 16115 | short __ovld __conv intel_sub_group_scan_exclusive_min( short x ); | |
| 16116 | ushort __ovld __conv intel_sub_group_scan_exclusive_min( ushort x ); | |
| 16117 | short __ovld __conv intel_sub_group_scan_exclusive_max( short x ); | |
| 16118 | ushort __ovld __conv intel_sub_group_scan_exclusive_max( ushort x ); | |
| 16119 | ||
| 16120 | short __ovld __conv intel_sub_group_scan_inclusive_add( short x ); | |
| 16121 | ushort __ovld __conv intel_sub_group_scan_inclusive_add( ushort x ); | |
| 16122 | short __ovld __conv intel_sub_group_scan_inclusive_min( short x ); | |
| 16123 | ushort __ovld __conv intel_sub_group_scan_inclusive_min( ushort x ); | |
| 16124 | short __ovld __conv intel_sub_group_scan_inclusive_max( short x ); | |
| 16125 | ushort __ovld __conv intel_sub_group_scan_inclusive_max( ushort x ); | |
| 16126 | ||
| 16127 | uint __ovld __conv intel_sub_group_block_read_ui( read_only image2d_t image, int2 byte_coord ); | |
| 16128 | uint2 __ovld __conv intel_sub_group_block_read_ui2( read_only image2d_t image, int2 byte_coord ); | |
| 16129 | uint4 __ovld __conv intel_sub_group_block_read_ui4( read_only image2d_t image, int2 byte_coord ); | |
| 16130 | uint8 __ovld __conv intel_sub_group_block_read_ui8( read_only image2d_t image, int2 byte_coord ); | |
| 16131 | ||
| 16132 | #if (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) | |
| 16133 | uint __ovld __conv intel_sub_group_block_read_ui( read_write image2d_t image, int2 byte_coord ); | |
| 16134 | uint2 __ovld __conv intel_sub_group_block_read_ui2( read_write image2d_t image, int2 byte_coord ); | |
| 16135 | uint4 __ovld __conv intel_sub_group_block_read_ui4( read_write image2d_t image, int2 byte_coord ); | |
| 16136 | uint8 __ovld __conv intel_sub_group_block_read_ui8( read_write image2d_t image, int2 byte_coord ); | |
| 16137 | #endif // (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) | |
| 16138 | ||
| 16139 | uint __ovld __conv intel_sub_group_block_read_ui( const __global uint* p ); | |
| 16140 | uint2 __ovld __conv intel_sub_group_block_read_ui2( const __global uint* p ); | |
| 16141 | uint4 __ovld __conv intel_sub_group_block_read_ui4( const __global uint* p ); | |
| 16142 | uint8 __ovld __conv intel_sub_group_block_read_ui8( const __global uint* p ); | |
| 16143 | ||
| 16144 | void __ovld __conv intel_sub_group_block_write_ui( read_only image2d_t image, int2 byte_coord, uint data ); | |
| 16145 | void __ovld __conv intel_sub_group_block_write_ui2( read_only image2d_t image, int2 byte_coord, uint2 data ); | |
| 16146 | void __ovld __conv intel_sub_group_block_write_ui4( read_only image2d_t image, int2 byte_coord, uint4 data ); | |
| 16147 | void __ovld __conv intel_sub_group_block_write_ui8( read_only image2d_t image, int2 byte_coord, uint8 data ); | |
| 16148 | ||
| 16149 | #if (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) | |
| 16150 | void __ovld __conv intel_sub_group_block_write_ui( read_write image2d_t image, int2 byte_coord, uint data ); | |
| 16151 | void __ovld __conv intel_sub_group_block_write_ui2( read_write image2d_t image, int2 byte_coord, uint2 data ); | |
| 16152 | void __ovld __conv intel_sub_group_block_write_ui4( read_write image2d_t image, int2 byte_coord, uint4 data ); | |
| 16153 | void __ovld __conv intel_sub_group_block_write_ui8( read_write image2d_t image, int2 byte_coord, uint8 data ); | |
| 16154 | #endif // (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) | |
| 16155 | ||
| 16156 | void __ovld __conv intel_sub_group_block_write_ui( __global uint* p, uint data ); | |
| 16157 | void __ovld __conv intel_sub_group_block_write_ui2( __global uint* p, uint2 data ); | |
| 16158 | void __ovld __conv intel_sub_group_block_write_ui4( __global uint* p, uint4 data ); | |
| 16159 | void __ovld __conv intel_sub_group_block_write_ui8( __global uint* p, uint8 data ); | |
| 16160 | ||
| 16161 | ushort __ovld __conv intel_sub_group_block_read_us( read_only image2d_t image, int2 coord ); | |
| 16162 | ushort2 __ovld __conv intel_sub_group_block_read_us2( read_only image2d_t image, int2 coord ); | |
| 16163 | ushort4 __ovld __conv intel_sub_group_block_read_us4( read_only image2d_t image, int2 coord ); | |
| 16164 | ushort8 __ovld __conv intel_sub_group_block_read_us8( read_only image2d_t image, int2 coord ); | |
| 16165 | ||
| 16166 | #if (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) | |
| 16167 | ushort __ovld __conv intel_sub_group_block_read_us(read_write image2d_t image, int2 coord); | |
| 16168 | ushort2 __ovld __conv intel_sub_group_block_read_us2(read_write image2d_t image, int2 coord); | |
| 16169 | ushort4 __ovld __conv intel_sub_group_block_read_us4(read_write image2d_t image, int2 coord); | |
| 16170 | ushort8 __ovld __conv intel_sub_group_block_read_us8(read_write image2d_t image, int2 coord); | |
| 16171 | #endif // (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) | |
| 16172 | ||
| 16173 | ushort __ovld __conv intel_sub_group_block_read_us( const __global ushort* p ); | |
| 16174 | ushort2 __ovld __conv intel_sub_group_block_read_us2( const __global ushort* p ); | |
| 16175 | ushort4 __ovld __conv intel_sub_group_block_read_us4( const __global ushort* p ); | |
| 16176 | ushort8 __ovld __conv intel_sub_group_block_read_us8( const __global ushort* p ); | |
| 16177 | ||
| 16178 | void __ovld __conv intel_sub_group_block_write_us(write_only image2d_t image, int2 coord, ushort data); | |
| 16179 | void __ovld __conv intel_sub_group_block_write_us2(write_only image2d_t image, int2 coord, ushort2 data); | |
| 16180 | void __ovld __conv intel_sub_group_block_write_us4(write_only image2d_t image, int2 coord, ushort4 data); | |
| 16181 | void __ovld __conv intel_sub_group_block_write_us8(write_only image2d_t image, int2 coord, ushort8 data); | |
| 16182 | ||
| 16183 | #if (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) | |
| 16184 | void __ovld __conv intel_sub_group_block_write_us(read_write image2d_t image, int2 coord, ushort data); | |
| 16185 | void __ovld __conv intel_sub_group_block_write_us2(read_write image2d_t image, int2 coord, ushort2 data); | |
| 16186 | void __ovld __conv intel_sub_group_block_write_us4(read_write image2d_t image, int2 coord, ushort4 data); | |
| 16187 | void __ovld __conv intel_sub_group_block_write_us8(read_write image2d_t image, int2 coord, ushort8 data); | |
| 16188 | #endif // (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) | |
| 16189 | ||
| 16190 | void __ovld __conv intel_sub_group_block_write_us( __global ushort* p, ushort data ); | |
| 16191 | void __ovld __conv intel_sub_group_block_write_us2( __global ushort* p, ushort2 data ); | |
| 16192 | void __ovld __conv intel_sub_group_block_write_us4( __global ushort* p, ushort4 data ); | |
| 16193 | void __ovld __conv intel_sub_group_block_write_us8( __global ushort* p, ushort8 data ); | |
| 16194 | #endif // cl_intel_subgroups_short | |
| 16195 | ||
| 16202 | 16196 | #ifdef cl_amd_media_ops |
| 16203 | 16197 | uint __ovld amd_bitalign(uint a, uint b, uint c); |
| 16204 | 16198 | uint2 __ovld amd_bitalign(uint2 a, uint2 b, uint2 c); |
c_headers/pmmintrin.h+3-3| ... | ... | @@ -115,8 +115,8 @@ _mm_hsub_ps(__m128 __a, __m128 __b) |
| 115 | 115 | return __builtin_ia32_hsubps((__v4sf)__a, (__v4sf)__b); |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | /// \brief Moves and duplicates high-order (odd-indexed) values from a 128-bit | |
| 119 | /// vector of [4 x float] to float values stored in a 128-bit vector of | |
| 118 | /// \brief Moves and duplicates odd-indexed values from a 128-bit vector | |
| 119 | /// of [4 x float] to float values stored in a 128-bit vector of | |
| 120 | 120 | /// [4 x float]. |
| 121 | 121 | /// |
| 122 | 122 | /// \headerfile <x86intrin.h> |
| ... | ... | @@ -137,7 +137,7 @@ _mm_movehdup_ps(__m128 __a) |
| 137 | 137 | return __builtin_shufflevector((__v4sf)__a, (__v4sf)__a, 1, 1, 3, 3); |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | /// \brief Duplicates low-order (even-indexed) values from a 128-bit vector of | |
| 140 | /// \brief Duplicates even-indexed values from a 128-bit vector of | |
| 141 | 141 | /// [4 x float] to float values stored in a 128-bit vector of [4 x float]. |
| 142 | 142 | /// |
| 143 | 143 | /// \headerfile <x86intrin.h> |
c_headers/smmintrin.h+3-3| ... | ... | @@ -648,7 +648,7 @@ _mm_mul_epi32 (__m128i __V1, __m128i __V2) |
| 648 | 648 | /// input vectors are used as an input for dot product; otherwise that input |
| 649 | 649 | /// is treated as zero. Bits [1:0] determine which elements of the result |
| 650 | 650 | /// will receive a copy of the final dot product, with bit [0] corresponding |
| 651 | /// to the lowest element and bit [3] corresponding to the highest element of | |
| 651 | /// to the lowest element and bit [1] corresponding to the highest element of | |
| 652 | 652 | /// each [2 x double] vector. If a bit is set, the dot product is returned in |
| 653 | 653 | /// the corresponding element; otherwise that element is set to zero. |
| 654 | 654 | #define _mm_dp_pd(X, Y, M) __extension__ ({\ |
| ... | ... | @@ -866,8 +866,8 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2) |
| 866 | 866 | /// 11: Copies the selected bits from \a Y to result bits [127:96]. \n |
| 867 | 867 | /// Bits[3:0]: If any of these bits are set, the corresponding result |
| 868 | 868 | /// element is cleared. |
| 869 | /// \returns A 128-bit vector of [4 x float] containing the copied single- | |
| 870 | /// precision floating point elements from the operands. | |
| 869 | /// \returns A 128-bit vector of [4 x float] containing the copied | |
| 870 | /// single-precision floating point elements from the operands. | |
| 871 | 871 | #define _mm_insert_ps(X, Y, N) __builtin_ia32_insertps128((X), (Y), (N)) |
| 872 | 872 | |
| 873 | 873 | /// \brief Extracts a 32-bit integer from a 128-bit vector of [4 x float] and |
c_headers/stdbool.h+4-1| ... | ... | @@ -32,12 +32,15 @@ |
| 32 | 32 | #define true 1 |
| 33 | 33 | #define false 0 |
| 34 | 34 | #elif defined(__GNUC__) && !defined(__STRICT_ANSI__) |
| 35 | /* Define _Bool, bool, false, true as a GNU extension. */ | |
| 35 | /* Define _Bool as a GNU extension. */ | |
| 36 | 36 | #define _Bool bool |
| 37 | #if __cplusplus < 201103L | |
| 38 | /* For C++98, define bool, false, true as a GNU extension. */ | |
| 37 | 39 | #define bool bool |
| 38 | 40 | #define false false |
| 39 | 41 | #define true true |
| 40 | 42 | #endif |
| 43 | #endif | |
| 41 | 44 | |
| 42 | 45 | #define __bool_true_false_are_defined 1 |
| 43 | 46 |
c_headers/unwind.h+59-21| ... | ... | @@ -76,7 +76,13 @@ typedef intptr_t _sleb128_t; |
| 76 | 76 | typedef uintptr_t _uleb128_t; |
| 77 | 77 | |
| 78 | 78 | struct _Unwind_Context; |
| 79 | #if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) || defined(__ARM_DWARF_EH__)) | |
| 80 | struct _Unwind_Control_Block; | |
| 81 | typedef struct _Unwind_Control_Block _Unwind_Exception; /* Alias */ | |
| 82 | #else | |
| 79 | 83 | struct _Unwind_Exception; |
| 84 | typedef struct _Unwind_Exception _Unwind_Exception; | |
| 85 | #endif | |
| 80 | 86 | typedef enum { |
| 81 | 87 | _URC_NO_REASON = 0, |
| 82 | 88 | #if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \ |
| ... | ... | @@ -109,8 +115,42 @@ typedef enum { |
| 109 | 115 | } _Unwind_Action; |
| 110 | 116 | |
| 111 | 117 | typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code, |
| 112 | struct _Unwind_Exception *); | |
| 113 | ||
| 118 | _Unwind_Exception *); | |
| 119 | ||
| 120 | #if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) || defined(__ARM_DWARF_EH__)) | |
| 121 | typedef struct _Unwind_Control_Block _Unwind_Control_Block; | |
| 122 | typedef uint32_t _Unwind_EHT_Header; | |
| 123 | ||
| 124 | struct _Unwind_Control_Block { | |
| 125 | uint64_t exception_class; | |
| 126 | void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block *); | |
| 127 | /* unwinder cache (private fields for the unwinder's use) */ | |
| 128 | struct { | |
| 129 | uint32_t reserved1; /* forced unwind stop function, 0 if not forced */ | |
| 130 | uint32_t reserved2; /* personality routine */ | |
| 131 | uint32_t reserved3; /* callsite */ | |
| 132 | uint32_t reserved4; /* forced unwind stop argument */ | |
| 133 | uint32_t reserved5; | |
| 134 | } unwinder_cache; | |
| 135 | /* propagation barrier cache (valid after phase 1) */ | |
| 136 | struct { | |
| 137 | uint32_t sp; | |
| 138 | uint32_t bitpattern[5]; | |
| 139 | } barrier_cache; | |
| 140 | /* cleanup cache (preserved over cleanup) */ | |
| 141 | struct { | |
| 142 | uint32_t bitpattern[4]; | |
| 143 | } cleanup_cache; | |
| 144 | /* personality cache (for personality's benefit) */ | |
| 145 | struct { | |
| 146 | uint32_t fnstart; /* function start address */ | |
| 147 | _Unwind_EHT_Header *ehtp; /* pointer to EHT entry header word */ | |
| 148 | uint32_t additional; /* additional data */ | |
| 149 | uint32_t reserved1; | |
| 150 | } pr_cache; | |
| 151 | long long int : 0; /* force alignment of next item to 8-byte boundary */ | |
| 152 | } __attribute__((__aligned__(8))); | |
| 153 | #else | |
| 114 | 154 | struct _Unwind_Exception { |
| 115 | 155 | _Unwind_Exception_Class exception_class; |
| 116 | 156 | _Unwind_Exception_Cleanup_Fn exception_cleanup; |
| ... | ... | @@ -120,23 +160,24 @@ struct _Unwind_Exception { |
| 120 | 160 | * aligned". GCC has interpreted this to mean "use the maximum useful |
| 121 | 161 | * alignment for the target"; so do we. */ |
| 122 | 162 | } __attribute__((__aligned__)); |
| 163 | #endif | |
| 123 | 164 | |
| 124 | 165 | typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)(int, _Unwind_Action, |
| 125 | 166 | _Unwind_Exception_Class, |
| 126 | struct _Unwind_Exception *, | |
| 167 | _Unwind_Exception *, | |
| 127 | 168 | struct _Unwind_Context *, |
| 128 | 169 | void *); |
| 129 | 170 | |
| 130 | typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)( | |
| 131 | int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, | |
| 132 | struct _Unwind_Context *); | |
| 171 | typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)(int, _Unwind_Action, | |
| 172 | _Unwind_Exception_Class, | |
| 173 | _Unwind_Exception *, | |
| 174 | struct _Unwind_Context *); | |
| 133 | 175 | typedef _Unwind_Personality_Fn __personality_routine; |
| 134 | 176 | |
| 135 | 177 | typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *, |
| 136 | 178 | void *); |
| 137 | 179 | |
| 138 | #if defined(__arm__) && !defined(__APPLE__) | |
| 139 | ||
| 180 | #if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) || defined(__ARM_DWARF_EH__)) | |
| 140 | 181 | typedef enum { |
| 141 | 182 | _UVRSC_CORE = 0, /* integer register */ |
| 142 | 183 | _UVRSC_VFP = 1, /* vfp */ |
| ... | ... | @@ -158,14 +199,12 @@ typedef enum { |
| 158 | 199 | _UVRSR_FAILED = 2 |
| 159 | 200 | } _Unwind_VRS_Result; |
| 160 | 201 | |
| 161 | #if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__ARM_DWARF_EH__) | |
| 162 | 202 | typedef uint32_t _Unwind_State; |
| 163 | 203 | #define _US_VIRTUAL_UNWIND_FRAME ((_Unwind_State)0) |
| 164 | 204 | #define _US_UNWIND_FRAME_STARTING ((_Unwind_State)1) |
| 165 | 205 | #define _US_UNWIND_FRAME_RESUME ((_Unwind_State)2) |
| 166 | 206 | #define _US_ACTION_MASK ((_Unwind_State)3) |
| 167 | 207 | #define _US_FORCE_UNWIND ((_Unwind_State)8) |
| 168 | #endif | |
| 169 | 208 | |
| 170 | 209 | _Unwind_VRS_Result _Unwind_VRS_Get(struct _Unwind_Context *__context, |
| 171 | 210 | _Unwind_VRS_RegClass __regclass, |
| ... | ... | @@ -224,13 +263,12 @@ _Unwind_Ptr _Unwind_GetRegionStart(struct _Unwind_Context *); |
| 224 | 263 | |
| 225 | 264 | /* DWARF EH functions; currently not available on Darwin/ARM */ |
| 226 | 265 | #if !defined(__APPLE__) || !defined(__arm__) |
| 227 | ||
| 228 | _Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *); | |
| 229 | _Unwind_Reason_Code _Unwind_ForcedUnwind(struct _Unwind_Exception *, | |
| 230 | _Unwind_Stop_Fn, void *); | |
| 231 | void _Unwind_DeleteException(struct _Unwind_Exception *); | |
| 232 | void _Unwind_Resume(struct _Unwind_Exception *); | |
| 233 | _Unwind_Reason_Code _Unwind_Resume_or_Rethrow(struct _Unwind_Exception *); | |
| 266 | _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception *); | |
| 267 | _Unwind_Reason_Code _Unwind_ForcedUnwind(_Unwind_Exception *, _Unwind_Stop_Fn, | |
| 268 | void *); | |
| 269 | void _Unwind_DeleteException(_Unwind_Exception *); | |
| 270 | void _Unwind_Resume(_Unwind_Exception *); | |
| 271 | _Unwind_Reason_Code _Unwind_Resume_or_Rethrow(_Unwind_Exception *); | |
| 234 | 272 | |
| 235 | 273 | #endif |
| 236 | 274 | |
| ... | ... | @@ -241,11 +279,11 @@ typedef struct SjLj_Function_Context *_Unwind_FunctionContext_t; |
| 241 | 279 | |
| 242 | 280 | void _Unwind_SjLj_Register(_Unwind_FunctionContext_t); |
| 243 | 281 | void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t); |
| 244 | _Unwind_Reason_Code _Unwind_SjLj_RaiseException(struct _Unwind_Exception *); | |
| 245 | _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(struct _Unwind_Exception *, | |
| 282 | _Unwind_Reason_Code _Unwind_SjLj_RaiseException(_Unwind_Exception *); | |
| 283 | _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(_Unwind_Exception *, | |
| 246 | 284 | _Unwind_Stop_Fn, void *); |
| 247 | void _Unwind_SjLj_Resume(struct _Unwind_Exception *); | |
| 248 | _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *); | |
| 285 | void _Unwind_SjLj_Resume(_Unwind_Exception *); | |
| 286 | _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception *); | |
| 249 | 287 | |
| 250 | 288 | void *_Unwind_FindEnclosingFunction(void *); |
| 251 | 289 |
c_headers/vaesintrin.h created+98| ... | ... | @@ -0,0 +1,98 @@ |
| 1 | /*===------------------ vaesintrin.h - VAES intrinsics ---------------------=== | |
| 2 | * | |
| 3 | * | |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 5 | * of this software and associated documentation files (the "Software"), to deal | |
| 6 | * in the Software without restriction, including without limitation the rights | |
| 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 8 | * copies of the Software, and to permit persons to whom the Software is | |
| 9 | * furnished to do so, subject to the following conditions: | |
| 10 | * | |
| 11 | * The above copyright notice and this permission notice shall be included in | |
| 12 | * all copies or substantial portions of the Software. | |
| 13 | * | |
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 20 | * THE SOFTWARE. | |
| 21 | * | |
| 22 | *===-----------------------------------------------------------------------=== | |
| 23 | */ | |
| 24 | #ifndef __IMMINTRIN_H | |
| 25 | #error "Never use <vaesintrin.h> directly; include <immintrin.h> instead." | |
| 26 | #endif | |
| 27 | ||
| 28 | #ifndef __VAESINTRIN_H | |
| 29 | #define __VAESINTRIN_H | |
| 30 | ||
| 31 | /* Default attributes for YMM forms. */ | |
| 32 | #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("vaes"))) | |
| 33 | ||
| 34 | /* Default attributes for ZMM forms. */ | |
| 35 | #define __DEFAULT_FN_ATTRS_F __attribute__((__always_inline__, __nodebug__, __target__("avx512f,vaes"))) | |
| 36 | ||
| 37 | ||
| 38 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 39 | _mm256_aesenc_epi128(__m256i __A, __m256i __B) | |
| 40 | { | |
| 41 | return (__m256i) __builtin_ia32_aesenc256((__v4di) __A, | |
| 42 | (__v4di) __B); | |
| 43 | } | |
| 44 | ||
| 45 | static __inline__ __m512i __DEFAULT_FN_ATTRS_F | |
| 46 | _mm512_aesenc_epi128(__m512i __A, __m512i __B) | |
| 47 | { | |
| 48 | return (__m512i) __builtin_ia32_aesenc512((__v8di) __A, | |
| 49 | (__v8di) __B); | |
| 50 | } | |
| 51 | ||
| 52 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 53 | _mm256_aesdec_epi128(__m256i __A, __m256i __B) | |
| 54 | { | |
| 55 | return (__m256i) __builtin_ia32_aesdec256((__v4di) __A, | |
| 56 | (__v4di) __B); | |
| 57 | } | |
| 58 | ||
| 59 | static __inline__ __m512i __DEFAULT_FN_ATTRS_F | |
| 60 | _mm512_aesdec_epi128(__m512i __A, __m512i __B) | |
| 61 | { | |
| 62 | return (__m512i) __builtin_ia32_aesdec512((__v8di) __A, | |
| 63 | (__v8di) __B); | |
| 64 | } | |
| 65 | ||
| 66 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 67 | _mm256_aesenclast_epi128(__m256i __A, __m256i __B) | |
| 68 | { | |
| 69 | return (__m256i) __builtin_ia32_aesenclast256((__v4di) __A, | |
| 70 | (__v4di) __B); | |
| 71 | } | |
| 72 | ||
| 73 | static __inline__ __m512i __DEFAULT_FN_ATTRS_F | |
| 74 | _mm512_aesenclast_epi128(__m512i __A, __m512i __B) | |
| 75 | { | |
| 76 | return (__m512i) __builtin_ia32_aesenclast512((__v8di) __A, | |
| 77 | (__v8di) __B); | |
| 78 | } | |
| 79 | ||
| 80 | static __inline__ __m256i __DEFAULT_FN_ATTRS | |
| 81 | _mm256_aesdeclast_epi128(__m256i __A, __m256i __B) | |
| 82 | { | |
| 83 | return (__m256i) __builtin_ia32_aesdeclast256((__v4di) __A, | |
| 84 | (__v4di) __B); | |
| 85 | } | |
| 86 | ||
| 87 | static __inline__ __m512i __DEFAULT_FN_ATTRS_F | |
| 88 | _mm512_aesdeclast_epi128(__m512i __A, __m512i __B) | |
| 89 | { | |
| 90 | return (__m512i) __builtin_ia32_aesdeclast512((__v8di) __A, | |
| 91 | (__v8di) __B); | |
| 92 | } | |
| 93 | ||
| 94 | ||
| 95 | #undef __DEFAULT_FN_ATTRS | |
| 96 | #undef __DEFAULT_FN_ATTRS_F | |
| 97 | ||
| 98 | #endif |
c_headers/vpclmulqdqintrin.h created+42| ... | ... | @@ -0,0 +1,42 @@ |
| 1 | /*===------------ vpclmulqdqintrin.h - VPCLMULQDQ intrinsics ---------------=== | |
| 2 | * | |
| 3 | * | |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 5 | * of this software and associated documentation files (the "Software"), to deal | |
| 6 | * in the Software without restriction, including without limitation the rights | |
| 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 8 | * copies of the Software, and to permit persons to whom the Software is | |
| 9 | * furnished to do so, subject to the following conditions: | |
| 10 | * | |
| 11 | * The above copyright notice and this permission notice shall be included in | |
| 12 | * all copies or substantial portions of the Software. | |
| 13 | * | |
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 20 | * THE SOFTWARE. | |
| 21 | * | |
| 22 | *===-----------------------------------------------------------------------=== | |
| 23 | */ | |
| 24 | #ifndef __IMMINTRIN_H | |
| 25 | #error "Never use <vpclmulqdqintrin.h> directly; include <immintrin.h> instead." | |
| 26 | #endif | |
| 27 | ||
| 28 | #ifndef __VPCLMULQDQINTRIN_H | |
| 29 | #define __VPCLMULQDQINTRIN_H | |
| 30 | ||
| 31 | #define _mm256_clmulepi64_epi128(A, B, I) __extension__ ({ \ | |
| 32 | (__m256i)__builtin_ia32_pclmulqdq256((__v4di)(__m256i)(A), \ | |
| 33 | (__v4di)(__m256i)(B), \ | |
| 34 | (char)(I)); }) | |
| 35 | ||
| 36 | #define _mm512_clmulepi64_epi128(A, B, I) __extension__ ({ \ | |
| 37 | (__m512i)__builtin_ia32_pclmulqdq512((__v8di)(__m512i)(A), \ | |
| 38 | (__v8di)(__m512i)(B), \ | |
| 39 | (char)(I)); }) | |
| 40 | ||
| 41 | #endif // __VPCLMULQDQINTRIN_H | |
| 42 |
c_headers/xmmintrin.h+7-4| ... | ... | @@ -2035,9 +2035,11 @@ _mm_storer_ps(float *__p, __m128 __a) |
| 2035 | 2035 | _mm_store_ps(__p, __a); |
| 2036 | 2036 | } |
| 2037 | 2037 | |
| 2038 | #define _MM_HINT_T0 3 | |
| 2039 | #define _MM_HINT_T1 2 | |
| 2040 | #define _MM_HINT_T2 1 | |
| 2038 | #define _MM_HINT_ET0 7 | |
| 2039 | #define _MM_HINT_ET1 6 | |
| 2040 | #define _MM_HINT_T0 3 | |
| 2041 | #define _MM_HINT_T1 2 | |
| 2042 | #define _MM_HINT_T2 1 | |
| 2041 | 2043 | #define _MM_HINT_NTA 0 |
| 2042 | 2044 | |
| 2043 | 2045 | #ifndef _MSC_VER |
| ... | ... | @@ -2068,7 +2070,8 @@ _mm_storer_ps(float *__p, __m128 __a) |
| 2068 | 2070 | /// be generated. \n |
| 2069 | 2071 | /// _MM_HINT_T2: Move data using the T2 hint. The PREFETCHT2 instruction will |
| 2070 | 2072 | /// be generated. |
| 2071 | #define _mm_prefetch(a, sel) (__builtin_prefetch((void *)(a), 0, (sel))) | |
| 2073 | #define _mm_prefetch(a, sel) (__builtin_prefetch((void *)(a), \ | |
| 2074 | ((sel) >> 2) & 1, (sel) & 0x3)) | |
| 2072 | 2075 | #endif |
| 2073 | 2076 | |
| 2074 | 2077 | /// \brief Stores a 64-bit integer in the specified aligned memory location. To |
ci/appveyor/appveyor.yml+1| ... | ... | @@ -7,3 +7,4 @@ after_build: |
| 7 | 7 | - '%APPVEYOR_BUILD_FOLDER%\ci\appveyor\after_build.bat' |
| 8 | 8 | cache: |
| 9 | 9 | - 'llvm+clang-5.0.1-win64-msvc-release.tar.xz' |
| 10 | - 'llvm+clang-6.0.0-win64-msvc-release.tar.xz' |
ci/appveyor/build_script.bat+2-2| ... | ... | @@ -7,13 +7,13 @@ SET "PATH=C:\msys64\mingw64\bin;C:\msys64\usr\bin;%PATH%" |
| 7 | 7 | SET "MSYSTEM=MINGW64" |
| 8 | 8 | SET "APPVEYOR_CACHE_ENTRY_ZIP_ARGS=-m0=Copy" |
| 9 | 9 | |
| 10 | bash -lc "cd ${APPVEYOR_BUILD_FOLDER} && if [ -s ""llvm+clang-5.0.1-win64-msvc-release.tar.xz"" ]; then echo 'skipping LLVM download'; else wget 'https://s3.amazonaws.com/ziglang.org/deps/llvm%%2bclang-5.0.1-win64-msvc-release.tar.xz'; fi && tar xf llvm+clang-5.0.1-win64-msvc-release.tar.xz" || exit /b | |
| 10 | bash -lc "cd ${APPVEYOR_BUILD_FOLDER} && if [ -s ""llvm+clang-6.0.0-win64-msvc-release.tar.xz"" ]; then echo 'skipping LLVM download'; else wget 'https://s3.amazonaws.com/ziglang.org/deps/llvm%%2bclang-6.0.0-win64-msvc-release.tar.xz'; fi && tar xf llvm+clang-6.0.0-win64-msvc-release.tar.xz" || exit /b | |
| 11 | 11 | |
| 12 | 12 | |
| 13 | 13 | SET "PATH=%PREVPATH%" |
| 14 | 14 | SET "MSYSTEM=%PREVMSYSTEM%" |
| 15 | 15 | SET "ZIGBUILDDIR=%APPVEYOR_BUILD_FOLDER%\build-msvc-release" |
| 16 | SET "ZIGPREFIXPATH=%APPVEYOR_BUILD_FOLDER%\llvm+clang-5.0.1-win64-msvc-release" | |
| 16 | SET "ZIGPREFIXPATH=%APPVEYOR_BUILD_FOLDER%\llvm+clang-6.0.0-win64-msvc-release" | |
| 17 | 17 | |
| 18 | 18 | call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 |
| 19 | 19 | call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64 |
ci/travis_linux_install+1-1| ... | ... | @@ -4,4 +4,4 @@ set -x |
| 4 | 4 | |
| 5 | 5 | sudo apt-get remove -y llvm-* |
| 6 | 6 | sudo rm -rf /usr/local/* |
| 7 | sudo apt-get install -y clang-5.0 libclang-5.0 libclang-5.0-dev llvm-5.0 llvm-5.0-dev liblld-5.0 liblld-5.0-dev cmake wine1.6-amd64 | |
| 7 | sudo apt-get install -y clang-6.0 libclang-6.0 libclang-6.0-dev llvm-6.0 llvm-6.0-dev liblld-6.0 liblld-6.0-dev cmake wine1.6-amd64 |
cmake/Findclang.cmake+4-4| ... | ... | @@ -26,16 +26,16 @@ if(MSVC) |
| 26 | 26 | else() |
| 27 | 27 | find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h |
| 28 | 28 | PATHS |
| 29 | /usr/lib/llvm/5/include | |
| 30 | /usr/lib/llvm-5.0/include | |
| 29 | /usr/lib/llvm/6/include | |
| 30 | /usr/lib/llvm-6.0/include | |
| 31 | 31 | /mingw64/include) |
| 32 | 32 | |
| 33 | 33 | macro(FIND_AND_ADD_CLANG_LIB _libname_) |
| 34 | 34 | string(TOUPPER ${_libname_} _prettylibname_) |
| 35 | 35 | find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_} |
| 36 | 36 | PATHS |
| 37 | /usr/lib/llvm/5/lib | |
| 38 | /usr/lib/llvm-5.0/lib | |
| 37 | /usr/lib/llvm/6/lib | |
| 38 | /usr/lib/llvm-6.0/lib | |
| 39 | 39 | /mingw64/lib |
| 40 | 40 | /c/msys64/mingw64/lib |
| 41 | 41 | c:\\msys64\\mingw64\\lib) |
cmake/Findlld.cmake+6-5| ... | ... | @@ -6,12 +6,12 @@ |
| 6 | 6 | # LLD_INCLUDE_DIRS |
| 7 | 7 | # LLD_LIBRARIES |
| 8 | 8 | |
| 9 | find_path(LLD_INCLUDE_DIRS NAMES lld/Driver/Driver.h | |
| 9 | find_path(LLD_INCLUDE_DIRS NAMES lld/Common/Driver.h | |
| 10 | 10 | PATHS |
| 11 | /usr/lib/llvm-5.0/include | |
| 11 | /usr/lib/llvm-6.0/include | |
| 12 | 12 | /mingw64/include) |
| 13 | 13 | |
| 14 | find_library(LLD_LIBRARY NAMES lld-5.0 lld PATHS /usr/lib/llvm-5.0/lib) | |
| 14 | find_library(LLD_LIBRARY NAMES lld-6.0 lld PATHS /usr/lib/llvm-6.0/lib) | |
| 15 | 15 | if(EXISTS ${LLD_LIBRARY}) |
| 16 | 16 | set(LLD_LIBRARIES ${LLD_LIBRARY}) |
| 17 | 17 | else() |
| ... | ... | @@ -19,7 +19,7 @@ else() |
| 19 | 19 | string(TOUPPER ${_libname_} _prettylibname_) |
| 20 | 20 | find_library(LLD_${_prettylibname_}_LIB NAMES ${_libname_} |
| 21 | 21 | PATHS |
| 22 | /usr/lib/llvm-5.0/lib | |
| 22 | /usr/lib/llvm-6.0/lib | |
| 23 | 23 | /mingw64/lib |
| 24 | 24 | /c/msys64/mingw64/lib |
| 25 | 25 | c:/msys64/mingw64/lib) |
| ... | ... | @@ -29,13 +29,14 @@ else() |
| 29 | 29 | endmacro(FIND_AND_ADD_LLD_LIB) |
| 30 | 30 | |
| 31 | 31 | FIND_AND_ADD_LLD_LIB(lldDriver) |
| 32 | FIND_AND_ADD_LLD_LIB(lldMinGW) | |
| 32 | 33 | FIND_AND_ADD_LLD_LIB(lldELF) |
| 33 | 34 | FIND_AND_ADD_LLD_LIB(lldCOFF) |
| 34 | 35 | FIND_AND_ADD_LLD_LIB(lldMachO) |
| 35 | 36 | FIND_AND_ADD_LLD_LIB(lldReaderWriter) |
| 36 | 37 | FIND_AND_ADD_LLD_LIB(lldCore) |
| 37 | 38 | FIND_AND_ADD_LLD_LIB(lldYAML) |
| 38 | FIND_AND_ADD_LLD_LIB(lldConfig) | |
| 39 | FIND_AND_ADD_LLD_LIB(lldCommon) | |
| 39 | 40 | endif() |
| 40 | 41 | |
| 41 | 42 | include(FindPackageHandleStandardArgs) |
cmake/Findllvm.cmake+3-3| ... | ... | @@ -8,12 +8,12 @@ |
| 8 | 8 | # LLVM_LIBDIRS |
| 9 | 9 | |
| 10 | 10 | find_program(LLVM_CONFIG_EXE |
| 11 | NAMES llvm-config-5.0 llvm-config | |
| 11 | NAMES llvm-config-6.0 llvm-config | |
| 12 | 12 | PATHS |
| 13 | 13 | "/mingw64/bin" |
| 14 | 14 | "/c/msys64/mingw64/bin" |
| 15 | 15 | "c:/msys64/mingw64/bin" |
| 16 | "C:/Libraries/llvm-5.0.0/bin") | |
| 16 | "C:/Libraries/llvm-6.0.0/bin") | |
| 17 | 17 | |
| 18 | 18 | if(NOT(CMAKE_BUILD_TYPE STREQUAL "Debug")) |
| 19 | 19 | execute_process( |
| ... | ... | @@ -62,7 +62,7 @@ execute_process( |
| 62 | 62 | set(LLVM_LIBRARIES ${LLVM_LIBRARIES} ${LLVM_SYSTEM_LIBS}) |
| 63 | 63 | |
| 64 | 64 | if(NOT LLVM_LIBRARIES) |
| 65 | find_library(LLVM_LIBRARIES NAMES LLVM LLVM-5.0 LLVM-5) | |
| 65 | find_library(LLVM_LIBRARIES NAMES LLVM LLVM-6.0 LLVM-6) | |
| 66 | 66 | endif() |
| 67 | 67 | |
| 68 | 68 | link_directories("${CMAKE_PREFIX_PATH}/lib") |
deps/lld-prebuilt/COFF/Options.inc+61-24| ... | ... | @@ -12,9 +12,10 @@ |
| 12 | 12 | #ifdef PREFIX |
| 13 | 13 | #define COMMA , |
| 14 | 14 | PREFIX(prefix_0, {nullptr}) |
| 15 | PREFIX(prefix_3, {"--" COMMA nullptr}) | |
| 15 | 16 | PREFIX(prefix_2, {"/" COMMA "-" COMMA nullptr}) |
| 16 | 17 | PREFIX(prefix_1, {"/" COMMA "-" COMMA "-?" COMMA nullptr}) |
| 17 | PREFIX(prefix_3, {"/?" COMMA "-?" COMMA nullptr}) | |
| 18 | PREFIX(prefix_4, {"/?" COMMA "-?" COMMA nullptr}) | |
| 18 | 19 | #undef COMMA |
| 19 | 20 | #endif // PREFIX |
| 20 | 21 | |
| ... | ... | @@ -30,19 +31,26 @@ OPTION(prefix_0, "<input>", INPUT, Input, INVALID, INVALID, nullptr, 0, 0, nullp |
| 30 | 31 | OPTION(prefix_0, "<unknown>", UNKNOWN, Unknown, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 31 | 32 | OPTION(prefix_1, "align:", align, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 32 | 33 | "Section alignment", nullptr, nullptr) |
| 34 | OPTION(prefix_1, "aligncomm:", aligncomm, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 35 | "Set common symbol alignment", nullptr, nullptr) | |
| 33 | 36 | OPTION(prefix_1, "allowbind:no", allowbind_no, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 34 | 37 | "Disable DLL binding", nullptr, nullptr) |
| 35 | OPTION(prefix_1, "allowbind", allowbind, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 38 | OPTION(prefix_1, "allowbind", allowbind, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 39 | "Enable DLL binding (default)", nullptr, nullptr) | |
| 36 | 40 | OPTION(prefix_1, "allowisolation:no", allowisolation_no, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 37 | "Set NO_ISOLATION bit", nullptr, nullptr) | |
| 38 | OPTION(prefix_1, "allowisolation", allowisolation, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 41 | "Disable DLL isolation", nullptr, nullptr) | |
| 42 | OPTION(prefix_1, "allowisolation", allowisolation, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 43 | "Enable DLL isolation (default)", nullptr, nullptr) | |
| 39 | 44 | OPTION(prefix_1, "alternatename:", alternatename, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 40 | 45 | "Define weak alias", nullptr, nullptr) |
| 41 | 46 | OPTION(prefix_1, "appcontainer:no", appcontainer_no, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 47 | "Image can run outside an app container (default)", nullptr, nullptr) | |
| 48 | OPTION(prefix_1, "appcontainer", appcontainer, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 42 | 49 | "Image can only be run in an app container", nullptr, nullptr) |
| 43 | OPTION(prefix_1, "appcontainer", appcontainer, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 44 | 50 | OPTION(prefix_1, "base:", base, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 45 | 51 | "Base address of the program", nullptr, nullptr) |
| 52 | OPTION(prefix_1, "debug:dwarf", debug_dwarf, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 53 | OPTION(prefix_1, "debug:ghash", debug_ghash, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 46 | 54 | OPTION(prefix_1, "debugtype:", debugtype, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 47 | 55 | "Debug Info Options", nullptr, nullptr) |
| 48 | 56 | OPTION(prefix_1, "debug", debug, Flag, INVALID, INVALID, nullptr, 0, 0, |
| ... | ... | @@ -60,22 +68,25 @@ OPTION(prefix_1, "dll", dll, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 60 | 68 | OPTION(prefix_1, "driver:", driver, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 61 | 69 | "Generate a Windows NT Kernel Mode Driver", nullptr, nullptr) |
| 62 | 70 | OPTION(prefix_1, "dynamicbase:no", dynamicbase_no, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 63 | "Disable address space layout randomization", nullptr, nullptr) | |
| 64 | OPTION(prefix_1, "dynamicbase", dynamicbase, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 71 | "Disable ASLR (default when /fixed)", nullptr, nullptr) | |
| 72 | OPTION(prefix_1, "dynamicbase", dynamicbase, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 73 | "Enable ASLR (default unless /fixed)", nullptr, nullptr) | |
| 65 | 74 | OPTION(prefix_1, "editandcontinue", editandcontinue, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 66 | 75 | OPTION(prefix_1, "entry:", entry, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 67 | 76 | "Name of entry point symbol", nullptr, nullptr) |
| 68 | 77 | OPTION(prefix_1, "errorlimit:", errorlimit, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 69 | 78 | "Maximum number of errors to emit before stopping (0 = no limit)", nullptr, nullptr) |
| 70 | 79 | OPTION(prefix_1, "errorreport:", errorreport, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 80 | OPTION(prefix_1, "export-all-symbols", export_all_symbols, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 71 | 81 | OPTION(prefix_1, "export:", export, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 72 | 82 | "Export a function", nullptr, nullptr) |
| 73 | 83 | OPTION(prefix_1, "failifmismatch:", failifmismatch, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 74 | 84 | "", nullptr, nullptr) |
| 75 | 85 | OPTION(prefix_1, "fastfail", fastfail, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 76 | 86 | OPTION(prefix_1, "fixed:no", fixed_no, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 77 | "Enable base relocations", nullptr, nullptr) | |
| 78 | OPTION(prefix_1, "fixed", fixed, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 87 | "Enable base relocations (default)", nullptr, nullptr) | |
| 88 | OPTION(prefix_1, "fixed", fixed, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 89 | "Disable base relocations", nullptr, nullptr) | |
| 79 | 90 | OPTION(prefix_1, "force:unresolved", force_unresolved, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 80 | 91 | OPTION(prefix_1, "force", force, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 81 | 92 | "Allow undefined symbols when creating executables", nullptr, nullptr) |
| ... | ... | @@ -85,10 +96,12 @@ OPTION(prefix_1, "heap:", heap, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 85 | 96 | "Size of the heap", nullptr, nullptr) |
| 86 | 97 | OPTION(prefix_1, "help", help, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 87 | 98 | OPTION(prefix_1, "highentropyva:no", highentropyva_no, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 88 | "Set HIGH_ENTROPY_VA bit", nullptr, nullptr) | |
| 89 | OPTION(prefix_1, "highentropyva", highentropyva, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 99 | "Disable 64-bit ASLR", nullptr, nullptr) | |
| 100 | OPTION(prefix_1, "highentropyva", highentropyva, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 101 | "Enable 64-bit ASLR (default on 64-bit)", nullptr, nullptr) | |
| 90 | 102 | OPTION(prefix_1, "idlout:", idlout, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 91 | OPTION(prefix_1, "ignore:", ignore, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 103 | OPTION(prefix_1, "ignore:", ignore, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 104 | "Specify warning codes to ignore", nullptr, nullptr) | |
| 92 | 105 | OPTION(prefix_1, "ignoreidl", ignoreidl, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 93 | 106 | OPTION(prefix_1, "implib:", implib, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 94 | 107 | "Import library name", nullptr, nullptr) |
| ... | ... | @@ -97,14 +110,20 @@ OPTION(prefix_2, "include:", incl, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 97 | 110 | OPTION(prefix_1, "incremental:no", no_incremental, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 98 | 111 | OPTION(prefix_1, "incremental", incremental, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 99 | 112 | OPTION(prefix_1, "largeaddressaware:no", largeaddressaware_no, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 100 | "Disable large addresses", nullptr, nullptr) | |
| 101 | OPTION(prefix_1, "largeaddressaware", largeaddressaware, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 113 | "Disable large addresses (default on 32-bit)", nullptr, nullptr) | |
| 114 | OPTION(prefix_1, "largeaddressaware", largeaddressaware, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 115 | "Enable large addresses (default on 64-bit)", nullptr, nullptr) | |
| 102 | 116 | OPTION(prefix_1, "libpath:", libpath, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 103 | 117 | "Additional library search path", nullptr, nullptr) |
| 104 | 118 | OPTION(prefix_1, "linkrepro:", linkrepro, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 105 | 119 | "Dump linker invocation and input files for debugging", nullptr, nullptr) |
| 120 | OPTION(prefix_1, "lldltocache:", lldltocache, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 121 | "Path to ThinLTO cached object file directory", nullptr, nullptr) | |
| 122 | OPTION(prefix_1, "lldltocachepolicy:", lldltocachepolicy, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 123 | "Pruning policy for the ThinLTO cache", nullptr, nullptr) | |
| 106 | 124 | OPTION(prefix_2, "lldmap:", lldmap_file, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 107 | 125 | 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) | |
| 108 | 127 | OPTION(prefix_1, "lldsavetemps", lldsavetemps, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 109 | 128 | "Save temporary files instead of deleting them", nullptr, nullptr) |
| 110 | 129 | OPTION(prefix_1, "machine:", machine, Joined, INVALID, INVALID, nullptr, 0, 0, |
| ... | ... | @@ -126,28 +145,31 @@ OPTION(prefix_1, "merge:", merge, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 126 | 145 | OPTION(prefix_1, "mllvm:", mllvm, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 127 | 146 | "Options to pass to LLVM", nullptr, nullptr) |
| 128 | 147 | 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) | |
| 129 | 149 | OPTION(prefix_1, "nodefaultlib:", nodefaultlib, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 130 | 150 | "Remove a default library", nullptr, nullptr) |
| 131 | 151 | OPTION(prefix_1, "nodefaultlib", nodefaultlib_all, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 132 | 152 | OPTION(prefix_1, "noentry", noentry, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 133 | 153 | OPTION(prefix_1, "nologo", nologo, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 134 | OPTION(prefix_1, "nopdb", nopdb, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 135 | "Disable PDB generation for DWARF users", nullptr, nullptr) | |
| 136 | OPTION(prefix_1, "nosymtab", nosymtab, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 137 | 154 | OPTION(prefix_1, "nxcompat:no", nxcompat_no, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 138 | 155 | "Disable data execution provention", nullptr, nullptr) |
| 139 | OPTION(prefix_1, "nxcompat", nxcompat, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 156 | OPTION(prefix_1, "nxcompat", nxcompat, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 157 | "Enable data execution prevention (default)", nullptr, nullptr) | |
| 140 | 158 | OPTION(prefix_1, "opt:", opt, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 141 | 159 | "Control optimizations", nullptr, nullptr) |
| 142 | 160 | OPTION(prefix_1, "out:", out, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 143 | 161 | "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) | |
| 144 | 163 | OPTION(prefix_1, "pdb:", pdb, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 145 | 164 | "PDB file path", nullptr, nullptr) |
| 146 | 165 | OPTION(prefix_1, "pdbaltpath:", pdbaltpath, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 147 | 166 | 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, | |
| 168 | "Quoting style for response files, 'windows' (default) or 'posix'", nullptr, nullptr) | |
| 148 | 169 | OPTION(prefix_1, "safeseh:no", safeseh_no, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 149 | "Produce an image with Safe Exception Handler", nullptr, nullptr) | |
| 150 | OPTION(prefix_1, "safeseh", safeseh, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 170 | "Don't produce an image with Safe Exception Handler", nullptr, nullptr) | |
| 171 | OPTION(prefix_1, "safeseh", safeseh, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 172 | "Produce an image with Safe Exception Handler (only for x86)", nullptr, nullptr) | |
| 151 | 173 | OPTION(prefix_1, "section:", section, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 152 | 174 | "Specify section attributes", nullptr, nullptr) |
| 153 | 175 | OPTION(prefix_1, "stack:", stack, Joined, INVALID, INVALID, nullptr, 0, 0, |
| ... | ... | @@ -163,12 +185,27 @@ OPTION(prefix_1, "tlbid:", tlbid, Joined, INVALID, INVALID, nullptr, 0, 0, nullp |
| 163 | 185 | OPTION(prefix_1, "tlbout:", tlbout, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 164 | 186 | OPTION(prefix_1, "tsaware:no", tsaware_no, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 165 | 187 | "Create non-Terminal Server aware executable", nullptr, nullptr) |
| 166 | OPTION(prefix_1, "tsaware", tsaware, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 188 | OPTION(prefix_1, "tsaware", tsaware, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 189 | "Create Terminal Server aware executable (default)", nullptr, nullptr) | |
| 167 | 190 | OPTION(prefix_1, "verbose:", verbose_all, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 168 | 191 | OPTION(prefix_1, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 169 | 192 | OPTION(prefix_1, "version:", version, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 170 | 193 | "Specify a version number in the PE header", nullptr, nullptr) |
| 171 | OPTION(prefix_1, "wx:no", wx_no, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 172 | OPTION(prefix_1, "wx", wx, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 173 | OPTION(prefix_3, "", help_q, Flag, INVALID, help, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 194 | OPTION(prefix_3, "version", dash_dash_version, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 195 | "Print version information", nullptr, nullptr) | |
| 196 | OPTION(prefix_1, "wholearchive:", wholearchive_file, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 197 | "Include all object files from this archive", nullptr, nullptr) | |
| 198 | OPTION(prefix_1, "wholearchive", wholearchive_flag, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 199 | OPTION(prefix_1, "WX:no", WX_no, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 200 | "Don't treat warnings as errors", nullptr, nullptr) | |
| 201 | OPTION(prefix_1, "WX", WX, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 202 | "Treat warnings as errors", nullptr, nullptr) | |
| 203 | OPTION(prefix_4, "", help_q, Flag, INVALID, help, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 174 | 204 | #endif // OPTION |
| 205 | ||
| 206 | #ifdef OPTTABLE_ARG_INIT | |
| 207 | ////////// | |
| 208 | // Option Values | |
| 209 | ||
| 210 | ||
| 211 | #endif // OPTTABLE_ARG_INIT |
deps/lld-prebuilt/DarwinLdOptions.inc+7| ... | ... | @@ -187,3 +187,10 @@ OPTION(prefix_1, "v", v, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 187 | 187 | OPTION(prefix_1, "Z", Z, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 188 | 188 | "Do not search standard directories for libraries or frameworks", nullptr, nullptr) |
| 189 | 189 | #endif // OPTION |
| 190 | ||
| 191 | #ifdef OPTTABLE_ARG_INIT | |
| 192 | ////////// | |
| 193 | // Option Values | |
| 194 | ||
| 195 | ||
| 196 | #endif // OPTTABLE_ARG_INIT |
deps/lld-prebuilt/ELF/Options.inc+124-46| ... | ... | @@ -52,19 +52,23 @@ OPTION(prefix_2, "build-id", build_id, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 52 | 52 | "Generate build ID note", nullptr, nullptr) |
| 53 | 53 | OPTION(prefix_2, "b", alias_format_b, Separate, INVALID, format, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 54 | 54 | OPTION(prefix_2, "call_shared", alias_Bdynamic_call_shared, Flag, INVALID, Bdynamic, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 55 | OPTION(prefix_2, "chroot", chroot, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 55 | 56 | OPTION(prefix_2, "color-diagnostics=", color_diagnostics_eq, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 56 | 57 | "Use colors in diagnostics", nullptr, nullptr) |
| 57 | 58 | OPTION(prefix_2, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 58 | 59 | "Use colors in diagnostics", nullptr, nullptr) |
| 59 | OPTION(prefix_2, "compress-debug-sections=", compress_debug_sections, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 60 | OPTION(prefix_2, "compress-debug-sections=", compress_debug_sections_eq, Joined, INVALID, compress_debug_sections, nullptr, 0, 0, | |
| 60 | 61 | "Compress DWARF debug sections", nullptr, nullptr) |
| 61 | OPTION(prefix_3, "cref", cref, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 62 | OPTION(prefix_2, "compress-debug-sections", compress_debug_sections, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 63 | "Compress DWARF debug sections", nullptr, nullptr) | |
| 64 | OPTION(prefix_2, "cref", cref, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 62 | 65 | OPTION(prefix_2, "dc", alias_define_common_dc, Flag, INVALID, define_common, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 63 | 66 | OPTION(prefix_2, "define-common", define_common, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 64 | 67 | "Assign space to common symbols", nullptr, nullptr) |
| 65 | OPTION(prefix_2, "defsym=", defsym, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 68 | OPTION(prefix_2, "defsym=", defsym_eq, Joined, INVALID, defsym, nullptr, 0, 0, | |
| 69 | "Define a symbol alias", nullptr, nullptr) | |
| 70 | OPTION(prefix_2, "defsym", defsym, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 66 | 71 | "Define a symbol alias", nullptr, nullptr) |
| 67 | OPTION(prefix_2, "defsym", alias_defsym, Separate, INVALID, defsym, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 68 | 72 | OPTION(prefix_2, "demangle", demangle, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 69 | 73 | "Demangle symbol names", nullptr, nullptr) |
| 70 | 74 | OPTION(prefix_2, "detect-odr-violations", detect_odr_violations, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| ... | ... | @@ -81,7 +85,8 @@ OPTION(prefix_2, "dn", alias_Bstatic_dn, Flag, INVALID, Bstatic, nullptr, 0, 0, |
| 81 | 85 | OPTION(prefix_2, "dp", alias_define_common_dp, Flag, INVALID, define_common, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 82 | 86 | OPTION(prefix_2, "dynamic-linker", dynamic_linker, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 83 | 87 | "Which dynamic linker to use", nullptr, nullptr) |
| 84 | OPTION(prefix_2, "dynamic-list=", alias_dynamic_list, Joined, INVALID, dynamic_list, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 88 | OPTION(prefix_2, "dynamic-list=", dynamic_list_eq, Joined, INVALID, dynamic_list, nullptr, 0, 0, | |
| 89 | "Read a list of dynamic symbols", nullptr, nullptr) | |
| 85 | 90 | OPTION(prefix_2, "dynamic-list", dynamic_list, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 86 | 91 | "Read a list of dynamic symbols", nullptr, nullptr) |
| 87 | 92 | OPTION(prefix_2, "dy", alias_Bdynamic_dy, Flag, INVALID, Bdynamic, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| ... | ... | @@ -97,18 +102,22 @@ OPTION(prefix_2, "enable-new-dtags", enable_new_dtags, Flag, INVALID, INVALID, n |
| 97 | 102 | OPTION(prefix_2, "end-group", end_group, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 98 | 103 | OPTION(prefix_2, "end-lib", end_lib, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 99 | 104 | "End a grouping of objects that should be treated as if they were together in an archive", nullptr, nullptr) |
| 100 | OPTION(prefix_2, "entry=", alias_entry_entry, Joined, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 105 | OPTION(prefix_2, "entry=", entry_eq, Joined, INVALID, entry, nullptr, 0, 0, | |
| 106 | "Name of entry point symbol", "<entry>", nullptr) | |
| 101 | 107 | OPTION(prefix_2, "entry", entry, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 102 | 108 | "Name of entry point symbol", "<entry>", nullptr) |
| 103 | OPTION(prefix_2, "error-limit=", alias_error_limit, Joined, INVALID, error_limit, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 109 | 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) | |
| 104 | 111 | OPTION(prefix_2, "error-limit", error_limit, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 105 | 112 | "Maximum number of errors to emit before stopping (0 = no limit)", nullptr, nullptr) |
| 106 | 113 | OPTION(prefix_2, "error-unresolved-symbols", error_unresolved_symbols, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 107 | 114 | "Report unresolved symbols as errors", nullptr, nullptr) |
| 108 | OPTION(prefix_2, "exclude-libs=", alias_exclude_libs, Joined, INVALID, exclude_libs, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 115 | OPTION(prefix_2, "exclude-libs=", exclude_libs_eq, Joined, INVALID, exclude_libs, nullptr, 0, 0, | |
| 116 | "Exclude static libraries from automatic export", nullptr, nullptr) | |
| 109 | 117 | OPTION(prefix_2, "exclude-libs", exclude_libs, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 110 | 118 | "Exclude static libraries from automatic export", nullptr, nullptr) |
| 111 | OPTION(prefix_2, "export-dynamic-symbol=", alias_export_dynamic_symbol, Joined, INVALID, export_dynamic_symbol, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 119 | 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) | |
| 112 | 121 | OPTION(prefix_2, "export-dynamic-symbol", export_dynamic_symbol, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 113 | 122 | "Put a symbol in the dynamic symbol table", nullptr, nullptr) |
| 114 | 123 | OPTION(prefix_2, "export-dynamic", export_dynamic, Flag, INVALID, INVALID, nullptr, 0, 0, |
| ... | ... | @@ -117,12 +126,19 @@ OPTION(prefix_1, "E", alias_export_dynamic_E, Flag, INVALID, export_dynamic, nul |
| 117 | 126 | OPTION(prefix_1, "e", alias_entry_e, JoinedOrSeparate, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 118 | 127 | OPTION(prefix_2, "fatal-warnings", fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 119 | 128 | "Treat warnings as errors", nullptr, nullptr) |
| 120 | OPTION(prefix_2, "filter=", filter, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 129 | OPTION(prefix_2, "filter=", filter_eq, Joined, INVALID, filter, nullptr, 0, 0, | |
| 130 | "Set DT_FILTER field to the specified name", nullptr, nullptr) | |
| 131 | OPTION(prefix_2, "filter", filter, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 121 | 132 | "Set DT_FILTER field to the specified name", nullptr, nullptr) |
| 122 | OPTION(prefix_2, "fini=", alias_fini_fini, Joined, INVALID, fini, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 133 | OPTION(prefix_2, "fini=", fini_eq, Joined, INVALID, fini, nullptr, 0, 0, | |
| 134 | "Specify a finalizer function", "<symbol>", nullptr) | |
| 123 | 135 | OPTION(prefix_2, "fini", fini, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 124 | 136 | "Specify a finalizer function", "<symbol>", nullptr) |
| 125 | OPTION(prefix_2, "format=", format, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 137 | 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) | |
| 139 | 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) | |
| 141 | OPTION(prefix_2, "format", format, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 126 | 142 | "Change the input format of the inputs following this option", "<input-format>", nullptr) |
| 127 | 143 | OPTION(prefix_2, "full-shutdown", full_shutdown, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 128 | 144 | "Perform a full shutdown instead of calling _exit", nullptr, nullptr) |
| ... | ... | @@ -134,23 +150,36 @@ OPTION(prefix_2, "gdb-index", gdb_index, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 134 | 150 | "Generate .gdb_index section", nullptr, nullptr) |
| 135 | 151 | OPTION(prefix_1, "G", G, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 136 | 152 | OPTION(prefix_1, "g", g, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 137 | OPTION(prefix_2, "hash-style=", alias_hash_style_hash_style, Joined, INVALID, hash_style, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 153 | 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) | |
| 138 | 155 | OPTION(prefix_2, "hash-style", hash_style, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 139 | 156 | "Specify hash style (sysv, gnu or both)", nullptr, nullptr) |
| 140 | 157 | OPTION(prefix_2, "help", help, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 141 | 158 | "Print option help", nullptr, nullptr) |
| 142 | 159 | OPTION(prefix_1, "h", alias_soname_h, JoinedOrSeparate, INVALID, soname, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 160 | OPTION(prefix_2, "icf-data", icf_data, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 161 | "Enable ICF to also fold identical read only data", nullptr, nullptr) | |
| 143 | 162 | OPTION(prefix_2, "icf=all", icf_all, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 144 | 163 | "Enable identical code folding", nullptr, nullptr) |
| 145 | 164 | OPTION(prefix_2, "icf=none", icf_none, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 146 | 165 | "Disable identical code folding", nullptr, nullptr) |
| 147 | OPTION(prefix_2, "image-base=", image_base, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 166 | OPTION(prefix_2, "image-base=", image_base_eq, Joined, INVALID, image_base, nullptr, 0, 0, | |
| 148 | 167 | "Set the base address", nullptr, nullptr) |
| 149 | OPTION(prefix_2, "init=", alias_init_init, Joined, INVALID, init, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 168 | OPTION(prefix_2, "image-base", image_base, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 169 | "Set the base address", nullptr, nullptr) | |
| 170 | OPTION(prefix_2, "init=", init_eq, Joined, INVALID, init, nullptr, 0, 0, | |
| 171 | "Specify an initializer function", "<symbol>", nullptr) | |
| 150 | 172 | OPTION(prefix_2, "init", init, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 151 | 173 | "Specify an initializer function", "<symbol>", nullptr) |
| 152 | OPTION(prefix_2, "library-path=", alias_L__library_path, Joined, INVALID, L, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 153 | OPTION(prefix_2, "library=", alias_l__library, Joined, INVALID, l, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 174 | 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) | |
| 176 | OPTION(prefix_2, "library-path", library_path, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 177 | "Add a directory to the library search path", "<dir>", nullptr) | |
| 178 | OPTION(prefix_2, "library=", library_eq, Joined, INVALID, library, nullptr, 0, 0, | |
| 179 | "Root name of library to use", "<libName>", nullptr) | |
| 180 | OPTION(prefix_2, "library", library, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 181 | "Root name of library to use", "<libName>", nullptr) | |
| 182 | OPTION(prefix_2, "long-plt", long_plt, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 154 | 183 | OPTION(prefix_2, "lto-aa-pipeline=", lto_aa_pipeline, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 155 | 184 | "AA pipeline to run during LTO. Used in conjunction with -lto-newpm-passes", nullptr, nullptr) |
| 156 | 185 | OPTION(prefix_2, "lto-newpm-passes=", lto_newpm_passes, Joined, INVALID, INVALID, nullptr, 0, 0, |
| ... | ... | @@ -159,13 +188,14 @@ OPTION(prefix_2, "lto-O", lto_O, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 159 | 188 | "Optimization level for LTO", "<opt-level>", nullptr) |
| 160 | 189 | OPTION(prefix_2, "lto-partitions=", lto_partitions, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 161 | 190 | "Number of LTO codegen partitions", nullptr, nullptr) |
| 162 | OPTION(prefix_1, "L", L, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | |
| 163 | "Add a directory to the library search path", "<dir>", nullptr) | |
| 164 | OPTION(prefix_1, "l", l, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | |
| 165 | "Root name of library to use", "<libName>", nullptr) | |
| 166 | OPTION(prefix_2, "Map=", alias_Map_eq, Joined, INVALID, Map, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 167 | OPTION(prefix_2, "Map", Map, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | |
| 191 | OPTION(prefix_1, "L", alias_library_path, JoinedOrSeparate, INVALID, library_path, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 192 | OPTION(prefix_1, "l", alias_library, JoinedOrSeparate, INVALID, library, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 193 | OPTION(prefix_2, "Map=", Map_eq, Joined, INVALID, Map, nullptr, 0, 0, | |
| 168 | 194 | "Print a link map to the specified file", nullptr, nullptr) |
| 195 | OPTION(prefix_2, "Map", Map, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 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, | |
| 198 | "Enable merging .ARM.exidx entries", nullptr, nullptr) | |
| 169 | 199 | OPTION(prefix_2, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 170 | 200 | OPTION(prefix_1, "M", alias_print_map_M, Flag, INVALID, print_map, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 171 | 201 | OPTION(prefix_1, "m", m, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| ... | ... | @@ -176,21 +206,32 @@ OPTION(prefix_2, "no-as-needed", no_as_needed, Flag, INVALID, INVALID, nullptr, |
| 176 | 206 | "Always DT_NEEDED for shared libraries", nullptr, nullptr) |
| 177 | 207 | OPTION(prefix_2, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 178 | 208 | "Do not use colors in diagnostics", nullptr, nullptr) |
| 179 | OPTION(prefix_2, "no-copy-dt-needed-entries", no_copy_dt_needed_entries, Flag, INVALID, no_add_needed, nullptr, 0, 0, nullptr, 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) | |
| 210 | OPTION(prefix_2, "no-ctors-in-init-array", no_ctors_in_init_array, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 180 | 211 | OPTION(prefix_2, "no-define-common", no_define_common, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 181 | 212 | "Do not assign space to common symbols", nullptr, nullptr) |
| 182 | 213 | OPTION(prefix_2, "no-demangle", no_demangle, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 183 | 214 | "Do not demangle symbol names", nullptr, nullptr) |
| 184 | 215 | OPTION(prefix_2, "no-dynamic-linker", no_dynamic_linker, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 185 | 216 | "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, | |
| 218 | "Do not create .eh_frame_hdr section", nullptr, nullptr) | |
| 186 | 219 | OPTION(prefix_2, "no-export-dynamic", no_export_dynamic, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 187 | 220 | OPTION(prefix_2, "no-fatal-warnings", no_fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 188 | 221 | OPTION(prefix_2, "no-gc-sections", no_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 189 | 222 | "Disable garbage collection of unused sections", nullptr, nullptr) |
| 223 | OPTION(prefix_2, "no-gdb-index", no_gdb_index, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 224 | "Do not generate .gdb_index section", nullptr, nullptr) | |
| 190 | 225 | OPTION(prefix_2, "no-gnu-unique", no_gnu_unique, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 191 | 226 | "Disable STB_GNU_UNIQUE symbol binding", nullptr, nullptr) |
| 192 | 227 | OPTION(prefix_2, "no-keep-memory", no_keep_memory, 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, | |
| 229 | "Disable merging .ARM.exidx entries", nullptr, nullptr) | |
| 193 | 230 | OPTION(prefix_2, "no-mmap-output-file", no_mmap_output_file, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 231 | OPTION(prefix_3, "no-omagic", no_omagic, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 232 | "Do not set the text data sections to be writable", "<magic>", nullptr) | |
| 233 | 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) | |
| 194 | 235 | OPTION(prefix_2, "no-rosegment", no_rosegment, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 195 | 236 | "Do not put read-only non-executable sections in their own segment", nullptr, nullptr) |
| 196 | 237 | OPTION(prefix_2, "no-threads", no_threads, Flag, INVALID, INVALID, nullptr, 0, 0, |
| ... | ... | @@ -219,17 +260,25 @@ OPTION(prefix_3, "opt-remarks-filename", opt_remarks_filename, Separate, INVALID |
| 219 | 260 | "YAML output file for optimization remarks", nullptr, nullptr) |
| 220 | 261 | OPTION(prefix_3, "opt-remarks-with-hotness", opt_remarks_with_hotness, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 221 | 262 | "Include hotness informations in the optimization remarks file", nullptr, nullptr) |
| 263 | 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) | |
| 265 | OPTION(prefix_2, "orphan-handling", orphan_handling, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 266 | "Control how orphan sections are handled when linker script used", nullptr, nullptr) | |
| 222 | 267 | OPTION(prefix_3, "output=", alias_o_output, Joined, INVALID, o, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 223 | 268 | OPTION(prefix_3, "output", alias_o_output2, Separate, INVALID, o, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 224 | OPTION(prefix_1, "O", O, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 269 | OPTION(prefix_1, "O", O, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | |
| 225 | 270 | "Optimize output file size", nullptr, nullptr) |
| 226 | 271 | OPTION(prefix_1, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| 227 | 272 | "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, | |
| 274 | "Pack dynamic relocations in the given format (none or android)", "<format>", nullptr) | |
| 228 | 275 | OPTION(prefix_2, "pic-executable", alias_pie_pic_executable, Flag, INVALID, pie, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 229 | 276 | OPTION(prefix_2, "pie", pie, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 230 | 277 | "Create a position independent executable", nullptr, nullptr) |
| 231 | OPTION(prefix_2, "plugin-opt=", plugin_opt_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 232 | OPTION(prefix_2, "plugin-opt", plugin_opt, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 278 | 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) | |
| 280 | OPTION(prefix_2, "plugin-opt", plugin_opt, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 281 | "specifies LTO options for compatibility with GNU linkers", nullptr, nullptr) | |
| 233 | 282 | OPTION(prefix_2, "plugin=", plugin_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 234 | 283 | OPTION(prefix_2, "plugin", plugin, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 235 | 284 | OPTION(prefix_2, "print-gc-sections", print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, |
| ... | ... | @@ -240,34 +289,42 @@ OPTION(prefix_2, "Qy", Qy, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullp |
| 240 | 289 | OPTION(prefix_1, "q", alias_emit_relocs, Flag, INVALID, emit_relocs, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 241 | 290 | OPTION(prefix_2, "relocatable", relocatable, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 242 | 291 | "Create relocatable object file", nullptr, nullptr) |
| 243 | OPTION(prefix_2, "reproduce=", alias_reproduce_eq, Joined, INVALID, reproduce, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 292 | OPTION(prefix_2, "reproduce=", reproduce_eq, Joined, INVALID, reproduce, nullptr, 0, 0, | |
| 293 | "Dump linker invocation and input files for debugging", nullptr, nullptr) | |
| 244 | 294 | OPTION(prefix_2, "reproduce", reproduce, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 245 | 295 | "Dump linker invocation and input files for debugging", nullptr, nullptr) |
| 246 | OPTION(prefix_2, "retain-symbols-file=", retain_symbols_file, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 296 | 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) | |
| 298 | OPTION(prefix_2, "retain-symbols-file", retain_symbols_file, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 247 | 299 | "Retain only the symbols listed in the file", "<file>", nullptr) |
| 248 | OPTION(prefix_2, "retain-symbols-file", alias_retain_symbols_file, Separate, INVALID, retain_symbols_file, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 249 | 300 | OPTION(prefix_2, "rpath-link=", rpath_link_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 250 | 301 | OPTION(prefix_2, "rpath-link", rpath_link, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 251 | OPTION(prefix_2, "rpath=", alias_rpath_rpath, Joined, INVALID, rpath, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 302 | OPTION(prefix_2, "rpath=", rpath_eq, Joined, INVALID, rpath, nullptr, 0, 0, | |
| 303 | "Add a DT_RUNPATH to the output", nullptr, nullptr) | |
| 252 | 304 | OPTION(prefix_2, "rpath", rpath, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 253 | 305 | "Add a DT_RUNPATH to the output", nullptr, nullptr) |
| 254 | OPTION(prefix_2, "rsp-quoting=", rsp_quoting, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 306 | 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) | |
| 308 | OPTION(prefix_2, "rsp-quoting", rsp_quoting, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 255 | 309 | "Quoting style for response files. Values supported: windows|posix", nullptr, nullptr) |
| 256 | 310 | OPTION(prefix_1, "R", alias_rpath_R, JoinedOrSeparate, INVALID, rpath, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 257 | 311 | OPTION(prefix_1, "r", alias_relocatable_r, Flag, INVALID, relocatable, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 258 | 312 | OPTION(prefix_2, "save-temps", save_temps, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 259 | OPTION(prefix_2, "script=", alias_script, Joined, INVALID, script, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 313 | OPTION(prefix_2, "script=", script_eq, Joined, INVALID, script, nullptr, 0, 0, | |
| 314 | "Read linker script", nullptr, nullptr) | |
| 260 | 315 | OPTION(prefix_2, "script", script, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 261 | 316 | "Read linker script", nullptr, nullptr) |
| 262 | 317 | OPTION(prefix_2, "section-start", section_start, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 263 | 318 | "Set address of section", "<address>", nullptr) |
| 264 | 319 | OPTION(prefix_2, "shared", shared, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 265 | 320 | "Build a shared object", nullptr, nullptr) |
| 266 | OPTION(prefix_2, "soname=", soname, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 321 | OPTION(prefix_2, "soname=", soname_eq, Joined, INVALID, soname, nullptr, 0, 0, | |
| 322 | "Set DT_SONAME", nullptr, nullptr) | |
| 323 | OPTION(prefix_2, "soname", soname, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 267 | 324 | "Set DT_SONAME", nullptr, nullptr) |
| 268 | OPTION(prefix_2, "soname", alias_soname_soname, Separate, INVALID, soname, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 269 | 325 | OPTION(prefix_2, "sort-common", sort_common, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 270 | OPTION(prefix_2, "sort-section=", alias_sort_section, Joined, INVALID, sort_section, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 326 | 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) | |
| 271 | 328 | OPTION(prefix_2, "sort-section", sort_section, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 272 | 329 | "Specifies sections sorting rule when linkerscript is used", nullptr, nullptr) |
| 273 | 330 | OPTION(prefix_2, "start-group", start_group, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| ... | ... | @@ -281,7 +338,9 @@ OPTION(prefix_2, "strip-debug", strip_debug, Flag, INVALID, INVALID, nullptr, 0, |
| 281 | 338 | "Strip debugging information", nullptr, nullptr) |
| 282 | 339 | OPTION(prefix_2, "symbol-ordering-file", symbol_ordering_file, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 283 | 340 | "Layout sections in the order specified by symbol file", nullptr, nullptr) |
| 284 | OPTION(prefix_2, "sysroot=", sysroot, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 341 | OPTION(prefix_2, "sysroot=", sysroot_eq, Joined, INVALID, sysroot, nullptr, 0, 0, | |
| 342 | "Set the system root", nullptr, nullptr) | |
| 343 | OPTION(prefix_2, "sysroot", sysroot, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 285 | 344 | "Set the system root", nullptr, nullptr) |
| 286 | 345 | OPTION(prefix_1, "S", alias_strip_debug_S, Flag, INVALID, strip_debug, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 287 | 346 | OPTION(prefix_1, "s", alias_strip_all, Flag, INVALID, strip_all, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| ... | ... | @@ -289,12 +348,16 @@ OPTION(prefix_2, "target1-abs", target1_abs, Flag, INVALID, INVALID, nullptr, 0, |
| 289 | 348 | "Interpret R_ARM_TARGET1 as R_ARM_ABS32", nullptr, nullptr) |
| 290 | 349 | OPTION(prefix_2, "target1-rel", target1_rel, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 291 | 350 | "Interpret R_ARM_TARGET1 as R_ARM_REL32", nullptr, nullptr) |
| 292 | OPTION(prefix_2, "target2=", target2, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 351 | 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) | |
| 353 | OPTION(prefix_2, "target2", target2, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 293 | 354 | "Interpret R_ARM_TARGET2 as <type>, where <type> is one of rel, abs, or got-rel", "<type>", nullptr) |
| 294 | OPTION(prefix_2, "Tbss=", alias_Tbss, Joined, INVALID, Tbss, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 355 | OPTION(prefix_2, "Tbss=", Tbss_eq, Joined, INVALID, Tbss, nullptr, 0, 0, | |
| 356 | "Same as --section-start with .bss as the sectionname", nullptr, nullptr) | |
| 295 | 357 | OPTION(prefix_2, "Tbss", Tbss, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 296 | 358 | "Same as --section-start with .bss as the sectionname", nullptr, nullptr) |
| 297 | OPTION(prefix_2, "Tdata=", alias_Tdata, Joined, INVALID, Tdata, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 359 | OPTION(prefix_2, "Tdata=", Tdata_eq, Joined, INVALID, Tdata, nullptr, 0, 0, | |
| 360 | "Same as --section-start with .data as the sectionname", nullptr, nullptr) | |
| 298 | 361 | OPTION(prefix_2, "Tdata", Tdata, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 299 | 362 | "Same as --section-start with .data as the sectionname", nullptr, nullptr) |
| 300 | 363 | OPTION(prefix_2, "thinlto-cache-dir=", thinlto_cache_dir, Joined, INVALID, INVALID, nullptr, 0, 0, |
| ... | ... | @@ -305,27 +368,33 @@ OPTION(prefix_2, "thinlto-jobs=", thinlto_jobs, Joined, INVALID, INVALID, nullpt |
| 305 | 368 | "Number of ThinLTO jobs", nullptr, nullptr) |
| 306 | 369 | OPTION(prefix_2, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 307 | 370 | "Run the linker multi-threaded", nullptr, nullptr) |
| 308 | OPTION(prefix_2, "trace-symbol=", trace_trace_symbol_eq, Joined, INVALID, trace_symbol, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 371 | OPTION(prefix_2, "trace-symbol=", trace_symbol_eq, Joined, INVALID, trace_symbol, nullptr, 0, 0, | |
| 372 | "Trace references to symbols", nullptr, nullptr) | |
| 309 | 373 | OPTION(prefix_2, "trace-symbol", trace_symbol, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 310 | 374 | "Trace references to symbols", nullptr, nullptr) |
| 311 | 375 | OPTION(prefix_2, "trace", trace, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 312 | 376 | "Print the names of the input files", nullptr, nullptr) |
| 313 | 377 | OPTION(prefix_2, "Ttext-segment=", alias_Ttext_segment_eq, Joined, INVALID, Ttext, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 314 | 378 | OPTION(prefix_2, "Ttext-segment", alias_Ttext_segment, Separate, INVALID, Ttext, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 315 | OPTION(prefix_2, "Ttext=", alias_Ttext, Joined, INVALID, Ttext, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 379 | OPTION(prefix_2, "Ttext=", Ttext_eq, Joined, INVALID, Ttext, nullptr, 0, 0, | |
| 380 | "Same as --section-start with .text as the sectionname", nullptr, nullptr) | |
| 316 | 381 | OPTION(prefix_2, "Ttext", Ttext, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 317 | 382 | "Same as --section-start with .text as the sectionname", nullptr, nullptr) |
| 318 | 383 | OPTION(prefix_1, "T", alias_script_T, JoinedOrSeparate, INVALID, script, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 319 | 384 | OPTION(prefix_1, "t", alias_trace, Flag, INVALID, trace, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 320 | OPTION(prefix_2, "undefined=", alias_undefined_eq, Joined, INVALID, undefined, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 385 | OPTION(prefix_2, "undefined=", undefined_eq, Joined, INVALID, undefined, nullptr, 0, 0, | |
| 386 | "Force undefined symbol during linking", nullptr, nullptr) | |
| 321 | 387 | OPTION(prefix_2, "undefined", undefined, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 322 | 388 | "Force undefined symbol during linking", nullptr, nullptr) |
| 323 | OPTION(prefix_2, "unresolved-symbols=", unresolved_symbols, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 389 | OPTION(prefix_2, "unresolved-symbols=", unresolved_symbols_eq, Joined, INVALID, unresolved_symbols, nullptr, 0, 0, | |
| 390 | "Determine how to handle unresolved symbols", nullptr, nullptr) | |
| 391 | OPTION(prefix_2, "unresolved-symbols", unresolved_symbols, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 324 | 392 | "Determine how to handle unresolved symbols", nullptr, nullptr) |
| 325 | 393 | OPTION(prefix_1, "u", alias_undefined_u, JoinedOrSeparate, INVALID, undefined, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 326 | 394 | OPTION(prefix_2, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 327 | 395 | "Verbose mode", nullptr, nullptr) |
| 328 | OPTION(prefix_2, "version-script=", alias_version_script_eq, Joined, INVALID, version_script, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 396 | OPTION(prefix_2, "version-script=", version_script_eq, Joined, INVALID, version_script, nullptr, 0, 0, | |
| 397 | "Read a version script", nullptr, nullptr) | |
| 329 | 398 | OPTION(prefix_2, "version-script", version_script, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 330 | 399 | "Read a version script", nullptr, nullptr) |
| 331 | 400 | OPTION(prefix_2, "version", version, Flag, INVALID, INVALID, nullptr, 0, 0, |
| ... | ... | @@ -336,12 +405,14 @@ OPTION(prefix_1, "v", v, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 336 | 405 | OPTION(prefix_2, "warn-common", warn_common, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 337 | 406 | "Warn about duplicate common symbols", nullptr, nullptr) |
| 338 | 407 | OPTION(prefix_2, "warn-execstack", warn_execstack, 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) | |
| 339 | 409 | OPTION(prefix_2, "warn-shared-textrel", warn_shared_textrel, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 340 | 410 | OPTION(prefix_2, "warn-unresolved-symbols", warn_unresolved_symbols, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 341 | 411 | "Report unresolved symbols as warnings", nullptr, nullptr) |
| 342 | 412 | OPTION(prefix_2, "whole-archive", whole_archive, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 343 | 413 | "Force load of all members in a static library", nullptr, nullptr) |
| 344 | OPTION(prefix_2, "wrap=", alias_wrap_wrap, Joined, INVALID, wrap, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 414 | OPTION(prefix_2, "wrap=", wrap_eq, Joined, INVALID, wrap, nullptr, 0, 0, | |
| 415 | "Use wrapper functions for symbol", "<symbol>", nullptr) | |
| 345 | 416 | OPTION(prefix_2, "wrap", wrap, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 346 | 417 | "Use wrapper functions for symbol", "<symbol>", nullptr) |
| 347 | 418 | OPTION(prefix_1, "X", alias_discard_locals_X, Flag, INVALID, discard_locals, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| ... | ... | @@ -350,3 +421,10 @@ OPTION(prefix_1, "y", alias_trace_symbol_y, JoinedOrSeparate, INVALID, trace_sym |
| 350 | 421 | OPTION(prefix_1, "z", z, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| 351 | 422 | "Linker option extensions", "<option>", nullptr) |
| 352 | 423 | #endif // OPTION |
| 424 | ||
| 425 | #ifdef OPTTABLE_ARG_INIT | |
| 426 | ////////// | |
| 427 | // Option Values | |
| 428 | ||
| 429 | ||
| 430 | #endif // OPTTABLE_ARG_INIT |
deps/lld-prebuilt/MinGW/Options.inc created+114| ... | ... | @@ -0,0 +1,114 @@ |
| 1 | /*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ | |
| 2 | |* *| | |
| 3 | |* Option Parsing Definitions *| | |
| 4 | |* *| | |
| 5 | |* Automatically generated file, do not edit! *| | |
| 6 | |* *| | |
| 7 | \*===----------------------------------------------------------------------===*/ | |
| 8 | ||
| 9 | ///////// | |
| 10 | // Prefixes | |
| 11 | ||
| 12 | #ifdef PREFIX | |
| 13 | #define COMMA , | |
| 14 | PREFIX(prefix_0, {nullptr}) | |
| 15 | PREFIX(prefix_1, {"-" COMMA nullptr}) | |
| 16 | PREFIX(prefix_3, {"--" COMMA nullptr}) | |
| 17 | PREFIX(prefix_2, {"--" COMMA "-" COMMA nullptr}) | |
| 18 | #undef COMMA | |
| 19 | #endif // PREFIX | |
| 20 | ||
| 21 | ///////// | |
| 22 | // Groups | |
| 23 | ||
| 24 | #ifdef OPTION | |
| 25 | ||
| 26 | ////////// | |
| 27 | // Options | |
| 28 | ||
| 29 | 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_1, "###", _HASH_HASH_HASH, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 32 | "Print (but do not run) the commands to run for this compilation", nullptr, nullptr) | |
| 33 | OPTION(prefix_2, "Bdynamic", Bdynamic, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 34 | "Link against shared libraries", nullptr, nullptr) | |
| 35 | OPTION(prefix_2, "Bstatic", Bstatic, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 36 | "Do not link against shared libraries", nullptr, nullptr) | |
| 37 | OPTION(prefix_2, "build-id", build_id, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 38 | OPTION(prefix_2, "disable-auto-image-base", disable_auto_image_base, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 39 | OPTION(prefix_2, "dynamicbase", dynamicbase, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 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) | |
| 42 | OPTION(prefix_2, "enable-auto-import", enable_auto_import, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 43 | OPTION(prefix_2, "entry", entry, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 44 | "Name of entry point symbol", "<entry>", nullptr) | |
| 45 | OPTION(prefix_2, "export-all-symbols", export_all_symbols, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 46 | "Export all symbols even if a def file or dllexport attributes are used", nullptr, nullptr) | |
| 47 | OPTION(prefix_1, "e", alias_entry_e, JoinedOrSeparate, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 48 | OPTION(prefix_3, "full-shutdown", full_shutdown, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 49 | OPTION(prefix_2, "gc-sections", gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 50 | "Remove unused sections", nullptr, nullptr) | |
| 51 | OPTION(prefix_2, "high-entropy-va", high_entropy_va, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 52 | "Enable 64-bit ASLR", nullptr, nullptr) | |
| 53 | OPTION(prefix_2, "icf=", icf, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 54 | "Identical code folding", nullptr, nullptr) | |
| 55 | OPTION(prefix_2, "image-base", image_base, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 56 | "Base address of the program", nullptr, nullptr) | |
| 57 | OPTION(prefix_3, "large-address-aware", large_address_aware, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 58 | "Enable large addresses", nullptr, nullptr) | |
| 59 | OPTION(prefix_1, "L", L, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | |
| 60 | "Add a directory to the library search path", "<dir>", nullptr) | |
| 61 | OPTION(prefix_1, "l", l, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | |
| 62 | "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) | |
| 64 | 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) | |
| 66 | OPTION(prefix_1, "m", m, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | |
| 67 | "Set target emulation", nullptr, nullptr) | |
| 68 | OPTION(prefix_2, "no-gc-sections", no_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 69 | "Don't remove unused sections", nullptr, nullptr) | |
| 70 | OPTION(prefix_2, "no-seh", no_seh, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 71 | OPTION(prefix_2, "no-whole-archive", no_whole_archive, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 72 | "No longer include all object files for following archives", nullptr, nullptr) | |
| 73 | OPTION(prefix_2, "nxcompat", nxcompat, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 74 | "Enable data execution prevention", nullptr, nullptr) | |
| 75 | OPTION(prefix_3, "out-implib=", out_implib_eq, Joined, INVALID, out_implib, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 76 | OPTION(prefix_3, "out-implib", out_implib, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 77 | "Import library name", nullptr, nullptr) | |
| 78 | OPTION(prefix_2, "output-def", output_def, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 79 | "Output def file", nullptr, nullptr) | |
| 80 | OPTION(prefix_1, "O", O, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 81 | "Optimize output file size", nullptr, nullptr) | |
| 82 | OPTION(prefix_1, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | |
| 83 | "Path to file to write output", "<path>", nullptr) | |
| 84 | 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, | |
| 86 | "Build a shared object", nullptr, nullptr) | |
| 87 | OPTION(prefix_2, "stack", stack, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 88 | OPTION(prefix_2, "strip-all", strip_all, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 89 | "Omit all symbol information from the output binary", nullptr, nullptr) | |
| 90 | OPTION(prefix_2, "subsystem", subs, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 91 | "Specify subsystem", nullptr, nullptr) | |
| 92 | OPTION(prefix_2, "sysroot", sysroot, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 93 | "Sysroot", nullptr, nullptr) | |
| 94 | 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, | |
| 96 | "Create Terminal Server aware executable", nullptr, nullptr) | |
| 97 | OPTION(prefix_2, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 98 | "Verbose mode", nullptr, nullptr) | |
| 99 | OPTION(prefix_2, "version", version, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 100 | "Display the version number and exit", nullptr, nullptr) | |
| 101 | OPTION(prefix_1, "v", v, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 102 | "Display the version number", nullptr, nullptr) | |
| 103 | OPTION(prefix_2, "whole-archive", whole_archive, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 104 | "Include all object files for following archives", nullptr, nullptr) | |
| 105 | OPTION(prefix_2, "Xlink=", Xlink, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 106 | "Pass <arg> to the COFF linker", "<arg>", nullptr) | |
| 107 | #endif // OPTION | |
| 108 | ||
| 109 | #ifdef OPTTABLE_ARG_INIT | |
| 110 | ////////// | |
| 111 | // Option Values | |
| 112 | ||
| 113 | ||
| 114 | #endif // OPTTABLE_ARG_INIT |
deps/lld-prebuilt/lld/Common/Version.inc created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | #define LLD_VERSION 6.0.0 | |
| 2 | #define LLD_VERSION_STRING "6.0.0" | |
| 3 | #define LLD_VERSION_MAJOR 6 | |
| 4 | #define LLD_VERSION_MINOR 0 | |
| 5 | #define LLD_REVISION_STRING "" | |
| 6 | #define LLD_REPOSITORY_STRING "" |
deps/lld-prebuilt/lld/Config/Version.inc deleted-6| ... | ... | @@ -1,6 +0,0 @@ |
| 1 | #define LLD_VERSION 5.0.1 | |
| 2 | #define LLD_VERSION_STRING "5.0.1" | |
| 3 | #define LLD_VERSION_MAJOR 5 | |
| 4 | #define LLD_VERSION_MINOR 0 | |
| 5 | #define LLD_REVISION_STRING "" | |
| 6 | #define LLD_REPOSITORY_STRING "" |
deps/lld-prebuilt/wasm/Options.inc created+106| ... | ... | @@ -0,0 +1,106 @@ |
| 1 | /*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ | |
| 2 | |* *| | |
| 3 | |* Option Parsing Definitions *| | |
| 4 | |* *| | |
| 5 | |* Automatically generated file, do not edit! *| | |
| 6 | |* *| | |
| 7 | \*===----------------------------------------------------------------------===*/ | |
| 8 | ||
| 9 | ///////// | |
| 10 | // Prefixes | |
| 11 | ||
| 12 | #ifdef PREFIX | |
| 13 | #define COMMA , | |
| 14 | PREFIX(prefix_0, {nullptr}) | |
| 15 | PREFIX(prefix_2, {"-" COMMA nullptr}) | |
| 16 | PREFIX(prefix_1, {"--" COMMA "-" COMMA nullptr}) | |
| 17 | #undef COMMA | |
| 18 | #endif // PREFIX | |
| 19 | ||
| 20 | ///////// | |
| 21 | // Groups | |
| 22 | ||
| 23 | #ifdef OPTION | |
| 24 | ||
| 25 | ////////// | |
| 26 | // Options | |
| 27 | ||
| 28 | OPTION(prefix_0, "<input>", INPUT, Input, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 29 | OPTION(prefix_0, "<unknown>", UNKNOWN, Unknown, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 30 | OPTION(prefix_1, "allow-undefined-file=", allow_undefined_file, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 31 | "Allow symbols listed in <file> to be undefined in linked binary", 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, | |
| 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, | |
| 38 | "Use colors in diagnostics", nullptr, nullptr) | |
| 39 | OPTION(prefix_1, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 40 | "Use colors in diagnostics", nullptr, nullptr) | |
| 41 | OPTION(prefix_1, "emit-relocs", emit_relocs, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 42 | "Generate relocations in output", nullptr, nullptr) | |
| 43 | 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, | |
| 45 | "Name of entry point symbol", "<entry>", nullptr) | |
| 46 | 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) | |
| 48 | OPTION(prefix_2, "e", alias_entry_e, JoinedOrSeparate, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 49 | OPTION(prefix_1, "global-base=", global_base, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 50 | "Where to start to place global data", nullptr, nullptr) | |
| 51 | OPTION(prefix_1, "help", help, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 52 | "Print option help", nullptr, nullptr) | |
| 53 | OPTION(prefix_1, "import-memory", import_memory, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 54 | "Import memory from the environment", nullptr, nullptr) | |
| 55 | OPTION(prefix_1, "initial-memory=", initial_memory, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 56 | "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) | |
| 58 | OPTION(prefix_2, "L", L, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | |
| 59 | "Add a directory to the library search path", "<dir>", nullptr) | |
| 60 | OPTION(prefix_2, "l", l, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | |
| 61 | "Root name of library to use", "<libName>", nullptr) | |
| 62 | OPTION(prefix_1, "max-memory=", max_memory, Joined, INVALID, INVALID, nullptr, 0, 0, | |
| 63 | "Maximum size of the linear memory", nullptr, nullptr) | |
| 64 | OPTION(prefix_1, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 65 | "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) | |
| 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, | |
| 70 | "Do not use colors in diagnostics", nullptr, nullptr) | |
| 71 | OPTION(prefix_1, "no-entry", no_entry, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 72 | "Do not output any entry point", nullptr, nullptr) | |
| 73 | OPTION(prefix_1, "no-threads", no_threads, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 74 | "Do not run the linker multi-threaded", nullptr, nullptr) | |
| 75 | OPTION(prefix_2, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | |
| 76 | "Path to file to write output", "<path>", nullptr) | |
| 77 | OPTION(prefix_1, "relocatable", relocatable, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 78 | "Create relocatable object file", nullptr, nullptr) | |
| 79 | OPTION(prefix_2, "r", alias_relocatable_r, Flag, INVALID, relocatable, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 80 | OPTION(prefix_1, "strip-all", strip_all, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 81 | "Strip all symbols", nullptr, nullptr) | |
| 82 | OPTION(prefix_1, "strip-debug", strip_debug, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 83 | "Strip debugging information", nullptr, nullptr) | |
| 84 | OPTION(prefix_1, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 85 | "Run the linker multi-threaded", nullptr, nullptr) | |
| 86 | OPTION(prefix_1, "undefined=", undefined_eq, Joined, INVALID, undefined, nullptr, 0, 0, | |
| 87 | "Force undefined symbol during linking", nullptr, nullptr) | |
| 88 | OPTION(prefix_1, "undefined", undefined, Separate, INVALID, INVALID, nullptr, 0, 0, | |
| 89 | "Force undefined symbol during linking", nullptr, nullptr) | |
| 90 | OPTION(prefix_2, "u", alias_undefined_u, JoinedOrSeparate, INVALID, undefined, nullptr, 0, 0, nullptr, nullptr, nullptr) | |
| 91 | OPTION(prefix_1, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 92 | "Verbose mode", nullptr, nullptr) | |
| 93 | OPTION(prefix_1, "version", version, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 94 | "Display the version number and exit", nullptr, nullptr) | |
| 95 | OPTION(prefix_2, "v", v, Flag, INVALID, INVALID, nullptr, 0, 0, | |
| 96 | "Display the version number", nullptr, nullptr) | |
| 97 | OPTION(prefix_2, "z", z, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | |
| 98 | "Linker option extensions", "<option>", nullptr) | |
| 99 | #endif // OPTION | |
| 100 | ||
| 101 | #ifdef OPTTABLE_ARG_INIT | |
| 102 | ////////// | |
| 103 | // Option Values | |
| 104 | ||
| 105 | ||
| 106 | #endif // OPTTABLE_ARG_INIT |
deps/lld/.arcconfig+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | 1 | { |
| 2 | "project_id" : "lld", | |
| 2 | "repository.callsign" : "LLD", | |
| 3 | 3 | "conduit_uri" : "https://reviews.llvm.org/" |
| 4 | 4 | } |
deps/lld/CMakeLists.txt+5-3| ... | ... | @@ -160,8 +160,8 @@ endif () |
| 160 | 160 | |
| 161 | 161 | # Configure the Version.inc file. |
| 162 | 162 | configure_file( |
| 163 | ${CMAKE_CURRENT_SOURCE_DIR}/include/lld/Config/Version.inc.in | |
| 164 | ${CMAKE_CURRENT_BINARY_DIR}/include/lld/Config/Version.inc) | |
| 163 | ${CMAKE_CURRENT_SOURCE_DIR}/include/lld/Common/Version.inc.in | |
| 164 | ${CMAKE_CURRENT_BINARY_DIR}/include/lld/Common/Version.inc) | |
| 165 | 165 | |
| 166 | 166 | |
| 167 | 167 | if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) |
| ... | ... | @@ -210,6 +210,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) |
| 210 | 210 | ) |
| 211 | 211 | endif() |
| 212 | 212 | |
| 213 | add_subdirectory(Common) | |
| 213 | 214 | add_subdirectory(lib) |
| 214 | 215 | add_subdirectory(tools/lld) |
| 215 | 216 | |
| ... | ... | @@ -221,4 +222,5 @@ endif() |
| 221 | 222 | add_subdirectory(docs) |
| 222 | 223 | add_subdirectory(COFF) |
| 223 | 224 | add_subdirectory(ELF) |
| 224 | ||
| 225 | add_subdirectory(MinGW) | |
| 226 | add_subdirectory(wasm) |
deps/lld/CODE_OWNERS.TXT+3| ... | ... | @@ -17,3 +17,6 @@ N: Lang Hames, Nick Kledzik |
| 17 | 17 | E: lhames@gmail.com, kledzik@apple.com |
| 18 | 18 | D: Mach-O backend |
| 19 | 19 | |
| 20 | N: Sam Clegg | |
| 21 | E: sbc@chromium.org | |
| 22 | D: WebAssembly backend (wasm/*) |
deps/lld/COFF/CMakeLists.txt+5-7| ... | ... | @@ -11,12 +11,12 @@ add_lld_library(lldCOFF |
| 11 | 11 | DLL.cpp |
| 12 | 12 | Driver.cpp |
| 13 | 13 | DriverUtils.cpp |
| 14 | Error.cpp | |
| 15 | 14 | ICF.cpp |
| 16 | 15 | InputFiles.cpp |
| 17 | 16 | LTO.cpp |
| 18 | 17 | MapFile.cpp |
| 19 | 18 | MarkLive.cpp |
| 19 | MinGW.cpp | |
| 20 | 20 | PDB.cpp |
| 21 | 21 | Strings.cpp |
| 22 | 22 | SymbolTable.cpp |
| ... | ... | @@ -26,22 +26,20 @@ add_lld_library(lldCOFF |
| 26 | 26 | LINK_COMPONENTS |
| 27 | 27 | ${LLVM_TARGETS_TO_BUILD} |
| 28 | 28 | BinaryFormat |
| 29 | BitReader | |
| 30 | 29 | Core |
| 31 | 30 | DebugInfoCodeView |
| 32 | 31 | DebugInfoMSF |
| 33 | 32 | DebugInfoPDB |
| 34 | LTO | |
| 35 | 33 | LibDriver |
| 36 | Object | |
| 34 | LTO | |
| 37 | 35 | MC |
| 38 | MCDisassembler | |
| 39 | Target | |
| 36 | Object | |
| 40 | 37 | Option |
| 41 | 38 | Support |
| 39 | WindowsManifest | |
| 42 | 40 | |
| 43 | 41 | LINK_LIBS |
| 44 | lldCore | |
| 42 | lldCommon | |
| 45 | 43 | ${LLVM_PTHREAD_LIB} |
| 46 | 44 | |
| 47 | 45 | DEPENDS |
deps/lld/COFF/Chunks.cpp+67-32| ... | ... | @@ -8,10 +8,10 @@ |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | 10 | #include "Chunks.h" |
| 11 | #include "Error.h" | |
| 12 | 11 | #include "InputFiles.h" |
| 13 | 12 | #include "Symbols.h" |
| 14 | 13 | #include "Writer.h" |
| 14 | #include "lld/Common/ErrorHandler.h" | |
| 15 | 15 | #include "llvm/ADT/Twine.h" |
| 16 | 16 | #include "llvm/BinaryFormat/COFF.h" |
| 17 | 17 | #include "llvm/Object/COFF.h" |
| ... | ... | @@ -29,17 +29,14 @@ using llvm::support::ulittle32_t; |
| 29 | 29 | namespace lld { |
| 30 | 30 | namespace coff { |
| 31 | 31 | |
| 32 | SectionChunk::SectionChunk(ObjectFile *F, const coff_section *H) | |
| 32 | SectionChunk::SectionChunk(ObjFile *F, const coff_section *H) | |
| 33 | 33 | : Chunk(SectionKind), Repl(this), Header(H), File(F), |
| 34 | 34 | Relocs(File->getCOFFObj()->getRelocations(Header)), |
| 35 | 35 | NumRelocs(std::distance(Relocs.begin(), Relocs.end())) { |
| 36 | 36 | // Initialize SectionName. |
| 37 | 37 | File->getCOFFObj()->getSectionName(Header, SectionName); |
| 38 | 38 | |
| 39 | Align = Header->getAlignment(); | |
| 40 | ||
| 41 | // Chunks may be discarded during comdat merging. | |
| 42 | Discarded = false; | |
| 39 | Alignment = Header->getAlignment(); | |
| 43 | 40 | |
| 44 | 41 | // If linker GC is disabled, every chunk starts out alive. If linker GC is |
| 45 | 42 | // enabled, treat non-comdat sections as roots. Generally optimized object |
| ... | ... | @@ -62,7 +59,10 @@ static void applySecRel(const SectionChunk *Sec, uint8_t *Off, |
| 62 | 59 | fatal("SECREL relocation cannot be applied to absolute symbols"); |
| 63 | 60 | } |
| 64 | 61 | uint64_t SecRel = S - OS->getRVA(); |
| 65 | assert(SecRel < INT32_MAX && "overflow in SECREL relocation"); | |
| 62 | if (SecRel > UINT32_MAX) { | |
| 63 | error("overflow in SECREL relocation in section: " + Sec->getSectionName()); | |
| 64 | return; | |
| 65 | } | |
| 66 | 66 | add32(Off, SecRel); |
| 67 | 67 | } |
| 68 | 68 | |
| ... | ... | @@ -119,7 +119,7 @@ static uint16_t readMOV(uint8_t *Off) { |
| 119 | 119 | return Imm; |
| 120 | 120 | } |
| 121 | 121 | |
| 122 | static void applyMOV32T(uint8_t *Off, uint32_t V) { | |
| 122 | void applyMOV32T(uint8_t *Off, uint32_t V) { | |
| 123 | 123 | uint16_t ImmW = readMOV(Off); // read MOVW operand |
| 124 | 124 | uint16_t ImmT = readMOV(Off + 4); // read MOVT operand |
| 125 | 125 | uint32_t Imm = ImmW | (ImmT << 16); |
| ... | ... | @@ -129,6 +129,8 @@ static void applyMOV32T(uint8_t *Off, uint32_t V) { |
| 129 | 129 | } |
| 130 | 130 | |
| 131 | 131 | static void applyBranch20T(uint8_t *Off, int32_t V) { |
| 132 | if (!isInt<21>(V)) | |
| 133 | fatal("relocation out of range"); | |
| 132 | 134 | uint32_t S = V < 0 ? 1 : 0; |
| 133 | 135 | uint32_t J1 = (V >> 19) & 1; |
| 134 | 136 | uint32_t J2 = (V >> 18) & 1; |
| ... | ... | @@ -136,7 +138,7 @@ static void applyBranch20T(uint8_t *Off, int32_t V) { |
| 136 | 138 | or16(Off + 2, (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff)); |
| 137 | 139 | } |
| 138 | 140 | |
| 139 | static void applyBranch24T(uint8_t *Off, int32_t V) { | |
| 141 | void applyBranch24T(uint8_t *Off, int32_t V) { | |
| 140 | 142 | if (!isInt<25>(V)) |
| 141 | 143 | fatal("relocation out of range"); |
| 142 | 144 | uint32_t S = V < 0 ? 1 : 0; |
| ... | ... | @@ -167,36 +169,61 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS, |
| 167 | 169 | } |
| 168 | 170 | } |
| 169 | 171 | |
| 170 | static void applyArm64Addr(uint8_t *Off, uint64_t Imm) { | |
| 172 | // Interpret the existing immediate value as a byte offset to the | |
| 173 | // target symbol, then update the instruction with the immediate as | |
| 174 | // the page offset from the current instruction to the target. | |
| 175 | static void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P) { | |
| 176 | uint32_t Orig = read32le(Off); | |
| 177 | uint64_t Imm = ((Orig >> 29) & 0x3) | ((Orig >> 3) & 0x1FFFFC); | |
| 178 | S += Imm; | |
| 179 | Imm = (S >> 12) - (P >> 12); | |
| 171 | 180 | uint32_t ImmLo = (Imm & 0x3) << 29; |
| 172 | 181 | uint32_t ImmHi = (Imm & 0x1FFFFC) << 3; |
| 173 | 182 | uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3); |
| 174 | write32le(Off, (read32le(Off) & ~Mask) | ImmLo | ImmHi); | |
| 183 | write32le(Off, (Orig & ~Mask) | ImmLo | ImmHi); | |
| 175 | 184 | } |
| 176 | 185 | |
| 177 | 186 | // Update the immediate field in a AARCH64 ldr, str, and add instruction. |
| 178 | static void applyArm64Imm(uint8_t *Off, uint64_t Imm) { | |
| 187 | // Optionally limit the range of the written immediate by one or more bits | |
| 188 | // (RangeLimit). | |
| 189 | static void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) { | |
| 179 | 190 | uint32_t Orig = read32le(Off); |
| 180 | 191 | Imm += (Orig >> 10) & 0xFFF; |
| 181 | 192 | Orig &= ~(0xFFF << 10); |
| 182 | write32le(Off, Orig | ((Imm & 0xFFF) << 10)); | |
| 193 | write32le(Off, Orig | ((Imm & (0xFFF >> RangeLimit)) << 10)); | |
| 183 | 194 | } |
| 184 | 195 | |
| 196 | // Add the 12 bit page offset to the existing immediate. | |
| 197 | // Ldr/str instructions store the opcode immediate scaled | |
| 198 | // by the load/store size (giving a larger range for larger | |
| 199 | // loads/stores). The immediate is always (both before and after | |
| 200 | // fixing up the relocation) stored scaled similarly. | |
| 201 | // Even if larger loads/stores have a larger range, limit the | |
| 202 | // effective offset to 12 bit, since it is intended to be a | |
| 203 | // page offset. | |
| 185 | 204 | static void applyArm64Ldr(uint8_t *Off, uint64_t Imm) { |
| 186 | int Size = read32le(Off) >> 30; | |
| 187 | Imm >>= Size; | |
| 188 | applyArm64Imm(Off, Imm); | |
| 205 | uint32_t Orig = read32le(Off); | |
| 206 | uint32_t Size = Orig >> 30; | |
| 207 | // 0x04000000 indicates SIMD/FP registers | |
| 208 | // 0x00800000 indicates 128 bit | |
| 209 | if ((Orig & 0x4800000) == 0x4800000) | |
| 210 | Size += 4; | |
| 211 | if ((Imm & ((1 << Size) - 1)) != 0) | |
| 212 | fatal("misaligned ldr/str offset"); | |
| 213 | applyArm64Imm(Off, Imm >> Size, Size); | |
| 189 | 214 | } |
| 190 | 215 | |
| 191 | 216 | void SectionChunk::applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, |
| 192 | 217 | uint64_t S, uint64_t P) const { |
| 193 | 218 | switch (Type) { |
| 194 | case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(Off, (S >> 12) - (P >> 12)); break; | |
| 195 | case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(Off, S & 0xfff); break; | |
| 219 | case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(Off, S, P); break; | |
| 220 | case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(Off, S & 0xfff, 0); break; | |
| 196 | 221 | case IMAGE_REL_ARM64_PAGEOFFSET_12L: applyArm64Ldr(Off, S & 0xfff); break; |
| 197 | 222 | case IMAGE_REL_ARM64_BRANCH26: or32(Off, ((S - P) & 0x0FFFFFFC) >> 2); break; |
| 198 | 223 | case IMAGE_REL_ARM64_ADDR32: add32(Off, S + Config->ImageBase); break; |
| 224 | case IMAGE_REL_ARM64_ADDR32NB: add32(Off, S); break; | |
| 199 | 225 | case IMAGE_REL_ARM64_ADDR64: add64(Off, S + Config->ImageBase); break; |
| 226 | case IMAGE_REL_ARM64_SECREL: applySecRel(this, Off, OS, S); break; | |
| 200 | 227 | default: |
| 201 | 228 | fatal("unsupported relocation type 0x" + Twine::utohexstr(Type)); |
| 202 | 229 | } |
| ... | ... | @@ -224,8 +251,19 @@ void SectionChunk::writeTo(uint8_t *Buf) const { |
| 224 | 251 | // Get the output section of the symbol for this relocation. The output |
| 225 | 252 | // section is needed to compute SECREL and SECTION relocations used in debug |
| 226 | 253 | // info. |
| 227 | SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex); | |
| 228 | Defined *Sym = cast<Defined>(Body); | |
| 254 | auto *Sym = | |
| 255 | dyn_cast_or_null<Defined>(File->getSymbol(Rel.SymbolTableIndex)); | |
| 256 | if (!Sym) { | |
| 257 | if (isCodeView() || isDWARF()) | |
| 258 | continue; | |
| 259 | // Symbols in early discarded sections are represented using null pointers, | |
| 260 | // so we need to retrieve the name from the object file. | |
| 261 | COFFSymbolRef Sym = | |
| 262 | check(File->getCOFFObj()->getSymbol(Rel.SymbolTableIndex)); | |
| 263 | StringRef Name; | |
| 264 | File->getCOFFObj()->getSymbolName(Sym, Name); | |
| 265 | fatal("relocation against symbol in discarded section: " + Name); | |
| 266 | } | |
| 229 | 267 | Chunk *C = Sym->getChunk(); |
| 230 | 268 | OutputSection *OS = C ? C->getOutputSection() : nullptr; |
| 231 | 269 | |
| ... | ... | @@ -301,8 +339,8 @@ void SectionChunk::getBaserels(std::vector<Baserel> *Res) { |
| 301 | 339 | uint8_t Ty = getBaserelType(Rel); |
| 302 | 340 | if (Ty == IMAGE_REL_BASED_ABSOLUTE) |
| 303 | 341 | continue; |
| 304 | SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex); | |
| 305 | if (isa<DefinedAbsolute>(Body)) | |
| 342 | Symbol *Target = File->getSymbol(Rel.SymbolTableIndex); | |
| 343 | if (!Target || isa<DefinedAbsolute>(Target)) | |
| 306 | 344 | continue; |
| 307 | 345 | Res->emplace_back(RVA + Rel.VirtualAddress, Ty); |
| 308 | 346 | } |
| ... | ... | @@ -323,12 +361,8 @@ bool SectionChunk::isCOMDAT() const { |
| 323 | 361 | void SectionChunk::printDiscardedMessage() const { |
| 324 | 362 | // Removed by dead-stripping. If it's removed by ICF, ICF already |
| 325 | 363 | // printed out the name, so don't repeat that here. |
| 326 | if (Sym && this == Repl) { | |
| 327 | if (Discarded) | |
| 328 | message("Discarded comdat symbol " + Sym->getName()); | |
| 329 | else if (!Live) | |
| 330 | message("Discarded " + Sym->getName()); | |
| 331 | } | |
| 364 | if (Sym && this == Repl) | |
| 365 | message("Discarded " + Sym->getName()); | |
| 332 | 366 | } |
| 333 | 367 | |
| 334 | 368 | StringRef SectionChunk::getDebugName() { |
| ... | ... | @@ -351,7 +385,7 @@ void SectionChunk::replace(SectionChunk *Other) { |
| 351 | 385 | CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) { |
| 352 | 386 | // Common symbols are aligned on natural boundaries up to 32 bytes. |
| 353 | 387 | // This is what MSVC link.exe does. |
| 354 | Align = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue())); | |
| 388 | Alignment = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue())); | |
| 355 | 389 | } |
| 356 | 390 | |
| 357 | 391 | uint32_t CommonChunk::getPermissions() const { |
| ... | ... | @@ -366,7 +400,7 @@ void StringChunk::writeTo(uint8_t *Buf) const { |
| 366 | 400 | ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(S) { |
| 367 | 401 | // Intel Optimization Manual says that all branch targets |
| 368 | 402 | // should be 16-byte aligned. MSVC linker does this too. |
| 369 | Align = 16; | |
| 403 | Alignment = 16; | |
| 370 | 404 | } |
| 371 | 405 | |
| 372 | 406 | void ImportThunkChunkX64::writeTo(uint8_t *Buf) const { |
| ... | ... | @@ -397,10 +431,9 @@ void ImportThunkChunkARM::writeTo(uint8_t *Buf) const { |
| 397 | 431 | } |
| 398 | 432 | |
| 399 | 433 | void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const { |
| 400 | int64_t PageOff = (ImpSymbol->getRVA() >> 12) - (RVA >> 12); | |
| 401 | 434 | int64_t Off = ImpSymbol->getRVA() & 0xfff; |
| 402 | 435 | memcpy(Buf + OutputSectionOff, ImportThunkARM64, sizeof(ImportThunkARM64)); |
| 403 | applyArm64Addr(Buf + OutputSectionOff, PageOff); | |
| 436 | applyArm64Addr(Buf + OutputSectionOff, ImpSymbol->getRVA(), RVA); | |
| 404 | 437 | applyArm64Ldr(Buf + OutputSectionOff + 4, Off); |
| 405 | 438 | } |
| 406 | 439 | |
| ... | ... | @@ -488,8 +521,10 @@ void BaserelChunk::writeTo(uint8_t *Buf) const { |
| 488 | 521 | uint8_t Baserel::getDefaultType() { |
| 489 | 522 | switch (Config->Machine) { |
| 490 | 523 | case AMD64: |
| 524 | case ARM64: | |
| 491 | 525 | return IMAGE_REL_BASED_DIR64; |
| 492 | 526 | case I386: |
| 527 | case ARMNT: | |
| 493 | 528 | return IMAGE_REL_BASED_HIGHLOW; |
| 494 | 529 | default: |
| 495 | 530 | llvm_unreachable("unknown machine type"); |
deps/lld/COFF/Chunks.h+28-38| ... | ... | @@ -12,7 +12,7 @@ |
| 12 | 12 | |
| 13 | 13 | #include "Config.h" |
| 14 | 14 | #include "InputFiles.h" |
| 15 | #include "lld/Core/LLVM.h" | |
| 15 | #include "lld/Common/LLVM.h" | |
| 16 | 16 | #include "llvm/ADT/ArrayRef.h" |
| 17 | 17 | #include "llvm/ADT/iterator.h" |
| 18 | 18 | #include "llvm/ADT/iterator_range.h" |
| ... | ... | @@ -33,9 +33,9 @@ class Baserel; |
| 33 | 33 | class Defined; |
| 34 | 34 | class DefinedImportData; |
| 35 | 35 | class DefinedRegular; |
| 36 | class ObjectFile; | |
| 36 | class ObjFile; | |
| 37 | 37 | class OutputSection; |
| 38 | class SymbolBody; | |
| 38 | class Symbol; | |
| 39 | 39 | |
| 40 | 40 | // Mask for section types (code, data, bss, disacardable, etc.) |
| 41 | 41 | // and permissions (writable, readable or executable). |
| ... | ... | @@ -62,7 +62,6 @@ public: |
| 62 | 62 | |
| 63 | 63 | // The writer sets and uses the addresses. |
| 64 | 64 | uint64_t getRVA() const { return RVA; } |
| 65 | uint32_t getAlign() const { return Align; } | |
| 66 | 65 | void setRVA(uint64_t V) { RVA = V; } |
| 67 | 66 | |
| 68 | 67 | // Returns true if this has non-zero data. BSS chunks return |
| ... | ... | @@ -82,7 +81,7 @@ public: |
| 82 | 81 | // An output section has pointers to chunks in the section, and each |
| 83 | 82 | // chunk has a back pointer to an output section. |
| 84 | 83 | void setOutputSection(OutputSection *O) { Out = O; } |
| 85 | OutputSection *getOutputSection() { return Out; } | |
| 84 | OutputSection *getOutputSection() const { return Out; } | |
| 86 | 85 | |
| 87 | 86 | // Windows-specific. |
| 88 | 87 | // Collect all locations that contain absolute addresses for base relocations. |
| ... | ... | @@ -92,23 +91,22 @@ public: |
| 92 | 91 | // bytes, so this is used only for logging or debugging. |
| 93 | 92 | virtual StringRef getDebugName() { return ""; } |
| 94 | 93 | |
| 94 | // The alignment of this chunk. The writer uses the value. | |
| 95 | uint32_t Alignment = 1; | |
| 96 | ||
| 95 | 97 | protected: |
| 96 | 98 | Chunk(Kind K = OtherKind) : ChunkKind(K) {} |
| 97 | 99 | const Kind ChunkKind; |
| 98 | 100 | |
| 99 | // The alignment of this chunk. The writer uses the value. | |
| 100 | uint32_t Align = 1; | |
| 101 | ||
| 102 | 101 | // The RVA of this chunk in the output. The writer sets a value. |
| 103 | 102 | uint64_t RVA = 0; |
| 104 | 103 | |
| 104 | // The output section for this chunk. | |
| 105 | OutputSection *Out = nullptr; | |
| 106 | ||
| 105 | 107 | public: |
| 106 | 108 | // The offset from beginning of the output section. The writer sets a value. |
| 107 | 109 | uint64_t OutputSectionOff = 0; |
| 108 | ||
| 109 | protected: | |
| 110 | // The output section for this chunk. | |
| 111 | OutputSection *Out = nullptr; | |
| 112 | 110 | }; |
| 113 | 111 | |
| 114 | 112 | // A chunk corresponding a section of an input file. |
| ... | ... | @@ -119,23 +117,21 @@ class SectionChunk final : public Chunk { |
| 119 | 117 | public: |
| 120 | 118 | class symbol_iterator : public llvm::iterator_adaptor_base< |
| 121 | 119 | symbol_iterator, const coff_relocation *, |
| 122 | std::random_access_iterator_tag, SymbolBody *> { | |
| 120 | std::random_access_iterator_tag, Symbol *> { | |
| 123 | 121 | friend SectionChunk; |
| 124 | 122 | |
| 125 | ObjectFile *File; | |
| 123 | ObjFile *File; | |
| 126 | 124 | |
| 127 | symbol_iterator(ObjectFile *File, const coff_relocation *I) | |
| 125 | symbol_iterator(ObjFile *File, const coff_relocation *I) | |
| 128 | 126 | : symbol_iterator::iterator_adaptor_base(I), File(File) {} |
| 129 | 127 | |
| 130 | 128 | public: |
| 131 | 129 | symbol_iterator() = default; |
| 132 | 130 | |
| 133 | SymbolBody *operator*() const { | |
| 134 | return File->getSymbolBody(I->SymbolTableIndex); | |
| 135 | } | |
| 131 | Symbol *operator*() const { return File->getSymbol(I->SymbolTableIndex); } | |
| 136 | 132 | }; |
| 137 | 133 | |
| 138 | SectionChunk(ObjectFile *File, const coff_section *Header); | |
| 134 | SectionChunk(ObjFile *File, const coff_section *Header); | |
| 139 | 135 | static bool classof(const Chunk *C) { return C->kind() == SectionKind; } |
| 140 | 136 | size_t getSize() const override { return Header->SizeOfRawData; } |
| 141 | 137 | ArrayRef<uint8_t> getContents() const; |
| ... | ... | @@ -163,10 +159,9 @@ public: |
| 163 | 159 | void addAssociative(SectionChunk *Child); |
| 164 | 160 | |
| 165 | 161 | StringRef getDebugName() override; |
| 166 | void setSymbol(DefinedRegular *S) { if (!Sym) Sym = S; } | |
| 167 | 162 | |
| 168 | // Returns true if the chunk was not dropped by GC or COMDAT deduplication. | |
| 169 | bool isLive() { return Live && !Discarded; } | |
| 163 | // Returns true if the chunk was not dropped by GC. | |
| 164 | bool isLive() { return Live; } | |
| 170 | 165 | |
| 171 | 166 | // Used by the garbage collector. |
| 172 | 167 | void markLive() { |
| ... | ... | @@ -175,21 +170,16 @@ public: |
| 175 | 170 | Live = true; |
| 176 | 171 | } |
| 177 | 172 | |
| 178 | // Returns true if this chunk was dropped by COMDAT deduplication. | |
| 179 | bool isDiscarded() const { return Discarded; } | |
| 180 | ||
| 181 | // Used by the SymbolTable when discarding unused comdat sections. This is | |
| 182 | // redundant when GC is enabled, as all comdat sections will start out dead. | |
| 183 | void markDiscarded() { Discarded = true; } | |
| 184 | ||
| 185 | 173 | // True if this is a codeview debug info chunk. These will not be laid out in |
| 186 | 174 | // the image. Instead they will end up in the PDB, if one is requested. |
| 187 | 175 | bool isCodeView() const { |
| 188 | 176 | return SectionName == ".debug" || SectionName.startswith(".debug$"); |
| 189 | 177 | } |
| 190 | 178 | |
| 191 | // True if this is a DWARF debug info chunk. | |
| 192 | bool isDWARF() const { return SectionName.startswith(".debug_"); } | |
| 179 | // True if this is a DWARF debug info or exception handling chunk. | |
| 180 | bool isDWARF() const { | |
| 181 | return SectionName.startswith(".debug_") || SectionName == ".eh_frame"; | |
| 182 | } | |
| 193 | 183 | |
| 194 | 184 | // Allow iteration over the bodies of this chunk's relocated symbols. |
| 195 | 185 | llvm::iterator_range<symbol_iterator> symbols() const { |
| ... | ... | @@ -213,7 +203,10 @@ public: |
| 213 | 203 | const coff_section *Header; |
| 214 | 204 | |
| 215 | 205 | // The file that this chunk was created from. |
| 216 | ObjectFile *File; | |
| 206 | ObjFile *File; | |
| 207 | ||
| 208 | // The COMDAT leader symbol if this is a COMDAT chunk. | |
| 209 | DefinedRegular *Sym = nullptr; | |
| 217 | 210 | |
| 218 | 211 | private: |
| 219 | 212 | StringRef SectionName; |
| ... | ... | @@ -221,18 +214,12 @@ private: |
| 221 | 214 | llvm::iterator_range<const coff_relocation *> Relocs; |
| 222 | 215 | size_t NumRelocs; |
| 223 | 216 | |
| 224 | // True if this chunk was discarded because it was a duplicate comdat section. | |
| 225 | bool Discarded; | |
| 226 | ||
| 227 | 217 | // Used by the garbage collector. |
| 228 | 218 | bool Live; |
| 229 | 219 | |
| 230 | 220 | // Used for ICF (Identical COMDAT Folding) |
| 231 | 221 | void replace(SectionChunk *Other); |
| 232 | 222 | uint32_t Class[2] = {0, 0}; |
| 233 | ||
| 234 | // Sym points to a section symbol if this is a COMDAT chunk. | |
| 235 | DefinedRegular *Sym = nullptr; | |
| 236 | 223 | }; |
| 237 | 224 | |
| 238 | 225 | // A chunk for common symbols. Common chunks don't have actual data. |
| ... | ... | @@ -369,6 +356,9 @@ public: |
| 369 | 356 | uint8_t Type; |
| 370 | 357 | }; |
| 371 | 358 | |
| 359 | void applyMOV32T(uint8_t *Off, uint32_t V); | |
| 360 | void applyBranch24T(uint8_t *Off, int32_t V); | |
| 361 | ||
| 372 | 362 | } // namespace coff |
| 373 | 363 | } // namespace lld |
| 374 | 364 |
deps/lld/COFF/Config.h+19-9| ... | ... | @@ -12,6 +12,7 @@ |
| 12 | 12 | |
| 13 | 13 | #include "llvm/ADT/StringRef.h" |
| 14 | 14 | #include "llvm/Object/COFF.h" |
| 15 | #include "llvm/Support/CachePruning.h" | |
| 15 | 16 | #include <cstdint> |
| 16 | 17 | #include <map> |
| 17 | 18 | #include <set> |
| ... | ... | @@ -26,8 +27,7 @@ using llvm::StringRef; |
| 26 | 27 | class DefinedAbsolute; |
| 27 | 28 | class DefinedRelative; |
| 28 | 29 | class StringChunk; |
| 29 | struct Symbol; | |
| 30 | class SymbolBody; | |
| 30 | class Symbol; | |
| 31 | 31 | |
| 32 | 32 | // Short aliases. |
| 33 | 33 | static const auto AMD64 = llvm::COFF::IMAGE_FILE_MACHINE_AMD64; |
| ... | ... | @@ -39,7 +39,7 @@ static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386; |
| 39 | 39 | struct Export { |
| 40 | 40 | StringRef Name; // N in /export:N or /export:E=N |
| 41 | 41 | StringRef ExtName; // E in /export:E=N |
| 42 | SymbolBody *Sym = nullptr; | |
| 42 | Symbol *Sym = nullptr; | |
| 43 | 43 | uint16_t Ordinal = 0; |
| 44 | 44 | bool Noname = false; |
| 45 | 45 | bool Data = false; |
| ... | ... | @@ -79,24 +79,23 @@ struct Configuration { |
| 79 | 79 | llvm::COFF::MachineTypes Machine = IMAGE_FILE_MACHINE_UNKNOWN; |
| 80 | 80 | bool Verbose = false; |
| 81 | 81 | WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN; |
| 82 | SymbolBody *Entry = nullptr; | |
| 82 | Symbol *Entry = nullptr; | |
| 83 | 83 | bool NoEntry = false; |
| 84 | 84 | std::string OutputFile; |
| 85 | 85 | std::string ImportName; |
| 86 | bool ColorDiagnostics; | |
| 87 | 86 | bool DoGC = true; |
| 88 | 87 | bool DoICF = true; |
| 89 | uint64_t ErrorLimit = 20; | |
| 90 | 88 | bool Relocatable = true; |
| 91 | 89 | bool Force = false; |
| 92 | 90 | bool Debug = false; |
| 93 | bool WriteSymtab = true; | |
| 91 | bool DebugDwarf = false; | |
| 92 | bool DebugGHashes = false; | |
| 94 | 93 | unsigned DebugTypes = static_cast<unsigned>(DebugType::None); |
| 95 | 94 | llvm::SmallString<128> PDBPath; |
| 96 | 95 | std::vector<llvm::StringRef> Argv; |
| 97 | 96 | |
| 98 | 97 | // Symbols in this set are considered as live by the garbage collector. |
| 99 | std::set<SymbolBody *> GCRoot; | |
| 98 | std::vector<Symbol *> GCRoot; | |
| 100 | 99 | |
| 101 | 100 | std::set<StringRef> NoDefaultLibs; |
| 102 | 101 | bool NoDefaultLibAll = false; |
| ... | ... | @@ -107,7 +106,7 @@ struct Configuration { |
| 107 | 106 | std::vector<Export> Exports; |
| 108 | 107 | std::set<std::string> DelayLoads; |
| 109 | 108 | std::map<std::string, int> DLLOrder; |
| 110 | SymbolBody *DelayLoadHelper = nullptr; | |
| 109 | Symbol *DelayLoadHelper = nullptr; | |
| 111 | 110 | |
| 112 | 111 | bool SaveTemps = false; |
| 113 | 112 | |
| ... | ... | @@ -123,6 +122,11 @@ struct Configuration { |
| 123 | 122 | // Used for /opt:lldltopartitions=N |
| 124 | 123 | unsigned LTOPartitions = 1; |
| 125 | 124 | |
| 125 | // Used for /opt:lldltocache=path | |
| 126 | StringRef LTOCache; | |
| 127 | // Used for /opt:lldltocachepolicy=policy | |
| 128 | llvm::CachePruningPolicy LTOCachePolicy; | |
| 129 | ||
| 126 | 130 | // Used for /merge:from=to (e.g. /merge:.rdata=.text) |
| 127 | 131 | std::map<StringRef, StringRef> Merge; |
| 128 | 132 | |
| ... | ... | @@ -139,6 +143,9 @@ struct Configuration { |
| 139 | 143 | StringRef ManifestUIAccess = "'false'"; |
| 140 | 144 | StringRef ManifestFile; |
| 141 | 145 | |
| 146 | // Used for /aligncomm. | |
| 147 | std::map<std::string, int> AlignComm; | |
| 148 | ||
| 142 | 149 | // Used for /failifmismatch. |
| 143 | 150 | std::map<StringRef, StringRef> MustMatch; |
| 144 | 151 | |
| ... | ... | @@ -159,12 +166,15 @@ struct Configuration { |
| 159 | 166 | uint32_t MinorOSVersion = 0; |
| 160 | 167 | bool CanExitEarly = false; |
| 161 | 168 | bool DynamicBase = true; |
| 169 | bool AllowBind = true; | |
| 162 | 170 | bool NxCompat = true; |
| 163 | 171 | bool AllowIsolation = true; |
| 164 | 172 | bool TerminalServerAware = true; |
| 165 | 173 | bool LargeAddressAware = false; |
| 166 | 174 | bool HighEntropyVA = false; |
| 167 | 175 | bool AppContainer = false; |
| 176 | bool MinGW = false; | |
| 177 | bool WarnLocallyDefinedImported = true; | |
| 168 | 178 | }; |
| 169 | 179 | |
| 170 | 180 | extern Configuration *Config; |
deps/lld/COFF/DLL.cpp+58-9| ... | ... | @@ -61,7 +61,7 @@ private: |
| 61 | 61 | // A chunk for the import descriptor table. |
| 62 | 62 | class LookupChunk : public Chunk { |
| 63 | 63 | public: |
| 64 | explicit LookupChunk(Chunk *C) : HintName(C) {} | |
| 64 | explicit LookupChunk(Chunk *C) : HintName(C) { Alignment = ptrSize(); } | |
| 65 | 65 | size_t getSize() const override { return ptrSize(); } |
| 66 | 66 | |
| 67 | 67 | void writeTo(uint8_t *Buf) const override { |
| ... | ... | @@ -76,7 +76,7 @@ public: |
| 76 | 76 | // See Microsoft PE/COFF spec 7.1. Import Header for details. |
| 77 | 77 | class OrdinalOnlyChunk : public Chunk { |
| 78 | 78 | public: |
| 79 | explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) {} | |
| 79 | explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) { Alignment = ptrSize(); } | |
| 80 | 80 | size_t getSize() const override { return ptrSize(); } |
| 81 | 81 | |
| 82 | 82 | void writeTo(uint8_t *Buf) const override { |
| ... | ... | @@ -117,7 +117,6 @@ public: |
| 117 | 117 | explicit NullChunk(size_t N) : Size(N) {} |
| 118 | 118 | bool hasData() const override { return false; } |
| 119 | 119 | size_t getSize() const override { return Size; } |
| 120 | void setAlign(size_t N) { Align = N; } | |
| 121 | 120 | |
| 122 | 121 | private: |
| 123 | 122 | size_t Size; |
| ... | ... | @@ -215,6 +214,22 @@ static const uint8_t ThunkX86[] = { |
| 215 | 214 | 0xFF, 0xE0, // jmp eax |
| 216 | 215 | }; |
| 217 | 216 | |
| 217 | static const uint8_t ThunkARM[] = { | |
| 218 | 0x40, 0xf2, 0x00, 0x0c, // mov.w ip, #0 __imp_<FUNCNAME> | |
| 219 | 0xc0, 0xf2, 0x00, 0x0c, // mov.t ip, #0 __imp_<FUNCNAME> | |
| 220 | 0x2d, 0xe9, 0x0f, 0x48, // push.w {r0, r1, r2, r3, r11, lr} | |
| 221 | 0x0d, 0xf2, 0x10, 0x0b, // addw r11, sp, #16 | |
| 222 | 0x2d, 0xed, 0x10, 0x0b, // vpush {d0, d1, d2, d3, d4, d5, d6, d7} | |
| 223 | 0x61, 0x46, // mov r1, ip | |
| 224 | 0x40, 0xf2, 0x00, 0x00, // mov.w r0, #0 DELAY_IMPORT_DESCRIPTOR | |
| 225 | 0xc0, 0xf2, 0x00, 0x00, // mov.t r0, #0 DELAY_IMPORT_DESCRIPTOR | |
| 226 | 0x00, 0xf0, 0x00, 0xd0, // bl #0 __delayLoadHelper2 | |
| 227 | 0x84, 0x46, // mov ip, r0 | |
| 228 | 0xbd, 0xec, 0x10, 0x0b, // vpop {d0, d1, d2, d3, d4, d5, d6, d7} | |
| 229 | 0xbd, 0xe8, 0x0f, 0x48, // pop.w {r0, r1, r2, r3, r11, lr} | |
| 230 | 0x60, 0x47, // bx ip | |
| 231 | }; | |
| 232 | ||
| 218 | 233 | // A chunk for the delay import thunk. |
| 219 | 234 | class ThunkChunkX64 : public Chunk { |
| 220 | 235 | public: |
| ... | ... | @@ -259,17 +274,45 @@ public: |
| 259 | 274 | Defined *Helper = nullptr; |
| 260 | 275 | }; |
| 261 | 276 | |
| 277 | class ThunkChunkARM : public Chunk { | |
| 278 | public: | |
| 279 | ThunkChunkARM(Defined *I, Chunk *D, Defined *H) | |
| 280 | : Imp(I), Desc(D), Helper(H) {} | |
| 281 | ||
| 282 | size_t getSize() const override { return sizeof(ThunkARM); } | |
| 283 | ||
| 284 | void writeTo(uint8_t *Buf) const override { | |
| 285 | memcpy(Buf + OutputSectionOff, ThunkARM, sizeof(ThunkARM)); | |
| 286 | applyMOV32T(Buf + OutputSectionOff + 0, Imp->getRVA() + Config->ImageBase); | |
| 287 | applyMOV32T(Buf + OutputSectionOff + 22, Desc->getRVA() + Config->ImageBase); | |
| 288 | applyBranch24T(Buf + OutputSectionOff + 30, Helper->getRVA() - RVA - 34); | |
| 289 | } | |
| 290 | ||
| 291 | void getBaserels(std::vector<Baserel> *Res) override { | |
| 292 | Res->emplace_back(RVA + 0, IMAGE_REL_BASED_ARM_MOV32T); | |
| 293 | Res->emplace_back(RVA + 22, IMAGE_REL_BASED_ARM_MOV32T); | |
| 294 | } | |
| 295 | ||
| 296 | Defined *Imp = nullptr; | |
| 297 | Chunk *Desc = nullptr; | |
| 298 | Defined *Helper = nullptr; | |
| 299 | }; | |
| 300 | ||
| 262 | 301 | // A chunk for the import descriptor table. |
| 263 | 302 | class DelayAddressChunk : public Chunk { |
| 264 | 303 | public: |
| 265 | explicit DelayAddressChunk(Chunk *C) : Thunk(C) {} | |
| 304 | explicit DelayAddressChunk(Chunk *C) : Thunk(C) { Alignment = ptrSize(); } | |
| 266 | 305 | size_t getSize() const override { return ptrSize(); } |
| 267 | 306 | |
| 268 | 307 | void writeTo(uint8_t *Buf) const override { |
| 269 | 308 | if (Config->is64()) { |
| 270 | 309 | write64le(Buf + OutputSectionOff, Thunk->getRVA() + Config->ImageBase); |
| 271 | 310 | } else { |
| 272 | write32le(Buf + OutputSectionOff, Thunk->getRVA() + Config->ImageBase); | |
| 311 | uint32_t Bit = 0; | |
| 312 | // Pointer to thumb code must have the LSB set, so adjust it. | |
| 313 | if (Config->Machine == ARMNT) | |
| 314 | Bit = 1; | |
| 315 | write32le(Buf + OutputSectionOff, (Thunk->getRVA() + Config->ImageBase) | Bit); | |
| 273 | 316 | } |
| 274 | 317 | } |
| 275 | 318 | |
| ... | ... | @@ -319,12 +362,16 @@ public: |
| 319 | 362 | size_t getSize() const override { return Size * 4; } |
| 320 | 363 | |
| 321 | 364 | void writeTo(uint8_t *Buf) const override { |
| 322 | for (Export &E : Config->Exports) { | |
| 365 | for (const Export &E : Config->Exports) { | |
| 323 | 366 | uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4; |
| 367 | uint32_t Bit = 0; | |
| 368 | // Pointer to thumb code must have the LSB set, so adjust it. | |
| 369 | if (Config->Machine == ARMNT && !E.Data) | |
| 370 | Bit = 1; | |
| 324 | 371 | if (E.ForwardChunk) { |
| 325 | write32le(P, E.ForwardChunk->getRVA()); | |
| 372 | write32le(P, E.ForwardChunk->getRVA() | Bit); | |
| 326 | 373 | } else { |
| 327 | write32le(P, cast<Defined>(E.Sym)->getRVA()); | |
| 374 | write32le(P, cast<Defined>(E.Sym)->getRVA() | Bit); | |
| 328 | 375 | } |
| 329 | 376 | } |
| 330 | 377 | } |
| ... | ... | @@ -487,7 +534,7 @@ void DelayLoadContents::create(Defined *H) { |
| 487 | 534 | for (int I = 0, E = Syms.size(); I < E; ++I) |
| 488 | 535 | Syms[I]->setLocation(Addresses[Base + I]); |
| 489 | 536 | auto *MH = make<NullChunk>(8); |
| 490 | MH->setAlign(8); | |
| 537 | MH->Alignment = 8; | |
| 491 | 538 | ModuleHandles.push_back(MH); |
| 492 | 539 | |
| 493 | 540 | // Fill the delay import table header fields. |
| ... | ... | @@ -506,6 +553,8 @@ Chunk *DelayLoadContents::newThunkChunk(DefinedImportData *S, Chunk *Dir) { |
| 506 | 553 | return make<ThunkChunkX64>(S, Dir, Helper); |
| 507 | 554 | case I386: |
| 508 | 555 | return make<ThunkChunkX86>(S, Dir, Helper); |
| 556 | case ARMNT: | |
| 557 | return make<ThunkChunkARM>(S, Dir, Helper); | |
| 509 | 558 | default: |
| 510 | 559 | llvm_unreachable("unsupported machine type"); |
| 511 | 560 | } |
deps/lld/COFF/Driver.cpp+348-198| ... | ... | @@ -9,13 +9,15 @@ |
| 9 | 9 | |
| 10 | 10 | #include "Driver.h" |
| 11 | 11 | #include "Config.h" |
| 12 | #include "Error.h" | |
| 13 | 12 | #include "InputFiles.h" |
| 14 | #include "Memory.h" | |
| 13 | #include "MinGW.h" | |
| 15 | 14 | #include "SymbolTable.h" |
| 16 | 15 | #include "Symbols.h" |
| 17 | 16 | #include "Writer.h" |
| 18 | #include "lld/Driver/Driver.h" | |
| 17 | #include "lld/Common/Driver.h" | |
| 18 | #include "lld/Common/ErrorHandler.h" | |
| 19 | #include "lld/Common/Memory.h" | |
| 20 | #include "lld/Common/Version.h" | |
| 19 | 21 | #include "llvm/ADT/Optional.h" |
| 20 | 22 | #include "llvm/ADT/StringSwitch.h" |
| 21 | 23 | #include "llvm/BinaryFormat/Magic.h" |
| ... | ... | @@ -48,27 +50,29 @@ namespace coff { |
| 48 | 50 | Configuration *Config; |
| 49 | 51 | LinkerDriver *Driver; |
| 50 | 52 | |
| 51 | BumpPtrAllocator BAlloc; | |
| 52 | StringSaver Saver{BAlloc}; | |
| 53 | std::vector<SpecificAllocBase *> SpecificAllocBase::Instances; | |
| 54 | ||
| 55 | 53 | bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) { |
| 56 | ErrorCount = 0; | |
| 57 | ErrorOS = &Diag; | |
| 54 | errorHandler().LogName = Args[0]; | |
| 55 | errorHandler().ErrorOS = &Diag; | |
| 56 | errorHandler().ColorDiagnostics = Diag.has_colors(); | |
| 57 | errorHandler().ErrorLimitExceededMsg = | |
| 58 | "too many errors emitted, stopping now" | |
| 59 | " (use /ERRORLIMIT:0 to see all errors)"; | |
| 60 | errorHandler().ExitEarly = CanExitEarly; | |
| 58 | 61 | Config = make<Configuration>(); |
| 59 | 62 | Config->Argv = {Args.begin(), Args.end()}; |
| 60 | Config->ColorDiagnostics = | |
| 61 | (ErrorOS == &llvm::errs() && Process::StandardErrHasColors()); | |
| 62 | 63 | Config->CanExitEarly = CanExitEarly; |
| 64 | ||
| 65 | Symtab = make<SymbolTable>(); | |
| 66 | ||
| 63 | 67 | Driver = make<LinkerDriver>(); |
| 64 | 68 | Driver->link(Args); |
| 65 | 69 | |
| 66 | 70 | // Call exit() if we can to avoid calling destructors. |
| 67 | 71 | if (CanExitEarly) |
| 68 | exitLld(ErrorCount ? 1 : 0); | |
| 72 | exitLld(errorCount() ? 1 : 0); | |
| 69 | 73 | |
| 70 | 74 | freeArena(); |
| 71 | return !ErrorCount; | |
| 75 | return !errorCount(); | |
| 72 | 76 | } |
| 73 | 77 | |
| 74 | 78 | // Drop directory components and replace extension with ".exe" or ".dll". |
| ... | ... | @@ -114,30 +118,46 @@ MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> MB) { |
| 114 | 118 | return MBRef; |
| 115 | 119 | } |
| 116 | 120 | |
| 117 | void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB) { | |
| 121 | void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB, | |
| 122 | bool WholeArchive) { | |
| 118 | 123 | MemoryBufferRef MBRef = takeBuffer(std::move(MB)); |
| 124 | FilePaths.push_back(MBRef.getBufferIdentifier()); | |
| 119 | 125 | |
| 120 | 126 | // File type is detected by contents, not by file extension. |
| 121 | file_magic Magic = identify_magic(MBRef.getBuffer()); | |
| 122 | if (Magic == file_magic::windows_resource) { | |
| 127 | switch (identify_magic(MBRef.getBuffer())) { | |
| 128 | case file_magic::windows_resource: | |
| 123 | 129 | Resources.push_back(MBRef); |
| 124 | return; | |
| 125 | } | |
| 130 | break; | |
| 126 | 131 | |
| 127 | FilePaths.push_back(MBRef.getBufferIdentifier()); | |
| 128 | if (Magic == file_magic::archive) | |
| 129 | return Symtab.addFile(make<ArchiveFile>(MBRef)); | |
| 130 | if (Magic == file_magic::bitcode) | |
| 131 | return Symtab.addFile(make<BitcodeFile>(MBRef)); | |
| 132 | case file_magic::archive: | |
| 133 | if (WholeArchive) { | |
| 134 | std::unique_ptr<Archive> File = | |
| 135 | CHECK(Archive::create(MBRef), | |
| 136 | MBRef.getBufferIdentifier() + ": failed to parse archive"); | |
| 137 | ||
| 138 | for (MemoryBufferRef M : getArchiveMembers(File.get())) | |
| 139 | addArchiveBuffer(M, "<whole-archive>", MBRef.getBufferIdentifier()); | |
| 140 | return; | |
| 141 | } | |
| 142 | Symtab->addFile(make<ArchiveFile>(MBRef)); | |
| 143 | break; | |
| 144 | ||
| 145 | case file_magic::bitcode: | |
| 146 | Symtab->addFile(make<BitcodeFile>(MBRef)); | |
| 147 | break; | |
| 132 | 148 | |
| 133 | if (Magic == file_magic::coff_cl_gl_object) | |
| 149 | case file_magic::coff_cl_gl_object: | |
| 134 | 150 | error(MBRef.getBufferIdentifier() + ": is not a native COFF file. " |
| 135 | 151 | "Recompile without /GL"); |
| 136 | else | |
| 137 | Symtab.addFile(make<ObjectFile>(MBRef)); | |
| 152 | break; | |
| 153 | ||
| 154 | default: | |
| 155 | Symtab->addFile(make<ObjFile>(MBRef)); | |
| 156 | break; | |
| 157 | } | |
| 138 | 158 | } |
| 139 | 159 | |
| 140 | void LinkerDriver::enqueuePath(StringRef Path) { | |
| 160 | void LinkerDriver::enqueuePath(StringRef Path, bool WholeArchive) { | |
| 141 | 161 | auto Future = |
| 142 | 162 | std::make_shared<std::future<MBErrPair>>(createFutureForFile(Path)); |
| 143 | 163 | std::string PathStr = Path; |
| ... | ... | @@ -146,7 +166,7 @@ void LinkerDriver::enqueuePath(StringRef Path) { |
| 146 | 166 | if (MBOrErr.second) |
| 147 | 167 | error("could not open " + PathStr + ": " + MBOrErr.second.message()); |
| 148 | 168 | else |
| 149 | Driver->addBuffer(std::move(MBOrErr.first)); | |
| 169 | Driver->addBuffer(std::move(MBOrErr.first), WholeArchive); | |
| 150 | 170 | }); |
| 151 | 171 | } |
| 152 | 172 | |
| ... | ... | @@ -154,13 +174,13 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef MB, StringRef SymName, |
| 154 | 174 | StringRef ParentName) { |
| 155 | 175 | file_magic Magic = identify_magic(MB.getBuffer()); |
| 156 | 176 | if (Magic == file_magic::coff_import_library) { |
| 157 | Symtab.addFile(make<ImportFile>(MB)); | |
| 177 | Symtab->addFile(make<ImportFile>(MB)); | |
| 158 | 178 | return; |
| 159 | 179 | } |
| 160 | 180 | |
| 161 | 181 | InputFile *Obj; |
| 162 | 182 | if (Magic == file_magic::coff_object) { |
| 163 | Obj = make<ObjectFile>(MB); | |
| 183 | Obj = make<ObjFile>(MB); | |
| 164 | 184 | } else if (Magic == file_magic::bitcode) { |
| 165 | 185 | Obj = make<BitcodeFile>(MB); |
| 166 | 186 | } else { |
| ... | ... | @@ -169,7 +189,7 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef MB, StringRef SymName, |
| 169 | 189 | } |
| 170 | 190 | |
| 171 | 191 | Obj->ParentName = ParentName; |
| 172 | Symtab.addFile(Obj); | |
| 192 | Symtab->addFile(Obj); | |
| 173 | 193 | log("Loaded " + toString(Obj) + " for " + SymName); |
| 174 | 194 | } |
| 175 | 195 | |
| ... | ... | @@ -177,7 +197,7 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &C, |
| 177 | 197 | StringRef SymName, |
| 178 | 198 | StringRef ParentName) { |
| 179 | 199 | if (!C.getParent()->isThin()) { |
| 180 | MemoryBufferRef MB = check( | |
| 200 | MemoryBufferRef MB = CHECK( | |
| 181 | 201 | C.getMemoryBufferRef(), |
| 182 | 202 | "could not get the buffer for the member defining symbol " + SymName); |
| 183 | 203 | enqueueTask([=]() { Driver->addArchiveBuffer(MB, SymName, ParentName); }); |
| ... | ... | @@ -185,39 +205,61 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &C, |
| 185 | 205 | } |
| 186 | 206 | |
| 187 | 207 | auto Future = std::make_shared<std::future<MBErrPair>>(createFutureForFile( |
| 188 | check(C.getFullName(), | |
| 208 | CHECK(C.getFullName(), | |
| 189 | 209 | "could not get the filename for the member defining symbol " + |
| 190 | 210 | SymName))); |
| 191 | 211 | enqueueTask([=]() { |
| 192 | 212 | auto MBOrErr = Future->get(); |
| 193 | 213 | if (MBOrErr.second) |
| 194 | fatal(MBOrErr.second, | |
| 195 | "could not get the buffer for the member defining " + SymName); | |
| 214 | fatal("could not get the buffer for the member defining " + SymName + | |
| 215 | ": " + MBOrErr.second.message()); | |
| 196 | 216 | Driver->addArchiveBuffer(takeBuffer(std::move(MBOrErr.first)), SymName, |
| 197 | 217 | ParentName); |
| 198 | 218 | }); |
| 199 | 219 | } |
| 200 | 220 | |
| 201 | 221 | static bool isDecorated(StringRef Sym) { |
| 202 | return Sym.startswith("_") || Sym.startswith("@") || Sym.startswith("?"); | |
| 222 | return Sym.startswith("@") || Sym.contains("@@") || Sym.startswith("?") || | |
| 223 | (!Config->MinGW && Sym.contains('@')); | |
| 203 | 224 | } |
| 204 | 225 | |
| 205 | 226 | // Parses .drectve section contents and returns a list of files |
| 206 | 227 | // specified by /defaultlib. |
| 207 | 228 | void LinkerDriver::parseDirectives(StringRef S) { |
| 208 | opt::InputArgList Args = Parser.parse(S); | |
| 229 | ArgParser Parser; | |
| 230 | // .drectve is always tokenized using Windows shell rules. | |
| 231 | opt::InputArgList Args = Parser.parseDirectives(S); | |
| 209 | 232 | |
| 210 | 233 | for (auto *Arg : Args) { |
| 211 | switch (Arg->getOption().getID()) { | |
| 234 | switch (Arg->getOption().getUnaliasedOption().getID()) { | |
| 235 | case OPT_aligncomm: | |
| 236 | parseAligncomm(Arg->getValue()); | |
| 237 | break; | |
| 212 | 238 | case OPT_alternatename: |
| 213 | 239 | parseAlternateName(Arg->getValue()); |
| 214 | 240 | break; |
| 215 | 241 | case OPT_defaultlib: |
| 216 | 242 | if (Optional<StringRef> Path = findLib(Arg->getValue())) |
| 217 | enqueuePath(*Path); | |
| 243 | enqueuePath(*Path, false); | |
| 244 | break; | |
| 245 | case OPT_entry: | |
| 246 | Config->Entry = addUndefined(mangle(Arg->getValue())); | |
| 218 | 247 | break; |
| 219 | 248 | case OPT_export: { |
| 249 | // If a common header file contains dllexported function | |
| 250 | // declarations, many object files may end up with having the | |
| 251 | // same /EXPORT options. In order to save cost of parsing them, | |
| 252 | // we dedup them first. | |
| 253 | if (!DirectivesExports.insert(Arg->getValue()).second) | |
| 254 | break; | |
| 255 | ||
| 220 | 256 | Export E = parseExport(Arg->getValue()); |
| 257 | if (Config->Machine == I386 && Config->MinGW) { | |
| 258 | if (!isDecorated(E.Name)) | |
| 259 | E.Name = Saver.save("_" + E.Name); | |
| 260 | if (!E.ExtName.empty() && !isDecorated(E.ExtName)) | |
| 261 | E.ExtName = Saver.save("_" + E.ExtName); | |
| 262 | } | |
| 221 | 263 | E.Directives = true; |
| 222 | 264 | Config->Exports.push_back(E); |
| 223 | 265 | break; |
| ... | ... | @@ -237,9 +279,14 @@ void LinkerDriver::parseDirectives(StringRef S) { |
| 237 | 279 | case OPT_section: |
| 238 | 280 | parseSection(Arg->getValue()); |
| 239 | 281 | break; |
| 282 | case OPT_subsystem: | |
| 283 | parseSubsystem(Arg->getValue(), &Config->Subsystem, | |
| 284 | &Config->MajorOSVersion, &Config->MinorOSVersion); | |
| 285 | break; | |
| 240 | 286 | case OPT_editandcontinue: |
| 241 | 287 | case OPT_fastfail: |
| 242 | 288 | case OPT_guardsym: |
| 289 | case OPT_natvis: | |
| 243 | 290 | case OPT_throwingnew: |
| 244 | 291 | break; |
| 245 | 292 | default: |
| ... | ... | @@ -254,7 +301,7 @@ StringRef LinkerDriver::doFindFile(StringRef Filename) { |
| 254 | 301 | bool HasPathSep = (Filename.find_first_of("/\\") != StringRef::npos); |
| 255 | 302 | if (HasPathSep) |
| 256 | 303 | return Filename; |
| 257 | bool HasExt = (Filename.find('.') != StringRef::npos); | |
| 304 | bool HasExt = Filename.contains('.'); | |
| 258 | 305 | for (StringRef Dir : SearchPaths) { |
| 259 | 306 | SmallString<128> Path = Dir; |
| 260 | 307 | sys::path::append(Path, Filename); |
| ... | ... | @@ -276,13 +323,15 @@ Optional<StringRef> LinkerDriver::findFile(StringRef Filename) { |
| 276 | 323 | bool Seen = !VisitedFiles.insert(Path.lower()).second; |
| 277 | 324 | if (Seen) |
| 278 | 325 | return None; |
| 326 | if (Path.endswith_lower(".lib")) | |
| 327 | VisitedLibs.insert(sys::path::filename(Path)); | |
| 279 | 328 | return Path; |
| 280 | 329 | } |
| 281 | 330 | |
| 282 | 331 | // Find library file from search path. |
| 283 | 332 | StringRef LinkerDriver::doFindLib(StringRef Filename) { |
| 284 | 333 | // Add ".lib" to Filename if that has no file extension. |
| 285 | bool HasExt = (Filename.find('.') != StringRef::npos); | |
| 334 | bool HasExt = Filename.contains('.'); | |
| 286 | 335 | if (!HasExt) |
| 287 | 336 | Filename = Saver.save(Filename + ".lib"); |
| 288 | 337 | return doFindFile(Filename); |
| ... | ... | @@ -317,9 +366,12 @@ void LinkerDriver::addLibSearchPaths() { |
| 317 | 366 | } |
| 318 | 367 | } |
| 319 | 368 | |
| 320 | SymbolBody *LinkerDriver::addUndefined(StringRef Name) { | |
| 321 | SymbolBody *B = Symtab.addUndefined(Name); | |
| 322 | Config->GCRoot.insert(B); | |
| 369 | Symbol *LinkerDriver::addUndefined(StringRef Name) { | |
| 370 | Symbol *B = Symtab->addUndefined(Name); | |
| 371 | if (!B->IsGCRoot) { | |
| 372 | B->IsGCRoot = true; | |
| 373 | Config->GCRoot.push_back(B); | |
| 374 | } | |
| 323 | 375 | return B; |
| 324 | 376 | } |
| 325 | 377 | |
| ... | ... | @@ -341,8 +393,8 @@ StringRef LinkerDriver::findDefaultEntry() { |
| 341 | 393 | {"wWinMain", "wWinMainCRTStartup"}, |
| 342 | 394 | }; |
| 343 | 395 | for (auto E : Entries) { |
| 344 | StringRef Entry = Symtab.findMangle(mangle(E[0])); | |
| 345 | if (!Entry.empty() && !isa<Undefined>(Symtab.find(Entry)->body())) | |
| 396 | StringRef Entry = Symtab->findMangle(mangle(E[0])); | |
| 397 | if (!Entry.empty() && !isa<Undefined>(Symtab->find(Entry))) | |
| 346 | 398 | return mangle(E[1]); |
| 347 | 399 | } |
| 348 | 400 | return ""; |
| ... | ... | @@ -351,9 +403,9 @@ StringRef LinkerDriver::findDefaultEntry() { |
| 351 | 403 | WindowsSubsystem LinkerDriver::inferSubsystem() { |
| 352 | 404 | if (Config->DLL) |
| 353 | 405 | return IMAGE_SUBSYSTEM_WINDOWS_GUI; |
| 354 | if (Symtab.findUnderscore("main") || Symtab.findUnderscore("wmain")) | |
| 406 | if (Symtab->findUnderscore("main") || Symtab->findUnderscore("wmain")) | |
| 355 | 407 | return IMAGE_SUBSYSTEM_WINDOWS_CUI; |
| 356 | if (Symtab.findUnderscore("WinMain") || Symtab.findUnderscore("wWinMain")) | |
| 408 | if (Symtab->findUnderscore("WinMain") || Symtab->findUnderscore("wWinMain")) | |
| 357 | 409 | return IMAGE_SUBSYSTEM_WINDOWS_GUI; |
| 358 | 410 | return IMAGE_SUBSYSTEM_UNKNOWN; |
| 359 | 411 | } |
| ... | ... | @@ -376,9 +428,15 @@ static std::string createResponseFile(const opt::InputArgList &Args, |
| 376 | 428 | case OPT_INPUT: |
| 377 | 429 | case OPT_defaultlib: |
| 378 | 430 | case OPT_libpath: |
| 431 | case OPT_manifest: | |
| 432 | case OPT_manifest_colon: | |
| 433 | case OPT_manifestdependency: | |
| 434 | case OPT_manifestfile: | |
| 435 | case OPT_manifestinput: | |
| 436 | case OPT_manifestuac: | |
| 379 | 437 | break; |
| 380 | 438 | default: |
| 381 | OS << toString(Arg) << "\n"; | |
| 439 | OS << toString(*Arg) << "\n"; | |
| 382 | 440 | } |
| 383 | 441 | } |
| 384 | 442 | |
| ... | ... | @@ -476,15 +534,17 @@ static void createImportLibrary(bool AsLib) { |
| 476 | 534 | Exports.push_back(E2); |
| 477 | 535 | } |
| 478 | 536 | |
| 479 | writeImportLibrary(getImportName(AsLib), getImplibPath(), Exports, | |
| 480 | Config->Machine, false); | |
| 537 | auto E = writeImportLibrary(getImportName(AsLib), getImplibPath(), Exports, | |
| 538 | Config->Machine, false); | |
| 539 | handleAllErrors(std::move(E), | |
| 540 | [&](ErrorInfoBase &EIB) { error(EIB.message()); }); | |
| 481 | 541 | } |
| 482 | 542 | |
| 483 | 543 | static void parseModuleDefs(StringRef Path) { |
| 484 | std::unique_ptr<MemoryBuffer> MB = check( | |
| 485 | MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); | |
| 486 | COFFModuleDefinition M = | |
| 487 | check(parseCOFFModuleDefinition(MB->getMemBufferRef(), Config->Machine)); | |
| 544 | std::unique_ptr<MemoryBuffer> MB = CHECK( | |
| 545 | MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); | |
| 546 | COFFModuleDefinition M = check(parseCOFFModuleDefinition( | |
| 547 | MB->getMemBufferRef(), Config->Machine, Config->MinGW)); | |
| 488 | 548 | |
| 489 | 549 | if (Config->OutputFile.empty()) |
| 490 | 550 | Config->OutputFile = Saver.save(M.OutputFile); |
| ... | ... | @@ -522,31 +582,12 @@ static void parseModuleDefs(StringRef Path) { |
| 522 | 582 | } |
| 523 | 583 | } |
| 524 | 584 | |
| 525 | std::vector<MemoryBufferRef> getArchiveMembers(Archive *File) { | |
| 526 | std::vector<MemoryBufferRef> V; | |
| 527 | Error Err = Error::success(); | |
| 528 | for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) { | |
| 529 | Archive::Child C = | |
| 530 | check(COrErr, | |
| 531 | File->getFileName() + ": could not get the child of the archive"); | |
| 532 | MemoryBufferRef MBRef = | |
| 533 | check(C.getMemoryBufferRef(), | |
| 534 | File->getFileName() + | |
| 535 | ": could not get the buffer for a child of the archive"); | |
| 536 | V.push_back(MBRef); | |
| 537 | } | |
| 538 | if (Err) | |
| 539 | fatal(File->getFileName() + | |
| 540 | ": Archive::children failed: " + toString(std::move(Err))); | |
| 541 | return V; | |
| 542 | } | |
| 543 | ||
| 544 | 585 | // A helper function for filterBitcodeFiles. |
| 545 | 586 | static bool needsRebuilding(MemoryBufferRef MB) { |
| 546 | 587 | // The MSVC linker doesn't support thin archives, so if it's a thin |
| 547 | 588 | // archive, we always need to rebuild it. |
| 548 | 589 | std::unique_ptr<Archive> File = |
| 549 | check(Archive::create(MB), "Failed to read " + MB.getBufferIdentifier()); | |
| 590 | CHECK(Archive::create(MB), "Failed to read " + MB.getBufferIdentifier()); | |
| 550 | 591 | if (File->isThin()) |
| 551 | 592 | return true; |
| 552 | 593 | |
| ... | ... | @@ -567,7 +608,7 @@ static bool needsRebuilding(MemoryBufferRef MB) { |
| 567 | 608 | // its path is returned. |
| 568 | 609 | static Optional<std::string> |
| 569 | 610 | filterBitcodeFiles(StringRef Path, std::vector<std::string> &TemporaryFiles) { |
| 570 | std::unique_ptr<MemoryBuffer> MB = check( | |
| 611 | std::unique_ptr<MemoryBuffer> MB = CHECK( | |
| 571 | 612 | MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); |
| 572 | 613 | MemoryBufferRef MBRef = MB->getMemBufferRef(); |
| 573 | 614 | file_magic Magic = identify_magic(MBRef.getBuffer()); |
| ... | ... | @@ -580,7 +621,7 @@ filterBitcodeFiles(StringRef Path, std::vector<std::string> &TemporaryFiles) { |
| 580 | 621 | return Path.str(); |
| 581 | 622 | |
| 582 | 623 | std::unique_ptr<Archive> File = |
| 583 | check(Archive::create(MBRef), | |
| 624 | CHECK(Archive::create(MBRef), | |
| 584 | 625 | MBRef.getBufferIdentifier() + ": failed to parse archive"); |
| 585 | 626 | |
| 586 | 627 | std::vector<NewArchiveMember> New; |
| ... | ... | @@ -596,16 +637,17 @@ filterBitcodeFiles(StringRef Path, std::vector<std::string> &TemporaryFiles) { |
| 596 | 637 | SmallString<128> S; |
| 597 | 638 | if (auto EC = sys::fs::createTemporaryFile("lld-" + sys::path::stem(Path), |
| 598 | 639 | ".lib", S)) |
| 599 | fatal(EC, "cannot create a temporary file"); | |
| 640 | fatal("cannot create a temporary file: " + EC.message()); | |
| 600 | 641 | std::string Temp = S.str(); |
| 601 | 642 | TemporaryFiles.push_back(Temp); |
| 602 | 643 | |
| 603 | std::pair<StringRef, std::error_code> Ret = | |
| 644 | Error E = | |
| 604 | 645 | llvm::writeArchive(Temp, New, /*WriteSymtab=*/true, Archive::Kind::K_GNU, |
| 605 | 646 | /*Deterministics=*/true, |
| 606 | 647 | /*Thin=*/false); |
| 607 | if (Ret.second) | |
| 608 | error("failed to create a new archive " + S.str() + ": " + Ret.first); | |
| 648 | handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) { | |
| 649 | error("failed to create a new archive " + S.str() + ": " + EI.message()); | |
| 650 | }); | |
| 609 | 651 | return Temp; |
| 610 | 652 | } |
| 611 | 653 | |
| ... | ... | @@ -617,16 +659,16 @@ void LinkerDriver::invokeMSVC(opt::InputArgList &Args) { |
| 617 | 659 | // Write out archive members that we used in symbol resolution and pass these |
| 618 | 660 | // to MSVC before any archives, so that MSVC uses the same objects to satisfy |
| 619 | 661 | // references. |
| 620 | for (const auto *O : Symtab.ObjectFiles) { | |
| 621 | if (O->ParentName.empty()) | |
| 662 | for (ObjFile *Obj : ObjFile::Instances) { | |
| 663 | if (Obj->ParentName.empty()) | |
| 622 | 664 | continue; |
| 623 | 665 | SmallString<128> S; |
| 624 | 666 | int Fd; |
| 625 | 667 | if (auto EC = sys::fs::createTemporaryFile( |
| 626 | "lld-" + sys::path::filename(O->ParentName), ".obj", Fd, S)) | |
| 627 | fatal(EC, "cannot create a temporary file"); | |
| 668 | "lld-" + sys::path::filename(Obj->ParentName), ".obj", Fd, S)) | |
| 669 | fatal("cannot create a temporary file: " + EC.message()); | |
| 628 | 670 | raw_fd_ostream OS(Fd, /*shouldClose*/ true); |
| 629 | OS << O->MB.getBuffer(); | |
| 671 | OS << Obj->MB.getBuffer(); | |
| 630 | 672 | Temps.push_back(S.str()); |
| 631 | 673 | Rsp += quote(S) + "\n"; |
| 632 | 674 | } |
| ... | ... | @@ -642,7 +684,7 @@ void LinkerDriver::invokeMSVC(opt::InputArgList &Args) { |
| 642 | 684 | break; |
| 643 | 685 | case OPT_opt: |
| 644 | 686 | if (!StringRef(Arg->getValue()).startswith("lld")) |
| 645 | Rsp += toString(Arg) + " "; | |
| 687 | Rsp += toString(*Arg) + " "; | |
| 646 | 688 | break; |
| 647 | 689 | case OPT_INPUT: { |
| 648 | 690 | if (Optional<StringRef> Path = doFindFile(Arg->getValue())) { |
| ... | ... | @@ -654,12 +696,12 @@ void LinkerDriver::invokeMSVC(opt::InputArgList &Args) { |
| 654 | 696 | break; |
| 655 | 697 | } |
| 656 | 698 | default: |
| 657 | Rsp += toString(Arg) + "\n"; | |
| 699 | Rsp += toString(*Arg) + "\n"; | |
| 658 | 700 | } |
| 659 | 701 | } |
| 660 | 702 | |
| 661 | std::vector<StringRef> ObjectFiles = Symtab.compileBitcodeFiles(); | |
| 662 | runMSVCLinker(Rsp, ObjectFiles); | |
| 703 | std::vector<StringRef> ObjFiles = Symtab->compileBitcodeFiles(); | |
| 704 | runMSVCLinker(Rsp, ObjFiles); | |
| 663 | 705 | |
| 664 | 706 | for (StringRef Path : Temps) |
| 665 | 707 | sys::fs::remove(Path); |
| ... | ... | @@ -696,6 +738,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 696 | 738 | InitializeAllDisassemblers(); |
| 697 | 739 | |
| 698 | 740 | // Parse command line options. |
| 741 | ArgParser Parser; | |
| 699 | 742 | opt::InputArgList Args = Parser.parseLINK(ArgsArr.slice(1)); |
| 700 | 743 | |
| 701 | 744 | // Parse and evaluate -mllvm options. |
| ... | ... | @@ -711,7 +754,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 711 | 754 | StringRef S = Arg->getValue(); |
| 712 | 755 | if (S.getAsInteger(10, N)) |
| 713 | 756 | error(Arg->getSpelling() + " number expected, but got " + S); |
| 714 | Config->ErrorLimit = N; | |
| 757 | errorHandler().ErrorLimit = N; | |
| 715 | 758 | } |
| 716 | 759 | |
| 717 | 760 | // Handle /help |
| ... | ... | @@ -720,6 +763,18 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 720 | 763 | return; |
| 721 | 764 | } |
| 722 | 765 | |
| 766 | // Handle --version, which is an lld extension. This option is a bit odd | |
| 767 | // because it doesn't start with "/", but we deliberately chose "--" to | |
| 768 | // avoid conflict with /version and for compatibility with clang-cl. | |
| 769 | if (Args.hasArg(OPT_dash_dash_version)) { | |
| 770 | outs() << getLLDVersion() << "\n"; | |
| 771 | return; | |
| 772 | } | |
| 773 | ||
| 774 | // Handle /lldmingw early, since it can potentially affect how other | |
| 775 | // options are handled. | |
| 776 | Config->MinGW = Args.hasArg(OPT_lldmingw); | |
| 777 | ||
| 723 | 778 | if (auto *Arg = Args.getLastArg(OPT_linkrepro)) { |
| 724 | 779 | SmallString<64> Path = StringRef(Arg->getValue()); |
| 725 | 780 | sys::path::append(Path, "repro.tar"); |
| ... | ... | @@ -735,8 +790,8 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 735 | 790 | } |
| 736 | 791 | } |
| 737 | 792 | |
| 738 | if (!Args.hasArgNoClaim(OPT_INPUT)) { | |
| 739 | if (Args.hasArgNoClaim(OPT_deffile)) | |
| 793 | if (!Args.hasArg(OPT_INPUT)) { | |
| 794 | if (Args.hasArg(OPT_deffile)) | |
| 740 | 795 | Config->NoEntry = true; |
| 741 | 796 | else |
| 742 | 797 | fatal("no input files"); |
| ... | ... | @@ -748,6 +803,13 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 748 | 803 | SearchPaths.push_back(Arg->getValue()); |
| 749 | 804 | addLibSearchPaths(); |
| 750 | 805 | |
| 806 | // Handle /ignore | |
| 807 | for (auto *Arg : Args.filtered(OPT_ignore)) { | |
| 808 | if (StringRef(Arg->getValue()) == "4217") | |
| 809 | Config->WarnLocallyDefinedImported = false; | |
| 810 | // Other warning numbers are ignored. | |
| 811 | } | |
| 812 | ||
| 751 | 813 | // Handle /out |
| 752 | 814 | if (auto *Arg = Args.getLastArg(OPT_out)) |
| 753 | 815 | Config->OutputFile = Arg->getValue(); |
| ... | ... | @@ -755,23 +817,26 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 755 | 817 | // Handle /verbose |
| 756 | 818 | if (Args.hasArg(OPT_verbose)) |
| 757 | 819 | Config->Verbose = true; |
| 820 | errorHandler().Verbose = Config->Verbose; | |
| 758 | 821 | |
| 759 | 822 | // Handle /force or /force:unresolved |
| 760 | if (Args.hasArg(OPT_force) || Args.hasArg(OPT_force_unresolved)) | |
| 823 | if (Args.hasArg(OPT_force, OPT_force_unresolved)) | |
| 761 | 824 | Config->Force = true; |
| 762 | 825 | |
| 763 | 826 | // Handle /debug |
| 764 | if (Args.hasArg(OPT_debug)) { | |
| 827 | if (Args.hasArg(OPT_debug, OPT_debug_dwarf, OPT_debug_ghash)) { | |
| 765 | 828 | Config->Debug = true; |
| 766 | Config->DebugTypes = | |
| 767 | Args.hasArg(OPT_debugtype) | |
| 768 | ? parseDebugType(Args.getLastArg(OPT_debugtype)->getValue()) | |
| 769 | : getDefaultDebugType(Args); | |
| 829 | if (auto *Arg = Args.getLastArg(OPT_debugtype)) | |
| 830 | Config->DebugTypes = parseDebugType(Arg->getValue()); | |
| 831 | else | |
| 832 | Config->DebugTypes = getDefaultDebugType(Args); | |
| 770 | 833 | } |
| 771 | 834 | |
| 772 | // Create a dummy PDB file to satisfy build sytem rules. | |
| 773 | if (auto *Arg = Args.getLastArg(OPT_pdb)) | |
| 774 | Config->PDBPath = Arg->getValue(); | |
| 835 | // Handle /pdb | |
| 836 | bool ShouldCreatePDB = Args.hasArg(OPT_debug, OPT_debug_ghash); | |
| 837 | if (ShouldCreatePDB) | |
| 838 | if (auto *Arg = Args.getLastArg(OPT_pdb)) | |
| 839 | Config->PDBPath = Arg->getValue(); | |
| 775 | 840 | |
| 776 | 841 | // Handle /noentry |
| 777 | 842 | if (Args.hasArg(OPT_noentry)) { |
| ... | ... | @@ -787,9 +852,18 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 787 | 852 | Config->ManifestID = 2; |
| 788 | 853 | } |
| 789 | 854 | |
| 790 | // Handle /fixed | |
| 791 | if (Args.hasArg(OPT_fixed)) { | |
| 792 | if (Args.hasArg(OPT_dynamicbase)) { | |
| 855 | // Handle /dynamicbase and /fixed. We can't use hasFlag for /dynamicbase | |
| 856 | // because we need to explicitly check whether that option or its inverse was | |
| 857 | // present in the argument list in order to handle /fixed. | |
| 858 | auto *DynamicBaseArg = Args.getLastArg(OPT_dynamicbase, OPT_dynamicbase_no); | |
| 859 | if (DynamicBaseArg && | |
| 860 | DynamicBaseArg->getOption().getID() == OPT_dynamicbase_no) | |
| 861 | Config->DynamicBase = false; | |
| 862 | ||
| 863 | bool Fixed = Args.hasFlag(OPT_fixed, OPT_fixed_no, false); | |
| 864 | if (Fixed) { | |
| 865 | if (DynamicBaseArg && | |
| 866 | DynamicBaseArg->getOption().getID() == OPT_dynamicbase) { | |
| 793 | 867 | error("/fixed must not be specified with /dynamicbase"); |
| 794 | 868 | } else { |
| 795 | 869 | Config->Relocatable = false; |
| ... | ... | @@ -797,8 +871,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 797 | 871 | } |
| 798 | 872 | } |
| 799 | 873 | |
| 800 | if (Args.hasArg(OPT_appcontainer)) | |
| 801 | Config->AppContainer = true; | |
| 874 | // Handle /appcontainer | |
| 875 | Config->AppContainer = | |
| 876 | Args.hasFlag(OPT_appcontainer, OPT_appcontainer_no, false); | |
| 802 | 877 | |
| 803 | 878 | // Handle /machine |
| 804 | 879 | if (auto *Arg = Args.getLastArg(OPT_machine)) |
| ... | ... | @@ -846,54 +921,65 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 846 | 921 | if (auto *Arg = Args.getLastArg(OPT_implib)) |
| 847 | 922 | Config->Implib = Arg->getValue(); |
| 848 | 923 | |
| 849 | // Handle /opt | |
| 924 | // Handle /opt. | |
| 925 | bool DoGC = !Args.hasArg(OPT_debug); | |
| 926 | unsigned ICFLevel = 1; // 0: off, 1: limited, 2: on | |
| 850 | 927 | for (auto *Arg : Args.filtered(OPT_opt)) { |
| 851 | 928 | std::string Str = StringRef(Arg->getValue()).lower(); |
| 852 | 929 | SmallVector<StringRef, 1> Vec; |
| 853 | 930 | StringRef(Str).split(Vec, ','); |
| 854 | 931 | for (StringRef S : Vec) { |
| 855 | if (S == "noref") { | |
| 856 | Config->DoGC = false; | |
| 857 | Config->DoICF = false; | |
| 858 | continue; | |
| 859 | } | |
| 860 | if (S == "icf" || StringRef(S).startswith("icf=")) { | |
| 861 | Config->DoICF = true; | |
| 862 | continue; | |
| 863 | } | |
| 864 | if (S == "noicf") { | |
| 865 | Config->DoICF = false; | |
| 866 | continue; | |
| 867 | } | |
| 868 | if (StringRef(S).startswith("lldlto=")) { | |
| 869 | StringRef OptLevel = StringRef(S).substr(7); | |
| 932 | if (S == "ref") { | |
| 933 | DoGC = true; | |
| 934 | } else if (S == "noref") { | |
| 935 | DoGC = false; | |
| 936 | } else if (S == "icf" || S.startswith("icf=")) { | |
| 937 | ICFLevel = 2; | |
| 938 | } else if (S == "noicf") { | |
| 939 | ICFLevel = 0; | |
| 940 | } else if (S.startswith("lldlto=")) { | |
| 941 | StringRef OptLevel = S.substr(7); | |
| 870 | 942 | if (OptLevel.getAsInteger(10, Config->LTOOptLevel) || |
| 871 | 943 | Config->LTOOptLevel > 3) |
| 872 | 944 | error("/opt:lldlto: invalid optimization level: " + OptLevel); |
| 873 | continue; | |
| 874 | } | |
| 875 | if (StringRef(S).startswith("lldltojobs=")) { | |
| 876 | StringRef Jobs = StringRef(S).substr(11); | |
| 945 | } else if (S.startswith("lldltojobs=")) { | |
| 946 | StringRef Jobs = S.substr(11); | |
| 877 | 947 | if (Jobs.getAsInteger(10, Config->LTOJobs) || Config->LTOJobs == 0) |
| 878 | 948 | error("/opt:lldltojobs: invalid job count: " + Jobs); |
| 879 | continue; | |
| 880 | } | |
| 881 | if (StringRef(S).startswith("lldltopartitions=")) { | |
| 882 | StringRef N = StringRef(S).substr(17); | |
| 949 | } else if (S.startswith("lldltopartitions=")) { | |
| 950 | StringRef N = S.substr(17); | |
| 883 | 951 | if (N.getAsInteger(10, Config->LTOPartitions) || |
| 884 | 952 | Config->LTOPartitions == 0) |
| 885 | 953 | error("/opt:lldltopartitions: invalid partition count: " + N); |
| 886 | continue; | |
| 887 | } | |
| 888 | if (S != "ref" && S != "lbr" && S != "nolbr") | |
| 954 | } else if (S != "lbr" && S != "nolbr") | |
| 889 | 955 | error("/opt: unknown option: " + S); |
| 890 | 956 | } |
| 891 | 957 | } |
| 892 | 958 | |
| 959 | // Limited ICF is enabled if GC is enabled and ICF was never mentioned | |
| 960 | // explicitly. | |
| 961 | // FIXME: LLD only implements "limited" ICF, i.e. it only merges identical | |
| 962 | // code. If the user passes /OPT:ICF explicitly, LLD should merge identical | |
| 963 | // comdat readonly data. | |
| 964 | if (ICFLevel == 1 && !DoGC) | |
| 965 | ICFLevel = 0; | |
| 966 | Config->DoGC = DoGC; | |
| 967 | Config->DoICF = ICFLevel > 0; | |
| 968 | ||
| 893 | 969 | // Handle /lldsavetemps |
| 894 | 970 | if (Args.hasArg(OPT_lldsavetemps)) |
| 895 | 971 | Config->SaveTemps = true; |
| 896 | 972 | |
| 973 | // Handle /lldltocache | |
| 974 | if (auto *Arg = Args.getLastArg(OPT_lldltocache)) | |
| 975 | Config->LTOCache = Arg->getValue(); | |
| 976 | ||
| 977 | // Handle /lldsavecachepolicy | |
| 978 | if (auto *Arg = Args.getLastArg(OPT_lldltocachepolicy)) | |
| 979 | Config->LTOCachePolicy = CHECK( | |
| 980 | parseCachePruningPolicy(Arg->getValue()), | |
| 981 | Twine("/lldltocachepolicy: invalid cache policy: ") + Arg->getValue()); | |
| 982 | ||
| 897 | 983 | // Handle /failifmismatch |
| 898 | 984 | for (auto *Arg : Args.filtered(OPT_failifmismatch)) |
| 899 | 985 | checkFailIfMismatch(Arg->getValue()); |
| ... | ... | @@ -906,6 +992,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 906 | 992 | for (auto *Arg : Args.filtered(OPT_section)) |
| 907 | 993 | parseSection(Arg->getValue()); |
| 908 | 994 | |
| 995 | // Handle /aligncomm | |
| 996 | for (auto *Arg : Args.filtered(OPT_aligncomm)) | |
| 997 | parseAligncomm(Arg->getValue()); | |
| 998 | ||
| 909 | 999 | // Handle /manifestdependency. This enables /manifest unless /manifest:no is |
| 910 | 1000 | // also passed. |
| 911 | 1001 | if (auto *Arg = Args.getLastArg(OPT_manifestdependency)) { |
| ... | ... | @@ -939,35 +1029,42 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 939 | 1029 | } |
| 940 | 1030 | |
| 941 | 1031 | // Handle miscellaneous boolean flags. |
| 942 | if (Args.hasArg(OPT_allowisolation_no)) | |
| 943 | Config->AllowIsolation = false; | |
| 944 | if (Args.hasArg(OPT_dynamicbase_no)) | |
| 945 | Config->DynamicBase = false; | |
| 946 | if (Args.hasArg(OPT_nxcompat_no)) | |
| 947 | Config->NxCompat = false; | |
| 948 | if (Args.hasArg(OPT_tsaware_no)) | |
| 949 | Config->TerminalServerAware = false; | |
| 950 | if (Args.hasArg(OPT_nosymtab)) | |
| 951 | Config->WriteSymtab = false; | |
| 1032 | Config->AllowBind = Args.hasFlag(OPT_allowbind, OPT_allowbind_no, true); | |
| 1033 | Config->AllowIsolation = | |
| 1034 | Args.hasFlag(OPT_allowisolation, OPT_allowisolation_no, true); | |
| 1035 | Config->NxCompat = Args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true); | |
| 1036 | Config->TerminalServerAware = Args.hasFlag(OPT_tsaware, OPT_tsaware_no, true); | |
| 1037 | Config->DebugDwarf = Args.hasArg(OPT_debug_dwarf); | |
| 1038 | Config->DebugGHashes = Args.hasArg(OPT_debug_ghash); | |
| 952 | 1039 | |
| 953 | 1040 | Config->MapFile = getMapFile(Args); |
| 954 | 1041 | |
| 955 | if (ErrorCount) | |
| 1042 | if (errorCount()) | |
| 956 | 1043 | return; |
| 957 | 1044 | |
| 1045 | bool WholeArchiveFlag = Args.hasArg(OPT_wholearchive_flag); | |
| 958 | 1046 | // Create a list of input files. Files can be given as arguments |
| 959 | 1047 | // for /defaultlib option. |
| 960 | 1048 | std::vector<MemoryBufferRef> MBs; |
| 961 | for (auto *Arg : Args.filtered(OPT_INPUT)) | |
| 962 | if (Optional<StringRef> Path = findFile(Arg->getValue())) | |
| 963 | enqueuePath(*Path); | |
| 1049 | for (auto *Arg : Args.filtered(OPT_INPUT, OPT_wholearchive_file)) { | |
| 1050 | switch (Arg->getOption().getID()) { | |
| 1051 | case OPT_INPUT: | |
| 1052 | if (Optional<StringRef> Path = findFile(Arg->getValue())) | |
| 1053 | enqueuePath(*Path, WholeArchiveFlag); | |
| 1054 | break; | |
| 1055 | case OPT_wholearchive_file: | |
| 1056 | if (Optional<StringRef> Path = findFile(Arg->getValue())) | |
| 1057 | enqueuePath(*Path, true); | |
| 1058 | break; | |
| 1059 | } | |
| 1060 | } | |
| 964 | 1061 | for (auto *Arg : Args.filtered(OPT_defaultlib)) |
| 965 | 1062 | if (Optional<StringRef> Path = findLib(Arg->getValue())) |
| 966 | enqueuePath(*Path); | |
| 1063 | enqueuePath(*Path, false); | |
| 967 | 1064 | |
| 968 | 1065 | // Windows specific -- Create a resource file containing a manifest file. |
| 969 | 1066 | if (Config->Manifest == Configuration::Embed) |
| 970 | addBuffer(createManifestRes()); | |
| 1067 | addBuffer(createManifestRes(), false); | |
| 971 | 1068 | |
| 972 | 1069 | // Read all input files given via the command line. |
| 973 | 1070 | run(); |
| ... | ... | @@ -983,7 +1080,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 983 | 1080 | // WindowsResource to convert resource files to a regular COFF file, |
| 984 | 1081 | // then link the resulting file normally. |
| 985 | 1082 | if (!Resources.empty()) |
| 986 | addBuffer(convertResToCOFF(Resources)); | |
| 1083 | Symtab->addFile(make<ObjFile>(convertResToCOFF(Resources))); | |
| 987 | 1084 | |
| 988 | 1085 | if (Tar) |
| 989 | 1086 | Tar->append("response.txt", |
| ... | ... | @@ -991,28 +1088,36 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 991 | 1088 | ArrayRef<StringRef>(SearchPaths).slice(1))); |
| 992 | 1089 | |
| 993 | 1090 | // Handle /largeaddressaware |
| 994 | if (Config->is64() || Args.hasArg(OPT_largeaddressaware)) | |
| 995 | Config->LargeAddressAware = true; | |
| 1091 | Config->LargeAddressAware = Args.hasFlag( | |
| 1092 | OPT_largeaddressaware, OPT_largeaddressaware_no, Config->is64()); | |
| 996 | 1093 | |
| 997 | 1094 | // Handle /highentropyva |
| 998 | if (Config->is64() && !Args.hasArg(OPT_highentropyva_no)) | |
| 999 | Config->HighEntropyVA = true; | |
| 1095 | Config->HighEntropyVA = | |
| 1096 | Config->is64() && | |
| 1097 | Args.hasFlag(OPT_highentropyva, OPT_highentropyva_no, true); | |
| 1098 | ||
| 1099 | if (!Config->DynamicBase && | |
| 1100 | (Config->Machine == ARMNT || Config->Machine == ARM64)) | |
| 1101 | error("/dynamicbase:no is not compatible with " + | |
| 1102 | machineToStr(Config->Machine)); | |
| 1000 | 1103 | |
| 1001 | 1104 | // Handle /entry and /dll |
| 1002 | 1105 | if (auto *Arg = Args.getLastArg(OPT_entry)) { |
| 1003 | 1106 | Config->Entry = addUndefined(mangle(Arg->getValue())); |
| 1004 | } else if (Args.hasArg(OPT_dll) && !Config->NoEntry) { | |
| 1005 | StringRef S = (Config->Machine == I386) ? "__DllMainCRTStartup@12" | |
| 1006 | : "_DllMainCRTStartup"; | |
| 1007 | Config->Entry = addUndefined(S); | |
| 1008 | } else if (!Config->NoEntry) { | |
| 1009 | // Windows specific -- If entry point name is not given, we need to | |
| 1010 | // infer that from user-defined entry name. | |
| 1011 | StringRef S = findDefaultEntry(); | |
| 1012 | if (S.empty()) | |
| 1013 | fatal("entry point must be defined"); | |
| 1014 | Config->Entry = addUndefined(S); | |
| 1015 | log("Entry name inferred: " + S); | |
| 1107 | } else if (!Config->Entry && !Config->NoEntry) { | |
| 1108 | if (Args.hasArg(OPT_dll)) { | |
| 1109 | StringRef S = (Config->Machine == I386) ? "__DllMainCRTStartup@12" | |
| 1110 | : "_DllMainCRTStartup"; | |
| 1111 | Config->Entry = addUndefined(S); | |
| 1112 | } else { | |
| 1113 | // Windows specific -- If entry point name is not given, we need to | |
| 1114 | // infer that from user-defined entry name. | |
| 1115 | StringRef S = findDefaultEntry(); | |
| 1116 | if (S.empty()) | |
| 1117 | fatal("entry point must be defined"); | |
| 1118 | Config->Entry = addUndefined(S); | |
| 1119 | log("Entry name inferred: " + S); | |
| 1120 | } | |
| 1016 | 1121 | } |
| 1017 | 1122 | |
| 1018 | 1123 | // Handle /export |
| ... | ... | @@ -1034,7 +1139,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1034 | 1139 | } |
| 1035 | 1140 | |
| 1036 | 1141 | // Handle generation of import library from a def file. |
| 1037 | if (!Args.hasArgNoClaim(OPT_INPUT)) { | |
| 1142 | if (!Args.hasArg(OPT_INPUT)) { | |
| 1038 | 1143 | fixupExports(); |
| 1039 | 1144 | createImportLibrary(/*AsLib=*/true); |
| 1040 | 1145 | return; |
| ... | ... | @@ -1057,34 +1162,32 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1057 | 1162 | } |
| 1058 | 1163 | |
| 1059 | 1164 | // Put the PDB next to the image if no /pdb flag was passed. |
| 1060 | if (Config->Debug && Config->PDBPath.empty()) { | |
| 1165 | if (ShouldCreatePDB && Config->PDBPath.empty()) { | |
| 1061 | 1166 | Config->PDBPath = Config->OutputFile; |
| 1062 | 1167 | sys::path::replace_extension(Config->PDBPath, ".pdb"); |
| 1063 | 1168 | } |
| 1064 | 1169 | |
| 1065 | // Disable PDB generation if the user requested it. | |
| 1066 | if (Args.hasArg(OPT_nopdb)) | |
| 1067 | Config->PDBPath = ""; | |
| 1068 | ||
| 1069 | 1170 | // Set default image base if /base is not given. |
| 1070 | 1171 | if (Config->ImageBase == uint64_t(-1)) |
| 1071 | 1172 | Config->ImageBase = getDefaultImageBase(); |
| 1072 | 1173 | |
| 1073 | Symtab.addSynthetic(mangle("__ImageBase"), nullptr); | |
| 1174 | Symtab->addSynthetic(mangle("__ImageBase"), nullptr); | |
| 1074 | 1175 | if (Config->Machine == I386) { |
| 1075 | Symtab.addAbsolute("___safe_se_handler_table", 0); | |
| 1076 | Symtab.addAbsolute("___safe_se_handler_count", 0); | |
| 1176 | Symtab->addAbsolute("___safe_se_handler_table", 0); | |
| 1177 | Symtab->addAbsolute("___safe_se_handler_count", 0); | |
| 1077 | 1178 | } |
| 1078 | 1179 | |
| 1079 | 1180 | // We do not support /guard:cf (control flow protection) yet. |
| 1080 | 1181 | // Define CFG symbols anyway so that we can link MSVC 2015 CRT. |
| 1081 | Symtab.addAbsolute(mangle("__guard_fids_count"), 0); | |
| 1082 | Symtab.addAbsolute(mangle("__guard_fids_table"), 0); | |
| 1083 | Symtab.addAbsolute(mangle("__guard_flags"), 0x100); | |
| 1084 | Symtab.addAbsolute(mangle("__guard_iat_count"), 0); | |
| 1085 | Symtab.addAbsolute(mangle("__guard_iat_table"), 0); | |
| 1086 | Symtab.addAbsolute(mangle("__guard_longjmp_count"), 0); | |
| 1087 | Symtab.addAbsolute(mangle("__guard_longjmp_table"), 0); | |
| 1182 | Symtab->addAbsolute(mangle("__guard_fids_count"), 0); | |
| 1183 | Symtab->addAbsolute(mangle("__guard_fids_table"), 0); | |
| 1184 | Symtab->addAbsolute(mangle("__guard_flags"), 0x100); | |
| 1185 | Symtab->addAbsolute(mangle("__guard_iat_count"), 0); | |
| 1186 | Symtab->addAbsolute(mangle("__guard_iat_table"), 0); | |
| 1187 | Symtab->addAbsolute(mangle("__guard_longjmp_count"), 0); | |
| 1188 | Symtab->addAbsolute(mangle("__guard_longjmp_table"), 0); | |
| 1189 | // Needed for MSVC 2017 15.5 CRT. | |
| 1190 | Symtab->addAbsolute(mangle("__enclave_config"), 0); | |
| 1088 | 1191 | |
| 1089 | 1192 | // This code may add new undefined symbols to the link, which may enqueue more |
| 1090 | 1193 | // symbol resolution tasks, so we need to continue executing tasks until we |
| ... | ... | @@ -1093,7 +1196,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1093 | 1196 | // Windows specific -- if entry point is not found, |
| 1094 | 1197 | // search for its mangled names. |
| 1095 | 1198 | if (Config->Entry) |
| 1096 | Symtab.mangleMaybe(Config->Entry); | |
| 1199 | Symtab->mangleMaybe(Config->Entry); | |
| 1097 | 1200 | |
| 1098 | 1201 | // Windows specific -- Make sure we resolve all dllexported symbols. |
| 1099 | 1202 | for (Export &E : Config->Exports) { |
| ... | ... | @@ -1101,7 +1204,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1101 | 1204 | continue; |
| 1102 | 1205 | E.Sym = addUndefined(E.Name); |
| 1103 | 1206 | if (!E.Directives) |
| 1104 | Symtab.mangleMaybe(E.Sym); | |
| 1207 | Symtab->mangleMaybe(E.Sym); | |
| 1105 | 1208 | } |
| 1106 | 1209 | |
| 1107 | 1210 | // Add weak aliases. Weak aliases is a mechanism to give remaining |
| ... | ... | @@ -1109,20 +1212,20 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1109 | 1212 | for (auto Pair : Config->AlternateNames) { |
| 1110 | 1213 | StringRef From = Pair.first; |
| 1111 | 1214 | StringRef To = Pair.second; |
| 1112 | Symbol *Sym = Symtab.find(From); | |
| 1215 | Symbol *Sym = Symtab->find(From); | |
| 1113 | 1216 | if (!Sym) |
| 1114 | 1217 | continue; |
| 1115 | if (auto *U = dyn_cast<Undefined>(Sym->body())) | |
| 1218 | if (auto *U = dyn_cast<Undefined>(Sym)) | |
| 1116 | 1219 | if (!U->WeakAlias) |
| 1117 | U->WeakAlias = Symtab.addUndefined(To); | |
| 1220 | U->WeakAlias = Symtab->addUndefined(To); | |
| 1118 | 1221 | } |
| 1119 | 1222 | |
| 1120 | 1223 | // Windows specific -- if __load_config_used can be resolved, resolve it. |
| 1121 | if (Symtab.findUnderscore("_load_config_used")) | |
| 1224 | if (Symtab->findUnderscore("_load_config_used")) | |
| 1122 | 1225 | addUndefined(mangle("_load_config_used")); |
| 1123 | 1226 | } while (run()); |
| 1124 | 1227 | |
| 1125 | if (ErrorCount) | |
| 1228 | if (errorCount()) | |
| 1126 | 1229 | return; |
| 1127 | 1230 | |
| 1128 | 1231 | // If /msvclto is given, we use the MSVC linker to link LTO output files. |
| ... | ... | @@ -1134,11 +1237,13 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1134 | 1237 | |
| 1135 | 1238 | // Do LTO by compiling bitcode input files to a set of native COFF files then |
| 1136 | 1239 | // link those files. |
| 1137 | Symtab.addCombinedLTOObjects(); | |
| 1240 | Symtab->addCombinedLTOObjects(); | |
| 1138 | 1241 | run(); |
| 1139 | 1242 | |
| 1140 | 1243 | // Make sure we have resolved all symbols. |
| 1141 | Symtab.reportRemainingUndefines(); | |
| 1244 | Symtab->reportRemainingUndefines(); | |
| 1245 | if (errorCount()) | |
| 1246 | return; | |
| 1142 | 1247 | |
| 1143 | 1248 | // Windows specific -- if no /subsystem is given, we need to infer |
| 1144 | 1249 | // that from entry point name. |
| ... | ... | @@ -1149,14 +1254,34 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1149 | 1254 | } |
| 1150 | 1255 | |
| 1151 | 1256 | // Handle /safeseh. |
| 1152 | if (Args.hasArg(OPT_safeseh)) { | |
| 1153 | for (ObjectFile *File : Symtab.ObjectFiles) | |
| 1257 | if (Args.hasFlag(OPT_safeseh, OPT_safeseh_no, false)) { | |
| 1258 | for (ObjFile *File : ObjFile::Instances) | |
| 1154 | 1259 | if (!File->SEHCompat) |
| 1155 | 1260 | error("/safeseh: " + File->getName() + " is not compatible with SEH"); |
| 1156 | if (ErrorCount) | |
| 1261 | if (errorCount()) | |
| 1157 | 1262 | return; |
| 1158 | 1263 | } |
| 1159 | 1264 | |
| 1265 | // In MinGW, all symbols are automatically exported if no symbols | |
| 1266 | // are chosen to be exported. | |
| 1267 | if (Config->DLL && ((Config->MinGW && Config->Exports.empty()) || | |
| 1268 | Args.hasArg(OPT_export_all_symbols))) { | |
| 1269 | AutoExporter Exporter; | |
| 1270 | ||
| 1271 | Symtab->forEachSymbol([=](Symbol *S) { | |
| 1272 | auto *Def = dyn_cast<Defined>(S); | |
| 1273 | if (!Exporter.shouldExport(Def)) | |
| 1274 | return; | |
| 1275 | Export E; | |
| 1276 | E.Name = Def->getName(); | |
| 1277 | E.Sym = Def; | |
| 1278 | if (Def->getChunk() && | |
| 1279 | !(Def->getChunk()->getPermissions() & IMAGE_SCN_MEM_EXECUTE)) | |
| 1280 | E.Data = true; | |
| 1281 | Config->Exports.push_back(E); | |
| 1282 | }); | |
| 1283 | } | |
| 1284 | ||
| 1160 | 1285 | // Windows specific -- when we are creating a .dll file, we also |
| 1161 | 1286 | // need to create a .lib file. |
| 1162 | 1287 | if (!Config->Exports.empty() || Config->DLL) { |
| ... | ... | @@ -1165,20 +1290,45 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1165 | 1290 | assignExportOrdinals(); |
| 1166 | 1291 | } |
| 1167 | 1292 | |
| 1293 | // Handle /output-def (MinGW specific). | |
| 1294 | if (auto *Arg = Args.getLastArg(OPT_output_def)) | |
| 1295 | writeDefFile(Arg->getValue()); | |
| 1296 | ||
| 1297 | // Set extra alignment for .comm symbols | |
| 1298 | for (auto Pair : Config->AlignComm) { | |
| 1299 | StringRef Name = Pair.first; | |
| 1300 | uint32_t Alignment = Pair.second; | |
| 1301 | ||
| 1302 | Symbol *Sym = Symtab->find(Name); | |
| 1303 | if (!Sym) { | |
| 1304 | warn("/aligncomm symbol " + Name + " not found"); | |
| 1305 | continue; | |
| 1306 | } | |
| 1307 | ||
| 1308 | auto *DC = dyn_cast<DefinedCommon>(Sym); | |
| 1309 | if (!DC) { | |
| 1310 | warn("/aligncomm symbol " + Name + " of wrong kind"); | |
| 1311 | continue; | |
| 1312 | } | |
| 1313 | ||
| 1314 | CommonChunk *C = DC->getChunk(); | |
| 1315 | C->Alignment = std::max(C->Alignment, Alignment); | |
| 1316 | } | |
| 1317 | ||
| 1168 | 1318 | // Windows specific -- Create a side-by-side manifest file. |
| 1169 | 1319 | if (Config->Manifest == Configuration::SideBySide) |
| 1170 | 1320 | createSideBySideManifest(); |
| 1171 | 1321 | |
| 1172 | 1322 | // Identify unreferenced COMDAT sections. |
| 1173 | 1323 | if (Config->DoGC) |
| 1174 | markLive(Symtab.getChunks()); | |
| 1324 | markLive(Symtab->getChunks()); | |
| 1175 | 1325 | |
| 1176 | 1326 | // Identify identical COMDAT sections to merge them. |
| 1177 | 1327 | if (Config->DoICF) |
| 1178 | doICF(Symtab.getChunks()); | |
| 1328 | doICF(Symtab->getChunks()); | |
| 1179 | 1329 | |
| 1180 | 1330 | // Write the result. |
| 1181 | writeResult(&Symtab); | |
| 1331 | writeResult(); | |
| 1182 | 1332 | } |
| 1183 | 1333 | |
| 1184 | 1334 | } // namespace coff |
deps/lld/COFF/Driver.h+29-21| ... | ... | @@ -12,10 +12,11 @@ |
| 12 | 12 | |
| 13 | 13 | #include "Config.h" |
| 14 | 14 | #include "SymbolTable.h" |
| 15 | #include "lld/Core/LLVM.h" | |
| 16 | #include "lld/Core/Reproduce.h" | |
| 15 | #include "lld/Common/LLVM.h" | |
| 16 | #include "lld/Common/Reproduce.h" | |
| 17 | 17 | #include "llvm/ADT/Optional.h" |
| 18 | 18 | #include "llvm/ADT/StringRef.h" |
| 19 | #include "llvm/ADT/StringSet.h" | |
| 19 | 20 | #include "llvm/Object/Archive.h" |
| 20 | 21 | #include "llvm/Object/COFF.h" |
| 21 | 22 | #include "llvm/Option/Arg.h" |
| ... | ... | @@ -36,31 +37,39 @@ using llvm::COFF::WindowsSubsystem; |
| 36 | 37 | using llvm::Optional; |
| 37 | 38 | |
| 38 | 39 | // Implemented in MarkLive.cpp. |
| 39 | void markLive(const std::vector<Chunk *> &Chunks); | |
| 40 | void markLive(ArrayRef<Chunk *> Chunks); | |
| 40 | 41 | |
| 41 | 42 | // Implemented in ICF.cpp. |
| 42 | void doICF(const std::vector<Chunk *> &Chunks); | |
| 43 | void doICF(ArrayRef<Chunk *> Chunks); | |
| 43 | 44 | |
| 44 | class ArgParser { | |
| 45 | class COFFOptTable : public llvm::opt::OptTable { | |
| 45 | 46 | public: |
| 46 | // Parses command line options. | |
| 47 | llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> Args); | |
| 47 | COFFOptTable(); | |
| 48 | }; | |
| 48 | 49 | |
| 49 | // Concatenate LINK environment varirable and given arguments and parse them. | |
| 50 | class ArgParser { | |
| 51 | public: | |
| 52 | // Concatenate LINK environment variable and given arguments and parse them. | |
| 50 | 53 | llvm::opt::InputArgList parseLINK(std::vector<const char *> Args); |
| 51 | 54 | |
| 52 | 55 | // Tokenizes a given string and then parses as command line options. |
| 53 | 56 | llvm::opt::InputArgList parse(StringRef S) { return parse(tokenize(S)); } |
| 54 | 57 | |
| 58 | // Tokenizes a given string and then parses as command line options in | |
| 59 | // .drectve section. | |
| 60 | llvm::opt::InputArgList parseDirectives(StringRef S); | |
| 61 | ||
| 55 | 62 | private: |
| 63 | // Parses command line options. | |
| 64 | llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> Args); | |
| 65 | ||
| 56 | 66 | std::vector<const char *> tokenize(StringRef S); |
| 57 | 67 | |
| 58 | std::vector<const char *> replaceResponseFiles(std::vector<const char *>); | |
| 68 | COFFOptTable Table; | |
| 59 | 69 | }; |
| 60 | 70 | |
| 61 | 71 | class LinkerDriver { |
| 62 | 72 | public: |
| 63 | LinkerDriver() { coff::Symtab = &Symtab; } | |
| 64 | 73 | void link(llvm::ArrayRef<const char *> Args); |
| 65 | 74 | |
| 66 | 75 | // Used by the resolver to parse .drectve section contents. |
| ... | ... | @@ -70,10 +79,9 @@ public: |
| 70 | 79 | void enqueueArchiveMember(const Archive::Child &C, StringRef SymName, |
| 71 | 80 | StringRef ParentName); |
| 72 | 81 | |
| 73 | private: | |
| 74 | ArgParser Parser; | |
| 75 | SymbolTable Symtab; | |
| 82 | MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> MB); | |
| 76 | 83 | |
| 84 | private: | |
| 77 | 85 | std::unique_ptr<llvm::TarWriter> Tar; // for /linkrepro |
| 78 | 86 | |
| 79 | 87 | // Opens a file. Path has to be resolved already. |
| ... | ... | @@ -93,7 +101,7 @@ private: |
| 93 | 101 | std::set<std::string> VisitedFiles; |
| 94 | 102 | std::set<std::string> VisitedLibs; |
| 95 | 103 | |
| 96 | SymbolBody *addUndefined(StringRef Sym); | |
| 104 | Symbol *addUndefined(StringRef Sym); | |
| 97 | 105 | StringRef mangle(StringRef Sym); |
| 98 | 106 | |
| 99 | 107 | // Windows specific -- "main" is not the only main function in Windows. |
| ... | ... | @@ -108,12 +116,11 @@ private: |
| 108 | 116 | |
| 109 | 117 | void invokeMSVC(llvm::opt::InputArgList &Args); |
| 110 | 118 | |
| 111 | MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> MB); | |
| 112 | void addBuffer(std::unique_ptr<MemoryBuffer> MB); | |
| 119 | void addBuffer(std::unique_ptr<MemoryBuffer> MB, bool WholeArchive); | |
| 113 | 120 | void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName, |
| 114 | 121 | StringRef ParentName); |
| 115 | 122 | |
| 116 | void enqueuePath(StringRef Path); | |
| 123 | void enqueuePath(StringRef Path, bool WholeArchive); | |
| 117 | 124 | |
| 118 | 125 | void enqueueTask(std::function<void()> Task); |
| 119 | 126 | bool run(); |
| ... | ... | @@ -121,6 +128,8 @@ private: |
| 121 | 128 | std::list<std::function<void()>> TaskQueue; |
| 122 | 129 | std::vector<StringRef> FilePaths; |
| 123 | 130 | std::vector<MemoryBufferRef> Resources; |
| 131 | ||
| 132 | llvm::StringSet<> DirectivesExports; | |
| 124 | 133 | }; |
| 125 | 134 | |
| 126 | 135 | // Functions below this line are defined in DriverUtils.cpp. |
| ... | ... | @@ -145,6 +154,7 @@ void parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major, |
| 145 | 154 | void parseAlternateName(StringRef); |
| 146 | 155 | void parseMerge(StringRef); |
| 147 | 156 | void parseSection(StringRef); |
| 157 | void parseAligncomm(StringRef); | |
| 148 | 158 | |
| 149 | 159 | // Parses a string in the form of "EMBED[,=<integer>]|NO". |
| 150 | 160 | void parseManifest(StringRef Arg); |
| ... | ... | @@ -167,10 +177,8 @@ void assignExportOrdinals(); |
| 167 | 177 | // incompatible objects. |
| 168 | 178 | void checkFailIfMismatch(StringRef Arg); |
| 169 | 179 | |
| 170 | // Convert Windows resource files (.res files) to a .obj file | |
| 171 | // using cvtres.exe. | |
| 172 | std::unique_ptr<MemoryBuffer> | |
| 173 | convertResToCOFF(const std::vector<MemoryBufferRef> &MBs); | |
| 180 | // Convert Windows resource files (.res files) to a .obj file. | |
| 181 | MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> MBs); | |
| 174 | 182 | |
| 175 | 183 | void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects); |
| 176 | 184 |
deps/lld/COFF/DriverUtils.cpp+149-83| ... | ... | @@ -15,9 +15,9 @@ |
| 15 | 15 | |
| 16 | 16 | #include "Config.h" |
| 17 | 17 | #include "Driver.h" |
| 18 | #include "Error.h" | |
| 19 | #include "Memory.h" | |
| 20 | 18 | #include "Symbols.h" |
| 19 | #include "lld/Common/ErrorHandler.h" | |
| 20 | #include "lld/Common/Memory.h" | |
| 21 | 21 | #include "llvm/ADT/Optional.h" |
| 22 | 22 | #include "llvm/ADT/StringSwitch.h" |
| 23 | 23 | #include "llvm/BinaryFormat/COFF.h" |
| ... | ... | @@ -32,12 +32,11 @@ |
| 32 | 32 | #include "llvm/Support/Process.h" |
| 33 | 33 | #include "llvm/Support/Program.h" |
| 34 | 34 | #include "llvm/Support/raw_ostream.h" |
| 35 | #include "llvm/WindowsManifest/WindowsManifestMerger.h" | |
| 35 | 36 | #include <memory> |
| 36 | 37 | |
| 37 | 38 | using namespace llvm::COFF; |
| 38 | 39 | using namespace llvm; |
| 39 | using llvm::cl::ExpandResponseFiles; | |
| 40 | using llvm::cl::TokenizeWindowsCommandLine; | |
| 41 | 40 | using llvm::sys::Process; |
| 42 | 41 | |
| 43 | 42 | namespace lld { |
| ... | ... | @@ -58,7 +57,7 @@ public: |
| 58 | 57 | void run() { |
| 59 | 58 | ErrorOr<std::string> ExeOrErr = sys::findProgramByName(Prog); |
| 60 | 59 | if (auto EC = ExeOrErr.getError()) |
| 61 | fatal(EC, "unable to find " + Prog + " in PATH: "); | |
| 60 | fatal("unable to find " + Prog + " in PATH: " + EC.message()); | |
| 62 | 61 | StringRef Exe = Saver.save(*ExeOrErr); |
| 63 | 62 | Args.insert(Args.begin(), Exe); |
| 64 | 63 | |
| ... | ... | @@ -221,6 +220,22 @@ void parseSection(StringRef S) { |
| 221 | 220 | Config->Section[Name] = parseSectionAttributes(Attrs); |
| 222 | 221 | } |
| 223 | 222 | |
| 223 | // Parses /aligncomm option argument. | |
| 224 | void parseAligncomm(StringRef S) { | |
| 225 | StringRef Name, Align; | |
| 226 | std::tie(Name, Align) = S.split(','); | |
| 227 | if (Name.empty() || Align.empty()) { | |
| 228 | error("/aligncomm: invalid argument: " + S); | |
| 229 | return; | |
| 230 | } | |
| 231 | int V; | |
| 232 | if (Align.getAsInteger(0, V)) { | |
| 233 | error("/aligncomm: invalid argument: " + S); | |
| 234 | return; | |
| 235 | } | |
| 236 | Config->AlignComm[Name] = std::max(Config->AlignComm[Name], 1 << V); | |
| 237 | } | |
| 238 | ||
| 224 | 239 | // Parses a string in the form of "EMBED[,=<integer>]|NO". |
| 225 | 240 | // Results are directly written to Config. |
| 226 | 241 | void parseManifest(StringRef Arg) { |
| ... | ... | @@ -273,14 +288,14 @@ public: |
| 273 | 288 | TemporaryFile(StringRef Prefix, StringRef Extn, StringRef Contents = "") { |
| 274 | 289 | SmallString<128> S; |
| 275 | 290 | if (auto EC = sys::fs::createTemporaryFile("lld-" + Prefix, Extn, S)) |
| 276 | fatal(EC, "cannot create a temporary file"); | |
| 291 | fatal("cannot create a temporary file: " + EC.message()); | |
| 277 | 292 | Path = S.str(); |
| 278 | 293 | |
| 279 | 294 | if (!Contents.empty()) { |
| 280 | 295 | std::error_code EC; |
| 281 | 296 | raw_fd_ostream OS(Path, EC, sys::fs::F_None); |
| 282 | 297 | if (EC) |
| 283 | fatal(EC, "failed to open " + Path); | |
| 298 | fatal("failed to open " + Path + ": " + EC.message()); | |
| 284 | 299 | OS << Contents; |
| 285 | 300 | } |
| 286 | 301 | } |
| ... | ... | @@ -302,7 +317,7 @@ public: |
| 302 | 317 | // is called (you cannot remove an opened file on Windows.) |
| 303 | 318 | std::unique_ptr<MemoryBuffer> getMemoryBuffer() { |
| 304 | 319 | // IsVolatileSize=true forces MemoryBuffer to not use mmap(). |
| 305 | return check(MemoryBuffer::getFile(Path, /*FileSize=*/-1, | |
| 320 | return CHECK(MemoryBuffer::getFile(Path, /*FileSize=*/-1, | |
| 306 | 321 | /*RequiresNullTerminator=*/false, |
| 307 | 322 | /*IsVolatileSize=*/true), |
| 308 | 323 | "could not open " + Path); |
| ... | ... | @@ -312,16 +327,9 @@ public: |
| 312 | 327 | }; |
| 313 | 328 | } |
| 314 | 329 | |
| 315 | // Create the default manifest file as a temporary file. | |
| 316 | TemporaryFile createDefaultXml() { | |
| 317 | // Create a temporary file. | |
| 318 | TemporaryFile File("defaultxml", "manifest"); | |
| 319 | ||
| 320 | // Open the temporary file for writing. | |
| 321 | std::error_code EC; | |
| 322 | raw_fd_ostream OS(File.Path, EC, sys::fs::F_Text); | |
| 323 | if (EC) | |
| 324 | fatal(EC, "failed to open " + File.Path); | |
| 330 | static std::string createDefaultXml() { | |
| 331 | std::string Ret; | |
| 332 | raw_string_ostream OS(Ret); | |
| 325 | 333 | |
| 326 | 334 | // Emit the XML. Note that we do *not* verify that the XML attributes are |
| 327 | 335 | // syntactically correct. This is intentional for link.exe compatibility. |
| ... | ... | @@ -337,46 +345,77 @@ TemporaryFile createDefaultXml() { |
| 337 | 345 | << " </requestedPrivileges>\n" |
| 338 | 346 | << " </security>\n" |
| 339 | 347 | << " </trustInfo>\n"; |
| 340 | if (!Config->ManifestDependency.empty()) { | |
| 341 | OS << " <dependency>\n" | |
| 342 | << " <dependentAssembly>\n" | |
| 343 | << " <assemblyIdentity " << Config->ManifestDependency << " />\n" | |
| 344 | << " </dependentAssembly>\n" | |
| 345 | << " </dependency>\n"; | |
| 346 | } | |
| 348 | } | |
| 349 | if (!Config->ManifestDependency.empty()) { | |
| 350 | OS << " <dependency>\n" | |
| 351 | << " <dependentAssembly>\n" | |
| 352 | << " <assemblyIdentity " << Config->ManifestDependency << " />\n" | |
| 353 | << " </dependentAssembly>\n" | |
| 354 | << " </dependency>\n"; | |
| 347 | 355 | } |
| 348 | 356 | OS << "</assembly>\n"; |
| 349 | OS.close(); | |
| 350 | return File; | |
| 357 | return OS.str(); | |
| 351 | 358 | } |
| 352 | 359 | |
| 353 | static std::string readFile(StringRef Path) { | |
| 354 | std::unique_ptr<MemoryBuffer> MB = | |
| 355 | check(MemoryBuffer::getFile(Path), "could not open " + Path); | |
| 356 | return MB->getBuffer(); | |
| 360 | static std::string createManifestXmlWithInternalMt(StringRef DefaultXml) { | |
| 361 | std::unique_ptr<MemoryBuffer> DefaultXmlCopy = | |
| 362 | MemoryBuffer::getMemBufferCopy(DefaultXml); | |
| 363 | ||
| 364 | windows_manifest::WindowsManifestMerger Merger; | |
| 365 | if (auto E = Merger.merge(*DefaultXmlCopy.get())) | |
| 366 | fatal("internal manifest tool failed on default xml: " + | |
| 367 | toString(std::move(E))); | |
| 368 | ||
| 369 | for (StringRef Filename : Config->ManifestInput) { | |
| 370 | std::unique_ptr<MemoryBuffer> Manifest = | |
| 371 | check(MemoryBuffer::getFile(Filename)); | |
| 372 | if (auto E = Merger.merge(*Manifest.get())) | |
| 373 | fatal("internal manifest tool failed on file " + Filename + ": " + | |
| 374 | toString(std::move(E))); | |
| 375 | } | |
| 376 | ||
| 377 | return Merger.getMergedManifest().get()->getBuffer(); | |
| 357 | 378 | } |
| 358 | 379 | |
| 359 | static std::string createManifestXml() { | |
| 360 | // Create the default manifest file. | |
| 361 | TemporaryFile File1 = createDefaultXml(); | |
| 362 | if (Config->ManifestInput.empty()) | |
| 363 | return readFile(File1.Path); | |
| 380 | static std::string createManifestXmlWithExternalMt(StringRef DefaultXml) { | |
| 381 | // Create the default manifest file as a temporary file. | |
| 382 | TemporaryFile Default("defaultxml", "manifest"); | |
| 383 | std::error_code EC; | |
| 384 | raw_fd_ostream OS(Default.Path, EC, sys::fs::F_Text); | |
| 385 | if (EC) | |
| 386 | fatal("failed to open " + Default.Path + ": " + EC.message()); | |
| 387 | OS << DefaultXml; | |
| 388 | OS.close(); | |
| 364 | 389 | |
| 365 | // If manifest files are supplied by the user using /MANIFESTINPUT | |
| 366 | // option, we need to merge them with the default manifest. | |
| 367 | TemporaryFile File2("user", "manifest"); | |
| 390 | // Merge user-supplied manifests if they are given. Since libxml2 is not | |
| 391 | // enabled, we must shell out to Microsoft's mt.exe tool. | |
| 392 | TemporaryFile User("user", "manifest"); | |
| 368 | 393 | |
| 369 | 394 | Executor E("mt.exe"); |
| 370 | 395 | E.add("/manifest"); |
| 371 | E.add(File1.Path); | |
| 396 | E.add(Default.Path); | |
| 372 | 397 | for (StringRef Filename : Config->ManifestInput) { |
| 373 | 398 | E.add("/manifest"); |
| 374 | 399 | E.add(Filename); |
| 375 | 400 | } |
| 376 | 401 | E.add("/nologo"); |
| 377 | E.add("/out:" + StringRef(File2.Path)); | |
| 402 | E.add("/out:" + StringRef(User.Path)); | |
| 378 | 403 | E.run(); |
| 379 | return readFile(File2.Path); | |
| 404 | ||
| 405 | return CHECK(MemoryBuffer::getFile(User.Path), "could not open " + User.Path) | |
| 406 | .get() | |
| 407 | ->getBuffer(); | |
| 408 | } | |
| 409 | ||
| 410 | static std::string createManifestXml() { | |
| 411 | std::string DefaultXml = createDefaultXml(); | |
| 412 | if (Config->ManifestInput.empty()) | |
| 413 | return DefaultXml; | |
| 414 | ||
| 415 | if (windows_manifest::isAvailable()) | |
| 416 | return createManifestXmlWithInternalMt(DefaultXml); | |
| 417 | ||
| 418 | return createManifestXmlWithExternalMt(DefaultXml); | |
| 380 | 419 | } |
| 381 | 420 | |
| 382 | 421 | static std::unique_ptr<MemoryBuffer> |
| ... | ... | @@ -386,7 +425,8 @@ createMemoryBufferForManifestRes(size_t ManifestSize) { |
| 386 | 425 | sizeof(object::WinResHeaderPrefix) + sizeof(object::WinResIDs) + |
| 387 | 426 | sizeof(object::WinResHeaderSuffix) + ManifestSize, |
| 388 | 427 | object::WIN_RES_DATA_ALIGNMENT); |
| 389 | return MemoryBuffer::getNewMemBuffer(ResSize); | |
| 428 | return MemoryBuffer::getNewMemBuffer(ResSize, | |
| 429 | Config->OutputFile + ".manifest.res"); | |
| 390 | 430 | } |
| 391 | 431 | |
| 392 | 432 | static void writeResFileHeader(char *&Buf) { |
| ... | ... | @@ -444,7 +484,7 @@ void createSideBySideManifest() { |
| 444 | 484 | std::error_code EC; |
| 445 | 485 | raw_fd_ostream Out(Path, EC, sys::fs::F_Text); |
| 446 | 486 | if (EC) |
| 447 | fatal(EC, "failed to create manifest"); | |
| 487 | fatal("failed to create manifest: " + EC.message()); | |
| 448 | 488 | Out << createManifestXml(); |
| 449 | 489 | } |
| 450 | 490 | |
| ... | ... | @@ -459,12 +499,12 @@ Export parseExport(StringRef Arg) { |
| 459 | 499 | if (E.Name.empty()) |
| 460 | 500 | goto err; |
| 461 | 501 | |
| 462 | if (E.Name.find('=') != StringRef::npos) { | |
| 502 | if (E.Name.contains('=')) { | |
| 463 | 503 | StringRef X, Y; |
| 464 | 504 | std::tie(X, Y) = E.Name.split("="); |
| 465 | 505 | |
| 466 | 506 | // If "<name>=<dllname>.<name>". |
| 467 | if (Y.find(".") != StringRef::npos) { | |
| 507 | if (Y.contains(".")) { | |
| 468 | 508 | E.Name = X; |
| 469 | 509 | E.ForwardTo = Y; |
| 470 | 510 | return E; |
| ... | ... | @@ -534,7 +574,7 @@ void fixupExports() { |
| 534 | 574 | } |
| 535 | 575 | |
| 536 | 576 | for (Export &E : Config->Exports) { |
| 537 | SymbolBody *Sym = E.Sym; | |
| 577 | Symbol *Sym = E.Sym; | |
| 538 | 578 | if (!E.ForwardTo.empty() || !Sym) { |
| 539 | 579 | E.SymbolName = E.Name; |
| 540 | 580 | } else { |
| ... | ... | @@ -554,7 +594,7 @@ void fixupExports() { |
| 554 | 594 | } |
| 555 | 595 | |
| 556 | 596 | // Uniquefy by name. |
| 557 | std::map<StringRef, Export *> Map; | |
| 597 | DenseMap<StringRef, Export *> Map(Config->Exports.size()); | |
| 558 | 598 | std::vector<Export> V; |
| 559 | 599 | for (Export &E : Config->Exports) { |
| 560 | 600 | auto Pair = Map.insert(std::make_pair(E.ExportName, &E)); |
| ... | ... | @@ -601,10 +641,8 @@ void checkFailIfMismatch(StringRef Arg) { |
| 601 | 641 | Config->MustMatch[K] = V; |
| 602 | 642 | } |
| 603 | 643 | |
| 604 | // Convert Windows resource files (.res files) to a .obj file | |
| 605 | // using cvtres.exe. | |
| 606 | std::unique_ptr<MemoryBuffer> | |
| 607 | convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) { | |
| 644 | // Convert Windows resource files (.res files) to a .obj file. | |
| 645 | MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> MBs) { | |
| 608 | 646 | object::WindowsResourceParser Parser; |
| 609 | 647 | |
| 610 | 648 | for (MemoryBufferRef MB : MBs) { |
| ... | ... | @@ -613,14 +651,17 @@ convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) { |
| 613 | 651 | if (!RF) |
| 614 | 652 | fatal("cannot compile non-resource file as resource"); |
| 615 | 653 | if (auto EC = Parser.parse(RF)) |
| 616 | fatal(EC, "failed to parse .res file"); | |
| 654 | fatal("failed to parse .res file: " + toString(std::move(EC))); | |
| 617 | 655 | } |
| 618 | 656 | |
| 619 | 657 | Expected<std::unique_ptr<MemoryBuffer>> E = |
| 620 | 658 | llvm::object::writeWindowsResourceCOFF(Config->Machine, Parser); |
| 621 | 659 | if (!E) |
| 622 | fatal(errorToErrorCode(E.takeError()), "failed to write .res to COFF"); | |
| 623 | return std::move(E.get()); | |
| 660 | fatal("failed to write .res to COFF: " + toString(E.takeError())); | |
| 661 | ||
| 662 | MemoryBufferRef MBRef = **E; | |
| 663 | make<std::unique_ptr<MemoryBuffer>>(std::move(*E)); // take ownership | |
| 664 | return MBRef; | |
| 624 | 665 | } |
| 625 | 666 | |
| 626 | 667 | // Run MSVC link.exe for given in-memory object files. |
| ... | ... | @@ -651,7 +692,7 @@ void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects) { |
| 651 | 692 | #undef PREFIX |
| 652 | 693 | |
| 653 | 694 | // Create table mapping all options defined in Options.td |
| 654 | static const llvm::opt::OptTable::Info infoTable[] = { | |
| 695 | static const llvm::opt::OptTable::Info InfoTable[] = { | |
| 655 | 696 | #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ |
| 656 | 697 | {X1, X2, X10, X11, OPT_##ID, llvm::opt::Option::KIND##Class, \ |
| 657 | 698 | X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12}, |
| ... | ... | @@ -659,30 +700,65 @@ static const llvm::opt::OptTable::Info infoTable[] = { |
| 659 | 700 | #undef OPTION |
| 660 | 701 | }; |
| 661 | 702 | |
| 662 | class COFFOptTable : public llvm::opt::OptTable { | |
| 663 | public: | |
| 664 | COFFOptTable() : OptTable(infoTable, true) {} | |
| 665 | }; | |
| 703 | COFFOptTable::COFFOptTable() : OptTable(InfoTable, true) {} | |
| 666 | 704 | |
| 667 | // Parses a given list of options. | |
| 668 | opt::InputArgList ArgParser::parse(ArrayRef<const char *> ArgsArr) { | |
| 669 | // First, replace respnose files (@<file>-style options). | |
| 670 | std::vector<const char *> Argv = replaceResponseFiles(ArgsArr); | |
| 705 | static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) { | |
| 706 | if (auto *Arg = Args.getLastArg(OPT_rsp_quoting)) { | |
| 707 | StringRef S = Arg->getValue(); | |
| 708 | if (S != "windows" && S != "posix") | |
| 709 | error("invalid response file quoting: " + S); | |
| 710 | if (S == "windows") | |
| 711 | return cl::TokenizeWindowsCommandLine; | |
| 712 | return cl::TokenizeGNUCommandLine; | |
| 713 | } | |
| 714 | // The COFF linker always defaults to Windows quoting. | |
| 715 | return cl::TokenizeWindowsCommandLine; | |
| 716 | } | |
| 671 | 717 | |
| 718 | // Parses a given list of options. | |
| 719 | opt::InputArgList ArgParser::parse(ArrayRef<const char *> Argv) { | |
| 672 | 720 | // Make InputArgList from string vectors. |
| 673 | COFFOptTable Table; | |
| 674 | 721 | unsigned MissingIndex; |
| 675 | 722 | unsigned MissingCount; |
| 676 | opt::InputArgList Args = Table.ParseArgs(Argv, MissingIndex, MissingCount); | |
| 723 | SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size()); | |
| 724 | ||
| 725 | // 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 | |
| 727 | // --rsp-quoting. | |
| 728 | opt::InputArgList Args = Table.ParseArgs(Vec, MissingIndex, MissingCount); | |
| 729 | ||
| 730 | // Expand response files (arguments in the form of @<filename>) | |
| 731 | // and then parse the argument again. | |
| 732 | cl::ExpandResponseFiles(Saver, getQuotingStyle(Args), Vec); | |
| 733 | Args = Table.ParseArgs(Vec, MissingIndex, MissingCount); | |
| 677 | 734 | |
| 678 | 735 | // Print the real command line if response files are expanded. |
| 679 | if (Args.hasArg(OPT_verbose) && ArgsArr.size() != Argv.size()) { | |
| 736 | if (Args.hasArg(OPT_verbose) && Argv.size() != Vec.size()) { | |
| 680 | 737 | std::string Msg = "Command line:"; |
| 681 | for (const char *S : Argv) | |
| 738 | for (const char *S : Vec) | |
| 682 | 739 | Msg += " " + std::string(S); |
| 683 | 740 | message(Msg); |
| 684 | 741 | } |
| 685 | 742 | |
| 743 | // Handle /WX early since it converts missing argument warnings to errors. | |
| 744 | errorHandler().FatalWarnings = Args.hasFlag(OPT_WX, OPT_WX_no, false); | |
| 745 | ||
| 746 | if (MissingCount) | |
| 747 | fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument"); | |
| 748 | for (auto *Arg : Args.filtered(OPT_UNKNOWN)) | |
| 749 | warn("ignoring unknown argument: " + Arg->getSpelling()); | |
| 750 | return Args; | |
| 751 | } | |
| 752 | ||
| 753 | // Tokenizes and parses a given string as command line in .drective section. | |
| 754 | opt::InputArgList ArgParser::parseDirectives(StringRef S) { | |
| 755 | // Make InputArgList from string vectors. | |
| 756 | unsigned MissingIndex; | |
| 757 | unsigned MissingCount; | |
| 758 | ||
| 759 | opt::InputArgList Args = | |
| 760 | Table.ParseArgs(tokenize(S), MissingIndex, MissingCount); | |
| 761 | ||
| 686 | 762 | if (MissingCount) |
| 687 | 763 | fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument"); |
| 688 | 764 | for (auto *Arg : Args.filtered(OPT_UNKNOWN)) |
| ... | ... | @@ -693,17 +769,17 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> ArgsArr) { |
| 693 | 769 | // link.exe has an interesting feature. If LINK or _LINK_ environment |
| 694 | 770 | // variables exist, their contents are handled as command line strings. |
| 695 | 771 | // So you can pass extra arguments using them. |
| 696 | opt::InputArgList ArgParser::parseLINK(std::vector<const char *> Args) { | |
| 772 | opt::InputArgList ArgParser::parseLINK(std::vector<const char *> Argv) { | |
| 697 | 773 | // Concatenate LINK env and command line arguments, and then parse them. |
| 698 | 774 | if (Optional<std::string> S = Process::GetEnv("LINK")) { |
| 699 | 775 | std::vector<const char *> V = tokenize(*S); |
| 700 | Args.insert(Args.begin(), V.begin(), V.end()); | |
| 776 | Argv.insert(Argv.begin(), V.begin(), V.end()); | |
| 701 | 777 | } |
| 702 | 778 | if (Optional<std::string> S = Process::GetEnv("_LINK_")) { |
| 703 | 779 | std::vector<const char *> V = tokenize(*S); |
| 704 | Args.insert(Args.begin(), V.begin(), V.end()); | |
| 780 | Argv.insert(Argv.begin(), V.begin(), V.end()); | |
| 705 | 781 | } |
| 706 | return parse(Args); | |
| 782 | return parse(Argv); | |
| 707 | 783 | } |
| 708 | 784 | |
| 709 | 785 | std::vector<const char *> ArgParser::tokenize(StringRef S) { |
| ... | ... | @@ -712,18 +788,8 @@ std::vector<const char *> ArgParser::tokenize(StringRef S) { |
| 712 | 788 | return std::vector<const char *>(Tokens.begin(), Tokens.end()); |
| 713 | 789 | } |
| 714 | 790 | |
| 715 | // Creates a new command line by replacing options starting with '@' | |
| 716 | // character. '@<filename>' is replaced by the file's contents. | |
| 717 | std::vector<const char *> | |
| 718 | ArgParser::replaceResponseFiles(std::vector<const char *> Argv) { | |
| 719 | SmallVector<const char *, 256> Tokens(Argv.data(), Argv.data() + Argv.size()); | |
| 720 | ExpandResponseFiles(Saver, TokenizeWindowsCommandLine, Tokens); | |
| 721 | return std::vector<const char *>(Tokens.begin(), Tokens.end()); | |
| 722 | } | |
| 723 | ||
| 724 | 791 | void printHelp(const char *Argv0) { |
| 725 | COFFOptTable Table; | |
| 726 | Table.PrintHelp(outs(), Argv0, "LLVM Linker", false); | |
| 792 | COFFOptTable().PrintHelp(outs(), Argv0, "LLVM Linker", false); | |
| 727 | 793 | } |
| 728 | 794 | |
| 729 | 795 | } // namespace coff |
deps/lld/COFF/Error.cpp deleted-115| ... | ... | @@ -1,115 +0,0 @@ |
| 1 | //===- Error.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 "Error.h" | |
| 11 | #include "Config.h" | |
| 12 | ||
| 13 | #include "llvm/ADT/Twine.h" | |
| 14 | #include "llvm/Support/Error.h" | |
| 15 | #include "llvm/Support/ManagedStatic.h" | |
| 16 | #include "llvm/Support/Process.h" | |
| 17 | #include "llvm/Support/raw_ostream.h" | |
| 18 | #include <mutex> | |
| 19 | ||
| 20 | #if !defined(_MSC_VER) && !defined(__MINGW32__) | |
| 21 | #include <unistd.h> | |
| 22 | #endif | |
| 23 | ||
| 24 | using namespace llvm; | |
| 25 | ||
| 26 | namespace lld { | |
| 27 | // The functions defined in this file can be called from multiple threads, | |
| 28 | // but outs() or errs() are not thread-safe. We protect them using a mutex. | |
| 29 | static std::mutex Mu; | |
| 30 | ||
| 31 | namespace coff { | |
| 32 | uint64_t ErrorCount; | |
| 33 | raw_ostream *ErrorOS; | |
| 34 | ||
| 35 | LLVM_ATTRIBUTE_NORETURN void exitLld(int Val) { | |
| 36 | // Dealloc/destroy ManagedStatic variables before calling | |
| 37 | // _exit(). In a non-LTO build, this is a nop. In an LTO | |
| 38 | // build allows us to get the output of -time-passes. | |
| 39 | llvm_shutdown(); | |
| 40 | ||
| 41 | outs().flush(); | |
| 42 | errs().flush(); | |
| 43 | _exit(Val); | |
| 44 | } | |
| 45 | ||
| 46 | static void print(StringRef S, raw_ostream::Colors C) { | |
| 47 | *ErrorOS << Config->Argv[0] << ": "; | |
| 48 | if (Config->ColorDiagnostics) { | |
| 49 | ErrorOS->changeColor(C, true); | |
| 50 | *ErrorOS << S; | |
| 51 | ErrorOS->resetColor(); | |
| 52 | } else { | |
| 53 | *ErrorOS << S; | |
| 54 | } | |
| 55 | } | |
| 56 | ||
| 57 | void log(const Twine &Msg) { | |
| 58 | if (Config->Verbose) { | |
| 59 | std::lock_guard<std::mutex> Lock(Mu); | |
| 60 | outs() << Config->Argv[0] << ": " << Msg << "\n"; | |
| 61 | outs().flush(); | |
| 62 | } | |
| 63 | } | |
| 64 | ||
| 65 | void message(const Twine &Msg) { | |
| 66 | std::lock_guard<std::mutex> Lock(Mu); | |
| 67 | outs() << Msg << "\n"; | |
| 68 | outs().flush(); | |
| 69 | } | |
| 70 | ||
| 71 | void error(const Twine &Msg) { | |
| 72 | std::lock_guard<std::mutex> Lock(Mu); | |
| 73 | ||
| 74 | if (Config->ErrorLimit == 0 || ErrorCount < Config->ErrorLimit) { | |
| 75 | print("error: ", raw_ostream::RED); | |
| 76 | *ErrorOS << Msg << "\n"; | |
| 77 | } else if (ErrorCount == Config->ErrorLimit) { | |
| 78 | print("error: ", raw_ostream::RED); | |
| 79 | *ErrorOS << "too many errors emitted, stopping now" | |
| 80 | << " (use /ERRORLIMIT:0 to see all errors)\n"; | |
| 81 | if (Config->CanExitEarly) | |
| 82 | exitLld(1); | |
| 83 | } | |
| 84 | ||
| 85 | ++ErrorCount; | |
| 86 | } | |
| 87 | ||
| 88 | void fatal(const Twine &Msg) { | |
| 89 | if (Config->ColorDiagnostics) { | |
| 90 | errs().changeColor(raw_ostream::RED, /*bold=*/true); | |
| 91 | errs() << "error: "; | |
| 92 | errs().resetColor(); | |
| 93 | } else { | |
| 94 | errs() << "error: "; | |
| 95 | } | |
| 96 | errs() << Msg << "\n"; | |
| 97 | exitLld(1); | |
| 98 | } | |
| 99 | ||
| 100 | void fatal(std::error_code EC, const Twine &Msg) { | |
| 101 | fatal(Msg + ": " + EC.message()); | |
| 102 | } | |
| 103 | ||
| 104 | void fatal(llvm::Error &Err, const Twine &Msg) { | |
| 105 | fatal(errorToErrorCode(std::move(Err)), Msg); | |
| 106 | } | |
| 107 | ||
| 108 | void warn(const Twine &Msg) { | |
| 109 | std::lock_guard<std::mutex> Lock(Mu); | |
| 110 | print("warning: ", raw_ostream::MAGENTA); | |
| 111 | *ErrorOS << Msg << "\n"; | |
| 112 | } | |
| 113 | ||
| 114 | } // namespace coff | |
| 115 | } // namespace lld |
deps/lld/COFF/Error.h deleted-64| ... | ... | @@ -1,64 +0,0 @@ |
| 1 | //===- Error.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_ERROR_H | |
| 11 | #define LLD_COFF_ERROR_H | |
| 12 | ||
| 13 | #include "lld/Core/LLVM.h" | |
| 14 | #include "llvm/Support/Error.h" | |
| 15 | ||
| 16 | namespace lld { | |
| 17 | namespace coff { | |
| 18 | ||
| 19 | extern uint64_t ErrorCount; | |
| 20 | extern llvm::raw_ostream *ErrorOS; | |
| 21 | ||
| 22 | void log(const Twine &Msg); | |
| 23 | void message(const Twine &Msg); | |
| 24 | void warn(const Twine &Msg); | |
| 25 | void error(const Twine &Msg); | |
| 26 | LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg); | |
| 27 | LLVM_ATTRIBUTE_NORETURN void fatal(std::error_code EC, const Twine &Prefix); | |
| 28 | LLVM_ATTRIBUTE_NORETURN void fatal(llvm::Error &Err, const Twine &Prefix); | |
| 29 | ||
| 30 | LLVM_ATTRIBUTE_NORETURN void exitLld(int Val); | |
| 31 | ||
| 32 | template <class T> T check(ErrorOr<T> V, const Twine &Prefix) { | |
| 33 | if (auto EC = V.getError()) | |
| 34 | fatal(EC, Prefix); | |
| 35 | return std::move(*V); | |
| 36 | } | |
| 37 | ||
| 38 | template <class T> T check(Expected<T> E, const Twine &Prefix) { | |
| 39 | if (llvm::Error Err = E.takeError()) | |
| 40 | fatal(Err, Prefix); | |
| 41 | return std::move(*E); | |
| 42 | } | |
| 43 | ||
| 44 | template <class T> T check(ErrorOr<T> EO) { | |
| 45 | if (!EO) | |
| 46 | fatal(EO.getError().message()); | |
| 47 | return std::move(*EO); | |
| 48 | } | |
| 49 | ||
| 50 | template <class T> T check(Expected<T> E) { | |
| 51 | if (!E) { | |
| 52 | std::string Buf; | |
| 53 | llvm::raw_string_ostream OS(Buf); | |
| 54 | logAllUnhandledErrors(E.takeError(), OS, ""); | |
| 55 | OS.flush(); | |
| 56 | fatal(Buf); | |
| 57 | } | |
| 58 | return std::move(*E); | |
| 59 | } | |
| 60 | ||
| 61 | } // namespace coff | |
| 62 | } // namespace lld | |
| 63 | ||
| 64 | #endif |
deps/lld/COFF/ICF.cpp+28-23| ... | ... | @@ -19,8 +19,8 @@ |
| 19 | 19 | //===----------------------------------------------------------------------===// |
| 20 | 20 | |
| 21 | 21 | #include "Chunks.h" |
| 22 | #include "Error.h" | |
| 23 | 22 | #include "Symbols.h" |
| 23 | #include "lld/Common/ErrorHandler.h" | |
| 24 | 24 | #include "llvm/ADT/Hashing.h" |
| 25 | 25 | #include "llvm/Support/Debug.h" |
| 26 | 26 | #include "llvm/Support/Parallel.h" |
| ... | ... | @@ -36,7 +36,7 @@ namespace coff { |
| 36 | 36 | |
| 37 | 37 | class ICF { |
| 38 | 38 | public: |
| 39 | void run(const std::vector<Chunk *> &V); | |
| 39 | void run(ArrayRef<Chunk *> V); | |
| 40 | 40 | |
| 41 | 41 | private: |
| 42 | 42 | void segregate(size_t Begin, size_t End, bool Constant); |
| ... | ... | @@ -61,12 +61,9 @@ private: |
| 61 | 61 | |
| 62 | 62 | // Returns a hash value for S. |
| 63 | 63 | uint32_t ICF::getHash(SectionChunk *C) { |
| 64 | return hash_combine(C->getPermissions(), | |
| 65 | hash_value(C->SectionName), | |
| 66 | C->NumRelocs, | |
| 67 | C->getAlign(), | |
| 68 | uint32_t(C->Header->SizeOfRawData), | |
| 69 | C->Checksum); | |
| 64 | return hash_combine(C->getPermissions(), C->SectionName, C->NumRelocs, | |
| 65 | C->Alignment, uint32_t(C->Header->SizeOfRawData), | |
| 66 | C->Checksum, C->getContents()); | |
| 70 | 67 | } |
| 71 | 68 | |
| 72 | 69 | // Returns true if section S is subject of ICF. |
| ... | ... | @@ -76,12 +73,21 @@ uint32_t ICF::getHash(SectionChunk *C) { |
| 76 | 73 | // 2017) says that /opt:icf folds both functions and read-only data. |
| 77 | 74 | // Despite that, the MSVC linker folds only functions. We found |
| 78 | 75 | // a few instances of programs that are not safe for data merging. |
| 79 | // Therefore, we merge only functions just like the MSVC tool. | |
| 76 | // Therefore, we merge only functions just like the MSVC tool. However, we merge | |
| 77 | // identical .xdata sections, because the address of unwind information is | |
| 78 | // insignificant to the user program and the Visual C++ linker does this. | |
| 80 | 79 | bool ICF::isEligible(SectionChunk *C) { |
| 81 | bool Global = C->Sym && C->Sym->isExternal(); | |
| 82 | bool Executable = C->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_EXECUTE; | |
| 80 | // Non-comdat chunks, dead chunks, and writable chunks are not elegible. | |
| 83 | 81 | bool Writable = C->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_WRITE; |
| 84 | return C->isCOMDAT() && C->isLive() && Global && Executable && !Writable; | |
| 82 | if (!C->isCOMDAT() || !C->isLive() || Writable) | |
| 83 | return false; | |
| 84 | ||
| 85 | // Code sections are eligible. | |
| 86 | if (C->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_EXECUTE) | |
| 87 | return true; | |
| 88 | ||
| 89 | // .xdata unwind info sections are eligble. | |
| 90 | return C->getSectionName().split('$').first == ".xdata"; | |
| 85 | 91 | } |
| 86 | 92 | |
| 87 | 93 | // Split an equivalence class into smaller classes. |
| ... | ... | @@ -122,8 +128,8 @@ bool ICF::equalsConstant(const SectionChunk *A, const SectionChunk *B) { |
| 122 | 128 | R1.VirtualAddress != R2.VirtualAddress) { |
| 123 | 129 | return false; |
| 124 | 130 | } |
| 125 | SymbolBody *B1 = A->File->getSymbolBody(R1.SymbolTableIndex); | |
| 126 | SymbolBody *B2 = B->File->getSymbolBody(R2.SymbolTableIndex); | |
| 131 | Symbol *B1 = A->File->getSymbol(R1.SymbolTableIndex); | |
| 132 | Symbol *B2 = B->File->getSymbol(R2.SymbolTableIndex); | |
| 127 | 133 | if (B1 == B2) |
| 128 | 134 | return true; |
| 129 | 135 | if (auto *D1 = dyn_cast<DefinedRegular>(B1)) |
| ... | ... | @@ -137,19 +143,17 @@ bool ICF::equalsConstant(const SectionChunk *A, const SectionChunk *B) { |
| 137 | 143 | |
| 138 | 144 | // Compare section attributes and contents. |
| 139 | 145 | return A->getPermissions() == B->getPermissions() && |
| 140 | A->SectionName == B->SectionName && | |
| 141 | A->getAlign() == B->getAlign() && | |
| 146 | A->SectionName == B->SectionName && A->Alignment == B->Alignment && | |
| 142 | 147 | A->Header->SizeOfRawData == B->Header->SizeOfRawData && |
| 143 | A->Checksum == B->Checksum && | |
| 144 | A->getContents() == B->getContents(); | |
| 148 | A->Checksum == B->Checksum && A->getContents() == B->getContents(); | |
| 145 | 149 | } |
| 146 | 150 | |
| 147 | 151 | // Compare "moving" part of two sections, namely relocation targets. |
| 148 | 152 | bool ICF::equalsVariable(const SectionChunk *A, const SectionChunk *B) { |
| 149 | 153 | // Compare relocations. |
| 150 | 154 | auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) { |
| 151 | SymbolBody *B1 = A->File->getSymbolBody(R1.SymbolTableIndex); | |
| 152 | SymbolBody *B2 = B->File->getSymbolBody(R2.SymbolTableIndex); | |
| 155 | Symbol *B1 = A->File->getSymbol(R1.SymbolTableIndex); | |
| 156 | Symbol *B2 = B->File->getSymbol(R2.SymbolTableIndex); | |
| 153 | 157 | if (B1 == B2) |
| 154 | 158 | return true; |
| 155 | 159 | if (auto *D1 = dyn_cast<DefinedRegular>(B1)) |
| ... | ... | @@ -202,7 +206,7 @@ void ICF::forEachClass(std::function<void(size_t, size_t)> Fn) { |
| 202 | 206 | // Merge identical COMDAT sections. |
| 203 | 207 | // Two sections are considered the same if their section headers, |
| 204 | 208 | // contents and relocations are all the same. |
| 205 | void ICF::run(const std::vector<Chunk *> &Vec) { | |
| 209 | void ICF::run(ArrayRef<Chunk *> Vec) { | |
| 206 | 210 | // Collect only mergeable sections and group by hash value. |
| 207 | 211 | uint32_t NextId = 1; |
| 208 | 212 | for (Chunk *C : Vec) { |
| ... | ... | @@ -215,9 +219,10 @@ void ICF::run(const std::vector<Chunk *> &Vec) { |
| 215 | 219 | } |
| 216 | 220 | |
| 217 | 221 | // Initially, we use hash values to partition sections. |
| 218 | for (SectionChunk *SC : Chunks) | |
| 222 | for_each(parallel::par, Chunks.begin(), Chunks.end(), [&](SectionChunk *SC) { | |
| 219 | 223 | // Set MSB to 1 to avoid collisions with non-hash classs. |
| 220 | 224 | SC->Class[0] = getHash(SC) | (1 << 31); |
| 225 | }); | |
| 221 | 226 | |
| 222 | 227 | // From now on, sections in Chunks are ordered so that sections in |
| 223 | 228 | // the same group are consecutive in the vector. |
| ... | ... | @@ -252,7 +257,7 @@ void ICF::run(const std::vector<Chunk *> &Vec) { |
| 252 | 257 | } |
| 253 | 258 | |
| 254 | 259 | // Entry point to ICF. |
| 255 | void doICF(const std::vector<Chunk *> &Chunks) { ICF().run(Chunks); } | |
| 260 | void doICF(ArrayRef<Chunk *> Chunks) { ICF().run(Chunks); } | |
| 256 | 261 | |
| 257 | 262 | } // namespace coff |
| 258 | 263 | } // namespace lld |
deps/lld/COFF/InputFiles.cpp+244-150| ... | ... | @@ -11,10 +11,10 @@ |
| 11 | 11 | #include "Chunks.h" |
| 12 | 12 | #include "Config.h" |
| 13 | 13 | #include "Driver.h" |
| 14 | #include "Error.h" | |
| 15 | #include "Memory.h" | |
| 16 | 14 | #include "SymbolTable.h" |
| 17 | 15 | #include "Symbols.h" |
| 16 | #include "lld/Common/ErrorHandler.h" | |
| 17 | #include "lld/Common/Memory.h" | |
| 18 | 18 | #include "llvm-c/lto.h" |
| 19 | 19 | #include "llvm/ADT/SmallVector.h" |
| 20 | 20 | #include "llvm/ADT/Triple.h" |
| ... | ... | @@ -43,14 +43,18 @@ using llvm::support::ulittle32_t; |
| 43 | 43 | namespace lld { |
| 44 | 44 | namespace coff { |
| 45 | 45 | |
| 46 | std::vector<ObjFile *> ObjFile::Instances; | |
| 47 | std::vector<ImportFile *> ImportFile::Instances; | |
| 48 | std::vector<BitcodeFile *> BitcodeFile::Instances; | |
| 49 | ||
| 46 | 50 | /// Checks that Source is compatible with being a weak alias to Target. |
| 47 | 51 | /// If Source is Undefined and has no weak alias set, makes it a weak |
| 48 | 52 | /// alias to Target. |
| 49 | 53 | static void checkAndSetWeakAlias(SymbolTable *Symtab, InputFile *F, |
| 50 | SymbolBody *Source, SymbolBody *Target) { | |
| 54 | Symbol *Source, Symbol *Target) { | |
| 51 | 55 | if (auto *U = dyn_cast<Undefined>(Source)) { |
| 52 | 56 | if (U->WeakAlias && U->WeakAlias != Target) |
| 53 | Symtab->reportDuplicate(Source->symbol(), F); | |
| 57 | Symtab->reportDuplicate(Source, F); | |
| 54 | 58 | U->WeakAlias = Target; |
| 55 | 59 | } |
| 56 | 60 | } |
| ... | ... | @@ -59,7 +63,7 @@ ArchiveFile::ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {} |
| 59 | 63 | |
| 60 | 64 | void ArchiveFile::parse() { |
| 61 | 65 | // Parse a MemoryBufferRef as an archive file. |
| 62 | File = check(Archive::create(MB), toString(this)); | |
| 66 | File = CHECK(Archive::create(MB), this); | |
| 63 | 67 | |
| 64 | 68 | // Read the symbol table to construct Lazy objects. |
| 65 | 69 | for (const Archive::Symbol &Sym : File->symbols()) |
| ... | ... | @@ -69,7 +73,7 @@ void ArchiveFile::parse() { |
| 69 | 73 | // Returns a buffer pointing to a member file containing a given symbol. |
| 70 | 74 | void ArchiveFile::addMember(const Archive::Symbol *Sym) { |
| 71 | 75 | const Archive::Child &C = |
| 72 | check(Sym->getMember(), | |
| 76 | CHECK(Sym->getMember(), | |
| 73 | 77 | "could not get the member for symbol " + Sym->getName()); |
| 74 | 78 | |
| 75 | 79 | // Return an empty buffer if we have already returned the same buffer. |
| ... | ... | @@ -79,9 +83,28 @@ void ArchiveFile::addMember(const Archive::Symbol *Sym) { |
| 79 | 83 | Driver->enqueueArchiveMember(C, Sym->getName(), getName()); |
| 80 | 84 | } |
| 81 | 85 | |
| 82 | void ObjectFile::parse() { | |
| 86 | std::vector<MemoryBufferRef> getArchiveMembers(Archive *File) { | |
| 87 | std::vector<MemoryBufferRef> V; | |
| 88 | Error Err = Error::success(); | |
| 89 | for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) { | |
| 90 | Archive::Child C = | |
| 91 | CHECK(COrErr, | |
| 92 | File->getFileName() + ": could not get the child of the archive"); | |
| 93 | MemoryBufferRef MBRef = | |
| 94 | CHECK(C.getMemoryBufferRef(), | |
| 95 | File->getFileName() + | |
| 96 | ": could not get the buffer for a child of the archive"); | |
| 97 | V.push_back(MBRef); | |
| 98 | } | |
| 99 | if (Err) | |
| 100 | fatal(File->getFileName() + | |
| 101 | ": Archive::children failed: " + toString(std::move(Err))); | |
| 102 | return V; | |
| 103 | } | |
| 104 | ||
| 105 | void ObjFile::parse() { | |
| 83 | 106 | // Parse a memory buffer as a COFF file. |
| 84 | std::unique_ptr<Binary> Bin = check(createBinary(MB), toString(this)); | |
| 107 | std::unique_ptr<Binary> Bin = CHECK(createBinary(MB), this); | |
| 85 | 108 | |
| 86 | 109 | if (auto *Obj = dyn_cast<COFFObjectFile>(Bin.get())) { |
| 87 | 110 | Bin.release(); |
| ... | ... | @@ -93,114 +116,184 @@ void ObjectFile::parse() { |
| 93 | 116 | // Read section and symbol tables. |
| 94 | 117 | initializeChunks(); |
| 95 | 118 | initializeSymbols(); |
| 96 | initializeSEH(); | |
| 97 | 119 | } |
| 98 | 120 | |
| 99 | void ObjectFile::initializeChunks() { | |
| 121 | // We set SectionChunk pointers in the SparseChunks vector to this value | |
| 122 | // temporarily to mark comdat sections as having an unknown resolution. As we | |
| 123 | // walk the object file's symbol table, once we visit either a leader symbol or | |
| 124 | // an associative section definition together with the parent comdat's leader, | |
| 125 | // we set the pointer to either nullptr (to mark the section as discarded) or a | |
| 126 | // valid SectionChunk for that section. | |
| 127 | static SectionChunk *const PendingComdat = reinterpret_cast<SectionChunk *>(1); | |
| 128 | ||
| 129 | void ObjFile::initializeChunks() { | |
| 100 | 130 | uint32_t NumSections = COFFObj->getNumberOfSections(); |
| 101 | 131 | Chunks.reserve(NumSections); |
| 102 | 132 | SparseChunks.resize(NumSections + 1); |
| 103 | 133 | for (uint32_t I = 1; I < NumSections + 1; ++I) { |
| 104 | 134 | const coff_section *Sec; |
| 105 | StringRef Name; | |
| 106 | 135 | if (auto EC = COFFObj->getSection(I, Sec)) |
| 107 | fatal(EC, "getSection failed: #" + Twine(I)); | |
| 108 | if (auto EC = COFFObj->getSectionName(Sec, Name)) | |
| 109 | fatal(EC, "getSectionName failed: #" + Twine(I)); | |
| 110 | if (Name == ".sxdata") { | |
| 111 | SXData = Sec; | |
| 112 | continue; | |
| 113 | } | |
| 114 | if (Name == ".drectve") { | |
| 115 | ArrayRef<uint8_t> Data; | |
| 116 | COFFObj->getSectionContents(Sec, Data); | |
| 117 | Directives = std::string((const char *)Data.data(), Data.size()); | |
| 118 | continue; | |
| 119 | } | |
| 136 | fatal("getSection failed: #" + Twine(I) + ": " + EC.message()); | |
| 120 | 137 | |
| 121 | // Object files may have DWARF debug info or MS CodeView debug info | |
| 122 | // (or both). | |
| 123 | // | |
| 124 | // DWARF sections don't need any special handling from the perspective | |
| 125 | // of the linker; they are just a data section containing relocations. | |
| 126 | // We can just link them to complete debug info. | |
| 127 | // | |
| 128 | // CodeView needs a linker support. We need to interpret and debug | |
| 129 | // info, and then write it to a separate .pdb file. | |
| 130 | ||
| 131 | // Ignore debug info unless /debug is given. | |
| 132 | if (!Config->Debug && Name.startswith(".debug")) | |
| 133 | continue; | |
| 134 | ||
| 135 | if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE) | |
| 136 | continue; | |
| 137 | auto *C = make<SectionChunk>(this, Sec); | |
| 138 | ||
| 139 | // CodeView sections are stored to a different vector because they are not | |
| 140 | // linked in the regular manner. | |
| 141 | if (C->isCodeView()) | |
| 142 | DebugChunks.push_back(C); | |
| 138 | if (Sec->Characteristics & IMAGE_SCN_LNK_COMDAT) | |
| 139 | SparseChunks[I] = PendingComdat; | |
| 143 | 140 | else |
| 144 | Chunks.push_back(C); | |
| 141 | SparseChunks[I] = readSection(I, nullptr); | |
| 142 | } | |
| 143 | } | |
| 145 | 144 | |
| 146 | SparseChunks[I] = C; | |
| 145 | SectionChunk *ObjFile::readSection(uint32_t SectionNumber, | |
| 146 | const coff_aux_section_definition *Def) { | |
| 147 | const coff_section *Sec; | |
| 148 | StringRef Name; | |
| 149 | if (auto EC = COFFObj->getSection(SectionNumber, Sec)) | |
| 150 | fatal("getSection failed: #" + Twine(SectionNumber) + ": " + EC.message()); | |
| 151 | if (auto EC = COFFObj->getSectionName(Sec, Name)) | |
| 152 | fatal("getSectionName failed: #" + Twine(SectionNumber) + ": " + | |
| 153 | EC.message()); | |
| 154 | if (Name == ".sxdata") { | |
| 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") { | |
| 164 | ArrayRef<uint8_t> Data; | |
| 165 | COFFObj->getSectionContents(Sec, Data); | |
| 166 | Directives = std::string((const char *)Data.data(), Data.size()); | |
| 167 | return nullptr; | |
| 147 | 168 | } |
| 169 | ||
| 170 | // Object files may have DWARF debug info or MS CodeView debug info | |
| 171 | // (or both). | |
| 172 | // | |
| 173 | // DWARF sections don't need any special handling from the perspective | |
| 174 | // of the linker; they are just a data section containing relocations. | |
| 175 | // We can just link them to complete debug info. | |
| 176 | // | |
| 177 | // CodeView needs a linker support. We need to interpret and debug | |
| 178 | // info, and then write it to a separate .pdb file. | |
| 179 | ||
| 180 | // Ignore debug info unless /debug is given. | |
| 181 | if (!Config->Debug && Name.startswith(".debug")) | |
| 182 | return nullptr; | |
| 183 | ||
| 184 | if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE) | |
| 185 | return nullptr; | |
| 186 | auto *C = make<SectionChunk>(this, Sec); | |
| 187 | if (Def) | |
| 188 | C->Checksum = Def->CheckSum; | |
| 189 | ||
| 190 | // CodeView sections are stored to a different vector because they are not | |
| 191 | // linked in the regular manner. | |
| 192 | if (C->isCodeView()) | |
| 193 | DebugChunks.push_back(C); | |
| 194 | else | |
| 195 | Chunks.push_back(C); | |
| 196 | ||
| 197 | return C; | |
| 148 | 198 | } |
| 149 | 199 | |
| 150 | void ObjectFile::initializeSymbols() { | |
| 200 | void ObjFile::readAssociativeDefinition( | |
| 201 | COFFSymbolRef Sym, const coff_aux_section_definition *Def) { | |
| 202 | SectionChunk *Parent = SparseChunks[Def->getNumber(Sym.isBigObj())]; | |
| 203 | ||
| 204 | // If the parent is pending, it probably means that its section definition | |
| 205 | // appears after us in the symbol table. Leave the associated section as | |
| 206 | // pending; we will handle it during the second pass in initializeSymbols(). | |
| 207 | if (Parent == PendingComdat) | |
| 208 | return; | |
| 209 | ||
| 210 | // Check whether the parent is prevailing. If it is, so are we, and we read | |
| 211 | // the section; otherwise mark it as discarded. | |
| 212 | int32_t SectionNumber = Sym.getSectionNumber(); | |
| 213 | if (Parent) { | |
| 214 | SparseChunks[SectionNumber] = readSection(SectionNumber, Def); | |
| 215 | if (SparseChunks[SectionNumber]) | |
| 216 | Parent->addAssociative(SparseChunks[SectionNumber]); | |
| 217 | } else { | |
| 218 | SparseChunks[SectionNumber] = nullptr; | |
| 219 | } | |
| 220 | } | |
| 221 | ||
| 222 | Symbol *ObjFile::createRegular(COFFSymbolRef Sym) { | |
| 223 | SectionChunk *SC = SparseChunks[Sym.getSectionNumber()]; | |
| 224 | if (Sym.isExternal()) { | |
| 225 | StringRef Name; | |
| 226 | COFFObj->getSymbolName(Sym, Name); | |
| 227 | if (SC) | |
| 228 | return Symtab->addRegular(this, Name, Sym.getGeneric(), SC); | |
| 229 | return Symtab->addUndefined(Name, this, false); | |
| 230 | } | |
| 231 | if (SC) | |
| 232 | return make<DefinedRegular>(this, /*Name*/ "", false, | |
| 233 | /*IsExternal*/ false, Sym.getGeneric(), SC); | |
| 234 | return nullptr; | |
| 235 | } | |
| 236 | ||
| 237 | void ObjFile::initializeSymbols() { | |
| 151 | 238 | uint32_t NumSymbols = COFFObj->getNumberOfSymbols(); |
| 152 | SymbolBodies.reserve(NumSymbols); | |
| 153 | SparseSymbolBodies.resize(NumSymbols); | |
| 239 | Symbols.resize(NumSymbols); | |
| 154 | 240 | |
| 155 | SmallVector<std::pair<SymbolBody *, uint32_t>, 8> WeakAliases; | |
| 156 | int32_t LastSectionNumber = 0; | |
| 241 | SmallVector<std::pair<Symbol *, uint32_t>, 8> WeakAliases; | |
| 242 | std::vector<uint32_t> PendingIndexes; | |
| 243 | PendingIndexes.reserve(NumSymbols); | |
| 244 | ||
| 245 | std::vector<const coff_aux_section_definition *> ComdatDefs( | |
| 246 | COFFObj->getNumberOfSections() + 1); | |
| 157 | 247 | |
| 158 | 248 | for (uint32_t I = 0; I < NumSymbols; ++I) { |
| 159 | // Get a COFFSymbolRef object. | |
| 160 | ErrorOr<COFFSymbolRef> SymOrErr = COFFObj->getSymbol(I); | |
| 161 | if (!SymOrErr) | |
| 162 | fatal(SymOrErr.getError(), "broken object file: " + toString(this)); | |
| 163 | COFFSymbolRef Sym = *SymOrErr; | |
| 164 | ||
| 165 | const void *AuxP = nullptr; | |
| 166 | if (Sym.getNumberOfAuxSymbols()) | |
| 167 | AuxP = COFFObj->getSymbol(I + 1)->getRawPtr(); | |
| 168 | bool IsFirst = (LastSectionNumber != Sym.getSectionNumber()); | |
| 169 | ||
| 170 | SymbolBody *Body = nullptr; | |
| 171 | if (Sym.isUndefined()) { | |
| 172 | Body = createUndefined(Sym); | |
| 173 | } else if (Sym.isWeakExternal()) { | |
| 174 | Body = createUndefined(Sym); | |
| 175 | uint32_t TagIndex = | |
| 176 | static_cast<const coff_aux_weak_external *>(AuxP)->TagIndex; | |
| 177 | WeakAliases.emplace_back(Body, TagIndex); | |
| 249 | COFFSymbolRef COFFSym = check(COFFObj->getSymbol(I)); | |
| 250 | if (COFFSym.isUndefined()) { | |
| 251 | Symbols[I] = createUndefined(COFFSym); | |
| 252 | } else if (COFFSym.isWeakExternal()) { | |
| 253 | Symbols[I] = createUndefined(COFFSym); | |
| 254 | uint32_t TagIndex = COFFSym.getAux<coff_aux_weak_external>()->TagIndex; | |
| 255 | WeakAliases.emplace_back(Symbols[I], TagIndex); | |
| 256 | } else if (Optional<Symbol *> OptSym = createDefined(COFFSym, ComdatDefs)) { | |
| 257 | Symbols[I] = *OptSym; | |
| 178 | 258 | } else { |
| 179 | Body = createDefined(Sym, AuxP, IsFirst); | |
| 180 | } | |
| 181 | if (Body) { | |
| 182 | SymbolBodies.push_back(Body); | |
| 183 | SparseSymbolBodies[I] = Body; | |
| 259 | // createDefined() returns None if a symbol belongs to a section that | |
| 260 | // was pending at the point when the symbol was read. This can happen in | |
| 261 | // two cases: | |
| 262 | // 1) section definition symbol for a comdat leader; | |
| 263 | // 2) symbol belongs to a comdat section associated with a section whose | |
| 264 | // section definition symbol appears later in the symbol table. | |
| 265 | // In both of these cases, we can expect the section to be resolved by | |
| 266 | // the time we finish visiting the remaining symbols in the symbol | |
| 267 | // table. So we postpone the handling of this symbol until that time. | |
| 268 | PendingIndexes.push_back(I); | |
| 184 | 269 | } |
| 185 | I += Sym.getNumberOfAuxSymbols(); | |
| 186 | LastSectionNumber = Sym.getSectionNumber(); | |
| 270 | I += COFFSym.getNumberOfAuxSymbols(); | |
| 271 | } | |
| 272 | ||
| 273 | for (uint32_t I : PendingIndexes) { | |
| 274 | COFFSymbolRef Sym = check(COFFObj->getSymbol(I)); | |
| 275 | if (auto *Def = Sym.getSectionDefinition()) | |
| 276 | if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) | |
| 277 | readAssociativeDefinition(Sym, Def); | |
| 278 | Symbols[I] = createRegular(Sym); | |
| 187 | 279 | } |
| 188 | 280 | |
| 189 | 281 | for (auto &KV : WeakAliases) { |
| 190 | SymbolBody *Sym = KV.first; | |
| 282 | Symbol *Sym = KV.first; | |
| 191 | 283 | uint32_t Idx = KV.second; |
| 192 | checkAndSetWeakAlias(Symtab, this, Sym, SparseSymbolBodies[Idx]); | |
| 284 | checkAndSetWeakAlias(Symtab, this, Sym, Symbols[Idx]); | |
| 193 | 285 | } |
| 194 | 286 | } |
| 195 | 287 | |
| 196 | SymbolBody *ObjectFile::createUndefined(COFFSymbolRef Sym) { | |
| 288 | Symbol *ObjFile::createUndefined(COFFSymbolRef Sym) { | |
| 197 | 289 | StringRef Name; |
| 198 | 290 | COFFObj->getSymbolName(Sym, Name); |
| 199 | return Symtab->addUndefined(Name, this, Sym.isWeakExternal())->body(); | |
| 291 | return Symtab->addUndefined(Name, this, Sym.isWeakExternal()); | |
| 200 | 292 | } |
| 201 | 293 | |
| 202 | SymbolBody *ObjectFile::createDefined(COFFSymbolRef Sym, const void *AuxP, | |
| 203 | bool IsFirst) { | |
| 294 | Optional<Symbol *> ObjFile::createDefined( | |
| 295 | COFFSymbolRef Sym, | |
| 296 | std::vector<const coff_aux_section_definition *> &ComdatDefs) { | |
| 204 | 297 | StringRef Name; |
| 205 | 298 | if (Sym.isCommon()) { |
| 206 | 299 | auto *C = make<CommonChunk>(Sym); |
| ... | ... | @@ -208,7 +301,7 @@ SymbolBody *ObjectFile::createDefined(COFFSymbolRef Sym, const void *AuxP, |
| 208 | 301 | COFFObj->getSymbolName(Sym, Name); |
| 209 | 302 | Symbol *S = |
| 210 | 303 | Symtab->addCommon(this, Name, Sym.getValue(), Sym.getGeneric(), C); |
| 211 | return S->body(); | |
| 304 | return S; | |
| 212 | 305 | } |
| 213 | 306 | if (Sym.isAbsolute()) { |
| 214 | 307 | COFFObj->getSymbolName(Sym, Name); |
| ... | ... | @@ -222,7 +315,7 @@ SymbolBody *ObjectFile::createDefined(COFFSymbolRef Sym, const void *AuxP, |
| 222 | 315 | return nullptr; |
| 223 | 316 | } |
| 224 | 317 | if (Sym.isExternal()) |
| 225 | return Symtab->addAbsolute(Name, Sym)->body(); | |
| 318 | return Symtab->addAbsolute(Name, Sym); | |
| 226 | 319 | else |
| 227 | 320 | return make<DefinedAbsolute>(Name, Sym); |
| 228 | 321 | } |
| ... | ... | @@ -239,54 +332,49 @@ SymbolBody *ObjectFile::createDefined(COFFSymbolRef Sym, const void *AuxP, |
| 239 | 332 | if ((uint32_t)SectionNumber >= SparseChunks.size()) |
| 240 | 333 | fatal("broken object file: " + toString(this)); |
| 241 | 334 | |
| 242 | // Nothing else to do without a section chunk. | |
| 243 | auto *SC = cast_or_null<SectionChunk>(SparseChunks[SectionNumber]); | |
| 244 | if (!SC) | |
| 245 | return nullptr; | |
| 246 | ||
| 247 | // Handle section definitions | |
| 248 | if (IsFirst && AuxP) { | |
| 249 | auto *Aux = reinterpret_cast<const coff_aux_section_definition *>(AuxP); | |
| 250 | if (Aux->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) | |
| 251 | if (auto *ParentSC = cast_or_null<SectionChunk>( | |
| 252 | SparseChunks[Aux->getNumber(Sym.isBigObj())])) { | |
| 253 | ParentSC->addAssociative(SC); | |
| 254 | // If we already discarded the parent, discard the child. | |
| 255 | if (ParentSC->isDiscarded()) | |
| 256 | SC->markDiscarded(); | |
| 257 | } | |
| 258 | SC->Checksum = Aux->CheckSum; | |
| 335 | // Handle comdat leader symbols. | |
| 336 | if (const coff_aux_section_definition *Def = ComdatDefs[SectionNumber]) { | |
| 337 | ComdatDefs[SectionNumber] = nullptr; | |
| 338 | Symbol *Leader; | |
| 339 | bool Prevailing; | |
| 340 | if (Sym.isExternal()) { | |
| 341 | COFFObj->getSymbolName(Sym, Name); | |
| 342 | std::tie(Leader, Prevailing) = | |
| 343 | Symtab->addComdat(this, Name, Sym.getGeneric()); | |
| 344 | } else { | |
| 345 | Leader = make<DefinedRegular>(this, /*Name*/ "", false, | |
| 346 | /*IsExternal*/ false, Sym.getGeneric()); | |
| 347 | Prevailing = true; | |
| 348 | } | |
| 349 | if (Prevailing) { | |
| 350 | SectionChunk *C = readSection(SectionNumber, Def); | |
| 351 | SparseChunks[SectionNumber] = C; | |
| 352 | C->Sym = cast<DefinedRegular>(Leader); | |
| 353 | cast<DefinedRegular>(Leader)->Data = &C->Repl; | |
| 354 | } else { | |
| 355 | SparseChunks[SectionNumber] = nullptr; | |
| 356 | } | |
| 357 | return Leader; | |
| 259 | 358 | } |
| 260 | 359 | |
| 261 | DefinedRegular *B; | |
| 262 | if (Sym.isExternal()) { | |
| 263 | COFFObj->getSymbolName(Sym, Name); | |
| 264 | Symbol *S = | |
| 265 | Symtab->addRegular(this, Name, SC->isCOMDAT(), Sym.getGeneric(), SC); | |
| 266 | B = cast<DefinedRegular>(S->body()); | |
| 267 | } else | |
| 268 | B = make<DefinedRegular>(this, /*Name*/ "", SC->isCOMDAT(), | |
| 269 | /*IsExternal*/ false, Sym.getGeneric(), SC); | |
| 270 | if (SC->isCOMDAT() && Sym.getValue() == 0 && !AuxP) | |
| 271 | SC->setSymbol(B); | |
| 272 | ||
| 273 | return B; | |
| 274 | } | |
| 360 | // Read associative section definitions and prepare to handle the comdat | |
| 361 | // leader symbol by setting the section's ComdatDefs pointer if we encounter a | |
| 362 | // non-associative comdat. | |
| 363 | if (SparseChunks[SectionNumber] == PendingComdat) { | |
| 364 | if (auto *Def = Sym.getSectionDefinition()) { | |
| 365 | if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) | |
| 366 | readAssociativeDefinition(Sym, Def); | |
| 367 | else | |
| 368 | ComdatDefs[SectionNumber] = Def; | |
| 369 | } | |
| 370 | } | |
| 275 | 371 | |
| 276 | void ObjectFile::initializeSEH() { | |
| 277 | if (!SEHCompat || !SXData) | |
| 278 | return; | |
| 279 | ArrayRef<uint8_t> A; | |
| 280 | COFFObj->getSectionContents(SXData, A); | |
| 281 | if (A.size() % 4 != 0) | |
| 282 | fatal(".sxdata must be an array of symbol table indices"); | |
| 283 | auto *I = reinterpret_cast<const ulittle32_t *>(A.data()); | |
| 284 | auto *E = reinterpret_cast<const ulittle32_t *>(A.data() + A.size()); | |
| 285 | for (; I != E; ++I) | |
| 286 | SEHandlers.insert(SparseSymbolBodies[*I]); | |
| 372 | if (SparseChunks[SectionNumber] == PendingComdat) | |
| 373 | return None; | |
| 374 | return createRegular(Sym); | |
| 287 | 375 | } |
| 288 | 376 | |
| 289 | MachineTypes ObjectFile::getMachineType() { | |
| 377 | MachineTypes ObjFile::getMachineType() { | |
| 290 | 378 | if (COFFObj) |
| 291 | 379 | return static_cast<MachineTypes>(COFFObj->getMachine()); |
| 292 | 380 | return IMAGE_FILE_MACHINE_UNKNOWN; |
| ... | ... | @@ -332,26 +420,27 @@ void ImportFile::parse() { |
| 332 | 420 | this->Hdr = Hdr; |
| 333 | 421 | ExternalName = ExtName; |
| 334 | 422 | |
| 335 | ImpSym = cast<DefinedImportData>( | |
| 336 | Symtab->addImportData(ImpName, this)->body()); | |
| 423 | ImpSym = Symtab->addImportData(ImpName, this); | |
| 424 | ||
| 337 | 425 | if (Hdr->getType() == llvm::COFF::IMPORT_CONST) |
| 338 | ConstSym = | |
| 339 | cast<DefinedImportData>(Symtab->addImportData(Name, this)->body()); | |
| 426 | static_cast<void>(Symtab->addImportData(Name, this)); | |
| 340 | 427 | |
| 341 | 428 | // If type is function, we need to create a thunk which jump to an |
| 342 | 429 | // address pointed by the __imp_ symbol. (This allows you to call |
| 343 | 430 | // DLL functions just like regular non-DLL functions.) |
| 344 | if (Hdr->getType() != llvm::COFF::IMPORT_CODE) | |
| 345 | return; | |
| 346 | ThunkSym = cast<DefinedImportThunk>( | |
| 347 | Symtab->addImportThunk(Name, ImpSym, Hdr->Machine)->body()); | |
| 431 | if (Hdr->getType() == llvm::COFF::IMPORT_CODE) | |
| 432 | ThunkSym = Symtab->addImportThunk(Name, ImpSym, Hdr->Machine); | |
| 348 | 433 | } |
| 349 | 434 | |
| 350 | 435 | void BitcodeFile::parse() { |
| 351 | 436 | Obj = check(lto::InputFile::create(MemoryBufferRef( |
| 352 | 437 | MB.getBuffer(), Saver.save(ParentName + MB.getBufferIdentifier())))); |
| 438 | std::vector<std::pair<Symbol *, bool>> Comdat(Obj->getComdatTable().size()); | |
| 439 | for (size_t I = 0; I != Obj->getComdatTable().size(); ++I) | |
| 440 | Comdat[I] = Symtab->addComdat(this, Saver.save(Obj->getComdatTable()[I])); | |
| 353 | 441 | for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) { |
| 354 | 442 | StringRef SymName = Saver.save(ObjSym.getName()); |
| 443 | int ComdatIndex = ObjSym.getComdatIndex(); | |
| 355 | 444 | Symbol *Sym; |
| 356 | 445 | if (ObjSym.isUndefined()) { |
| 357 | 446 | Sym = Symtab->addUndefined(SymName, this, false); |
| ... | ... | @@ -361,13 +450,19 @@ void BitcodeFile::parse() { |
| 361 | 450 | // Weak external. |
| 362 | 451 | Sym = Symtab->addUndefined(SymName, this, true); |
| 363 | 452 | std::string Fallback = ObjSym.getCOFFWeakExternalFallback(); |
| 364 | SymbolBody *Alias = Symtab->addUndefined(Saver.save(Fallback)); | |
| 365 | checkAndSetWeakAlias(Symtab, this, Sym->body(), Alias); | |
| 453 | Symbol *Alias = Symtab->addUndefined(Saver.save(Fallback)); | |
| 454 | checkAndSetWeakAlias(Symtab, this, Sym, Alias); | |
| 455 | } else if (ComdatIndex != -1) { | |
| 456 | if (SymName == Obj->getComdatTable()[ComdatIndex]) | |
| 457 | Sym = Comdat[ComdatIndex].first; | |
| 458 | else if (Comdat[ComdatIndex].second) | |
| 459 | Sym = Symtab->addRegular(this, SymName); | |
| 460 | else | |
| 461 | Sym = Symtab->addUndefined(SymName, this, false); | |
| 366 | 462 | } else { |
| 367 | bool IsCOMDAT = ObjSym.getComdatIndex() != -1; | |
| 368 | Sym = Symtab->addRegular(this, SymName, IsCOMDAT); | |
| 463 | Sym = Symtab->addRegular(this, SymName); | |
| 369 | 464 | } |
| 370 | SymbolBodies.push_back(Sym->body()); | |
| 465 | SymbolBodies.push_back(Sym); | |
| 371 | 466 | } |
| 372 | 467 | Directives = Obj->getCOFFLinkerOpts(); |
| 373 | 468 | } |
| ... | ... | @@ -398,14 +493,13 @@ static StringRef getBasename(StringRef Path) { |
| 398 | 493 | } |
| 399 | 494 | |
| 400 | 495 | // Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)". |
| 401 | std::string lld::toString(coff::InputFile *File) { | |
| 496 | std::string lld::toString(const coff::InputFile *File) { | |
| 402 | 497 | if (!File) |
| 403 | return "(internal)"; | |
| 498 | return "<internal>"; | |
| 404 | 499 | if (File->ParentName.empty()) |
| 405 | return File->getName().lower(); | |
| 500 | return File->getName(); | |
| 406 | 501 | |
| 407 | std::string Res = | |
| 408 | (getBasename(File->ParentName) + "(" + getBasename(File->getName()) + ")") | |
| 409 | .str(); | |
| 410 | return StringRef(Res).lower(); | |
| 502 | return (getBasename(File->ParentName) + "(" + getBasename(File->getName()) + | |
| 503 | ")") | |
| 504 | .str(); | |
| 411 | 505 | } |
deps/lld/COFF/InputFiles.h+41-29| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | #define LLD_COFF_INPUT_FILES_H |
| 12 | 12 | |
| 13 | 13 | #include "Config.h" |
| 14 | #include "lld/Core/LLVM.h" | |
| 14 | #include "lld/Common/LLVM.h" | |
| 15 | 15 | #include "llvm/ADT/ArrayRef.h" |
| 16 | 16 | #include "llvm/ADT/DenseSet.h" |
| 17 | 17 | #include "llvm/LTO/LTO.h" |
| ... | ... | @@ -31,6 +31,8 @@ class DbiModuleDescriptorBuilder; |
| 31 | 31 | namespace lld { |
| 32 | 32 | namespace coff { |
| 33 | 33 | |
| 34 | std::vector<MemoryBufferRef> getArchiveMembers(llvm::object::Archive *File); | |
| 35 | ||
| 34 | 36 | using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN; |
| 35 | 37 | using llvm::COFF::MachineTypes; |
| 36 | 38 | using llvm::object::Archive; |
| ... | ... | @@ -45,8 +47,7 @@ class DefinedImportData; |
| 45 | 47 | class DefinedImportThunk; |
| 46 | 48 | class Lazy; |
| 47 | 49 | class SectionChunk; |
| 48 | struct Symbol; | |
| 49 | class SymbolBody; | |
| 50 | class Symbol; | |
| 50 | 51 | class Undefined; |
| 51 | 52 | |
| 52 | 53 | // The root class of input files. |
| ... | ... | @@ -57,7 +58,7 @@ public: |
| 57 | 58 | virtual ~InputFile() {} |
| 58 | 59 | |
| 59 | 60 | // Returns the filename. |
| 60 | StringRef getName() { return MB.getBufferIdentifier(); } | |
| 61 | StringRef getName() const { return MB.getBufferIdentifier(); } | |
| 61 | 62 | |
| 62 | 63 | // Reads a file (the constructor doesn't do that). |
| 63 | 64 | virtual void parse() = 0; |
| ... | ... | @@ -101,32 +102,34 @@ private: |
| 101 | 102 | }; |
| 102 | 103 | |
| 103 | 104 | // .obj or .o file. This may be a member of an archive file. |
| 104 | class ObjectFile : public InputFile { | |
| 105 | class ObjFile : public InputFile { | |
| 105 | 106 | public: |
| 106 | explicit ObjectFile(MemoryBufferRef M) : InputFile(ObjectKind, M) {} | |
| 107 | explicit ObjFile(MemoryBufferRef M) : InputFile(ObjectKind, M) {} | |
| 107 | 108 | static bool classof(const InputFile *F) { return F->kind() == ObjectKind; } |
| 108 | 109 | void parse() override; |
| 109 | 110 | MachineTypes getMachineType() override; |
| 110 | std::vector<Chunk *> &getChunks() { return Chunks; } | |
| 111 | std::vector<SectionChunk *> &getDebugChunks() { return DebugChunks; } | |
| 112 | std::vector<SymbolBody *> &getSymbols() { return SymbolBodies; } | |
| 111 | ArrayRef<Chunk *> getChunks() { return Chunks; } | |
| 112 | ArrayRef<SectionChunk *> getDebugChunks() { return DebugChunks; } | |
| 113 | ArrayRef<Symbol *> getSymbols() { return Symbols; } | |
| 113 | 114 | |
| 114 | // Returns a SymbolBody object for the SymbolIndex'th symbol in the | |
| 115 | // Returns a Symbol object for the SymbolIndex'th symbol in the | |
| 115 | 116 | // underlying object file. |
| 116 | SymbolBody *getSymbolBody(uint32_t SymbolIndex) { | |
| 117 | return SparseSymbolBodies[SymbolIndex]; | |
| 117 | Symbol *getSymbol(uint32_t SymbolIndex) { | |
| 118 | return Symbols[SymbolIndex]; | |
| 118 | 119 | } |
| 119 | 120 | |
| 120 | 121 | // Returns the underying COFF file. |
| 121 | 122 | COFFObjectFile *getCOFFObj() { return COFFObj.get(); } |
| 122 | 123 | |
| 124 | static std::vector<ObjFile *> Instances; | |
| 125 | ||
| 123 | 126 | // True if this object file is compatible with SEH. |
| 124 | 127 | // COFF-specific and x86-only. |
| 125 | 128 | bool SEHCompat = false; |
| 126 | 129 | |
| 127 | // The list of safe exception handlers listed in .sxdata section. | |
| 130 | // The symbol table indexes of the safe exception handlers. | |
| 128 | 131 | // COFF-specific and x86-only. |
| 129 | std::set<SymbolBody *> SEHandlers; | |
| 132 | ArrayRef<llvm::support::ulittle32_t> SXData; | |
| 130 | 133 | |
| 131 | 134 | // Pointer to the PDB module descriptor builder. Various debug info records |
| 132 | 135 | // will reference object files by "module index", which is here. Things like |
| ... | ... | @@ -137,13 +140,23 @@ public: |
| 137 | 140 | private: |
| 138 | 141 | void initializeChunks(); |
| 139 | 142 | void initializeSymbols(); |
| 140 | void initializeSEH(); | |
| 141 | 143 | |
| 142 | SymbolBody *createDefined(COFFSymbolRef Sym, const void *Aux, bool IsFirst); | |
| 143 | SymbolBody *createUndefined(COFFSymbolRef Sym); | |
| 144 | SectionChunk * | |
| 145 | readSection(uint32_t SectionNumber, | |
| 146 | const llvm::object::coff_aux_section_definition *Def); | |
| 147 | ||
| 148 | void readAssociativeDefinition( | |
| 149 | COFFSymbolRef COFFSym, | |
| 150 | const llvm::object::coff_aux_section_definition *Def); | |
| 151 | ||
| 152 | llvm::Optional<Symbol *> | |
| 153 | createDefined(COFFSymbolRef Sym, | |
| 154 | std::vector<const llvm::object::coff_aux_section_definition *> | |
| 155 | &ComdatDefs); | |
| 156 | Symbol *createRegular(COFFSymbolRef Sym); | |
| 157 | Symbol *createUndefined(COFFSymbolRef Sym); | |
| 144 | 158 | |
| 145 | 159 | std::unique_ptr<COFFObjectFile> COFFObj; |
| 146 | const coff_section *SXData = nullptr; | |
| 147 | 160 | |
| 148 | 161 | // List of all chunks defined by this file. This includes both section |
| 149 | 162 | // chunks and non-section chunks for common symbols. |
| ... | ... | @@ -157,16 +170,13 @@ private: |
| 157 | 170 | // Nonexistent section indices are filled with null pointers. |
| 158 | 171 | // (Because section number is 1-based, the first slot is always a |
| 159 | 172 | // null pointer.) |
| 160 | std::vector<Chunk *> SparseChunks; | |
| 161 | ||
| 162 | // List of all symbols referenced or defined by this file. | |
| 163 | std::vector<SymbolBody *> SymbolBodies; | |
| 173 | std::vector<SectionChunk *> SparseChunks; | |
| 164 | 174 | |
| 165 | // This vector contains the same symbols as SymbolBodies, but they | |
| 166 | // are indexed such that you can get a SymbolBody by symbol | |
| 175 | // This vector contains a list of all symbols defined or referenced by this | |
| 176 | // file. They are indexed such that you can get a Symbol by symbol | |
| 167 | 177 | // index. Nonexistent indices (which are occupied by auxiliary |
| 168 | 178 | // symbols in the real symbol table) are filled with null pointers. |
| 169 | std::vector<SymbolBody *> SparseSymbolBodies; | |
| 179 | std::vector<Symbol *> Symbols; | |
| 170 | 180 | }; |
| 171 | 181 | |
| 172 | 182 | // This type represents import library members that contain DLL names |
| ... | ... | @@ -179,8 +189,9 @@ public: |
| 179 | 189 | |
| 180 | 190 | static bool classof(const InputFile *F) { return F->kind() == ImportKind; } |
| 181 | 191 | |
| 192 | static std::vector<ImportFile *> Instances; | |
| 193 | ||
| 182 | 194 | DefinedImportData *ImpSym = nullptr; |
| 183 | DefinedImportData *ConstSym = nullptr; | |
| 184 | 195 | DefinedImportThunk *ThunkSym = nullptr; |
| 185 | 196 | std::string DLLName; |
| 186 | 197 | |
| ... | ... | @@ -206,18 +217,19 @@ class BitcodeFile : public InputFile { |
| 206 | 217 | public: |
| 207 | 218 | explicit BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {} |
| 208 | 219 | static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; } |
| 209 | std::vector<SymbolBody *> &getSymbols() { return SymbolBodies; } | |
| 220 | ArrayRef<Symbol *> getSymbols() { return SymbolBodies; } | |
| 210 | 221 | MachineTypes getMachineType() override; |
| 222 | static std::vector<BitcodeFile *> Instances; | |
| 211 | 223 | std::unique_ptr<llvm::lto::InputFile> Obj; |
| 212 | 224 | |
| 213 | 225 | private: |
| 214 | 226 | void parse() override; |
| 215 | 227 | |
| 216 | std::vector<SymbolBody *> SymbolBodies; | |
| 228 | std::vector<Symbol *> SymbolBodies; | |
| 217 | 229 | }; |
| 218 | 230 | } // namespace coff |
| 219 | 231 | |
| 220 | std::string toString(coff::InputFile *File); | |
| 232 | std::string toString(const coff::InputFile *File); | |
| 221 | 233 | } // namespace lld |
| 222 | 234 | |
| 223 | 235 | #endif |
deps/lld/COFF/LTO.cpp+42-19| ... | ... | @@ -9,15 +9,16 @@ |
| 9 | 9 | |
| 10 | 10 | #include "LTO.h" |
| 11 | 11 | #include "Config.h" |
| 12 | #include "Error.h" | |
| 13 | 12 | #include "InputFiles.h" |
| 14 | 13 | #include "Symbols.h" |
| 15 | #include "lld/Core/TargetOptionsCommandFlags.h" | |
| 14 | #include "lld/Common/ErrorHandler.h" | |
| 15 | #include "lld/Common/TargetOptionsCommandFlags.h" | |
| 16 | 16 | #include "llvm/ADT/STLExtras.h" |
| 17 | 17 | #include "llvm/ADT/SmallString.h" |
| 18 | 18 | #include "llvm/ADT/StringRef.h" |
| 19 | 19 | #include "llvm/ADT/Twine.h" |
| 20 | 20 | #include "llvm/IR/DiagnosticPrinter.h" |
| 21 | #include "llvm/LTO/Caching.h" | |
| 21 | 22 | #include "llvm/LTO/Config.h" |
| 22 | 23 | #include "llvm/LTO/LTO.h" |
| 23 | 24 | #include "llvm/Object/SymbolicFile.h" |
| ... | ... | @@ -48,10 +49,8 @@ static void diagnosticHandler(const DiagnosticInfo &DI) { |
| 48 | 49 | } |
| 49 | 50 | |
| 50 | 51 | static void checkError(Error E) { |
| 51 | handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) -> Error { | |
| 52 | error(EIB.message()); | |
| 53 | return Error::success(); | |
| 54 | }); | |
| 52 | handleAllErrors(std::move(E), | |
| 53 | [&](ErrorInfoBase &EIB) { error(EIB.message()); }); | |
| 55 | 54 | } |
| 56 | 55 | |
| 57 | 56 | static void saveBuffer(StringRef Buffer, const Twine &Path) { |
| ... | ... | @@ -65,7 +64,13 @@ static void saveBuffer(StringRef Buffer, const Twine &Path) { |
| 65 | 64 | static std::unique_ptr<lto::LTO> createLTO() { |
| 66 | 65 | lto::Config Conf; |
| 67 | 66 | Conf.Options = InitTargetOptionsFromCodeGenFlags(); |
| 68 | Conf.RelocModel = Reloc::PIC_; | |
| 67 | // 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 | |
| 69 | // using the PIC model (see PR34306). | |
| 70 | if (Config->Machine == COFF::IMAGE_FILE_MACHINE_I386) | |
| 71 | Conf.RelocModel = Reloc::Static; | |
| 72 | else | |
| 73 | Conf.RelocModel = Reloc::PIC_; | |
| 69 | 74 | Conf.DisableVerify = true; |
| 70 | 75 | Conf.DiagHandler = diagnosticHandler; |
| 71 | 76 | Conf.OptLevel = Config->LTOOptLevel; |
| ... | ... | @@ -83,20 +88,17 @@ BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {} |
| 83 | 88 | |
| 84 | 89 | BitcodeCompiler::~BitcodeCompiler() = default; |
| 85 | 90 | |
| 86 | static void undefine(Symbol *S) { | |
| 87 | replaceBody<Undefined>(S, S->body()->getName()); | |
| 88 | } | |
| 91 | static void undefine(Symbol *S) { replaceSymbol<Undefined>(S, S->getName()); } | |
| 89 | 92 | |
| 90 | 93 | void BitcodeCompiler::add(BitcodeFile &F) { |
| 91 | 94 | lto::InputFile &Obj = *F.Obj; |
| 92 | 95 | unsigned SymNum = 0; |
| 93 | std::vector<SymbolBody *> SymBodies = F.getSymbols(); | |
| 96 | std::vector<Symbol *> SymBodies = F.getSymbols(); | |
| 94 | 97 | std::vector<lto::SymbolResolution> Resols(SymBodies.size()); |
| 95 | 98 | |
| 96 | 99 | // Provide a resolution to the LTO API for each symbol. |
| 97 | 100 | for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) { |
| 98 | SymbolBody *B = SymBodies[SymNum]; | |
| 99 | Symbol *Sym = B->symbol(); | |
| 101 | Symbol *Sym = SymBodies[SymNum]; | |
| 100 | 102 | lto::SymbolResolution &R = Resols[SymNum]; |
| 101 | 103 | ++SymNum; |
| 102 | 104 | |
| ... | ... | @@ -105,7 +107,7 @@ void BitcodeCompiler::add(BitcodeFile &F) { |
| 105 | 107 | // flags an undefined in IR with a definition in ASM as prevailing. |
| 106 | 108 | // Once IRObjectFile is fixed to report only one symbol this hack can |
| 107 | 109 | // be removed. |
| 108 | R.Prevailing = !ObjSym.isUndefined() && B->getFile() == &F; | |
| 110 | R.Prevailing = !ObjSym.isUndefined() && Sym->getFile() == &F; | |
| 109 | 111 | R.VisibleToRegularObj = Sym->IsUsedInRegularObj; |
| 110 | 112 | if (R.Prevailing) |
| 111 | 113 | undefine(Sym); |
| ... | ... | @@ -118,11 +120,27 @@ void BitcodeCompiler::add(BitcodeFile &F) { |
| 118 | 120 | std::vector<StringRef> BitcodeCompiler::compile() { |
| 119 | 121 | unsigned MaxTasks = LTOObj->getMaxTasks(); |
| 120 | 122 | Buff.resize(MaxTasks); |
| 121 | ||
| 122 | checkError(LTOObj->run([&](size_t Task) { | |
| 123 | return llvm::make_unique<lto::NativeObjectStream>( | |
| 124 | llvm::make_unique<raw_svector_ostream>(Buff[Task])); | |
| 125 | })); | |
| 123 | Files.resize(MaxTasks); | |
| 124 | ||
| 125 | // The /lldltocache option specifies the path to a directory in which to cache | |
| 126 | // native object files for ThinLTO incremental builds. If a path was | |
| 127 | // specified, configure LTO to use it as the cache directory. | |
| 128 | lto::NativeObjectCache Cache; | |
| 129 | if (!Config->LTOCache.empty()) | |
| 130 | Cache = check( | |
| 131 | lto::localCache(Config->LTOCache, | |
| 132 | [&](size_t Task, std::unique_ptr<MemoryBuffer> MB, | |
| 133 | StringRef Path) { Files[Task] = std::move(MB); })); | |
| 134 | ||
| 135 | checkError(LTOObj->run( | |
| 136 | [&](size_t Task) { | |
| 137 | return llvm::make_unique<lto::NativeObjectStream>( | |
| 138 | llvm::make_unique<raw_svector_ostream>(Buff[Task])); | |
| 139 | }, | |
| 140 | Cache)); | |
| 141 | ||
| 142 | if (!Config->LTOCache.empty()) | |
| 143 | pruneCache(Config->LTOCache, Config->LTOCachePolicy); | |
| 126 | 144 | |
| 127 | 145 | std::vector<StringRef> Ret; |
| 128 | 146 | for (unsigned I = 0; I != MaxTasks; ++I) { |
| ... | ... | @@ -136,5 +154,10 @@ std::vector<StringRef> BitcodeCompiler::compile() { |
| 136 | 154 | } |
| 137 | 155 | Ret.emplace_back(Buff[I].data(), Buff[I].size()); |
| 138 | 156 | } |
| 157 | ||
| 158 | for (std::unique_ptr<MemoryBuffer> &File : Files) | |
| 159 | if (File) | |
| 160 | Ret.push_back(File->getBuffer()); | |
| 161 | ||
| 139 | 162 | return Ret; |
| 140 | 163 | } |
deps/lld/COFF/LTO.h+2-1| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | #ifndef LLD_COFF_LTO_H |
| 22 | 22 | #define LLD_COFF_LTO_H |
| 23 | 23 | |
| 24 | #include "lld/Core/LLVM.h" | |
| 24 | #include "lld/Common/LLVM.h" | |
| 25 | 25 | #include "llvm/ADT/SmallString.h" |
| 26 | 26 | #include <memory> |
| 27 | 27 | #include <vector> |
| ... | ... | @@ -49,6 +49,7 @@ public: |
| 49 | 49 | private: |
| 50 | 50 | std::unique_ptr<llvm::lto::LTO> LTOObj; |
| 51 | 51 | std::vector<SmallString<0>> Buff; |
| 52 | std::vector<std::unique_ptr<MemoryBuffer>> Files; | |
| 52 | 53 | }; |
| 53 | 54 | } |
| 54 | 55 | } |
deps/lld/COFF/MapFile.cpp+5-5| ... | ... | @@ -20,11 +20,11 @@ |
| 20 | 20 | //===----------------------------------------------------------------------===// |
| 21 | 21 | |
| 22 | 22 | #include "MapFile.h" |
| 23 | #include "Error.h" | |
| 24 | 23 | #include "SymbolTable.h" |
| 25 | 24 | #include "Symbols.h" |
| 26 | 25 | #include "Writer.h" |
| 27 | 26 | |
| 27 | #include "lld/Common/ErrorHandler.h" | |
| 28 | 28 | #include "llvm/Support/Parallel.h" |
| 29 | 29 | #include "llvm/Support/raw_ostream.h" |
| 30 | 30 | |
| ... | ... | @@ -48,9 +48,9 @@ static std::string indent(int Depth) { return std::string(Depth * 8, ' '); } |
| 48 | 48 | // Returns a list of all symbols that we want to print out. |
| 49 | 49 | static std::vector<DefinedRegular *> getSymbols() { |
| 50 | 50 | std::vector<DefinedRegular *> V; |
| 51 | for (coff::ObjectFile *File : Symtab->ObjectFiles) | |
| 52 | for (SymbolBody *B : File->getSymbols()) | |
| 53 | if (auto *Sym = dyn_cast<DefinedRegular>(B)) | |
| 51 | for (ObjFile *File : ObjFile::Instances) | |
| 52 | for (Symbol *B : File->getSymbols()) | |
| 53 | if (auto *Sym = dyn_cast_or_null<DefinedRegular>(B)) | |
| 54 | 54 | if (Sym && !Sym->getCOFFSymbol().isSectionDefinition()) |
| 55 | 55 | V.push_back(Sym); |
| 56 | 56 | return V; |
| ... | ... | @@ -115,7 +115,7 @@ void coff::writeMapFile(ArrayRef<OutputSection *> OutputSections) { |
| 115 | 115 | if (!SC) |
| 116 | 116 | continue; |
| 117 | 117 | |
| 118 | writeHeader(OS, SC->getRVA(), SC->getSize(), SC->getAlign()); | |
| 118 | writeHeader(OS, SC->getRVA(), SC->getSize(), SC->Alignment); | |
| 119 | 119 | OS << indent(1) << SC->File->getName() << ":(" << SC->getSectionName() |
| 120 | 120 | << ")\n"; |
| 121 | 121 | for (DefinedRegular *Sym : SectionSyms[SC]) |
deps/lld/COFF/MarkLive.cpp+6-12| ... | ... | @@ -18,7 +18,7 @@ namespace coff { |
| 18 | 18 | // Set live bit on for each reachable chunk. Unmarked (unreachable) |
| 19 | 19 | // COMDAT chunks will be ignored by Writer, so they will be excluded |
| 20 | 20 | // from the final output. |
| 21 | void markLive(const std::vector<Chunk *> &Chunks) { | |
| 21 | void markLive(ArrayRef<Chunk *> Chunks) { | |
| 22 | 22 | // We build up a worklist of sections which have been marked as live. We only |
| 23 | 23 | // push into the worklist when we discover an unmarked section, and we mark |
| 24 | 24 | // as we push, so sections never appear twice in the list. |
| ... | ... | @@ -37,7 +37,7 @@ void markLive(const std::vector<Chunk *> &Chunks) { |
| 37 | 37 | Worklist.push_back(C); |
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | auto AddSym = [&](SymbolBody *B) { | |
| 40 | auto AddSym = [&](Symbol *B) { | |
| 41 | 41 | if (auto *Sym = dyn_cast<DefinedRegular>(B)) |
| 42 | 42 | Enqueue(Sym->getChunk()); |
| 43 | 43 | else if (auto *Sym = dyn_cast<DefinedImportData>(B)) |
| ... | ... | @@ -47,23 +47,17 @@ void markLive(const std::vector<Chunk *> &Chunks) { |
| 47 | 47 | }; |
| 48 | 48 | |
| 49 | 49 | // Add GC root chunks. |
| 50 | for (SymbolBody *B : Config->GCRoot) | |
| 50 | for (Symbol *B : Config->GCRoot) | |
| 51 | 51 | AddSym(B); |
| 52 | 52 | |
| 53 | 53 | while (!Worklist.empty()) { |
| 54 | 54 | SectionChunk *SC = Worklist.pop_back_val(); |
| 55 | ||
| 56 | // If this section was discarded, there are relocations referring to | |
| 57 | // discarded sections. Ignore these sections to avoid crashing. They will be | |
| 58 | // diagnosed during relocation processing. | |
| 59 | if (SC->isDiscarded()) | |
| 60 | continue; | |
| 61 | ||
| 62 | 55 | assert(SC->isLive() && "We mark as live when pushing onto the worklist!"); |
| 63 | 56 | |
| 64 | 57 | // Mark all symbols listed in the relocation table for this section. |
| 65 | for (SymbolBody *B : SC->symbols()) | |
| 66 | AddSym(B); | |
| 58 | for (Symbol *B : SC->symbols()) | |
| 59 | if (B) | |
| 60 | AddSym(B); | |
| 67 | 61 | |
| 68 | 62 | // Mark associative sections if any. |
| 69 | 63 | for (SectionChunk *C : SC->children()) |
deps/lld/COFF/Memory.h deleted-52| ... | ... | @@ -1,52 +0,0 @@ |
| 1 | //===- Memory.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 | // See ELF/Memory.h | |
| 11 | // | |
| 12 | //===----------------------------------------------------------------------===// | |
| 13 | ||
| 14 | #ifndef LLD_COFF_MEMORY_H | |
| 15 | #define LLD_COFF_MEMORY_H | |
| 16 | ||
| 17 | #include "llvm/Support/Allocator.h" | |
| 18 | #include "llvm/Support/StringSaver.h" | |
| 19 | #include <vector> | |
| 20 | ||
| 21 | namespace lld { | |
| 22 | namespace coff { | |
| 23 | ||
| 24 | extern llvm::BumpPtrAllocator BAlloc; | |
| 25 | extern llvm::StringSaver Saver; | |
| 26 | ||
| 27 | struct SpecificAllocBase { | |
| 28 | SpecificAllocBase() { Instances.push_back(this); } | |
| 29 | virtual ~SpecificAllocBase() = default; | |
| 30 | virtual void reset() = 0; | |
| 31 | static std::vector<SpecificAllocBase *> Instances; | |
| 32 | }; | |
| 33 | ||
| 34 | template <class T> struct SpecificAlloc : public SpecificAllocBase { | |
| 35 | void reset() override { Alloc.DestroyAll(); } | |
| 36 | llvm::SpecificBumpPtrAllocator<T> Alloc; | |
| 37 | }; | |
| 38 | ||
| 39 | template <typename T, typename... U> T *make(U &&... Args) { | |
| 40 | static SpecificAlloc<T> Alloc; | |
| 41 | return new (Alloc.Alloc.Allocate()) T(std::forward<U>(Args)...); | |
| 42 | } | |
| 43 | ||
| 44 | inline void freeArena() { | |
| 45 | for (SpecificAllocBase *Alloc : SpecificAllocBase::Instances) | |
| 46 | Alloc->reset(); | |
| 47 | BAlloc.Reset(); | |
| 48 | } | |
| 49 | } | |
| 50 | } | |
| 51 | ||
| 52 | #endif |
deps/lld/COFF/MinGW.cpp created+146| ... | ... | @@ -0,0 +1,146 @@ |
| 1 | //===- MinGW.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 "MinGW.h" | |
| 11 | #include "SymbolTable.h" | |
| 12 | #include "lld/Common/ErrorHandler.h" | |
| 13 | #include "llvm/Object/COFF.h" | |
| 14 | #include "llvm/Support/Path.h" | |
| 15 | #include "llvm/Support/raw_ostream.h" | |
| 16 | ||
| 17 | using namespace lld; | |
| 18 | using namespace lld::coff; | |
| 19 | using namespace llvm; | |
| 20 | using namespace llvm::COFF; | |
| 21 | ||
| 22 | AutoExporter::AutoExporter() { | |
| 23 | if (Config->Machine == I386) { | |
| 24 | ExcludeSymbols = { | |
| 25 | "__NULL_IMPORT_DESCRIPTOR", | |
| 26 | "__pei386_runtime_relocator", | |
| 27 | "_do_pseudo_reloc", | |
| 28 | "_impure_ptr", | |
| 29 | "__impure_ptr", | |
| 30 | "__fmode", | |
| 31 | "_environ", | |
| 32 | "___dso_handle", | |
| 33 | // These are the MinGW names that differ from the standard | |
| 34 | // ones (lacking an extra underscore). | |
| 35 | "_DllMain@12", | |
| 36 | "_DllEntryPoint@12", | |
| 37 | "_DllMainCRTStartup@12", | |
| 38 | }; | |
| 39 | } else { | |
| 40 | ExcludeSymbols = { | |
| 41 | "_NULL_IMPORT_DESCRIPTOR", | |
| 42 | "_pei386_runtime_relocator", | |
| 43 | "do_pseudo_reloc", | |
| 44 | "impure_ptr", | |
| 45 | "_impure_ptr", | |
| 46 | "_fmode", | |
| 47 | "environ", | |
| 48 | "__dso_handle", | |
| 49 | // These are the MinGW names that differ from the standard | |
| 50 | // ones (lacking an extra underscore). | |
| 51 | "DllMain", | |
| 52 | "DllEntryPoint", | |
| 53 | "DllMainCRTStartup", | |
| 54 | }; | |
| 55 | } | |
| 56 | ||
| 57 | ExcludeLibs = { | |
| 58 | "libgcc", | |
| 59 | "libgcc_s", | |
| 60 | "libstdc++", | |
| 61 | "libmingw32", | |
| 62 | "libmingwex", | |
| 63 | "libg2c", | |
| 64 | "libsupc++", | |
| 65 | "libobjc", | |
| 66 | "libgcj", | |
| 67 | "libclang_rt.builtins-aarch64", | |
| 68 | "libclang_rt.builtins-arm", | |
| 69 | "libclang_rt.builtins-i386", | |
| 70 | "libclang_rt.builtins-x86_64", | |
| 71 | "libc++", | |
| 72 | "libc++abi", | |
| 73 | "libunwind", | |
| 74 | "libmsvcrt", | |
| 75 | "libucrtbase", | |
| 76 | }; | |
| 77 | ExcludeObjects = { | |
| 78 | "crt0.o", | |
| 79 | "crt1.o", | |
| 80 | "crt1u.o", | |
| 81 | "crt2.o", | |
| 82 | "crt2u.o", | |
| 83 | "dllcrt1.o", | |
| 84 | "dllcrt2.o", | |
| 85 | "gcrt0.o", | |
| 86 | "gcrt1.o", | |
| 87 | "gcrt2.o", | |
| 88 | "crtbegin.o", | |
| 89 | "crtend.o", | |
| 90 | }; | |
| 91 | } | |
| 92 | ||
| 93 | bool AutoExporter::shouldExport(Defined *Sym) const { | |
| 94 | if (!Sym || !Sym->isLive() || !Sym->getChunk()) | |
| 95 | return false; | |
| 96 | ||
| 97 | // Only allow the symbol kinds that make sense to export; in particular, | |
| 98 | // disallow import symbols. | |
| 99 | if (!isa<DefinedRegular>(Sym) && !isa<DefinedCommon>(Sym)) | |
| 100 | return false; | |
| 101 | if (ExcludeSymbols.count(Sym->getName())) | |
| 102 | return false; | |
| 103 | ||
| 104 | // Don't export anything that looks like an import symbol (which also can be | |
| 105 | // a manually defined data symbol with such a name). | |
| 106 | if (Sym->getName().startswith("__imp_")) | |
| 107 | return false; | |
| 108 | ||
| 109 | // If a corresponding __imp_ symbol exists and is defined, don't export it. | |
| 110 | if (Symtab->find(("__imp_" + Sym->getName()).str())) | |
| 111 | return false; | |
| 112 | ||
| 113 | // Check that file is non-null before dereferencing it, symbols not | |
| 114 | // originating in regular object files probably shouldn't be exported. | |
| 115 | if (!Sym->getFile()) | |
| 116 | return false; | |
| 117 | ||
| 118 | StringRef LibName = sys::path::filename(Sym->getFile()->ParentName); | |
| 119 | ||
| 120 | // Drop the file extension. | |
| 121 | LibName = LibName.substr(0, LibName.rfind('.')); | |
| 122 | if (!LibName.empty()) | |
| 123 | return !ExcludeLibs.count(LibName); | |
| 124 | ||
| 125 | StringRef FileName = sys::path::filename(Sym->getFile()->getName()); | |
| 126 | return !ExcludeObjects.count(FileName); | |
| 127 | } | |
| 128 | ||
| 129 | void coff::writeDefFile(StringRef Name) { | |
| 130 | std::error_code EC; | |
| 131 | raw_fd_ostream OS(Name, EC, sys::fs::F_None); | |
| 132 | if (EC) | |
| 133 | fatal("cannot open " + Name + ": " + EC.message()); | |
| 134 | ||
| 135 | OS << "EXPORTS\n"; | |
| 136 | for (Export &E : Config->Exports) { | |
| 137 | OS << " " << E.ExportName << " " | |
| 138 | << "@" << E.Ordinal; | |
| 139 | if (auto *Def = dyn_cast_or_null<Defined>(E.Sym)) { | |
| 140 | if (Def && Def->getChunk() && | |
| 141 | !(Def->getChunk()->getPermissions() & IMAGE_SCN_MEM_EXECUTE)) | |
| 142 | OS << " DATA"; | |
| 143 | } | |
| 144 | OS << "\n"; | |
| 145 | } | |
| 146 | } |
deps/lld/COFF/MinGW.h created+38| ... | ... | @@ -0,0 +1,38 @@ |
| 1 | //===- MinGW.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_MINGW_H | |
| 11 | #define LLD_COFF_MINGW_H | |
| 12 | ||
| 13 | #include "Config.h" | |
| 14 | #include "Symbols.h" | |
| 15 | #include "lld/Common/LLVM.h" | |
| 16 | ||
| 17 | namespace lld { | |
| 18 | namespace coff { | |
| 19 | ||
| 20 | // Logic for deciding what symbols to export, when exporting all | |
| 21 | // symbols for MinGW. | |
| 22 | class AutoExporter { | |
| 23 | public: | |
| 24 | AutoExporter(); | |
| 25 | ||
| 26 | llvm::StringSet<> ExcludeSymbols; | |
| 27 | llvm::StringSet<> ExcludeLibs; | |
| 28 | llvm::StringSet<> ExcludeObjects; | |
| 29 | ||
| 30 | bool shouldExport(Defined *Sym) const; | |
| 31 | }; | |
| 32 | ||
| 33 | void writeDefFile(StringRef Name); | |
| 34 | ||
| 35 | } // namespace coff | |
| 36 | } // namespace lld | |
| 37 | ||
| 38 | #endif |
deps/lld/COFF/Options.td+46-20| ... | ... | @@ -9,13 +9,15 @@ class F<string name> : Flag<["/", "-", "-?"], name>; |
| 9 | 9 | class P<string name, string help> : |
| 10 | 10 | Joined<["/", "-", "-?"], name#":">, HelpText<help>; |
| 11 | 11 | |
| 12 | // Boolean flag suffixed by ":no". | |
| 13 | multiclass B<string name, string help> { | |
| 14 | def "" : F<name>; | |
| 15 | def _no : F<name#":no">, HelpText<help>; | |
| 12 | // Boolean flag which can be suffixed by ":no". Using it unsuffixed turns the | |
| 13 | // flag on and using it suffixed by ":no" turns it off. | |
| 14 | multiclass B<string name, string help_on, string help_off> { | |
| 15 | def "" : F<name>, HelpText<help_on>; | |
| 16 | def _no : F<name#":no">, HelpText<help_off>; | |
| 16 | 17 | } |
| 17 | 18 | |
| 18 | 19 | def align : P<"align", "Section alignment">; |
| 20 | def aligncomm : P<"aligncomm", "Set common symbol alignment">; | |
| 19 | 21 | def alternatename : P<"alternatename", "Define weak alias">; |
| 20 | 22 | def base : P<"base", "Base address of the program">; |
| 21 | 23 | def defaultlib : P<"defaultlib", "Add the library to the list of input files">; |
| ... | ... | @@ -27,9 +29,12 @@ def export : P<"export", "Export a function">; |
| 27 | 29 | // No help text because /failifmismatch is not intended to be used by the user. |
| 28 | 30 | def failifmismatch : P<"failifmismatch", "">; |
| 29 | 31 | def heap : P<"heap", "Size of the heap">; |
| 32 | def ignore : P<"ignore", "Specify warning codes to ignore">; | |
| 30 | 33 | def implib : P<"implib", "Import library name">; |
| 31 | 34 | def libpath : P<"libpath", "Additional library search path">; |
| 32 | 35 | def linkrepro : P<"linkrepro", "Dump linker invocation and input files for debugging">; |
| 36 | def lldltocache : P<"lldltocache", "Path to ThinLTO cached object file directory">; | |
| 37 | def lldltocachepolicy : P<"lldltocachepolicy", "Pruning policy for the ThinLTO cache">; | |
| 33 | 38 | def lldsavetemps : F<"lldsavetemps">, |
| 34 | 39 | HelpText<"Save temporary files instead of deleting them">; |
| 35 | 40 | def machine : P<"machine", "Specify target platform">; |
| ... | ... | @@ -44,6 +49,7 @@ def stack : P<"stack", "Size of the stack">; |
| 44 | 49 | def stub : P<"stub", "Specify DOS stub file">; |
| 45 | 50 | def subsystem : P<"subsystem", "Specify subsystem">; |
| 46 | 51 | 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">; | |
| 47 | 53 | |
| 48 | 54 | def disallowlib : Joined<["/", "-", "-?"], "disallowlib:">, Alias<nodefaultlib>; |
| 49 | 55 | |
| ... | ... | @@ -75,31 +81,53 @@ def profile : F<"profile">; |
| 75 | 81 | def swaprun_cd : F<"swaprun:cd">; |
| 76 | 82 | def swaprun_net : F<"swaprun:net">; |
| 77 | 83 | def verbose : F<"verbose">; |
| 84 | def wholearchive_flag : F<"wholearchive">; | |
| 78 | 85 | |
| 79 | 86 | def force : F<"force">, |
| 80 | 87 | HelpText<"Allow undefined symbols when creating executables">; |
| 81 | 88 | def force_unresolved : F<"force:unresolved">; |
| 89 | defm WX : B<"WX", "Treat warnings as errors", "Don't treat warnings as errors">; | |
| 82 | 90 | |
| 83 | defm allowbind: B<"allowbind", "Disable DLL binding">; | |
| 84 | defm allowisolation : B<"allowisolation", "Set NO_ISOLATION bit">; | |
| 91 | defm allowbind : B<"allowbind", "Enable DLL binding (default)", | |
| 92 | "Disable DLL binding">; | |
| 93 | defm allowisolation : B<"allowisolation", "Enable DLL isolation (default)", | |
| 94 | "Disable DLL isolation">; | |
| 85 | 95 | defm appcontainer : B<"appcontainer", |
| 86 | "Image can only be run in an app container">; | |
| 87 | defm dynamicbase : B<"dynamicbase", | |
| 88 | "Disable address space layout randomization">; | |
| 89 | defm fixed : B<"fixed", "Enable base relocations">; | |
| 90 | defm highentropyva : B<"highentropyva", "Set HIGH_ENTROPY_VA bit">; | |
| 91 | defm largeaddressaware : B<"largeaddressaware", "Disable large addresses">; | |
| 92 | defm nxcompat : B<"nxcompat", "Disable data execution provention">; | |
| 93 | defm safeseh : B<"safeseh", "Produce an image with Safe Exception Handler">; | |
| 94 | defm tsaware : B<"tsaware", "Create non-Terminal Server aware executable">; | |
| 96 | "Image can only be run in an app container", | |
| 97 | "Image can run outside an app container (default)">; | |
| 98 | defm dynamicbase : B<"dynamicbase", "Enable ASLR (default unless /fixed)", | |
| 99 | "Disable ASLR (default when /fixed)">; | |
| 100 | defm fixed : B<"fixed", "Disable base relocations", | |
| 101 | "Enable base relocations (default)">; | |
| 102 | defm highentropyva : B<"highentropyva", | |
| 103 | "Enable 64-bit ASLR (default on 64-bit)", | |
| 104 | "Disable 64-bit ASLR">; | |
| 105 | defm largeaddressaware : B<"largeaddressaware", | |
| 106 | "Enable large addresses (default on 64-bit)", | |
| 107 | "Disable large addresses (default on 32-bit)">; | |
| 108 | defm nxcompat : B<"nxcompat", "Enable data execution prevention (default)", | |
| 109 | "Disable data execution provention">; | |
| 110 | defm safeseh : B<"safeseh", | |
| 111 | "Produce an image with Safe Exception Handler (only for x86)", | |
| 112 | "Don't produce an image with Safe Exception Handler">; | |
| 113 | defm tsaware : B<"tsaware", | |
| 114 | "Create Terminal Server aware executable (default)", | |
| 115 | "Create non-Terminal Server aware executable">; | |
| 95 | 116 | |
| 96 | 117 | def help : F<"help">; |
| 97 | 118 | def help_q : Flag<["/?", "-?"], "">, Alias<help>; |
| 98 | 119 | |
| 99 | 120 | // LLD extensions |
| 100 | def nopdb : F<"nopdb">, HelpText<"Disable PDB generation for DWARF users">; | |
| 101 | def nosymtab : F<"nosymtab">; | |
| 121 | def debug_ghash : F<"debug:ghash">; | |
| 122 | def debug_dwarf : F<"debug:dwarf">; | |
| 123 | def export_all_symbols : F<"export-all-symbols">; | |
| 124 | def lldmingw : F<"lldmingw">; | |
| 102 | 125 | def msvclto : F<"msvclto">; |
| 126 | def output_def : Joined<["/", "-"], "output-def:">; | |
| 127 | def rsp_quoting : Joined<["--"], "rsp-quoting=">, | |
| 128 | HelpText<"Quoting style for response files, 'windows' (default) or 'posix'">; | |
| 129 | def dash_dash_version : Flag<["--"], "version">, | |
| 130 | HelpText<"Print version information">; | |
| 103 | 131 | |
| 104 | 132 | // Flags for debugging |
| 105 | 133 | def lldmap : F<"lldmap">; |
| ... | ... | @@ -128,12 +156,10 @@ def fastfail : F<"fastfail">; |
| 128 | 156 | def delay : QF<"delay">; |
| 129 | 157 | def errorreport : QF<"errorreport">; |
| 130 | 158 | def idlout : QF<"idlout">; |
| 131 | def ignore : QF<"ignore">; | |
| 132 | 159 | def maxilksize : QF<"maxilksize">; |
| 160 | def natvis : QF<"natvis">; | |
| 133 | 161 | def pdbaltpath : QF<"pdbaltpath">; |
| 134 | 162 | def tlbid : QF<"tlbid">; |
| 135 | 163 | def tlbout : QF<"tlbout">; |
| 136 | 164 | def verbose_all : QF<"verbose">; |
| 137 | 165 | def guardsym : QF<"guardsym">; |
| 138 | ||
| 139 | defm wx : QB<"wx">; |
deps/lld/COFF/PDB.cpp+474-124| ... | ... | @@ -10,37 +10,44 @@ |
| 10 | 10 | #include "PDB.h" |
| 11 | 11 | #include "Chunks.h" |
| 12 | 12 | #include "Config.h" |
| 13 | #include "Error.h" | |
| 13 | #include "Driver.h" | |
| 14 | 14 | #include "SymbolTable.h" |
| 15 | 15 | #include "Symbols.h" |
| 16 | #include "Writer.h" | |
| 17 | #include "lld/Common/ErrorHandler.h" | |
| 16 | 18 | #include "llvm/DebugInfo/CodeView/CVDebugRecord.h" |
| 17 | 19 | #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" |
| 20 | #include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h" | |
| 18 | 21 | #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" |
| 22 | #include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h" | |
| 23 | #include "llvm/DebugInfo/CodeView/RecordName.h" | |
| 24 | #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" | |
| 19 | 25 | #include "llvm/DebugInfo/CodeView/SymbolSerializer.h" |
| 20 | 26 | #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" |
| 21 | 27 | #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h" |
| 22 | 28 | #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" |
| 23 | 29 | #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h" |
| 24 | #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" | |
| 25 | 30 | #include "llvm/DebugInfo/MSF/MSFBuilder.h" |
| 26 | 31 | #include "llvm/DebugInfo/MSF/MSFCommon.h" |
| 27 | 32 | #include "llvm/DebugInfo/PDB/GenericError.h" |
| 28 | 33 | #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h" |
| 29 | 34 | #include "llvm/DebugInfo/PDB/Native/DbiStream.h" |
| 30 | 35 | #include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h" |
| 36 | #include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h" | |
| 31 | 37 | #include "llvm/DebugInfo/PDB/Native/InfoStream.h" |
| 32 | 38 | #include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h" |
| 33 | 39 | #include "llvm/DebugInfo/PDB/Native/NativeSession.h" |
| 34 | 40 | #include "llvm/DebugInfo/PDB/Native/PDBFile.h" |
| 35 | 41 | #include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h" |
| 36 | 42 | #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h" |
| 43 | #include "llvm/DebugInfo/PDB/Native/TpiHashing.h" | |
| 37 | 44 | #include "llvm/DebugInfo/PDB/Native/TpiStream.h" |
| 38 | 45 | #include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h" |
| 39 | 46 | #include "llvm/DebugInfo/PDB/PDB.h" |
| 40 | 47 | #include "llvm/Object/COFF.h" |
| 41 | 48 | #include "llvm/Support/BinaryByteStream.h" |
| 42 | 49 | #include "llvm/Support/Endian.h" |
| 43 | #include "llvm/Support/FileOutputBuffer.h" | |
| 50 | #include "llvm/Support/JamCRC.h" | |
| 44 | 51 | #include "llvm/Support/Path.h" |
| 45 | 52 | #include "llvm/Support/ScopedPrinter.h" |
| 46 | 53 | #include <memory> |
| ... | ... | @@ -67,16 +74,16 @@ class PDBLinker { |
| 67 | 74 | public: |
| 68 | 75 | PDBLinker(SymbolTable *Symtab) |
| 69 | 76 | : Alloc(), Symtab(Symtab), Builder(Alloc), TypeTable(Alloc), |
| 70 | IDTable(Alloc) {} | |
| 77 | IDTable(Alloc), GlobalTypeTable(Alloc), GlobalIDTable(Alloc) {} | |
| 71 | 78 | |
| 72 | 79 | /// Emit the basic PDB structure: initial streams, headers, etc. |
| 73 | void initialize(const llvm::codeview::DebugInfo *DI); | |
| 80 | void initialize(const llvm::codeview::DebugInfo &BuildId); | |
| 74 | 81 | |
| 75 | 82 | /// Link CodeView from each object file in the symbol table into the PDB. |
| 76 | 83 | void addObjectsToPDB(); |
| 77 | 84 | |
| 78 | 85 | /// Link CodeView from a single object file into the PDB. |
| 79 | void addObjectFile(ObjectFile *File); | |
| 86 | void addObjFile(ObjFile *File); | |
| 80 | 87 | |
| 81 | 88 | /// Produce a mapping from the type and item indices used in the object |
| 82 | 89 | /// file to those in the destination PDB. |
| ... | ... | @@ -89,13 +96,18 @@ public: |
| 89 | 96 | /// If the object does not use a type server PDB (compiled with /Z7), we merge |
| 90 | 97 | /// all the type and item records from the .debug$S stream and fill in the |
| 91 | 98 | /// caller-provided ObjectIndexMap. |
| 92 | const CVIndexMap &mergeDebugT(ObjectFile *File, CVIndexMap &ObjectIndexMap); | |
| 99 | Expected<const CVIndexMap&> mergeDebugT(ObjFile *File, | |
| 100 | CVIndexMap &ObjectIndexMap); | |
| 93 | 101 | |
| 94 | const CVIndexMap &maybeMergeTypeServerPDB(ObjectFile *File, | |
| 95 | TypeServer2Record &TS); | |
| 102 | Expected<const CVIndexMap&> maybeMergeTypeServerPDB(ObjFile *File, | |
| 103 | TypeServer2Record &TS); | |
| 96 | 104 | |
| 97 | 105 | /// Add the section map and section contributions to the PDB. |
| 98 | void addSections(ArrayRef<uint8_t> SectionTable); | |
| 106 | void addSections(ArrayRef<OutputSection *> OutputSections, | |
| 107 | ArrayRef<uint8_t> SectionTable); | |
| 108 | ||
| 109 | void addSectionContrib(pdb::DbiModuleDescriptorBuilder &LinkerModule, | |
| 110 | OutputSection *OS, Chunk *C); | |
| 99 | 111 | |
| 100 | 112 | /// Write the PDB to disk. |
| 101 | 113 | void commit(); |
| ... | ... | @@ -108,10 +120,16 @@ private: |
| 108 | 120 | pdb::PDBFileBuilder Builder; |
| 109 | 121 | |
| 110 | 122 | /// Type records that will go into the PDB TPI stream. |
| 111 | TypeTableBuilder TypeTable; | |
| 123 | MergingTypeTableBuilder TypeTable; | |
| 112 | 124 | |
| 113 | 125 | /// Item records that will go into the PDB IPI stream. |
| 114 | TypeTableBuilder IDTable; | |
| 126 | MergingTypeTableBuilder IDTable; | |
| 127 | ||
| 128 | /// Type records that will go into the PDB TPI stream (for /DEBUG:GHASH) | |
| 129 | GlobalTypeTableBuilder GlobalTypeTable; | |
| 130 | ||
| 131 | /// Item records that will go into the PDB IPI stream (for /DEBUG:GHASH) | |
| 132 | GlobalTypeTableBuilder GlobalIDTable; | |
| 115 | 133 | |
| 116 | 134 | /// PDBs use a single global string table for filenames in the file checksum |
| 117 | 135 | /// table. |
| ... | ... | @@ -123,18 +141,14 @@ private: |
| 123 | 141 | |
| 124 | 142 | /// Type index mappings of type server PDBs that we've loaded so far. |
| 125 | 143 | std::map<GUID, CVIndexMap> TypeServerIndexMappings; |
| 126 | }; | |
| 127 | } | |
| 128 | 144 | |
| 129 | // Returns a list of all SectionChunks. | |
| 130 | static void addSectionContribs(SymbolTable *Symtab, | |
| 131 | pdb::DbiStreamBuilder &DbiBuilder) { | |
| 132 | for (Chunk *C : Symtab->getChunks()) | |
| 133 | if (auto *SC = dyn_cast<SectionChunk>(C)) | |
| 134 | DbiBuilder.addSectionContrib(SC->File->ModuleDBI, SC->Header); | |
| 145 | /// List of TypeServer PDBs which cannot be loaded. | |
| 146 | /// Cached to prevent repeated load attempts. | |
| 147 | std::set<GUID> MissingTypeServerPDBs; | |
| 148 | }; | |
| 135 | 149 | } |
| 136 | 150 | |
| 137 | static SectionChunk *findByName(std::vector<SectionChunk *> &Sections, | |
| 151 | static SectionChunk *findByName(ArrayRef<SectionChunk *> Sections, | |
| 138 | 152 | StringRef Name) { |
| 139 | 153 | for (SectionChunk *C : Sections) |
| 140 | 154 | if (C->getSectionName() == Name) |
| ... | ... | @@ -152,21 +166,58 @@ static ArrayRef<uint8_t> consumeDebugMagic(ArrayRef<uint8_t> Data, |
| 152 | 166 | return Data.slice(4); |
| 153 | 167 | } |
| 154 | 168 | |
| 155 | static ArrayRef<uint8_t> getDebugSection(ObjectFile *File, StringRef SecName) { | |
| 169 | static ArrayRef<uint8_t> getDebugSection(ObjFile *File, StringRef SecName) { | |
| 156 | 170 | if (SectionChunk *Sec = findByName(File->getDebugChunks(), SecName)) |
| 157 | 171 | return consumeDebugMagic(Sec->getContents(), SecName); |
| 158 | 172 | return {}; |
| 159 | 173 | } |
| 160 | 174 | |
| 175 | // A COFF .debug$H section is currently a clang extension. This function checks | |
| 176 | // if a .debug$H section is in a format that we expect / understand, so that we | |
| 177 | // can ignore any sections which are coincidentally also named .debug$H but do | |
| 178 | // not contain a format we recognize. | |
| 179 | static bool canUseDebugH(ArrayRef<uint8_t> DebugH) { | |
| 180 | if (DebugH.size() < sizeof(object::debug_h_header)) | |
| 181 | return false; | |
| 182 | auto *Header = | |
| 183 | reinterpret_cast<const object::debug_h_header *>(DebugH.data()); | |
| 184 | DebugH = DebugH.drop_front(sizeof(object::debug_h_header)); | |
| 185 | return Header->Magic == COFF::DEBUG_HASHES_SECTION_MAGIC && | |
| 186 | Header->Version == 0 && | |
| 187 | Header->HashAlgorithm == uint16_t(GlobalTypeHashAlg::SHA1) && | |
| 188 | (DebugH.size() % 20 == 0); | |
| 189 | } | |
| 190 | ||
| 191 | static Optional<ArrayRef<uint8_t>> getDebugH(ObjFile *File) { | |
| 192 | SectionChunk *Sec = findByName(File->getDebugChunks(), ".debug$H"); | |
| 193 | if (!Sec) | |
| 194 | return llvm::None; | |
| 195 | ArrayRef<uint8_t> Contents = Sec->getContents(); | |
| 196 | if (!canUseDebugH(Contents)) | |
| 197 | return None; | |
| 198 | return Contents; | |
| 199 | } | |
| 200 | ||
| 201 | static ArrayRef<GloballyHashedType> | |
| 202 | getHashesFromDebugH(ArrayRef<uint8_t> DebugH) { | |
| 203 | assert(canUseDebugH(DebugH)); | |
| 204 | ||
| 205 | DebugH = DebugH.drop_front(sizeof(object::debug_h_header)); | |
| 206 | uint32_t Count = DebugH.size() / sizeof(GloballyHashedType); | |
| 207 | return {reinterpret_cast<const GloballyHashedType *>(DebugH.data()), Count}; | |
| 208 | } | |
| 209 | ||
| 161 | 210 | static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder, |
| 162 | TypeTableBuilder &TypeTable) { | |
| 211 | TypeCollection &TypeTable) { | |
| 163 | 212 | // Start the TPI or IPI stream header. |
| 164 | 213 | TpiBuilder.setVersionHeader(pdb::PdbTpiV80); |
| 165 | 214 | |
| 166 | // Flatten the in memory type table. | |
| 167 | TypeTable.ForEachRecord([&](TypeIndex TI, ArrayRef<uint8_t> Rec) { | |
| 168 | // FIXME: Hash types. | |
| 169 | TpiBuilder.addTypeRecord(Rec, None); | |
| 215 | // Flatten the in memory type table and hash each type. | |
| 216 | TypeTable.ForEachRecord([&](TypeIndex TI, const CVType &Type) { | |
| 217 | auto Hash = pdb::hashTypeRecord(Type); | |
| 218 | if (auto E = Hash.takeError()) | |
| 219 | fatal("type hashing error"); | |
| 220 | TpiBuilder.addTypeRecord(Type.RecordData, *Hash); | |
| 170 | 221 | }); |
| 171 | 222 | } |
| 172 | 223 | |
| ... | ... | @@ -180,12 +231,12 @@ maybeReadTypeServerRecord(CVTypeArray &Types) { |
| 180 | 231 | return None; |
| 181 | 232 | TypeServer2Record TS; |
| 182 | 233 | if (auto EC = TypeDeserializer::deserializeAs(const_cast<CVType &>(Type), TS)) |
| 183 | fatal(EC, "error reading type server record"); | |
| 234 | fatal("error reading type server record: " + toString(std::move(EC))); | |
| 184 | 235 | return std::move(TS); |
| 185 | 236 | } |
| 186 | 237 | |
| 187 | const CVIndexMap &PDBLinker::mergeDebugT(ObjectFile *File, | |
| 188 | CVIndexMap &ObjectIndexMap) { | |
| 238 | Expected<const CVIndexMap&> PDBLinker::mergeDebugT(ObjFile *File, | |
| 239 | CVIndexMap &ObjectIndexMap) { | |
| 189 | 240 | ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T"); |
| 190 | 241 | if (Data.empty()) |
| 191 | 242 | return ObjectIndexMap; |
| ... | ... | @@ -194,7 +245,7 @@ const CVIndexMap &PDBLinker::mergeDebugT(ObjectFile *File, |
| 194 | 245 | CVTypeArray Types; |
| 195 | 246 | BinaryStreamReader Reader(Stream); |
| 196 | 247 | if (auto EC = Reader.readArray(Types, Reader.getLength())) |
| 197 | fatal(EC, "Reader::readArray failed"); | |
| 248 | fatal("Reader::readArray failed: " + toString(std::move(EC))); | |
| 198 | 249 | |
| 199 | 250 | // Look through type servers. If we've already seen this type server, don't |
| 200 | 251 | // merge any type information. |
| ... | ... | @@ -203,17 +254,41 @@ const CVIndexMap &PDBLinker::mergeDebugT(ObjectFile *File, |
| 203 | 254 | |
| 204 | 255 | // This is a /Z7 object. Fill in the temporary, caller-provided |
| 205 | 256 | // ObjectIndexMap. |
| 206 | if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable, | |
| 207 | ObjectIndexMap.TPIMap, Types)) | |
| 208 | fatal(Err, "codeview::mergeTypeAndIdRecords failed"); | |
| 257 | if (Config->DebugGHashes) { | |
| 258 | ArrayRef<GloballyHashedType> Hashes; | |
| 259 | std::vector<GloballyHashedType> OwnedHashes; | |
| 260 | if (Optional<ArrayRef<uint8_t>> DebugH = getDebugH(File)) | |
| 261 | Hashes = getHashesFromDebugH(*DebugH); | |
| 262 | else { | |
| 263 | OwnedHashes = GloballyHashedType::hashTypes(Types); | |
| 264 | Hashes = OwnedHashes; | |
| 265 | } | |
| 266 | ||
| 267 | if (auto Err = mergeTypeAndIdRecords(GlobalIDTable, GlobalTypeTable, | |
| 268 | ObjectIndexMap.TPIMap, Types, Hashes)) | |
| 269 | fatal("codeview::mergeTypeAndIdRecords failed: " + | |
| 270 | toString(std::move(Err))); | |
| 271 | } else { | |
| 272 | if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable, | |
| 273 | ObjectIndexMap.TPIMap, Types)) | |
| 274 | fatal("codeview::mergeTypeAndIdRecords failed: " + | |
| 275 | toString(std::move(Err))); | |
| 276 | } | |
| 209 | 277 | return ObjectIndexMap; |
| 210 | 278 | } |
| 211 | 279 | |
| 212 | 280 | static Expected<std::unique_ptr<pdb::NativeSession>> |
| 213 | 281 | tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) { |
| 282 | ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile( | |
| 283 | TSPath, /*FileSize=*/-1, /*RequiresNullTerminator=*/false); | |
| 284 | if (!MBOrErr) | |
| 285 | return errorCodeToError(MBOrErr.getError()); | |
| 286 | ||
| 214 | 287 | std::unique_ptr<pdb::IPDBSession> ThisSession; |
| 215 | if (auto EC = | |
| 216 | pdb::loadDataForPDB(pdb::PDB_ReaderType::Native, TSPath, ThisSession)) | |
| 288 | if (auto EC = pdb::NativeSession::createFromPdb( | |
| 289 | MemoryBuffer::getMemBuffer(Driver->takeBuffer(std::move(*MBOrErr)), | |
| 290 | /*RequiresNullTerminator=*/false), | |
| 291 | ThisSession)) | |
| 217 | 292 | return std::move(EC); |
| 218 | 293 | |
| 219 | 294 | std::unique_ptr<pdb::NativeSession> NS( |
| ... | ... | @@ -234,11 +309,19 @@ tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) { |
| 234 | 309 | return std::move(NS); |
| 235 | 310 | } |
| 236 | 311 | |
| 237 | const CVIndexMap &PDBLinker::maybeMergeTypeServerPDB(ObjectFile *File, | |
| 238 | TypeServer2Record &TS) { | |
| 239 | // First, check if we already loaded a PDB with this GUID. Return the type | |
| 312 | Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, | |
| 313 | TypeServer2Record &TS) { | |
| 314 | const GUID& TSId = TS.getGuid(); | |
| 315 | StringRef TSPath = TS.getName(); | |
| 316 | ||
| 317 | // First, check if the PDB has previously failed to load. | |
| 318 | if (MissingTypeServerPDBs.count(TSId)) | |
| 319 | return make_error<pdb::GenericError>( | |
| 320 | pdb::generic_error_code::type_server_not_found, TSPath); | |
| 321 | ||
| 322 | // Second, check if we already loaded a PDB with this GUID. Return the type | |
| 240 | 323 | // index mapping if we have it. |
| 241 | auto Insertion = TypeServerIndexMappings.insert({TS.getGuid(), CVIndexMap()}); | |
| 324 | auto Insertion = TypeServerIndexMappings.insert({TSId, CVIndexMap()}); | |
| 242 | 325 | CVIndexMap &IndexMap = Insertion.first->second; |
| 243 | 326 | if (!Insertion.second) |
| 244 | 327 | return IndexMap; |
| ... | ... | @@ -249,34 +332,60 @@ const CVIndexMap &PDBLinker::maybeMergeTypeServerPDB(ObjectFile *File, |
| 249 | 332 | // Check for a PDB at: |
| 250 | 333 | // 1. The given file path |
| 251 | 334 | // 2. Next to the object file or archive file |
| 252 | auto ExpectedSession = tryToLoadPDB(TS.getGuid(), TS.getName()); | |
| 335 | auto ExpectedSession = tryToLoadPDB(TSId, TSPath); | |
| 253 | 336 | if (!ExpectedSession) { |
| 254 | 337 | consumeError(ExpectedSession.takeError()); |
| 255 | 338 | StringRef LocalPath = |
| 256 | 339 | !File->ParentName.empty() ? File->ParentName : File->getName(); |
| 257 | 340 | SmallString<128> Path = sys::path::parent_path(LocalPath); |
| 258 | 341 | sys::path::append( |
| 259 | Path, sys::path::filename(TS.getName(), sys::path::Style::windows)); | |
| 260 | ExpectedSession = tryToLoadPDB(TS.getGuid(), Path); | |
| 342 | Path, sys::path::filename(TSPath, sys::path::Style::windows)); | |
| 343 | ExpectedSession = tryToLoadPDB(TSId, Path); | |
| 344 | } | |
| 345 | if (auto E = ExpectedSession.takeError()) { | |
| 346 | TypeServerIndexMappings.erase(TSId); | |
| 347 | MissingTypeServerPDBs.emplace(TSId); | |
| 348 | return std::move(E); | |
| 261 | 349 | } |
| 262 | if (auto E = ExpectedSession.takeError()) | |
| 263 | fatal(E, "Type server PDB was not found"); | |
| 264 | 350 | |
| 265 | // Merge TPI first, because the IPI stream will reference type indices. | |
| 266 | 351 | auto ExpectedTpi = (*ExpectedSession)->getPDBFile().getPDBTpiStream(); |
| 267 | 352 | if (auto E = ExpectedTpi.takeError()) |
| 268 | fatal(E, "Type server does not have TPI stream"); | |
| 269 | if (auto Err = mergeTypeRecords(TypeTable, IndexMap.TPIMap, | |
| 270 | ExpectedTpi->typeArray())) | |
| 271 | fatal(Err, "codeview::mergeTypeRecords failed"); | |
| 272 | ||
| 273 | // Merge IPI. | |
| 353 | fatal("Type server does not have TPI stream: " + toString(std::move(E))); | |
| 274 | 354 | auto ExpectedIpi = (*ExpectedSession)->getPDBFile().getPDBIpiStream(); |
| 275 | 355 | if (auto E = ExpectedIpi.takeError()) |
| 276 | fatal(E, "Type server does not have TPI stream"); | |
| 277 | if (auto Err = mergeIdRecords(IDTable, IndexMap.TPIMap, IndexMap.IPIMap, | |
| 278 | ExpectedIpi->typeArray())) | |
| 279 | fatal(Err, "codeview::mergeIdRecords failed"); | |
| 356 | fatal("Type server does not have TPI stream: " + toString(std::move(E))); | |
| 357 | ||
| 358 | if (Config->DebugGHashes) { | |
| 359 | // PDBs do not actually store global hashes, so when merging a type server | |
| 360 | // PDB we have to synthesize global hashes. To do this, we first synthesize | |
| 361 | // global hashes for the TPI stream, since it is independent, then we | |
| 362 | // synthesize hashes for the IPI stream, using the hashes for the TPI stream | |
| 363 | // as inputs. | |
| 364 | auto TpiHashes = GloballyHashedType::hashTypes(ExpectedTpi->typeArray()); | |
| 365 | auto IpiHashes = | |
| 366 | GloballyHashedType::hashIds(ExpectedIpi->typeArray(), TpiHashes); | |
| 367 | ||
| 368 | // Merge TPI first, because the IPI stream will reference type indices. | |
| 369 | if (auto Err = mergeTypeRecords(GlobalTypeTable, IndexMap.TPIMap, | |
| 370 | ExpectedTpi->typeArray(), TpiHashes)) | |
| 371 | fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err))); | |
| 372 | ||
| 373 | // Merge IPI. | |
| 374 | if (auto Err = | |
| 375 | mergeIdRecords(GlobalIDTable, IndexMap.TPIMap, IndexMap.IPIMap, | |
| 376 | ExpectedIpi->typeArray(), IpiHashes)) | |
| 377 | fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err))); | |
| 378 | } else { | |
| 379 | // Merge TPI first, because the IPI stream will reference type indices. | |
| 380 | if (auto Err = mergeTypeRecords(TypeTable, IndexMap.TPIMap, | |
| 381 | ExpectedTpi->typeArray())) | |
| 382 | fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err))); | |
| 383 | ||
| 384 | // Merge IPI. | |
| 385 | if (auto Err = mergeIdRecords(IDTable, IndexMap.TPIMap, IndexMap.IPIMap, | |
| 386 | ExpectedIpi->typeArray())) | |
| 387 | fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err))); | |
| 388 | } | |
| 280 | 389 | |
| 281 | 390 | return IndexMap; |
| 282 | 391 | } |
| ... | ... | @@ -290,7 +399,7 @@ static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) { |
| 290 | 399 | return true; |
| 291 | 400 | } |
| 292 | 401 | |
| 293 | static void remapTypesInSymbolRecord(ObjectFile *File, | |
| 402 | static void remapTypesInSymbolRecord(ObjFile *File, SymbolKind SymKind, | |
| 294 | 403 | MutableArrayRef<uint8_t> Contents, |
| 295 | 404 | const CVIndexMap &IndexMap, |
| 296 | 405 | ArrayRef<TiReference> TypeRefs) { |
| ... | ... | @@ -301,27 +410,73 @@ static void remapTypesInSymbolRecord(ObjectFile *File, |
| 301 | 410 | |
| 302 | 411 | // This can be an item index or a type index. Choose the appropriate map. |
| 303 | 412 | ArrayRef<TypeIndex> TypeOrItemMap = IndexMap.TPIMap; |
| 304 | if (Ref.Kind == TiRefKind::IndexRef && IndexMap.IsTypeServerMap) | |
| 413 | bool IsItemIndex = Ref.Kind == TiRefKind::IndexRef; | |
| 414 | if (IsItemIndex && IndexMap.IsTypeServerMap) | |
| 305 | 415 | TypeOrItemMap = IndexMap.IPIMap; |
| 306 | 416 | |
| 307 | 417 | MutableArrayRef<TypeIndex> TIs( |
| 308 | 418 | reinterpret_cast<TypeIndex *>(Contents.data() + Ref.Offset), Ref.Count); |
| 309 | 419 | for (TypeIndex &TI : TIs) { |
| 310 | 420 | if (!remapTypeIndex(TI, TypeOrItemMap)) { |
| 421 | log("ignoring symbol record of kind 0x" + utohexstr(SymKind) + " in " + | |
| 422 | File->getName() + " with bad " + (IsItemIndex ? "item" : "type") + | |
| 423 | " index 0x" + utohexstr(TI.getIndex())); | |
| 311 | 424 | TI = TypeIndex(SimpleTypeKind::NotTranslated); |
| 312 | log("ignoring symbol record in " + File->getName() + | |
| 313 | " with bad type index 0x" + utohexstr(TI.getIndex())); | |
| 314 | 425 | continue; |
| 315 | 426 | } |
| 316 | 427 | } |
| 317 | 428 | } |
| 318 | 429 | } |
| 319 | 430 | |
| 320 | /// MSVC translates S_PROC_ID_END to S_END. | |
| 321 | uint16_t canonicalizeSymbolKind(SymbolKind Kind) { | |
| 322 | if (Kind == SymbolKind::S_PROC_ID_END) | |
| 323 | return SymbolKind::S_END; | |
| 324 | return Kind; | |
| 431 | static SymbolKind symbolKind(ArrayRef<uint8_t> RecordData) { | |
| 432 | const RecordPrefix *Prefix = | |
| 433 | reinterpret_cast<const RecordPrefix *>(RecordData.data()); | |
| 434 | return static_cast<SymbolKind>(uint16_t(Prefix->RecordKind)); | |
| 435 | } | |
| 436 | ||
| 437 | /// MSVC translates S_PROC_ID_END to S_END, and S_[LG]PROC32_ID to S_[LG]PROC32 | |
| 438 | static void translateIdSymbols(MutableArrayRef<uint8_t> &RecordData, | |
| 439 | TypeCollection &IDTable) { | |
| 440 | RecordPrefix *Prefix = reinterpret_cast<RecordPrefix *>(RecordData.data()); | |
| 441 | ||
| 442 | SymbolKind Kind = symbolKind(RecordData); | |
| 443 | ||
| 444 | if (Kind == SymbolKind::S_PROC_ID_END) { | |
| 445 | Prefix->RecordKind = SymbolKind::S_END; | |
| 446 | return; | |
| 447 | } | |
| 448 | ||
| 449 | // In an object file, GPROC32_ID has an embedded reference which refers to the | |
| 450 | // single object file type index namespace. This has already been translated | |
| 451 | // to the PDB file's ID stream index space, but we need to convert this to a | |
| 452 | // symbol that refers to the type stream index space. So we remap again from | |
| 453 | // ID index space to type index space. | |
| 454 | if (Kind == SymbolKind::S_GPROC32_ID || Kind == SymbolKind::S_LPROC32_ID) { | |
| 455 | SmallVector<TiReference, 1> Refs; | |
| 456 | auto Content = RecordData.drop_front(sizeof(RecordPrefix)); | |
| 457 | CVSymbol Sym(Kind, RecordData); | |
| 458 | discoverTypeIndicesInSymbol(Sym, Refs); | |
| 459 | assert(Refs.size() == 1); | |
| 460 | assert(Refs.front().Count == 1); | |
| 461 | ||
| 462 | TypeIndex *TI = | |
| 463 | reinterpret_cast<TypeIndex *>(Content.data() + Refs[0].Offset); | |
| 464 | // `TI` is the index of a FuncIdRecord or MemberFuncIdRecord which lives in | |
| 465 | // the IPI stream, whose `FunctionType` member refers to the TPI stream. | |
| 466 | // Note that LF_FUNC_ID and LF_MEMFUNC_ID have the same record layout, and | |
| 467 | // in both cases we just need the second type index. | |
| 468 | if (!TI->isSimple() && !TI->isNoneType()) { | |
| 469 | CVType FuncIdData = IDTable.getType(*TI); | |
| 470 | SmallVector<TypeIndex, 2> Indices; | |
| 471 | discoverTypeIndices(FuncIdData, Indices); | |
| 472 | assert(Indices.size() == 2); | |
| 473 | *TI = Indices[1]; | |
| 474 | } | |
| 475 | ||
| 476 | Kind = (Kind == SymbolKind::S_GPROC32_ID) ? SymbolKind::S_GPROC32 | |
| 477 | : SymbolKind::S_LPROC32; | |
| 478 | Prefix->RecordKind = uint16_t(Kind); | |
| 479 | } | |
| 325 | 480 | } |
| 326 | 481 | |
| 327 | 482 | /// Copy the symbol record. In a PDB, symbol records must be 4 byte aligned. |
| ... | ... | @@ -339,10 +494,8 @@ static MutableArrayRef<uint8_t> copySymbolForPdb(const CVSymbol &Sym, |
| 339 | 494 | memset(NewData.data() + Sym.length(), 0, Size - Sym.length()); |
| 340 | 495 | |
| 341 | 496 | // Update the record prefix length. It should point to the beginning of the |
| 342 | // next record. MSVC does some canonicalization of the record kind, so we do | |
| 343 | // that as well. | |
| 497 | // next record. | |
| 344 | 498 | auto *Prefix = reinterpret_cast<RecordPrefix *>(Mem); |
| 345 | Prefix->RecordKind = canonicalizeSymbolKind(Sym.kind()); | |
| 346 | 499 | Prefix->RecordLen = Size - 2; |
| 347 | 500 | return NewData; |
| 348 | 501 | } |
| ... | ... | @@ -402,7 +555,7 @@ static void scopeStackOpen(SmallVectorImpl<SymbolScope> &Stack, |
| 402 | 555 | } |
| 403 | 556 | |
| 404 | 557 | static void scopeStackClose(SmallVectorImpl<SymbolScope> &Stack, |
| 405 | uint32_t CurOffset, ObjectFile *File) { | |
| 558 | uint32_t CurOffset, ObjFile *File) { | |
| 406 | 559 | if (Stack.empty()) { |
| 407 | 560 | warn("symbol scopes are not balanced in " + File->getName()); |
| 408 | 561 | return; |
| ... | ... | @@ -411,8 +564,86 @@ static void scopeStackClose(SmallVectorImpl<SymbolScope> &Stack, |
| 411 | 564 | S.OpeningRecord->PtrEnd = CurOffset; |
| 412 | 565 | } |
| 413 | 566 | |
| 414 | static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjectFile *File, | |
| 567 | static bool symbolGoesInModuleStream(const CVSymbol &Sym) { | |
| 568 | switch (Sym.kind()) { | |
| 569 | case SymbolKind::S_GDATA32: | |
| 570 | case SymbolKind::S_CONSTANT: | |
| 571 | case SymbolKind::S_UDT: | |
| 572 | // We really should not be seeing S_PROCREF and S_LPROCREF in the first place | |
| 573 | // since they are synthesized by the linker in response to S_GPROC32 and | |
| 574 | // S_LPROC32, but if we do see them, don't put them in the module stream I | |
| 575 | // guess. | |
| 576 | case SymbolKind::S_PROCREF: | |
| 577 | case SymbolKind::S_LPROCREF: | |
| 578 | return false; | |
| 579 | // S_GDATA32 does not go in the module stream, but S_LDATA32 does. | |
| 580 | case SymbolKind::S_LDATA32: | |
| 581 | default: | |
| 582 | return true; | |
| 583 | } | |
| 584 | } | |
| 585 | ||
| 586 | static bool symbolGoesInGlobalsStream(const CVSymbol &Sym) { | |
| 587 | switch (Sym.kind()) { | |
| 588 | case SymbolKind::S_CONSTANT: | |
| 589 | case SymbolKind::S_GDATA32: | |
| 590 | // S_LDATA32 goes in both the module stream and the globals stream. | |
| 591 | case SymbolKind::S_LDATA32: | |
| 592 | case SymbolKind::S_GPROC32: | |
| 593 | case SymbolKind::S_LPROC32: | |
| 594 | // We really should not be seeing S_PROCREF and S_LPROCREF in the first place | |
| 595 | // since they are synthesized by the linker in response to S_GPROC32 and | |
| 596 | // S_LPROC32, but if we do see them, copy them straight through. | |
| 597 | case SymbolKind::S_PROCREF: | |
| 598 | case SymbolKind::S_LPROCREF: | |
| 599 | return true; | |
| 600 | // FIXME: For now, we drop all S_UDT symbols (i.e. they don't go in the | |
| 601 | // globals stream or the modules stream). These have special handling which | |
| 602 | // needs more investigation before we can get right, but by putting them all | |
| 603 | // into the globals stream WinDbg fails to display local variables of class | |
| 604 | // types saying that it cannot find the type Foo *. So as a stopgap just to | |
| 605 | // keep things working, we drop them. | |
| 606 | case SymbolKind::S_UDT: | |
| 607 | default: | |
| 608 | return false; | |
| 609 | } | |
| 610 | } | |
| 611 | ||
| 612 | static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, ObjFile &File, | |
| 613 | const CVSymbol &Sym) { | |
| 614 | switch (Sym.kind()) { | |
| 615 | case SymbolKind::S_CONSTANT: | |
| 616 | case SymbolKind::S_UDT: | |
| 617 | case SymbolKind::S_GDATA32: | |
| 618 | case SymbolKind::S_LDATA32: | |
| 619 | case SymbolKind::S_PROCREF: | |
| 620 | case SymbolKind::S_LPROCREF: | |
| 621 | Builder.addGlobalSymbol(Sym); | |
| 622 | break; | |
| 623 | case SymbolKind::S_GPROC32: | |
| 624 | case SymbolKind::S_LPROC32: { | |
| 625 | SymbolRecordKind K = SymbolRecordKind::ProcRefSym; | |
| 626 | if (Sym.kind() == SymbolKind::S_LPROC32) | |
| 627 | K = SymbolRecordKind::LocalProcRef; | |
| 628 | ProcRefSym PS(K); | |
| 629 | PS.Module = static_cast<uint16_t>(File.ModuleDBI->getModuleIndex()); | |
| 630 | // For some reason, MSVC seems to add one to this value. | |
| 631 | ++PS.Module; | |
| 632 | PS.Name = getSymbolName(Sym); | |
| 633 | PS.SumName = 0; | |
| 634 | PS.SymOffset = File.ModuleDBI->getNextSymbolOffset(); | |
| 635 | Builder.addGlobalSymbol(PS); | |
| 636 | break; | |
| 637 | } | |
| 638 | default: | |
| 639 | llvm_unreachable("Invalid symbol kind!"); | |
| 640 | } | |
| 641 | } | |
| 642 | ||
| 643 | static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjFile *File, | |
| 644 | pdb::GSIStreamBuilder &GsiBuilder, | |
| 415 | 645 | const CVIndexMap &IndexMap, |
| 646 | TypeCollection &IDTable, | |
| 416 | 647 | BinaryStreamRef SymData) { |
| 417 | 648 | // FIXME: Improve error recovery by warning and skipping records when |
| 418 | 649 | // possible. |
| ... | ... | @@ -420,11 +651,11 @@ static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjectFile *File, |
| 420 | 651 | BinaryStreamReader Reader(SymData); |
| 421 | 652 | ExitOnErr(Reader.readArray(Syms, Reader.getLength())); |
| 422 | 653 | SmallVector<SymbolScope, 4> Scopes; |
| 423 | for (const CVSymbol &Sym : Syms) { | |
| 654 | for (CVSymbol Sym : Syms) { | |
| 424 | 655 | // Discover type index references in the record. Skip it if we don't know |
| 425 | 656 | // where they are. |
| 426 | 657 | SmallVector<TiReference, 32> TypeRefs; |
| 427 | if (!discoverTypeIndices(Sym, TypeRefs)) { | |
| 658 | if (!discoverTypeIndicesInSymbol(Sym, TypeRefs)) { | |
| 428 | 659 | log("ignoring unknown symbol record with kind 0x" + utohexstr(Sym.kind())); |
| 429 | 660 | continue; |
| 430 | 661 | } |
| ... | ... | @@ -435,17 +666,30 @@ static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjectFile *File, |
| 435 | 666 | // Re-map all the type index references. |
| 436 | 667 | MutableArrayRef<uint8_t> Contents = |
| 437 | 668 | NewData.drop_front(sizeof(RecordPrefix)); |
| 438 | remapTypesInSymbolRecord(File, Contents, IndexMap, TypeRefs); | |
| 669 | remapTypesInSymbolRecord(File, Sym.kind(), Contents, IndexMap, TypeRefs); | |
| 670 | ||
| 671 | // An object file may have S_xxx_ID symbols, but these get converted to | |
| 672 | // "real" symbols in a PDB. | |
| 673 | translateIdSymbols(NewData, IDTable); | |
| 674 | ||
| 675 | SymbolKind NewKind = symbolKind(NewData); | |
| 439 | 676 | |
| 440 | 677 | // Fill in "Parent" and "End" fields by maintaining a stack of scopes. |
| 441 | CVSymbol NewSym(Sym.kind(), NewData); | |
| 442 | if (symbolOpensScope(Sym.kind())) | |
| 678 | CVSymbol NewSym(NewKind, NewData); | |
| 679 | if (symbolOpensScope(NewKind)) | |
| 443 | 680 | scopeStackOpen(Scopes, File->ModuleDBI->getNextSymbolOffset(), NewSym); |
| 444 | else if (symbolEndsScope(Sym.kind())) | |
| 681 | else if (symbolEndsScope(NewKind)) | |
| 445 | 682 | scopeStackClose(Scopes, File->ModuleDBI->getNextSymbolOffset(), File); |
| 446 | 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 | ||
| 447 | 690 | // Add the symbol to the module. |
| 448 | File->ModuleDBI->addSymbol(NewSym); | |
| 691 | if (symbolGoesInModuleStream(NewSym)) | |
| 692 | File->ModuleDBI->addSymbol(NewSym); | |
| 449 | 693 | } |
| 450 | 694 | } |
| 451 | 695 | |
| ... | ... | @@ -460,7 +704,7 @@ static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc, |
| 460 | 704 | ".debug$S"); |
| 461 | 705 | } |
| 462 | 706 | |
| 463 | void PDBLinker::addObjectFile(ObjectFile *File) { | |
| 707 | void PDBLinker::addObjFile(ObjFile *File) { | |
| 464 | 708 | // Add a module descriptor for every object file. We need to put an absolute |
| 465 | 709 | // path to the object into the PDB. If this is a plain object, we make its |
| 466 | 710 | // path absolute. If it's an object in an archive, we make the archive path |
| ... | ... | @@ -479,7 +723,16 @@ void PDBLinker::addObjectFile(ObjectFile *File) { |
| 479 | 723 | // the PDB first, so that we can get the map from object file type and item |
| 480 | 724 | // indices to PDB type and item indices. |
| 481 | 725 | CVIndexMap ObjectIndexMap; |
| 482 | const CVIndexMap &IndexMap = mergeDebugT(File, ObjectIndexMap); | |
| 726 | auto IndexMapResult = mergeDebugT(File, ObjectIndexMap); | |
| 727 | ||
| 728 | // If the .debug$T sections fail to merge, assume there is no debug info. | |
| 729 | if (!IndexMapResult) { | |
| 730 | warn("Type server PDB for " + Name + " is invalid, ignoring debug info. " + | |
| 731 | toString(IndexMapResult.takeError())); | |
| 732 | return; | |
| 733 | } | |
| 734 | ||
| 735 | const CVIndexMap &IndexMap = *IndexMapResult; | |
| 483 | 736 | |
| 484 | 737 | // Now do all live .debug$S sections. |
| 485 | 738 | for (SectionChunk *DebugChunk : File->getDebugChunks()) { |
| ... | ... | @@ -511,7 +764,13 @@ void PDBLinker::addObjectFile(ObjectFile *File) { |
| 511 | 764 | File->ModuleDBI->addDebugSubsection(SS); |
| 512 | 765 | break; |
| 513 | 766 | case DebugSubsectionKind::Symbols: |
| 514 | mergeSymbolRecords(Alloc, File, IndexMap, SS.getRecordData()); | |
| 767 | if (Config->DebugGHashes) { | |
| 768 | mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap, | |
| 769 | GlobalIDTable, SS.getRecordData()); | |
| 770 | } else { | |
| 771 | mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap, | |
| 772 | IDTable, SS.getRecordData()); | |
| 773 | } | |
| 515 | 774 | break; |
| 516 | 775 | default: |
| 517 | 776 | // FIXME: Process the rest of the subsections. |
| ... | ... | @@ -539,45 +798,88 @@ void PDBLinker::addObjectFile(ObjectFile *File) { |
| 539 | 798 | } |
| 540 | 799 | } |
| 541 | 800 | |
| 801 | static PublicSym32 createPublic(Defined *Def) { | |
| 802 | PublicSym32 Pub(SymbolKind::S_PUB32); | |
| 803 | Pub.Name = Def->getName(); | |
| 804 | if (auto *D = dyn_cast<DefinedCOFF>(Def)) { | |
| 805 | if (D->getCOFFSymbol().isFunctionDefinition()) | |
| 806 | Pub.Flags = PublicSymFlags::Function; | |
| 807 | } else if (isa<DefinedImportThunk>(Def)) { | |
| 808 | Pub.Flags = PublicSymFlags::Function; | |
| 809 | } | |
| 810 | ||
| 811 | OutputSection *OS = Def->getChunk()->getOutputSection(); | |
| 812 | assert(OS && "all publics should be in final image"); | |
| 813 | Pub.Offset = Def->getRVA() - OS->getRVA(); | |
| 814 | Pub.Segment = OS->SectionIndex; | |
| 815 | return Pub; | |
| 816 | } | |
| 817 | ||
| 542 | 818 | // Add all object files to the PDB. Merge .debug$T sections into IpiData and |
| 543 | 819 | // TpiData. |
| 544 | 820 | void PDBLinker::addObjectsToPDB() { |
| 545 | for (ObjectFile *File : Symtab->ObjectFiles) | |
| 546 | addObjectFile(File); | |
| 821 | for (ObjFile *File : ObjFile::Instances) | |
| 822 | addObjFile(File); | |
| 547 | 823 | |
| 548 | 824 | Builder.getStringTableBuilder().setStrings(PDBStrTab); |
| 549 | 825 | |
| 550 | // Construct TPI stream contents. | |
| 551 | addTypeInfo(Builder.getTpiBuilder(), TypeTable); | |
| 552 | ||
| 553 | // Construct IPI stream contents. | |
| 554 | addTypeInfo(Builder.getIpiBuilder(), IDTable); | |
| 826 | // Construct TPI and IPI stream contents. | |
| 827 | if (Config->DebugGHashes) { | |
| 828 | addTypeInfo(Builder.getTpiBuilder(), GlobalTypeTable); | |
| 829 | addTypeInfo(Builder.getIpiBuilder(), GlobalIDTable); | |
| 830 | } else { | |
| 831 | addTypeInfo(Builder.getTpiBuilder(), TypeTable); | |
| 832 | addTypeInfo(Builder.getIpiBuilder(), IDTable); | |
| 833 | } | |
| 555 | 834 | |
| 556 | // Add public and symbol records stream. | |
| 835 | // Compute the public and global symbols. | |
| 836 | auto &GsiBuilder = Builder.getGsiBuilder(); | |
| 837 | std::vector<PublicSym32> Publics; | |
| 838 | Symtab->forEachSymbol([&Publics](Symbol *S) { | |
| 839 | // Only emit defined, live symbols that have a chunk. | |
| 840 | auto *Def = dyn_cast<Defined>(S); | |
| 841 | if (Def && Def->isLive() && Def->getChunk()) | |
| 842 | Publics.push_back(createPublic(Def)); | |
| 843 | }); | |
| 557 | 844 | |
| 558 | // For now we don't actually write any thing useful to the publics stream, but | |
| 559 | // the act of "getting" it also creates it lazily so that we write an empty | |
| 560 | // stream. | |
| 561 | (void)Builder.getPublicsBuilder(); | |
| 845 | if (!Publics.empty()) { | |
| 846 | // Sort the public symbols and add them to the stream. | |
| 847 | std::sort(Publics.begin(), Publics.end(), | |
| 848 | [](const PublicSym32 &L, const PublicSym32 &R) { | |
| 849 | return L.Name < R.Name; | |
| 850 | }); | |
| 851 | for (const PublicSym32 &Pub : Publics) | |
| 852 | GsiBuilder.addPublicSymbol(Pub); | |
| 853 | } | |
| 562 | 854 | } |
| 563 | 855 | |
| 564 | static void addLinkerModuleSymbols(StringRef Path, | |
| 565 | pdb::DbiModuleDescriptorBuilder &Mod, | |
| 566 | BumpPtrAllocator &Allocator) { | |
| 567 | codeview::SymbolSerializer Serializer(Allocator, CodeViewContainer::Pdb); | |
| 568 | codeview::ObjNameSym ONS(SymbolRecordKind::ObjNameSym); | |
| 569 | codeview::Compile3Sym CS(SymbolRecordKind::Compile3Sym); | |
| 570 | codeview::EnvBlockSym EBS(SymbolRecordKind::EnvBlockSym); | |
| 856 | static void addCommonLinkerModuleSymbols(StringRef Path, | |
| 857 | pdb::DbiModuleDescriptorBuilder &Mod, | |
| 858 | BumpPtrAllocator &Allocator) { | |
| 859 | ObjNameSym ONS(SymbolRecordKind::ObjNameSym); | |
| 860 | Compile3Sym CS(SymbolRecordKind::Compile3Sym); | |
| 861 | EnvBlockSym EBS(SymbolRecordKind::EnvBlockSym); | |
| 571 | 862 | |
| 572 | 863 | ONS.Name = "* Linker *"; |
| 573 | 864 | ONS.Signature = 0; |
| 574 | 865 | |
| 575 | 866 | CS.Machine = Config->is64() ? CPUType::X64 : CPUType::Intel80386; |
| 867 | // 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. | |
| 869 | // By setting this to a valid MSVC linker version string, local variables are | |
| 870 | // displayed properly. As such, even though it is not representative of | |
| 871 | // LLVM's version information, we need this for compatibility. | |
| 576 | 872 | CS.Flags = CompileSym3Flags::None; |
| 577 | CS.VersionBackendBuild = 0; | |
| 578 | CS.VersionBackendMajor = 0; | |
| 579 | CS.VersionBackendMinor = 0; | |
| 873 | CS.VersionBackendBuild = 25019; | |
| 874 | CS.VersionBackendMajor = 14; | |
| 875 | CS.VersionBackendMinor = 10; | |
| 580 | 876 | CS.VersionBackendQFE = 0; |
| 877 | ||
| 878 | // MSVC also sets the frontend to 0.0.0.0 since this is specifically for the | |
| 879 | // linker module (which is by definition a backend), so we don't need to do | |
| 880 | // anything here. Also, it seems we can use "LLVM Linker" for the linker name | |
| 881 | // without any problems. Only the backend version has to be hardcoded to a | |
| 882 | // magic number. | |
| 581 | 883 | CS.VersionFrontendBuild = 0; |
| 582 | 884 | CS.VersionFrontendMajor = 0; |
| 583 | 885 | CS.VersionFrontendMinor = 0; |
| ... | ... | @@ -592,7 +894,9 @@ static void addLinkerModuleSymbols(StringRef Path, |
| 592 | 894 | sys::fs::current_path(cwd); |
| 593 | 895 | EBS.Fields.push_back(cwd); |
| 594 | 896 | EBS.Fields.push_back("exe"); |
| 595 | EBS.Fields.push_back(Config->Argv[0]); | |
| 897 | SmallString<64> exe = Config->Argv[0]; | |
| 898 | llvm::sys::fs::make_absolute(exe); | |
| 899 | EBS.Fields.push_back(exe); | |
| 596 | 900 | EBS.Fields.push_back("pdb"); |
| 597 | 901 | EBS.Fields.push_back(Path); |
| 598 | 902 | EBS.Fields.push_back("cmd"); |
| ... | ... | @@ -605,17 +909,33 @@ static void addLinkerModuleSymbols(StringRef Path, |
| 605 | 909 | EBS, Allocator, CodeViewContainer::Pdb)); |
| 606 | 910 | } |
| 607 | 911 | |
| 912 | static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod, | |
| 913 | OutputSection &OS, | |
| 914 | BumpPtrAllocator &Allocator) { | |
| 915 | SectionSym Sym(SymbolRecordKind::SectionSym); | |
| 916 | Sym.Alignment = 12; // 2^12 = 4KB | |
| 917 | Sym.Characteristics = OS.getCharacteristics(); | |
| 918 | Sym.Length = OS.getVirtualSize(); | |
| 919 | Sym.Name = OS.getName(); | |
| 920 | Sym.Rva = OS.getRVA(); | |
| 921 | Sym.SectionNumber = OS.SectionIndex; | |
| 922 | Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( | |
| 923 | Sym, Allocator, CodeViewContainer::Pdb)); | |
| 924 | } | |
| 925 | ||
| 608 | 926 | // Creates a PDB file. |
| 609 | void coff::createPDB(SymbolTable *Symtab, ArrayRef<uint8_t> SectionTable, | |
| 610 | const llvm::codeview::DebugInfo *DI) { | |
| 927 | void coff::createPDB(SymbolTable *Symtab, | |
| 928 | ArrayRef<OutputSection *> OutputSections, | |
| 929 | ArrayRef<uint8_t> SectionTable, | |
| 930 | const llvm::codeview::DebugInfo &BuildId) { | |
| 611 | 931 | PDBLinker PDB(Symtab); |
| 612 | PDB.initialize(DI); | |
| 932 | PDB.initialize(BuildId); | |
| 613 | 933 | PDB.addObjectsToPDB(); |
| 614 | PDB.addSections(SectionTable); | |
| 934 | PDB.addSections(OutputSections, SectionTable); | |
| 615 | 935 | PDB.commit(); |
| 616 | 936 | } |
| 617 | 937 | |
| 618 | void PDBLinker::initialize(const llvm::codeview::DebugInfo *DI) { | |
| 938 | void PDBLinker::initialize(const llvm::codeview::DebugInfo &BuildId) { | |
| 619 | 939 | ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize |
| 620 | 940 | |
| 621 | 941 | // Create streams in MSF for predefined streams, namely |
| ... | ... | @@ -625,41 +945,71 @@ void PDBLinker::initialize(const llvm::codeview::DebugInfo *DI) { |
| 625 | 945 | |
| 626 | 946 | // Add an Info stream. |
| 627 | 947 | auto &InfoBuilder = Builder.getInfoBuilder(); |
| 628 | InfoBuilder.setAge(DI ? DI->PDB70.Age : 0); | |
| 948 | InfoBuilder.setAge(BuildId.PDB70.Age); | |
| 629 | 949 | |
| 630 | GUID uuid{}; | |
| 631 | if (DI) | |
| 632 | memcpy(&uuid, &DI->PDB70.Signature, sizeof(uuid)); | |
| 950 | GUID uuid; | |
| 951 | memcpy(&uuid, &BuildId.PDB70.Signature, sizeof(uuid)); | |
| 633 | 952 | InfoBuilder.setGuid(uuid); |
| 634 | 953 | InfoBuilder.setSignature(time(nullptr)); |
| 635 | 954 | InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70); |
| 636 | 955 | |
| 637 | 956 | // Add an empty DBI stream. |
| 638 | 957 | pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); |
| 958 | DbiBuilder.setAge(BuildId.PDB70.Age); | |
| 639 | 959 | DbiBuilder.setVersionHeader(pdb::PdbDbiV70); |
| 640 | 960 | ExitOnErr(DbiBuilder.addDbgStream(pdb::DbgHeaderType::NewFPO, {})); |
| 641 | 961 | } |
| 642 | 962 | |
| 643 | void PDBLinker::addSections(ArrayRef<uint8_t> SectionTable) { | |
| 644 | // Add Section Contributions. | |
| 645 | pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); | |
| 646 | addSectionContribs(Symtab, DbiBuilder); | |
| 647 | ||
| 648 | // Add Section Map stream. | |
| 649 | ArrayRef<object::coff_section> Sections = { | |
| 650 | (const object::coff_section *)SectionTable.data(), | |
| 651 | SectionTable.size() / sizeof(object::coff_section)}; | |
| 652 | SectionMap = pdb::DbiStreamBuilder::createSectionMap(Sections); | |
| 653 | DbiBuilder.setSectionMap(SectionMap); | |
| 963 | void PDBLinker::addSectionContrib(pdb::DbiModuleDescriptorBuilder &LinkerModule, | |
| 964 | OutputSection *OS, Chunk *C) { | |
| 965 | pdb::SectionContrib SC; | |
| 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 | } | |
| 654 | 987 | |
| 988 | void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections, | |
| 989 | ArrayRef<uint8_t> SectionTable) { | |
| 655 | 990 | // It's not entirely clear what this is, but the * Linker * module uses it. |
| 991 | pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); | |
| 656 | 992 | NativePath = Config->PDBPath; |
| 657 | 993 | sys::fs::make_absolute(NativePath); |
| 658 | 994 | sys::path::native(NativePath, sys::path::Style::windows); |
| 659 | 995 | uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath); |
| 660 | 996 | auto &LinkerModule = ExitOnErr(DbiBuilder.addModuleInfo("* Linker *")); |
| 661 | 997 | LinkerModule.setPdbFilePathNI(PdbFilePathNI); |
| 662 | addLinkerModuleSymbols(NativePath, LinkerModule, Alloc); | |
| 998 | addCommonLinkerModuleSymbols(NativePath, LinkerModule, Alloc); | |
| 999 | ||
| 1000 | // Add section contributions. They must be ordered by ascending RVA. | |
| 1001 | for (OutputSection *OS : OutputSections) { | |
| 1002 | addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc); | |
| 1003 | for (Chunk *C : OS->getChunks()) | |
| 1004 | addSectionContrib(LinkerModule, OS, C); | |
| 1005 | } | |
| 1006 | ||
| 1007 | // Add Section Map stream. | |
| 1008 | ArrayRef<object::coff_section> Sections = { | |
| 1009 | (const object::coff_section *)SectionTable.data(), | |
| 1010 | SectionTable.size() / sizeof(object::coff_section)}; | |
| 1011 | SectionMap = pdb::DbiStreamBuilder::createSectionMap(Sections); | |
| 1012 | DbiBuilder.setSectionMap(SectionMap); | |
| 663 | 1013 | |
| 664 | 1014 | // Add COFF section header stream. |
| 665 | 1015 | ExitOnErr( |
deps/lld/COFF/PDB.h+5-2| ... | ... | @@ -21,10 +21,13 @@ union DebugInfo; |
| 21 | 21 | |
| 22 | 22 | namespace lld { |
| 23 | 23 | namespace coff { |
| 24 | class OutputSection; | |
| 24 | 25 | class SymbolTable; |
| 25 | 26 | |
| 26 | void createPDB(SymbolTable *Symtab, llvm::ArrayRef<uint8_t> SectionTable, | |
| 27 | const llvm::codeview::DebugInfo *DI); | |
| 27 | void createPDB(SymbolTable *Symtab, | |
| 28 | llvm::ArrayRef<OutputSection *> OutputSections, | |
| 29 | llvm::ArrayRef<uint8_t> SectionTable, | |
| 30 | const llvm::codeview::DebugInfo &BuildId); | |
| 28 | 31 | } |
| 29 | 32 | } |
| 30 | 33 |
deps/lld/COFF/Strings.cpp+1-1| ... | ... | @@ -20,7 +20,7 @@ using namespace lld; |
| 20 | 20 | using namespace lld::coff; |
| 21 | 21 | using namespace llvm; |
| 22 | 22 | |
| 23 | Optional<std::string> coff::demangle(StringRef S) { | |
| 23 | Optional<std::string> coff::demangleMSVC(StringRef S) { | |
| 24 | 24 | #if defined(_MSC_VER) |
| 25 | 25 | // UnDecorateSymbolName is not thread-safe, so we need a mutex. |
| 26 | 26 | static std::mutex Mu; |
deps/lld/COFF/Strings.h+1-1| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | |
| 17 | 17 | namespace lld { |
| 18 | 18 | namespace coff { |
| 19 | llvm::Optional<std::string> demangle(llvm::StringRef S); | |
| 19 | llvm::Optional<std::string> demangleMSVC(llvm::StringRef S); | |
| 20 | 20 | } |
| 21 | 21 | } |
| 22 | 22 |
deps/lld/COFF/SymbolTable.cpp+148-128| ... | ... | @@ -10,10 +10,10 @@ |
| 10 | 10 | #include "SymbolTable.h" |
| 11 | 11 | #include "Config.h" |
| 12 | 12 | #include "Driver.h" |
| 13 | #include "Error.h" | |
| 14 | 13 | #include "LTO.h" |
| 15 | #include "Memory.h" | |
| 16 | 14 | #include "Symbols.h" |
| 15 | #include "lld/Common/ErrorHandler.h" | |
| 16 | #include "lld/Common/Memory.h" | |
| 17 | 17 | #include "llvm/IR/LLVMContext.h" |
| 18 | 18 | #include "llvm/Support/Debug.h" |
| 19 | 19 | #include "llvm/Support/raw_ostream.h" |
| ... | ... | @@ -24,36 +24,6 @@ using namespace llvm; |
| 24 | 24 | namespace lld { |
| 25 | 25 | namespace coff { |
| 26 | 26 | |
| 27 | enum SymbolPreference { | |
| 28 | SP_EXISTING = -1, | |
| 29 | SP_CONFLICT = 0, | |
| 30 | SP_NEW = 1, | |
| 31 | }; | |
| 32 | ||
| 33 | /// Checks if an existing symbol S should be kept or replaced by a new symbol. | |
| 34 | /// Returns SP_EXISTING when S should be kept, SP_NEW when the new symbol | |
| 35 | /// should be kept, and SP_CONFLICT if no valid resolution exists. | |
| 36 | static SymbolPreference compareDefined(Symbol *S, bool WasInserted, | |
| 37 | bool NewIsCOMDAT) { | |
| 38 | // If the symbol wasn't previously known, the new symbol wins by default. | |
| 39 | if (WasInserted || !isa<Defined>(S->body())) | |
| 40 | return SP_NEW; | |
| 41 | ||
| 42 | // If the existing symbol is a DefinedRegular, both it and the new symbol | |
| 43 | // must be comdats. In that case, we have no reason to prefer one symbol | |
| 44 | // over the other, and we keep the existing one. If one of the symbols | |
| 45 | // is not a comdat, we report a conflict. | |
| 46 | if (auto *R = dyn_cast<DefinedRegular>(S->body())) { | |
| 47 | if (NewIsCOMDAT && R->isCOMDAT()) | |
| 48 | return SP_EXISTING; | |
| 49 | else | |
| 50 | return SP_CONFLICT; | |
| 51 | } | |
| 52 | ||
| 53 | // Existing symbol is not a DefinedRegular; new symbol wins. | |
| 54 | return SP_NEW; | |
| 55 | } | |
| 56 | ||
| 57 | 27 | SymbolTable *Symtab; |
| 58 | 28 | |
| 59 | 29 | void SymbolTable::addFile(InputFile *File) { |
| ... | ... | @@ -68,12 +38,12 @@ void SymbolTable::addFile(InputFile *File) { |
| 68 | 38 | " conflicts with " + machineToStr(Config->Machine)); |
| 69 | 39 | } |
| 70 | 40 | |
| 71 | if (auto *F = dyn_cast<ObjectFile>(File)) { | |
| 72 | ObjectFiles.push_back(F); | |
| 41 | if (auto *F = dyn_cast<ObjFile>(File)) { | |
| 42 | ObjFile::Instances.push_back(F); | |
| 73 | 43 | } else if (auto *F = dyn_cast<BitcodeFile>(File)) { |
| 74 | BitcodeFiles.push_back(F); | |
| 44 | BitcodeFile::Instances.push_back(F); | |
| 75 | 45 | } else if (auto *F = dyn_cast<ImportFile>(File)) { |
| 76 | ImportFiles.push_back(F); | |
| 46 | ImportFile::Instances.push_back(F); | |
| 77 | 47 | } |
| 78 | 48 | |
| 79 | 49 | StringRef S = File->getDirectives(); |
| ... | ... | @@ -84,70 +54,95 @@ void SymbolTable::addFile(InputFile *File) { |
| 84 | 54 | Driver->parseDirectives(S); |
| 85 | 55 | } |
| 86 | 56 | |
| 57 | static void errorOrWarn(const Twine &S) { | |
| 58 | if (Config->Force) | |
| 59 | warn(S); | |
| 60 | else | |
| 61 | error(S); | |
| 62 | } | |
| 63 | ||
| 87 | 64 | void SymbolTable::reportRemainingUndefines() { |
| 88 | SmallPtrSet<SymbolBody *, 8> Undefs; | |
| 89 | for (auto &I : Symtab) { | |
| 65 | SmallPtrSet<Symbol *, 8> Undefs; | |
| 66 | DenseMap<Symbol *, Symbol *> LocalImports; | |
| 67 | ||
| 68 | for (auto &I : SymMap) { | |
| 90 | 69 | Symbol *Sym = I.second; |
| 91 | auto *Undef = dyn_cast<Undefined>(Sym->body()); | |
| 70 | auto *Undef = dyn_cast<Undefined>(Sym); | |
| 92 | 71 | if (!Undef) |
| 93 | 72 | continue; |
| 94 | 73 | if (!Sym->IsUsedInRegularObj) |
| 95 | 74 | continue; |
| 75 | ||
| 96 | 76 | StringRef Name = Undef->getName(); |
| 77 | ||
| 97 | 78 | // A weak alias may have been resolved, so check for that. |
| 98 | 79 | if (Defined *D = Undef->getWeakAlias()) { |
| 99 | // We resolve weak aliases by replacing the alias's SymbolBody with the | |
| 100 | // target's SymbolBody. This causes all SymbolBody pointers referring to | |
| 101 | // the old symbol to instead refer to the new symbol. However, we can't | |
| 102 | // just blindly copy sizeof(Symbol::Body) bytes from D to Sym->Body | |
| 103 | // because D may be an internal symbol, and internal symbols are stored as | |
| 104 | // "unparented" SymbolBodies. For that reason we need to check which type | |
| 105 | // of symbol we are dealing with and copy the correct number of bytes. | |
| 80 | // We want to replace Sym with D. However, we can't just blindly | |
| 81 | // copy sizeof(SymbolUnion) bytes from D to Sym because D may be an | |
| 82 | // internal symbol, and internal symbols are stored as "unparented" | |
| 83 | // Symbols. For that reason we need to check which type of symbol we | |
| 84 | // are dealing with and copy the correct number of bytes. | |
| 106 | 85 | if (isa<DefinedRegular>(D)) |
| 107 | memcpy(Sym->Body.buffer, D, sizeof(DefinedRegular)); | |
| 86 | memcpy(Sym, D, sizeof(DefinedRegular)); | |
| 108 | 87 | else if (isa<DefinedAbsolute>(D)) |
| 109 | memcpy(Sym->Body.buffer, D, sizeof(DefinedAbsolute)); | |
| 88 | memcpy(Sym, D, sizeof(DefinedAbsolute)); | |
| 110 | 89 | else |
| 111 | // No other internal symbols are possible. | |
| 112 | Sym->Body = D->symbol()->Body; | |
| 90 | memcpy(Sym, D, sizeof(SymbolUnion)); | |
| 113 | 91 | continue; |
| 114 | 92 | } |
| 93 | ||
| 115 | 94 | // If we can resolve a symbol by removing __imp_ prefix, do that. |
| 116 | 95 | // This odd rule is for compatibility with MSVC linker. |
| 117 | 96 | if (Name.startswith("__imp_")) { |
| 118 | 97 | Symbol *Imp = find(Name.substr(strlen("__imp_"))); |
| 119 | if (Imp && isa<Defined>(Imp->body())) { | |
| 120 | auto *D = cast<Defined>(Imp->body()); | |
| 121 | replaceBody<DefinedLocalImport>(Sym, Name, D); | |
| 122 | LocalImportChunks.push_back( | |
| 123 | cast<DefinedLocalImport>(Sym->body())->getChunk()); | |
| 98 | if (Imp && isa<Defined>(Imp)) { | |
| 99 | auto *D = cast<Defined>(Imp); | |
| 100 | replaceSymbol<DefinedLocalImport>(Sym, Name, D); | |
| 101 | LocalImportChunks.push_back(cast<DefinedLocalImport>(Sym)->getChunk()); | |
| 102 | LocalImports[Sym] = D; | |
| 124 | 103 | continue; |
| 125 | 104 | } |
| 126 | 105 | } |
| 106 | ||
| 127 | 107 | // Remaining undefined symbols are not fatal if /force is specified. |
| 128 | 108 | // They are replaced with dummy defined symbols. |
| 129 | 109 | if (Config->Force) |
| 130 | replaceBody<DefinedAbsolute>(Sym, Name, 0); | |
| 131 | Undefs.insert(Sym->body()); | |
| 110 | replaceSymbol<DefinedAbsolute>(Sym, Name, 0); | |
| 111 | Undefs.insert(Sym); | |
| 132 | 112 | } |
| 133 | if (Undefs.empty()) | |
| 113 | ||
| 114 | if (Undefs.empty() && LocalImports.empty()) | |
| 134 | 115 | return; |
| 135 | for (SymbolBody *B : Config->GCRoot) | |
| 116 | ||
| 117 | for (Symbol *B : Config->GCRoot) { | |
| 136 | 118 | if (Undefs.count(B)) |
| 137 | warn("<root>: undefined symbol: " + B->getName()); | |
| 138 | for (ObjectFile *File : ObjectFiles) | |
| 139 | for (SymbolBody *Sym : File->getSymbols()) | |
| 119 | errorOrWarn("<root>: undefined symbol: " + B->getName()); | |
| 120 | if (Config->WarnLocallyDefinedImported) | |
| 121 | if (Symbol *Imp = LocalImports.lookup(B)) | |
| 122 | warn("<root>: locally defined symbol imported: " + Imp->getName() + | |
| 123 | " (defined in " + toString(Imp->getFile()) + ")"); | |
| 124 | } | |
| 125 | ||
| 126 | for (ObjFile *File : ObjFile::Instances) { | |
| 127 | for (Symbol *Sym : File->getSymbols()) { | |
| 128 | if (!Sym) | |
| 129 | continue; | |
| 140 | 130 | if (Undefs.count(Sym)) |
| 141 | warn(toString(File) + ": undefined symbol: " + Sym->getName()); | |
| 142 | if (!Config->Force) | |
| 143 | fatal("link failed"); | |
| 131 | errorOrWarn(toString(File) + ": undefined symbol: " + Sym->getName()); | |
| 132 | if (Config->WarnLocallyDefinedImported) | |
| 133 | if (Symbol *Imp = LocalImports.lookup(Sym)) | |
| 134 | warn(toString(File) + ": locally defined symbol imported: " + | |
| 135 | Imp->getName() + " (defined in " + toString(Imp->getFile()) + | |
| 136 | ")"); | |
| 137 | } | |
| 138 | } | |
| 144 | 139 | } |
| 145 | 140 | |
| 146 | 141 | std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { |
| 147 | Symbol *&Sym = Symtab[CachedHashStringRef(Name)]; | |
| 142 | Symbol *&Sym = SymMap[CachedHashStringRef(Name)]; | |
| 148 | 143 | if (Sym) |
| 149 | 144 | return {Sym, false}; |
| 150 | Sym = make<Symbol>(); | |
| 145 | Sym = (Symbol *)make<SymbolUnion>(); | |
| 151 | 146 | Sym->IsUsedInRegularObj = false; |
| 152 | 147 | Sym->PendingArchiveLoad = false; |
| 153 | 148 | return {Sym, true}; |
| ... | ... | @@ -160,11 +155,11 @@ Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F, |
| 160 | 155 | std::tie(S, WasInserted) = insert(Name); |
| 161 | 156 | if (!F || !isa<BitcodeFile>(F)) |
| 162 | 157 | S->IsUsedInRegularObj = true; |
| 163 | if (WasInserted || (isa<Lazy>(S->body()) && IsWeakAlias)) { | |
| 164 | replaceBody<Undefined>(S, Name); | |
| 158 | if (WasInserted || (isa<Lazy>(S) && IsWeakAlias)) { | |
| 159 | replaceSymbol<Undefined>(S, Name); | |
| 165 | 160 | return S; |
| 166 | 161 | } |
| 167 | if (auto *L = dyn_cast<Lazy>(S->body())) { | |
| 162 | if (auto *L = dyn_cast<Lazy>(S)) { | |
| 168 | 163 | if (!S->PendingArchiveLoad) { |
| 169 | 164 | S->PendingArchiveLoad = true; |
| 170 | 165 | L->File->addMember(&L->Sym); |
| ... | ... | @@ -179,10 +174,10 @@ void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) { |
| 179 | 174 | bool WasInserted; |
| 180 | 175 | std::tie(S, WasInserted) = insert(Name); |
| 181 | 176 | if (WasInserted) { |
| 182 | replaceBody<Lazy>(S, F, Sym); | |
| 177 | replaceSymbol<Lazy>(S, F, Sym); | |
| 183 | 178 | return; |
| 184 | 179 | } |
| 185 | auto *U = dyn_cast<Undefined>(S->body()); | |
| 180 | auto *U = dyn_cast<Undefined>(S); | |
| 186 | 181 | if (!U || U->WeakAlias || S->PendingArchiveLoad) |
| 187 | 182 | return; |
| 188 | 183 | S->PendingArchiveLoad = true; |
| ... | ... | @@ -190,9 +185,8 @@ void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) { |
| 190 | 185 | } |
| 191 | 186 | |
| 192 | 187 | void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) { |
| 193 | error("duplicate symbol: " + toString(*Existing->body()) + " in " + | |
| 194 | toString(Existing->body()->getFile()) + " and in " + | |
| 195 | (NewFile ? toString(NewFile) : "(internal)")); | |
| 188 | error("duplicate symbol: " + toString(*Existing) + " in " + | |
| 189 | toString(Existing->getFile()) + " and in " + toString(NewFile)); | |
| 196 | 190 | } |
| 197 | 191 | |
| 198 | 192 | Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) { |
| ... | ... | @@ -200,9 +194,9 @@ Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) { |
| 200 | 194 | bool WasInserted; |
| 201 | 195 | std::tie(S, WasInserted) = insert(N); |
| 202 | 196 | S->IsUsedInRegularObj = true; |
| 203 | if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) | |
| 204 | replaceBody<DefinedAbsolute>(S, N, Sym); | |
| 205 | else if (!isa<DefinedCOFF>(S->body())) | |
| 197 | if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) | |
| 198 | replaceSymbol<DefinedAbsolute>(S, N, Sym); | |
| 199 | else if (!isa<DefinedCOFF>(S)) | |
| 206 | 200 | reportDuplicate(S, nullptr); |
| 207 | 201 | return S; |
| 208 | 202 | } |
| ... | ... | @@ -212,9 +206,9 @@ Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) { |
| 212 | 206 | bool WasInserted; |
| 213 | 207 | std::tie(S, WasInserted) = insert(N); |
| 214 | 208 | S->IsUsedInRegularObj = true; |
| 215 | if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) | |
| 216 | replaceBody<DefinedAbsolute>(S, N, VA); | |
| 217 | else if (!isa<DefinedCOFF>(S->body())) | |
| 209 | if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) | |
| 210 | replaceSymbol<DefinedAbsolute>(S, N, VA); | |
| 211 | else if (!isa<DefinedCOFF>(S)) | |
| 218 | 212 | reportDuplicate(S, nullptr); |
| 219 | 213 | return S; |
| 220 | 214 | } |
| ... | ... | @@ -224,14 +218,14 @@ Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) { |
| 224 | 218 | bool WasInserted; |
| 225 | 219 | std::tie(S, WasInserted) = insert(N); |
| 226 | 220 | S->IsUsedInRegularObj = true; |
| 227 | if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) | |
| 228 | replaceBody<DefinedSynthetic>(S, N, C); | |
| 229 | else if (!isa<DefinedCOFF>(S->body())) | |
| 221 | if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) | |
| 222 | replaceSymbol<DefinedSynthetic>(S, N, C); | |
| 223 | else if (!isa<DefinedCOFF>(S)) | |
| 230 | 224 | reportDuplicate(S, nullptr); |
| 231 | 225 | return S; |
| 232 | 226 | } |
| 233 | 227 | |
| 234 | Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, bool IsCOMDAT, | |
| 228 | Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, | |
| 235 | 229 | const coff_symbol_generic *Sym, |
| 236 | 230 | SectionChunk *C) { |
| 237 | 231 | Symbol *S; |
| ... | ... | @@ -239,21 +233,32 @@ Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, bool IsCOMDAT, |
| 239 | 233 | std::tie(S, WasInserted) = insert(N); |
| 240 | 234 | if (!isa<BitcodeFile>(F)) |
| 241 | 235 | S->IsUsedInRegularObj = true; |
| 242 | SymbolPreference SP = compareDefined(S, WasInserted, IsCOMDAT); | |
| 243 | if (SP == SP_CONFLICT) { | |
| 236 | if (WasInserted || !isa<DefinedRegular>(S)) | |
| 237 | replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ false, | |
| 238 | /*IsExternal*/ true, Sym, C); | |
| 239 | else | |
| 244 | 240 | reportDuplicate(S, F); |
| 245 | } else if (SP == SP_NEW) { | |
| 246 | replaceBody<DefinedRegular>(S, F, N, IsCOMDAT, /*IsExternal*/ true, Sym, C); | |
| 247 | } else if (SP == SP_EXISTING && IsCOMDAT && C) { | |
| 248 | C->markDiscarded(); | |
| 249 | // Discard associative chunks that we've parsed so far. No need to recurse | |
| 250 | // because an associative section cannot have children. | |
| 251 | for (SectionChunk *Child : C->children()) | |
| 252 | Child->markDiscarded(); | |
| 253 | } | |
| 254 | 241 | return S; |
| 255 | 242 | } |
| 256 | 243 | |
| 244 | std::pair<Symbol *, bool> | |
| 245 | SymbolTable::addComdat(InputFile *F, StringRef N, | |
| 246 | const coff_symbol_generic *Sym) { | |
| 247 | Symbol *S; | |
| 248 | bool WasInserted; | |
| 249 | std::tie(S, WasInserted) = insert(N); | |
| 250 | if (!isa<BitcodeFile>(F)) | |
| 251 | S->IsUsedInRegularObj = true; | |
| 252 | if (WasInserted || !isa<DefinedRegular>(S)) { | |
| 253 | replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ true, | |
| 254 | /*IsExternal*/ true, Sym, nullptr); | |
| 255 | return {S, true}; | |
| 256 | } | |
| 257 | if (!cast<DefinedRegular>(S)->isCOMDAT()) | |
| 258 | reportDuplicate(S, F); | |
| 259 | return {S, false}; | |
| 260 | } | |
| 261 | ||
| 257 | 262 | Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size, |
| 258 | 263 | const coff_symbol_generic *Sym, CommonChunk *C) { |
| 259 | 264 | Symbol *S; |
| ... | ... | @@ -261,51 +266,56 @@ Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size, |
| 261 | 266 | std::tie(S, WasInserted) = insert(N); |
| 262 | 267 | if (!isa<BitcodeFile>(F)) |
| 263 | 268 | S->IsUsedInRegularObj = true; |
| 264 | if (WasInserted || !isa<DefinedCOFF>(S->body())) | |
| 265 | replaceBody<DefinedCommon>(S, F, N, Size, Sym, C); | |
| 266 | else if (auto *DC = dyn_cast<DefinedCommon>(S->body())) | |
| 269 | if (WasInserted || !isa<DefinedCOFF>(S)) | |
| 270 | replaceSymbol<DefinedCommon>(S, F, N, Size, Sym, C); | |
| 271 | else if (auto *DC = dyn_cast<DefinedCommon>(S)) | |
| 267 | 272 | if (Size > DC->getSize()) |
| 268 | replaceBody<DefinedCommon>(S, F, N, Size, Sym, C); | |
| 273 | replaceSymbol<DefinedCommon>(S, F, N, Size, Sym, C); | |
| 269 | 274 | return S; |
| 270 | 275 | } |
| 271 | 276 | |
| 272 | Symbol *SymbolTable::addImportData(StringRef N, ImportFile *F) { | |
| 277 | DefinedImportData *SymbolTable::addImportData(StringRef N, ImportFile *F) { | |
| 273 | 278 | Symbol *S; |
| 274 | 279 | bool WasInserted; |
| 275 | 280 | std::tie(S, WasInserted) = insert(N); |
| 276 | 281 | S->IsUsedInRegularObj = true; |
| 277 | if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) | |
| 278 | replaceBody<DefinedImportData>(S, N, F); | |
| 279 | else if (!isa<DefinedCOFF>(S->body())) | |
| 280 | reportDuplicate(S, nullptr); | |
| 281 | return S; | |
| 282 | if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) { | |
| 283 | replaceSymbol<DefinedImportData>(S, N, F); | |
| 284 | return cast<DefinedImportData>(S); | |
| 285 | } | |
| 286 | ||
| 287 | reportDuplicate(S, F); | |
| 288 | return nullptr; | |
| 282 | 289 | } |
| 283 | 290 | |
| 284 | Symbol *SymbolTable::addImportThunk(StringRef Name, DefinedImportData *ID, | |
| 285 | uint16_t Machine) { | |
| 291 | DefinedImportThunk *SymbolTable::addImportThunk(StringRef Name, | |
| 292 | DefinedImportData *ID, | |
| 293 | uint16_t Machine) { | |
| 286 | 294 | Symbol *S; |
| 287 | 295 | bool WasInserted; |
| 288 | 296 | std::tie(S, WasInserted) = insert(Name); |
| 289 | 297 | S->IsUsedInRegularObj = true; |
| 290 | if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) | |
| 291 | replaceBody<DefinedImportThunk>(S, Name, ID, Machine); | |
| 292 | else if (!isa<DefinedCOFF>(S->body())) | |
| 293 | reportDuplicate(S, nullptr); | |
| 294 | return S; | |
| 298 | if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) { | |
| 299 | replaceSymbol<DefinedImportThunk>(S, Name, ID, Machine); | |
| 300 | return cast<DefinedImportThunk>(S); | |
| 301 | } | |
| 302 | ||
| 303 | reportDuplicate(S, ID->File); | |
| 304 | return nullptr; | |
| 295 | 305 | } |
| 296 | 306 | |
| 297 | 307 | std::vector<Chunk *> SymbolTable::getChunks() { |
| 298 | 308 | std::vector<Chunk *> Res; |
| 299 | for (ObjectFile *File : ObjectFiles) { | |
| 300 | std::vector<Chunk *> &V = File->getChunks(); | |
| 309 | for (ObjFile *File : ObjFile::Instances) { | |
| 310 | ArrayRef<Chunk *> V = File->getChunks(); | |
| 301 | 311 | Res.insert(Res.end(), V.begin(), V.end()); |
| 302 | 312 | } |
| 303 | 313 | return Res; |
| 304 | 314 | } |
| 305 | 315 | |
| 306 | 316 | Symbol *SymbolTable::find(StringRef Name) { |
| 307 | auto It = Symtab.find(CachedHashStringRef(Name)); | |
| 308 | if (It == Symtab.end()) | |
| 317 | auto It = SymMap.find(CachedHashStringRef(Name)); | |
| 318 | if (It == SymMap.end()) | |
| 309 | 319 | return nullptr; |
| 310 | 320 | return It->second; |
| 311 | 321 | } |
| ... | ... | @@ -317,7 +327,7 @@ Symbol *SymbolTable::findUnderscore(StringRef Name) { |
| 317 | 327 | } |
| 318 | 328 | |
| 319 | 329 | StringRef SymbolTable::findByPrefix(StringRef Prefix) { |
| 320 | for (auto Pair : Symtab) { | |
| 330 | for (auto Pair : SymMap) { | |
| 321 | 331 | StringRef Name = Pair.first.val(); |
| 322 | 332 | if (Name.startswith(Prefix)) |
| 323 | 333 | return Name; |
| ... | ... | @@ -327,47 +337,57 @@ StringRef SymbolTable::findByPrefix(StringRef Prefix) { |
| 327 | 337 | |
| 328 | 338 | StringRef SymbolTable::findMangle(StringRef Name) { |
| 329 | 339 | if (Symbol *Sym = find(Name)) |
| 330 | if (!isa<Undefined>(Sym->body())) | |
| 340 | if (!isa<Undefined>(Sym)) | |
| 331 | 341 | return Name; |
| 332 | 342 | if (Config->Machine != I386) |
| 333 | 343 | return findByPrefix(("?" + Name + "@@Y").str()); |
| 334 | 344 | if (!Name.startswith("_")) |
| 335 | 345 | return ""; |
| 336 | // Search for x86 C function. | |
| 346 | // Search for x86 stdcall function. | |
| 337 | 347 | StringRef S = findByPrefix((Name + "@").str()); |
| 348 | if (!S.empty()) | |
| 349 | return S; | |
| 350 | // Search for x86 fastcall function. | |
| 351 | S = findByPrefix(("@" + Name.substr(1) + "@").str()); | |
| 352 | if (!S.empty()) | |
| 353 | return S; | |
| 354 | // Search for x86 vectorcall function. | |
| 355 | S = findByPrefix((Name.substr(1) + "@@").str()); | |
| 338 | 356 | if (!S.empty()) |
| 339 | 357 | return S; |
| 340 | 358 | // Search for x86 C++ non-member function. |
| 341 | 359 | return findByPrefix(("?" + Name.substr(1) + "@@Y").str()); |
| 342 | 360 | } |
| 343 | 361 | |
| 344 | void SymbolTable::mangleMaybe(SymbolBody *B) { | |
| 362 | void SymbolTable::mangleMaybe(Symbol *B) { | |
| 345 | 363 | auto *U = dyn_cast<Undefined>(B); |
| 346 | 364 | if (!U || U->WeakAlias) |
| 347 | 365 | return; |
| 348 | 366 | StringRef Alias = findMangle(U->getName()); |
| 349 | if (!Alias.empty()) | |
| 367 | if (!Alias.empty()) { | |
| 368 | log(U->getName() + " aliased to " + Alias); | |
| 350 | 369 | U->WeakAlias = addUndefined(Alias); |
| 370 | } | |
| 351 | 371 | } |
| 352 | 372 | |
| 353 | SymbolBody *SymbolTable::addUndefined(StringRef Name) { | |
| 354 | return addUndefined(Name, nullptr, false)->body(); | |
| 373 | Symbol *SymbolTable::addUndefined(StringRef Name) { | |
| 374 | return addUndefined(Name, nullptr, false); | |
| 355 | 375 | } |
| 356 | 376 | |
| 357 | 377 | std::vector<StringRef> SymbolTable::compileBitcodeFiles() { |
| 358 | 378 | LTO.reset(new BitcodeCompiler); |
| 359 | for (BitcodeFile *F : BitcodeFiles) | |
| 379 | for (BitcodeFile *F : BitcodeFile::Instances) | |
| 360 | 380 | LTO->add(*F); |
| 361 | 381 | return LTO->compile(); |
| 362 | 382 | } |
| 363 | 383 | |
| 364 | 384 | void SymbolTable::addCombinedLTOObjects() { |
| 365 | if (BitcodeFiles.empty()) | |
| 385 | if (BitcodeFile::Instances.empty()) | |
| 366 | 386 | return; |
| 367 | 387 | for (StringRef Object : compileBitcodeFiles()) { |
| 368 | auto *Obj = make<ObjectFile>(MemoryBufferRef(Object, "lto.tmp")); | |
| 388 | auto *Obj = make<ObjFile>(MemoryBufferRef(Object, "lto.tmp")); | |
| 369 | 389 | Obj->parse(); |
| 370 | ObjectFiles.push_back(Obj); | |
| 390 | ObjFile::Instances.push_back(Obj); | |
| 371 | 391 | } |
| 372 | 392 | } |
| 373 | 393 |
deps/lld/COFF/SymbolTable.h+17-18| ... | ... | @@ -31,8 +31,7 @@ class DefinedAbsolute; |
| 31 | 31 | class DefinedRelative; |
| 32 | 32 | class Lazy; |
| 33 | 33 | class SectionChunk; |
| 34 | class SymbolBody; | |
| 35 | struct Symbol; | |
| 34 | class Symbol; | |
| 36 | 35 | |
| 37 | 36 | // SymbolTable is a bucket of all known symbols, including defined, |
| 38 | 37 | // undefined, or lazy symbols (the last one is symbols in archive |
| ... | ... | @@ -66,7 +65,7 @@ public: |
| 66 | 65 | // mangled symbol. This function tries to find a mangled name |
| 67 | 66 | // for U from the symbol table, and if found, set the symbol as |
| 68 | 67 | // a weak alias for U. |
| 69 | void mangleMaybe(SymbolBody *B); | |
| 68 | void mangleMaybe(Symbol *B); | |
| 70 | 69 | StringRef findMangle(StringRef Name); |
| 71 | 70 | |
| 72 | 71 | // Build a set of COFF objects representing the combined contents of |
| ... | ... | @@ -75,15 +74,8 @@ public: |
| 75 | 74 | void addCombinedLTOObjects(); |
| 76 | 75 | std::vector<StringRef> compileBitcodeFiles(); |
| 77 | 76 | |
| 78 | // The writer needs to handle DLL import libraries specially in | |
| 79 | // order to create the import descriptor table. | |
| 80 | std::vector<ImportFile *> ImportFiles; | |
| 81 | ||
| 82 | // The writer needs to infer the machine type from the object files. | |
| 83 | std::vector<ObjectFile *> ObjectFiles; | |
| 84 | ||
| 85 | 77 | // Creates an Undefined symbol for a given name. |
| 86 | SymbolBody *addUndefined(StringRef Name); | |
| 78 | Symbol *addUndefined(StringRef Name); | |
| 87 | 79 | |
| 88 | 80 | Symbol *addSynthetic(StringRef N, Chunk *C); |
| 89 | 81 | Symbol *addAbsolute(StringRef N, uint64_t VA); |
| ... | ... | @@ -91,28 +83,35 @@ public: |
| 91 | 83 | Symbol *addUndefined(StringRef Name, InputFile *F, bool IsWeakAlias); |
| 92 | 84 | void addLazy(ArchiveFile *F, const Archive::Symbol Sym); |
| 93 | 85 | Symbol *addAbsolute(StringRef N, COFFSymbolRef S); |
| 94 | Symbol *addRegular(InputFile *F, StringRef N, bool IsCOMDAT, | |
| 86 | Symbol *addRegular(InputFile *F, StringRef N, | |
| 95 | 87 | const llvm::object::coff_symbol_generic *S = nullptr, |
| 96 | 88 | SectionChunk *C = nullptr); |
| 89 | std::pair<Symbol *, bool> | |
| 90 | addComdat(InputFile *F, StringRef N, | |
| 91 | const llvm::object::coff_symbol_generic *S = nullptr); | |
| 97 | 92 | Symbol *addCommon(InputFile *F, StringRef N, uint64_t Size, |
| 98 | 93 | const llvm::object::coff_symbol_generic *S = nullptr, |
| 99 | 94 | CommonChunk *C = nullptr); |
| 100 | Symbol *addImportData(StringRef N, ImportFile *F); | |
| 101 | Symbol *addImportThunk(StringRef Name, DefinedImportData *S, | |
| 102 | uint16_t Machine); | |
| 95 | DefinedImportData *addImportData(StringRef N, ImportFile *F); | |
| 96 | DefinedImportThunk *addImportThunk(StringRef Name, DefinedImportData *S, | |
| 97 | uint16_t Machine); | |
| 103 | 98 | |
| 104 | 99 | void reportDuplicate(Symbol *Existing, InputFile *NewFile); |
| 105 | 100 | |
| 106 | 101 | // A list of chunks which to be added to .rdata. |
| 107 | 102 | std::vector<Chunk *> LocalImportChunks; |
| 108 | 103 | |
| 104 | // Iterates symbols in non-determinstic hash table order. | |
| 105 | template <typename T> void forEachSymbol(T Callback) { | |
| 106 | for (auto &Pair : SymMap) | |
| 107 | Callback(Pair.second); | |
| 108 | } | |
| 109 | ||
| 109 | 110 | private: |
| 110 | 111 | std::pair<Symbol *, bool> insert(StringRef Name); |
| 111 | 112 | StringRef findByPrefix(StringRef Prefix); |
| 112 | 113 | |
| 113 | llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> Symtab; | |
| 114 | ||
| 115 | std::vector<BitcodeFile *> BitcodeFiles; | |
| 114 | llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap; | |
| 116 | 115 | std::unique_ptr<BitcodeCompiler> LTO; |
| 117 | 116 | }; |
| 118 | 117 |
deps/lld/COFF/Symbols.cpp+20-10| ... | ... | @@ -8,10 +8,10 @@ |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | 10 | #include "Symbols.h" |
| 11 | #include "Error.h" | |
| 12 | 11 | #include "InputFiles.h" |
| 13 | #include "Memory.h" | |
| 14 | 12 | #include "Strings.h" |
| 13 | #include "lld/Common/ErrorHandler.h" | |
| 14 | #include "lld/Common/Memory.h" | |
| 15 | 15 | #include "llvm/ADT/STLExtras.h" |
| 16 | 16 | #include "llvm/Support/Debug.h" |
| 17 | 17 | #include "llvm/Support/raw_ostream.h" |
| ... | ... | @@ -20,8 +20,8 @@ using namespace llvm; |
| 20 | 20 | using namespace llvm::object; |
| 21 | 21 | |
| 22 | 22 | // Returns a symbol name for an error message. |
| 23 | std::string lld::toString(coff::SymbolBody &B) { | |
| 24 | if (Optional<std::string> S = coff::demangle(B.getName())) | |
| 23 | std::string lld::toString(coff::Symbol &B) { | |
| 24 | if (Optional<std::string> S = coff::demangleMSVC(B.getName())) | |
| 25 | 25 | return ("\"" + *S + "\" (" + B.getName() + ")").str(); |
| 26 | 26 | return B.getName(); |
| 27 | 27 | } |
| ... | ... | @@ -29,7 +29,7 @@ std::string lld::toString(coff::SymbolBody &B) { |
| 29 | 29 | namespace lld { |
| 30 | 30 | namespace coff { |
| 31 | 31 | |
| 32 | StringRef SymbolBody::getName() { | |
| 32 | StringRef Symbol::getName() { | |
| 33 | 33 | // COFF symbol names are read lazily for a performance reason. |
| 34 | 34 | // Non-external symbol names are never used by the linker except for logging |
| 35 | 35 | // or debugging. Their internal references are resolved not by name but by |
| ... | ... | @@ -39,12 +39,12 @@ StringRef SymbolBody::getName() { |
| 39 | 39 | // is a waste of time. |
| 40 | 40 | if (Name.empty()) { |
| 41 | 41 | auto *D = cast<DefinedCOFF>(this); |
| 42 | cast<ObjectFile>(D->File)->getCOFFObj()->getSymbolName(D->Sym, Name); | |
| 42 | cast<ObjFile>(D->File)->getCOFFObj()->getSymbolName(D->Sym, Name); | |
| 43 | 43 | } |
| 44 | 44 | return Name; |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | InputFile *SymbolBody::getFile() { | |
| 47 | InputFile *Symbol::getFile() { | |
| 48 | 48 | if (auto *Sym = dyn_cast<DefinedCOFF>(this)) |
| 49 | 49 | return Sym->File; |
| 50 | 50 | if (auto *Sym = dyn_cast<Lazy>(this)) |
| ... | ... | @@ -52,9 +52,19 @@ InputFile *SymbolBody::getFile() { |
| 52 | 52 | return nullptr; |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | bool Symbol::isLive() const { | |
| 56 | if (auto *R = dyn_cast<DefinedRegular>(this)) | |
| 57 | return R->getChunk()->isLive(); | |
| 58 | if (auto *Imp = dyn_cast<DefinedImportData>(this)) | |
| 59 | return Imp->File->Live; | |
| 60 | if (auto *Imp = dyn_cast<DefinedImportThunk>(this)) | |
| 61 | return Imp->WrappedSym->File->Live; | |
| 62 | // Assume any other kind of symbol is live. | |
| 63 | return true; | |
| 64 | } | |
| 65 | ||
| 55 | 66 | COFFSymbolRef DefinedCOFF::getCOFFSymbol() { |
| 56 | size_t SymSize = | |
| 57 | cast<ObjectFile>(File)->getCOFFObj()->getSymbolTableEntrySize(); | |
| 67 | size_t SymSize = cast<ObjFile>(File)->getCOFFObj()->getSymbolTableEntrySize(); | |
| 58 | 68 | if (SymSize == sizeof(coff_symbol16)) |
| 59 | 69 | return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(Sym)); |
| 60 | 70 | assert(SymSize == sizeof(coff_symbol32)); |
| ... | ... | @@ -81,7 +91,7 @@ DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S, |
| 81 | 91 | |
| 82 | 92 | Defined *Undefined::getWeakAlias() { |
| 83 | 93 | // A weak alias may be a weak alias to another symbol, so check recursively. |
| 84 | for (SymbolBody *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias) | |
| 94 | for (Symbol *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias) | |
| 85 | 95 | if (auto *D = dyn_cast<Defined>(A)) |
| 86 | 96 | return D; |
| 87 | 97 | return nullptr; |
deps/lld/COFF/Symbols.h+67-79| ... | ... | @@ -12,8 +12,8 @@ |
| 12 | 12 | |
| 13 | 13 | #include "Chunks.h" |
| 14 | 14 | #include "Config.h" |
| 15 | #include "Memory.h" | |
| 16 | #include "lld/Core/LLVM.h" | |
| 15 | #include "lld/Common/LLVM.h" | |
| 16 | #include "lld/Common/Memory.h" | |
| 17 | 17 | #include "llvm/ADT/ArrayRef.h" |
| 18 | 18 | #include "llvm/Object/Archive.h" |
| 19 | 19 | #include "llvm/Object/COFF.h" |
| ... | ... | @@ -31,12 +31,11 @@ using llvm::object::coff_symbol_generic; |
| 31 | 31 | |
| 32 | 32 | class ArchiveFile; |
| 33 | 33 | class InputFile; |
| 34 | class ObjectFile; | |
| 35 | struct Symbol; | |
| 34 | class ObjFile; | |
| 36 | 35 | class SymbolTable; |
| 37 | 36 | |
| 38 | 37 | // The base class for real symbol classes. |
| 39 | class SymbolBody { | |
| 38 | class Symbol { | |
| 40 | 39 | public: |
| 41 | 40 | enum Kind { |
| 42 | 41 | // The order of these is significant. We start with the regular defined |
| ... | ... | @@ -70,16 +69,16 @@ public: |
| 70 | 69 | // Returns the file from which this symbol was created. |
| 71 | 70 | InputFile *getFile(); |
| 72 | 71 | |
| 73 | Symbol *symbol(); | |
| 74 | const Symbol *symbol() const { | |
| 75 | return const_cast<SymbolBody *>(this)->symbol(); | |
| 76 | } | |
| 72 | // Indicates that this symbol will be included in the final image. Only valid | |
| 73 | // after calling markLive. | |
| 74 | bool isLive() const; | |
| 77 | 75 | |
| 78 | 76 | protected: |
| 79 | 77 | friend SymbolTable; |
| 80 | explicit SymbolBody(Kind K, StringRef N = "") | |
| 78 | explicit Symbol(Kind K, StringRef N = "") | |
| 81 | 79 | : SymbolKind(K), IsExternal(true), IsCOMDAT(false), |
| 82 | WrittenToSymtab(false), Name(N) {} | |
| 80 | WrittenToSymtab(false), PendingArchiveLoad(false), IsGCRoot(false), | |
| 81 | Name(N) {} | |
| 83 | 82 | |
| 84 | 83 | const unsigned SymbolKind : 8; |
| 85 | 84 | unsigned IsExternal : 1; |
| ... | ... | @@ -92,19 +91,28 @@ public: |
| 92 | 91 | // symbols from being written to the symbol table more than once. |
| 93 | 92 | unsigned WrittenToSymtab : 1; |
| 94 | 93 | |
| 94 | // True if this symbol was referenced by a regular (non-bitcode) object. | |
| 95 | unsigned IsUsedInRegularObj : 1; | |
| 96 | ||
| 97 | // True if we've seen both a lazy and an undefined symbol with this symbol | |
| 98 | // name, which means that we have enqueued an archive member load and should | |
| 99 | // not load any more archive members to resolve the same symbol. | |
| 100 | unsigned PendingArchiveLoad : 1; | |
| 101 | ||
| 102 | /// True if we've already added this symbol to the list of GC roots. | |
| 103 | unsigned IsGCRoot : 1; | |
| 104 | ||
| 95 | 105 | protected: |
| 96 | 106 | StringRef Name; |
| 97 | 107 | }; |
| 98 | 108 | |
| 99 | 109 | // The base class for any defined symbols, including absolute symbols, |
| 100 | 110 | // etc. |
| 101 | class Defined : public SymbolBody { | |
| 111 | class Defined : public Symbol { | |
| 102 | 112 | public: |
| 103 | Defined(Kind K, StringRef N) : SymbolBody(K, N) {} | |
| 113 | Defined(Kind K, StringRef N) : Symbol(K, N) {} | |
| 104 | 114 | |
| 105 | static bool classof(const SymbolBody *S) { | |
| 106 | return S->kind() <= LastDefinedKind; | |
| 107 | } | |
| 115 | static bool classof(const Symbol *S) { return S->kind() <= LastDefinedKind; } | |
| 108 | 116 | |
| 109 | 117 | // Returns the RVA (relative virtual address) of this symbol. The |
| 110 | 118 | // writer sets and uses RVAs. |
| ... | ... | @@ -120,12 +128,13 @@ public: |
| 120 | 128 | // loaded through that. For bitcode files, Sym is nullptr and the name is stored |
| 121 | 129 | // as a StringRef. |
| 122 | 130 | class DefinedCOFF : public Defined { |
| 123 | friend SymbolBody; | |
| 131 | friend Symbol; | |
| 132 | ||
| 124 | 133 | public: |
| 125 | 134 | DefinedCOFF(Kind K, InputFile *F, StringRef N, const coff_symbol_generic *S) |
| 126 | 135 | : Defined(K, N), File(F), Sym(S) {} |
| 127 | 136 | |
| 128 | static bool classof(const SymbolBody *S) { | |
| 137 | static bool classof(const Symbol *S) { | |
| 129 | 138 | return S->kind() <= LastDefinedCOFFKind; |
| 130 | 139 | } |
| 131 | 140 | |
| ... | ... | @@ -151,16 +160,15 @@ public: |
| 151 | 160 | this->IsCOMDAT = IsCOMDAT; |
| 152 | 161 | } |
| 153 | 162 | |
| 154 | static bool classof(const SymbolBody *S) { | |
| 163 | static bool classof(const Symbol *S) { | |
| 155 | 164 | return S->kind() == DefinedRegularKind; |
| 156 | 165 | } |
| 157 | 166 | |
| 158 | uint64_t getRVA() { return (*Data)->getRVA() + Sym->Value; } | |
| 159 | bool isCOMDAT() { return IsCOMDAT; } | |
| 160 | SectionChunk *getChunk() { return *Data; } | |
| 161 | uint32_t getValue() { return Sym->Value; } | |
| 167 | uint64_t getRVA() const { return (*Data)->getRVA() + Sym->Value; } | |
| 168 | bool isCOMDAT() const { return IsCOMDAT; } | |
| 169 | SectionChunk *getChunk() const { return *Data; } | |
| 170 | uint32_t getValue() const { return Sym->Value; } | |
| 162 | 171 | |
| 163 | private: | |
| 164 | 172 | SectionChunk **Data; |
| 165 | 173 | }; |
| 166 | 174 | |
| ... | ... | @@ -173,12 +181,12 @@ public: |
| 173 | 181 | this->IsExternal = true; |
| 174 | 182 | } |
| 175 | 183 | |
| 176 | static bool classof(const SymbolBody *S) { | |
| 184 | static bool classof(const Symbol *S) { | |
| 177 | 185 | return S->kind() == DefinedCommonKind; |
| 178 | 186 | } |
| 179 | 187 | |
| 180 | 188 | uint64_t getRVA() { return Data->getRVA(); } |
| 181 | Chunk *getChunk() { return Data; } | |
| 189 | CommonChunk *getChunk() { return Data; } | |
| 182 | 190 | |
| 183 | 191 | private: |
| 184 | 192 | friend SymbolTable; |
| ... | ... | @@ -198,7 +206,7 @@ public: |
| 198 | 206 | DefinedAbsolute(StringRef N, uint64_t V) |
| 199 | 207 | : Defined(DefinedAbsoluteKind, N), VA(V) {} |
| 200 | 208 | |
| 201 | static bool classof(const SymbolBody *S) { | |
| 209 | static bool classof(const Symbol *S) { | |
| 202 | 210 | return S->kind() == DefinedAbsoluteKind; |
| 203 | 211 | } |
| 204 | 212 | |
| ... | ... | @@ -222,7 +230,7 @@ public: |
| 222 | 230 | explicit DefinedSynthetic(StringRef Name, Chunk *C) |
| 223 | 231 | : Defined(DefinedSyntheticKind, Name), C(C) {} |
| 224 | 232 | |
| 225 | static bool classof(const SymbolBody *S) { | |
| 233 | static bool classof(const Symbol *S) { | |
| 226 | 234 | return S->kind() == DefinedSyntheticKind; |
| 227 | 235 | } |
| 228 | 236 | |
| ... | ... | @@ -240,12 +248,12 @@ private: |
| 240 | 248 | // object file from an archive to replace itself with a defined |
| 241 | 249 | // symbol. If the resolver finds both Undefined and Lazy for |
| 242 | 250 | // the same name, it will ask the Lazy to load a file. |
| 243 | class Lazy : public SymbolBody { | |
| 251 | class Lazy : public Symbol { | |
| 244 | 252 | public: |
| 245 | 253 | Lazy(ArchiveFile *F, const Archive::Symbol S) |
| 246 | : SymbolBody(LazyKind, S.getName()), File(F), Sym(S) {} | |
| 254 | : Symbol(LazyKind, S.getName()), File(F), Sym(S) {} | |
| 247 | 255 | |
| 248 | static bool classof(const SymbolBody *S) { return S->kind() == LazyKind; } | |
| 256 | static bool classof(const Symbol *S) { return S->kind() == LazyKind; } | |
| 249 | 257 | |
| 250 | 258 | ArchiveFile *File; |
| 251 | 259 | |
| ... | ... | @@ -257,19 +265,17 @@ private: |
| 257 | 265 | }; |
| 258 | 266 | |
| 259 | 267 | // Undefined symbols. |
| 260 | class Undefined : public SymbolBody { | |
| 268 | class Undefined : public Symbol { | |
| 261 | 269 | public: |
| 262 | explicit Undefined(StringRef N) : SymbolBody(UndefinedKind, N) {} | |
| 270 | explicit Undefined(StringRef N) : Symbol(UndefinedKind, N) {} | |
| 263 | 271 | |
| 264 | static bool classof(const SymbolBody *S) { | |
| 265 | return S->kind() == UndefinedKind; | |
| 266 | } | |
| 272 | static bool classof(const Symbol *S) { return S->kind() == UndefinedKind; } | |
| 267 | 273 | |
| 268 | 274 | // An undefined symbol can have a fallback symbol which gives an |
| 269 | 275 | // undefined symbol a second chance if it would remain undefined. |
| 270 | 276 | // If it remains undefined, it'll be replaced with whatever the |
| 271 | 277 | // Alias pointer points to. |
| 272 | SymbolBody *WeakAlias = nullptr; | |
| 278 | Symbol *WeakAlias = nullptr; | |
| 273 | 279 | |
| 274 | 280 | // If this symbol is external weak, try to resolve it to a defined |
| 275 | 281 | // symbol by searching the chain of fallback symbols. Returns the symbol if |
| ... | ... | @@ -289,7 +295,7 @@ public: |
| 289 | 295 | : Defined(DefinedImportDataKind, N), File(F) { |
| 290 | 296 | } |
| 291 | 297 | |
| 292 | static bool classof(const SymbolBody *S) { | |
| 298 | static bool classof(const Symbol *S) { | |
| 293 | 299 | return S->kind() == DefinedImportDataKind; |
| 294 | 300 | } |
| 295 | 301 | |
| ... | ... | @@ -313,7 +319,7 @@ class DefinedImportThunk : public Defined { |
| 313 | 319 | public: |
| 314 | 320 | DefinedImportThunk(StringRef Name, DefinedImportData *S, uint16_t Machine); |
| 315 | 321 | |
| 316 | static bool classof(const SymbolBody *S) { | |
| 322 | static bool classof(const Symbol *S) { | |
| 317 | 323 | return S->kind() == DefinedImportThunkKind; |
| 318 | 324 | } |
| 319 | 325 | |
| ... | ... | @@ -336,7 +342,7 @@ public: |
| 336 | 342 | DefinedLocalImport(StringRef N, Defined *S) |
| 337 | 343 | : Defined(DefinedLocalImportKind, N), Data(make<LocalImportChunk>(S)) {} |
| 338 | 344 | |
| 339 | static bool classof(const SymbolBody *S) { | |
| 345 | static bool classof(const Symbol *S) { | |
| 340 | 346 | return S->kind() == DefinedLocalImportKind; |
| 341 | 347 | } |
| 342 | 348 | |
| ... | ... | @@ -393,51 +399,33 @@ inline Chunk *Defined::getChunk() { |
| 393 | 399 | llvm_unreachable("unknown symbol kind"); |
| 394 | 400 | } |
| 395 | 401 | |
| 396 | // A real symbol object, SymbolBody, is usually stored within a Symbol. There's | |
| 397 | // always one Symbol for each symbol name. The resolver updates the SymbolBody | |
| 398 | // stored in the Body field of this object as it resolves symbols. Symbol also | |
| 399 | // holds computed properties of symbol names. | |
| 400 | struct Symbol { | |
| 401 | // True if this symbol was referenced by a regular (non-bitcode) object. | |
| 402 | unsigned IsUsedInRegularObj : 1; | |
| 403 | ||
| 404 | // True if we've seen both a lazy and an undefined symbol with this symbol | |
| 405 | // name, which means that we have enqueued an archive member load and should | |
| 406 | // not load any more archive members to resolve the same symbol. | |
| 407 | unsigned PendingArchiveLoad : 1; | |
| 408 | ||
| 409 | // This field is used to store the Symbol's SymbolBody. This instantiation of | |
| 410 | // AlignedCharArrayUnion gives us a struct with a char array field that is | |
| 411 | // large and aligned enough to store any derived class of SymbolBody. | |
| 412 | llvm::AlignedCharArrayUnion< | |
| 413 | DefinedRegular, DefinedCommon, DefinedAbsolute, DefinedSynthetic, Lazy, | |
| 414 | Undefined, DefinedImportData, DefinedImportThunk, DefinedLocalImport> | |
| 415 | Body; | |
| 416 | ||
| 417 | SymbolBody *body() { | |
| 418 | return reinterpret_cast<SymbolBody *>(Body.buffer); | |
| 419 | } | |
| 420 | const SymbolBody *body() const { return const_cast<Symbol *>(this)->body(); } | |
| 402 | // A buffer class that is large enough to hold any Symbol-derived | |
| 403 | // object. We allocate memory using this class and instantiate a symbol | |
| 404 | // using the placement new. | |
| 405 | union SymbolUnion { | |
| 406 | alignas(DefinedRegular) char A[sizeof(DefinedRegular)]; | |
| 407 | alignas(DefinedCommon) char B[sizeof(DefinedCommon)]; | |
| 408 | alignas(DefinedAbsolute) char C[sizeof(DefinedAbsolute)]; | |
| 409 | alignas(DefinedSynthetic) char D[sizeof(DefinedSynthetic)]; | |
| 410 | alignas(Lazy) char E[sizeof(Lazy)]; | |
| 411 | alignas(Undefined) char F[sizeof(Undefined)]; | |
| 412 | alignas(DefinedImportData) char G[sizeof(DefinedImportData)]; | |
| 413 | alignas(DefinedImportThunk) char H[sizeof(DefinedImportThunk)]; | |
| 414 | alignas(DefinedLocalImport) char I[sizeof(DefinedLocalImport)]; | |
| 421 | 415 | }; |
| 422 | 416 | |
| 423 | 417 | template <typename T, typename... ArgT> |
| 424 | void replaceBody(Symbol *S, ArgT &&... Arg) { | |
| 425 | static_assert(sizeof(T) <= sizeof(S->Body), "Body too small"); | |
| 426 | static_assert(alignof(T) <= alignof(decltype(S->Body)), | |
| 427 | "Body not aligned enough"); | |
| 428 | assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr && | |
| 429 | "Not a SymbolBody"); | |
| 430 | new (S->Body.buffer) T(std::forward<ArgT>(Arg)...); | |
| 431 | } | |
| 432 | ||
| 433 | inline Symbol *SymbolBody::symbol() { | |
| 434 | assert(isExternal()); | |
| 435 | return reinterpret_cast<Symbol *>(reinterpret_cast<char *>(this) - | |
| 436 | offsetof(Symbol, Body)); | |
| 418 | void replaceSymbol(Symbol *S, ArgT &&... Arg) { | |
| 419 | static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small"); | |
| 420 | static_assert(alignof(T) <= alignof(SymbolUnion), | |
| 421 | "SymbolUnion not aligned enough"); | |
| 422 | assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr && | |
| 423 | "Not a Symbol"); | |
| 424 | new (S) T(std::forward<ArgT>(Arg)...); | |
| 437 | 425 | } |
| 438 | 426 | } // namespace coff |
| 439 | 427 | |
| 440 | std::string toString(coff::SymbolBody &B); | |
| 428 | std::string toString(coff::Symbol &B); | |
| 441 | 429 | } // namespace lld |
| 442 | 430 | |
| 443 | 431 | #endif |
deps/lld/COFF/Writer.cpp+201-130| ... | ... | @@ -10,22 +10,22 @@ |
| 10 | 10 | #include "Writer.h" |
| 11 | 11 | #include "Config.h" |
| 12 | 12 | #include "DLL.h" |
| 13 | #include "Error.h" | |
| 14 | 13 | #include "InputFiles.h" |
| 15 | 14 | #include "MapFile.h" |
| 16 | #include "Memory.h" | |
| 17 | 15 | #include "PDB.h" |
| 18 | 16 | #include "SymbolTable.h" |
| 19 | 17 | #include "Symbols.h" |
| 18 | #include "lld/Common/ErrorHandler.h" | |
| 19 | #include "lld/Common/Memory.h" | |
| 20 | 20 | #include "llvm/ADT/DenseMap.h" |
| 21 | 21 | #include "llvm/ADT/STLExtras.h" |
| 22 | 22 | #include "llvm/ADT/StringSwitch.h" |
| 23 | #include "llvm/Support/BinaryStreamReader.h" | |
| 23 | 24 | #include "llvm/Support/Debug.h" |
| 24 | 25 | #include "llvm/Support/Endian.h" |
| 25 | 26 | #include "llvm/Support/FileOutputBuffer.h" |
| 26 | 27 | #include "llvm/Support/Parallel.h" |
| 27 | 28 | #include "llvm/Support/RandomNumberGenerator.h" |
| 28 | #include "llvm/Support/raw_ostream.h" | |
| 29 | 29 | #include <algorithm> |
| 30 | 30 | #include <cstdio> |
| 31 | 31 | #include <map> |
| ... | ... | @@ -65,8 +65,9 @@ public: |
| 65 | 65 | D->Type = COFF::IMAGE_DEBUG_TYPE_CODEVIEW; |
| 66 | 66 | D->SizeOfData = Record->getSize(); |
| 67 | 67 | D->AddressOfRawData = Record->getRVA(); |
| 68 | // TODO(compnerd) get the file offset | |
| 69 | D->PointerToRawData = 0; | |
| 68 | OutputSection *OS = Record->getOutputSection(); | |
| 69 | uint64_t Offs = OS->getFileOff() + (Record->getRVA() - OS->getRVA()); | |
| 70 | D->PointerToRawData = Offs; | |
| 70 | 71 | |
| 71 | 72 | ++D; |
| 72 | 73 | } |
| ... | ... | @@ -77,32 +78,37 @@ private: |
| 77 | 78 | }; |
| 78 | 79 | |
| 79 | 80 | class CVDebugRecordChunk : public Chunk { |
| 81 | public: | |
| 82 | CVDebugRecordChunk() { | |
| 83 | PDBAbsPath = Config->PDBPath; | |
| 84 | if (!PDBAbsPath.empty()) | |
| 85 | llvm::sys::fs::make_absolute(PDBAbsPath); | |
| 86 | } | |
| 87 | ||
| 80 | 88 | size_t getSize() const override { |
| 81 | return sizeof(codeview::DebugInfo) + Config->PDBPath.size() + 1; | |
| 89 | return sizeof(codeview::DebugInfo) + PDBAbsPath.size() + 1; | |
| 82 | 90 | } |
| 83 | 91 | |
| 84 | 92 | void writeTo(uint8_t *B) const override { |
| 85 | 93 | // Save off the DebugInfo entry to backfill the file signature (build id) |
| 86 | 94 | // in Writer::writeBuildId |
| 87 | DI = reinterpret_cast<codeview::DebugInfo *>(B + OutputSectionOff); | |
| 88 | ||
| 89 | DI->Signature.CVSignature = OMF::Signature::PDB70; | |
| 95 | BuildId = reinterpret_cast<codeview::DebugInfo *>(B + OutputSectionOff); | |
| 90 | 96 | |
| 91 | 97 | // variable sized field (PDB Path) |
| 92 | auto *P = reinterpret_cast<char *>(B + OutputSectionOff + sizeof(*DI)); | |
| 93 | if (!Config->PDBPath.empty()) | |
| 94 | memcpy(P, Config->PDBPath.data(), Config->PDBPath.size()); | |
| 95 | P[Config->PDBPath.size()] = '\0'; | |
| 98 | char *P = reinterpret_cast<char *>(B + OutputSectionOff + sizeof(*BuildId)); | |
| 99 | if (!PDBAbsPath.empty()) | |
| 100 | memcpy(P, PDBAbsPath.data(), PDBAbsPath.size()); | |
| 101 | P[PDBAbsPath.size()] = '\0'; | |
| 96 | 102 | } |
| 97 | 103 | |
| 98 | public: | |
| 99 | mutable codeview::DebugInfo *DI = nullptr; | |
| 104 | SmallString<128> PDBAbsPath; | |
| 105 | mutable codeview::DebugInfo *BuildId = nullptr; | |
| 100 | 106 | }; |
| 101 | 107 | |
| 102 | 108 | // The writer writes a SymbolTable result to a file. |
| 103 | 109 | class Writer { |
| 104 | 110 | public: |
| 105 | Writer(SymbolTable *T) : Symtab(T) {} | |
| 111 | Writer() : Buffer(errorHandler().OutputBuffer) {} | |
| 106 | 112 | void run(); |
| 107 | 113 | |
| 108 | 114 | private: |
| ... | ... | @@ -115,11 +121,11 @@ private: |
| 115 | 121 | void createSymbolAndStringTable(); |
| 116 | 122 | void openFile(StringRef OutputPath); |
| 117 | 123 | template <typename PEHeaderTy> void writeHeader(); |
| 118 | void fixSafeSEHSymbols(); | |
| 124 | void createSEHTable(OutputSection *RData); | |
| 119 | 125 | void setSectionPermissions(); |
| 120 | 126 | void writeSections(); |
| 121 | void sortExceptionTable(); | |
| 122 | 127 | void writeBuildId(); |
| 128 | void sortExceptionTable(); | |
| 123 | 129 | |
| 124 | 130 | llvm::Optional<coff_symbol16> createSymbol(Defined *D); |
| 125 | 131 | size_t addEntryToStringTable(StringRef Str); |
| ... | ... | @@ -132,8 +138,7 @@ private: |
| 132 | 138 | uint32_t getSizeOfInitializedData(); |
| 133 | 139 | std::map<StringRef, std::vector<DefinedImportData *>> binImports(); |
| 134 | 140 | |
| 135 | SymbolTable *Symtab; | |
| 136 | std::unique_ptr<FileOutputBuffer> Buffer; | |
| 141 | std::unique_ptr<FileOutputBuffer> &Buffer; | |
| 137 | 142 | std::vector<OutputSection *> OutputSections; |
| 138 | 143 | std::vector<char> Strtab; |
| 139 | 144 | std::vector<llvm::object::coff_symbol16> OutputSymtab; |
| ... | ... | @@ -145,6 +150,7 @@ private: |
| 145 | 150 | Chunk *DebugDirectory = nullptr; |
| 146 | 151 | std::vector<Chunk *> DebugRecords; |
| 147 | 152 | CVDebugRecordChunk *BuildId = nullptr; |
| 153 | Optional<codeview::DebugInfo> PreviousBuildId; | |
| 148 | 154 | ArrayRef<uint8_t> SectionTable; |
| 149 | 155 | |
| 150 | 156 | uint64_t FileSize; |
| ... | ... | @@ -157,7 +163,7 @@ private: |
| 157 | 163 | namespace lld { |
| 158 | 164 | namespace coff { |
| 159 | 165 | |
| 160 | void writeResult(SymbolTable *T) { Writer(T).run(); } | |
| 166 | void writeResult() { Writer().run(); } | |
| 161 | 167 | |
| 162 | 168 | void OutputSection::setRVA(uint64_t RVA) { |
| 163 | 169 | Header.VirtualAddress = RVA; |
| ... | ... | @@ -178,10 +184,12 @@ void OutputSection::addChunk(Chunk *C) { |
| 178 | 184 | Chunks.push_back(C); |
| 179 | 185 | C->setOutputSection(this); |
| 180 | 186 | uint64_t Off = Header.VirtualSize; |
| 181 | Off = alignTo(Off, C->getAlign()); | |
| 187 | Off = alignTo(Off, C->Alignment); | |
| 182 | 188 | C->setRVA(Off); |
| 183 | 189 | C->OutputSectionOff = Off; |
| 184 | 190 | Off += C->getSize(); |
| 191 | if (Off > UINT32_MAX) | |
| 192 | error("section larger than 4 GiB: " + Name); | |
| 185 | 193 | Header.VirtualSize = Off; |
| 186 | 194 | if (C->hasData()) |
| 187 | 195 | Header.SizeOfRawData = alignTo(Off, SectorSize); |
| ... | ... | @@ -203,7 +211,8 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) { |
| 203 | 211 | // If name is too long, write offset into the string table as a name. |
| 204 | 212 | sprintf(Hdr->Name, "/%d", StringTableOff); |
| 205 | 213 | } else { |
| 206 | assert(!Config->Debug || Name.size() <= COFF::NameSize); | |
| 214 | assert(!Config->Debug || Name.size() <= COFF::NameSize || | |
| 215 | (Hdr->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0); | |
| 207 | 216 | strncpy(Hdr->Name, Name.data(), |
| 208 | 217 | std::min(Name.size(), (size_t)COFF::NameSize)); |
| 209 | 218 | } |
| ... | ... | @@ -212,6 +221,67 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) { |
| 212 | 221 | } // namespace coff |
| 213 | 222 | } // namespace lld |
| 214 | 223 | |
| 224 | // PDBs are matched against executables using a build id which consists of three | |
| 225 | // components: | |
| 226 | // 1. A 16-bit GUID | |
| 227 | // 2. An age | |
| 228 | // 3. A time stamp. | |
| 229 | // | |
| 230 | // Debuggers and symbol servers match executables against debug info by checking | |
| 231 | // each of these components of the EXE/DLL against the corresponding value in | |
| 232 | // the PDB and failing a match if any of the components differ. In the case of | |
| 233 | // symbol servers, symbols are cached in a folder that is a function of the | |
| 234 | // GUID. As a result, in order to avoid symbol cache pollution where every | |
| 235 | // incremental build copies a new PDB to the symbol cache, we must try to re-use | |
| 236 | // the existing GUID if one exists, but bump the age. This way the match will | |
| 237 | // fail, so the symbol cache knows to use the new PDB, but the GUID matches, so | |
| 238 | // it overwrites the existing item in the symbol cache rather than making a new | |
| 239 | // one. | |
| 240 | static Optional<codeview::DebugInfo> loadExistingBuildId(StringRef Path) { | |
| 241 | // We don't need to incrementally update a previous build id if we're not | |
| 242 | // writing codeview debug info. | |
| 243 | if (!Config->Debug) | |
| 244 | return None; | |
| 245 | ||
| 246 | auto ExpectedBinary = llvm::object::createBinary(Path); | |
| 247 | if (!ExpectedBinary) { | |
| 248 | consumeError(ExpectedBinary.takeError()); | |
| 249 | return None; | |
| 250 | } | |
| 251 | ||
| 252 | auto Binary = std::move(*ExpectedBinary); | |
| 253 | if (!Binary.getBinary()->isCOFF()) | |
| 254 | return None; | |
| 255 | ||
| 256 | std::error_code EC; | |
| 257 | COFFObjectFile File(Binary.getBinary()->getMemoryBufferRef(), EC); | |
| 258 | if (EC) | |
| 259 | return None; | |
| 260 | ||
| 261 | // If the machine of the binary we're outputting doesn't match the machine | |
| 262 | // of the existing binary, don't try to re-use the build id. | |
| 263 | if (File.is64() != Config->is64() || File.getMachine() != Config->Machine) | |
| 264 | return None; | |
| 265 | ||
| 266 | for (const auto &DebugDir : File.debug_directories()) { | |
| 267 | if (DebugDir.Type != IMAGE_DEBUG_TYPE_CODEVIEW) | |
| 268 | continue; | |
| 269 | ||
| 270 | const codeview::DebugInfo *ExistingDI = nullptr; | |
| 271 | StringRef PDBFileName; | |
| 272 | if (auto EC = File.getDebugPDBInfo(ExistingDI, PDBFileName)) { | |
| 273 | (void)EC; | |
| 274 | return None; | |
| 275 | } | |
| 276 | // We only support writing PDBs in v70 format. So if this is not a build | |
| 277 | // id that we recognize / support, ignore it. | |
| 278 | if (ExistingDI->Signature.CVSignature != OMF::Signature::PDB70) | |
| 279 | return None; | |
| 280 | return *ExistingDI; | |
| 281 | } | |
| 282 | return None; | |
| 283 | } | |
| 284 | ||
| 215 | 285 | // The main function of the writer. |
| 216 | 286 | void Writer::run() { |
| 217 | 287 | createSections(); |
| ... | ... | @@ -224,32 +294,39 @@ void Writer::run() { |
| 224 | 294 | removeEmptySections(); |
| 225 | 295 | setSectionPermissions(); |
| 226 | 296 | createSymbolAndStringTable(); |
| 297 | ||
| 298 | // 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. | |
| 300 | PreviousBuildId = loadExistingBuildId(Config->OutputFile); | |
| 227 | 301 | openFile(Config->OutputFile); |
| 228 | 302 | if (Config->is64()) { |
| 229 | 303 | writeHeader<pe32plus_header>(); |
| 230 | 304 | } else { |
| 231 | 305 | writeHeader<pe32_header>(); |
| 232 | 306 | } |
| 233 | fixSafeSEHSymbols(); | |
| 234 | 307 | writeSections(); |
| 235 | 308 | sortExceptionTable(); |
| 236 | 309 | writeBuildId(); |
| 237 | 310 | |
| 238 | 311 | if (!Config->PDBPath.empty() && Config->Debug) { |
| 239 | const llvm::codeview::DebugInfo *DI = nullptr; | |
| 240 | if (Config->DebugTypes & static_cast<unsigned>(coff::DebugType::CV)) | |
| 241 | DI = BuildId->DI; | |
| 242 | createPDB(Symtab, SectionTable, DI); | |
| 312 | ||
| 313 | assert(BuildId); | |
| 314 | createPDB(Symtab, OutputSections, SectionTable, *BuildId->BuildId); | |
| 243 | 315 | } |
| 244 | 316 | |
| 245 | 317 | writeMapFile(OutputSections); |
| 246 | 318 | |
| 247 | if (auto EC = Buffer->commit()) | |
| 248 | fatal(EC, "failed to write the output file"); | |
| 319 | if (auto E = Buffer->commit()) | |
| 320 | fatal("failed to write the output file: " + toString(std::move(E))); | |
| 249 | 321 | } |
| 250 | 322 | |
| 251 | 323 | static StringRef getOutputSection(StringRef Name) { |
| 252 | 324 | StringRef S = Name.split('$').first; |
| 325 | ||
| 326 | // Treat a later period as a separator for MinGW, for sections like | |
| 327 | // ".ctors.01234". | |
| 328 | S = S.substr(0, S.find('.', 1)); | |
| 329 | ||
| 253 | 330 | auto It = Config->Merge.find(S); |
| 254 | 331 | if (It == Config->Merge.end()) |
| 255 | 332 | return S; |
| ... | ... | @@ -303,41 +380,20 @@ void Writer::createMiscChunks() { |
| 303 | 380 | if (Config->Debug) { |
| 304 | 381 | DebugDirectory = make<DebugDirectoryChunk>(DebugRecords); |
| 305 | 382 | |
| 306 | // TODO(compnerd) create a coffgrp entry if DebugType::CV is not enabled | |
| 307 | if (Config->DebugTypes & static_cast<unsigned>(coff::DebugType::CV)) { | |
| 308 | auto *Chunk = make<CVDebugRecordChunk>(); | |
| 309 | ||
| 310 | BuildId = Chunk; | |
| 311 | DebugRecords.push_back(Chunk); | |
| 312 | } | |
| 383 | // 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 | |
| 385 | // allowing a debugger to match a PDB and an executable. So we need it even | |
| 386 | // if we're ultimately not going to write CodeView data to the PDB. | |
| 387 | auto *CVChunk = make<CVDebugRecordChunk>(); | |
| 388 | BuildId = CVChunk; | |
| 389 | DebugRecords.push_back(CVChunk); | |
| 313 | 390 | |
| 314 | 391 | RData->addChunk(DebugDirectory); |
| 315 | 392 | for (Chunk *C : DebugRecords) |
| 316 | 393 | RData->addChunk(C); |
| 317 | 394 | } |
| 318 | 395 | |
| 319 | // Create SEH table. x86-only. | |
| 320 | if (Config->Machine != I386) | |
| 321 | return; | |
| 322 | ||
| 323 | std::set<Defined *> Handlers; | |
| 324 | ||
| 325 | for (lld::coff::ObjectFile *File : Symtab->ObjectFiles) { | |
| 326 | if (!File->SEHCompat) | |
| 327 | return; | |
| 328 | for (SymbolBody *B : File->SEHandlers) { | |
| 329 | // Make sure the handler is still live. Assume all handlers are regular | |
| 330 | // symbols. | |
| 331 | auto *D = dyn_cast<DefinedRegular>(B); | |
| 332 | if (D && D->getChunk()->isLive()) | |
| 333 | Handlers.insert(D); | |
| 334 | } | |
| 335 | } | |
| 336 | ||
| 337 | if (!Handlers.empty()) { | |
| 338 | SEHTable = make<SEHTableChunk>(Handlers); | |
| 339 | RData->addChunk(SEHTable); | |
| 340 | } | |
| 396 | createSEHTable(RData); | |
| 341 | 397 | } |
| 342 | 398 | |
| 343 | 399 | // Create .idata section for the DLL-imported symbol table. |
| ... | ... | @@ -345,13 +401,13 @@ void Writer::createMiscChunks() { |
| 345 | 401 | // IdataContents class abstracted away the details for us, |
| 346 | 402 | // so we just let it create chunks and add them to the section. |
| 347 | 403 | void Writer::createImportTables() { |
| 348 | if (Symtab->ImportFiles.empty()) | |
| 404 | if (ImportFile::Instances.empty()) | |
| 349 | 405 | return; |
| 350 | 406 | |
| 351 | 407 | // Initialize DLLOrder so that import entries are ordered in |
| 352 | 408 | // the same order as in the command line. (That affects DLL |
| 353 | 409 | // initialization order, and this ordering is MSVC-compatible.) |
| 354 | for (ImportFile *File : Symtab->ImportFiles) { | |
| 410 | for (ImportFile *File : ImportFile::Instances) { | |
| 355 | 411 | if (!File->Live) |
| 356 | 412 | continue; |
| 357 | 413 | |
| ... | ... | @@ -361,7 +417,7 @@ void Writer::createImportTables() { |
| 361 | 417 | } |
| 362 | 418 | |
| 363 | 419 | OutputSection *Text = createSection(".text"); |
| 364 | for (ImportFile *File : Symtab->ImportFiles) { | |
| 420 | for (ImportFile *File : ImportFile::Instances) { | |
| 365 | 421 | if (!File->Live) |
| 366 | 422 | continue; |
| 367 | 423 | |
| ... | ... | @@ -432,19 +488,12 @@ Optional<coff_symbol16> Writer::createSymbol(Defined *Def) { |
| 432 | 488 | if (isa<DefinedSynthetic>(Def)) |
| 433 | 489 | return None; |
| 434 | 490 | |
| 435 | if (auto *D = dyn_cast<DefinedRegular>(Def)) { | |
| 436 | // Don't write dead symbols or symbols in codeview sections to the symbol | |
| 437 | // table. | |
| 438 | if (!D->getChunk()->isLive() || D->getChunk()->isCodeView()) | |
| 439 | return None; | |
| 440 | } | |
| 441 | ||
| 442 | if (auto *Sym = dyn_cast<DefinedImportData>(Def)) | |
| 443 | if (!Sym->File->Live) | |
| 444 | return None; | |
| 445 | ||
| 446 | if (auto *Sym = dyn_cast<DefinedImportThunk>(Def)) | |
| 447 | if (!Sym->WrappedSym->File->Live) | |
| 491 | // Don't write dead symbols or symbols in codeview sections to the symbol | |
| 492 | // table. | |
| 493 | if (!Def->isLive()) | |
| 494 | return None; | |
| 495 | if (auto *D = dyn_cast<DefinedRegular>(Def)) | |
| 496 | if (D->getChunk()->isCodeView()) | |
| 448 | 497 | return None; |
| 449 | 498 | |
| 450 | 499 | coff_symbol16 Sym; |
| ... | ... | @@ -468,7 +517,7 @@ Optional<coff_symbol16> Writer::createSymbol(Defined *Def) { |
| 468 | 517 | Sym.NumberOfAuxSymbols = 0; |
| 469 | 518 | |
| 470 | 519 | switch (Def->kind()) { |
| 471 | case SymbolBody::DefinedAbsoluteKind: | |
| 520 | case Symbol::DefinedAbsoluteKind: | |
| 472 | 521 | Sym.Value = Def->getRVA(); |
| 473 | 522 | Sym.SectionNumber = IMAGE_SYM_ABSOLUTE; |
| 474 | 523 | break; |
| ... | ... | @@ -489,40 +538,46 @@ Optional<coff_symbol16> Writer::createSymbol(Defined *Def) { |
| 489 | 538 | } |
| 490 | 539 | |
| 491 | 540 | void Writer::createSymbolAndStringTable() { |
| 492 | if (!Config->Debug || !Config->WriteSymtab) | |
| 493 | return; | |
| 494 | ||
| 495 | 541 | // Name field in the section table is 8 byte long. Longer names need |
| 496 | 542 | // to be written to the string table. First, construct string table. |
| 497 | 543 | for (OutputSection *Sec : OutputSections) { |
| 498 | 544 | StringRef Name = Sec->getName(); |
| 499 | 545 | if (Name.size() <= COFF::NameSize) |
| 500 | 546 | continue; |
| 547 | // If a section isn't discardable (i.e. will be mapped at runtime), | |
| 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; | |
| 501 | 554 | Sec->setStringTableOff(addEntryToStringTable(Name)); |
| 502 | 555 | } |
| 503 | 556 | |
| 504 | for (lld::coff::ObjectFile *File : Symtab->ObjectFiles) { | |
| 505 | for (SymbolBody *B : File->getSymbols()) { | |
| 506 | auto *D = dyn_cast<Defined>(B); | |
| 507 | if (!D || D->WrittenToSymtab) | |
| 508 | continue; | |
| 509 | D->WrittenToSymtab = true; | |
| 557 | if (Config->DebugDwarf) { | |
| 558 | for (ObjFile *File : ObjFile::Instances) { | |
| 559 | for (Symbol *B : File->getSymbols()) { | |
| 560 | auto *D = dyn_cast_or_null<Defined>(B); | |
| 561 | if (!D || D->WrittenToSymtab) | |
| 562 | continue; | |
| 563 | D->WrittenToSymtab = true; | |
| 510 | 564 | |
| 511 | if (Optional<coff_symbol16> Sym = createSymbol(D)) | |
| 512 | OutputSymtab.push_back(*Sym); | |
| 565 | if (Optional<coff_symbol16> Sym = createSymbol(D)) | |
| 566 | OutputSymtab.push_back(*Sym); | |
| 567 | } | |
| 513 | 568 | } |
| 514 | 569 | } |
| 515 | 570 | |
| 571 | if (OutputSymtab.empty() && Strtab.empty()) | |
| 572 | return; | |
| 573 | ||
| 516 | 574 | OutputSection *LastSection = OutputSections.back(); |
| 517 | 575 | // We position the symbol table to be adjacent to the end of the last section. |
| 518 | 576 | uint64_t FileOff = LastSection->getFileOff() + |
| 519 | 577 | alignTo(LastSection->getRawSize(), SectorSize); |
| 520 | if (!OutputSymtab.empty()) { | |
| 521 | PointerToSymbolTable = FileOff; | |
| 522 | FileOff += OutputSymtab.size() * sizeof(coff_symbol16); | |
| 523 | } | |
| 524 | if (!Strtab.empty()) | |
| 525 | FileOff += Strtab.size() + 4; | |
| 578 | PointerToSymbolTable = FileOff; | |
| 579 | FileOff += OutputSymtab.size() * sizeof(coff_symbol16); | |
| 580 | FileOff += 4 + Strtab.size(); | |
| 526 | 581 | FileSize = alignTo(FileOff, SectorSize); |
| 527 | 582 | } |
| 528 | 583 | |
| ... | ... | @@ -551,7 +606,7 @@ void Writer::assignAddresses() { |
| 551 | 606 | RVA += alignTo(Sec->getVirtualSize(), PageSize); |
| 552 | 607 | FileSize += alignTo(Sec->getRawSize(), SectorSize); |
| 553 | 608 | } |
| 554 | SizeOfImage = SizeOfHeaders + alignTo(RVA - 0x1000, PageSize); | |
| 609 | SizeOfImage = alignTo(RVA, PageSize); | |
| 555 | 610 | } |
| 556 | 611 | |
| 557 | 612 | template <typename PEHeaderTy> void Writer::writeHeader() { |
| ... | ... | @@ -621,23 +676,21 @@ template <typename PEHeaderTy> void Writer::writeHeader() { |
| 621 | 676 | PE->SizeOfStackCommit = Config->StackCommit; |
| 622 | 677 | PE->SizeOfHeapReserve = Config->HeapReserve; |
| 623 | 678 | PE->SizeOfHeapCommit = Config->HeapCommit; |
| 624 | ||
| 625 | // Import Descriptor Tables and Import Address Tables are merged | |
| 626 | // in our output. That's not compatible with the Binding feature | |
| 627 | // that is sort of prelinking. Setting this flag to make it clear | |
| 628 | // that our outputs are not for the Binding. | |
| 629 | PE->DLLCharacteristics = IMAGE_DLL_CHARACTERISTICS_NO_BIND; | |
| 630 | ||
| 631 | 679 | if (Config->AppContainer) |
| 632 | 680 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER; |
| 633 | 681 | if (Config->DynamicBase) |
| 634 | 682 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE; |
| 635 | 683 | if (Config->HighEntropyVA) |
| 636 | 684 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA; |
| 685 | if (!Config->AllowBind) | |
| 686 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_BIND; | |
| 637 | 687 | if (Config->NxCompat) |
| 638 | 688 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT; |
| 639 | 689 | if (!Config->AllowIsolation) |
| 640 | 690 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION; |
| 691 | if (Config->Machine == I386 && !SEHTable && | |
| 692 | !Symtab->findUnderscore("_load_config_used")) | |
| 693 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH; | |
| 641 | 694 | if (Config->TerminalServerAware) |
| 642 | 695 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE; |
| 643 | 696 | PE->NumberOfRvaAndSize = NumberfOfDataDirectory; |
| ... | ... | @@ -673,7 +726,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() { |
| 673 | 726 | Dir[BASE_RELOCATION_TABLE].Size = Sec->getVirtualSize(); |
| 674 | 727 | } |
| 675 | 728 | if (Symbol *Sym = Symtab->findUnderscore("_tls_used")) { |
| 676 | if (Defined *B = dyn_cast<Defined>(Sym->body())) { | |
| 729 | if (Defined *B = dyn_cast<Defined>(Sym)) { | |
| 677 | 730 | Dir[TLS_TABLE].RelativeVirtualAddress = B->getRVA(); |
| 678 | 731 | Dir[TLS_TABLE].Size = Config->is64() |
| 679 | 732 | ? sizeof(object::coff_tls_directory64) |
| ... | ... | @@ -685,7 +738,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() { |
| 685 | 738 | Dir[DEBUG_DIRECTORY].Size = DebugDirectory->getSize(); |
| 686 | 739 | } |
| 687 | 740 | if (Symbol *Sym = Symtab->findUnderscore("_load_config_used")) { |
| 688 | if (auto *B = dyn_cast<DefinedRegular>(Sym->body())) { | |
| 741 | if (auto *B = dyn_cast<DefinedRegular>(Sym)) { | |
| 689 | 742 | SectionChunk *SC = B->getChunk(); |
| 690 | 743 | assert(B->getRVA() >= SC->getRVA()); |
| 691 | 744 | uint64_t OffsetInChunk = B->getRVA() - SC->getRVA(); |
| ... | ... | @@ -715,7 +768,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() { |
| 715 | 768 | SectionTable = ArrayRef<uint8_t>( |
| 716 | 769 | Buf - OutputSections.size() * sizeof(coff_section), Buf); |
| 717 | 770 | |
| 718 | if (OutputSymtab.empty()) | |
| 771 | if (OutputSymtab.empty() && Strtab.empty()) | |
| 719 | 772 | return; |
| 720 | 773 | |
| 721 | 774 | COFF->PointerToSymbolTable = PointerToSymbolTable; |
| ... | ... | @@ -734,21 +787,40 @@ template <typename PEHeaderTy> void Writer::writeHeader() { |
| 734 | 787 | } |
| 735 | 788 | |
| 736 | 789 | void Writer::openFile(StringRef Path) { |
| 737 | Buffer = check( | |
| 790 | Buffer = CHECK( | |
| 738 | 791 | FileOutputBuffer::create(Path, FileSize, FileOutputBuffer::F_executable), |
| 739 | 792 | "failed to open " + Path); |
| 740 | 793 | } |
| 741 | 794 | |
| 742 | void Writer::fixSafeSEHSymbols() { | |
| 743 | if (!SEHTable) | |
| 795 | void Writer::createSEHTable(OutputSection *RData) { | |
| 796 | // Create SEH table. x86-only. | |
| 797 | if (Config->Machine != I386) | |
| 798 | return; | |
| 799 | ||
| 800 | std::set<Defined *> Handlers; | |
| 801 | ||
| 802 | for (ObjFile *File : ObjFile::Instances) { | |
| 803 | if (!File->SEHCompat) | |
| 804 | return; | |
| 805 | for (uint32_t I : File->SXData) | |
| 806 | if (Symbol *B = File->getSymbol(I)) | |
| 807 | if (B->isLive()) | |
| 808 | Handlers.insert(cast<Defined>(B)); | |
| 809 | } | |
| 810 | ||
| 811 | if (Handlers.empty()) | |
| 744 | 812 | return; |
| 813 | ||
| 814 | SEHTable = make<SEHTableChunk>(Handlers); | |
| 815 | RData->addChunk(SEHTable); | |
| 816 | ||
| 745 | 817 | // Replace the absolute table symbol with a synthetic symbol pointing to the |
| 746 | 818 | // SEHTable chunk so that we can emit base relocations for it and resolve |
| 747 | 819 | // section relative relocations. |
| 748 | 820 | Symbol *T = Symtab->find("___safe_se_handler_table"); |
| 749 | 821 | Symbol *C = Symtab->find("___safe_se_handler_count"); |
| 750 | replaceBody<DefinedSynthetic>(T, T->body()->getName(), SEHTable); | |
| 751 | cast<DefinedAbsolute>(C->body())->setVA(SEHTable->getSize() / 4); | |
| 822 | replaceSymbol<DefinedSynthetic>(T, T->getName(), SEHTable); | |
| 823 | cast<DefinedAbsolute>(C)->setVA(SEHTable->getSize() / 4); | |
| 752 | 824 | } |
| 753 | 825 | |
| 754 | 826 | // Handles /section options to allow users to overwrite |
| ... | ... | @@ -781,6 +853,25 @@ void Writer::writeSections() { |
| 781 | 853 | } |
| 782 | 854 | } |
| 783 | 855 | |
| 856 | void Writer::writeBuildId() { | |
| 857 | // If we're not writing a build id (e.g. because /debug is not specified), | |
| 858 | // then just return; | |
| 859 | if (!Config->Debug) | |
| 860 | return; | |
| 861 | ||
| 862 | assert(BuildId && "BuildId is not set!"); | |
| 863 | ||
| 864 | if (PreviousBuildId.hasValue()) { | |
| 865 | *BuildId->BuildId = *PreviousBuildId; | |
| 866 | BuildId->BuildId->PDB70.Age = BuildId->BuildId->PDB70.Age + 1; | |
| 867 | return; | |
| 868 | } | |
| 869 | ||
| 870 | BuildId->BuildId->Signature.CVSignature = OMF::Signature::PDB70; | |
| 871 | BuildId->BuildId->PDB70.Age = 1; | |
| 872 | llvm::getRandomBytes(BuildId->BuildId->PDB70.Signature, 16); | |
| 873 | } | |
| 874 | ||
| 784 | 875 | // Sort .pdata section contents according to PE/COFF spec 5.5. |
| 785 | 876 | void Writer::sortExceptionTable() { |
| 786 | 877 | OutputSection *Sec = findSection(".pdata"); |
| ... | ... | @@ -795,7 +886,7 @@ void Writer::sortExceptionTable() { |
| 795 | 886 | [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; }); |
| 796 | 887 | return; |
| 797 | 888 | } |
| 798 | if (Config->Machine == ARMNT) { | |
| 889 | if (Config->Machine == ARMNT || Config->Machine == ARM64) { | |
| 799 | 890 | struct Entry { ulittle32_t Begin, Unwind; }; |
| 800 | 891 | sort(parallel::par, (Entry *)Begin, (Entry *)End, |
| 801 | 892 | [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; }); |
| ... | ... | @@ -804,26 +895,6 @@ void Writer::sortExceptionTable() { |
| 804 | 895 | errs() << "warning: don't know how to handle .pdata.\n"; |
| 805 | 896 | } |
| 806 | 897 | |
| 807 | // Backfill the CVSignature in a PDB70 Debug Record. This backfilling allows us | |
| 808 | // to get reproducible builds. | |
| 809 | void Writer::writeBuildId() { | |
| 810 | // There is nothing to backfill if BuildId was not setup. | |
| 811 | if (BuildId == nullptr) | |
| 812 | return; | |
| 813 | ||
| 814 | assert(BuildId->DI->Signature.CVSignature == OMF::Signature::PDB70 && | |
| 815 | "only PDB 7.0 is supported"); | |
| 816 | assert(sizeof(BuildId->DI->PDB70.Signature) == 16 && | |
| 817 | "signature size mismatch"); | |
| 818 | ||
| 819 | // Compute an MD5 hash. | |
| 820 | ArrayRef<uint8_t> Buf(Buffer->getBufferStart(), Buffer->getBufferEnd()); | |
| 821 | memcpy(BuildId->DI->PDB70.Signature, MD5::hash(Buf).data(), 16); | |
| 822 | ||
| 823 | // TODO(compnerd) track the Age | |
| 824 | BuildId->DI->PDB70.Age = 1; | |
| 825 | } | |
| 826 | ||
| 827 | 898 | OutputSection *Writer::findSection(StringRef Name) { |
| 828 | 899 | for (OutputSection *Sec : OutputSections) |
| 829 | 900 | if (Sec->getName() == Name) |
deps/lld/COFF/Writer.h+2-4| ... | ... | @@ -18,11 +18,9 @@ |
| 18 | 18 | |
| 19 | 19 | namespace lld { |
| 20 | 20 | namespace coff { |
| 21 | class SymbolTable; | |
| 22 | ||
| 23 | 21 | static const int PageSize = 4096; |
| 24 | 22 | |
| 25 | void writeResult(SymbolTable *T); | |
| 23 | void writeResult(); | |
| 26 | 24 | |
| 27 | 25 | // OutputSection represents a section in an output file. It's a |
| 28 | 26 | // container of chunks. OutputSection and Chunk are 1:N relationship. |
| ... | ... | @@ -36,7 +34,7 @@ public: |
| 36 | 34 | void setFileOffset(uint64_t); |
| 37 | 35 | void addChunk(Chunk *C); |
| 38 | 36 | llvm::StringRef getName() { return Name; } |
| 39 | std::vector<Chunk *> &getChunks() { return Chunks; } | |
| 37 | ArrayRef<Chunk *> getChunks() { return Chunks; } | |
| 40 | 38 | void addPermissions(uint32_t C); |
| 41 | 39 | void setPermissions(uint32_t C); |
| 42 | 40 | uint32_t getPermissions() { return Header.Characteristics & PermMask; } |
deps/lld/Common/Args.cpp created+62| ... | ... | @@ -0,0 +1,62 @@ |
| 1 | //===- Args.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/Args.h" | |
| 11 | #include "lld/Common/ErrorHandler.h" | |
| 12 | #include "llvm/ADT/SmallVector.h" | |
| 13 | #include "llvm/ADT/StringExtras.h" | |
| 14 | #include "llvm/ADT/StringRef.h" | |
| 15 | #include "llvm/Option/ArgList.h" | |
| 16 | ||
| 17 | using namespace llvm; | |
| 18 | using namespace lld; | |
| 19 | ||
| 20 | int lld::args::getInteger(opt::InputArgList &Args, unsigned Key, int Default) { | |
| 21 | int V = Default; | |
| 22 | if (auto *Arg = Args.getLastArg(Key)) { | |
| 23 | StringRef S = Arg->getValue(); | |
| 24 | if (!to_integer(S, V, 10)) | |
| 25 | error(Arg->getSpelling() + ": number expected, but got '" + S + "'"); | |
| 26 | } | |
| 27 | return V; | |
| 28 | } | |
| 29 | ||
| 30 | std::vector<StringRef> lld::args::getStrings(opt::InputArgList &Args, int Id) { | |
| 31 | std::vector<StringRef> V; | |
| 32 | for (auto *Arg : Args.filtered(Id)) | |
| 33 | V.push_back(Arg->getValue()); | |
| 34 | return V; | |
| 35 | } | |
| 36 | ||
| 37 | uint64_t lld::args::getZOptionValue(opt::InputArgList &Args, int Id, | |
| 38 | StringRef Key, uint64_t Default) { | |
| 39 | for (auto *Arg : Args.filtered(Id)) { | |
| 40 | std::pair<StringRef, StringRef> KV = StringRef(Arg->getValue()).split('='); | |
| 41 | if (KV.first == Key) { | |
| 42 | uint64_t Result = Default; | |
| 43 | if (!to_integer(KV.second, Result)) | |
| 44 | error("invalid " + Key + ": " + KV.second); | |
| 45 | return Result; | |
| 46 | } | |
| 47 | } | |
| 48 | return Default; | |
| 49 | } | |
| 50 | ||
| 51 | std::vector<StringRef> lld::args::getLines(MemoryBufferRef MB) { | |
| 52 | SmallVector<StringRef, 0> Arr; | |
| 53 | MB.getBuffer().split(Arr, '\n'); | |
| 54 | ||
| 55 | std::vector<StringRef> Ret; | |
| 56 | for (StringRef S : Arr) { | |
| 57 | S = S.trim(); | |
| 58 | if (!S.empty() && S[0] != '#') | |
| 59 | Ret.push_back(S); | |
| 60 | } | |
| 61 | return Ret; | |
| 62 | } |
deps/lld/Common/CMakeLists.txt created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | if(NOT LLD_BUILT_STANDALONE) | |
| 2 | set(tablegen_deps intrinsics_gen) | |
| 3 | endif() | |
| 4 | ||
| 5 | add_lld_library(lldCommon | |
| 6 | Args.cpp | |
| 7 | ErrorHandler.cpp | |
| 8 | Memory.cpp | |
| 9 | Reproduce.cpp | |
| 10 | Strings.cpp | |
| 11 | TargetOptionsCommandFlags.cpp | |
| 12 | Threads.cpp | |
| 13 | Version.cpp | |
| 14 | ||
| 15 | ADDITIONAL_HEADER_DIRS | |
| 16 | ${LLD_INCLUDE_DIR}/lld/Common | |
| 17 | ||
| 18 | LINK_COMPONENTS | |
| 19 | Codegen | |
| 20 | Core | |
| 21 | Demangle | |
| 22 | MC | |
| 23 | Option | |
| 24 | Support | |
| 25 | Target | |
| 26 | ||
| 27 | LINK_LIBS | |
| 28 | ${LLVM_PTHREAD_LIB} | |
| 29 | ||
| 30 | DEPENDS | |
| 31 | ${tablegen_deps} | |
| 32 | ) |
deps/lld/Common/ErrorHandler.cpp created+118| ... | ... | @@ -0,0 +1,118 @@ |
| 1 | //===- ErrorHandler.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/ErrorHandler.h" | |
| 11 | ||
| 12 | #include "lld/Common/Threads.h" | |
| 13 | ||
| 14 | #include "llvm/ADT/Twine.h" | |
| 15 | #include "llvm/Support/Error.h" | |
| 16 | #include "llvm/Support/ManagedStatic.h" | |
| 17 | #include "llvm/Support/raw_ostream.h" | |
| 18 | #include <mutex> | |
| 19 | ||
| 20 | #if !defined(_MSC_VER) && !defined(__MINGW32__) | |
| 21 | #include <unistd.h> | |
| 22 | #endif | |
| 23 | ||
| 24 | using namespace llvm; | |
| 25 | using namespace lld; | |
| 26 | ||
| 27 | // The functions defined in this file can be called from multiple threads, | |
| 28 | // but outs() or errs() are not thread-safe. We protect them using a mutex. | |
| 29 | static std::mutex Mu; | |
| 30 | ||
| 31 | // Prints "\n" or does nothing, depending on Msg contents of | |
| 32 | // the previous call of this function. | |
| 33 | static void newline(raw_ostream *ErrorOS, const Twine &Msg) { | |
| 34 | // True if the previous error message contained "\n". | |
| 35 | // We want to separate multi-line error messages with a newline. | |
| 36 | static bool Flag; | |
| 37 | ||
| 38 | if (Flag) | |
| 39 | *ErrorOS << "\n"; | |
| 40 | Flag = StringRef(Msg.str()).contains('\n'); | |
| 41 | } | |
| 42 | ||
| 43 | ErrorHandler &lld::errorHandler() { | |
| 44 | static ErrorHandler Handler; | |
| 45 | return Handler; | |
| 46 | } | |
| 47 | ||
| 48 | void lld::exitLld(int Val) { | |
| 49 | // Delete the output buffer so that any tempory file is deleted. | |
| 50 | errorHandler().OutputBuffer.reset(); | |
| 51 | ||
| 52 | // Dealloc/destroy ManagedStatic variables before calling | |
| 53 | // _exit(). In a non-LTO build, this is a nop. In an LTO | |
| 54 | // build allows us to get the output of -time-passes. | |
| 55 | llvm_shutdown(); | |
| 56 | ||
| 57 | outs().flush(); | |
| 58 | errs().flush(); | |
| 59 | _exit(Val); | |
| 60 | } | |
| 61 | ||
| 62 | void ErrorHandler::print(StringRef S, raw_ostream::Colors C) { | |
| 63 | *ErrorOS << LogName << ": "; | |
| 64 | if (ColorDiagnostics) { | |
| 65 | ErrorOS->changeColor(C, true); | |
| 66 | *ErrorOS << S; | |
| 67 | ErrorOS->resetColor(); | |
| 68 | } else { | |
| 69 | *ErrorOS << S; | |
| 70 | } | |
| 71 | } | |
| 72 | ||
| 73 | void ErrorHandler::log(const Twine &Msg) { | |
| 74 | if (Verbose) { | |
| 75 | std::lock_guard<std::mutex> Lock(Mu); | |
| 76 | *ErrorOS << LogName << ": " << Msg << "\n"; | |
| 77 | } | |
| 78 | } | |
| 79 | ||
| 80 | void ErrorHandler::message(const Twine &Msg) { | |
| 81 | std::lock_guard<std::mutex> Lock(Mu); | |
| 82 | outs() << Msg << "\n"; | |
| 83 | outs().flush(); | |
| 84 | } | |
| 85 | ||
| 86 | void ErrorHandler::warn(const Twine &Msg) { | |
| 87 | if (FatalWarnings) { | |
| 88 | error(Msg); | |
| 89 | return; | |
| 90 | } | |
| 91 | ||
| 92 | std::lock_guard<std::mutex> Lock(Mu); | |
| 93 | newline(ErrorOS, Msg); | |
| 94 | print("warning: ", raw_ostream::MAGENTA); | |
| 95 | *ErrorOS << Msg << "\n"; | |
| 96 | } | |
| 97 | ||
| 98 | void ErrorHandler::error(const Twine &Msg) { | |
| 99 | std::lock_guard<std::mutex> Lock(Mu); | |
| 100 | newline(ErrorOS, Msg); | |
| 101 | ||
| 102 | if (ErrorLimit == 0 || ErrorCount < ErrorLimit) { | |
| 103 | print("error: ", raw_ostream::RED); | |
| 104 | *ErrorOS << Msg << "\n"; | |
| 105 | } else if (ErrorCount == ErrorLimit) { | |
| 106 | print("error: ", raw_ostream::RED); | |
| 107 | *ErrorOS << ErrorLimitExceededMsg << "\n"; | |
| 108 | if (ExitEarly) | |
| 109 | exitLld(1); | |
| 110 | } | |
| 111 | ||
| 112 | ++ErrorCount; | |
| 113 | } | |
| 114 | ||
| 115 | void ErrorHandler::fatal(const Twine &Msg) { | |
| 116 | error(Msg); | |
| 117 | exitLld(1); | |
| 118 | } |
deps/lld/Common/Memory.cpp created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | //===- Memory.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/Memory.h" | |
| 11 | ||
| 12 | using namespace llvm; | |
| 13 | using namespace lld; | |
| 14 | ||
| 15 | BumpPtrAllocator lld::BAlloc; | |
| 16 | StringSaver lld::Saver{BAlloc}; | |
| 17 | std::vector<SpecificAllocBase *> lld::SpecificAllocBase::Instances; | |
| 18 | ||
| 19 | void lld::freeArena() { | |
| 20 | for (SpecificAllocBase *Alloc : SpecificAllocBase::Instances) | |
| 21 | Alloc->reset(); | |
| 22 | BAlloc.Reset(); | |
| 23 | } |
deps/lld/Common/Reproduce.cpp created+66| ... | ... | @@ -0,0 +1,66 @@ |
| 1 | //===- Reproduce.cpp - Utilities for creating reproducers -----------------===// | |
| 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/Reproduce.h" | |
| 11 | #include "llvm/Option/Arg.h" | |
| 12 | #include "llvm/Support/Error.h" | |
| 13 | #include "llvm/Support/FileSystem.h" | |
| 14 | #include "llvm/Support/Path.h" | |
| 15 | ||
| 16 | using namespace lld; | |
| 17 | using namespace llvm; | |
| 18 | using namespace llvm::sys; | |
| 19 | ||
| 20 | // Makes a given pathname an absolute path first, and then remove | |
| 21 | // beginning /. For example, "../foo.o" is converted to "home/john/foo.o", | |
| 22 | // assuming that the current directory is "/home/john/bar". | |
| 23 | // Returned string is a forward slash separated path even on Windows to avoid | |
| 24 | // a mess with backslash-as-escape and backslash-as-path-separator. | |
| 25 | std::string lld::relativeToRoot(StringRef Path) { | |
| 26 | SmallString<128> Abs = Path; | |
| 27 | if (fs::make_absolute(Abs)) | |
| 28 | return Path; | |
| 29 | path::remove_dots(Abs, /*remove_dot_dot=*/true); | |
| 30 | ||
| 31 | // This is Windows specific. root_name() returns a drive letter | |
| 32 | // (e.g. "c:") or a UNC name (//net). We want to keep it as part | |
| 33 | // of the result. | |
| 34 | SmallString<128> Res; | |
| 35 | StringRef Root = path::root_name(Abs); | |
| 36 | if (Root.endswith(":")) | |
| 37 | Res = Root.drop_back(); | |
| 38 | else if (Root.startswith("//")) | |
| 39 | Res = Root.substr(2); | |
| 40 | ||
| 41 | path::append(Res, path::relative_path(Abs)); | |
| 42 | return path::convert_to_slash(Res); | |
| 43 | } | |
| 44 | ||
| 45 | // Quote a given string if it contains a space character. | |
| 46 | std::string lld::quote(StringRef S) { | |
| 47 | if (S.contains(' ')) | |
| 48 | return ("\"" + S + "\"").str(); | |
| 49 | return S; | |
| 50 | } | |
| 51 | ||
| 52 | std::string lld::rewritePath(StringRef S) { | |
| 53 | if (fs::exists(S)) | |
| 54 | return relativeToRoot(S); | |
| 55 | return S; | |
| 56 | } | |
| 57 | ||
| 58 | std::string lld::toString(const opt::Arg &Arg) { | |
| 59 | std::string K = Arg.getSpelling(); | |
| 60 | if (Arg.getNumValues() == 0) | |
| 61 | return K; | |
| 62 | std::string V = quote(Arg.getValue()); | |
| 63 | if (Arg.getOption().getRenderStyle() == opt::Option::RenderJoinedStyle) | |
| 64 | return K + V; | |
| 65 | return K + " " + V; | |
| 66 | } |
deps/lld/Common/Strings.cpp created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 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 "lld/Common/Strings.h" | |
| 11 | #include "llvm/Demangle/Demangle.h" | |
| 12 | ||
| 13 | using namespace llvm; | |
| 14 | using namespace lld; | |
| 15 | ||
| 16 | // Returns the demangled C++ symbol name for Name. | |
| 17 | Optional<std::string> lld::demangleItanium(StringRef Name) { | |
| 18 | // itaniumDemangle can be used to demangle strings other than symbol | |
| 19 | // names which do not necessarily start with "_Z". Name can be | |
| 20 | // either a C or C++ symbol. Don't call itaniumDemangle if the name | |
| 21 | // does not look like a C++ symbol name to avoid getting unexpected | |
| 22 | // result for a C symbol that happens to match a mangled type name. | |
| 23 | if (!Name.startswith("_Z")) | |
| 24 | return None; | |
| 25 | ||
| 26 | char *Buf = itaniumDemangle(Name.str().c_str(), nullptr, nullptr, nullptr); | |
| 27 | if (!Buf) | |
| 28 | return None; | |
| 29 | std::string S(Buf); | |
| 30 | free(Buf); | |
| 31 | return S; | |
| 32 | } |
deps/lld/Common/TargetOptionsCommandFlags.cpp created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | //===-- TargetOptionsCommandFlags.cpp ---------------------------*- 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 exists as a place for global variables defined in LLVM's | |
| 11 | // CodeGen/CommandFlags.def. By putting the resulting object file in | |
| 12 | // an archive and linking with it, the definitions will automatically be | |
| 13 | // included when needed and skipped when already present. | |
| 14 | // | |
| 15 | //===----------------------------------------------------------------------===// | |
| 16 | ||
| 17 | #include "lld/Common/TargetOptionsCommandFlags.h" | |
| 18 | ||
| 19 | #include "llvm/CodeGen/CommandFlags.def" | |
| 20 | #include "llvm/Target/TargetOptions.h" | |
| 21 | ||
| 22 | // Define an externally visible version of | |
| 23 | // InitTargetOptionsFromCodeGenFlags, so that its functionality can be | |
| 24 | // used without having to include llvm/CodeGen/CommandFlags.def, which | |
| 25 | // would lead to multiple definitions of the command line flags. | |
| 26 | llvm::TargetOptions lld::InitTargetOptionsFromCodeGenFlags() { | |
| 27 | return ::InitTargetOptionsFromCodeGenFlags(); | |
| 28 | } | |
| 29 | ||
| 30 | llvm::Optional<llvm::CodeModel::Model> lld::GetCodeModelFromCMModel() { | |
| 31 | return getCodeModel(); | |
| 32 | } |
deps/lld/Common/Threads.cpp created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | //===- Threads.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/Threads.h" | |
| 11 | ||
| 12 | bool lld::ThreadsEnabled = true; |
deps/lld/Common/Version.cpp created+43| ... | ... | @@ -0,0 +1,43 @@ |
| 1 | //===- lib/Common/Version.cpp - LLD Version Number ---------------*- C++-=====// | |
| 2 | // | |
| 3 | // The LLVM Compiler Infrastructure | |
| 4 | // | |
| 5 | // This file is distributed under the University of Illinois Open Source | |
| 6 | // License. See LICENSE.TXT for details. | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | // | |
| 10 | // This file defines several version-related utility functions for LLD. | |
| 11 | // | |
| 12 | //===----------------------------------------------------------------------===// | |
| 13 | ||
| 14 | #include "lld/Common/Version.h" | |
| 15 | ||
| 16 | using namespace llvm; | |
| 17 | ||
| 18 | // Returns an SVN repository path, which is usually "trunk". | |
| 19 | static std::string getRepositoryPath() { | |
| 20 | StringRef S = LLD_REPOSITORY_STRING; | |
| 21 | size_t Pos = S.find("lld/"); | |
| 22 | if (Pos != StringRef::npos) | |
| 23 | return S.substr(Pos + 4); | |
| 24 | return S; | |
| 25 | } | |
| 26 | ||
| 27 | // Returns an SVN repository name, e.g., " (trunk 284614)" | |
| 28 | // or an empty string if no repository info is available. | |
| 29 | static std::string getRepository() { | |
| 30 | std::string Repo = getRepositoryPath(); | |
| 31 | std::string Rev = LLD_REVISION_STRING; | |
| 32 | ||
| 33 | if (Repo.empty() && Rev.empty()) | |
| 34 | return ""; | |
| 35 | if (!Repo.empty() && !Rev.empty()) | |
| 36 | return " (" + Repo + " " + Rev + ")"; | |
| 37 | return " (" + Repo + Rev + ")"; | |
| 38 | } | |
| 39 | ||
| 40 | // Returns a version string, e.g., "LLD 4.0 (lld/trunk 284614)". | |
| 41 | std::string lld::getLLDVersion() { | |
| 42 | return "LLD " + std::string(LLD_VERSION_STRING) + getRepository(); | |
| 43 | } |
deps/lld/ELF/AArch64ErrataFix.cpp created+649| ... | ... | @@ -0,0 +1,649 @@ |
| 1 | //===- AArch64ErrataFix.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 | // This file implements Section Patching for the purpose of working around | |
| 10 | // errata in CPUs. The general principle is that an erratum sequence of one or | |
| 11 | // more instructions is detected in the instruction stream, one of the | |
| 12 | // instructions in the sequence is replaced with a branch to a patch sequence | |
| 13 | // of replacement instructions. At the end of the replacement sequence the | |
| 14 | // patch branches back to the instruction stream. | |
| 15 | ||
| 16 | // This technique is only suitable for fixing an erratum when: | |
| 17 | // - There is a set of necessary conditions required to trigger the erratum that | |
| 18 | // can be detected at static link time. | |
| 19 | // - There is a set of replacement instructions that can be used to remove at | |
| 20 | // least one of the necessary conditions that trigger the erratum. | |
| 21 | // - We can overwrite an instruction in the erratum sequence with a branch to | |
| 22 | // the replacement sequence. | |
| 23 | // - We can place the replacement sequence within range of the branch. | |
| 24 | ||
| 25 | // FIXME: | |
| 26 | // - The implementation here only supports one patch, the AArch64 Cortex-53 | |
| 27 | // errata 843419 that affects r0p0, r0p1, r0p2 and r0p4 versions of the core. | |
| 28 | // To keep the initial version simple there is no support for multiple | |
| 29 | // architectures or selection of different patches. | |
| 30 | //===----------------------------------------------------------------------===// | |
| 31 | ||
| 32 | #include "AArch64ErrataFix.h" | |
| 33 | #include "Config.h" | |
| 34 | #include "LinkerScript.h" | |
| 35 | #include "OutputSections.h" | |
| 36 | #include "Relocations.h" | |
| 37 | #include "Strings.h" | |
| 38 | #include "Symbols.h" | |
| 39 | #include "SyntheticSections.h" | |
| 40 | #include "Target.h" | |
| 41 | #include "lld/Common/Memory.h" | |
| 42 | ||
| 43 | #include "llvm/Support/Endian.h" | |
| 44 | #include "llvm/Support/raw_ostream.h" | |
| 45 | #include <algorithm> | |
| 46 | ||
| 47 | using namespace llvm; | |
| 48 | using namespace llvm::ELF; | |
| 49 | using namespace llvm::object; | |
| 50 | using namespace llvm::support; | |
| 51 | using namespace llvm::support::endian; | |
| 52 | ||
| 53 | using namespace lld; | |
| 54 | using namespace lld::elf; | |
| 55 | ||
| 56 | // Helper functions to identify instructions and conditions needed to trigger | |
| 57 | // the Cortex-A53-843419 erratum. | |
| 58 | ||
| 59 | // ADRP | |
| 60 | // | 1 | immlo (2) | 1 | 0 0 0 0 | immhi (19) | Rd (5) | | |
| 61 | static bool isADRP(uint32_t Instr) { | |
| 62 | return (Instr & 0x9f000000) == 0x90000000; | |
| 63 | } | |
| 64 | ||
| 65 | // Load and store bit patterns from ARMv8-A ARM ARM. | |
| 66 | // Instructions appear in order of appearance starting from table in | |
| 67 | // C4.1.3 Loads and Stores. | |
| 68 | ||
| 69 | // All loads and stores have 1 (at bit postion 27), (0 at bit position 25). | |
| 70 | // | op0 x op1 (2) | 1 op2 0 op3 (2) | x | op4 (5) | xxxx | op5 (2) | x (10) | | |
| 71 | static bool isLoadStoreClass(uint32_t Instr) { | |
| 72 | return (Instr & 0x0a000000) == 0x08000000; | |
| 73 | } | |
| 74 | ||
| 75 | // LDN/STN multiple no offset | |
| 76 | // | 0 Q 00 | 1100 | 0 L 00 | 0000 | opcode (4) | size (2) | Rn (5) | Rt (5) | | |
| 77 | // LDN/STN multiple post-indexed | |
| 78 | // | 0 Q 00 | 1100 | 1 L 0 | Rm (5)| opcode (4) | size (2) | Rn (5) | Rt (5) | | |
| 79 | // L == 0 for stores. | |
| 80 | ||
| 81 | // Utility routine to decode opcode field of LDN/STN multiple structure | |
| 82 | // instructions to find the ST1 instructions. | |
| 83 | // opcode == 0010 ST1 4 registers. | |
| 84 | // opcode == 0110 ST1 3 registers. | |
| 85 | // opcode == 0111 ST1 1 register. | |
| 86 | // opcode == 1010 ST1 2 registers. | |
| 87 | static bool isST1MultipleOpcode(uint32_t Instr) { | |
| 88 | return (Instr & 0x0000f000) == 0x00002000 || | |
| 89 | (Instr & 0x0000f000) == 0x00006000 || | |
| 90 | (Instr & 0x0000f000) == 0x00007000 || | |
| 91 | (Instr & 0x0000f000) == 0x0000a000; | |
| 92 | } | |
| 93 | ||
| 94 | static bool isST1Multiple(uint32_t Instr) { | |
| 95 | return (Instr & 0xbfff0000) == 0x0c000000 && isST1MultipleOpcode(Instr); | |
| 96 | } | |
| 97 | ||
| 98 | // Writes to Rn (writeback). | |
| 99 | static bool isST1MultiplePost(uint32_t Instr) { | |
| 100 | return (Instr & 0xbfe00000) == 0x0c800000 && isST1MultipleOpcode(Instr); | |
| 101 | } | |
| 102 | ||
| 103 | // LDN/STN single no offset | |
| 104 | // | 0 Q 00 | 1101 | 0 L R 0 | 0000 | opc (3) S | size (2) | Rn (5) | Rt (5)| | |
| 105 | // LDN/STN single post-indexed | |
| 106 | // | 0 Q 00 | 1101 | 1 L R | Rm (5) | opc (3) S | size (2) | Rn (5) | Rt (5)| | |
| 107 | // L == 0 for stores | |
| 108 | ||
| 109 | // Utility routine to decode opcode field of LDN/STN single structure | |
| 110 | // instructions to find the ST1 instructions. | |
| 111 | // R == 0 for ST1 and ST3, R == 1 for ST2 and ST4. | |
| 112 | // opcode == 000 ST1 8-bit. | |
| 113 | // opcode == 010 ST1 16-bit. | |
| 114 | // opcode == 100 ST1 32 or 64-bit (Size determines which). | |
| 115 | static bool isST1SingleOpcode(uint32_t Instr) { | |
| 116 | return (Instr & 0x0040e000) == 0x00000000 || | |
| 117 | (Instr & 0x0040e000) == 0x00004000 || | |
| 118 | (Instr & 0x0040e000) == 0x00008000; | |
| 119 | } | |
| 120 | ||
| 121 | static bool isST1Single(uint32_t Instr) { | |
| 122 | return (Instr & 0xbfff0000) == 0x0d000000 && isST1SingleOpcode(Instr); | |
| 123 | } | |
| 124 | ||
| 125 | // Writes to Rn (writeback). | |
| 126 | static bool isST1SinglePost(uint32_t Instr) { | |
| 127 | return (Instr & 0xbfe00000) == 0x0d800000 && isST1SingleOpcode(Instr); | |
| 128 | } | |
| 129 | ||
| 130 | static bool isST1(uint32_t Instr) { | |
| 131 | return isST1Multiple(Instr) || isST1MultiplePost(Instr) || | |
| 132 | isST1Single(Instr) || isST1SinglePost(Instr); | |
| 133 | } | |
| 134 | ||
| 135 | // Load/store exclusive | |
| 136 | // | size (2) 00 | 1000 | o2 L o1 | Rs (5) | o0 | Rt2 (5) | Rn (5) | Rt (5) | | |
| 137 | // L == 0 for Stores. | |
| 138 | static bool isLoadStoreExclusive(uint32_t Instr) { | |
| 139 | return (Instr & 0x3f000000) == 0x08000000; | |
| 140 | } | |
| 141 | ||
| 142 | static bool isLoadExclusive(uint32_t Instr) { | |
| 143 | return (Instr & 0x3f400000) == 0x08400000; | |
| 144 | } | |
| 145 | ||
| 146 | // Load register literal | |
| 147 | // | opc (2) 01 | 1 V 00 | imm19 | Rt (5) | | |
| 148 | static bool isLoadLiteral(uint32_t Instr) { | |
| 149 | return (Instr & 0x3b000000) == 0x18000000; | |
| 150 | } | |
| 151 | ||
| 152 | // Load/store no-allocate pair | |
| 153 | // (offset) | |
| 154 | // | opc (2) 10 | 1 V 00 | 0 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) | | |
| 155 | // L == 0 for stores. | |
| 156 | // Never writes to register | |
| 157 | static bool isSTNP(uint32_t Instr) { | |
| 158 | return (Instr & 0x3bc00000) == 0x28000000; | |
| 159 | } | |
| 160 | ||
| 161 | // Load/store register pair | |
| 162 | // (post-indexed) | |
| 163 | // | opc (2) 10 | 1 V 00 | 1 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) | | |
| 164 | // L == 0 for stores, V == 0 for Scalar, V == 1 for Simd/FP | |
| 165 | // Writes to Rn. | |
| 166 | static bool isSTPPost(uint32_t Instr) { | |
| 167 | return (Instr & 0x3bc00000) == 0x28800000; | |
| 168 | } | |
| 169 | ||
| 170 | // (offset) | |
| 171 | // | opc (2) 10 | 1 V 01 | 0 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) | | |
| 172 | static bool isSTPOffset(uint32_t Instr) { | |
| 173 | return (Instr & 0x3bc00000) == 0x29000000; | |
| 174 | } | |
| 175 | ||
| 176 | // (pre-index) | |
| 177 | // | opc (2) 10 | 1 V 01 | 1 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) | | |
| 178 | // Writes to Rn. | |
| 179 | static bool isSTPPre(uint32_t Instr) { | |
| 180 | return (Instr & 0x3bc00000) == 0x29800000; | |
| 181 | } | |
| 182 | ||
| 183 | static bool isSTP(uint32_t Instr) { | |
| 184 | return isSTPPost(Instr) || isSTPOffset(Instr) || isSTPPre(Instr); | |
| 185 | } | |
| 186 | ||
| 187 | // Load/store register (unscaled immediate) | |
| 188 | // | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 00 | Rn (5) | Rt (5) | | |
| 189 | // V == 0 for Scalar, V == 1 for Simd/FP. | |
| 190 | static bool isLoadStoreUnscaled(uint32_t Instr) { | |
| 191 | return (Instr & 0x3b000c00) == 0x38000000; | |
| 192 | } | |
| 193 | ||
| 194 | // Load/store register (immediate post-indexed) | |
| 195 | // | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 01 | Rn (5) | Rt (5) | | |
| 196 | static bool isLoadStoreImmediatePost(uint32_t Instr) { | |
| 197 | return (Instr & 0x3b200c00) == 0x38000400; | |
| 198 | } | |
| 199 | ||
| 200 | // Load/store register (unprivileged) | |
| 201 | // | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 10 | Rn (5) | Rt (5) | | |
| 202 | static bool isLoadStoreUnpriv(uint32_t Instr) { | |
| 203 | return (Instr & 0x3b200c00) == 0x38000800; | |
| 204 | } | |
| 205 | ||
| 206 | // Load/store register (immediate pre-indexed) | |
| 207 | // | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 11 | Rn (5) | Rt (5) | | |
| 208 | static bool isLoadStoreImmediatePre(uint32_t Instr) { | |
| 209 | return (Instr & 0x3b200c00) == 0x38000c00; | |
| 210 | } | |
| 211 | ||
| 212 | // Load/store register (register offset) | |
| 213 | // | size (2) 11 | 1 V 00 | opc (2) 1 | Rm (5) | option (3) S | 10 | Rn | Rt | | |
| 214 | static bool isLoadStoreRegisterOff(uint32_t Instr) { | |
| 215 | return (Instr & 0x3b200c00) == 0x38200800; | |
| 216 | } | |
| 217 | ||
| 218 | // Load/store register (unsigned immediate) | |
| 219 | // | size (2) 11 | 1 V 01 | opc (2) | imm12 | Rn (5) | Rt (5) | | |
| 220 | static bool isLoadStoreRegisterUnsigned(uint32_t Instr) { | |
| 221 | return (Instr & 0x3b000000) == 0x39000000; | |
| 222 | } | |
| 223 | ||
| 224 | // Rt is always in bit position 0 - 4. | |
| 225 | static uint32_t getRt(uint32_t Instr) { return (Instr & 0x1f); } | |
| 226 | ||
| 227 | // Rn is always in bit position 5 - 9. | |
| 228 | static uint32_t getRn(uint32_t Instr) { return (Instr >> 5) & 0x1f; } | |
| 229 | ||
| 230 | // C4.1.2 Branches, Exception Generating and System instructions | |
| 231 | // | op0 (3) 1 | 01 op1 (4) | x (22) | | |
| 232 | // op0 == 010 101 op1 == 0xxx Conditional Branch. | |
| 233 | // op0 == 110 101 op1 == 1xxx Unconditional Branch Register. | |
| 234 | // op0 == x00 101 op1 == xxxx Unconditional Branch immediate. | |
| 235 | // op0 == x01 101 op1 == 0xxx Compare and branch immediate. | |
| 236 | // op0 == x01 101 op1 == 1xxx Test and branch immediate. | |
| 237 | static bool isBranch(uint32_t Instr) { | |
| 238 | return ((Instr & 0xfe000000) == 0xd6000000) || // Cond branch. | |
| 239 | ((Instr & 0xfe000000) == 0x54000000) || // Uncond branch reg. | |
| 240 | ((Instr & 0x7c000000) == 0x14000000) || // Uncond branch imm. | |
| 241 | ((Instr & 0x7c000000) == 0x34000000); // Compare and test branch. | |
| 242 | } | |
| 243 | ||
| 244 | static bool isV8SingleRegisterNonStructureLoadStore(uint32_t Instr) { | |
| 245 | return isLoadStoreUnscaled(Instr) || isLoadStoreImmediatePost(Instr) || | |
| 246 | isLoadStoreUnpriv(Instr) || isLoadStoreImmediatePre(Instr) || | |
| 247 | isLoadStoreRegisterOff(Instr) || isLoadStoreRegisterUnsigned(Instr); | |
| 248 | } | |
| 249 | ||
| 250 | // Note that this function refers to v8.0 only and does not include the | |
| 251 | // additional load and store instructions added for in later revisions of | |
| 252 | // the architecture such as the Atomic memory operations introduced | |
| 253 | // in v8.1. | |
| 254 | static bool isV8NonStructureLoad(uint32_t Instr) { | |
| 255 | if (isLoadExclusive(Instr)) | |
| 256 | return true; | |
| 257 | if (isLoadLiteral(Instr)) | |
| 258 | return true; | |
| 259 | else if (isV8SingleRegisterNonStructureLoadStore(Instr)) { | |
| 260 | // For Load and Store single register, Loads are derived from a | |
| 261 | // combination of the Size, V and Opc fields. | |
| 262 | uint32_t Size = (Instr >> 30) & 0xff; | |
| 263 | uint32_t V = (Instr >> 26) & 0x1; | |
| 264 | uint32_t Opc = (Instr >> 22) & 0x3; | |
| 265 | // For the load and store instructions that we are decoding. | |
| 266 | // Opc == 0 are all stores. | |
| 267 | // Opc == 1 with a couple of exceptions are loads. The exceptions are: | |
| 268 | // Size == 00 (0), V == 1, Opc == 10 (2) which is a store and | |
| 269 | // Size == 11 (3), V == 0, Opc == 10 (2) which is a prefetch. | |
| 270 | return Opc != 0 && !(Size == 0 && V == 1 && Opc == 2) && | |
| 271 | !(Size == 3 && V == 0 && Opc == 2); | |
| 272 | } | |
| 273 | return false; | |
| 274 | } | |
| 275 | ||
| 276 | // The following decode instructions are only complete up to the instructions | |
| 277 | // needed for errata 843419. | |
| 278 | ||
| 279 | // Instruction with writeback updates the index register after the load/store. | |
| 280 | static bool hasWriteback(uint32_t Instr) { | |
| 281 | return isLoadStoreImmediatePre(Instr) || isLoadStoreImmediatePost(Instr) || | |
| 282 | isSTPPre(Instr) || isSTPPost(Instr) || isST1SinglePost(Instr) || | |
| 283 | isST1MultiplePost(Instr); | |
| 284 | } | |
| 285 | ||
| 286 | // For the load and store class of instructions, a load can write to the | |
| 287 | // destination register, a load and a store can write to the base register when | |
| 288 | // the instruction has writeback. | |
| 289 | static bool doesLoadStoreWriteToReg(uint32_t Instr, uint32_t Reg) { | |
| 290 | return (isV8NonStructureLoad(Instr) && getRt(Instr) == Reg) || | |
| 291 | (hasWriteback(Instr) && getRn(Instr) == Reg); | |
| 292 | } | |
| 293 | ||
| 294 | // Scanner for Cortex-A53 errata 843419 | |
| 295 | // Full details are available in the Cortex A53 MPCore revision 0 Software | |
| 296 | // Developers Errata Notice (ARM-EPM-048406). | |
| 297 | // | |
| 298 | // The instruction sequence that triggers the erratum is common in compiled | |
| 299 | // AArch64 code, however it is sensitive to the offset of the sequence within | |
| 300 | // a 4k page. This means that by scanning and fixing the patch after we have | |
| 301 | // assigned addresses we only need to disassemble and fix instances of the | |
| 302 | // sequence in the range of affected offsets. | |
| 303 | // | |
| 304 | // In summary the erratum conditions are a series of 4 instructions: | |
| 305 | // 1.) An ADRP instruction that writes to register Rn with low 12 bits of | |
| 306 | // address of instruction either 0xff8 or 0xffc. | |
| 307 | // 2.) A load or store instruction that can be: | |
| 308 | // - A single register load or store, of either integer or vector registers. | |
| 309 | // - An STP or STNP, of either integer or vector registers. | |
| 310 | // - An Advanced SIMD ST1 store instruction. | |
| 311 | // - Must not write to Rn, but may optionally read from it. | |
| 312 | // 3.) An optional instruction that is not a branch and does not write to Rn. | |
| 313 | // 4.) A load or store from the Load/store register (unsigned immediate) class | |
| 314 | // that uses Rn as the base address register. | |
| 315 | // | |
| 316 | // Note that we do not attempt to scan for Sequence 2 as described in the | |
| 317 | // Software Developers Errata Notice as this has been assessed to be extremely | |
| 318 | // unlikely to occur in compiled code. This matches gold and ld.bfd behavior. | |
| 319 | ||
| 320 | // Return true if the Instruction sequence Adrp, Instr2, and Instr4 match | |
| 321 | // the erratum sequence. The Adrp, Instr2 and Instr4 correspond to 1.), 2.), | |
| 322 | // and 4.) in the Scanner for Cortex-A53 errata comment above. | |
| 323 | static bool is843419ErratumSequence(uint32_t Instr1, uint32_t Instr2, | |
| 324 | uint32_t Instr4) { | |
| 325 | if (!isADRP(Instr1)) | |
| 326 | return false; | |
| 327 | ||
| 328 | uint32_t Rn = getRt(Instr1); | |
| 329 | return isLoadStoreClass(Instr2) && | |
| 330 | (isLoadStoreExclusive(Instr2) || isLoadLiteral(Instr2) || | |
| 331 | isV8SingleRegisterNonStructureLoadStore(Instr2) || isSTP(Instr2) || | |
| 332 | isSTNP(Instr2) || isST1(Instr2)) && | |
| 333 | !doesLoadStoreWriteToReg(Instr2, Rn) && | |
| 334 | isLoadStoreRegisterUnsigned(Instr4) && getRn(Instr4) == Rn; | |
| 335 | } | |
| 336 | ||
| 337 | // Scan the instruction sequence starting at Offset Off from the base of | |
| 338 | // InputSection IS. We update Off in this function rather than in the caller as | |
| 339 | // we can skip ahead much further into the section when we know how many | |
| 340 | // instructions we've scanned. | |
| 341 | // Return the offset of the load or store instruction in IS that we want to | |
| 342 | // patch or 0 if no patch required. | |
| 343 | static uint64_t scanCortexA53Errata843419(InputSection *IS, uint64_t &Off, | |
| 344 | uint64_t Limit) { | |
| 345 | uint64_t ISAddr = IS->getParent()->Addr + IS->OutSecOff; | |
| 346 | ||
| 347 | // Advance Off so that (ISAddr + Off) modulo 0x1000 is at least 0xff8. | |
| 348 | uint64_t InitialPageOff = (ISAddr + Off) & 0xfff; | |
| 349 | if (InitialPageOff < 0xff8) | |
| 350 | Off += 0xff8 - InitialPageOff; | |
| 351 | ||
| 352 | bool OptionalAllowed = Limit - Off > 12; | |
| 353 | if (Off >= Limit || Limit - Off < 12) { | |
| 354 | // Need at least 3 4-byte sized instructions to trigger erratum. | |
| 355 | Off = Limit; | |
| 356 | return 0; | |
| 357 | } | |
| 358 | ||
| 359 | uint64_t PatchOff = 0; | |
| 360 | const uint8_t *Buf = IS->Data.begin(); | |
| 361 | const ulittle32_t *InstBuf = reinterpret_cast<const ulittle32_t *>(Buf + Off); | |
| 362 | uint32_t Instr1 = *InstBuf++; | |
| 363 | uint32_t Instr2 = *InstBuf++; | |
| 364 | uint32_t Instr3 = *InstBuf++; | |
| 365 | if (is843419ErratumSequence(Instr1, Instr2, Instr3)) { | |
| 366 | PatchOff = Off + 8; | |
| 367 | } else if (OptionalAllowed && !isBranch(Instr3)) { | |
| 368 | uint32_t Instr4 = *InstBuf++; | |
| 369 | if (is843419ErratumSequence(Instr1, Instr2, Instr4)) | |
| 370 | PatchOff = Off + 12; | |
| 371 | } | |
| 372 | if (((ISAddr + Off) & 0xfff) == 0xff8) | |
| 373 | Off += 4; | |
| 374 | else | |
| 375 | Off += 0xffc; | |
| 376 | return PatchOff; | |
| 377 | } | |
| 378 | ||
| 379 | class lld::elf::Patch843419Section : public SyntheticSection { | |
| 380 | public: | |
| 381 | Patch843419Section(InputSection *P, uint64_t Off); | |
| 382 | ||
| 383 | void writeTo(uint8_t *Buf) override; | |
| 384 | ||
| 385 | size_t getSize() const override { return 8; } | |
| 386 | ||
| 387 | uint64_t getLDSTAddr() const; | |
| 388 | ||
| 389 | // The Section we are patching. | |
| 390 | const InputSection *Patchee; | |
| 391 | // The offset of the instruction in the Patchee section we are patching. | |
| 392 | uint64_t PatcheeOffset; | |
| 393 | // A label for the start of the Patch that we can use as a relocation target. | |
| 394 | Symbol *PatchSym; | |
| 395 | }; | |
| 396 | ||
| 397 | lld::elf::Patch843419Section::Patch843419Section(InputSection *P, uint64_t Off) | |
| 398 | : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 4, | |
| 399 | ".text.patch"), | |
| 400 | Patchee(P), PatcheeOffset(Off) { | |
| 401 | this->Parent = P->getParent(); | |
| 402 | PatchSym = addSyntheticLocal( | |
| 403 | Saver.save("__CortexA53843419_" + utohexstr(getLDSTAddr())), STT_FUNC, 0, | |
| 404 | getSize(), *this); | |
| 405 | addSyntheticLocal(Saver.save("$x"), STT_NOTYPE, 0, 0, *this); | |
| 406 | } | |
| 407 | ||
| 408 | uint64_t lld::elf::Patch843419Section::getLDSTAddr() const { | |
| 409 | return Patchee->getParent()->Addr + Patchee->OutSecOff + PatcheeOffset; | |
| 410 | } | |
| 411 | ||
| 412 | void lld::elf::Patch843419Section::writeTo(uint8_t *Buf) { | |
| 413 | // Copy the instruction that we will be replacing with a branch in the | |
| 414 | // Patchee Section. | |
| 415 | write32le(Buf, read32le(Patchee->Data.begin() + PatcheeOffset)); | |
| 416 | ||
| 417 | // Apply any relocation transferred from the original PatcheeSection. | |
| 418 | // For a SyntheticSection Buf already has OutSecOff added, but relocateAlloc | |
| 419 | // also adds OutSecOff so we need to subtract to avoid double counting. | |
| 420 | this->relocateAlloc(Buf - OutSecOff, Buf - OutSecOff + getSize()); | |
| 421 | ||
| 422 | // Return address is the next instruction after the one we have just copied. | |
| 423 | uint64_t S = getLDSTAddr() + 4; | |
| 424 | uint64_t P = PatchSym->getVA() + 4; | |
| 425 | Target->relocateOne(Buf + 4, R_AARCH64_JUMP26, S - P); | |
| 426 | } | |
| 427 | ||
| 428 | void AArch64Err843419Patcher::init() { | |
| 429 | // The AArch64 ABI permits data in executable sections. We must avoid scanning | |
| 430 | // this data as if it were instructions to avoid false matches. We use the | |
| 431 | // mapping symbols in the InputObjects to identify this data, caching the | |
| 432 | // results in SectionMap so we don't have to recalculate it each pass. | |
| 433 | ||
| 434 | // The ABI Section 4.5.4 Mapping symbols; defines local symbols that describe | |
| 435 | // half open intervals [Symbol Value, Next Symbol Value) of code and data | |
| 436 | // within sections. If there is no next symbol then the half open interval is | |
| 437 | // [Symbol Value, End of section). The type, code or data, is determined by | |
| 438 | // the mapping symbol name, $x for code, $d for data. | |
| 439 | auto IsCodeMapSymbol = [](const Symbol *B) { | |
| 440 | return B->getName() == "$x" || B->getName().startswith("$x."); | |
| 441 | }; | |
| 442 | auto IsDataMapSymbol = [](const Symbol *B) { | |
| 443 | return B->getName() == "$d" || B->getName().startswith("$d."); | |
| 444 | }; | |
| 445 | ||
| 446 | // Collect mapping symbols for every executable InputSection. | |
| 447 | for (InputFile *File : ObjectFiles) { | |
| 448 | auto *F = cast<ObjFile<ELF64LE>>(File); | |
| 449 | for (Symbol *B : F->getLocalSymbols()) { | |
| 450 | auto *Def = dyn_cast<Defined>(B); | |
| 451 | if (!Def) | |
| 452 | continue; | |
| 453 | if (!IsCodeMapSymbol(Def) && !IsDataMapSymbol(Def)) | |
| 454 | continue; | |
| 455 | if (auto *Sec = dyn_cast<InputSection>(Def->Section)) | |
| 456 | if (Sec->Flags & SHF_EXECINSTR) | |
| 457 | SectionMap[Sec].push_back(Def); | |
| 458 | } | |
| 459 | } | |
| 460 | // For each InputSection make sure the mapping symbols are in sorted in | |
| 461 | // ascending order and free from consecutive runs of mapping symbols with | |
| 462 | // the same type. For example we must remove the redundant $d.1 from $x.0 | |
| 463 | // $d.0 $d.1 $x.1. | |
| 464 | for (auto &KV : SectionMap) { | |
| 465 | std::vector<const Defined *> &MapSyms = KV.second; | |
| 466 | if (MapSyms.size() <= 1) | |
| 467 | continue; | |
| 468 | std::stable_sort( | |
| 469 | MapSyms.begin(), MapSyms.end(), | |
| 470 | [](const Defined *A, const Defined *B) { return A->Value < B->Value; }); | |
| 471 | MapSyms.erase( | |
| 472 | std::unique(MapSyms.begin(), MapSyms.end(), | |
| 473 | [=](const Defined *A, const Defined *B) { | |
| 474 | return (IsCodeMapSymbol(A) && IsCodeMapSymbol(B)) || | |
| 475 | (IsDataMapSymbol(A) && IsDataMapSymbol(B)); | |
| 476 | }), | |
| 477 | MapSyms.end()); | |
| 478 | } | |
| 479 | Initialized = true; | |
| 480 | } | |
| 481 | ||
| 482 | // Insert the PatchSections we have created back into the | |
| 483 | // InputSectionDescription. As inserting patches alters the addresses of | |
| 484 | // InputSections that follow them, we try and place the patches after all the | |
| 485 | // executable sections, although we may need to insert them earlier if the | |
| 486 | // InputSectionDescription is larger than the maximum branch range. | |
| 487 | void AArch64Err843419Patcher::insertPatches( | |
| 488 | InputSectionDescription &ISD, std::vector<Patch843419Section *> &Patches) { | |
| 489 | uint64_t ISLimit; | |
| 490 | uint64_t PrevISLimit = ISD.Sections.front()->OutSecOff; | |
| 491 | uint64_t PatchUpperBound = PrevISLimit + Target->ThunkSectionSpacing; | |
| 492 | ||
| 493 | // Set the OutSecOff of patches to the place where we want to insert them. | |
| 494 | // We use a similar strategy to Thunk placement. Place patches roughly | |
| 495 | // every multiple of maximum branch range. | |
| 496 | auto PatchIt = Patches.begin(); | |
| 497 | auto PatchEnd = Patches.end(); | |
| 498 | for (const InputSection *IS : ISD.Sections) { | |
| 499 | ISLimit = IS->OutSecOff + IS->getSize(); | |
| 500 | if (ISLimit > PatchUpperBound) { | |
| 501 | while (PatchIt != PatchEnd) { | |
| 502 | if ((*PatchIt)->getLDSTAddr() >= PrevISLimit) | |
| 503 | break; | |
| 504 | (*PatchIt)->OutSecOff = PrevISLimit; | |
| 505 | ++PatchIt; | |
| 506 | } | |
| 507 | PatchUpperBound = PrevISLimit + Target->ThunkSectionSpacing; | |
| 508 | } | |
| 509 | PrevISLimit = ISLimit; | |
| 510 | } | |
| 511 | for (; PatchIt != PatchEnd; ++PatchIt) { | |
| 512 | (*PatchIt)->OutSecOff = ISLimit; | |
| 513 | } | |
| 514 | ||
| 515 | // merge all patch sections. We use the OutSecOff assigned above to | |
| 516 | // determine the insertion point. This is ok as we only merge into an | |
| 517 | // InputSectionDescription once per pass, and at the end of the pass | |
| 518 | // assignAddresses() will recalculate all the OutSecOff values. | |
| 519 | std::vector<InputSection *> Tmp; | |
| 520 | Tmp.reserve(ISD.Sections.size() + Patches.size()); | |
| 521 | auto MergeCmp = [](const InputSection *A, const InputSection *B) { | |
| 522 | if (A->OutSecOff < B->OutSecOff) | |
| 523 | return true; | |
| 524 | if (A->OutSecOff == B->OutSecOff && isa<Patch843419Section>(A) && | |
| 525 | !isa<Patch843419Section>(B)) | |
| 526 | return true; | |
| 527 | return false; | |
| 528 | }; | |
| 529 | std::merge(ISD.Sections.begin(), ISD.Sections.end(), Patches.begin(), | |
| 530 | Patches.end(), std::back_inserter(Tmp), MergeCmp); | |
| 531 | ISD.Sections = std::move(Tmp); | |
| 532 | } | |
| 533 | ||
| 534 | // Given an erratum sequence that starts at address AdrpAddr, with an | |
| 535 | // instruction that we need to patch at PatcheeOffset from the start of | |
| 536 | // InputSection IS, create a Patch843419 Section and add it to the | |
| 537 | // Patches that we need to insert. | |
| 538 | static void implementPatch(uint64_t AdrpAddr, uint64_t PatcheeOffset, | |
| 539 | InputSection *IS, | |
| 540 | std::vector<Patch843419Section *> &Patches) { | |
| 541 | // There may be a relocation at the same offset that we are patching. There | |
| 542 | // are three cases that we need to consider. | |
| 543 | // Case 1: R_AARCH64_JUMP26 branch relocation. We have already patched this | |
| 544 | // instance of the erratum on a previous patch and altered the relocation. We | |
| 545 | // have nothing more to do. | |
| 546 | // Case 2: A load/store register (unsigned immediate) class relocation. There | |
| 547 | // are two of these R_AARCH_LD64_ABS_LO12_NC and R_AARCH_LD64_GOT_LO12_NC and | |
| 548 | // they are both absolute. We need to add the same relocation to the patch, | |
| 549 | // and replace the relocation with a R_AARCH_JUMP26 branch relocation. | |
| 550 | // Case 3: No relocation. We must create a new R_AARCH64_JUMP26 branch | |
| 551 | // relocation at the offset. | |
| 552 | auto RelIt = std::find_if( | |
| 553 | IS->Relocations.begin(), IS->Relocations.end(), | |
| 554 | [=](const Relocation &R) { return R.Offset == PatcheeOffset; }); | |
| 555 | if (RelIt != IS->Relocations.end() && RelIt->Type == R_AARCH64_JUMP26) | |
| 556 | return; | |
| 557 | ||
| 558 | if (Config->Verbose) | |
| 559 | message("detected cortex-a53-843419 erratum sequence starting at " + | |
| 560 | utohexstr(AdrpAddr) + " in unpatched output."); | |
| 561 | ||
| 562 | auto *PS = make<Patch843419Section>(IS, PatcheeOffset); | |
| 563 | Patches.push_back(PS); | |
| 564 | ||
| 565 | auto MakeRelToPatch = [](uint64_t Offset, Symbol *PatchSym) { | |
| 566 | return Relocation{R_PC, R_AARCH64_JUMP26, Offset, 0, PatchSym}; | |
| 567 | }; | |
| 568 | ||
| 569 | if (RelIt != IS->Relocations.end()) { | |
| 570 | PS->Relocations.push_back( | |
| 571 | {RelIt->Expr, RelIt->Type, 0, RelIt->Addend, RelIt->Sym}); | |
| 572 | *RelIt = MakeRelToPatch(PatcheeOffset, PS->PatchSym); | |
| 573 | } else | |
| 574 | IS->Relocations.push_back(MakeRelToPatch(PatcheeOffset, PS->PatchSym)); | |
| 575 | } | |
| 576 | ||
| 577 | // Scan all the instructions in InputSectionDescription, for each instance of | |
| 578 | // the erratum sequence create a Patch843419Section. We return the list of | |
| 579 | // Patch843419Sections that need to be applied to ISD. | |
| 580 | std::vector<Patch843419Section *> | |
| 581 | AArch64Err843419Patcher::patchInputSectionDescription( | |
| 582 | InputSectionDescription &ISD) { | |
| 583 | std::vector<Patch843419Section *> Patches; | |
| 584 | for (InputSection *IS : ISD.Sections) { | |
| 585 | // LLD doesn't use the erratum sequence in SyntheticSections. | |
| 586 | if (isa<SyntheticSection>(IS)) | |
| 587 | continue; | |
| 588 | // Use SectionMap to make sure we only scan code and not inline data. | |
| 589 | // We have already sorted MapSyms in ascending order and removed consecutive | |
| 590 | // mapping symbols of the same type. Our range of executable instructions to | |
| 591 | // scan is therefore [CodeSym->Value, DataSym->Value) or [CodeSym->Value, | |
| 592 | // section size). | |
| 593 | std::vector<const Defined *> &MapSyms = SectionMap[IS]; | |
| 594 | ||
| 595 | auto CodeSym = llvm::find_if(MapSyms, [&](const Defined *MS) { | |
| 596 | return MS->getName().startswith("$x"); | |
| 597 | }); | |
| 598 | ||
| 599 | while (CodeSym != MapSyms.end()) { | |
| 600 | auto DataSym = std::next(CodeSym); | |
| 601 | uint64_t Off = (*CodeSym)->Value; | |
| 602 | uint64_t Limit = | |
| 603 | (DataSym == MapSyms.end()) ? IS->Data.size() : (*DataSym)->Value; | |
| 604 | ||
| 605 | while (Off < Limit) { | |
| 606 | uint64_t StartAddr = IS->getParent()->Addr + IS->OutSecOff + Off; | |
| 607 | if (uint64_t PatcheeOffset = scanCortexA53Errata843419(IS, Off, Limit)) | |
| 608 | implementPatch(StartAddr, PatcheeOffset, IS, Patches); | |
| 609 | } | |
| 610 | if (DataSym == MapSyms.end()) | |
| 611 | break; | |
| 612 | CodeSym = std::next(DataSym); | |
| 613 | } | |
| 614 | } | |
| 615 | return Patches; | |
| 616 | } | |
| 617 | ||
| 618 | // For each InputSectionDescription make one pass over the executable sections | |
| 619 | // looking for the erratum sequence; creating a synthetic Patch843419Section | |
| 620 | // for each instance found. We insert these synthetic patch sections after the | |
| 621 | // executable code in each InputSectionDescription. | |
| 622 | // | |
| 623 | // PreConditions: | |
| 624 | // The Output and Input Sections have had their final addresses assigned. | |
| 625 | // | |
| 626 | // PostConditions: | |
| 627 | // Returns true if at least one patch was added. The addresses of the | |
| 628 | // Ouptut and Input Sections may have been changed. | |
| 629 | // Returns false if no patches were required and no changes were made. | |
| 630 | bool AArch64Err843419Patcher::createFixes() { | |
| 631 | if (Initialized == false) | |
| 632 | init(); | |
| 633 | ||
| 634 | bool AddressesChanged = false; | |
| 635 | for (OutputSection *OS : OutputSections) { | |
| 636 | if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR)) | |
| 637 | continue; | |
| 638 | for (BaseCommand *BC : OS->SectionCommands) | |
| 639 | if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) { | |
| 640 | std::vector<Patch843419Section *> Patches = | |
| 641 | patchInputSectionDescription(*ISD); | |
| 642 | if (!Patches.empty()) { | |
| 643 | insertPatches(*ISD, Patches); | |
| 644 | AddressesChanged = true; | |
| 645 | } | |
| 646 | } | |
| 647 | } | |
| 648 | return AddressesChanged; | |
| 649 | } |
deps/lld/ELF/AArch64ErrataFix.h created+52| ... | ... | @@ -0,0 +1,52 @@ |
| 1 | //===- AArch64ErrataFix.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_AARCH64ERRATAFIX_H | |
| 11 | #define LLD_ELF_AARCH64ERRATAFIX_H | |
| 12 | ||
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | ||
| 15 | #include <map> | |
| 16 | #include <vector> | |
| 17 | ||
| 18 | namespace lld { | |
| 19 | namespace elf { | |
| 20 | ||
| 21 | class Defined; | |
| 22 | class InputSection; | |
| 23 | struct InputSectionDescription; | |
| 24 | class OutputSection; | |
| 25 | class Patch843419Section; | |
| 26 | ||
| 27 | class AArch64Err843419Patcher { | |
| 28 | public: | |
| 29 | // return true if Patches have been added to the OutputSections. | |
| 30 | bool createFixes(); | |
| 31 | ||
| 32 | private: | |
| 33 | std::vector<Patch843419Section *> | |
| 34 | patchInputSectionDescription(InputSectionDescription &ISD); | |
| 35 | ||
| 36 | void insertPatches(InputSectionDescription &ISD, | |
| 37 | std::vector<Patch843419Section *> &Patches); | |
| 38 | ||
| 39 | void init(); | |
| 40 | ||
| 41 | // A cache of the mapping symbols defined by the InputSecion sorted in order | |
| 42 | // of ascending value with redundant symbols removed. These describe | |
| 43 | // the ranges of code and data in an executable InputSection. | |
| 44 | std::map<InputSection *, std::vector<const Defined *>> SectionMap; | |
| 45 | ||
| 46 | bool Initialized = false; | |
| 47 | }; | |
| 48 | ||
| 49 | } // namespace elf | |
| 50 | } // namespace lld | |
| 51 | ||
| 52 | #endif |
deps/lld/ELF/Arch/AArch64.cpp+72-22| ... | ... | @@ -7,11 +7,11 @@ |
| 7 | 7 | // |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | #include "Error.h" | |
| 11 | 10 | #include "Symbols.h" |
| 12 | 11 | #include "SyntheticSections.h" |
| 13 | 12 | #include "Target.h" |
| 14 | 13 | #include "Thunks.h" |
| 14 | #include "lld/Common/ErrorHandler.h" | |
| 15 | 15 | #include "llvm/Object/ELF.h" |
| 16 | 16 | #include "llvm/Support/Endian.h" |
| 17 | 17 | |
| ... | ... | @@ -32,20 +32,23 @@ namespace { |
| 32 | 32 | class AArch64 final : public TargetInfo { |
| 33 | 33 | public: |
| 34 | 34 | AArch64(); |
| 35 | RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 35 | RelExpr getRelExpr(RelType Type, const Symbol &S, | |
| 36 | 36 | const uint8_t *Loc) const override; |
| 37 | bool isPicRel(uint32_t Type) const override; | |
| 38 | void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override; | |
| 37 | bool isPicRel(RelType Type) const override; | |
| 38 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | |
| 39 | 39 | void writePltHeader(uint8_t *Buf) const override; |
| 40 | 40 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, |
| 41 | 41 | int32_t Index, unsigned RelOff) const override; |
| 42 | bool usesOnlyLowPageBits(uint32_t Type) const override; | |
| 43 | void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 44 | RelExpr adjustRelaxExpr(uint32_t Type, const uint8_t *Data, | |
| 42 | bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File, | |
| 43 | uint64_t BranchAddr, const Symbol &S) const override; | |
| 44 | bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override; | |
| 45 | bool usesOnlyLowPageBits(RelType Type) const override; | |
| 46 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 47 | RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data, | |
| 45 | 48 | RelExpr Expr) const override; |
| 46 | void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 47 | void relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 48 | void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 49 | void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 50 | void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 51 | void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 49 | 52 | }; |
| 50 | 53 | } // namespace |
| 51 | 54 | |
| ... | ... | @@ -66,13 +69,17 @@ AArch64::AArch64() { |
| 66 | 69 | // It doesn't seem to be documented anywhere, but tls on aarch64 uses variant |
| 67 | 70 | // 1 of the tls structures and the tcb size is 16. |
| 68 | 71 | TcbSize = 16; |
| 72 | NeedsThunks = true; | |
| 73 | ||
| 74 | // See comment in Arch/ARM.cpp for a more detailed explanation of | |
| 75 | // ThunkSectionSpacing. For AArch64 the only branches we are permitted to | |
| 76 | // Thunk have a range of +/- 128 MiB | |
| 77 | ThunkSectionSpacing = (128 * 1024 * 1024) - 0x30000; | |
| 69 | 78 | } |
| 70 | 79 | |
| 71 | RelExpr AArch64::getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 80 | RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S, | |
| 72 | 81 | const uint8_t *Loc) const { |
| 73 | 82 | switch (Type) { |
| 74 | default: | |
| 75 | return R_ABS; | |
| 76 | 83 | case R_AARCH64_TLSDESC_ADR_PAGE21: |
| 77 | 84 | return R_TLSDESC_PAGE; |
| 78 | 85 | case R_AARCH64_TLSDESC_LD64_LO12: |
| ... | ... | @@ -92,6 +99,7 @@ RelExpr AArch64::getRelExpr(uint32_t Type, const SymbolBody &S, |
| 92 | 99 | case R_AARCH64_PREL32: |
| 93 | 100 | case R_AARCH64_PREL64: |
| 94 | 101 | case R_AARCH64_ADR_PREL_LO21: |
| 102 | case R_AARCH64_LD_PREL_LO19: | |
| 95 | 103 | return R_PC; |
| 96 | 104 | case R_AARCH64_ADR_PREL_PG_HI21: |
| 97 | 105 | return R_PAGE_PC; |
| ... | ... | @@ -103,10 +111,12 @@ RelExpr AArch64::getRelExpr(uint32_t Type, const SymbolBody &S, |
| 103 | 111 | return R_GOT_PAGE_PC; |
| 104 | 112 | case R_AARCH64_NONE: |
| 105 | 113 | return R_NONE; |
| 114 | default: | |
| 115 | return R_ABS; | |
| 106 | 116 | } |
| 107 | 117 | } |
| 108 | 118 | |
| 109 | RelExpr AArch64::adjustRelaxExpr(uint32_t Type, const uint8_t *Data, | |
| 119 | RelExpr AArch64::adjustRelaxExpr(RelType Type, const uint8_t *Data, | |
| 110 | 120 | RelExpr Expr) const { |
| 111 | 121 | if (Expr == R_RELAX_TLS_GD_TO_IE) { |
| 112 | 122 | if (Type == R_AARCH64_TLSDESC_ADR_PAGE21) |
| ... | ... | @@ -116,7 +126,7 @@ RelExpr AArch64::adjustRelaxExpr(uint32_t Type, const uint8_t *Data, |
| 116 | 126 | return Expr; |
| 117 | 127 | } |
| 118 | 128 | |
| 119 | bool AArch64::usesOnlyLowPageBits(uint32_t Type) const { | |
| 129 | bool AArch64::usesOnlyLowPageBits(RelType Type) const { | |
| 120 | 130 | switch (Type) { |
| 121 | 131 | default: |
| 122 | 132 | return false; |
| ... | ... | @@ -134,11 +144,11 @@ bool AArch64::usesOnlyLowPageBits(uint32_t Type) const { |
| 134 | 144 | } |
| 135 | 145 | } |
| 136 | 146 | |
| 137 | bool AArch64::isPicRel(uint32_t Type) const { | |
| 147 | bool AArch64::isPicRel(RelType Type) const { | |
| 138 | 148 | return Type == R_AARCH64_ABS32 || Type == R_AARCH64_ABS64; |
| 139 | 149 | } |
| 140 | 150 | |
| 141 | void AArch64::writeGotPlt(uint8_t *Buf, const SymbolBody &) const { | |
| 151 | void AArch64::writeGotPlt(uint8_t *Buf, const Symbol &) const { | |
| 142 | 152 | write64le(Buf, InX::Plt->getVA()); |
| 143 | 153 | } |
| 144 | 154 | |
| ... | ... | @@ -180,6 +190,31 @@ void AArch64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 180 | 190 | relocateOne(Buf + 8, R_AARCH64_ADD_ABS_LO12_NC, GotPltEntryAddr); |
| 181 | 191 | } |
| 182 | 192 | |
| 193 | bool AArch64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File, | |
| 194 | uint64_t BranchAddr, const Symbol &S) const { | |
| 195 | // ELF for the ARM 64-bit architecture, section Call and Jump relocations | |
| 196 | // only permits range extension thunks for R_AARCH64_CALL26 and | |
| 197 | // R_AARCH64_JUMP26 relocation types. | |
| 198 | if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26) | |
| 199 | return false; | |
| 200 | uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA(); | |
| 201 | return !inBranchRange(Type, BranchAddr, Dst); | |
| 202 | } | |
| 203 | ||
| 204 | bool AArch64::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const { | |
| 205 | if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26) | |
| 206 | return true; | |
| 207 | // The AArch64 call and unconditional branch instructions have a range of | |
| 208 | // +/- 128 MiB. | |
| 209 | uint64_t Range = 128 * 1024 * 1024; | |
| 210 | if (Dst > Src) { | |
| 211 | // Immediate of branch is signed. | |
| 212 | Range -= 4; | |
| 213 | return Dst - Src <= Range; | |
| 214 | } | |
| 215 | return Src - Dst <= Range; | |
| 216 | } | |
| 217 | ||
| 183 | 218 | static void write32AArch64Addr(uint8_t *L, uint64_t Imm) { |
| 184 | 219 | uint32_t ImmLo = (Imm & 0x3) << 29; |
| 185 | 220 | uint32_t ImmHi = (Imm & 0x1FFFFC) << 3; |
| ... | ... | @@ -201,7 +236,7 @@ static void or32AArch64Imm(uint8_t *L, uint64_t Imm) { |
| 201 | 236 | or32le(L, (Imm & 0xFFF) << 10); |
| 202 | 237 | } |
| 203 | 238 | |
| 204 | void AArch64::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 239 | void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 205 | 240 | switch (Type) { |
| 206 | 241 | case R_AARCH64_ABS16: |
| 207 | 242 | case R_AARCH64_PREL16: |
| ... | ... | @@ -232,12 +267,23 @@ void AArch64::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 232 | 267 | checkInt<21>(Loc, Val, Type); |
| 233 | 268 | write32AArch64Addr(Loc, Val); |
| 234 | 269 | break; |
| 235 | case R_AARCH64_CALL26: | |
| 236 | 270 | case R_AARCH64_JUMP26: |
| 271 | // Normally we would just write the bits of the immediate field, however | |
| 272 | // when patching instructions for the cpu errata fix -fix-cortex-a53-843419 | |
| 273 | // we want to replace a non-branch instruction with a branch immediate | |
| 274 | // instruction. By writing all the bits of the instruction including the | |
| 275 | // opcode and the immediate (0 001 | 01 imm26) we can do this | |
| 276 | // transformation by placing a R_AARCH64_JUMP26 relocation at the offset of | |
| 277 | // the instruction we want to patch. | |
| 278 | write32le(Loc, 0x14000000); | |
| 279 | LLVM_FALLTHROUGH; | |
| 280 | case R_AARCH64_CALL26: | |
| 237 | 281 | checkInt<28>(Loc, Val, Type); |
| 238 | 282 | or32le(Loc, (Val & 0x0FFFFFFC) >> 2); |
| 239 | 283 | break; |
| 240 | 284 | case R_AARCH64_CONDBR19: |
| 285 | case R_AARCH64_LD_PREL_LO19: | |
| 286 | checkAlignment<4>(Loc, Val, Type); | |
| 241 | 287 | checkInt<21>(Loc, Val, Type); |
| 242 | 288 | or32le(Loc, (Val & 0x1FFFFC) << 3); |
| 243 | 289 | break; |
| ... | ... | @@ -251,15 +297,19 @@ void AArch64::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 251 | 297 | or32AArch64Imm(Loc, getBits(Val, 0, 11)); |
| 252 | 298 | break; |
| 253 | 299 | case R_AARCH64_LDST16_ABS_LO12_NC: |
| 300 | checkAlignment<2>(Loc, Val, Type); | |
| 254 | 301 | or32AArch64Imm(Loc, getBits(Val, 1, 11)); |
| 255 | 302 | break; |
| 256 | 303 | case R_AARCH64_LDST32_ABS_LO12_NC: |
| 304 | checkAlignment<4>(Loc, Val, Type); | |
| 257 | 305 | or32AArch64Imm(Loc, getBits(Val, 2, 11)); |
| 258 | 306 | break; |
| 259 | 307 | case R_AARCH64_LDST64_ABS_LO12_NC: |
| 308 | checkAlignment<8>(Loc, Val, Type); | |
| 260 | 309 | or32AArch64Imm(Loc, getBits(Val, 3, 11)); |
| 261 | 310 | break; |
| 262 | 311 | case R_AARCH64_LDST128_ABS_LO12_NC: |
| 312 | checkAlignment<16>(Loc, Val, Type); | |
| 263 | 313 | or32AArch64Imm(Loc, getBits(Val, 4, 11)); |
| 264 | 314 | break; |
| 265 | 315 | case R_AARCH64_MOVW_UABS_G0_NC: |
| ... | ... | @@ -291,7 +341,7 @@ void AArch64::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 291 | 341 | } |
| 292 | 342 | } |
| 293 | 343 | |
| 294 | void AArch64::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 344 | void AArch64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 295 | 345 | // TLSDESC Global-Dynamic relocation are in the form: |
| 296 | 346 | // adrp x0, :tlsdesc:v [R_AARCH64_TLSDESC_ADR_PAGE21] |
| 297 | 347 | // ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12] |
| ... | ... | @@ -321,7 +371,7 @@ void AArch64::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 321 | 371 | } |
| 322 | 372 | } |
| 323 | 373 | |
| 324 | void AArch64::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 374 | void AArch64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 325 | 375 | // TLSDESC Global-Dynamic relocation are in the form: |
| 326 | 376 | // adrp x0, :tlsdesc:v [R_AARCH64_TLSDESC_ADR_PAGE21] |
| 327 | 377 | // ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12] |
| ... | ... | @@ -352,7 +402,7 @@ void AArch64::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 352 | 402 | } |
| 353 | 403 | } |
| 354 | 404 | |
| 355 | void AArch64::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 405 | void AArch64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 356 | 406 | checkUInt<32>(Loc, Val, Type); |
| 357 | 407 | |
| 358 | 408 | if (Type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) { |
deps/lld/ELF/Arch/AMDGPU.cpp+26-8| ... | ... | @@ -7,10 +7,10 @@ |
| 7 | 7 | // |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | #include "Error.h" | |
| 11 | 10 | #include "InputFiles.h" |
| 12 | 11 | #include "Symbols.h" |
| 13 | 12 | #include "Target.h" |
| 13 | #include "lld/Common/ErrorHandler.h" | |
| 14 | 14 | #include "llvm/Object/ELF.h" |
| 15 | 15 | #include "llvm/Support/Endian.h" |
| 16 | 16 | |
| ... | ... | @@ -25,19 +25,38 @@ namespace { |
| 25 | 25 | class AMDGPU final : public TargetInfo { |
| 26 | 26 | public: |
| 27 | 27 | AMDGPU(); |
| 28 | void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 29 | RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 28 | uint32_t calcEFlags() const override; | |
| 29 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 30 | RelExpr getRelExpr(RelType Type, const Symbol &S, | |
| 30 | 31 | const uint8_t *Loc) const override; |
| 31 | 32 | }; |
| 32 | 33 | } // namespace |
| 33 | 34 | |
| 34 | 35 | AMDGPU::AMDGPU() { |
| 35 | RelativeRel = R_AMDGPU_REL64; | |
| 36 | RelativeRel = R_AMDGPU_RELATIVE64; | |
| 36 | 37 | GotRel = R_AMDGPU_ABS64; |
| 37 | 38 | GotEntrySize = 8; |
| 38 | 39 | } |
| 39 | 40 | |
| 40 | void AMDGPU::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 41 | static uint32_t getEFlags(InputFile *File) { | |
| 42 | return cast<ObjFile<ELF64LE>>(File)->getObj().getHeader()->e_flags; | |
| 43 | } | |
| 44 | ||
| 45 | uint32_t AMDGPU::calcEFlags() const { | |
| 46 | assert(!ObjectFiles.empty()); | |
| 47 | uint32_t Ret = getEFlags(ObjectFiles[0]); | |
| 48 | ||
| 49 | // Verify that all input files have the same e_flags. | |
| 50 | for (InputFile *F : makeArrayRef(ObjectFiles).slice(1)) { | |
| 51 | if (Ret == getEFlags(F)) | |
| 52 | continue; | |
| 53 | error("incompatible e_flags: " + toString(F)); | |
| 54 | return 0; | |
| 55 | } | |
| 56 | return Ret; | |
| 57 | } | |
| 58 | ||
| 59 | void AMDGPU::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 41 | 60 | switch (Type) { |
| 42 | 61 | case R_AMDGPU_ABS32: |
| 43 | 62 | case R_AMDGPU_GOTPCREL: |
| ... | ... | @@ -58,7 +77,7 @@ void AMDGPU::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 58 | 77 | } |
| 59 | 78 | } |
| 60 | 79 | |
| 61 | RelExpr AMDGPU::getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 80 | RelExpr AMDGPU::getRelExpr(RelType Type, const Symbol &S, | |
| 62 | 81 | const uint8_t *Loc) const { |
| 63 | 82 | switch (Type) { |
| 64 | 83 | case R_AMDGPU_ABS32: |
| ... | ... | @@ -73,8 +92,7 @@ RelExpr AMDGPU::getRelExpr(uint32_t Type, const SymbolBody &S, |
| 73 | 92 | case R_AMDGPU_GOTPCREL32_HI: |
| 74 | 93 | return R_GOT_PC; |
| 75 | 94 | default: |
| 76 | error(toString(S.File) + ": unknown relocation type: " + toString(Type)); | |
| 77 | return R_HINT; | |
| 95 | return R_INVALID; | |
| 78 | 96 | } |
| 79 | 97 | } |
| 80 | 98 |
deps/lld/ELF/Arch/ARM.cpp+151-48| ... | ... | @@ -7,12 +7,12 @@ |
| 7 | 7 | // |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | #include "Error.h" | |
| 11 | 10 | #include "InputFiles.h" |
| 12 | 11 | #include "Symbols.h" |
| 13 | 12 | #include "SyntheticSections.h" |
| 14 | 13 | #include "Target.h" |
| 15 | 14 | #include "Thunks.h" |
| 15 | #include "lld/Common/ErrorHandler.h" | |
| 16 | 16 | #include "llvm/Object/ELF.h" |
| 17 | 17 | #include "llvm/Support/Endian.h" |
| 18 | 18 | |
| ... | ... | @@ -26,23 +26,23 @@ namespace { |
| 26 | 26 | class ARM final : public TargetInfo { |
| 27 | 27 | public: |
| 28 | 28 | ARM(); |
| 29 | RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 29 | uint32_t calcEFlags() const override; | |
| 30 | RelExpr getRelExpr(RelType Type, const Symbol &S, | |
| 30 | 31 | const uint8_t *Loc) const override; |
| 31 | bool isPicRel(uint32_t Type) const override; | |
| 32 | uint32_t getDynRel(uint32_t Type) const override; | |
| 33 | int64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const override; | |
| 34 | void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override; | |
| 35 | void writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const override; | |
| 32 | bool isPicRel(RelType Type) const override; | |
| 33 | RelType getDynRel(RelType Type) const override; | |
| 34 | int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override; | |
| 35 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | |
| 36 | void writeIgotPlt(uint8_t *Buf, const Symbol &S) const override; | |
| 36 | 37 | void writePltHeader(uint8_t *Buf) const override; |
| 37 | 38 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, |
| 38 | 39 | int32_t Index, unsigned RelOff) const override; |
| 39 | void addPltSymbols(InputSectionBase *IS, uint64_t Off) const override; | |
| 40 | void addPltHeaderSymbols(InputSectionBase *ISD) const override; | |
| 41 | bool needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File, | |
| 42 | const SymbolBody &S) const override; | |
| 43 | bool inBranchRange(uint32_t RelocType, uint64_t Src, | |
| 44 | uint64_t Dst) const override; | |
| 45 | void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 40 | void addPltSymbols(InputSection &IS, uint64_t Off) const override; | |
| 41 | void addPltHeaderSymbols(InputSection &ISD) const override; | |
| 42 | bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File, | |
| 43 | uint64_t BranchAddr, const Symbol &S) const override; | |
| 44 | bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override; | |
| 45 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 46 | 46 | }; |
| 47 | 47 | } // namespace |
| 48 | 48 | |
| ... | ... | @@ -58,18 +58,54 @@ ARM::ARM() { |
| 58 | 58 | GotEntrySize = 4; |
| 59 | 59 | GotPltEntrySize = 4; |
| 60 | 60 | PltEntrySize = 16; |
| 61 | PltHeaderSize = 20; | |
| 61 | PltHeaderSize = 32; | |
| 62 | 62 | TrapInstr = 0xd4d4d4d4; |
| 63 | 63 | // ARM uses Variant 1 TLS |
| 64 | 64 | TcbSize = 8; |
| 65 | 65 | NeedsThunks = true; |
| 66 | ||
| 67 | // The placing of pre-created ThunkSections is controlled by the | |
| 68 | // ThunkSectionSpacing parameter. The aim is to place the | |
| 69 | // ThunkSection such that all branches from the InputSections prior to the | |
| 70 | // ThunkSection can reach a Thunk placed at the end of the ThunkSection. | |
| 71 | // Graphically: | |
| 72 | // | up to ThunkSectionSpacing .text input sections | | |
| 73 | // | ThunkSection | | |
| 74 | // | up to ThunkSectionSpacing .text input sections | | |
| 75 | // | ThunkSection | | |
| 76 | ||
| 77 | // Pre-created ThunkSections are spaced roughly 16MiB apart on ARM. This is to | |
| 78 | // match the most common expected case of a Thumb 2 encoded BL, BLX or B.W | |
| 79 | // ARM B, BL, BLX range +/- 32MiB | |
| 80 | // Thumb B.W, BL, BLX range +/- 16MiB | |
| 81 | // Thumb B<cc>.W range +/- 1MiB | |
| 82 | // If a branch cannot reach a pre-created ThunkSection a new one will be | |
| 83 | // created so we can handle the rare cases of a Thumb 2 conditional branch. | |
| 84 | // We intentionally use a lower size for ThunkSectionSpacing than the maximum | |
| 85 | // branch range so the end of the ThunkSection is more likely to be within | |
| 86 | // range of the branch instruction that is furthest away. The value we shorten | |
| 87 | // ThunkSectionSpacing by is set conservatively to allow us to create 16,384 | |
| 88 | // 12 byte Thunks at any offset in a ThunkSection without risk of a branch to | |
| 89 | // one of the Thunks going out of range. | |
| 90 | ||
| 91 | // FIXME: lld assumes that the Thumb BL and BLX encoding permits the J1 and | |
| 92 | // J2 bits to be used to extend the branch range. On earlier Architectures | |
| 93 | // such as ARMv4, ARMv5 and ARMv6 (except ARMv6T2) the range is +/- 4MiB. If | |
| 94 | // support for the earlier encodings is added then when they are used the | |
| 95 | // ThunkSectionSpacing will need lowering. | |
| 96 | ThunkSectionSpacing = 0x1000000 - 0x30000; | |
| 97 | } | |
| 98 | ||
| 99 | uint32_t ARM::calcEFlags() const { | |
| 100 | // 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 | |
| 102 | // kernels (as of 2016) require an EABI version to be set. | |
| 103 | return EF_ARM_EABI_VER5; | |
| 66 | 104 | } |
| 67 | 105 | |
| 68 | RelExpr ARM::getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 106 | RelExpr ARM::getRelExpr(RelType Type, const Symbol &S, | |
| 69 | 107 | const uint8_t *Loc) const { |
| 70 | 108 | switch (Type) { |
| 71 | default: | |
| 72 | return R_ABS; | |
| 73 | 109 | case R_ARM_THM_JUMP11: |
| 74 | 110 | return R_PC; |
| 75 | 111 | case R_ARM_CALL: |
| ... | ... | @@ -120,15 +156,17 @@ RelExpr ARM::getRelExpr(uint32_t Type, const SymbolBody &S, |
| 120 | 156 | return R_NONE; |
| 121 | 157 | case R_ARM_TLS_LE32: |
| 122 | 158 | return R_TLS; |
| 159 | default: | |
| 160 | return R_ABS; | |
| 123 | 161 | } |
| 124 | 162 | } |
| 125 | 163 | |
| 126 | bool ARM::isPicRel(uint32_t Type) const { | |
| 164 | bool ARM::isPicRel(RelType Type) const { | |
| 127 | 165 | return (Type == R_ARM_TARGET1 && !Config->Target1Rel) || |
| 128 | 166 | (Type == R_ARM_ABS32); |
| 129 | 167 | } |
| 130 | 168 | |
| 131 | uint32_t ARM::getDynRel(uint32_t Type) const { | |
| 169 | RelType ARM::getDynRel(RelType Type) const { | |
| 132 | 170 | if (Type == R_ARM_TARGET1 && !Config->Target1Rel) |
| 133 | 171 | return R_ARM_ABS32; |
| 134 | 172 | if (Type == R_ARM_ABS32) |
| ... | ... | @@ -137,41 +175,73 @@ uint32_t ARM::getDynRel(uint32_t Type) const { |
| 137 | 175 | return R_ARM_ABS32; |
| 138 | 176 | } |
| 139 | 177 | |
| 140 | void ARM::writeGotPlt(uint8_t *Buf, const SymbolBody &) const { | |
| 178 | void ARM::writeGotPlt(uint8_t *Buf, const Symbol &) const { | |
| 141 | 179 | write32le(Buf, InX::Plt->getVA()); |
| 142 | 180 | } |
| 143 | 181 | |
| 144 | void ARM::writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const { | |
| 182 | void ARM::writeIgotPlt(uint8_t *Buf, const Symbol &S) const { | |
| 145 | 183 | // An ARM entry is the address of the ifunc resolver function. |
| 146 | 184 | write32le(Buf, S.getVA()); |
| 147 | 185 | } |
| 148 | 186 | |
| 149 | void ARM::writePltHeader(uint8_t *Buf) const { | |
| 187 | // Long form PLT Header that does not have any restrictions on the displacement | |
| 188 | // of the .plt from the .plt.got. | |
| 189 | static void writePltHeaderLong(uint8_t *Buf) { | |
| 150 | 190 | const uint8_t PltData[] = { |
| 151 | 191 | 0x04, 0xe0, 0x2d, 0xe5, // str lr, [sp,#-4]! |
| 152 | 192 | 0x04, 0xe0, 0x9f, 0xe5, // ldr lr, L2 |
| 153 | 193 | 0x0e, 0xe0, 0x8f, 0xe0, // L1: add lr, pc, lr |
| 154 | 194 | 0x08, 0xf0, 0xbe, 0xe5, // ldr pc, [lr, #8] |
| 155 | 195 | 0x00, 0x00, 0x00, 0x00, // L2: .word &(.got.plt) - L1 - 8 |
| 156 | }; | |
| 196 | 0xd4, 0xd4, 0xd4, 0xd4, // Pad to 32-byte boundary | |
| 197 | 0xd4, 0xd4, 0xd4, 0xd4, // Pad to 32-byte boundary | |
| 198 | 0xd4, 0xd4, 0xd4, 0xd4}; | |
| 157 | 199 | memcpy(Buf, PltData, sizeof(PltData)); |
| 158 | 200 | uint64_t GotPlt = InX::GotPlt->getVA(); |
| 159 | 201 | uint64_t L1 = InX::Plt->getVA() + 8; |
| 160 | 202 | write32le(Buf + 16, GotPlt - L1 - 8); |
| 161 | 203 | } |
| 162 | 204 | |
| 163 | void ARM::addPltHeaderSymbols(InputSectionBase *ISD) const { | |
| 164 | auto *IS = cast<InputSection>(ISD); | |
| 205 | // The default PLT header requires the .plt.got to be within 128 Mb of the | |
| 206 | // .plt in the positive direction. | |
| 207 | void ARM::writePltHeader(uint8_t *Buf) const { | |
| 208 | // Use a similar sequence to that in writePlt(), the difference is the calling | |
| 209 | // conventions mean we use lr instead of ip. The PLT entry is responsible for | |
| 210 | // saving lr on the stack, the dynamic loader is responsible for reloading | |
| 211 | // it. | |
| 212 | const uint32_t PltData[] = { | |
| 213 | 0xe52de004, // L1: str lr, [sp,#-4]! | |
| 214 | 0xe28fe600, // add lr, pc, #0x0NN00000 &(.got.plt - L1 - 4) | |
| 215 | 0xe28eea00, // add lr, lr, #0x000NN000 &(.got.plt - L1 - 4) | |
| 216 | 0xe5bef000, // ldr pc, [lr, #0x00000NNN] &(.got.plt -L1 - 4) | |
| 217 | }; | |
| 218 | ||
| 219 | uint64_t Offset = InX::GotPlt->getVA() - InX::Plt->getVA() - 4; | |
| 220 | if (!llvm::isUInt<27>(Offset)) { | |
| 221 | // We cannot encode the Offset, use the long form. | |
| 222 | writePltHeaderLong(Buf); | |
| 223 | return; | |
| 224 | } | |
| 225 | write32le(Buf + 0, PltData[0]); | |
| 226 | write32le(Buf + 4, PltData[1] | ((Offset >> 20) & 0xff)); | |
| 227 | write32le(Buf + 8, PltData[2] | ((Offset >> 12) & 0xff)); | |
| 228 | write32le(Buf + 12, PltData[3] | (Offset & 0xfff)); | |
| 229 | write32le(Buf + 16, TrapInstr); // Pad to 32-byte boundary | |
| 230 | write32le(Buf + 20, TrapInstr); | |
| 231 | write32le(Buf + 24, TrapInstr); | |
| 232 | write32le(Buf + 28, TrapInstr); | |
| 233 | } | |
| 234 | ||
| 235 | void ARM::addPltHeaderSymbols(InputSection &IS) const { | |
| 165 | 236 | addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS); |
| 166 | 237 | addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS); |
| 167 | 238 | } |
| 168 | 239 | |
| 169 | void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | |
| 170 | uint64_t PltEntryAddr, int32_t Index, | |
| 171 | unsigned RelOff) const { | |
| 172 | // FIXME: Using simple code sequence with simple relocations. | |
| 173 | // There is a more optimal sequence but it requires support for the group | |
| 174 | // relocations. See ELF for the ARM Architecture Appendix A.3 | |
| 240 | // Long form PLT entries that do not have any restrictions on the displacement | |
| 241 | // of the .plt from the .plt.got. | |
| 242 | static void writePltLong(uint8_t *Buf, uint64_t GotPltEntryAddr, | |
| 243 | uint64_t PltEntryAddr, int32_t Index, | |
| 244 | unsigned RelOff) { | |
| 175 | 245 | const uint8_t PltData[] = { |
| 176 | 246 | 0x04, 0xc0, 0x9f, 0xe5, // ldr ip, L2 |
| 177 | 247 | 0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc |
| ... | ... | @@ -183,24 +253,49 @@ void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 183 | 253 | write32le(Buf + 12, GotPltEntryAddr - L1 - 8); |
| 184 | 254 | } |
| 185 | 255 | |
| 186 | void ARM::addPltSymbols(InputSectionBase *ISD, uint64_t Off) const { | |
| 187 | auto *IS = cast<InputSection>(ISD); | |
| 256 | // The default PLT entries require the .plt.got to be within 128 Mb of the | |
| 257 | // .plt in the positive direction. | |
| 258 | void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | |
| 259 | uint64_t PltEntryAddr, int32_t Index, | |
| 260 | unsigned RelOff) const { | |
| 261 | // The PLT entry is similar to the example given in Appendix A of ELF for | |
| 262 | // the Arm Architecture. Instead of using the Group Relocations to find the | |
| 263 | // optimal rotation for the 8-bit immediate used in the add instructions we | |
| 264 | // hard code the most compact rotations for simplicity. This saves a load | |
| 265 | // instruction over the long plt sequences. | |
| 266 | const uint32_t PltData[] = { | |
| 267 | 0xe28fc600, // L1: add ip, pc, #0x0NN00000 Offset(&(.plt.got) - L1 - 8 | |
| 268 | 0xe28cca00, // add ip, ip, #0x000NN000 Offset(&(.plt.got) - L1 - 8 | |
| 269 | 0xe5bcf000, // ldr pc, [ip, #0x00000NNN] Offset(&(.plt.got) - L1 - 8 | |
| 270 | }; | |
| 271 | ||
| 272 | uint64_t Offset = GotPltEntryAddr - PltEntryAddr - 8; | |
| 273 | if (!llvm::isUInt<27>(Offset)) { | |
| 274 | // We cannot encode the Offset, use the long form. | |
| 275 | writePltLong(Buf, GotPltEntryAddr, PltEntryAddr, Index, RelOff); | |
| 276 | return; | |
| 277 | } | |
| 278 | write32le(Buf + 0, PltData[0] | ((Offset >> 20) & 0xff)); | |
| 279 | write32le(Buf + 4, PltData[1] | ((Offset >> 12) & 0xff)); | |
| 280 | write32le(Buf + 8, PltData[2] | (Offset & 0xfff)); | |
| 281 | write32le(Buf + 12, TrapInstr); // Pad to 16-byte boundary | |
| 282 | } | |
| 283 | ||
| 284 | void ARM::addPltSymbols(InputSection &IS, uint64_t Off) const { | |
| 188 | 285 | addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS); |
| 189 | 286 | addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS); |
| 190 | 287 | } |
| 191 | 288 | |
| 192 | bool ARM::needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File, | |
| 193 | const SymbolBody &S) const { | |
| 194 | // If S is an undefined weak symbol in an executable we don't need a Thunk. | |
| 195 | // In a DSO calls to undefined symbols, including weak ones get PLT entries | |
| 196 | // which may need a thunk. | |
| 197 | if (S.isUndefined() && !S.isLocal() && S.symbol()->isWeak() && | |
| 198 | !Config->Shared) | |
| 289 | bool ARM::needsThunk(RelExpr Expr, RelType Type, const InputFile *File, | |
| 290 | uint64_t BranchAddr, const Symbol &S) const { | |
| 291 | // If S is an undefined weak symbol and does not have a PLT entry then it | |
| 292 | // will be resolved as a branch to the next instruction. | |
| 293 | if (S.isUndefWeak() && !S.isInPlt()) | |
| 199 | 294 | return false; |
| 200 | 295 | // A state change from ARM to Thumb and vice versa must go through an |
| 201 | 296 | // interworking thunk if the relocation type is not R_ARM_CALL or |
| 202 | 297 | // R_ARM_THM_CALL. |
| 203 | switch (RelocType) { | |
| 298 | switch (Type) { | |
| 204 | 299 | case R_ARM_PC24: |
| 205 | 300 | case R_ARM_PLT32: |
| 206 | 301 | case R_ARM_JUMP24: |
| ... | ... | @@ -208,23 +303,31 @@ bool ARM::needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File, |
| 208 | 303 | // Otherwise we need to interwork if Symbol has bit 0 set (Thumb). |
| 209 | 304 | if (Expr == R_PC && ((S.getVA() & 1) == 1)) |
| 210 | 305 | return true; |
| 211 | break; | |
| 306 | LLVM_FALLTHROUGH; | |
| 307 | case R_ARM_CALL: { | |
| 308 | uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA(); | |
| 309 | return !inBranchRange(Type, BranchAddr, Dst); | |
| 310 | } | |
| 212 | 311 | case R_ARM_THM_JUMP19: |
| 213 | 312 | case R_ARM_THM_JUMP24: |
| 214 | 313 | // Source is Thumb, all PLT entries are ARM so interworking is required. |
| 215 | 314 | // Otherwise we need to interwork if Symbol has bit 0 clear (ARM). |
| 216 | 315 | if (Expr == R_PLT_PC || ((S.getVA() & 1) == 0)) |
| 217 | 316 | return true; |
| 218 | break; | |
| 317 | LLVM_FALLTHROUGH; | |
| 318 | case R_ARM_THM_CALL: { | |
| 319 | uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA(); | |
| 320 | return !inBranchRange(Type, BranchAddr, Dst); | |
| 321 | } | |
| 219 | 322 | } |
| 220 | 323 | return false; |
| 221 | 324 | } |
| 222 | 325 | |
| 223 | bool ARM::inBranchRange(uint32_t RelocType, uint64_t Src, uint64_t Dst) const { | |
| 326 | bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const { | |
| 224 | 327 | uint64_t Range; |
| 225 | 328 | uint64_t InstrSize; |
| 226 | 329 | |
| 227 | switch (RelocType) { | |
| 330 | switch (Type) { | |
| 228 | 331 | case R_ARM_PC24: |
| 229 | 332 | case R_ARM_PLT32: |
| 230 | 333 | case R_ARM_JUMP24: |
| ... | ... | @@ -263,7 +366,7 @@ bool ARM::inBranchRange(uint32_t RelocType, uint64_t Src, uint64_t Dst) const { |
| 263 | 366 | return Distance <= Range; |
| 264 | 367 | } |
| 265 | 368 | |
| 266 | void ARM::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 369 | void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 267 | 370 | switch (Type) { |
| 268 | 371 | case R_ARM_ABS32: |
| 269 | 372 | case R_ARM_BASE_PREL: |
| ... | ... | @@ -400,7 +503,7 @@ void ARM::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 400 | 503 | } |
| 401 | 504 | } |
| 402 | 505 | |
| 403 | int64_t ARM::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const { | |
| 506 | int64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const { | |
| 404 | 507 | switch (Type) { |
| 405 | 508 | default: |
| 406 | 509 | return 0; |
deps/lld/ELF/Arch/AVR.cpp+6-12| ... | ... | @@ -26,10 +26,10 @@ |
| 26 | 26 | // |
| 27 | 27 | //===----------------------------------------------------------------------===// |
| 28 | 28 | |
| 29 | #include "Error.h" | |
| 30 | 29 | #include "InputFiles.h" |
| 31 | 30 | #include "Symbols.h" |
| 32 | 31 | #include "Target.h" |
| 32 | #include "lld/Common/ErrorHandler.h" | |
| 33 | 33 | #include "llvm/Object/ELF.h" |
| 34 | 34 | #include "llvm/Support/Endian.h" |
| 35 | 35 | |
| ... | ... | @@ -43,24 +43,18 @@ using namespace lld::elf; |
| 43 | 43 | namespace { |
| 44 | 44 | class AVR final : public TargetInfo { |
| 45 | 45 | public: |
| 46 | RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 46 | RelExpr getRelExpr(RelType Type, const Symbol &S, | |
| 47 | 47 | const uint8_t *Loc) const override; |
| 48 | void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 48 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 49 | 49 | }; |
| 50 | 50 | } // namespace |
| 51 | 51 | |
| 52 | RelExpr AVR::getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 52 | RelExpr AVR::getRelExpr(RelType Type, const Symbol &S, | |
| 53 | 53 | const uint8_t *Loc) const { |
| 54 | switch (Type) { | |
| 55 | case R_AVR_CALL: | |
| 56 | return R_ABS; | |
| 57 | default: | |
| 58 | error(toString(S.File) + ": unknown relocation type: " + toString(Type)); | |
| 59 | return R_HINT; | |
| 60 | } | |
| 54 | return R_ABS; | |
| 61 | 55 | } |
| 62 | 56 | |
| 63 | void AVR::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 57 | void AVR::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 64 | 58 | switch (Type) { |
| 65 | 59 | case R_AVR_CALL: { |
| 66 | 60 | uint16_t Hi = Val >> 17; |
deps/lld/ELF/Arch/Mips.cpp+361-102| ... | ... | @@ -7,13 +7,13 @@ |
| 7 | 7 | // |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | #include "Error.h" | |
| 11 | 10 | #include "InputFiles.h" |
| 12 | 11 | #include "OutputSections.h" |
| 13 | 12 | #include "Symbols.h" |
| 14 | 13 | #include "SyntheticSections.h" |
| 15 | 14 | #include "Target.h" |
| 16 | 15 | #include "Thunks.h" |
| 16 | #include "lld/Common/ErrorHandler.h" | |
| 17 | 17 | #include "llvm/Object/ELF.h" |
| 18 | 18 | #include "llvm/Support/Endian.h" |
| 19 | 19 | |
| ... | ... | @@ -28,19 +28,20 @@ namespace { |
| 28 | 28 | template <class ELFT> class MIPS final : public TargetInfo { |
| 29 | 29 | public: |
| 30 | 30 | MIPS(); |
| 31 | RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 31 | uint32_t calcEFlags() const override; | |
| 32 | RelExpr getRelExpr(RelType Type, const Symbol &S, | |
| 32 | 33 | const uint8_t *Loc) const override; |
| 33 | int64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const override; | |
| 34 | bool isPicRel(uint32_t Type) const override; | |
| 35 | uint32_t getDynRel(uint32_t Type) const override; | |
| 36 | void writeGotPlt(uint8_t *Buf, const SymbolBody &S) 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; | |
| 37 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | |
| 37 | 38 | void writePltHeader(uint8_t *Buf) const override; |
| 38 | 39 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, |
| 39 | 40 | int32_t Index, unsigned RelOff) const override; |
| 40 | bool needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File, | |
| 41 | const SymbolBody &S) const override; | |
| 42 | void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 43 | bool usesOnlyLowPageBits(uint32_t Type) const override; | |
| 41 | bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File, | |
| 42 | uint64_t BranchAddr, const Symbol &S) const override; | |
| 43 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 44 | bool usesOnlyLowPageBits(RelType Type) const override; | |
| 44 | 45 | }; |
| 45 | 46 | } // namespace |
| 46 | 47 | |
| ... | ... | @@ -69,24 +70,39 @@ template <class ELFT> MIPS<ELFT>::MIPS() { |
| 69 | 70 | } |
| 70 | 71 | } |
| 71 | 72 | |
| 73 | template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const { | |
| 74 | return calcMipsEFlags<ELFT>(); | |
| 75 | } | |
| 76 | ||
| 72 | 77 | template <class ELFT> |
| 73 | RelExpr MIPS<ELFT>::getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 78 | RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S, | |
| 74 | 79 | const uint8_t *Loc) const { |
| 75 | 80 | // See comment in the calculateMipsRelChain. |
| 76 | 81 | if (ELFT::Is64Bits || Config->MipsN32Abi) |
| 77 | 82 | Type &= 0xff; |
| 83 | ||
| 78 | 84 | switch (Type) { |
| 79 | default: | |
| 80 | return R_ABS; | |
| 81 | 85 | case R_MIPS_JALR: |
| 86 | case R_MICROMIPS_JALR: | |
| 82 | 87 | return R_HINT; |
| 83 | 88 | case R_MIPS_GPREL16: |
| 84 | 89 | case R_MIPS_GPREL32: |
| 90 | case R_MICROMIPS_GPREL16: | |
| 91 | case R_MICROMIPS_GPREL7_S2: | |
| 85 | 92 | return R_MIPS_GOTREL; |
| 86 | 93 | case R_MIPS_26: |
| 94 | case R_MICROMIPS_26_S1: | |
| 87 | 95 | return R_PLT; |
| 96 | case R_MICROMIPS_PC26_S1: | |
| 97 | return R_PLT_PC; | |
| 88 | 98 | case R_MIPS_HI16: |
| 89 | 99 | case R_MIPS_LO16: |
| 100 | case R_MIPS_HIGHER: | |
| 101 | case R_MIPS_HIGHEST: | |
| 102 | case R_MICROMIPS_HI16: | |
| 103 | case R_MICROMIPS_LO16: | |
| 104 | case R_MICROMIPS_HIGHER: | |
| 105 | case R_MICROMIPS_HIGHEST: | |
| 90 | 106 | // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate |
| 91 | 107 | // offset between start of function and 'gp' value which by default |
| 92 | 108 | // equal to the start of .got section. In that case we consider these |
| ... | ... | @@ -96,7 +112,24 @@ RelExpr MIPS<ELFT>::getRelExpr(uint32_t Type, const SymbolBody &S, |
| 96 | 112 | if (&S == ElfSym::MipsLocalGp) |
| 97 | 113 | return R_MIPS_GOT_GP; |
| 98 | 114 | LLVM_FALLTHROUGH; |
| 115 | case R_MIPS_32: | |
| 116 | case R_MIPS_64: | |
| 99 | 117 | case R_MIPS_GOT_OFST: |
| 118 | case R_MIPS_SUB: | |
| 119 | case R_MIPS_TLS_DTPREL_HI16: | |
| 120 | case R_MIPS_TLS_DTPREL_LO16: | |
| 121 | case R_MIPS_TLS_DTPREL32: | |
| 122 | case R_MIPS_TLS_DTPREL64: | |
| 123 | case R_MIPS_TLS_TPREL_HI16: | |
| 124 | case R_MIPS_TLS_TPREL_LO16: | |
| 125 | case R_MIPS_TLS_TPREL32: | |
| 126 | case R_MIPS_TLS_TPREL64: | |
| 127 | case R_MICROMIPS_GOT_OFST: | |
| 128 | case R_MICROMIPS_SUB: | |
| 129 | case R_MICROMIPS_TLS_DTPREL_HI16: | |
| 130 | case R_MICROMIPS_TLS_DTPREL_LO16: | |
| 131 | case R_MICROMIPS_TLS_TPREL_HI16: | |
| 132 | case R_MICROMIPS_TLS_TPREL_LO16: | |
| 100 | 133 | return R_ABS; |
| 101 | 134 | case R_MIPS_PC32: |
| 102 | 135 | case R_MIPS_PC16: |
| ... | ... | @@ -105,111 +138,171 @@ RelExpr MIPS<ELFT>::getRelExpr(uint32_t Type, const SymbolBody &S, |
| 105 | 138 | case R_MIPS_PC26_S2: |
| 106 | 139 | case R_MIPS_PCHI16: |
| 107 | 140 | case R_MIPS_PCLO16: |
| 141 | case R_MICROMIPS_PC7_S1: | |
| 142 | case R_MICROMIPS_PC10_S1: | |
| 143 | case R_MICROMIPS_PC16_S1: | |
| 144 | case R_MICROMIPS_PC18_S3: | |
| 145 | case R_MICROMIPS_PC19_S2: | |
| 146 | case R_MICROMIPS_PC23_S2: | |
| 147 | case R_MICROMIPS_PC21_S1: | |
| 108 | 148 | return R_PC; |
| 109 | 149 | case R_MIPS_GOT16: |
| 150 | case R_MICROMIPS_GOT16: | |
| 110 | 151 | if (S.isLocal()) |
| 111 | 152 | return R_MIPS_GOT_LOCAL_PAGE; |
| 112 | 153 | LLVM_FALLTHROUGH; |
| 113 | 154 | case R_MIPS_CALL16: |
| 114 | 155 | case R_MIPS_GOT_DISP: |
| 115 | 156 | case R_MIPS_TLS_GOTTPREL: |
| 157 | case R_MICROMIPS_CALL16: | |
| 158 | case R_MICROMIPS_GOT_DISP: | |
| 159 | case R_MICROMIPS_TLS_GOTTPREL: | |
| 116 | 160 | return R_MIPS_GOT_OFF; |
| 117 | 161 | case R_MIPS_CALL_HI16: |
| 118 | 162 | case R_MIPS_CALL_LO16: |
| 119 | 163 | case R_MIPS_GOT_HI16: |
| 120 | 164 | case R_MIPS_GOT_LO16: |
| 165 | case R_MICROMIPS_CALL_HI16: | |
| 166 | case R_MICROMIPS_CALL_LO16: | |
| 167 | case R_MICROMIPS_GOT_HI16: | |
| 168 | case R_MICROMIPS_GOT_LO16: | |
| 121 | 169 | return R_MIPS_GOT_OFF32; |
| 122 | 170 | case R_MIPS_GOT_PAGE: |
| 171 | case R_MICROMIPS_GOT_PAGE: | |
| 123 | 172 | return R_MIPS_GOT_LOCAL_PAGE; |
| 124 | 173 | case R_MIPS_TLS_GD: |
| 174 | case R_MICROMIPS_TLS_GD: | |
| 125 | 175 | return R_MIPS_TLSGD; |
| 126 | 176 | case R_MIPS_TLS_LDM: |
| 177 | case R_MICROMIPS_TLS_LDM: | |
| 127 | 178 | return R_MIPS_TLSLD; |
| 179 | case R_MIPS_NONE: | |
| 180 | return R_NONE; | |
| 181 | default: | |
| 182 | return R_INVALID; | |
| 128 | 183 | } |
| 129 | 184 | } |
| 130 | 185 | |
| 131 | template <class ELFT> bool MIPS<ELFT>::isPicRel(uint32_t Type) const { | |
| 186 | template <class ELFT> bool MIPS<ELFT>::isPicRel(RelType Type) const { | |
| 132 | 187 | return Type == R_MIPS_32 || Type == R_MIPS_64; |
| 133 | 188 | } |
| 134 | 189 | |
| 135 | template <class ELFT> uint32_t MIPS<ELFT>::getDynRel(uint32_t Type) const { | |
| 190 | template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType Type) const { | |
| 136 | 191 | return RelativeRel; |
| 137 | 192 | } |
| 138 | 193 | |
| 139 | 194 | template <class ELFT> |
| 140 | void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const SymbolBody &) const { | |
| 141 | write32<ELFT::TargetEndianness>(Buf, InX::Plt->getVA()); | |
| 142 | } | |
| 143 | ||
| 144 | template <endianness E, uint8_t BSIZE, uint8_t SHIFT> | |
| 145 | static int64_t getPcRelocAddend(const uint8_t *Loc) { | |
| 146 | uint32_t Instr = read32<E>(Loc); | |
| 147 | uint32_t Mask = 0xffffffff >> (32 - BSIZE); | |
| 148 | return SignExtend64<BSIZE + SHIFT>((Instr & Mask) << SHIFT); | |
| 195 | void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &) const { | |
| 196 | uint64_t VA = InX::Plt->getVA(); | |
| 197 | if (isMicroMips()) | |
| 198 | VA |= 1; | |
| 199 | write32<ELFT::TargetEndianness>(Buf, VA); | |
| 149 | 200 | } |
| 150 | 201 | |
| 151 | template <endianness E, uint8_t BSIZE, uint8_t SHIFT> | |
| 152 | static void applyMipsPcReloc(uint8_t *Loc, uint32_t Type, uint64_t V) { | |
| 153 | uint32_t Mask = 0xffffffff >> (32 - BSIZE); | |
| 154 | uint32_t Instr = read32<E>(Loc); | |
| 155 | if (SHIFT > 0) | |
| 156 | checkAlignment<(1 << SHIFT)>(Loc, V, Type); | |
| 157 | checkInt<BSIZE + SHIFT>(Loc, V, Type); | |
| 158 | write32<E>(Loc, (Instr & ~Mask) | ((V >> SHIFT) & Mask)); | |
| 202 | template <endianness E> static uint32_t readShuffle(const uint8_t *Loc) { | |
| 203 | // The major opcode of a microMIPS instruction needs to appear | |
| 204 | // in the first 16-bit word (lowest address) for efficient hardware | |
| 205 | // decode so that it knows if the instruction is 16-bit or 32-bit | |
| 206 | // as early as possible. To do so, little-endian binaries keep 16-bit | |
| 207 | // words in a big-endian order. That is why we have to swap these | |
| 208 | // words to get a correct value. | |
| 209 | uint32_t V = read32<E>(Loc); | |
| 210 | if (E == support::little) | |
| 211 | return (V << 16) | (V >> 16); | |
| 212 | return V; | |
| 159 | 213 | } |
| 160 | 214 | |
| 161 | template <endianness E> static void writeMipsHi16(uint8_t *Loc, uint64_t V) { | |
| 215 | template <endianness E> | |
| 216 | static void writeRelocation(uint8_t *Loc, uint64_t V, uint8_t BitsSize, | |
| 217 | uint8_t Shift) { | |
| 162 | 218 | uint32_t Instr = read32<E>(Loc); |
| 163 | uint16_t Res = ((V + 0x8000) >> 16) & 0xffff; | |
| 164 | write32<E>(Loc, (Instr & 0xffff0000) | Res); | |
| 219 | uint32_t Mask = 0xffffffff >> (32 - BitsSize); | |
| 220 | uint32_t Data = (Instr & ~Mask) | ((V >> Shift) & Mask); | |
| 221 | write32<E>(Loc, Data); | |
| 165 | 222 | } |
| 166 | 223 | |
| 167 | template <endianness E> static void writeMipsHigher(uint8_t *Loc, uint64_t V) { | |
| 168 | uint32_t Instr = read32<E>(Loc); | |
| 169 | uint16_t Res = ((V + 0x80008000) >> 32) & 0xffff; | |
| 170 | write32<E>(Loc, (Instr & 0xffff0000) | Res); | |
| 171 | } | |
| 224 | template <endianness E> | |
| 225 | static void writeMicroRelocation32(uint8_t *Loc, uint64_t V, uint8_t BitsSize, | |
| 226 | uint8_t Shift) { | |
| 227 | // See comments in readShuffle for purpose of this code. | |
| 228 | uint16_t *Words = (uint16_t *)Loc; | |
| 229 | if (E == support::little) | |
| 230 | std::swap(Words[0], Words[1]); | |
| 172 | 231 | |
| 173 | template <endianness E> static void writeMipsHighest(uint8_t *Loc, uint64_t V) { | |
| 174 | uint32_t Instr = read32<E>(Loc); | |
| 175 | uint16_t Res = ((V + 0x800080008000) >> 48) & 0xffff; | |
| 176 | write32<E>(Loc, (Instr & 0xffff0000) | Res); | |
| 177 | } | |
| 232 | writeRelocation<E>(Loc, V, BitsSize, Shift); | |
| 178 | 233 | |
| 179 | template <endianness E> static void writeMipsLo16(uint8_t *Loc, uint64_t V) { | |
| 180 | uint32_t Instr = read32<E>(Loc); | |
| 181 | write32<E>(Loc, (Instr & 0xffff0000) | (V & 0xffff)); | |
| 234 | if (E == support::little) | |
| 235 | std::swap(Words[0], Words[1]); | |
| 182 | 236 | } |
| 183 | 237 | |
| 184 | template <class ELFT> static bool isMipsR6() { | |
| 185 | const auto &FirstObj = cast<ELFFileBase<ELFT>>(*Config->FirstElf); | |
| 186 | uint32_t Arch = FirstObj.getObj().getHeader()->e_flags & EF_MIPS_ARCH; | |
| 187 | return Arch == EF_MIPS_ARCH_32R6 || Arch == EF_MIPS_ARCH_64R6; | |
| 238 | template <endianness E> | |
| 239 | static void writeMicroRelocation16(uint8_t *Loc, uint64_t V, uint8_t BitsSize, | |
| 240 | uint8_t Shift) { | |
| 241 | uint16_t Instr = read16<E>(Loc); | |
| 242 | uint16_t Mask = 0xffff >> (16 - BitsSize); | |
| 243 | uint16_t Data = (Instr & ~Mask) | ((V >> Shift) & Mask); | |
| 244 | write16<E>(Loc, Data); | |
| 188 | 245 | } |
| 189 | 246 | |
| 190 | 247 | template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const { |
| 191 | 248 | const endianness E = ELFT::TargetEndianness; |
| 249 | if (isMicroMips()) { | |
| 250 | uint64_t GotPlt = InX::GotPlt->getVA(); | |
| 251 | uint64_t Plt = InX::Plt->getVA(); | |
| 252 | // Overwrite trap instructions written by Writer::writeTrapInstr. | |
| 253 | memset(Buf, 0, PltHeaderSize); | |
| 254 | ||
| 255 | write16<E>(Buf, isMipsR6() ? 0x7860 : 0x7980); // addiupc v1, (GOTPLT) - . | |
| 256 | write16<E>(Buf + 4, 0xff23); // lw $25, 0($3) | |
| 257 | write16<E>(Buf + 8, 0x0535); // subu16 $2, $2, $3 | |
| 258 | write16<E>(Buf + 10, 0x2525); // srl16 $2, $2, 2 | |
| 259 | write16<E>(Buf + 12, 0x3302); // addiu $24, $2, -2 | |
| 260 | write16<E>(Buf + 14, 0xfffe); | |
| 261 | write16<E>(Buf + 16, 0x0dff); // move $15, $31 | |
| 262 | if (isMipsR6()) { | |
| 263 | write16<E>(Buf + 18, 0x0f83); // move $28, $3 | |
| 264 | write16<E>(Buf + 20, 0x472b); // jalrc $25 | |
| 265 | write16<E>(Buf + 22, 0x0c00); // nop | |
| 266 | relocateOne(Buf, R_MICROMIPS_PC19_S2, GotPlt - Plt); | |
| 267 | } else { | |
| 268 | write16<E>(Buf + 18, 0x45f9); // jalrc $25 | |
| 269 | write16<E>(Buf + 20, 0x0f83); // move $28, $3 | |
| 270 | write16<E>(Buf + 22, 0x0c00); // nop | |
| 271 | relocateOne(Buf, R_MICROMIPS_PC23_S2, GotPlt - Plt); | |
| 272 | } | |
| 273 | return; | |
| 274 | } | |
| 275 | ||
| 192 | 276 | if (Config->MipsN32Abi) { |
| 193 | 277 | write32<E>(Buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0]) |
| 194 | 278 | write32<E>(Buf + 4, 0x8dd90000); // lw $25, %lo(&GOTPLT[0])($14) |
| 195 | 279 | write32<E>(Buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0]) |
| 196 | 280 | write32<E>(Buf + 12, 0x030ec023); // subu $24, $24, $14 |
| 281 | write32<E>(Buf + 16, 0x03e07825); // move $15, $31 | |
| 282 | write32<E>(Buf + 20, 0x0018c082); // srl $24, $24, 2 | |
| 283 | } else if (ELFT::Is64Bits) { | |
| 284 | write32<E>(Buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0]) | |
| 285 | write32<E>(Buf + 4, 0xddd90000); // ld $25, %lo(&GOTPLT[0])($14) | |
| 286 | write32<E>(Buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0]) | |
| 287 | write32<E>(Buf + 12, 0x030ec023); // subu $24, $24, $14 | |
| 288 | write32<E>(Buf + 16, 0x03e07825); // move $15, $31 | |
| 289 | write32<E>(Buf + 20, 0x0018c0c2); // srl $24, $24, 3 | |
| 197 | 290 | } else { |
| 198 | 291 | write32<E>(Buf, 0x3c1c0000); // lui $28, %hi(&GOTPLT[0]) |
| 199 | 292 | write32<E>(Buf + 4, 0x8f990000); // lw $25, %lo(&GOTPLT[0])($28) |
| 200 | 293 | write32<E>(Buf + 8, 0x279c0000); // addiu $28, $28, %lo(&GOTPLT[0]) |
| 201 | 294 | write32<E>(Buf + 12, 0x031cc023); // subu $24, $24, $28 |
| 295 | write32<E>(Buf + 16, 0x03e07825); // move $15, $31 | |
| 296 | write32<E>(Buf + 20, 0x0018c082); // srl $24, $24, 2 | |
| 202 | 297 | } |
| 203 | 298 | |
| 204 | write32<E>(Buf + 16, 0x03e07825); // move $15, $31 | |
| 205 | write32<E>(Buf + 20, 0x0018c082); // srl $24, $24, 2 | |
| 206 | 299 | write32<E>(Buf + 24, 0x0320f809); // jalr $25 |
| 207 | 300 | write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2 |
| 208 | 301 | |
| 209 | 302 | uint64_t GotPlt = InX::GotPlt->getVA(); |
| 210 | writeMipsHi16<E>(Buf, GotPlt); | |
| 211 | writeMipsLo16<E>(Buf + 4, GotPlt); | |
| 212 | writeMipsLo16<E>(Buf + 8, GotPlt); | |
| 303 | writeRelocation<E>(Buf, GotPlt + 0x8000, 16, 16); | |
| 304 | writeRelocation<E>(Buf + 4, GotPlt, 16, 0); | |
| 305 | writeRelocation<E>(Buf + 8, GotPlt, 16, 0); | |
| 213 | 306 | } |
| 214 | 307 | |
| 215 | 308 | template <class ELFT> |
| ... | ... | @@ -217,25 +310,45 @@ void MIPS<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 217 | 310 | uint64_t PltEntryAddr, int32_t Index, |
| 218 | 311 | unsigned RelOff) const { |
| 219 | 312 | const endianness E = ELFT::TargetEndianness; |
| 313 | if (isMicroMips()) { | |
| 314 | // Overwrite trap instructions written by Writer::writeTrapInstr. | |
| 315 | memset(Buf, 0, PltEntrySize); | |
| 316 | ||
| 317 | if (isMipsR6()) { | |
| 318 | write16<E>(Buf, 0x7840); // addiupc $2, (GOTPLT) - . | |
| 319 | write16<E>(Buf + 4, 0xff22); // lw $25, 0($2) | |
| 320 | write16<E>(Buf + 8, 0x0f02); // move $24, $2 | |
| 321 | write16<E>(Buf + 10, 0x4723); // jrc $25 / jr16 $25 | |
| 322 | relocateOne(Buf, R_MICROMIPS_PC19_S2, GotPltEntryAddr - PltEntryAddr); | |
| 323 | } else { | |
| 324 | write16<E>(Buf, 0x7900); // addiupc $2, (GOTPLT) - . | |
| 325 | write16<E>(Buf + 4, 0xff22); // lw $25, 0($2) | |
| 326 | write16<E>(Buf + 8, 0x4599); // jrc $25 / jr16 $25 | |
| 327 | write16<E>(Buf + 10, 0x0f02); // move $24, $2 | |
| 328 | relocateOne(Buf, R_MICROMIPS_PC23_S2, GotPltEntryAddr - PltEntryAddr); | |
| 329 | } | |
| 330 | return; | |
| 331 | } | |
| 332 | ||
| 220 | 333 | write32<E>(Buf, 0x3c0f0000); // lui $15, %hi(.got.plt entry) |
| 221 | 334 | write32<E>(Buf + 4, 0x8df90000); // l[wd] $25, %lo(.got.plt entry)($15) |
| 222 | // jr $25 | |
| 223 | write32<E>(Buf + 8, isMipsR6<ELFT>() ? 0x03200009 : 0x03200008); | |
| 335 | write32<E>(Buf + 8, isMipsR6() ? 0x03200009 : 0x03200008); // jr $25 | |
| 224 | 336 | write32<E>(Buf + 12, 0x25f80000); // addiu $24, $15, %lo(.got.plt entry) |
| 225 | writeMipsHi16<E>(Buf, GotPltEntryAddr); | |
| 226 | writeMipsLo16<E>(Buf + 4, GotPltEntryAddr); | |
| 227 | writeMipsLo16<E>(Buf + 12, GotPltEntryAddr); | |
| 337 | writeRelocation<E>(Buf, GotPltEntryAddr + 0x8000, 16, 16); | |
| 338 | writeRelocation<E>(Buf + 4, GotPltEntryAddr, 16, 0); | |
| 339 | writeRelocation<E>(Buf + 12, GotPltEntryAddr, 16, 0); | |
| 228 | 340 | } |
| 229 | 341 | |
| 230 | 342 | template <class ELFT> |
| 231 | bool MIPS<ELFT>::needsThunk(RelExpr Expr, uint32_t Type, const InputFile *File, | |
| 232 | const SymbolBody &S) const { | |
| 343 | bool MIPS<ELFT>::needsThunk(RelExpr Expr, RelType Type, const InputFile *File, | |
| 344 | uint64_t BranchAddr, const Symbol &S) const { | |
| 233 | 345 | // Any MIPS PIC code function is invoked with its address in register $t9. |
| 234 | 346 | // So if we have a branch instruction from non-PIC code to the PIC one |
| 235 | 347 | // we cannot make the jump directly and need to create a small stubs |
| 236 | 348 | // to save the target function address. |
| 237 | 349 | // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf |
| 238 | if (Type != R_MIPS_26) | |
| 350 | if (Type != R_MIPS_26 && Type != R_MICROMIPS_26_S1 && | |
| 351 | Type != R_MICROMIPS_PC26_S1) | |
| 239 | 352 | return false; |
| 240 | 353 | auto *F = dyn_cast_or_null<ELFFileBase<ELFT>>(File); |
| 241 | 354 | if (!F) |
| ... | ... | @@ -243,18 +356,16 @@ bool MIPS<ELFT>::needsThunk(RelExpr Expr, uint32_t Type, const InputFile *File, |
| 243 | 356 | // If current file has PIC code, LA25 stub is not required. |
| 244 | 357 | if (F->getObj().getHeader()->e_flags & EF_MIPS_PIC) |
| 245 | 358 | return false; |
| 246 | auto *D = dyn_cast<DefinedRegular>(&S); | |
| 359 | auto *D = dyn_cast<Defined>(&S); | |
| 247 | 360 | // LA25 is required if target file has PIC code |
| 248 | 361 | // or target symbol is a PIC symbol. |
| 249 | return D && D->isMipsPIC<ELFT>(); | |
| 362 | return D && isMipsPIC<ELFT>(D); | |
| 250 | 363 | } |
| 251 | 364 | |
| 252 | 365 | template <class ELFT> |
| 253 | int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const { | |
| 366 | int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *Buf, RelType Type) const { | |
| 254 | 367 | const endianness E = ELFT::TargetEndianness; |
| 255 | 368 | switch (Type) { |
| 256 | default: | |
| 257 | return 0; | |
| 258 | 369 | case R_MIPS_32: |
| 259 | 370 | case R_MIPS_GPREL32: |
| 260 | 371 | case R_MIPS_TLS_DTPREL32: |
| ... | ... | @@ -264,7 +375,11 @@ int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const { |
| 264 | 375 | // FIXME (simon): If the relocation target symbol is not a PLT entry |
| 265 | 376 | // we should use another expression for calculation: |
| 266 | 377 | // ((A << 2) | (P & 0xf0000000)) >> 2 |
| 267 | return SignExtend64<28>((read32<E>(Buf) & 0x3ffffff) << 2); | |
| 378 | return SignExtend64<28>(read32<E>(Buf) << 2); | |
| 379 | case R_MIPS_GOT16: | |
| 380 | case R_MIPS_HI16: | |
| 381 | case R_MIPS_PCHI16: | |
| 382 | return SignExtend64<16>(read32<E>(Buf)) << 16; | |
| 268 | 383 | case R_MIPS_GPREL16: |
| 269 | 384 | case R_MIPS_LO16: |
| 270 | 385 | case R_MIPS_PCLO16: |
| ... | ... | @@ -273,21 +388,53 @@ int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const { |
| 273 | 388 | case R_MIPS_TLS_TPREL_HI16: |
| 274 | 389 | case R_MIPS_TLS_TPREL_LO16: |
| 275 | 390 | return SignExtend64<16>(read32<E>(Buf)); |
| 391 | case R_MICROMIPS_GOT16: | |
| 392 | case R_MICROMIPS_HI16: | |
| 393 | return SignExtend64<16>(readShuffle<E>(Buf)) << 16; | |
| 394 | case R_MICROMIPS_GPREL16: | |
| 395 | case R_MICROMIPS_LO16: | |
| 396 | case R_MICROMIPS_TLS_DTPREL_HI16: | |
| 397 | case R_MICROMIPS_TLS_DTPREL_LO16: | |
| 398 | case R_MICROMIPS_TLS_TPREL_HI16: | |
| 399 | case R_MICROMIPS_TLS_TPREL_LO16: | |
| 400 | return SignExtend64<16>(readShuffle<E>(Buf)); | |
| 401 | case R_MICROMIPS_GPREL7_S2: | |
| 402 | return SignExtend64<9>(readShuffle<E>(Buf) << 2); | |
| 276 | 403 | case R_MIPS_PC16: |
| 277 | return getPcRelocAddend<E, 16, 2>(Buf); | |
| 404 | return SignExtend64<18>(read32<E>(Buf) << 2); | |
| 278 | 405 | case R_MIPS_PC19_S2: |
| 279 | return getPcRelocAddend<E, 19, 2>(Buf); | |
| 406 | return SignExtend64<21>(read32<E>(Buf) << 2); | |
| 280 | 407 | case R_MIPS_PC21_S2: |
| 281 | return getPcRelocAddend<E, 21, 2>(Buf); | |
| 408 | return SignExtend64<23>(read32<E>(Buf) << 2); | |
| 282 | 409 | case R_MIPS_PC26_S2: |
| 283 | return getPcRelocAddend<E, 26, 2>(Buf); | |
| 410 | return SignExtend64<28>(read32<E>(Buf) << 2); | |
| 284 | 411 | case R_MIPS_PC32: |
| 285 | return getPcRelocAddend<E, 32, 0>(Buf); | |
| 412 | return SignExtend64<32>(read32<E>(Buf)); | |
| 413 | case R_MICROMIPS_26_S1: | |
| 414 | return SignExtend64<27>(readShuffle<E>(Buf) << 1); | |
| 415 | case R_MICROMIPS_PC7_S1: | |
| 416 | return SignExtend64<8>(read16<E>(Buf) << 1); | |
| 417 | case R_MICROMIPS_PC10_S1: | |
| 418 | return SignExtend64<11>(read16<E>(Buf) << 1); | |
| 419 | case R_MICROMIPS_PC16_S1: | |
| 420 | return SignExtend64<17>(readShuffle<E>(Buf) << 1); | |
| 421 | case R_MICROMIPS_PC18_S3: | |
| 422 | return SignExtend64<21>(readShuffle<E>(Buf) << 3); | |
| 423 | case R_MICROMIPS_PC19_S2: | |
| 424 | return SignExtend64<21>(readShuffle<E>(Buf) << 2); | |
| 425 | case R_MICROMIPS_PC21_S1: | |
| 426 | return SignExtend64<22>(readShuffle<E>(Buf) << 1); | |
| 427 | case R_MICROMIPS_PC23_S2: | |
| 428 | return SignExtend64<25>(readShuffle<E>(Buf) << 2); | |
| 429 | case R_MICROMIPS_PC26_S1: | |
| 430 | return SignExtend64<27>(readShuffle<E>(Buf) << 1); | |
| 431 | default: | |
| 432 | return 0; | |
| 286 | 433 | } |
| 287 | 434 | } |
| 288 | 435 | |
| 289 | 436 | static std::pair<uint32_t, uint64_t> |
| 290 | calculateMipsRelChain(uint8_t *Loc, uint32_t Type, uint64_t Val) { | |
| 437 | calculateMipsRelChain(uint8_t *Loc, RelType Type, uint64_t Val) { | |
| 291 | 438 | // MIPS N64 ABI packs multiple relocations into the single relocation |
| 292 | 439 | // record. In general, all up to three relocations can have arbitrary |
| 293 | 440 | // types. In fact, Clang and GCC uses only a few combinations. For now, |
| ... | ... | @@ -300,32 +447,43 @@ calculateMipsRelChain(uint8_t *Loc, uint32_t Type, uint64_t Val) { |
| 300 | 447 | // relocations used to modify result of the first one: extend it to |
| 301 | 448 | // 64-bit, extract high or low part etc. For details, see part 2.9 Relocation |
| 302 | 449 | // at the https://dmz-portal.mips.com/mw/images/8/82/007-4658-001.pdf |
| 303 | uint32_t Type2 = (Type >> 8) & 0xff; | |
| 304 | uint32_t Type3 = (Type >> 16) & 0xff; | |
| 450 | RelType Type2 = (Type >> 8) & 0xff; | |
| 451 | RelType Type3 = (Type >> 16) & 0xff; | |
| 305 | 452 | if (Type2 == R_MIPS_NONE && Type3 == R_MIPS_NONE) |
| 306 | 453 | return std::make_pair(Type, Val); |
| 307 | 454 | if (Type2 == R_MIPS_64 && Type3 == R_MIPS_NONE) |
| 308 | 455 | return std::make_pair(Type2, Val); |
| 309 | 456 | if (Type2 == R_MIPS_SUB && (Type3 == R_MIPS_HI16 || Type3 == R_MIPS_LO16)) |
| 310 | 457 | 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); | |
| 311 | 461 | error(getErrorLocation(Loc) + "unsupported relocations combination " + |
| 312 | 462 | Twine(Type)); |
| 313 | 463 | return std::make_pair(Type & 0xff, Val); |
| 314 | 464 | } |
| 315 | 465 | |
| 316 | 466 | template <class ELFT> |
| 317 | void MIPS<ELFT>::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 467 | void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 318 | 468 | const endianness E = ELFT::TargetEndianness; |
| 469 | ||
| 319 | 470 | // Thread pointer and DRP offsets from the start of TLS data area. |
| 320 | 471 | // https://www.linux-mips.org/wiki/NPTL |
| 321 | 472 | if (Type == R_MIPS_TLS_DTPREL_HI16 || Type == R_MIPS_TLS_DTPREL_LO16 || |
| 322 | Type == R_MIPS_TLS_DTPREL32 || Type == R_MIPS_TLS_DTPREL64) | |
| 473 | Type == R_MIPS_TLS_DTPREL32 || Type == R_MIPS_TLS_DTPREL64 || | |
| 474 | Type == R_MICROMIPS_TLS_DTPREL_HI16 || | |
| 475 | Type == R_MICROMIPS_TLS_DTPREL_LO16) { | |
| 323 | 476 | Val -= 0x8000; |
| 324 | else if (Type == R_MIPS_TLS_TPREL_HI16 || Type == R_MIPS_TLS_TPREL_LO16 || | |
| 325 | Type == R_MIPS_TLS_TPREL32 || Type == R_MIPS_TLS_TPREL64) | |
| 477 | } else if (Type == R_MIPS_TLS_TPREL_HI16 || Type == R_MIPS_TLS_TPREL_LO16 || | |
| 478 | Type == R_MIPS_TLS_TPREL32 || Type == R_MIPS_TLS_TPREL64 || | |
| 479 | Type == R_MICROMIPS_TLS_TPREL_HI16 || | |
| 480 | Type == R_MICROMIPS_TLS_TPREL_LO16) { | |
| 326 | 481 | Val -= 0x7000; |
| 482 | } | |
| 483 | ||
| 327 | 484 | if (ELFT::Is64Bits || Config->MipsN32Abi) |
| 328 | 485 | std::tie(Type, Val) = calculateMipsRelChain(Loc, Type, Val); |
| 486 | ||
| 329 | 487 | switch (Type) { |
| 330 | 488 | case R_MIPS_32: |
| 331 | 489 | case R_MIPS_GPREL32: |
| ... | ... | @@ -339,36 +497,65 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 339 | 497 | write64<E>(Loc, Val); |
| 340 | 498 | break; |
| 341 | 499 | case R_MIPS_26: |
| 342 | write32<E>(Loc, (read32<E>(Loc) & ~0x3ffffff) | ((Val >> 2) & 0x3ffffff)); | |
| 500 | writeRelocation<E>(Loc, Val, 26, 2); | |
| 343 | 501 | break; |
| 344 | 502 | case R_MIPS_GOT16: |
| 345 | 503 | // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode |
| 346 | 504 | // is updated addend (not a GOT index). In that case write high 16 bits |
| 347 | 505 | // to store a correct addend value. |
| 348 | if (Config->Relocatable) | |
| 349 | writeMipsHi16<E>(Loc, Val); | |
| 350 | else { | |
| 506 | if (Config->Relocatable) { | |
| 507 | writeRelocation<E>(Loc, Val + 0x8000, 16, 16); | |
| 508 | } else { | |
| 351 | 509 | checkInt<16>(Loc, Val, Type); |
| 352 | writeMipsLo16<E>(Loc, Val); | |
| 510 | writeRelocation<E>(Loc, Val, 16, 0); | |
| 353 | 511 | } |
| 354 | 512 | break; |
| 513 | case R_MICROMIPS_GOT16: | |
| 514 | if (Config->Relocatable) { | |
| 515 | writeMicroRelocation32<E>(Loc, Val + 0x8000, 16, 16); | |
| 516 | } else { | |
| 517 | checkInt<16>(Loc, Val, Type); | |
| 518 | writeMicroRelocation32<E>(Loc, Val, 16, 0); | |
| 519 | } | |
| 520 | break; | |
| 521 | case R_MIPS_CALL16: | |
| 355 | 522 | case R_MIPS_GOT_DISP: |
| 356 | 523 | case R_MIPS_GOT_PAGE: |
| 357 | 524 | case R_MIPS_GPREL16: |
| 358 | 525 | case R_MIPS_TLS_GD: |
| 526 | case R_MIPS_TLS_GOTTPREL: | |
| 359 | 527 | case R_MIPS_TLS_LDM: |
| 360 | 528 | checkInt<16>(Loc, Val, Type); |
| 361 | 529 | LLVM_FALLTHROUGH; |
| 362 | case R_MIPS_CALL16: | |
| 363 | 530 | case R_MIPS_CALL_LO16: |
| 364 | 531 | case R_MIPS_GOT_LO16: |
| 365 | 532 | case R_MIPS_GOT_OFST: |
| 366 | 533 | case R_MIPS_LO16: |
| 367 | 534 | case R_MIPS_PCLO16: |
| 368 | 535 | case R_MIPS_TLS_DTPREL_LO16: |
| 369 | case R_MIPS_TLS_GOTTPREL: | |
| 370 | 536 | case R_MIPS_TLS_TPREL_LO16: |
| 371 | writeMipsLo16<E>(Loc, Val); | |
| 537 | writeRelocation<E>(Loc, Val, 16, 0); | |
| 538 | break; | |
| 539 | case R_MICROMIPS_GOT_DISP: | |
| 540 | case R_MICROMIPS_GOT_PAGE: | |
| 541 | case R_MICROMIPS_GPREL16: | |
| 542 | case R_MICROMIPS_TLS_GD: | |
| 543 | case R_MICROMIPS_TLS_LDM: | |
| 544 | checkInt<16>(Loc, Val, Type); | |
| 545 | writeMicroRelocation32<E>(Loc, Val, 16, 0); | |
| 546 | break; | |
| 547 | case R_MICROMIPS_CALL16: | |
| 548 | case R_MICROMIPS_CALL_LO16: | |
| 549 | case R_MICROMIPS_GOT_OFST: | |
| 550 | case R_MICROMIPS_LO16: | |
| 551 | case R_MICROMIPS_TLS_DTPREL_LO16: | |
| 552 | case R_MICROMIPS_TLS_GOTTPREL: | |
| 553 | case R_MICROMIPS_TLS_TPREL_LO16: | |
| 554 | writeMicroRelocation32<E>(Loc, Val, 16, 0); | |
| 555 | break; | |
| 556 | case R_MICROMIPS_GPREL7_S2: | |
| 557 | checkInt<7>(Loc, Val, Type); | |
| 558 | writeMicroRelocation32<E>(Loc, Val, 7, 2); | |
| 372 | 559 | break; |
| 373 | 560 | case R_MIPS_CALL_HI16: |
| 374 | 561 | case R_MIPS_GOT_HI16: |
| ... | ... | @@ -376,40 +563,107 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 376 | 563 | case R_MIPS_PCHI16: |
| 377 | 564 | case R_MIPS_TLS_DTPREL_HI16: |
| 378 | 565 | case R_MIPS_TLS_TPREL_HI16: |
| 379 | writeMipsHi16<E>(Loc, Val); | |
| 566 | writeRelocation<E>(Loc, Val + 0x8000, 16, 16); | |
| 567 | break; | |
| 568 | case R_MICROMIPS_CALL_HI16: | |
| 569 | case R_MICROMIPS_GOT_HI16: | |
| 570 | case R_MICROMIPS_HI16: | |
| 571 | case R_MICROMIPS_TLS_DTPREL_HI16: | |
| 572 | case R_MICROMIPS_TLS_TPREL_HI16: | |
| 573 | writeMicroRelocation32<E>(Loc, Val + 0x8000, 16, 16); | |
| 380 | 574 | break; |
| 381 | 575 | case R_MIPS_HIGHER: |
| 382 | writeMipsHigher<E>(Loc, Val); | |
| 576 | writeRelocation<E>(Loc, Val + 0x80008000, 16, 32); | |
| 383 | 577 | break; |
| 384 | 578 | case R_MIPS_HIGHEST: |
| 385 | writeMipsHighest<E>(Loc, Val); | |
| 579 | writeRelocation<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); | |
| 386 | 586 | break; |
| 387 | 587 | case R_MIPS_JALR: |
| 588 | case R_MICROMIPS_JALR: | |
| 388 | 589 | // Ignore this optimization relocation for now |
| 389 | 590 | break; |
| 390 | 591 | case R_MIPS_PC16: |
| 391 | applyMipsPcReloc<E, 16, 2>(Loc, Type, Val); | |
| 592 | checkAlignment<4>(Loc, Val, Type); | |
| 593 | checkInt<18>(Loc, Val, Type); | |
| 594 | writeRelocation<E>(Loc, Val, 16, 2); | |
| 392 | 595 | break; |
| 393 | 596 | case R_MIPS_PC19_S2: |
| 394 | applyMipsPcReloc<E, 19, 2>(Loc, Type, Val); | |
| 597 | checkAlignment<4>(Loc, Val, Type); | |
| 598 | checkInt<21>(Loc, Val, Type); | |
| 599 | writeRelocation<E>(Loc, Val, 19, 2); | |
| 395 | 600 | break; |
| 396 | 601 | case R_MIPS_PC21_S2: |
| 397 | applyMipsPcReloc<E, 21, 2>(Loc, Type, Val); | |
| 602 | checkAlignment<4>(Loc, Val, Type); | |
| 603 | checkInt<23>(Loc, Val, Type); | |
| 604 | writeRelocation<E>(Loc, Val, 21, 2); | |
| 398 | 605 | break; |
| 399 | 606 | case R_MIPS_PC26_S2: |
| 400 | applyMipsPcReloc<E, 26, 2>(Loc, Type, Val); | |
| 607 | checkAlignment<4>(Loc, Val, Type); | |
| 608 | checkInt<28>(Loc, Val, Type); | |
| 609 | writeRelocation<E>(Loc, Val, 26, 2); | |
| 401 | 610 | break; |
| 402 | 611 | case R_MIPS_PC32: |
| 403 | applyMipsPcReloc<E, 32, 0>(Loc, Type, Val); | |
| 612 | writeRelocation<E>(Loc, Val, 32, 0); | |
| 613 | break; | |
| 614 | case R_MICROMIPS_26_S1: | |
| 615 | case R_MICROMIPS_PC26_S1: | |
| 616 | checkInt<27>(Loc, Val, Type); | |
| 617 | writeMicroRelocation32<E>(Loc, Val, 26, 1); | |
| 618 | break; | |
| 619 | case R_MICROMIPS_PC7_S1: | |
| 620 | checkInt<8>(Loc, Val, Type); | |
| 621 | writeMicroRelocation16<E>(Loc, Val, 7, 1); | |
| 622 | break; | |
| 623 | case R_MICROMIPS_PC10_S1: | |
| 624 | checkInt<11>(Loc, Val, Type); | |
| 625 | writeMicroRelocation16<E>(Loc, Val, 10, 1); | |
| 626 | break; | |
| 627 | case R_MICROMIPS_PC16_S1: | |
| 628 | checkInt<17>(Loc, Val, Type); | |
| 629 | writeMicroRelocation32<E>(Loc, Val, 16, 1); | |
| 630 | break; | |
| 631 | case R_MICROMIPS_PC18_S3: | |
| 632 | checkInt<21>(Loc, Val, Type); | |
| 633 | writeMicroRelocation32<E>(Loc, Val, 18, 3); | |
| 634 | break; | |
| 635 | case R_MICROMIPS_PC19_S2: | |
| 636 | checkInt<21>(Loc, Val, Type); | |
| 637 | writeMicroRelocation32<E>(Loc, Val, 19, 2); | |
| 638 | break; | |
| 639 | case R_MICROMIPS_PC21_S1: | |
| 640 | checkInt<22>(Loc, Val, Type); | |
| 641 | writeMicroRelocation32<E>(Loc, Val, 21, 1); | |
| 642 | break; | |
| 643 | case R_MICROMIPS_PC23_S2: | |
| 644 | checkInt<25>(Loc, Val, Type); | |
| 645 | writeMicroRelocation32<E>(Loc, Val, 23, 2); | |
| 404 | 646 | break; |
| 405 | 647 | default: |
| 406 | 648 | error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); |
| 407 | 649 | } |
| 408 | 650 | } |
| 409 | 651 | |
| 410 | template <class ELFT> | |
| 411 | bool MIPS<ELFT>::usesOnlyLowPageBits(uint32_t Type) const { | |
| 412 | return Type == R_MIPS_LO16 || Type == R_MIPS_GOT_OFST; | |
| 652 | template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType Type) const { | |
| 653 | return Type == R_MIPS_LO16 || Type == R_MIPS_GOT_OFST || | |
| 654 | Type == R_MICROMIPS_LO16 || Type == R_MICROMIPS_GOT_OFST; | |
| 655 | } | |
| 656 | ||
| 657 | // Return true if the symbol is a PIC function. | |
| 658 | template <class ELFT> bool elf::isMipsPIC(const Defined *Sym) { | |
| 659 | typedef typename ELFT::Ehdr Elf_Ehdr; | |
| 660 | if (!Sym->Section || !Sym->isFunc()) | |
| 661 | return false; | |
| 662 | ||
| 663 | auto *Sec = cast<InputSectionBase>(Sym->Section); | |
| 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); | |
| 413 | 667 | } |
| 414 | 668 | |
| 415 | 669 | template <class ELFT> TargetInfo *elf::getMipsTargetInfo() { |
| ... | ... | @@ -421,3 +675,8 @@ template TargetInfo *elf::getMipsTargetInfo<ELF32LE>(); |
| 421 | 675 | template TargetInfo *elf::getMipsTargetInfo<ELF32BE>(); |
| 422 | 676 | template TargetInfo *elf::getMipsTargetInfo<ELF64LE>(); |
| 423 | 677 | template TargetInfo *elf::getMipsTargetInfo<ELF64BE>(); |
| 678 | ||
| 679 | template bool elf::isMipsPIC<ELF32LE>(const Defined *); | |
| 680 | template bool elf::isMipsPIC<ELF32BE>(const Defined *); | |
| 681 | template bool elf::isMipsPIC<ELF64LE>(const Defined *); | |
| 682 | template bool elf::isMipsPIC<ELF64BE>(const Defined *); |
deps/lld/ELF/Arch/MipsArchTree.cpp+34-20| ... | ... | @@ -11,11 +11,11 @@ |
| 11 | 11 | // |
| 12 | 12 | //===---------------------------------------------------------------------===// |
| 13 | 13 | |
| 14 | #include "Error.h" | |
| 15 | 14 | #include "InputFiles.h" |
| 16 | 15 | #include "SymbolTable.h" |
| 17 | 16 | #include "Writer.h" |
| 18 | 17 | |
| 18 | #include "lld/Common/ErrorHandler.h" | |
| 19 | 19 | #include "llvm/BinaryFormat/ELF.h" |
| 20 | 20 | #include "llvm/Object/ELF.h" |
| 21 | 21 | #include "llvm/Support/MipsABIFlags.h" |
| ... | ... | @@ -34,7 +34,7 @@ struct ArchTreeEdge { |
| 34 | 34 | }; |
| 35 | 35 | |
| 36 | 36 | struct FileFlags { |
| 37 | StringRef Filename; | |
| 37 | InputFile *File; | |
| 38 | 38 | uint32_t Flags; |
| 39 | 39 | }; |
| 40 | 40 | } // namespace |
| ... | ... | @@ -73,17 +73,17 @@ static void checkFlags(ArrayRef<FileFlags> Files) { |
| 73 | 73 | uint32_t ABI2 = F.Flags & (EF_MIPS_ABI | EF_MIPS_ABI2); |
| 74 | 74 | if (ABI != ABI2) |
| 75 | 75 | error("target ABI '" + getAbiName(ABI) + "' is incompatible with '" + |
| 76 | getAbiName(ABI2) + "': " + F.Filename); | |
| 76 | getAbiName(ABI2) + "': " + toString(F.File)); | |
| 77 | 77 | |
| 78 | 78 | bool Nan2 = F.Flags & EF_MIPS_NAN2008; |
| 79 | 79 | if (Nan != Nan2) |
| 80 | 80 | error("target -mnan=" + getNanName(Nan) + " is incompatible with -mnan=" + |
| 81 | getNanName(Nan2) + ": " + F.Filename); | |
| 81 | getNanName(Nan2) + ": " + toString(F.File)); | |
| 82 | 82 | |
| 83 | 83 | bool Fp2 = F.Flags & EF_MIPS_FP64; |
| 84 | 84 | if (Fp != Fp2) |
| 85 | 85 | error("target -mfp" + getFpName(Fp) + " is incompatible with -mfp" + |
| 86 | getFpName(Fp2) + ": " + F.Filename); | |
| 86 | getFpName(Fp2) + ": " + toString(F.File)); | |
| 87 | 87 | } |
| 88 | 88 | } |
| 89 | 89 | |
| ... | ... | @@ -102,9 +102,11 @@ static uint32_t getPicFlags(ArrayRef<FileFlags> Files) { |
| 102 | 102 | for (const FileFlags &F : Files.slice(1)) { |
| 103 | 103 | bool IsPic2 = F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC); |
| 104 | 104 | if (IsPic && !IsPic2) |
| 105 | warn("linking abicalls code with non-abicalls file: " + F.Filename); | |
| 105 | warn("linking abicalls code " + toString(Files[0].File) + | |
| 106 | " with non-abicalls file: " + toString(F.File)); | |
| 106 | 107 | if (!IsPic && IsPic2) |
| 107 | warn("linking non-abicalls code with abicalls file: " + F.Filename); | |
| 108 | warn("linking non-abicalls code " + toString(Files[0].File) + | |
| 109 | " with abicalls file: " + toString(F.File)); | |
| 108 | 110 | } |
| 109 | 111 | |
| 110 | 112 | // Compute the result PIC/non-PIC flag. |
| ... | ... | @@ -221,10 +223,6 @@ static StringRef getMachName(uint32_t Flags) { |
| 221 | 223 | } |
| 222 | 224 | |
| 223 | 225 | static StringRef getArchName(uint32_t Flags) { |
| 224 | StringRef S = getMachName(Flags); | |
| 225 | if (!S.empty()) | |
| 226 | return S; | |
| 227 | ||
| 228 | 226 | switch (Flags & EF_MIPS_ARCH) { |
| 229 | 227 | case EF_MIPS_ARCH_1: |
| 230 | 228 | return "mips1"; |
| ... | ... | @@ -253,6 +251,14 @@ static StringRef getArchName(uint32_t Flags) { |
| 253 | 251 | } |
| 254 | 252 | } |
| 255 | 253 | |
| 254 | static std::string getFullArchName(uint32_t Flags) { | |
| 255 | StringRef Arch = getArchName(Flags); | |
| 256 | StringRef Mach = getMachName(Flags); | |
| 257 | if (Mach.empty()) | |
| 258 | return Arch.str(); | |
| 259 | return (Arch + " (" + Mach + ")").str(); | |
| 260 | } | |
| 261 | ||
| 256 | 262 | // There are (arguably too) many MIPS ISAs out there. Their relationships |
| 257 | 263 | // can be represented as a forest. If all input files have ISAs which |
| 258 | 264 | // reachable by repeated proceeding from the single child to the parent, |
| ... | ... | @@ -272,8 +278,9 @@ static uint32_t getArchFlags(ArrayRef<FileFlags> Files) { |
| 272 | 278 | if (isArchMatched(New, Ret)) |
| 273 | 279 | continue; |
| 274 | 280 | if (!isArchMatched(Ret, New)) { |
| 275 | error("target ISA '" + getArchName(Ret) + "' is incompatible with '" + | |
| 276 | getArchName(New) + "': " + F.Filename); | |
| 281 | error("incompatible target ISA:\n>>> " + toString(Files[0].File) + ": " + | |
| 282 | getFullArchName(Ret) + "\n>>> " + toString(F.File) + ": " + | |
| 283 | getFullArchName(New)); | |
| 277 | 284 | return 0; |
| 278 | 285 | } |
| 279 | 286 | Ret = New; |
| ... | ... | @@ -281,10 +288,10 @@ static uint32_t getArchFlags(ArrayRef<FileFlags> Files) { |
| 281 | 288 | return Ret; |
| 282 | 289 | } |
| 283 | 290 | |
| 284 | template <class ELFT> uint32_t elf::getMipsEFlags() { | |
| 291 | template <class ELFT> uint32_t elf::calcMipsEFlags() { | |
| 285 | 292 | std::vector<FileFlags> V; |
| 286 | for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) | |
| 287 | V.push_back({F->getName(), F->getObj().getHeader()->e_flags}); | |
| 293 | for (InputFile *F : ObjectFiles) | |
| 294 | V.push_back({F, cast<ObjFile<ELFT>>(F)->getObj().getHeader()->e_flags}); | |
| 288 | 295 | if (V.empty()) |
| 289 | 296 | return 0; |
| 290 | 297 | checkFlags(V); |
| ... | ... | @@ -363,7 +370,14 @@ bool elf::isMipsN32Abi(const InputFile *F) { |
| 363 | 370 | } |
| 364 | 371 | } |
| 365 | 372 | |
| 366 | template uint32_t elf::getMipsEFlags<ELF32LE>(); | |
| 367 | template uint32_t elf::getMipsEFlags<ELF32BE>(); | |
| 368 | template uint32_t elf::getMipsEFlags<ELF64LE>(); | |
| 369 | template uint32_t elf::getMipsEFlags<ELF64BE>(); | |
| 373 | bool elf::isMicroMips() { return Config->EFlags & EF_MIPS_MICROMIPS; } | |
| 374 | ||
| 375 | bool elf::isMipsR6() { | |
| 376 | uint32_t Arch = Config->EFlags & EF_MIPS_ARCH; | |
| 377 | return Arch == EF_MIPS_ARCH_32R6 || Arch == EF_MIPS_ARCH_64R6; | |
| 378 | } | |
| 379 | ||
| 380 | template uint32_t elf::calcMipsEFlags<ELF32LE>(); | |
| 381 | template uint32_t elf::calcMipsEFlags<ELF32BE>(); | |
| 382 | template uint32_t elf::calcMipsEFlags<ELF64LE>(); | |
| 383 | template uint32_t elf::calcMipsEFlags<ELF64BE>(); |
deps/lld/ELF/Arch/PPC.cpp+21-15| ... | ... | @@ -7,9 +7,9 @@ |
| 7 | 7 | // |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | #include "Error.h" | |
| 11 | 10 | #include "Symbols.h" |
| 12 | 11 | #include "Target.h" |
| 12 | #include "lld/Common/ErrorHandler.h" | |
| 13 | 13 | #include "llvm/Support/Endian.h" |
| 14 | 14 | |
| 15 | 15 | using namespace llvm; |
| ... | ... | @@ -22,17 +22,33 @@ namespace { |
| 22 | 22 | class PPC final : public TargetInfo { |
| 23 | 23 | public: |
| 24 | 24 | PPC() { GotBaseSymOff = 0x8000; } |
| 25 | void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 26 | RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 25 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 26 | RelExpr getRelExpr(RelType Type, const Symbol &S, | |
| 27 | 27 | const uint8_t *Loc) const override; |
| 28 | 28 | }; |
| 29 | 29 | } // namespace |
| 30 | 30 | |
| 31 | void PPC::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 31 | RelExpr PPC::getRelExpr(RelType Type, const Symbol &S, | |
| 32 | const uint8_t *Loc) const { | |
| 33 | switch (Type) { | |
| 34 | case R_PPC_REL24: | |
| 35 | case R_PPC_REL32: | |
| 36 | return R_PC; | |
| 37 | case R_PPC_PLTREL24: | |
| 38 | return R_PLT_PC; | |
| 39 | default: | |
| 40 | return R_ABS; | |
| 41 | } | |
| 42 | } | |
| 43 | ||
| 44 | void PPC::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 32 | 45 | switch (Type) { |
| 33 | 46 | case R_PPC_ADDR16_HA: |
| 34 | 47 | write16be(Loc, (Val + 0x8000) >> 16); |
| 35 | 48 | break; |
| 49 | case R_PPC_ADDR16_HI: | |
| 50 | write16be(Loc, Val >> 16); | |
| 51 | break; | |
| 36 | 52 | case R_PPC_ADDR16_LO: |
| 37 | 53 | write16be(Loc, Val); |
| 38 | 54 | break; |
| ... | ... | @@ -40,6 +56,7 @@ void PPC::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 40 | 56 | case R_PPC_REL32: |
| 41 | 57 | write32be(Loc, Val); |
| 42 | 58 | break; |
| 59 | case R_PPC_PLTREL24: | |
| 43 | 60 | case R_PPC_REL24: |
| 44 | 61 | write32be(Loc, read32be(Loc) | (Val & 0x3FFFFFC)); |
| 45 | 62 | break; |
| ... | ... | @@ -48,17 +65,6 @@ void PPC::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 48 | 65 | } |
| 49 | 66 | } |
| 50 | 67 | |
| 51 | RelExpr PPC::getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 52 | const uint8_t *Loc) const { | |
| 53 | switch (Type) { | |
| 54 | case R_PPC_REL24: | |
| 55 | case R_PPC_REL32: | |
| 56 | return R_PC; | |
| 57 | default: | |
| 58 | return R_ABS; | |
| 59 | } | |
| 60 | } | |
| 61 | ||
| 62 | 68 | TargetInfo *elf::getPPCTargetInfo() { |
| 63 | 69 | static PPC Target; |
| 64 | 70 | return &Target; |
deps/lld/ELF/Arch/PPC64.cpp+8-8| ... | ... | @@ -7,10 +7,10 @@ |
| 7 | 7 | // |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | #include "Error.h" | |
| 11 | 10 | #include "Symbols.h" |
| 12 | 11 | #include "SyntheticSections.h" |
| 13 | 12 | #include "Target.h" |
| 13 | #include "lld/Common/ErrorHandler.h" | |
| 14 | 14 | #include "llvm/Support/Endian.h" |
| 15 | 15 | |
| 16 | 16 | using namespace llvm; |
| ... | ... | @@ -39,11 +39,11 @@ namespace { |
| 39 | 39 | class PPC64 final : public TargetInfo { |
| 40 | 40 | public: |
| 41 | 41 | PPC64(); |
| 42 | RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 42 | RelExpr getRelExpr(RelType Type, const Symbol &S, | |
| 43 | 43 | const uint8_t *Loc) const override; |
| 44 | 44 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, |
| 45 | 45 | int32_t Index, unsigned RelOff) const override; |
| 46 | void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 46 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 47 | 47 | }; |
| 48 | 48 | } // namespace |
| 49 | 49 | |
| ... | ... | @@ -82,11 +82,9 @@ PPC64::PPC64() { |
| 82 | 82 | DefaultImageBase = 0x10000000; |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | RelExpr PPC64::getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 85 | RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S, | |
| 86 | 86 | const uint8_t *Loc) const { |
| 87 | 87 | switch (Type) { |
| 88 | default: | |
| 89 | return R_ABS; | |
| 90 | 88 | case R_PPC64_TOC16: |
| 91 | 89 | case R_PPC64_TOC16_DS: |
| 92 | 90 | case R_PPC64_TOC16_HA: |
| ... | ... | @@ -98,6 +96,8 @@ RelExpr PPC64::getRelExpr(uint32_t Type, const SymbolBody &S, |
| 98 | 96 | return R_PPC_TOC; |
| 99 | 97 | case R_PPC64_REL24: |
| 100 | 98 | return R_PPC_PLT_OPD; |
| 99 | default: | |
| 100 | return R_ABS; | |
| 101 | 101 | } |
| 102 | 102 | } |
| 103 | 103 | |
| ... | ... | @@ -122,7 +122,7 @@ void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 122 | 122 | write32be(Buf + 28, 0x4e800420); // bctr |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | static std::pair<uint32_t, uint64_t> toAddr16Rel(uint32_t Type, uint64_t Val) { | |
| 125 | static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) { | |
| 126 | 126 | uint64_t V = Val - PPC64TocOffset; |
| 127 | 127 | switch (Type) { |
| 128 | 128 | case R_PPC64_TOC16: |
| ... | ... | @@ -142,7 +142,7 @@ static std::pair<uint32_t, uint64_t> toAddr16Rel(uint32_t Type, uint64_t Val) { |
| 142 | 142 | } |
| 143 | 143 | } |
| 144 | 144 | |
| 145 | void PPC64::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 145 | void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 146 | 146 | // For a TOC-relative relocation, proceed in terms of the corresponding |
| 147 | 147 | // ADDR16 relocation type. |
| 148 | 148 | std::tie(Type, Val) = toAddr16Rel(Type, Val); |
deps/lld/ELF/Arch/SPARCV9.cpp+6-7| ... | ... | @@ -7,11 +7,11 @@ |
| 7 | 7 | // |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | #include "Error.h" | |
| 11 | 10 | #include "InputFiles.h" |
| 12 | 11 | #include "Symbols.h" |
| 13 | 12 | #include "SyntheticSections.h" |
| 14 | 13 | #include "Target.h" |
| 14 | #include "lld/Common/ErrorHandler.h" | |
| 15 | 15 | #include "llvm/Support/Endian.h" |
| 16 | 16 | |
| 17 | 17 | using namespace llvm; |
| ... | ... | @@ -24,11 +24,11 @@ namespace { |
| 24 | 24 | class SPARCV9 final : public TargetInfo { |
| 25 | 25 | public: |
| 26 | 26 | SPARCV9(); |
| 27 | RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 27 | RelExpr getRelExpr(RelType Type, const Symbol &S, | |
| 28 | 28 | const uint8_t *Loc) const override; |
| 29 | 29 | void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr, |
| 30 | 30 | int32_t Index, unsigned RelOff) const override; |
| 31 | void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 31 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 32 | 32 | }; |
| 33 | 33 | } // namespace |
| 34 | 34 | |
| ... | ... | @@ -46,7 +46,7 @@ SPARCV9::SPARCV9() { |
| 46 | 46 | DefaultImageBase = 0x100000; |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | RelExpr SPARCV9::getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 49 | RelExpr SPARCV9::getRelExpr(RelType Type, const Symbol &S, | |
| 50 | 50 | const uint8_t *Loc) const { |
| 51 | 51 | switch (Type) { |
| 52 | 52 | case R_SPARC_32: |
| ... | ... | @@ -68,12 +68,11 @@ RelExpr SPARCV9::getRelExpr(uint32_t Type, const SymbolBody &S, |
| 68 | 68 | case R_SPARC_NONE: |
| 69 | 69 | return R_NONE; |
| 70 | 70 | default: |
| 71 | error(toString(S.File) + ": unknown relocation type: " + toString(Type)); | |
| 72 | return R_HINT; | |
| 71 | return R_INVALID; | |
| 73 | 72 | } |
| 74 | 73 | } |
| 75 | 74 | |
| 76 | void SPARCV9::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 75 | void SPARCV9::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 77 | 76 | switch (Type) { |
| 78 | 77 | case R_SPARC_32: |
| 79 | 78 | case R_SPARC_UA32: |
deps/lld/ELF/Arch/X86.cpp+239-60| ... | ... | @@ -7,11 +7,11 @@ |
| 7 | 7 | // |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | #include "Error.h" | |
| 11 | 10 | #include "InputFiles.h" |
| 12 | 11 | #include "Symbols.h" |
| 13 | 12 | #include "SyntheticSections.h" |
| 14 | 13 | #include "Target.h" |
| 14 | #include "lld/Common/ErrorHandler.h" | |
| 15 | 15 | #include "llvm/Support/Endian.h" |
| 16 | 16 | |
| 17 | 17 | using namespace llvm; |
| ... | ... | @@ -21,27 +21,27 @@ using namespace lld; |
| 21 | 21 | using namespace lld::elf; |
| 22 | 22 | |
| 23 | 23 | namespace { |
| 24 | class X86 final : public TargetInfo { | |
| 24 | class X86 : public TargetInfo { | |
| 25 | 25 | public: |
| 26 | 26 | X86(); |
| 27 | RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 27 | RelExpr getRelExpr(RelType Type, const Symbol &S, | |
| 28 | 28 | const uint8_t *Loc) const override; |
| 29 | int64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const override; | |
| 29 | int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override; | |
| 30 | 30 | void writeGotPltHeader(uint8_t *Buf) const override; |
| 31 | uint32_t getDynRel(uint32_t Type) const override; | |
| 32 | void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override; | |
| 33 | void writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const override; | |
| 31 | RelType getDynRel(RelType Type) const override; | |
| 32 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | |
| 33 | void writeIgotPlt(uint8_t *Buf, const Symbol &S) const override; | |
| 34 | 34 | void writePltHeader(uint8_t *Buf) const override; |
| 35 | 35 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, |
| 36 | 36 | int32_t Index, unsigned RelOff) const override; |
| 37 | void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 37 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 38 | 38 | |
| 39 | RelExpr adjustRelaxExpr(uint32_t Type, const uint8_t *Data, | |
| 39 | RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data, | |
| 40 | 40 | RelExpr Expr) const override; |
| 41 | void relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 42 | void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 43 | void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 44 | void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 41 | void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 42 | void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 43 | void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 44 | void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 45 | 45 | }; |
| 46 | 46 | } // namespace |
| 47 | 47 | |
| ... | ... | @@ -63,7 +63,9 @@ X86::X86() { |
| 63 | 63 | TrapInstr = 0xcccccccc; // 0xcc = INT3 |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | RelExpr X86::getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 66 | static bool hasBaseReg(uint8_t ModRM) { return (ModRM & 0xc7) != 0x5; } | |
| 67 | ||
| 68 | RelExpr X86::getRelExpr(RelType Type, const Symbol &S, | |
| 67 | 69 | const uint8_t *Loc) const { |
| 68 | 70 | switch (Type) { |
| 69 | 71 | case R_386_8: |
| ... | ... | @@ -87,24 +89,42 @@ RelExpr X86::getRelExpr(uint32_t Type, const SymbolBody &S, |
| 87 | 89 | return R_GOT; |
| 88 | 90 | case R_386_GOT32: |
| 89 | 91 | case R_386_GOT32X: |
| 90 | // These relocations can be calculated in two different ways. | |
| 91 | // Usual calculation is G + A - GOT what means an offset in GOT table | |
| 92 | // (R_GOT_FROM_END). When instruction pointed by relocation has no base | |
| 93 | // register, then relocations can be used when PIC code is disabled. In that | |
| 94 | // case calculation is G + A, it resolves to an address of entry in GOT | |
| 95 | // (R_GOT) and not an offset. | |
| 92 | // These relocations are arguably mis-designed because their calculations | |
| 93 | // depend on the instructions they are applied to. This is bad because we | |
| 94 | // usually don't care about whether the target section contains valid | |
| 95 | // machine instructions or not. But this is part of the documented ABI, so | |
| 96 | // we had to implement as the standard requires. | |
| 96 | 97 | // |
| 97 | // To check that instruction has no base register we scan ModR/M byte. | |
| 98 | // See "Table 2-2. 32-Bit Addressing Forms with the ModR/M Byte" | |
| 99 | // (http://www.intel.com/content/dam/www/public/us/en/documents/manuals/ | |
| 100 | // 64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf) | |
| 101 | if ((Loc[-1] & 0xc7) != 0x5) | |
| 102 | return R_GOT_FROM_END; | |
| 103 | if (Config->Pic) | |
| 104 | error(toString(S.File) + ": relocation " + toString(Type) + " against '" + | |
| 105 | S.getName() + | |
| 106 | "' without base register can not be used when PIC enabled"); | |
| 107 | return R_GOT; | |
| 98 | // x86 does not support PC-relative data access. Therefore, in order to | |
| 99 | // access GOT contents, a GOT address needs to be known at link-time | |
| 100 | // (which means non-PIC) or compilers have to emit code to get a GOT | |
| 101 | // address at runtime (which means code is position-independent but | |
| 102 | // compilers need to emit extra code for each GOT access.) This decision | |
| 103 | // is made at compile-time. In the latter case, compilers emit code to | |
| 104 | // load an GOT address to a register, which is usually %ebx. | |
| 105 | // | |
| 106 | // So, there are two ways to refer to symbol foo's GOT entry: foo@GOT or | |
| 107 | // foo@GOT(%reg). | |
| 108 | // | |
| 109 | // foo@GOT is not usable in PIC. If we are creating a PIC output and if we | |
| 110 | // find such relocation, we should report an error. foo@GOT is resolved to | |
| 111 | // an *absolute* address of foo's GOT entry, because both GOT address and | |
| 112 | // foo's offset are known. In other words, it's G + A. | |
| 113 | // | |
| 114 | // foo@GOT(%reg) needs to be resolved to a *relative* offset from a GOT to | |
| 115 | // foo's GOT entry in the table, because GOT address is not known but foo's | |
| 116 | // offset in the table is known. It's G + A - GOT. | |
| 117 | // | |
| 118 | // It's unfortunate that compilers emit the same relocation for these | |
| 119 | // different use cases. In order to distinguish them, we have to read a | |
| 120 | // machine instruction. | |
| 121 | // | |
| 122 | // The following code implements it. We assume that Loc[0] is the first | |
| 123 | // byte of a displacement or an immediate field of a valid machine | |
| 124 | // instruction. That means a ModRM byte is at Loc[-1]. By taking a look at | |
| 125 | // the byte, we can determine whether the instruction is register-relative | |
| 126 | // (i.e. it was generated for foo@GOT(%reg)) or absolute (i.e. foo@GOT). | |
| 127 | return hasBaseReg(Loc[-1]) ? R_GOT_FROM_END : R_GOT; | |
| 108 | 128 | case R_386_TLS_GOTIE: |
| 109 | 129 | return R_GOT_FROM_END; |
| 110 | 130 | case R_386_GOTOFF: |
| ... | ... | @@ -116,12 +136,11 @@ RelExpr X86::getRelExpr(uint32_t Type, const SymbolBody &S, |
| 116 | 136 | case R_386_NONE: |
| 117 | 137 | return R_NONE; |
| 118 | 138 | default: |
| 119 | error(toString(S.File) + ": unknown relocation type: " + toString(Type)); | |
| 120 | return R_HINT; | |
| 139 | return R_INVALID; | |
| 121 | 140 | } |
| 122 | 141 | } |
| 123 | 142 | |
| 124 | RelExpr X86::adjustRelaxExpr(uint32_t Type, const uint8_t *Data, | |
| 143 | RelExpr X86::adjustRelaxExpr(RelType Type, const uint8_t *Data, | |
| 125 | 144 | RelExpr Expr) const { |
| 126 | 145 | switch (Expr) { |
| 127 | 146 | default: |
| ... | ... | @@ -137,18 +156,18 @@ void X86::writeGotPltHeader(uint8_t *Buf) const { |
| 137 | 156 | write32le(Buf, InX::Dynamic->getVA()); |
| 138 | 157 | } |
| 139 | 158 | |
| 140 | void X86::writeGotPlt(uint8_t *Buf, const SymbolBody &S) const { | |
| 159 | void X86::writeGotPlt(uint8_t *Buf, const Symbol &S) const { | |
| 141 | 160 | // Entries in .got.plt initially points back to the corresponding |
| 142 | 161 | // PLT entries with a fixed offset to skip the first instruction. |
| 143 | 162 | write32le(Buf, S.getPltVA() + 6); |
| 144 | 163 | } |
| 145 | 164 | |
| 146 | void X86::writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const { | |
| 165 | void X86::writeIgotPlt(uint8_t *Buf, const Symbol &S) const { | |
| 147 | 166 | // An x86 entry is the address of the ifunc resolver function. |
| 148 | 167 | write32le(Buf, S.getVA()); |
| 149 | 168 | } |
| 150 | 169 | |
| 151 | uint32_t X86::getDynRel(uint32_t Type) const { | |
| 170 | RelType X86::getDynRel(RelType Type) const { | |
| 152 | 171 | if (Type == R_386_TLS_LE) |
| 153 | 172 | return R_386_TLS_TPOFF; |
| 154 | 173 | if (Type == R_386_TLS_LE_32) |
| ... | ... | @@ -173,9 +192,9 @@ void X86::writePltHeader(uint8_t *Buf) const { |
| 173 | 192 | } |
| 174 | 193 | |
| 175 | 194 | const uint8_t PltData[] = { |
| 176 | 0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushl (GOTPLT+4) | |
| 177 | 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *(GOTPLT+8) | |
| 178 | 0x90, 0x90, 0x90, 0x90 // nop | |
| 195 | 0xff, 0x35, 0, 0, 0, 0, // pushl (GOTPLT+4) | |
| 196 | 0xff, 0x25, 0, 0, 0, 0, // jmp *(GOTPLT+8) | |
| 197 | 0x90, 0x90, 0x90, 0x90, // nop | |
| 179 | 198 | }; |
| 180 | 199 | memcpy(Buf, PltData, sizeof(PltData)); |
| 181 | 200 | uint32_t GotPlt = InX::GotPlt->getVA(); |
| ... | ... | @@ -187,9 +206,9 @@ void X86::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 187 | 206 | uint64_t PltEntryAddr, int32_t Index, |
| 188 | 207 | unsigned RelOff) const { |
| 189 | 208 | const uint8_t Inst[] = { |
| 190 | 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, // jmp *foo_in_GOT|*foo@GOT(%ebx) | |
| 191 | 0x68, 0x00, 0x00, 0x00, 0x00, // pushl $reloc_offset | |
| 192 | 0xe9, 0x00, 0x00, 0x00, 0x00 // jmp .PLT0@PC | |
| 209 | 0xff, 0x00, 0, 0, 0, 0, // jmp *foo_in_GOT or jmp *foo@GOT(%ebx) | |
| 210 | 0x68, 0, 0, 0, 0, // pushl $reloc_offset | |
| 211 | 0xe9, 0, 0, 0, 0, // jmp .PLT0@PC | |
| 193 | 212 | }; |
| 194 | 213 | memcpy(Buf, Inst, sizeof(Inst)); |
| 195 | 214 | |
| ... | ... | @@ -208,10 +227,8 @@ void X86::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 208 | 227 | write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16); |
| 209 | 228 | } |
| 210 | 229 | |
| 211 | int64_t X86::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const { | |
| 230 | int64_t X86::getImplicitAddend(const uint8_t *Buf, RelType Type) const { | |
| 212 | 231 | switch (Type) { |
| 213 | default: | |
| 214 | return 0; | |
| 215 | 232 | case R_386_8: |
| 216 | 233 | case R_386_PC8: |
| 217 | 234 | return SignExtend64<8>(*Buf); |
| ... | ... | @@ -228,15 +245,17 @@ int64_t X86::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const { |
| 228 | 245 | case R_386_TLS_LDO_32: |
| 229 | 246 | case R_386_TLS_LE: |
| 230 | 247 | return SignExtend64<32>(read32le(Buf)); |
| 248 | default: | |
| 249 | return 0; | |
| 231 | 250 | } |
| 232 | 251 | } |
| 233 | 252 | |
| 234 | void X86::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 235 | // R_386_{PC,}{8,16} are not part of the i386 psABI, but they are | |
| 236 | // being used for some 16-bit programs such as boot loaders, so | |
| 237 | // we want to support them. | |
| 253 | void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 238 | 254 | switch (Type) { |
| 239 | 255 | case R_386_8: |
| 256 | // 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 | |
| 258 | // we want to support them. | |
| 240 | 259 | checkUInt<8>(Loc, Val, Type); |
| 241 | 260 | *Loc = Val; |
| 242 | 261 | break; |
| ... | ... | @@ -262,13 +281,35 @@ void X86::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 262 | 281 | checkInt<17>(Loc, Val, Type); |
| 263 | 282 | write16le(Loc, Val); |
| 264 | 283 | break; |
| 265 | default: | |
| 284 | case R_386_32: | |
| 285 | case R_386_GLOB_DAT: | |
| 286 | case R_386_GOT32: | |
| 287 | case R_386_GOT32X: | |
| 288 | case R_386_GOTOFF: | |
| 289 | case R_386_GOTPC: | |
| 290 | case R_386_PC32: | |
| 291 | case R_386_PLT32: | |
| 292 | case R_386_RELATIVE: | |
| 293 | case R_386_TLS_DTPMOD32: | |
| 294 | case R_386_TLS_DTPOFF32: | |
| 295 | case R_386_TLS_GD: | |
| 296 | case R_386_TLS_GOTIE: | |
| 297 | case R_386_TLS_IE: | |
| 298 | case R_386_TLS_LDM: | |
| 299 | case R_386_TLS_LDO_32: | |
| 300 | case R_386_TLS_LE: | |
| 301 | case R_386_TLS_LE_32: | |
| 302 | case R_386_TLS_TPOFF: | |
| 303 | case R_386_TLS_TPOFF32: | |
| 266 | 304 | checkInt<32>(Loc, Val, Type); |
| 267 | 305 | write32le(Loc, Val); |
| 306 | break; | |
| 307 | default: | |
| 308 | error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); | |
| 268 | 309 | } |
| 269 | 310 | } |
| 270 | 311 | |
| 271 | void X86::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 312 | void X86::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 272 | 313 | // Convert |
| 273 | 314 | // leal x@tlsgd(, %ebx, 1), |
| 274 | 315 | // call __tls_get_addr@plt |
| ... | ... | @@ -277,13 +318,13 @@ void X86::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 277 | 318 | // subl $x@ntpoff,%eax |
| 278 | 319 | const uint8_t Inst[] = { |
| 279 | 320 | 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0, %eax |
| 280 | 0x81, 0xe8, 0x00, 0x00, 0x00, 0x00 // subl 0(%ebx), %eax | |
| 321 | 0x81, 0xe8, 0, 0, 0, 0, // subl Val(%ebx), %eax | |
| 281 | 322 | }; |
| 282 | 323 | memcpy(Loc - 3, Inst, sizeof(Inst)); |
| 283 | 324 | write32le(Loc + 5, Val); |
| 284 | 325 | } |
| 285 | 326 | |
| 286 | void X86::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 327 | void X86::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 287 | 328 | // Convert |
| 288 | 329 | // leal x@tlsgd(, %ebx, 1), |
| 289 | 330 | // call __tls_get_addr@plt |
| ... | ... | @@ -292,7 +333,7 @@ void X86::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 292 | 333 | // addl x@gotntpoff(%ebx), %eax |
| 293 | 334 | const uint8_t Inst[] = { |
| 294 | 335 | 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0, %eax |
| 295 | 0x03, 0x83, 0x00, 0x00, 0x00, 0x00 // addl 0(%ebx), %eax | |
| 336 | 0x03, 0x83, 0, 0, 0, 0, // addl Val(%ebx), %eax | |
| 296 | 337 | }; |
| 297 | 338 | memcpy(Loc - 3, Inst, sizeof(Inst)); |
| 298 | 339 | write32le(Loc + 5, Val); |
| ... | ... | @@ -300,7 +341,7 @@ void X86::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 300 | 341 | |
| 301 | 342 | // In some conditions, relocations can be optimized to avoid using GOT. |
| 302 | 343 | // This function does that for Initial Exec to Local Exec case. |
| 303 | void X86::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 344 | void X86::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 304 | 345 | // Ulrich's document section 6.2 says that @gotntpoff can |
| 305 | 346 | // be used with MOVL or ADDL instructions. |
| 306 | 347 | // @indntpoff is similar to @gotntpoff, but for use in |
| ... | ... | @@ -337,7 +378,7 @@ void X86::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 337 | 378 | write32le(Loc, Val); |
| 338 | 379 | } |
| 339 | 380 | |
| 340 | void X86::relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { | |
| 381 | void X86::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 341 | 382 | if (Type == R_386_TLS_LDO_32) { |
| 342 | 383 | write32le(Loc, Val); |
| 343 | 384 | return; |
| ... | ... | @@ -353,12 +394,150 @@ void X86::relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { |
| 353 | 394 | const uint8_t Inst[] = { |
| 354 | 395 | 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0,%eax |
| 355 | 396 | 0x90, // nop |
| 356 | 0x8d, 0x74, 0x26, 0x00 // leal 0(%esi,1),%esi | |
| 397 | 0x8d, 0x74, 0x26, 0x00, // leal 0(%esi,1),%esi | |
| 357 | 398 | }; |
| 358 | 399 | memcpy(Loc - 2, Inst, sizeof(Inst)); |
| 359 | 400 | } |
| 360 | 401 | |
| 402 | namespace { | |
| 403 | class RetpolinePic : public X86 { | |
| 404 | public: | |
| 405 | RetpolinePic(); | |
| 406 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | |
| 407 | void writePltHeader(uint8_t *Buf) const override; | |
| 408 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, | |
| 409 | int32_t Index, unsigned RelOff) const override; | |
| 410 | }; | |
| 411 | ||
| 412 | class RetpolineNoPic : public X86 { | |
| 413 | public: | |
| 414 | RetpolineNoPic(); | |
| 415 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | |
| 416 | void writePltHeader(uint8_t *Buf) const override; | |
| 417 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, | |
| 418 | int32_t Index, unsigned RelOff) const override; | |
| 419 | }; | |
| 420 | } // namespace | |
| 421 | ||
| 422 | RetpolinePic::RetpolinePic() { | |
| 423 | PltHeaderSize = 48; | |
| 424 | PltEntrySize = 32; | |
| 425 | } | |
| 426 | ||
| 427 | void RetpolinePic::writeGotPlt(uint8_t *Buf, const Symbol &S) const { | |
| 428 | write32le(Buf, S.getPltVA() + 17); | |
| 429 | } | |
| 430 | ||
| 431 | void RetpolinePic::writePltHeader(uint8_t *Buf) const { | |
| 432 | const uint8_t Insn[] = { | |
| 433 | 0xff, 0xb3, 0, 0, 0, 0, // 0: pushl GOTPLT+4(%ebx) | |
| 434 | 0x50, // 6: pushl %eax | |
| 435 | 0x8b, 0x83, 0, 0, 0, 0, // 7: mov GOTPLT+8(%ebx), %eax | |
| 436 | 0xe8, 0x0e, 0x00, 0x00, 0x00, // d: call next | |
| 437 | 0xf3, 0x90, // 12: loop: pause | |
| 438 | 0x0f, 0xae, 0xe8, // 14: lfence | |
| 439 | 0xeb, 0xf9, // 17: jmp loop | |
| 440 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 19: int3; .align 16 | |
| 441 | 0x89, 0x0c, 0x24, // 20: next: mov %ecx, (%esp) | |
| 442 | 0x8b, 0x4c, 0x24, 0x04, // 23: mov 0x4(%esp), %ecx | |
| 443 | 0x89, 0x44, 0x24, 0x04, // 27: mov %eax ,0x4(%esp) | |
| 444 | 0x89, 0xc8, // 2b: mov %ecx, %eax | |
| 445 | 0x59, // 2d: pop %ecx | |
| 446 | 0xc3, // 2e: ret | |
| 447 | }; | |
| 448 | memcpy(Buf, Insn, sizeof(Insn)); | |
| 449 | ||
| 450 | uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize(); | |
| 451 | uint32_t GotPlt = InX::GotPlt->getVA() - Ebx; | |
| 452 | write32le(Buf + 2, GotPlt + 4); | |
| 453 | write32le(Buf + 9, GotPlt + 8); | |
| 454 | } | |
| 455 | ||
| 456 | void RetpolinePic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | |
| 457 | uint64_t PltEntryAddr, int32_t Index, | |
| 458 | unsigned RelOff) const { | |
| 459 | const uint8_t Insn[] = { | |
| 460 | 0x50, // pushl %eax | |
| 461 | 0x8b, 0x83, 0, 0, 0, 0, // mov foo@GOT(%ebx), %eax | |
| 462 | 0xe8, 0, 0, 0, 0, // call plt+0x20 | |
| 463 | 0xe9, 0, 0, 0, 0, // jmp plt+0x12 | |
| 464 | 0x68, 0, 0, 0, 0, // pushl $reloc_offset | |
| 465 | 0xe9, 0, 0, 0, 0, // jmp plt+0 | |
| 466 | }; | |
| 467 | memcpy(Buf, Insn, sizeof(Insn)); | |
| 468 | ||
| 469 | uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize(); | |
| 470 | write32le(Buf + 3, GotPltEntryAddr - Ebx); | |
| 471 | write32le(Buf + 8, -Index * PltEntrySize - PltHeaderSize - 12 + 32); | |
| 472 | write32le(Buf + 13, -Index * PltEntrySize - PltHeaderSize - 17 + 18); | |
| 473 | write32le(Buf + 18, RelOff); | |
| 474 | write32le(Buf + 23, -Index * PltEntrySize - PltHeaderSize - 27); | |
| 475 | } | |
| 476 | ||
| 477 | RetpolineNoPic::RetpolineNoPic() { | |
| 478 | PltHeaderSize = 48; | |
| 479 | PltEntrySize = 32; | |
| 480 | } | |
| 481 | ||
| 482 | void RetpolineNoPic::writeGotPlt(uint8_t *Buf, const Symbol &S) const { | |
| 483 | write32le(Buf, S.getPltVA() + 16); | |
| 484 | } | |
| 485 | ||
| 486 | void RetpolineNoPic::writePltHeader(uint8_t *Buf) const { | |
| 487 | const uint8_t PltData[] = { | |
| 488 | 0xff, 0x35, 0, 0, 0, 0, // 0: pushl GOTPLT+4 | |
| 489 | 0x50, // 6: pushl %eax | |
| 490 | 0xa1, 0, 0, 0, 0, // 7: mov GOTPLT+8, %eax | |
| 491 | 0xe8, 0x0f, 0x00, 0x00, 0x00, // c: call next | |
| 492 | 0xf3, 0x90, // 11: loop: pause | |
| 493 | 0x0f, 0xae, 0xe8, // 13: lfence | |
| 494 | 0xeb, 0xf9, // 16: jmp loop | |
| 495 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 18: int3 | |
| 496 | 0xcc, 0xcc, 0xcc, // 1f: int3; .align 16 | |
| 497 | 0x89, 0x0c, 0x24, // 20: next: mov %ecx, (%esp) | |
| 498 | 0x8b, 0x4c, 0x24, 0x04, // 23: mov 0x4(%esp), %ecx | |
| 499 | 0x89, 0x44, 0x24, 0x04, // 27: mov %eax ,0x4(%esp) | |
| 500 | 0x89, 0xc8, // 2b: mov %ecx, %eax | |
| 501 | 0x59, // 2d: pop %ecx | |
| 502 | 0xc3, // 2e: ret | |
| 503 | }; | |
| 504 | memcpy(Buf, PltData, sizeof(PltData)); | |
| 505 | ||
| 506 | uint32_t GotPlt = InX::GotPlt->getVA(); | |
| 507 | write32le(Buf + 2, GotPlt + 4); | |
| 508 | write32le(Buf + 8, GotPlt + 8); | |
| 509 | } | |
| 510 | ||
| 511 | void RetpolineNoPic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | |
| 512 | uint64_t PltEntryAddr, int32_t Index, | |
| 513 | unsigned RelOff) const { | |
| 514 | const uint8_t Insn[] = { | |
| 515 | 0x50, // 0: pushl %eax | |
| 516 | 0xa1, 0, 0, 0, 0, // 1: mov foo_in_GOT, %eax | |
| 517 | 0xe8, 0, 0, 0, 0, // 6: call plt+0x20 | |
| 518 | 0xe9, 0, 0, 0, 0, // b: jmp plt+0x11 | |
| 519 | 0x68, 0, 0, 0, 0, // 10: pushl $reloc_offset | |
| 520 | 0xe9, 0, 0, 0, 0, // 15: jmp plt+0 | |
| 521 | }; | |
| 522 | memcpy(Buf, Insn, sizeof(Insn)); | |
| 523 | ||
| 524 | write32le(Buf + 2, GotPltEntryAddr); | |
| 525 | write32le(Buf + 7, -Index * PltEntrySize - PltHeaderSize - 11 + 32); | |
| 526 | write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16 + 17); | |
| 527 | write32le(Buf + 17, RelOff); | |
| 528 | write32le(Buf + 22, -Index * PltEntrySize - PltHeaderSize - 26); | |
| 529 | } | |
| 530 | ||
| 361 | 531 | TargetInfo *elf::getX86TargetInfo() { |
| 362 | static X86 Target; | |
| 363 | return &Target; | |
| 532 | if (Config->ZRetpolineplt) { | |
| 533 | if (Config->Pic) { | |
| 534 | static RetpolinePic T; | |
| 535 | return &T; | |
| 536 | } | |
| 537 | static RetpolineNoPic T; | |
| 538 | return &T; | |
| 539 | } | |
| 540 | ||
| 541 | static X86 T; | |
| 542 | return &T; | |
| 364 | 543 | } |
deps/lld/ELF/Arch/X86_64.cpp+153-42| ... | ... | @@ -7,11 +7,11 @@ |
| 7 | 7 | // |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | #include "Error.h" | |
| 11 | 10 | #include "InputFiles.h" |
| 12 | 11 | #include "Symbols.h" |
| 13 | 12 | #include "SyntheticSections.h" |
| 14 | 13 | #include "Target.h" |
| 14 | #include "lld/Common/ErrorHandler.h" | |
| 15 | 15 | #include "llvm/Object/ELF.h" |
| 16 | 16 | #include "llvm/Support/Endian.h" |
| 17 | 17 | |
| ... | ... | @@ -23,26 +23,26 @@ using namespace lld; |
| 23 | 23 | using namespace lld::elf; |
| 24 | 24 | |
| 25 | 25 | namespace { |
| 26 | template <class ELFT> class X86_64 final : public TargetInfo { | |
| 26 | template <class ELFT> class X86_64 : public TargetInfo { | |
| 27 | 27 | public: |
| 28 | 28 | X86_64(); |
| 29 | RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 29 | RelExpr getRelExpr(RelType Type, const Symbol &S, | |
| 30 | 30 | const uint8_t *Loc) const override; |
| 31 | bool isPicRel(uint32_t Type) const override; | |
| 31 | bool isPicRel(RelType Type) const override; | |
| 32 | 32 | void writeGotPltHeader(uint8_t *Buf) const override; |
| 33 | void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override; | |
| 33 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | |
| 34 | 34 | void writePltHeader(uint8_t *Buf) const override; |
| 35 | 35 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, |
| 36 | 36 | int32_t Index, unsigned RelOff) const override; |
| 37 | void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 37 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 38 | 38 | |
| 39 | RelExpr adjustRelaxExpr(uint32_t Type, const uint8_t *Data, | |
| 39 | RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data, | |
| 40 | 40 | RelExpr Expr) const override; |
| 41 | 41 | void relaxGot(uint8_t *Loc, uint64_t Val) const override; |
| 42 | void relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 43 | void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 44 | void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 45 | void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; | |
| 42 | void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 43 | void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 44 | void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 45 | void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | |
| 46 | 46 | |
| 47 | 47 | private: |
| 48 | 48 | void relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op, |
| ... | ... | @@ -73,7 +73,7 @@ template <class ELFT> X86_64<ELFT>::X86_64() { |
| 73 | 73 | } |
| 74 | 74 | |
| 75 | 75 | template <class ELFT> |
| 76 | RelExpr X86_64<ELFT>::getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 76 | RelExpr X86_64<ELFT>::getRelExpr(RelType Type, const Symbol &S, | |
| 77 | 77 | const uint8_t *Loc) const { |
| 78 | 78 | switch (Type) { |
| 79 | 79 | case R_X86_64_8: |
| ... | ... | @@ -109,8 +109,7 @@ RelExpr X86_64<ELFT>::getRelExpr(uint32_t Type, const SymbolBody &S, |
| 109 | 109 | case R_X86_64_NONE: |
| 110 | 110 | return R_NONE; |
| 111 | 111 | default: |
| 112 | error(toString(S.File) + ": unknown relocation type: " + toString(Type)); | |
| 113 | return R_HINT; | |
| 112 | return R_INVALID; | |
| 114 | 113 | } |
| 115 | 114 | } |
| 116 | 115 | |
| ... | ... | @@ -123,16 +122,16 @@ template <class ELFT> void X86_64<ELFT>::writeGotPltHeader(uint8_t *Buf) const { |
| 123 | 122 | } |
| 124 | 123 | |
| 125 | 124 | template <class ELFT> |
| 126 | void X86_64<ELFT>::writeGotPlt(uint8_t *Buf, const SymbolBody &S) const { | |
| 127 | // See comments in X86TargetInfo::writeGotPlt. | |
| 125 | void X86_64<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &S) const { | |
| 126 | // See comments in X86::writeGotPlt. | |
| 128 | 127 | write32le(Buf, S.getPltVA() + 6); |
| 129 | 128 | } |
| 130 | 129 | |
| 131 | 130 | template <class ELFT> void X86_64<ELFT>::writePltHeader(uint8_t *Buf) const { |
| 132 | 131 | const uint8_t PltData[] = { |
| 133 | 0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushq GOTPLT+8(%rip) | |
| 134 | 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *GOTPLT+16(%rip) | |
| 135 | 0x0f, 0x1f, 0x40, 0x00 // nop | |
| 132 | 0xff, 0x35, 0, 0, 0, 0, // pushq GOTPLT+8(%rip) | |
| 133 | 0xff, 0x25, 0, 0, 0, 0, // jmp *GOTPLT+16(%rip) | |
| 134 | 0x0f, 0x1f, 0x40, 0x00, // nop | |
| 136 | 135 | }; |
| 137 | 136 | memcpy(Buf, PltData, sizeof(PltData)); |
| 138 | 137 | uint64_t GotPlt = InX::GotPlt->getVA(); |
| ... | ... | @@ -146,9 +145,9 @@ void X86_64<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 146 | 145 | uint64_t PltEntryAddr, int32_t Index, |
| 147 | 146 | unsigned RelOff) const { |
| 148 | 147 | const uint8_t Inst[] = { |
| 149 | 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *got(%rip) | |
| 150 | 0x68, 0x00, 0x00, 0x00, 0x00, // pushq <relocation index> | |
| 151 | 0xe9, 0x00, 0x00, 0x00, 0x00 // jmpq plt[0] | |
| 148 | 0xff, 0x25, 0, 0, 0, 0, // jmpq *got(%rip) | |
| 149 | 0x68, 0, 0, 0, 0, // pushq <relocation index> | |
| 150 | 0xe9, 0, 0, 0, 0, // jmpq plt[0] | |
| 152 | 151 | }; |
| 153 | 152 | memcpy(Buf, Inst, sizeof(Inst)); |
| 154 | 153 | |
| ... | ... | @@ -157,13 +156,13 @@ void X86_64<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 157 | 156 | write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16); |
| 158 | 157 | } |
| 159 | 158 | |
| 160 | template <class ELFT> bool X86_64<ELFT>::isPicRel(uint32_t Type) const { | |
| 159 | template <class ELFT> bool X86_64<ELFT>::isPicRel(RelType Type) const { | |
| 161 | 160 | return Type != R_X86_64_PC32 && Type != R_X86_64_32 && |
| 162 | 161 | Type != R_X86_64_TPOFF32; |
| 163 | 162 | } |
| 164 | 163 | |
| 165 | 164 | template <class ELFT> |
| 166 | void X86_64<ELFT>::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, | |
| 165 | void X86_64<ELFT>::relaxTlsGdToLe(uint8_t *Loc, RelType Type, | |
| 167 | 166 | uint64_t Val) const { |
| 168 | 167 | // Convert |
| 169 | 168 | // .byte 0x66 |
| ... | ... | @@ -176,7 +175,7 @@ void X86_64<ELFT>::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, |
| 176 | 175 | // lea x@tpoff,%rax |
| 177 | 176 | const uint8_t Inst[] = { |
| 178 | 177 | 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0x0,%rax |
| 179 | 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00 // lea x@tpoff,%rax | |
| 178 | 0x48, 0x8d, 0x80, 0, 0, 0, 0, // lea x@tpoff,%rax | |
| 180 | 179 | }; |
| 181 | 180 | memcpy(Loc - 4, Inst, sizeof(Inst)); |
| 182 | 181 | |
| ... | ... | @@ -186,7 +185,7 @@ void X86_64<ELFT>::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, |
| 186 | 185 | } |
| 187 | 186 | |
| 188 | 187 | template <class ELFT> |
| 189 | void X86_64<ELFT>::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, | |
| 188 | void X86_64<ELFT>::relaxTlsGdToIe(uint8_t *Loc, RelType Type, | |
| 190 | 189 | uint64_t Val) const { |
| 191 | 190 | // Convert |
| 192 | 191 | // .byte 0x66 |
| ... | ... | @@ -199,7 +198,7 @@ void X86_64<ELFT>::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, |
| 199 | 198 | // addq x@tpoff,%rax |
| 200 | 199 | const uint8_t Inst[] = { |
| 201 | 200 | 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0x0,%rax |
| 202 | 0x48, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00 // addq x@tpoff,%rax | |
| 201 | 0x48, 0x03, 0x05, 0, 0, 0, 0, // addq x@tpoff,%rax | |
| 203 | 202 | }; |
| 204 | 203 | memcpy(Loc - 4, Inst, sizeof(Inst)); |
| 205 | 204 | |
| ... | ... | @@ -211,7 +210,7 @@ void X86_64<ELFT>::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, |
| 211 | 210 | // In some conditions, R_X86_64_GOTTPOFF relocation can be optimized to |
| 212 | 211 | // R_X86_64_TPOFF32 so that it does not use GOT. |
| 213 | 212 | template <class ELFT> |
| 214 | void X86_64<ELFT>::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, | |
| 213 | void X86_64<ELFT>::relaxTlsIeToLe(uint8_t *Loc, RelType Type, | |
| 215 | 214 | uint64_t Val) const { |
| 216 | 215 | uint8_t *Inst = Loc - 3; |
| 217 | 216 | uint8_t Reg = Loc[-1] >> 3; |
| ... | ... | @@ -254,7 +253,7 @@ void X86_64<ELFT>::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, |
| 254 | 253 | } |
| 255 | 254 | |
| 256 | 255 | template <class ELFT> |
| 257 | void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, | |
| 256 | void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, RelType Type, | |
| 258 | 257 | uint64_t Val) const { |
| 259 | 258 | // Convert |
| 260 | 259 | // leaq bar@tlsld(%rip), %rdi |
| ... | ... | @@ -275,16 +274,15 @@ void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, |
| 275 | 274 | } |
| 276 | 275 | |
| 277 | 276 | const uint8_t Inst[] = { |
| 278 | 0x66, 0x66, // .word 0x6666 | |
| 279 | 0x66, // .byte 0x66 | |
| 280 | 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00 // mov %fs:0,%rax | |
| 277 | 0x66, 0x66, // .word 0x6666 | |
| 278 | 0x66, // .byte 0x66 | |
| 279 | 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0,%rax | |
| 281 | 280 | }; |
| 282 | 281 | memcpy(Loc - 3, Inst, sizeof(Inst)); |
| 283 | 282 | } |
| 284 | 283 | |
| 285 | 284 | template <class ELFT> |
| 286 | void X86_64<ELFT>::relocateOne(uint8_t *Loc, uint32_t Type, | |
| 287 | uint64_t Val) const { | |
| 285 | void X86_64<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | |
| 288 | 286 | switch (Type) { |
| 289 | 287 | case R_X86_64_8: |
| 290 | 288 | checkUInt<8>(Loc, Val, Type); |
| ... | ... | @@ -323,12 +321,12 @@ void X86_64<ELFT>::relocateOne(uint8_t *Loc, uint32_t Type, |
| 323 | 321 | write64le(Loc, Val); |
| 324 | 322 | break; |
| 325 | 323 | default: |
| 326 | llvm_unreachable("unexpected relocation"); | |
| 324 | error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); | |
| 327 | 325 | } |
| 328 | 326 | } |
| 329 | 327 | |
| 330 | 328 | template <class ELFT> |
| 331 | RelExpr X86_64<ELFT>::adjustRelaxExpr(uint32_t Type, const uint8_t *Data, | |
| 329 | RelExpr X86_64<ELFT>::adjustRelaxExpr(RelType Type, const uint8_t *Data, | |
| 332 | 330 | RelExpr RelExpr) const { |
| 333 | 331 | if (Type != R_X86_64_GOTPCRELX && Type != R_X86_64_REX_GOTPCRELX) |
| 334 | 332 | return RelExpr; |
| ... | ... | @@ -462,12 +460,125 @@ void X86_64<ELFT>::relaxGot(uint8_t *Loc, uint64_t Val) const { |
| 462 | 460 | write32le(Loc - 1, Val + 1); |
| 463 | 461 | } |
| 464 | 462 | |
| 465 | TargetInfo *elf::getX32TargetInfo() { | |
| 466 | static X86_64<ELF32LE> Target; | |
| 467 | return &Target; | |
| 463 | namespace { | |
| 464 | template <class ELFT> class Retpoline : public X86_64<ELFT> { | |
| 465 | public: | |
| 466 | Retpoline(); | |
| 467 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | |
| 468 | void writePltHeader(uint8_t *Buf) const override; | |
| 469 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, | |
| 470 | int32_t Index, unsigned RelOff) const override; | |
| 471 | }; | |
| 472 | ||
| 473 | template <class ELFT> class RetpolineZNow : public X86_64<ELFT> { | |
| 474 | public: | |
| 475 | RetpolineZNow(); | |
| 476 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override {} | |
| 477 | void writePltHeader(uint8_t *Buf) const override; | |
| 478 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, | |
| 479 | int32_t Index, unsigned RelOff) const override; | |
| 480 | }; | |
| 481 | } // namespace | |
| 482 | ||
| 483 | template <class ELFT> Retpoline<ELFT>::Retpoline() { | |
| 484 | TargetInfo::PltHeaderSize = 48; | |
| 485 | TargetInfo::PltEntrySize = 32; | |
| 468 | 486 | } |
| 469 | 487 | |
| 470 | TargetInfo *elf::getX86_64TargetInfo() { | |
| 471 | static X86_64<ELF64LE> Target; | |
| 472 | return &Target; | |
| 488 | template <class ELFT> | |
| 489 | void Retpoline<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &S) const { | |
| 490 | write32le(Buf, S.getPltVA() + 17); | |
| 473 | 491 | } |
| 492 | ||
| 493 | template <class ELFT> void Retpoline<ELFT>::writePltHeader(uint8_t *Buf) const { | |
| 494 | const uint8_t Insn[] = { | |
| 495 | 0xff, 0x35, 0, 0, 0, 0, // 0: pushq GOTPLT+8(%rip) | |
| 496 | 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // 6: mov GOTPLT+16(%rip), %r11 | |
| 497 | 0xe8, 0x0e, 0x00, 0x00, 0x00, // d: callq next | |
| 498 | 0xf3, 0x90, // 12: loop: pause | |
| 499 | 0x0f, 0xae, 0xe8, // 14: lfence | |
| 500 | 0xeb, 0xf9, // 17: jmp loop | |
| 501 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 19: int3; .align 16 | |
| 502 | 0x4c, 0x89, 0x1c, 0x24, // 20: next: mov %r11, (%rsp) | |
| 503 | 0xc3, // 24: ret | |
| 504 | }; | |
| 505 | memcpy(Buf, Insn, sizeof(Insn)); | |
| 506 | ||
| 507 | uint64_t GotPlt = InX::GotPlt->getVA(); | |
| 508 | uint64_t Plt = InX::Plt->getVA(); | |
| 509 | write32le(Buf + 2, GotPlt - Plt - 6 + 8); | |
| 510 | write32le(Buf + 9, GotPlt - Plt - 13 + 16); | |
| 511 | } | |
| 512 | ||
| 513 | template <class ELFT> | |
| 514 | void Retpoline<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | |
| 515 | uint64_t PltEntryAddr, int32_t Index, | |
| 516 | unsigned RelOff) const { | |
| 517 | const uint8_t Insn[] = { | |
| 518 | 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // 0: mov foo@GOTPLT(%rip), %r11 | |
| 519 | 0xe8, 0, 0, 0, 0, // 7: callq plt+0x20 | |
| 520 | 0xe9, 0, 0, 0, 0, // c: jmp plt+0x12 | |
| 521 | 0x68, 0, 0, 0, 0, // 11: pushq <relocation index> | |
| 522 | 0xe9, 0, 0, 0, 0, // 16: jmp plt+0 | |
| 523 | }; | |
| 524 | memcpy(Buf, Insn, sizeof(Insn)); | |
| 525 | ||
| 526 | uint64_t Off = TargetInfo::PltHeaderSize + TargetInfo::PltEntrySize * Index; | |
| 527 | ||
| 528 | write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7); | |
| 529 | write32le(Buf + 8, -Off - 12 + 32); | |
| 530 | write32le(Buf + 13, -Off - 17 + 18); | |
| 531 | write32le(Buf + 18, Index); | |
| 532 | write32le(Buf + 23, -Off - 27); | |
| 533 | } | |
| 534 | ||
| 535 | template <class ELFT> RetpolineZNow<ELFT>::RetpolineZNow() { | |
| 536 | TargetInfo::PltHeaderSize = 32; | |
| 537 | TargetInfo::PltEntrySize = 16; | |
| 538 | } | |
| 539 | ||
| 540 | template <class ELFT> | |
| 541 | void RetpolineZNow<ELFT>::writePltHeader(uint8_t *Buf) const { | |
| 542 | const uint8_t Insn[] = { | |
| 543 | 0xe8, 0x0b, 0x00, 0x00, 0x00, // 0: call next | |
| 544 | 0xf3, 0x90, // 5: loop: pause | |
| 545 | 0x0f, 0xae, 0xe8, // 7: lfence | |
| 546 | 0xeb, 0xf9, // a: jmp loop | |
| 547 | 0xcc, 0xcc, 0xcc, 0xcc, // c: int3; .align 16 | |
| 548 | 0x4c, 0x89, 0x1c, 0x24, // 10: next: mov %r11, (%rsp) | |
| 549 | 0xc3, // 14: ret | |
| 550 | }; | |
| 551 | memcpy(Buf, Insn, sizeof(Insn)); | |
| 552 | } | |
| 553 | ||
| 554 | template <class ELFT> | |
| 555 | void RetpolineZNow<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | |
| 556 | uint64_t PltEntryAddr, int32_t Index, | |
| 557 | unsigned RelOff) const { | |
| 558 | const uint8_t Insn[] = { | |
| 559 | 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // mov foo@GOTPLT(%rip), %r11 | |
| 560 | 0xe9, 0, 0, 0, 0, // jmp plt+0 | |
| 561 | }; | |
| 562 | memcpy(Buf, Insn, sizeof(Insn)); | |
| 563 | ||
| 564 | write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7); | |
| 565 | write32le(Buf + 8, | |
| 566 | -Index * TargetInfo::PltEntrySize - TargetInfo::PltHeaderSize - 12); | |
| 567 | } | |
| 568 | ||
| 569 | template <class ELFT> TargetInfo *getTargetInfo() { | |
| 570 | if (Config->ZRetpolineplt) { | |
| 571 | if (Config->ZNow) { | |
| 572 | static RetpolineZNow<ELFT> T; | |
| 573 | return &T; | |
| 574 | } | |
| 575 | static Retpoline<ELFT> T; | |
| 576 | return &T; | |
| 577 | } | |
| 578 | ||
| 579 | static X86_64<ELFT> T; | |
| 580 | return &T; | |
| 581 | } | |
| 582 | ||
| 583 | TargetInfo *elf::getX32TargetInfo() { return getTargetInfo<ELF32LE>(); } | |
| 584 | TargetInfo *elf::getX86_64TargetInfo() { return getTargetInfo<ELF64LE>(); } |
deps/lld/ELF/Bits.h created+35| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | //===- Bits.h ---------------------------------------------------*- C++ -*-===// | |
| 2 | // | |
| 3 | // The LLVM Linker | |
| 4 | // | |
| 5 | // This file is distributed under the University of Illinois Open Source | |
| 6 | // License. See LICENSE.TXT for details. | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef LLD_ELF_BITS_H | |
| 11 | #define LLD_ELF_BITS_H | |
| 12 | ||
| 13 | #include "Config.h" | |
| 14 | #include "llvm/Support/Endian.h" | |
| 15 | ||
| 16 | namespace lld { | |
| 17 | namespace elf { | |
| 18 | ||
| 19 | inline uint64_t readUint(uint8_t *Buf) { | |
| 20 | if (Config->Is64) | |
| 21 | return llvm::support::endian::read64(Buf, Config->Endianness); | |
| 22 | return llvm::support::endian::read32(Buf, Config->Endianness); | |
| 23 | } | |
| 24 | ||
| 25 | inline void writeUint(uint8_t *Buf, uint64_t Val) { | |
| 26 | if (Config->Is64) | |
| 27 | llvm::support::endian::write64(Buf, Val, Config->Endianness); | |
| 28 | else | |
| 29 | llvm::support::endian::write32(Buf, Val, Config->Endianness); | |
| 30 | } | |
| 31 | ||
| 32 | } // namespace elf | |
| 33 | } // namespace lld | |
| 34 | ||
| 35 | #endif |
deps/lld/ELF/CMakeLists.txt+3-14| ... | ... | @@ -7,6 +7,7 @@ if(NOT LLD_BUILT_STANDALONE) |
| 7 | 7 | endif() |
| 8 | 8 | |
| 9 | 9 | add_lld_library(lldELF |
| 10 | AArch64ErrataFix.cpp | |
| 10 | 11 | Arch/AArch64.cpp |
| 11 | 12 | Arch/AMDGPU.cpp |
| 12 | 13 | Arch/ARM.cpp |
| ... | ... | @@ -21,7 +22,6 @@ add_lld_library(lldELF |
| 21 | 22 | Driver.cpp |
| 22 | 23 | DriverUtils.cpp |
| 23 | 24 | EhFrame.cpp |
| 24 | Error.cpp | |
| 25 | 25 | Filesystem.cpp |
| 26 | 26 | GdbIndex.cpp |
| 27 | 27 | ICF.cpp |
| ... | ... | @@ -45,28 +45,17 @@ add_lld_library(lldELF |
| 45 | 45 | |
| 46 | 46 | LINK_COMPONENTS |
| 47 | 47 | ${LLVM_TARGETS_TO_BUILD} |
| 48 | Analysis | |
| 49 | 48 | BinaryFormat |
| 50 | BitReader | |
| 51 | BitWriter | |
| 52 | Codegen | |
| 53 | 49 | Core |
| 54 | 50 | DebugInfoDWARF |
| 55 | Demangle | |
| 56 | IPO | |
| 57 | Linker | |
| 58 | 51 | LTO |
| 52 | MC | |
| 59 | 53 | Object |
| 60 | 54 | Option |
| 61 | Passes | |
| 62 | MC | |
| 63 | 55 | Support |
| 64 | Target | |
| 65 | TransformUtils | |
| 66 | 56 | |
| 67 | 57 | LINK_LIBS |
| 68 | lldConfig | |
| 69 | lldCore | |
| 58 | lldCommon | |
| 70 | 59 | ${LLVM_PTHREAD_LIB} |
| 71 | 60 | |
| 72 | 61 | DEPENDS |
deps/lld/ELF/Config.h+24-17| ... | ... | @@ -24,7 +24,6 @@ namespace lld { |
| 24 | 24 | namespace elf { |
| 25 | 25 | |
| 26 | 26 | class InputFile; |
| 27 | struct Symbol; | |
| 28 | 27 | |
| 29 | 28 | enum ELFKind { |
| 30 | 29 | ELFNoneKind, |
| ... | ... | @@ -44,7 +43,10 @@ enum class DiscardPolicy { Default, All, Locals, None }; |
| 44 | 43 | enum class StripPolicy { None, All, Debug }; |
| 45 | 44 | |
| 46 | 45 | // For --unresolved-symbols. |
| 47 | enum class UnresolvedPolicy { ReportError, Warn, WarnAll, Ignore, IgnoreAll }; | |
| 46 | enum class UnresolvedPolicy { ReportError, Warn, Ignore, IgnoreAll }; | |
| 47 | ||
| 48 | // For --orphan-handling. | |
| 49 | enum class OrphanHandlingPolicy { Place, Warn, Error }; | |
| 48 | 50 | |
| 49 | 51 | // For --sort-section and linkerscript sorting rules. |
| 50 | 52 | enum class SortSectionPolicy { Default, None, Alignment, Name, Priority }; |
| ... | ... | @@ -67,21 +69,15 @@ struct VersionDefinition { |
| 67 | 69 | size_t NameOff = 0; // Offset in the string table |
| 68 | 70 | }; |
| 69 | 71 | |
| 70 | // Structure for mapping renamed symbols | |
| 71 | struct RenamedSymbol { | |
| 72 | Symbol *Target; | |
| 73 | uint8_t OriginalBinding; | |
| 74 | }; | |
| 75 | ||
| 76 | 72 | // This struct contains the global configuration for the linker. |
| 77 | 73 | // Most fields are direct mapping from the command line options |
| 78 | 74 | // and such fields have the same name as the corresponding options. |
| 79 | 75 | // Most fields are initialized by the driver. |
| 80 | 76 | struct Configuration { |
| 81 | InputFile *FirstElf = nullptr; | |
| 82 | 77 | uint8_t OSABI = 0; |
| 83 | 78 | llvm::CachePruningPolicy ThinLTOCachePolicy; |
| 84 | 79 | llvm::StringMap<uint64_t> SectionStartMap; |
| 80 | llvm::StringRef Chroot; | |
| 85 | 81 | llvm::StringRef DynamicLinker; |
| 86 | 82 | llvm::StringRef Entry; |
| 87 | 83 | llvm::StringRef Emulation; |
| ... | ... | @@ -103,15 +99,18 @@ struct Configuration { |
| 103 | 99 | std::vector<llvm::StringRef> SearchPaths; |
| 104 | 100 | std::vector<llvm::StringRef> SymbolOrderingFile; |
| 105 | 101 | std::vector<llvm::StringRef> Undefined; |
| 102 | std::vector<SymbolVersion> DynamicList; | |
| 106 | 103 | std::vector<SymbolVersion> VersionScriptGlobals; |
| 107 | 104 | std::vector<SymbolVersion> VersionScriptLocals; |
| 108 | 105 | std::vector<uint8_t> BuildIdVector; |
| 109 | llvm::MapVector<Symbol *, RenamedSymbol> RenamedSymbols; | |
| 110 | 106 | bool AllowMultipleDefinition; |
| 107 | bool AndroidPackDynRelocs = false; | |
| 108 | bool ARMHasBlx = false; | |
| 109 | bool ARMHasMovtMovw = false; | |
| 110 | bool ARMJ1J2BranchEncoding = false; | |
| 111 | 111 | bool AsNeeded = false; |
| 112 | 112 | bool Bsymbolic; |
| 113 | 113 | bool BsymbolicFunctions; |
| 114 | bool ColorDiagnostics = false; | |
| 115 | 114 | bool CompressDebugSections; |
| 116 | 115 | bool DefineCommon; |
| 117 | 116 | bool Demangle = true; |
| ... | ... | @@ -120,14 +119,19 @@ struct Configuration { |
| 120 | 119 | bool EmitRelocs; |
| 121 | 120 | bool EnableNewDtags; |
| 122 | 121 | bool ExportDynamic; |
| 123 | bool FatalWarnings; | |
| 122 | bool FixCortexA53Errata843419; | |
| 124 | 123 | bool GcSections; |
| 125 | 124 | bool GdbIndex; |
| 126 | bool GnuHash; | |
| 125 | bool GnuHash = false; | |
| 126 | bool HasDynamicList = false; | |
| 127 | bool HasDynSymTab; | |
| 127 | 128 | bool ICF; |
| 129 | bool ICFData; | |
| 130 | bool MergeArmExidx; | |
| 128 | 131 | bool MipsN32Abi = false; |
| 129 | 132 | bool NoGnuUnique; |
| 130 | 133 | bool NoUndefinedVersion; |
| 134 | bool NoinhibitExec; | |
| 131 | 135 | bool Nostdlib; |
| 132 | 136 | bool OFormatBinary; |
| 133 | 137 | bool Omagic; |
| ... | ... | @@ -139,9 +143,8 @@ struct Configuration { |
| 139 | 143 | bool SingleRoRx; |
| 140 | 144 | bool Shared; |
| 141 | 145 | bool Static = false; |
| 142 | bool SysvHash; | |
| 146 | bool SysvHash = false; | |
| 143 | 147 | bool Target1Rel; |
| 144 | bool Threads; | |
| 145 | 148 | bool Trace; |
| 146 | 149 | bool Verbose; |
| 147 | 150 | bool WarnCommon; |
| ... | ... | @@ -156,9 +159,11 @@ struct Configuration { |
| 156 | 159 | bool ZRelro; |
| 157 | 160 | bool ZRodynamic; |
| 158 | 161 | bool ZText; |
| 162 | bool ZRetpolineplt; | |
| 159 | 163 | bool ExitEarly; |
| 160 | 164 | bool ZWxneeded; |
| 161 | 165 | DiscardPolicy Discard; |
| 166 | OrphanHandlingPolicy OrphanHandling; | |
| 162 | 167 | SortSectionPolicy SortSection; |
| 163 | 168 | StripPolicy Strip; |
| 164 | 169 | UnresolvedPolicy UnresolvedSymbols; |
| ... | ... | @@ -167,8 +172,7 @@ struct Configuration { |
| 167 | 172 | ELFKind EKind = ELFNoneKind; |
| 168 | 173 | uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL; |
| 169 | 174 | uint16_t EMachine = llvm::ELF::EM_NONE; |
| 170 | uint64_t ErrorLimit = 20; | |
| 171 | uint64_t ImageBase; | |
| 175 | llvm::Optional<uint64_t> ImageBase; | |
| 172 | 176 | uint64_t MaxPageSize; |
| 173 | 177 | uint64_t ZStackSize; |
| 174 | 178 | unsigned LTOPartitions; |
| ... | ... | @@ -206,6 +210,9 @@ struct Configuration { |
| 206 | 210 | // if that's true.) |
| 207 | 211 | bool IsMips64EL; |
| 208 | 212 | |
| 213 | // Holds set of ELF header flags for the target. | |
| 214 | uint32_t EFlags = 0; | |
| 215 | ||
| 209 | 216 | // The ELF spec defines two types of relocation table entries, RELA and |
| 210 | 217 | // REL. RELA is a triplet of (offset, info, addend) while REL is a |
| 211 | 218 | // tuple of (offset, info). Addends for REL are implicit and read from |
deps/lld/ELF/Driver.cpp+283-211| ... | ... | @@ -25,23 +25,25 @@ |
| 25 | 25 | |
| 26 | 26 | #include "Driver.h" |
| 27 | 27 | #include "Config.h" |
| 28 | #include "Error.h" | |
| 29 | 28 | #include "Filesystem.h" |
| 30 | 29 | #include "ICF.h" |
| 31 | 30 | #include "InputFiles.h" |
| 32 | 31 | #include "InputSection.h" |
| 33 | 32 | #include "LinkerScript.h" |
| 34 | #include "Memory.h" | |
| 35 | 33 | #include "OutputSections.h" |
| 36 | 34 | #include "ScriptParser.h" |
| 37 | 35 | #include "Strings.h" |
| 38 | 36 | #include "SymbolTable.h" |
| 37 | #include "Symbols.h" | |
| 39 | 38 | #include "SyntheticSections.h" |
| 40 | 39 | #include "Target.h" |
| 41 | #include "Threads.h" | |
| 42 | 40 | #include "Writer.h" |
| 43 | #include "lld/Config/Version.h" | |
| 44 | #include "lld/Driver/Driver.h" | |
| 41 | #include "lld/Common/Args.h" | |
| 42 | #include "lld/Common/Driver.h" | |
| 43 | #include "lld/Common/ErrorHandler.h" | |
| 44 | #include "lld/Common/Memory.h" | |
| 45 | #include "lld/Common/Threads.h" | |
| 46 | #include "lld/Common/Version.h" | |
| 45 | 47 | #include "llvm/ADT/StringExtras.h" |
| 46 | 48 | #include "llvm/ADT/StringSwitch.h" |
| 47 | 49 | #include "llvm/Support/CommandLine.h" |
| ... | ... | @@ -64,27 +66,40 @@ using namespace lld::elf; |
| 64 | 66 | Configuration *elf::Config; |
| 65 | 67 | LinkerDriver *elf::Driver; |
| 66 | 68 | |
| 67 | BumpPtrAllocator elf::BAlloc; | |
| 68 | StringSaver elf::Saver{BAlloc}; | |
| 69 | std::vector<SpecificAllocBase *> elf::SpecificAllocBase::Instances; | |
| 70 | ||
| 71 | 69 | static void setConfigs(); |
| 72 | 70 | |
| 73 | 71 | bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly, |
| 74 | 72 | raw_ostream &Error) { |
| 75 | ErrorCount = 0; | |
| 76 | ErrorOS = &Error; | |
| 73 | errorHandler().LogName = Args[0]; | |
| 74 | errorHandler().ErrorLimitExceededMsg = | |
| 75 | "too many errors emitted, stopping now (use " | |
| 76 | "-error-limit=0 to see all errors)"; | |
| 77 | errorHandler().ErrorOS = &Error; | |
| 78 | errorHandler().ColorDiagnostics = Error.has_colors(); | |
| 77 | 79 | InputSections.clear(); |
| 80 | OutputSections.clear(); | |
| 78 | 81 | Tar = nullptr; |
| 82 | BinaryFiles.clear(); | |
| 83 | BitcodeFiles.clear(); | |
| 84 | ObjectFiles.clear(); | |
| 85 | SharedFiles.clear(); | |
| 79 | 86 | |
| 80 | 87 | Config = make<Configuration>(); |
| 81 | 88 | Driver = make<LinkerDriver>(); |
| 82 | 89 | Script = make<LinkerScript>(); |
| 90 | Symtab = make<SymbolTable>(); | |
| 83 | 91 | Config->Argv = {Args.begin(), Args.end()}; |
| 84 | 92 | |
| 85 | 93 | Driver->main(Args, CanExitEarly); |
| 94 | ||
| 95 | // Exit immediately if we don't need to return to the caller. | |
| 96 | // This saves time because the overhead of calling destructors | |
| 97 | // for all globally-allocated objects is not negligible. | |
| 98 | if (Config->ExitEarly) | |
| 99 | exitLld(errorCount() ? 1 : 0); | |
| 100 | ||
| 86 | 101 | freeArena(); |
| 87 | return !ErrorCount; | |
| 102 | return !errorCount(); | |
| 88 | 103 | } |
| 89 | 104 | |
| 90 | 105 | // Parses a linker -m option. |
| ... | ... | @@ -112,12 +127,8 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) { |
| 112 | 127 | .Case("elf_iamcu", {ELF32LEKind, EM_IAMCU}) |
| 113 | 128 | .Default({ELFNoneKind, EM_NONE}); |
| 114 | 129 | |
| 115 | if (Ret.first == ELFNoneKind) { | |
| 116 | if (S == "i386pe" || S == "i386pep" || S == "thumb2pe") | |
| 117 | error("Windows targets are not supported on the ELF frontend: " + Emul); | |
| 118 | else | |
| 119 | error("unknown emulation: " + Emul); | |
| 120 | } | |
| 130 | if (Ret.first == ELFNoneKind) | |
| 131 | error("unknown emulation: " + Emul); | |
| 121 | 132 | return std::make_tuple(Ret.first, Ret.second, OSABI); |
| 122 | 133 | } |
| 123 | 134 | |
| ... | ... | @@ -126,19 +137,22 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) { |
| 126 | 137 | std::vector<std::pair<MemoryBufferRef, uint64_t>> static getArchiveMembers( |
| 127 | 138 | MemoryBufferRef MB) { |
| 128 | 139 | std::unique_ptr<Archive> File = |
| 129 | check(Archive::create(MB), | |
| 140 | CHECK(Archive::create(MB), | |
| 130 | 141 | MB.getBufferIdentifier() + ": failed to parse archive"); |
| 131 | 142 | |
| 132 | 143 | std::vector<std::pair<MemoryBufferRef, uint64_t>> V; |
| 133 | 144 | Error Err = Error::success(); |
| 145 | bool AddToTar = File->isThin() && Tar; | |
| 134 | 146 | for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) { |
| 135 | 147 | Archive::Child C = |
| 136 | check(COrErr, MB.getBufferIdentifier() + | |
| 148 | CHECK(COrErr, MB.getBufferIdentifier() + | |
| 137 | 149 | ": could not get the child of the archive"); |
| 138 | 150 | MemoryBufferRef MBRef = |
| 139 | check(C.getMemoryBufferRef(), | |
| 151 | CHECK(C.getMemoryBufferRef(), | |
| 140 | 152 | MB.getBufferIdentifier() + |
| 141 | 153 | ": could not get the buffer for a child of the archive"); |
| 154 | if (AddToTar) | |
| 155 | Tar->append(relativeToRoot(check(C.getFullName())), MBRef.getBuffer()); | |
| 142 | 156 | V.push_back(std::make_pair(MBRef, C.getChildOffset())); |
| 143 | 157 | } |
| 144 | 158 | if (Err) |
| ... | ... | @@ -179,7 +193,7 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) { |
| 179 | 193 | } |
| 180 | 194 | |
| 181 | 195 | std::unique_ptr<Archive> File = |
| 182 | check(Archive::create(MBRef), Path + ": failed to parse archive"); | |
| 196 | CHECK(Archive::create(MBRef), Path + ": failed to parse archive"); | |
| 183 | 197 | |
| 184 | 198 | // If an archive file has no symbol table, it is likely that a user |
| 185 | 199 | // is attempting LTO and using a default ar command that doesn't |
| ... | ... | @@ -187,7 +201,7 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) { |
| 187 | 201 | // we'll handle it as if it had a symbol table. |
| 188 | 202 | if (!File->isEmpty() && !File->hasSymbolTable()) { |
| 189 | 203 | for (const auto &P : getArchiveMembers(MBRef)) |
| 190 | Files.push_back(make<LazyObjectFile>(P.first, Path, P.second)); | |
| 204 | Files.push_back(make<LazyObjFile>(P.first, Path, P.second)); | |
| 191 | 205 | return; |
| 192 | 206 | } |
| 193 | 207 | |
| ... | ... | @@ -216,7 +230,7 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) { |
| 216 | 230 | return; |
| 217 | 231 | default: |
| 218 | 232 | if (InLib) |
| 219 | Files.push_back(make<LazyObjectFile>(MBRef, "", 0)); | |
| 233 | Files.push_back(make<LazyObjFile>(MBRef, "", 0)); | |
| 220 | 234 | else |
| 221 | 235 | Files.push_back(createObjectFile(MBRef)); |
| 222 | 236 | } |
| ... | ... | @@ -256,6 +270,9 @@ static void checkOptions(opt::InputArgList &Args) { |
| 256 | 270 | if (Config->EMachine == EM_MIPS && Config->GnuHash) |
| 257 | 271 | error("the .gnu.hash section is not compatible with the MIPS target."); |
| 258 | 272 | |
| 273 | if (Config->FixCortexA53Errata843419 && Config->EMachine != EM_AARCH64) | |
| 274 | error("--fix-cortex-a53-843419 is only supported on AArch64 targets."); | |
| 275 | ||
| 259 | 276 | if (Config->Pie && Config->Shared) |
| 260 | 277 | error("-shared and -pie may not be used together"); |
| 261 | 278 | |
| ... | ... | @@ -265,6 +282,9 @@ static void checkOptions(opt::InputArgList &Args) { |
| 265 | 282 | if (!Config->Shared && !Config->AuxiliaryList.empty()) |
| 266 | 283 | error("-f may not be used without -shared"); |
| 267 | 284 | |
| 285 | if (!Config->Relocatable && !Config->DefineCommon) | |
| 286 | error("-no-define-common not supported in non relocatable output"); | |
| 287 | ||
| 268 | 288 | if (Config->Relocatable) { |
| 269 | 289 | if (Config->Shared) |
| 270 | 290 | error("-r and -shared may not be used together"); |
| ... | ... | @@ -277,16 +297,6 @@ static void checkOptions(opt::InputArgList &Args) { |
| 277 | 297 | } |
| 278 | 298 | } |
| 279 | 299 | |
| 280 | static int getInteger(opt::InputArgList &Args, unsigned Key, int Default) { | |
| 281 | int V = Default; | |
| 282 | if (auto *Arg = Args.getLastArg(Key)) { | |
| 283 | StringRef S = Arg->getValue(); | |
| 284 | if (!to_integer(S, V, 10)) | |
| 285 | error(Arg->getSpelling() + ": number expected, but got " + S); | |
| 286 | } | |
| 287 | return V; | |
| 288 | } | |
| 289 | ||
| 290 | 300 | static const char *getReproduceOption(opt::InputArgList &Args) { |
| 291 | 301 | if (auto *Arg = Args.getLastArg(OPT_reproduce)) |
| 292 | 302 | return Arg->getValue(); |
| ... | ... | @@ -300,26 +310,12 @@ static bool hasZOption(opt::InputArgList &Args, StringRef Key) { |
| 300 | 310 | return false; |
| 301 | 311 | } |
| 302 | 312 | |
| 303 | static uint64_t getZOptionValue(opt::InputArgList &Args, StringRef Key, | |
| 304 | uint64_t Default) { | |
| 305 | for (auto *Arg : Args.filtered(OPT_z)) { | |
| 306 | std::pair<StringRef, StringRef> KV = StringRef(Arg->getValue()).split('='); | |
| 307 | if (KV.first == Key) { | |
| 308 | uint64_t Result = Default; | |
| 309 | if (!to_integer(KV.second, Result)) | |
| 310 | error("invalid " + Key + ": " + KV.second); | |
| 311 | return Result; | |
| 312 | } | |
| 313 | } | |
| 314 | return Default; | |
| 315 | } | |
| 316 | ||
| 317 | 313 | void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) { |
| 318 | 314 | ELFOptTable Parser; |
| 319 | 315 | opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); |
| 320 | 316 | |
| 321 | 317 | // Interpret this flag early because error() depends on them. |
| 322 | Config->ErrorLimit = getInteger(Args, OPT_error_limit, 20); | |
| 318 | errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20); | |
| 323 | 319 | |
| 324 | 320 | // Handle -help |
| 325 | 321 | if (Args.hasArg(OPT_help)) { |
| ... | ... | @@ -345,13 +341,15 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) { |
| 345 | 341 | if (Args.hasArg(OPT_v) || Args.hasArg(OPT_version)) |
| 346 | 342 | message(getLLDVersion() + " (compatible with GNU linkers)"); |
| 347 | 343 | |
| 348 | // ld.bfd always exits after printing out the version string. | |
| 349 | // ld.gold proceeds if a given option is -v. Because gold's behavior | |
| 350 | // is more permissive than ld.bfd, we chose what gold does here. | |
| 344 | // The behavior of -v or --version is a bit strange, but this is | |
| 345 | // needed for compatibility with GNU linkers. | |
| 346 | if (Args.hasArg(OPT_v) && !Args.hasArg(OPT_INPUT)) | |
| 347 | return; | |
| 351 | 348 | if (Args.hasArg(OPT_version)) |
| 352 | 349 | return; |
| 353 | 350 | |
| 354 | 351 | Config->ExitEarly = CanExitEarly && !Args.hasArg(OPT_full_shutdown); |
| 352 | errorHandler().ExitEarly = Config->ExitEarly; | |
| 355 | 353 | |
| 356 | 354 | if (const char *Path = getReproduceOption(Args)) { |
| 357 | 355 | // Note that --reproduce is a debug option so you can ignore it |
| ... | ... | @@ -375,7 +373,7 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) { |
| 375 | 373 | inferMachineType(); |
| 376 | 374 | setConfigs(); |
| 377 | 375 | checkOptions(Args); |
| 378 | if (ErrorCount) | |
| 376 | if (errorCount()) | |
| 379 | 377 | return; |
| 380 | 378 | |
| 381 | 379 | switch (Config->EKind) { |
| ... | ... | @@ -396,36 +394,19 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) { |
| 396 | 394 | } |
| 397 | 395 | } |
| 398 | 396 | |
| 399 | static bool getArg(opt::InputArgList &Args, unsigned K1, unsigned K2, | |
| 400 | bool Default) { | |
| 401 | if (auto *Arg = Args.getLastArg(K1, K2)) | |
| 402 | return Arg->getOption().getID() == K1; | |
| 403 | return Default; | |
| 404 | } | |
| 405 | ||
| 406 | static std::vector<StringRef> getArgs(opt::InputArgList &Args, int Id) { | |
| 407 | std::vector<StringRef> V; | |
| 408 | for (auto *Arg : Args.filtered(Id)) | |
| 409 | V.push_back(Arg->getValue()); | |
| 410 | return V; | |
| 411 | } | |
| 412 | ||
| 413 | 397 | static std::string getRpath(opt::InputArgList &Args) { |
| 414 | std::vector<StringRef> V = getArgs(Args, OPT_rpath); | |
| 398 | std::vector<StringRef> V = args::getStrings(Args, OPT_rpath); | |
| 415 | 399 | return llvm::join(V.begin(), V.end(), ":"); |
| 416 | 400 | } |
| 417 | 401 | |
| 418 | 402 | // Determines what we should do if there are remaining unresolved |
| 419 | 403 | // symbols after the name resolution. |
| 420 | 404 | static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &Args) { |
| 421 | // -noinhibit-exec or -r imply some default values. | |
| 422 | if (Args.hasArg(OPT_noinhibit_exec)) | |
| 423 | return UnresolvedPolicy::WarnAll; | |
| 424 | 405 | if (Args.hasArg(OPT_relocatable)) |
| 425 | 406 | return UnresolvedPolicy::IgnoreAll; |
| 426 | 407 | |
| 427 | UnresolvedPolicy ErrorOrWarn = getArg(Args, OPT_error_unresolved_symbols, | |
| 428 | OPT_warn_unresolved_symbols, true) | |
| 408 | UnresolvedPolicy ErrorOrWarn = Args.hasFlag(OPT_error_unresolved_symbols, | |
| 409 | OPT_warn_unresolved_symbols, true) | |
| 429 | 410 | ? UnresolvedPolicy::ReportError |
| 430 | 411 | : UnresolvedPolicy::Warn; |
| 431 | 412 | |
| ... | ... | @@ -513,7 +494,7 @@ static StripPolicy getStrip(opt::InputArgList &Args) { |
| 513 | 494 | return StripPolicy::Debug; |
| 514 | 495 | } |
| 515 | 496 | |
| 516 | static uint64_t parseSectionAddress(StringRef S, opt::Arg *Arg) { | |
| 497 | static uint64_t parseSectionAddress(StringRef S, const opt::Arg &Arg) { | |
| 517 | 498 | uint64_t VA = 0; |
| 518 | 499 | if (S.startswith("0x")) |
| 519 | 500 | S = S.drop_front(2); |
| ... | ... | @@ -528,15 +509,15 @@ static StringMap<uint64_t> getSectionStartMap(opt::InputArgList &Args) { |
| 528 | 509 | StringRef Name; |
| 529 | 510 | StringRef Addr; |
| 530 | 511 | std::tie(Name, Addr) = StringRef(Arg->getValue()).split('='); |
| 531 | Ret[Name] = parseSectionAddress(Addr, Arg); | |
| 512 | Ret[Name] = parseSectionAddress(Addr, *Arg); | |
| 532 | 513 | } |
| 533 | 514 | |
| 534 | 515 | if (auto *Arg = Args.getLastArg(OPT_Ttext)) |
| 535 | Ret[".text"] = parseSectionAddress(Arg->getValue(), Arg); | |
| 516 | Ret[".text"] = parseSectionAddress(Arg->getValue(), *Arg); | |
| 536 | 517 | if (auto *Arg = Args.getLastArg(OPT_Tdata)) |
| 537 | Ret[".data"] = parseSectionAddress(Arg->getValue(), Arg); | |
| 518 | Ret[".data"] = parseSectionAddress(Arg->getValue(), *Arg); | |
| 538 | 519 | if (auto *Arg = Args.getLastArg(OPT_Tbss)) |
| 539 | Ret[".bss"] = parseSectionAddress(Arg->getValue(), Arg); | |
| 520 | Ret[".bss"] = parseSectionAddress(Arg->getValue(), *Arg); | |
| 540 | 521 | return Ret; |
| 541 | 522 | } |
| 542 | 523 | |
| ... | ... | @@ -551,15 +532,15 @@ static SortSectionPolicy getSortSection(opt::InputArgList &Args) { |
| 551 | 532 | return SortSectionPolicy::Default; |
| 552 | 533 | } |
| 553 | 534 | |
| 554 | static std::pair<bool, bool> getHashStyle(opt::InputArgList &Args) { | |
| 555 | StringRef S = Args.getLastArgValue(OPT_hash_style, "sysv"); | |
| 556 | if (S == "sysv") | |
| 557 | return {true, false}; | |
| 558 | if (S == "gnu") | |
| 559 | return {false, true}; | |
| 560 | if (S != "both") | |
| 561 | error("unknown -hash-style: " + S); | |
| 562 | return {true, true}; | |
| 535 | static OrphanHandlingPolicy getOrphanHandling(opt::InputArgList &Args) { | |
| 536 | StringRef S = Args.getLastArgValue(OPT_orphan_handling, "place"); | |
| 537 | if (S == "warn") | |
| 538 | return OrphanHandlingPolicy::Warn; | |
| 539 | if (S == "error") | |
| 540 | return OrphanHandlingPolicy::Error; | |
| 541 | if (S != "place") | |
| 542 | error("unknown --orphan-handling mode: " + S); | |
| 543 | return OrphanHandlingPolicy::Place; | |
| 563 | 544 | } |
| 564 | 545 | |
| 565 | 546 | // Parse --build-id or --build-id=<style>. We handle "tree" as a |
| ... | ... | @@ -589,19 +570,6 @@ getBuildId(opt::InputArgList &Args) { |
| 589 | 570 | return {BuildIdKind::None, {}}; |
| 590 | 571 | } |
| 591 | 572 | |
| 592 | static std::vector<StringRef> getLines(MemoryBufferRef MB) { | |
| 593 | SmallVector<StringRef, 0> Arr; | |
| 594 | MB.getBuffer().split(Arr, '\n'); | |
| 595 | ||
| 596 | std::vector<StringRef> Ret; | |
| 597 | for (StringRef S : Arr) { | |
| 598 | S = S.trim(); | |
| 599 | if (!S.empty()) | |
| 600 | Ret.push_back(S); | |
| 601 | } | |
| 602 | return Ret; | |
| 603 | } | |
| 604 | ||
| 605 | 573 | static bool getCompressDebugSections(opt::InputArgList &Args) { |
| 606 | 574 | StringRef S = Args.getLastArgValue(OPT_compress_debug_sections, "none"); |
| 607 | 575 | if (S == "none") |
| ... | ... | @@ -613,53 +581,70 @@ static bool getCompressDebugSections(opt::InputArgList &Args) { |
| 613 | 581 | return true; |
| 614 | 582 | } |
| 615 | 583 | |
| 584 | static int parseInt(StringRef S, opt::Arg *Arg) { | |
| 585 | int V = 0; | |
| 586 | if (!to_integer(S, V, 10)) | |
| 587 | error(Arg->getSpelling() + ": number expected, but got '" + S + "'"); | |
| 588 | return V; | |
| 589 | } | |
| 590 | ||
| 616 | 591 | // Initializes Config members by the command line options. |
| 617 | 592 | void LinkerDriver::readConfigs(opt::InputArgList &Args) { |
| 618 | Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition); | |
| 619 | Config->AuxiliaryList = getArgs(Args, OPT_auxiliary); | |
| 593 | Config->AllowMultipleDefinition = | |
| 594 | Args.hasArg(OPT_allow_multiple_definition) || hasZOption(Args, "muldefs"); | |
| 595 | Config->AuxiliaryList = args::getStrings(Args, OPT_auxiliary); | |
| 620 | 596 | Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic); |
| 621 | 597 | Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions); |
| 598 | Config->Chroot = Args.getLastArgValue(OPT_chroot); | |
| 622 | 599 | Config->CompressDebugSections = getCompressDebugSections(Args); |
| 623 | Config->DefineCommon = getArg(Args, OPT_define_common, OPT_no_define_common, | |
| 624 | !Args.hasArg(OPT_relocatable)); | |
| 625 | Config->Demangle = getArg(Args, OPT_demangle, OPT_no_demangle, true); | |
| 600 | Config->DefineCommon = Args.hasFlag(OPT_define_common, OPT_no_define_common, | |
| 601 | !Args.hasArg(OPT_relocatable)); | |
| 602 | Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true); | |
| 626 | 603 | Config->DisableVerify = Args.hasArg(OPT_disable_verify); |
| 627 | 604 | Config->Discard = getDiscard(Args); |
| 628 | 605 | Config->DynamicLinker = getDynamicLinker(Args); |
| 629 | Config->EhFrameHdr = Args.hasArg(OPT_eh_frame_hdr); | |
| 606 | Config->EhFrameHdr = | |
| 607 | Args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false); | |
| 630 | 608 | Config->EmitRelocs = Args.hasArg(OPT_emit_relocs); |
| 631 | 609 | Config->EnableNewDtags = !Args.hasArg(OPT_disable_new_dtags); |
| 632 | 610 | Config->Entry = Args.getLastArgValue(OPT_entry); |
| 633 | 611 | Config->ExportDynamic = |
| 634 | getArg(Args, OPT_export_dynamic, OPT_no_export_dynamic, false); | |
| 635 | Config->FatalWarnings = | |
| 636 | getArg(Args, OPT_fatal_warnings, OPT_no_fatal_warnings, false); | |
| 637 | Config->FilterList = getArgs(Args, OPT_filter); | |
| 612 | 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); | |
| 638 | 616 | Config->Fini = Args.getLastArgValue(OPT_fini, "_fini"); |
| 639 | Config->GcSections = getArg(Args, OPT_gc_sections, OPT_no_gc_sections, false); | |
| 640 | Config->GdbIndex = Args.hasArg(OPT_gdb_index); | |
| 641 | Config->ICF = getArg(Args, OPT_icf_all, OPT_icf_none, false); | |
| 617 | Config->FixCortexA53Errata843419 = Args.hasArg(OPT_fix_cortex_a53_843419); | |
| 618 | Config->GcSections = Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false); | |
| 619 | Config->GdbIndex = Args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false); | |
| 620 | Config->ICF = Args.hasFlag(OPT_icf_all, OPT_icf_none, false); | |
| 621 | Config->ICFData = Args.hasArg(OPT_icf_data); | |
| 642 | 622 | Config->Init = Args.getLastArgValue(OPT_init, "_init"); |
| 643 | 623 | Config->LTOAAPipeline = Args.getLastArgValue(OPT_lto_aa_pipeline); |
| 644 | 624 | Config->LTONewPmPasses = Args.getLastArgValue(OPT_lto_newpm_passes); |
| 645 | Config->LTOO = getInteger(Args, OPT_lto_O, 2); | |
| 646 | Config->LTOPartitions = getInteger(Args, OPT_lto_partitions, 1); | |
| 625 | Config->LTOO = args::getInteger(Args, OPT_lto_O, 2); | |
| 626 | Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1); | |
| 647 | 627 | Config->MapFile = Args.getLastArgValue(OPT_Map); |
| 648 | 628 | Config->NoGnuUnique = Args.hasArg(OPT_no_gnu_unique); |
| 629 | Config->MergeArmExidx = | |
| 630 | Args.hasFlag(OPT_merge_exidx_entries, OPT_no_merge_exidx_entries, true); | |
| 649 | 631 | Config->NoUndefinedVersion = Args.hasArg(OPT_no_undefined_version); |
| 632 | Config->NoinhibitExec = Args.hasArg(OPT_noinhibit_exec); | |
| 650 | 633 | Config->Nostdlib = Args.hasArg(OPT_nostdlib); |
| 651 | 634 | Config->OFormatBinary = isOutputFormatBinary(Args); |
| 652 | Config->Omagic = Args.hasArg(OPT_omagic); | |
| 635 | Config->Omagic = Args.hasFlag(OPT_omagic, OPT_no_omagic, false); | |
| 653 | 636 | Config->OptRemarksFilename = Args.getLastArgValue(OPT_opt_remarks_filename); |
| 654 | 637 | Config->OptRemarksWithHotness = Args.hasArg(OPT_opt_remarks_with_hotness); |
| 655 | Config->Optimize = getInteger(Args, OPT_O, 1); | |
| 638 | Config->Optimize = args::getInteger(Args, OPT_O, 1); | |
| 639 | Config->OrphanHandling = getOrphanHandling(Args); | |
| 656 | 640 | Config->OutputFile = Args.getLastArgValue(OPT_o); |
| 657 | Config->Pie = getArg(Args, OPT_pie, OPT_nopie, false); | |
| 658 | Config->PrintGcSections = Args.hasArg(OPT_print_gc_sections); | |
| 641 | Config->Pie = Args.hasFlag(OPT_pie, OPT_nopie, false); | |
| 642 | Config->PrintGcSections = | |
| 643 | Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false); | |
| 659 | 644 | Config->Rpath = getRpath(Args); |
| 660 | 645 | Config->Relocatable = Args.hasArg(OPT_relocatable); |
| 661 | 646 | Config->SaveTemps = Args.hasArg(OPT_save_temps); |
| 662 | Config->SearchPaths = getArgs(Args, OPT_L); | |
| 647 | Config->SearchPaths = args::getStrings(Args, OPT_library_path); | |
| 663 | 648 | Config->SectionStartMap = getSectionStartMap(Args); |
| 664 | 649 | Config->Shared = Args.hasArg(OPT_shared); |
| 665 | 650 | Config->SingleRoRx = Args.hasArg(OPT_no_rosegment); |
| ... | ... | @@ -667,18 +652,19 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { |
| 667 | 652 | Config->SortSection = getSortSection(Args); |
| 668 | 653 | Config->Strip = getStrip(Args); |
| 669 | 654 | Config->Sysroot = Args.getLastArgValue(OPT_sysroot); |
| 670 | Config->Target1Rel = getArg(Args, OPT_target1_rel, OPT_target1_abs, false); | |
| 655 | Config->Target1Rel = Args.hasFlag(OPT_target1_rel, OPT_target1_abs, false); | |
| 671 | 656 | Config->Target2 = getTarget2(Args); |
| 672 | 657 | Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir); |
| 673 | Config->ThinLTOCachePolicy = check( | |
| 658 | Config->ThinLTOCachePolicy = CHECK( | |
| 674 | 659 | parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)), |
| 675 | 660 | "--thinlto-cache-policy: invalid cache policy"); |
| 676 | Config->ThinLTOJobs = getInteger(Args, OPT_thinlto_jobs, -1u); | |
| 677 | Config->Threads = getArg(Args, OPT_threads, OPT_no_threads, true); | |
| 661 | Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u); | |
| 662 | ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true); | |
| 678 | 663 | Config->Trace = Args.hasArg(OPT_trace); |
| 679 | Config->Undefined = getArgs(Args, OPT_undefined); | |
| 664 | Config->Undefined = args::getStrings(Args, OPT_undefined); | |
| 680 | 665 | Config->UnresolvedSymbols = getUnresolvedSymbolPolicy(Args); |
| 681 | 666 | Config->Verbose = Args.hasArg(OPT_verbose); |
| 667 | errorHandler().Verbose = Config->Verbose; | |
| 682 | 668 | Config->WarnCommon = Args.hasArg(OPT_warn_common); |
| 683 | 669 | Config->ZCombreloc = !hasZOption(Args, "nocombreloc"); |
| 684 | 670 | Config->ZExecstack = hasZOption(Args, "execstack"); |
| ... | ... | @@ -688,21 +674,41 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { |
| 688 | 674 | Config->ZNow = hasZOption(Args, "now"); |
| 689 | 675 | Config->ZOrigin = hasZOption(Args, "origin"); |
| 690 | 676 | Config->ZRelro = !hasZOption(Args, "norelro"); |
| 677 | Config->ZRetpolineplt = hasZOption(Args, "retpolineplt"); | |
| 691 | 678 | Config->ZRodynamic = hasZOption(Args, "rodynamic"); |
| 692 | Config->ZStackSize = getZOptionValue(Args, "stack-size", 0); | |
| 679 | Config->ZStackSize = args::getZOptionValue(Args, OPT_z, "stack-size", 0); | |
| 693 | 680 | Config->ZText = !hasZOption(Args, "notext"); |
| 694 | 681 | Config->ZWxneeded = hasZOption(Args, "wxneeded"); |
| 695 | 682 | |
| 683 | // Parse LTO plugin-related options for compatibility with gold. | |
| 684 | for (auto *Arg : Args.filtered(OPT_plugin_opt, OPT_plugin_opt_eq)) { | |
| 685 | StringRef S = Arg->getValue(); | |
| 686 | if (S == "disable-verify") | |
| 687 | Config->DisableVerify = true; | |
| 688 | else if (S == "save-temps") | |
| 689 | Config->SaveTemps = true; | |
| 690 | else if (S.startswith("O")) | |
| 691 | Config->LTOO = parseInt(S.substr(1), Arg); | |
| 692 | else if (S.startswith("lto-partitions=")) | |
| 693 | Config->LTOPartitions = parseInt(S.substr(15), Arg); | |
| 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 | ||
| 696 | 703 | if (Config->LTOO > 3) |
| 697 | error("invalid optimization level for LTO: " + | |
| 698 | Args.getLastArgValue(OPT_lto_O)); | |
| 704 | error("invalid optimization level for LTO: " + Twine(Config->LTOO)); | |
| 699 | 705 | if (Config->LTOPartitions == 0) |
| 700 | 706 | error("--lto-partitions: number of threads must be > 0"); |
| 701 | 707 | if (Config->ThinLTOJobs == 0) |
| 702 | 708 | error("--thinlto-jobs: number of threads must be > 0"); |
| 703 | 709 | |
| 710 | // Parse ELF{32,64}{LE,BE} and CPU type. | |
| 704 | 711 | if (auto *Arg = Args.getLastArg(OPT_m)) { |
| 705 | // Parse ELF{32,64}{LE,BE} and CPU type. | |
| 706 | 712 | StringRef S = Arg->getValue(); |
| 707 | 713 | std::tie(Config->EKind, Config->EMachine, Config->OSABI) = |
| 708 | 714 | parseEmulation(S); |
| ... | ... | @@ -710,6 +716,19 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { |
| 710 | 716 | Config->Emulation = S; |
| 711 | 717 | } |
| 712 | 718 | |
| 719 | // Parse -hash-style={sysv,gnu,both}. | |
| 720 | if (auto *Arg = Args.getLastArg(OPT_hash_style)) { | |
| 721 | StringRef S = Arg->getValue(); | |
| 722 | if (S == "sysv") | |
| 723 | Config->SysvHash = true; | |
| 724 | else if (S == "gnu") | |
| 725 | Config->GnuHash = true; | |
| 726 | else if (S == "both") | |
| 727 | Config->SysvHash = Config->GnuHash = true; | |
| 728 | else | |
| 729 | error("unknown -hash-style: " + S); | |
| 730 | } | |
| 731 | ||
| 713 | 732 | if (Args.hasArg(OPT_print_map)) |
| 714 | 733 | Config->MapFile = "-"; |
| 715 | 734 | |
| ... | ... | @@ -720,25 +739,32 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { |
| 720 | 739 | if (Config->Omagic) |
| 721 | 740 | Config->ZRelro = false; |
| 722 | 741 | |
| 723 | std::tie(Config->SysvHash, Config->GnuHash) = getHashStyle(Args); | |
| 724 | 742 | std::tie(Config->BuildId, Config->BuildIdVector) = getBuildId(Args); |
| 725 | 743 | |
| 744 | if (auto *Arg = Args.getLastArg(OPT_pack_dyn_relocs_eq)) { | |
| 745 | StringRef S = Arg->getValue(); | |
| 746 | if (S == "android") | |
| 747 | Config->AndroidPackDynRelocs = true; | |
| 748 | else if (S != "none") | |
| 749 | error("unknown -pack-dyn-relocs format: " + S); | |
| 750 | } | |
| 751 | ||
| 726 | 752 | if (auto *Arg = Args.getLastArg(OPT_symbol_ordering_file)) |
| 727 | 753 | if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue())) |
| 728 | Config->SymbolOrderingFile = getLines(*Buffer); | |
| 754 | Config->SymbolOrderingFile = args::getLines(*Buffer); | |
| 729 | 755 | |
| 730 | 756 | // If --retain-symbol-file is used, we'll keep only the symbols listed in |
| 731 | 757 | // the file and discard all others. |
| 732 | 758 | if (auto *Arg = Args.getLastArg(OPT_retain_symbols_file)) { |
| 733 | 759 | Config->DefaultSymbolVersion = VER_NDX_LOCAL; |
| 734 | 760 | if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue())) |
| 735 | for (StringRef S : getLines(*Buffer)) | |
| 761 | for (StringRef S : args::getLines(*Buffer)) | |
| 736 | 762 | Config->VersionScriptGlobals.push_back( |
| 737 | 763 | {S, /*IsExternCpp*/ false, /*HasWildcard*/ false}); |
| 738 | 764 | } |
| 739 | 765 | |
| 740 | 766 | bool HasExportDynamic = |
| 741 | getArg(Args, OPT_export_dynamic, OPT_no_export_dynamic, false); | |
| 767 | Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false); | |
| 742 | 768 | |
| 743 | 769 | // Parses -dynamic-list and -export-dynamic-symbol. They make some |
| 744 | 770 | // symbols private. Note that -export-dynamic takes precedence over them |
| ... | ... | @@ -749,21 +775,11 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { |
| 749 | 775 | readDynamicList(*Buffer); |
| 750 | 776 | |
| 751 | 777 | for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol)) |
| 752 | Config->VersionScriptGlobals.push_back( | |
| 778 | Config->DynamicList.push_back( | |
| 753 | 779 | {Arg->getValue(), /*IsExternCpp*/ false, /*HasWildcard*/ false}); |
| 754 | ||
| 755 | // Dynamic lists are a simplified linker script that doesn't need the | |
| 756 | // "global:" and implicitly ends with a "local:*". Set the variables | |
| 757 | // needed to simulate that. | |
| 758 | if (Args.hasArg(OPT_dynamic_list) || | |
| 759 | Args.hasArg(OPT_export_dynamic_symbol)) { | |
| 760 | Config->ExportDynamic = true; | |
| 761 | if (!Config->Shared) | |
| 762 | Config->DefaultSymbolVersion = VER_NDX_LOCAL; | |
| 763 | } | |
| 764 | 780 | } |
| 765 | 781 | |
| 766 | if (auto *Arg = Args.getLastArg(OPT_version_script)) | |
| 782 | for (auto *Arg : Args.filtered(OPT_version_script)) | |
| 767 | 783 | if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue())) |
| 768 | 784 | readVersionScript(*Buffer); |
| 769 | 785 | } |
| ... | ... | @@ -804,17 +820,20 @@ static bool getBinaryOption(StringRef S) { |
| 804 | 820 | |
| 805 | 821 | void LinkerDriver::createFiles(opt::InputArgList &Args) { |
| 806 | 822 | for (auto *Arg : Args) { |
| 807 | switch (Arg->getOption().getID()) { | |
| 808 | case OPT_l: | |
| 823 | switch (Arg->getOption().getUnaliasedOption().getID()) { | |
| 824 | case OPT_library: | |
| 809 | 825 | addLibrary(Arg->getValue()); |
| 810 | 826 | break; |
| 811 | 827 | case OPT_INPUT: |
| 812 | 828 | addFile(Arg->getValue(), /*WithLOption=*/false); |
| 813 | 829 | break; |
| 814 | case OPT_alias_script_T: | |
| 815 | 830 | case OPT_script: |
| 816 | if (Optional<MemoryBufferRef> MB = readFile(Arg->getValue())) | |
| 817 | readLinkerScript(*MB); | |
| 831 | if (Optional<std::string> Path = searchLinkerScript(Arg->getValue())) { | |
| 832 | if (Optional<MemoryBufferRef> MB = readFile(*Path)) | |
| 833 | readLinkerScript(*MB); | |
| 834 | break; | |
| 835 | } | |
| 836 | error(Twine("cannot find linker script ") + Arg->getValue()); | |
| 818 | 837 | break; |
| 819 | 838 | case OPT_as_needed: |
| 820 | 839 | Config->AsNeeded = true; |
| ... | ... | @@ -846,7 +865,7 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) { |
| 846 | 865 | } |
| 847 | 866 | } |
| 848 | 867 | |
| 849 | if (Files.empty() && ErrorCount == 0) | |
| 868 | if (Files.empty() && errorCount() == 0) | |
| 850 | 869 | error("no input files"); |
| 851 | 870 | } |
| 852 | 871 | |
| ... | ... | @@ -870,21 +889,20 @@ void LinkerDriver::inferMachineType() { |
| 870 | 889 | // Parse -z max-page-size=<value>. The default value is defined by |
| 871 | 890 | // each target. |
| 872 | 891 | static uint64_t getMaxPageSize(opt::InputArgList &Args) { |
| 873 | uint64_t Val = | |
| 874 | getZOptionValue(Args, "max-page-size", Target->DefaultMaxPageSize); | |
| 892 | uint64_t Val = args::getZOptionValue(Args, OPT_z, "max-page-size", | |
| 893 | Target->DefaultMaxPageSize); | |
| 875 | 894 | if (!isPowerOf2_64(Val)) |
| 876 | 895 | error("max-page-size: value isn't a power of 2"); |
| 877 | 896 | return Val; |
| 878 | 897 | } |
| 879 | 898 | |
| 880 | 899 | // Parses -image-base option. |
| 881 | static uint64_t getImageBase(opt::InputArgList &Args) { | |
| 882 | // Use default if no -image-base option is given. | |
| 883 | // Because we are using "Target" here, this function | |
| 884 | // has to be called after the variable is initialized. | |
| 900 | static Optional<uint64_t> getImageBase(opt::InputArgList &Args) { | |
| 901 | // Because we are using "Config->MaxPageSize" here, this function has to be | |
| 902 | // called after the variable is initialized. | |
| 885 | 903 | auto *Arg = Args.getLastArg(OPT_image_base); |
| 886 | 904 | if (!Arg) |
| 887 | return Config->Pic ? 0 : Target->DefaultImageBase; | |
| 905 | return None; | |
| 888 | 906 | |
| 889 | 907 | StringRef S = Arg->getValue(); |
| 890 | 908 | uint64_t V; |
| ... | ... | @@ -897,21 +915,6 @@ static uint64_t getImageBase(opt::InputArgList &Args) { |
| 897 | 915 | return V; |
| 898 | 916 | } |
| 899 | 917 | |
| 900 | // Parses --defsym=alias option. | |
| 901 | static std::vector<std::pair<StringRef, StringRef>> | |
| 902 | getDefsym(opt::InputArgList &Args) { | |
| 903 | std::vector<std::pair<StringRef, StringRef>> Ret; | |
| 904 | for (auto *Arg : Args.filtered(OPT_defsym)) { | |
| 905 | StringRef From; | |
| 906 | StringRef To; | |
| 907 | std::tie(From, To) = StringRef(Arg->getValue()).split('='); | |
| 908 | if (!isValidCIdentifier(To)) | |
| 909 | error("--defsym: symbol name expected, but got " + To); | |
| 910 | Ret.push_back({From, To}); | |
| 911 | } | |
| 912 | return Ret; | |
| 913 | } | |
| 914 | ||
| 915 | 918 | // Parses `--exclude-libs=lib,lib,...`. |
| 916 | 919 | // The library names may be delimited by commas or colons. |
| 917 | 920 | static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &Args) { |
| ... | ... | @@ -930,33 +933,50 @@ static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &Args) { |
| 930 | 933 | return Ret; |
| 931 | 934 | } |
| 932 | 935 | |
| 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 | ||
| 933 | 944 | // Handles the -exclude-libs option. If a static library file is specified |
| 934 | 945 | // by the -exclude-libs option, all public symbols from the archive become |
| 935 | 946 | // private unless otherwise specified by version scripts or something. |
| 936 | 947 | // A special library name "ALL" means all archive files. |
| 937 | 948 | // |
| 938 | 949 | // This is not a popular option, but some programs such as bionic libc use it. |
| 950 | template <class ELFT> | |
| 939 | 951 | static void excludeLibs(opt::InputArgList &Args, ArrayRef<InputFile *> Files) { |
| 940 | 952 | DenseSet<StringRef> Libs = getExcludeLibs(Args); |
| 941 | 953 | bool All = Libs.count("ALL"); |
| 942 | 954 | |
| 943 | 955 | for (InputFile *File : Files) |
| 944 | if (auto *F = dyn_cast<ArchiveFile>(File)) | |
| 945 | if (All || Libs.count(path::filename(F->getName()))) | |
| 946 | for (Symbol *Sym : F->getSymbols()) | |
| 947 | Sym->VersionId = VER_NDX_LOCAL; | |
| 956 | if (Optional<StringRef> Archive = getArchiveName(File)) | |
| 957 | if (All || Libs.count(path::filename(*Archive))) | |
| 958 | for (Symbol *Sym : File->getSymbols()) | |
| 959 | if (!Sym->isLocal()) | |
| 960 | Sym->VersionId = VER_NDX_LOCAL; | |
| 948 | 961 | } |
| 949 | 962 | |
| 950 | 963 | // Do actual linking. Note that when this function is called, |
| 951 | 964 | // all linker scripts have already been parsed. |
| 952 | 965 | template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { |
| 953 | SymbolTable<ELFT> Symtab; | |
| 954 | elf::Symtab<ELFT>::X = &Symtab; | |
| 955 | 966 | Target = getTarget(); |
| 956 | 967 | |
| 957 | 968 | Config->MaxPageSize = getMaxPageSize(Args); |
| 958 | 969 | Config->ImageBase = getImageBase(Args); |
| 959 | 970 | |
| 971 | // If a -hash-style option was not given, set to a default value, | |
| 972 | // which varies depending on the target. | |
| 973 | if (!Args.hasArg(OPT_hash_style)) { | |
| 974 | if (Config->EMachine == EM_MIPS) | |
| 975 | Config->SysvHash = true; | |
| 976 | else | |
| 977 | Config->SysvHash = Config->GnuHash = true; | |
| 978 | } | |
| 979 | ||
| 960 | 980 | // Default output filename is "a.out" by the Unix tradition. |
| 961 | 981 | if (Config->OutputFile.empty()) |
| 962 | 982 | Config->OutputFile = "a.out"; |
| ... | ... | @@ -968,7 +988,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { |
| 968 | 988 | error("cannot open output file " + Config->OutputFile + ": " + E.message()); |
| 969 | 989 | if (auto E = tryCreateFile(Config->MapFile)) |
| 970 | 990 | error("cannot open map file " + Config->MapFile + ": " + E.message()); |
| 971 | if (ErrorCount) | |
| 991 | if (errorCount()) | |
| 972 | 992 | return; |
| 973 | 993 | |
| 974 | 994 | // Use default entry point name if no name was given via the command |
| ... | ... | @@ -981,78 +1001,130 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { |
| 981 | 1001 | |
| 982 | 1002 | // Handle --trace-symbol. |
| 983 | 1003 | for (auto *Arg : Args.filtered(OPT_trace_symbol)) |
| 984 | Symtab.trace(Arg->getValue()); | |
| 1004 | Symtab->trace(Arg->getValue()); | |
| 985 | 1005 | |
| 986 | 1006 | // Add all files to the symbol table. This will add almost all |
| 987 | 1007 | // symbols that we need to the symbol table. |
| 988 | 1008 | for (InputFile *F : Files) |
| 989 | Symtab.addFile(F); | |
| 1009 | Symtab->addFile<ELFT>(F); | |
| 1010 | ||
| 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 | |
| 1020 | // dynamic symbol table. | |
| 1021 | // We need one if we were asked to export dynamic symbols or if we are | |
| 1022 | // producing a shared library. | |
| 1023 | // We also need one if any shared libraries are used and for pie executables | |
| 1024 | // (probably because the dynamic linker needs it). | |
| 1025 | Config->HasDynSymTab = | |
| 1026 | !SharedFiles.empty() || Config->Pic || Config->ExportDynamic; | |
| 1027 | ||
| 1028 | // Some symbols (such as __ehdr_start) are defined lazily only when there | |
| 1029 | // are undefined symbols for them, so we add these to trigger that logic. | |
| 1030 | for (StringRef Sym : Script->ReferencedSymbols) | |
| 1031 | Symtab->addUndefined<ELFT>(Sym); | |
| 1032 | ||
| 1033 | // Handle the `--undefined <sym>` options. | |
| 1034 | for (StringRef S : Config->Undefined) | |
| 1035 | Symtab->fetchIfLazy<ELFT>(S); | |
| 990 | 1036 | |
| 991 | 1037 | // If an entry symbol is in a static archive, pull out that file now |
| 992 | 1038 | // to complete the symbol table. After this, no new names except a |
| 993 | 1039 | // few linker-synthesized ones will be added to the symbol table. |
| 994 | if (Symtab.find(Config->Entry)) | |
| 995 | Symtab.addUndefined(Config->Entry); | |
| 1040 | Symtab->fetchIfLazy<ELFT>(Config->Entry); | |
| 996 | 1041 | |
| 997 | 1042 | // Return if there were name resolution errors. |
| 998 | if (ErrorCount) | |
| 1043 | if (errorCount()) | |
| 999 | 1044 | return; |
| 1000 | 1045 | |
| 1001 | // Handle the `--undefined <sym>` options. | |
| 1002 | Symtab.scanUndefinedFlags(); | |
| 1003 | ||
| 1004 | 1046 | // Handle undefined symbols in DSOs. |
| 1005 | Symtab.scanShlibUndefined(); | |
| 1047 | if (!Config->Shared) | |
| 1048 | Symtab->scanShlibUndefined<ELFT>(); | |
| 1006 | 1049 | |
| 1007 | 1050 | // Handle the -exclude-libs option. |
| 1008 | 1051 | if (Args.hasArg(OPT_exclude_libs)) |
| 1009 | excludeLibs(Args, Files); | |
| 1052 | excludeLibs<ELFT>(Args, Files); | |
| 1053 | ||
| 1054 | // Create ElfHeader early. We need a dummy section in | |
| 1055 | // addReservedSymbols to mark the created symbols as not absolute. | |
| 1056 | Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC); | |
| 1057 | Out::ElfHeader->Size = sizeof(typename ELFT::Ehdr); | |
| 1058 | ||
| 1059 | // We need to create some reserved symbols such as _end. Create them. | |
| 1060 | if (!Config->Relocatable) | |
| 1061 | addReservedSymbols(); | |
| 1010 | 1062 | |
| 1011 | 1063 | // Apply version scripts. |
| 1012 | Symtab.scanVersionScript(); | |
| 1064 | // | |
| 1065 | // For a relocatable output, version scripts don't make sense, and | |
| 1066 | // parsing a symbol version string (e.g. dropping "@ver1" from a symbol | |
| 1067 | // name "foo@ver1") rather do harm, so we don't call this if -r is given. | |
| 1068 | if (!Config->Relocatable) | |
| 1069 | Symtab->scanVersionScript(); | |
| 1013 | 1070 | |
| 1014 | 1071 | // Create wrapped symbols for -wrap option. |
| 1015 | 1072 | for (auto *Arg : Args.filtered(OPT_wrap)) |
| 1016 | Symtab.addSymbolWrap(Arg->getValue()); | |
| 1017 | ||
| 1018 | // Create alias symbols for -defsym option. | |
| 1019 | for (std::pair<StringRef, StringRef> &Def : getDefsym(Args)) | |
| 1020 | Symtab.addSymbolAlias(Def.first, Def.second); | |
| 1073 | Symtab->addSymbolWrap<ELFT>(Arg->getValue()); | |
| 1021 | 1074 | |
| 1022 | Symtab.addCombinedLTOObject(); | |
| 1023 | if (ErrorCount) | |
| 1075 | Symtab->addCombinedLTOObject<ELFT>(); | |
| 1076 | if (errorCount()) | |
| 1024 | 1077 | return; |
| 1025 | 1078 | |
| 1026 | // Some symbols (such as __ehdr_start) are defined lazily only when there | |
| 1027 | // are undefined symbols for them, so we add these to trigger that logic. | |
| 1028 | for (StringRef Sym : Script->Opt.ReferencedSymbols) | |
| 1029 | Symtab.addUndefined(Sym); | |
| 1030 | ||
| 1031 | // Apply symbol renames for -wrap and -defsym | |
| 1032 | Symtab.applySymbolRenames(); | |
| 1079 | // Apply symbol renames for -wrap. | |
| 1080 | Symtab->applySymbolWrap(); | |
| 1033 | 1081 | |
| 1034 | 1082 | // Now that we have a complete list of input files. |
| 1035 | 1083 | // Beyond this point, no new files are added. |
| 1036 | 1084 | // Aggregate all input sections into one place. |
| 1037 | for (elf::ObjectFile<ELFT> *F : Symtab.getObjectFiles()) | |
| 1085 | for (InputFile *F : ObjectFiles) | |
| 1038 | 1086 | for (InputSectionBase *S : F->getSections()) |
| 1039 | 1087 | if (S && S != &InputSection::Discarded) |
| 1040 | 1088 | InputSections.push_back(S); |
| 1041 | for (BinaryFile *F : Symtab.getBinaryFiles()) | |
| 1089 | for (BinaryFile *F : BinaryFiles) | |
| 1042 | 1090 | for (InputSectionBase *S : F->getSections()) |
| 1043 | 1091 | InputSections.push_back(cast<InputSection>(S)); |
| 1044 | 1092 | |
| 1093 | // We do not want to emit debug sections if --strip-all | |
| 1094 | // or -strip-debug are given. | |
| 1095 | if (Config->Strip != StripPolicy::None) | |
| 1096 | llvm::erase_if(InputSections, [](InputSectionBase *S) { | |
| 1097 | return S->Name.startswith(".debug") || S->Name.startswith(".zdebug"); | |
| 1098 | }); | |
| 1099 | ||
| 1100 | Config->EFlags = Target->calcEFlags(); | |
| 1101 | ||
| 1102 | if (Config->EMachine == EM_ARM) { | |
| 1103 | // FIXME: These warnings can be removed when lld only uses these features | |
| 1104 | // when the input objects have been compiled with an architecture that | |
| 1105 | // supports them. | |
| 1106 | if (Config->ARMHasBlx == false) | |
| 1107 | warn("lld uses blx instruction, no object with architecture supporting " | |
| 1108 | "feature detected."); | |
| 1109 | if (Config->ARMJ1J2BranchEncoding == false) | |
| 1110 | warn("lld uses extended branch encoding, no object with architecture " | |
| 1111 | "supporting feature detected."); | |
| 1112 | if (Config->ARMHasMovtMovw == false) | |
| 1113 | warn("lld may use movt/movw, no object with architecture supporting " | |
| 1114 | "feature detected."); | |
| 1115 | } | |
| 1116 | ||
| 1045 | 1117 | // This adds a .comment section containing a version string. We have to add it |
| 1046 | 1118 | // before decompressAndMergeSections because the .comment section is a |
| 1047 | 1119 | // mergeable section. |
| 1048 | 1120 | if (!Config->Relocatable) |
| 1049 | InputSections.push_back(createCommentSection<ELFT>()); | |
| 1121 | InputSections.push_back(createCommentSection()); | |
| 1050 | 1122 | |
| 1051 | 1123 | // Do size optimizations: garbage collection, merging of SHF_MERGE sections |
| 1052 | 1124 | // and identical code folding. |
| 1053 | if (Config->GcSections) | |
| 1054 | markLive<ELFT>(); | |
| 1055 | decompressAndMergeSections(); | |
| 1125 | markLive<ELFT>(); | |
| 1126 | decompressSections(); | |
| 1127 | mergeSections(); | |
| 1056 | 1128 | if (Config->ICF) |
| 1057 | 1129 | doIcf<ELFT>(); |
| 1058 | 1130 |
deps/lld/ELF/Driver.h+3-2| ... | ... | @@ -11,8 +11,8 @@ |
| 11 | 11 | #define LLD_ELF_DRIVER_H |
| 12 | 12 | |
| 13 | 13 | #include "SymbolTable.h" |
| 14 | #include "lld/Core/LLVM.h" | |
| 15 | #include "lld/Core/Reproduce.h" | |
| 14 | #include "lld/Common/LLVM.h" | |
| 15 | #include "lld/Common/Reproduce.h" | |
| 16 | 16 | #include "llvm/ADT/Optional.h" |
| 17 | 17 | #include "llvm/ADT/StringRef.h" |
| 18 | 18 | #include "llvm/ADT/StringSet.h" |
| ... | ... | @@ -67,6 +67,7 @@ void printHelp(const char *Argv0); |
| 67 | 67 | std::string createResponseFile(const llvm::opt::InputArgList &Args); |
| 68 | 68 | |
| 69 | 69 | llvm::Optional<std::string> findFromSearchPaths(StringRef Path); |
| 70 | llvm::Optional<std::string> searchLinkerScript(StringRef Path); | |
| 70 | 71 | llvm::Optional<std::string> searchLibrary(StringRef Path); |
| 71 | 72 | |
| 72 | 73 | } // namespace elf |
deps/lld/ELF/DriverUtils.cpp+39-29| ... | ... | @@ -14,10 +14,10 @@ |
| 14 | 14 | //===----------------------------------------------------------------------===// |
| 15 | 15 | |
| 16 | 16 | #include "Driver.h" |
| 17 | #include "Error.h" | |
| 18 | #include "Memory.h" | |
| 19 | #include "lld/Config/Version.h" | |
| 20 | #include "lld/Core/Reproduce.h" | |
| 17 | #include "lld/Common/ErrorHandler.h" | |
| 18 | #include "lld/Common/Memory.h" | |
| 19 | #include "lld/Common/Reproduce.h" | |
| 20 | #include "lld/Common/Version.h" | |
| 21 | 21 | #include "llvm/ADT/Optional.h" |
| 22 | 22 | #include "llvm/ADT/STLExtras.h" |
| 23 | 23 | #include "llvm/ADT/Triple.h" |
| ... | ... | @@ -51,25 +51,26 @@ static const opt::OptTable::Info OptInfo[] = { |
| 51 | 51 | |
| 52 | 52 | ELFOptTable::ELFOptTable() : OptTable(OptInfo) {} |
| 53 | 53 | |
| 54 | // Parse -color-diagnostics={auto,always,never} or -no-color-diagnostics. | |
| 55 | static bool getColorDiagnostics(opt::InputArgList &Args) { | |
| 54 | // Set color diagnostics according to -color-diagnostics={auto,always,never} | |
| 55 | // or -no-color-diagnostics flags. | |
| 56 | static void handleColorDiagnostics(opt::InputArgList &Args) { | |
| 56 | 57 | auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq, |
| 57 | 58 | OPT_no_color_diagnostics); |
| 58 | 59 | if (!Arg) |
| 59 | return ErrorOS->has_colors(); | |
| 60 | if (Arg->getOption().getID() == OPT_color_diagnostics) | |
| 61 | return true; | |
| 62 | if (Arg->getOption().getID() == OPT_no_color_diagnostics) | |
| 63 | return false; | |
| 64 | ||
| 65 | StringRef S = Arg->getValue(); | |
| 66 | if (S == "auto") | |
| 67 | return ErrorOS->has_colors(); | |
| 68 | if (S == "always") | |
| 69 | return true; | |
| 70 | if (S != "never") | |
| 71 | error("unknown option: -color-diagnostics=" + S); | |
| 72 | return false; | |
| 60 | return; | |
| 61 | else if (Arg->getOption().getID() == OPT_color_diagnostics) | |
| 62 | errorHandler().ColorDiagnostics = true; | |
| 63 | else if (Arg->getOption().getID() == OPT_no_color_diagnostics) | |
| 64 | errorHandler().ColorDiagnostics = false; | |
| 65 | else { | |
| 66 | StringRef S = Arg->getValue(); | |
| 67 | if (S == "always") | |
| 68 | errorHandler().ColorDiagnostics = true; | |
| 69 | else if (S == "never") | |
| 70 | errorHandler().ColorDiagnostics = false; | |
| 71 | else if (S != "auto") | |
| 72 | error("unknown option: -color-diagnostics=" + S); | |
| 73 | } | |
| 73 | 74 | } |
| 74 | 75 | |
| 75 | 76 | static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) { |
| ... | ... | @@ -103,9 +104,7 @@ opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) { |
| 103 | 104 | cl::ExpandResponseFiles(Saver, getQuotingStyle(Args), Vec); |
| 104 | 105 | Args = this->ParseArgs(Vec, MissingIndex, MissingCount); |
| 105 | 106 | |
| 106 | // Interpret -color-diagnostics early so that error messages | |
| 107 | // for unknown flags are colored. | |
| 108 | Config->ColorDiagnostics = getColorDiagnostics(Args); | |
| 107 | handleColorDiagnostics(Args); | |
| 109 | 108 | if (MissingCount) |
| 110 | 109 | error(Twine(Args.getArgString(MissingIndex)) + ": missing argument"); |
| 111 | 110 | |
| ... | ... | @@ -115,8 +114,8 @@ opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) { |
| 115 | 114 | } |
| 116 | 115 | |
| 117 | 116 | void elf::printHelp(const char *Argv0) { |
| 118 | ELFOptTable Table; | |
| 119 | Table.PrintHelp(outs(), Argv0, "lld", false); | |
| 117 | ELFOptTable().PrintHelp(outs(), Argv0, "lld", false /*ShowHidden*/, | |
| 118 | true /*ShowAllAliases*/); | |
| 120 | 119 | outs() << "\n"; |
| 121 | 120 | |
| 122 | 121 | // Scripts generated by Libtool versions up to at least 2.4.6 (the most |
| ... | ... | @@ -138,10 +137,11 @@ void elf::printHelp(const char *Argv0) { |
| 138 | 137 | std::string elf::createResponseFile(const opt::InputArgList &Args) { |
| 139 | 138 | SmallString<0> Data; |
| 140 | 139 | raw_svector_ostream OS(Data); |
| 140 | OS << "--chroot .\n"; | |
| 141 | 141 | |
| 142 | 142 | // Copy the command line to the output while rewriting paths. |
| 143 | 143 | for (auto *Arg : Args) { |
| 144 | switch (Arg->getOption().getID()) { | |
| 144 | switch (Arg->getOption().getUnaliasedOption().getID()) { | |
| 145 | 145 | case OPT_reproduce: |
| 146 | 146 | break; |
| 147 | 147 | case OPT_INPUT: |
| ... | ... | @@ -154,17 +154,18 @@ std::string elf::createResponseFile(const opt::InputArgList &Args) { |
| 154 | 154 | // Strip directories to prevent the issue. |
| 155 | 155 | OS << "-o " << quote(sys::path::filename(Arg->getValue())) << "\n"; |
| 156 | 156 | break; |
| 157 | case OPT_L: | |
| 158 | 157 | case OPT_dynamic_list: |
| 158 | case OPT_library_path: | |
| 159 | 159 | case OPT_rpath: |
| 160 | case OPT_alias_script_T: | |
| 161 | 160 | case OPT_script: |
| 161 | case OPT_symbol_ordering_file: | |
| 162 | case OPT_sysroot: | |
| 162 | 163 | case OPT_version_script: |
| 163 | 164 | OS << Arg->getSpelling() << " " << quote(rewritePath(Arg->getValue())) |
| 164 | 165 | << "\n"; |
| 165 | 166 | break; |
| 166 | 167 | default: |
| 167 | OS << toString(Arg) << "\n"; | |
| 168 | OS << toString(*Arg) << "\n"; | |
| 168 | 169 | } |
| 169 | 170 | } |
| 170 | 171 | return Data.str(); |
| ... | ... | @@ -206,3 +207,12 @@ Optional<std::string> elf::searchLibrary(StringRef Name) { |
| 206 | 207 | } |
| 207 | 208 | return None; |
| 208 | 209 | } |
| 210 | ||
| 211 | // If a linker script doesn't exist in the current directory, we also look for | |
| 212 | // the script in the '-L' search paths. This matches the behaviour of both '-T' | |
| 213 | // and linker script INPUT() directives in ld.bfd. | |
| 214 | Optional<std::string> elf::searchLinkerScript(StringRef Name) { | |
| 215 | if (fs::exists(Name)) | |
| 216 | return Name.str(); | |
| 217 | return findFromSearchPaths(Name); | |
| 218 | } |
deps/lld/ELF/EhFrame.cpp+15-27| ... | ... | @@ -17,11 +17,12 @@ |
| 17 | 17 | //===----------------------------------------------------------------------===// |
| 18 | 18 | |
| 19 | 19 | #include "EhFrame.h" |
| 20 | #include "Error.h" | |
| 20 | #include "Config.h" | |
| 21 | 21 | #include "InputSection.h" |
| 22 | 22 | #include "Relocations.h" |
| 23 | 23 | #include "Strings.h" |
| 24 | 24 | |
| 25 | #include "lld/Common/ErrorHandler.h" | |
| 25 | 26 | #include "llvm/BinaryFormat/Dwarf.h" |
| 26 | 27 | #include "llvm/Object/ELF.h" |
| 27 | 28 | #include "llvm/Support/Endian.h" |
| ... | ... | @@ -36,7 +37,7 @@ using namespace lld; |
| 36 | 37 | using namespace lld::elf; |
| 37 | 38 | |
| 38 | 39 | namespace { |
| 39 | template <class ELFT> class EhReader { | |
| 40 | class EhReader { | |
| 40 | 41 | public: |
| 41 | 42 | EhReader(InputSectionBase *S, ArrayRef<uint8_t> D) : IS(S), D(D) {} |
| 42 | 43 | size_t readEhRecordSize(); |
| ... | ... | @@ -45,7 +46,7 @@ public: |
| 45 | 46 | private: |
| 46 | 47 | template <class P> void failOn(const P *Loc, const Twine &Msg) { |
| 47 | 48 | fatal("corrupted .eh_frame: " + Msg + "\n>>> defined in " + |
| 48 | IS->getObjMsg<ELFT>((const uint8_t *)Loc - IS->Data.data())); | |
| 49 | IS->getObjMsg((const uint8_t *)Loc - IS->Data.data())); | |
| 49 | 50 | } |
| 50 | 51 | |
| 51 | 52 | uint8_t readByte(); |
| ... | ... | @@ -59,22 +60,20 @@ private: |
| 59 | 60 | }; |
| 60 | 61 | } |
| 61 | 62 | |
| 62 | template <class ELFT> | |
| 63 | 63 | size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off) { |
| 64 | return EhReader<ELFT>(S, S->Data.slice(Off)).readEhRecordSize(); | |
| 64 | return EhReader(S, S->Data.slice(Off)).readEhRecordSize(); | |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | 67 | // .eh_frame section is a sequence of records. Each record starts with |
| 68 | 68 | // a 4 byte length field. This function reads the length. |
| 69 | template <class ELFT> size_t EhReader<ELFT>::readEhRecordSize() { | |
| 70 | const endianness E = ELFT::TargetEndianness; | |
| 69 | size_t EhReader::readEhRecordSize() { | |
| 71 | 70 | if (D.size() < 4) |
| 72 | 71 | failOn(D.data(), "CIE/FDE too small"); |
| 73 | 72 | |
| 74 | 73 | // First 4 bytes of CIE/FDE is the size of the record. |
| 75 | 74 | // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead, |
| 76 | 75 | // but we do not support that format yet. |
| 77 | uint64_t V = read32<E>(D.data()); | |
| 76 | uint64_t V = read32(D.data(), Config->Endianness); | |
| 78 | 77 | if (V == UINT32_MAX) |
| 79 | 78 | failOn(D.data(), "CIE/FDE too large"); |
| 80 | 79 | uint64_t Size = V + 4; |
| ... | ... | @@ -84,7 +83,7 @@ template <class ELFT> size_t EhReader<ELFT>::readEhRecordSize() { |
| 84 | 83 | } |
| 85 | 84 | |
| 86 | 85 | // Read a byte and advance D by one byte. |
| 87 | template <class ELFT> uint8_t EhReader<ELFT>::readByte() { | |
| 86 | uint8_t EhReader::readByte() { | |
| 88 | 87 | if (D.empty()) |
| 89 | 88 | failOn(D.data(), "unexpected end of CIE"); |
| 90 | 89 | uint8_t B = D.front(); |
| ... | ... | @@ -92,14 +91,14 @@ template <class ELFT> uint8_t EhReader<ELFT>::readByte() { |
| 92 | 91 | return B; |
| 93 | 92 | } |
| 94 | 93 | |
| 95 | template <class ELFT> void EhReader<ELFT>::skipBytes(size_t Count) { | |
| 94 | void EhReader::skipBytes(size_t Count) { | |
| 96 | 95 | if (D.size() < Count) |
| 97 | 96 | failOn(D.data(), "CIE is too small"); |
| 98 | 97 | D = D.slice(Count); |
| 99 | 98 | } |
| 100 | 99 | |
| 101 | 100 | // Read a null-terminated string. |
| 102 | template <class ELFT> StringRef EhReader<ELFT>::readString() { | |
| 101 | StringRef EhReader::readString() { | |
| 103 | 102 | const uint8_t *End = std::find(D.begin(), D.end(), '\0'); |
| 104 | 103 | if (End == D.end()) |
| 105 | 104 | failOn(D.data(), "corrupted CIE (failed to read string)"); |
| ... | ... | @@ -112,7 +111,7 @@ template <class ELFT> StringRef EhReader<ELFT>::readString() { |
| 112 | 111 | // Actual number is not of interest because only the runtime needs it. |
| 113 | 112 | // But we need to be at least able to skip it so that we can read |
| 114 | 113 | // the field that follows a LEB128 number. |
| 115 | template <class ELFT> void EhReader<ELFT>::skipLeb128() { | |
| 114 | void EhReader::skipLeb128() { | |
| 116 | 115 | const uint8_t *ErrPos = D.data(); |
| 117 | 116 | while (!D.empty()) { |
| 118 | 117 | uint8_t Val = D.front(); |
| ... | ... | @@ -141,7 +140,7 @@ static size_t getAugPSize(unsigned Enc) { |
| 141 | 140 | return 0; |
| 142 | 141 | } |
| 143 | 142 | |
| 144 | template <class ELFT> void EhReader<ELFT>::skipAugP() { | |
| 143 | void EhReader::skipAugP() { | |
| 145 | 144 | uint8_t Enc = readByte(); |
| 146 | 145 | if ((Enc & 0xf0) == DW_EH_PE_aligned) |
| 147 | 146 | failOn(D.data() - 1, "DW_EH_PE_aligned encoding is not supported"); |
| ... | ... | @@ -153,12 +152,11 @@ template <class ELFT> void EhReader<ELFT>::skipAugP() { |
| 153 | 152 | D = D.slice(Size); |
| 154 | 153 | } |
| 155 | 154 | |
| 156 | template <class ELFT> uint8_t elf::getFdeEncoding(EhSectionPiece *P) { | |
| 157 | auto *IS = static_cast<InputSectionBase *>(P->ID); | |
| 158 | return EhReader<ELFT>(IS, P->data()).getFdeEncoding(); | |
| 155 | uint8_t elf::getFdeEncoding(EhSectionPiece *P) { | |
| 156 | return EhReader(P->Sec, P->data()).getFdeEncoding(); | |
| 159 | 157 | } |
| 160 | 158 | |
| 161 | template <class ELFT> uint8_t EhReader<ELFT>::getFdeEncoding() { | |
| 159 | uint8_t EhReader::getFdeEncoding() { | |
| 162 | 160 | skipBytes(8); |
| 163 | 161 | int Version = readByte(); |
| 164 | 162 | if (Version != 1 && Version != 3) |
| ... | ... | @@ -200,13 +198,3 @@ template <class ELFT> uint8_t EhReader<ELFT>::getFdeEncoding() { |
| 200 | 198 | } |
| 201 | 199 | return DW_EH_PE_absptr; |
| 202 | 200 | } |
| 203 | ||
| 204 | template size_t elf::readEhRecordSize<ELF32LE>(InputSectionBase *S, size_t Off); | |
| 205 | template size_t elf::readEhRecordSize<ELF32BE>(InputSectionBase *S, size_t Off); | |
| 206 | template size_t elf::readEhRecordSize<ELF64LE>(InputSectionBase *S, size_t Off); | |
| 207 | template size_t elf::readEhRecordSize<ELF64BE>(InputSectionBase *S, size_t Off); | |
| 208 | ||
| 209 | template uint8_t elf::getFdeEncoding<ELF32LE>(EhSectionPiece *P); | |
| 210 | template uint8_t elf::getFdeEncoding<ELF32BE>(EhSectionPiece *P); | |
| 211 | template uint8_t elf::getFdeEncoding<ELF64LE>(EhSectionPiece *P); | |
| 212 | template uint8_t elf::getFdeEncoding<ELF64BE>(EhSectionPiece *P); |
deps/lld/ELF/EhFrame.h+3-3| ... | ... | @@ -10,15 +10,15 @@ |
| 10 | 10 | #ifndef LLD_ELF_EHFRAME_H |
| 11 | 11 | #define LLD_ELF_EHFRAME_H |
| 12 | 12 | |
| 13 | #include "lld/Core/LLVM.h" | |
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | 14 | |
| 15 | 15 | namespace lld { |
| 16 | 16 | namespace elf { |
| 17 | 17 | class InputSectionBase; |
| 18 | 18 | struct EhSectionPiece; |
| 19 | 19 | |
| 20 | template <class ELFT> size_t readEhRecordSize(InputSectionBase *S, size_t Off); | |
| 21 | template <class ELFT> uint8_t getFdeEncoding(EhSectionPiece *P); | |
| 20 | size_t readEhRecordSize(InputSectionBase *S, size_t Off); | |
| 21 | uint8_t getFdeEncoding(EhSectionPiece *P); | |
| 22 | 22 | } // namespace elf |
| 23 | 23 | } // namespace lld |
| 24 | 24 |
deps/lld/ELF/Error.cpp deleted-116| ... | ... | @@ -1,116 +0,0 @@ |
| 1 | //===- Error.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 "Error.h" | |
| 11 | #include "Config.h" | |
| 12 | ||
| 13 | #include "llvm/ADT/Twine.h" | |
| 14 | #include "llvm/Support/Error.h" | |
| 15 | #include "llvm/Support/ManagedStatic.h" | |
| 16 | #include "llvm/Support/raw_ostream.h" | |
| 17 | #include <mutex> | |
| 18 | ||
| 19 | #if !defined(_MSC_VER) && !defined(__MINGW32__) | |
| 20 | #include <unistd.h> | |
| 21 | #endif | |
| 22 | ||
| 23 | using namespace llvm; | |
| 24 | ||
| 25 | using namespace lld; | |
| 26 | using namespace lld::elf; | |
| 27 | ||
| 28 | uint64_t elf::ErrorCount; | |
| 29 | raw_ostream *elf::ErrorOS; | |
| 30 | ||
| 31 | // The functions defined in this file can be called from multiple threads, | |
| 32 | // but outs() or errs() are not thread-safe. We protect them using a mutex. | |
| 33 | static std::mutex Mu; | |
| 34 | ||
| 35 | // Prints "\n" or does nothing, depending on Msg contents of | |
| 36 | // the previous call of this function. | |
| 37 | static void newline(const Twine &Msg) { | |
| 38 | // True if the previous error message contained "\n". | |
| 39 | // We want to separate multi-line error messages with a newline. | |
| 40 | static bool Flag; | |
| 41 | ||
| 42 | if (Flag) | |
| 43 | *ErrorOS << "\n"; | |
| 44 | Flag = (StringRef(Msg.str()).find('\n') != StringRef::npos); | |
| 45 | } | |
| 46 | ||
| 47 | static void print(StringRef S, raw_ostream::Colors C) { | |
| 48 | *ErrorOS << Config->Argv[0] << ": "; | |
| 49 | if (Config->ColorDiagnostics) { | |
| 50 | ErrorOS->changeColor(C, true); | |
| 51 | *ErrorOS << S; | |
| 52 | ErrorOS->resetColor(); | |
| 53 | } else { | |
| 54 | *ErrorOS << S; | |
| 55 | } | |
| 56 | } | |
| 57 | ||
| 58 | void elf::log(const Twine &Msg) { | |
| 59 | if (Config->Verbose) { | |
| 60 | std::lock_guard<std::mutex> Lock(Mu); | |
| 61 | outs() << Config->Argv[0] << ": " << Msg << "\n"; | |
| 62 | outs().flush(); | |
| 63 | } | |
| 64 | } | |
| 65 | ||
| 66 | void elf::message(const Twine &Msg) { | |
| 67 | std::lock_guard<std::mutex> Lock(Mu); | |
| 68 | outs() << Msg << "\n"; | |
| 69 | outs().flush(); | |
| 70 | } | |
| 71 | ||
| 72 | void elf::warn(const Twine &Msg) { | |
| 73 | if (Config->FatalWarnings) { | |
| 74 | error(Msg); | |
| 75 | return; | |
| 76 | } | |
| 77 | ||
| 78 | std::lock_guard<std::mutex> Lock(Mu); | |
| 79 | newline(Msg); | |
| 80 | print("warning: ", raw_ostream::MAGENTA); | |
| 81 | *ErrorOS << Msg << "\n"; | |
| 82 | } | |
| 83 | ||
| 84 | void elf::error(const Twine &Msg) { | |
| 85 | std::lock_guard<std::mutex> Lock(Mu); | |
| 86 | newline(Msg); | |
| 87 | ||
| 88 | if (Config->ErrorLimit == 0 || ErrorCount < Config->ErrorLimit) { | |
| 89 | print("error: ", raw_ostream::RED); | |
| 90 | *ErrorOS << Msg << "\n"; | |
| 91 | } else if (ErrorCount == Config->ErrorLimit) { | |
| 92 | print("error: ", raw_ostream::RED); | |
| 93 | *ErrorOS << "too many errors emitted, stopping now" | |
| 94 | << " (use -error-limit=0 to see all errors)\n"; | |
| 95 | if (Config->ExitEarly) | |
| 96 | exitLld(1); | |
| 97 | } | |
| 98 | ||
| 99 | ++ErrorCount; | |
| 100 | } | |
| 101 | ||
| 102 | void elf::exitLld(int Val) { | |
| 103 | // Dealloc/destroy ManagedStatic variables before calling | |
| 104 | // _exit(). In a non-LTO build, this is a nop. In an LTO | |
| 105 | // build allows us to get the output of -time-passes. | |
| 106 | llvm_shutdown(); | |
| 107 | ||
| 108 | outs().flush(); | |
| 109 | errs().flush(); | |
| 110 | _exit(Val); | |
| 111 | } | |
| 112 | ||
| 113 | void elf::fatal(const Twine &Msg) { | |
| 114 | error(Msg); | |
| 115 | exitLld(1); | |
| 116 | } |
deps/lld/ELF/Error.h deleted-78| ... | ... | @@ -1,78 +0,0 @@ |
| 1 | //===- Error.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 | // In LLD, we have three levels of errors: fatal, error or warn. | |
| 11 | // | |
| 12 | // Fatal makes the program exit immediately with an error message. | |
| 13 | // You shouldn't use it except for reporting a corrupted input file. | |
| 14 | // | |
| 15 | // Error prints out an error message and increment a global variable | |
| 16 | // ErrorCount to record the fact that we met an error condition. It does | |
| 17 | // not exit, so it is safe for a lld-as-a-library use case. It is generally | |
| 18 | // useful because it can report more than one error in a single run. | |
| 19 | // | |
| 20 | // Warn doesn't do anything but printing out a given message. | |
| 21 | // | |
| 22 | // It is not recommended to use llvm::outs() or llvm::errs() directly | |
| 23 | // in LLD because they are not thread-safe. The functions declared in | |
| 24 | // this file are mutually excluded, so you want to use them instead. | |
| 25 | // | |
| 26 | //===----------------------------------------------------------------------===// | |
| 27 | ||
| 28 | #ifndef LLD_ELF_ERROR_H | |
| 29 | #define LLD_ELF_ERROR_H | |
| 30 | ||
| 31 | #include "lld/Core/LLVM.h" | |
| 32 | ||
| 33 | #include "llvm/Support/Error.h" | |
| 34 | ||
| 35 | namespace lld { | |
| 36 | namespace elf { | |
| 37 | ||
| 38 | extern uint64_t ErrorCount; | |
| 39 | extern llvm::raw_ostream *ErrorOS; | |
| 40 | ||
| 41 | void log(const Twine &Msg); | |
| 42 | void message(const Twine &Msg); | |
| 43 | void warn(const Twine &Msg); | |
| 44 | void error(const Twine &Msg); | |
| 45 | LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg); | |
| 46 | ||
| 47 | LLVM_ATTRIBUTE_NORETURN void exitLld(int Val); | |
| 48 | ||
| 49 | // check() functions are convenient functions to strip errors | |
| 50 | // from error-or-value objects. | |
| 51 | template <class T> T check(ErrorOr<T> E) { | |
| 52 | if (auto EC = E.getError()) | |
| 53 | fatal(EC.message()); | |
| 54 | return std::move(*E); | |
| 55 | } | |
| 56 | ||
| 57 | template <class T> T check(Expected<T> E) { | |
| 58 | if (!E) | |
| 59 | fatal(llvm::toString(E.takeError())); | |
| 60 | return std::move(*E); | |
| 61 | } | |
| 62 | ||
| 63 | template <class T> T check(ErrorOr<T> E, const Twine &Prefix) { | |
| 64 | if (auto EC = E.getError()) | |
| 65 | fatal(Prefix + ": " + EC.message()); | |
| 66 | return std::move(*E); | |
| 67 | } | |
| 68 | ||
| 69 | template <class T> T check(Expected<T> E, const Twine &Prefix) { | |
| 70 | if (!E) | |
| 71 | fatal(Prefix + ": " + toString(E.takeError())); | |
| 72 | return std::move(*E); | |
| 73 | } | |
| 74 | ||
| 75 | } // namespace elf | |
| 76 | } // namespace lld | |
| 77 | ||
| 78 | #endif |
deps/lld/ELF/Filesystem.cpp+27-18| ... | ... | @@ -13,8 +13,13 @@ |
| 13 | 13 | |
| 14 | 14 | #include "Filesystem.h" |
| 15 | 15 | #include "Config.h" |
| 16 | #include "llvm/Support/FileSystem.h" | |
| 16 | #include "lld/Common/Threads.h" | |
| 17 | #include "llvm/Config/llvm-config.h" | |
| 17 | 18 | #include "llvm/Support/FileOutputBuffer.h" |
| 19 | #include "llvm/Support/FileSystem.h" | |
| 20 | #if LLVM_ON_UNIX | |
| 21 | #include <unistd.h> | |
| 22 | #endif | |
| 18 | 23 | #include <thread> |
| 19 | 24 | |
| 20 | 25 | using namespace llvm; |
| ... | ... | @@ -35,27 +40,29 @@ using namespace lld::elf; |
| 35 | 40 | // Since LLD can link a 1 GB binary in about 5 seconds, that waste |
| 36 | 41 | // actually counts. |
| 37 | 42 | // |
| 38 | // This function spawns a background thread to call unlink. | |
| 43 | // This function spawns a background thread to remove the file. | |
| 39 | 44 | // The calling thread returns almost immediately. |
| 40 | 45 | void elf::unlinkAsync(StringRef Path) { |
| 41 | if (!Config->Threads || !sys::fs::exists(Config->OutputFile) || | |
| 42 | !sys::fs::is_regular_file(Config->OutputFile)) | |
| 46 | // Removing a file is async on windows. | |
| 47 | #if defined(LLVM_ON_WIN32) | |
| 48 | sys::fs::remove(Path); | |
| 49 | #else | |
| 50 | if (!ThreadsEnabled || !sys::fs::exists(Path) || | |
| 51 | !sys::fs::is_regular_file(Path)) | |
| 43 | 52 | return; |
| 44 | 53 | |
| 45 | // First, rename Path to avoid race condition. We cannot remove | |
| 46 | // Path from a different thread because we are now going to create | |
| 47 | // Path as a new file. If we do that in a different thread, the new | |
| 48 | // thread can remove the new file. | |
| 49 | SmallString<128> TempPath; | |
| 50 | if (sys::fs::createUniqueFile(Path + "tmp%%%%%%%%", TempPath)) | |
| 51 | return; | |
| 52 | if (sys::fs::rename(Path, TempPath)) { | |
| 53 | sys::fs::remove(TempPath); | |
| 54 | return; | |
| 55 | } | |
| 54 | // We cannot just remove path from a different thread because we are now going | |
| 55 | // to create path as a new file. | |
| 56 | // Instead we open the file and unlink it on this thread. The unlink is fast | |
| 57 | // since the open fd guarantees that it is not removing the last reference. | |
| 58 | int FD; | |
| 59 | std::error_code EC = sys::fs::openFileForRead(Path, FD); | |
| 60 | sys::fs::remove(Path); | |
| 56 | 61 | |
| 57 | // Remove TempPath in background. | |
| 58 | std::thread([=] { ::remove(TempPath.str().str().c_str()); }).detach(); | |
| 62 | // close and therefore remove TempPath in background. | |
| 63 | if (!EC) | |
| 64 | std::thread([=] { ::close(FD); }).detach(); | |
| 65 | #endif | |
| 59 | 66 | } |
| 60 | 67 | |
| 61 | 68 | // Simulate file creation to see if Path is writable. |
| ... | ... | @@ -73,5 +80,7 @@ void elf::unlinkAsync(StringRef Path) { |
| 73 | 80 | std::error_code elf::tryCreateFile(StringRef Path) { |
| 74 | 81 | if (Path.empty()) |
| 75 | 82 | return std::error_code(); |
| 76 | return FileOutputBuffer::create(Path, 1).getError(); | |
| 83 | if (Path == "-") | |
| 84 | return std::error_code(); | |
| 85 | return errorToErrorCode(FileOutputBuffer::create(Path, 1).takeError()); | |
| 77 | 86 | } |
deps/lld/ELF/Filesystem.h+2-1| ... | ... | @@ -10,7 +10,8 @@ |
| 10 | 10 | #ifndef LLD_ELF_FILESYSTEM_H |
| 11 | 11 | #define LLD_ELF_FILESYSTEM_H |
| 12 | 12 | |
| 13 | #include "lld/Core/LLVM.h" | |
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | #include <system_error> | |
| 14 | 15 | |
| 15 | 16 | namespace lld { |
| 16 | 17 | namespace elf { |
deps/lld/ELF/GdbIndex.cpp+70-18| ... | ... | @@ -15,7 +15,8 @@ |
| 15 | 15 | //===----------------------------------------------------------------------===// |
| 16 | 16 | |
| 17 | 17 | #include "GdbIndex.h" |
| 18 | #include "Memory.h" | |
| 18 | #include "Symbols.h" | |
| 19 | #include "lld/Common/Memory.h" | |
| 19 | 20 | #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h" |
| 20 | 21 | #include "llvm/Object/ELFObjectFile.h" |
| 21 | 22 | |
| ... | ... | @@ -24,26 +25,77 @@ using namespace llvm::object; |
| 24 | 25 | using namespace lld; |
| 25 | 26 | using namespace lld::elf; |
| 26 | 27 | |
| 27 | std::pair<bool, GdbSymbol *> GdbHashTab::add(uint32_t Hash, size_t Offset) { | |
| 28 | GdbSymbol *&Sym = Map[Offset]; | |
| 29 | if (Sym) | |
| 30 | return {false, Sym}; | |
| 31 | Sym = make<GdbSymbol>(Hash, Offset); | |
| 32 | return {true, Sym}; | |
| 28 | template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *Obj) { | |
| 29 | for (InputSectionBase *Sec : Obj->getSections()) { | |
| 30 | if (!Sec) | |
| 31 | continue; | |
| 32 | if (LLDDWARFSection *M = StringSwitch<LLDDWARFSection *>(Sec->Name) | |
| 33 | .Case(".debug_info", &InfoSection) | |
| 34 | .Case(".debug_ranges", &RangeSection) | |
| 35 | .Case(".debug_line", &LineSection) | |
| 36 | .Default(nullptr)) { | |
| 37 | Sec->maybeUncompress(); | |
| 38 | M->Data = toStringRef(Sec->Data); | |
| 39 | M->Sec = Sec; | |
| 40 | continue; | |
| 41 | } | |
| 42 | if (Sec->Name == ".debug_abbrev") | |
| 43 | AbbrevSection = toStringRef(Sec->Data); | |
| 44 | else if (Sec->Name == ".debug_gnu_pubnames") | |
| 45 | GnuPubNamesSection = toStringRef(Sec->Data); | |
| 46 | else if (Sec->Name == ".debug_gnu_pubtypes") | |
| 47 | GnuPubTypesSection = toStringRef(Sec->Data); | |
| 48 | else if (Sec->Name == ".debug_str") | |
| 49 | StrSection = toStringRef(Sec->Data); | |
| 50 | } | |
| 33 | 51 | } |
| 34 | 52 | |
| 35 | void GdbHashTab::finalizeContents() { | |
| 36 | uint32_t Size = std::max<uint32_t>(1024, NextPowerOf2(Map.size() * 4 / 3)); | |
| 37 | uint32_t Mask = Size - 1; | |
| 38 | Table.resize(Size); | |
| 53 | // Find if there is a relocation at Pos in Sec. The code is a bit | |
| 54 | // more complicated than usual because we need to pass a section index | |
| 55 | // to llvm since it has no idea about InputSection. | |
| 56 | template <class ELFT> | |
| 57 | template <class RelTy> | |
| 58 | Optional<RelocAddrEntry> | |
| 59 | LLDDwarfObj<ELFT>::findAux(const InputSectionBase &Sec, uint64_t Pos, | |
| 60 | ArrayRef<RelTy> Rels) const { | |
| 61 | auto It = std::lower_bound( | |
| 62 | Rels.begin(), Rels.end(), Pos, | |
| 63 | [](const RelTy &A, uint64_t B) { return A.r_offset < B; }); | |
| 64 | if (It == Rels.end() || It->r_offset != Pos) | |
| 65 | return None; | |
| 66 | const RelTy &Rel = *It; | |
| 39 | 67 | |
| 40 | for (auto &P : Map) { | |
| 41 | GdbSymbol *Sym = P.second; | |
| 42 | uint32_t I = Sym->NameHash & Mask; | |
| 43 | uint32_t Step = ((Sym->NameHash * 17) & Mask) | 1; | |
| 68 | const ObjFile<ELFT> *File = Sec.getFile<ELFT>(); | |
| 69 | uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL); | |
| 70 | const typename ELFT::Sym &Sym = File->getELFSyms()[SymIndex]; | |
| 71 | uint32_t SecIndex = File->getSectionIndex(Sym); | |
| 44 | 72 | |
| 45 | while (Table[I]) | |
| 46 | I = (I + Step) & Mask; | |
| 47 | Table[I] = Sym; | |
| 73 | // Broken debug info can point to a non-Defined symbol. | |
| 74 | auto *DR = dyn_cast<Defined>(&File->getRelocTargetSym(Rel)); | |
| 75 | if (!DR) { | |
| 76 | error("unsupported relocation target while parsing debug info"); | |
| 77 | return None; | |
| 48 | 78 | } |
| 79 | uint64_t Val = DR->Value + getAddend<ELFT>(Rel); | |
| 80 | ||
| 81 | // FIXME: We should be consistent about always adding the file | |
| 82 | // offset or not. | |
| 83 | if (DR->Section->Flags & ELF::SHF_ALLOC) | |
| 84 | Val += cast<InputSection>(DR->Section)->getOffsetInFile(); | |
| 85 | ||
| 86 | return RelocAddrEntry{SecIndex, Val}; | |
| 49 | 87 | } |
| 88 | ||
| 89 | template <class ELFT> | |
| 90 | Optional<RelocAddrEntry> LLDDwarfObj<ELFT>::find(const llvm::DWARFSection &S, | |
| 91 | uint64_t Pos) const { | |
| 92 | auto &Sec = static_cast<const LLDDWARFSection &>(S); | |
| 93 | if (Sec.Sec->AreRelocsRela) | |
| 94 | return findAux(*Sec.Sec, Pos, Sec.Sec->template relas<ELFT>()); | |
| 95 | return findAux(*Sec.Sec, Pos, Sec.Sec->template rels<ELFT>()); | |
| 96 | } | |
| 97 | ||
| 98 | template class elf::LLDDwarfObj<ELF32LE>; | |
| 99 | template class elf::LLDDwarfObj<ELF32BE>; | |
| 100 | template class elf::LLDDwarfObj<ELF64LE>; | |
| 101 | template class elf::LLDDwarfObj<ELF64BE>; |
deps/lld/ELF/GdbIndex.h+39-50| ... | ... | @@ -19,61 +19,50 @@ namespace elf { |
| 19 | 19 | |
| 20 | 20 | class InputSection; |
| 21 | 21 | |
| 22 | // Struct represents single entry of address area of gdb index. | |
| 23 | struct AddressEntry { | |
| 24 | InputSection *Section; | |
| 25 | uint64_t LowAddress; | |
| 26 | uint64_t HighAddress; | |
| 27 | uint32_t CuIndex; | |
| 22 | struct LLDDWARFSection final : public llvm::DWARFSection { | |
| 23 | InputSectionBase *Sec = nullptr; | |
| 28 | 24 | }; |
| 29 | 25 | |
| 30 | // Struct represents single entry of compilation units list area of gdb index. | |
| 31 | // It consist of CU offset in .debug_info section and it's size. | |
| 32 | struct CompilationUnitEntry { | |
| 33 | uint64_t CuOffset; | |
| 34 | uint64_t CuLength; | |
| 35 | }; | |
| 36 | ||
| 37 | // Represents data about symbol and type names which are used | |
| 38 | // to build symbol table and constant pool area of gdb index. | |
| 39 | struct NameTypeEntry { | |
| 40 | StringRef Name; | |
| 41 | uint8_t Type; | |
| 42 | }; | |
| 43 | ||
| 44 | // We fill one GdbIndexDataChunk for each object where scan of | |
| 45 | // debug information performed. That information futher used | |
| 46 | // for filling gdb index section areas. | |
| 47 | struct GdbIndexChunk { | |
| 48 | InputSection *DebugInfoSec; | |
| 49 | std::vector<AddressEntry> AddressArea; | |
| 50 | std::vector<CompilationUnitEntry> CompilationUnits; | |
| 51 | std::vector<NameTypeEntry> NamesAndTypes; | |
| 52 | }; | |
| 26 | template <class ELFT> class LLDDwarfObj final : public llvm::DWARFObject { | |
| 27 | LLDDWARFSection InfoSection; | |
| 28 | LLDDWARFSection RangeSection; | |
| 29 | LLDDWARFSection LineSection; | |
| 30 | StringRef AbbrevSection; | |
| 31 | StringRef GnuPubNamesSection; | |
| 32 | StringRef GnuPubTypesSection; | |
| 33 | StringRef StrSection; | |
| 53 | 34 | |
| 54 | // Element of GdbHashTab hash table. | |
| 55 | struct GdbSymbol { | |
| 56 | GdbSymbol(uint32_t Hash, size_t Offset) | |
| 57 | : NameHash(Hash), NameOffset(Offset) {} | |
| 58 | uint32_t NameHash; | |
| 59 | size_t NameOffset; | |
| 60 | size_t CuVectorIndex; | |
| 61 | }; | |
| 35 | template <class RelTy> | |
| 36 | llvm::Optional<llvm::RelocAddrEntry> findAux(const InputSectionBase &Sec, | |
| 37 | uint64_t Pos, | |
| 38 | ArrayRef<RelTy> Rels) const; | |
| 62 | 39 | |
| 63 | // This class manages the hashed symbol table for the .gdb_index section. | |
| 64 | // The hash value for a table entry is computed by applying an iterative hash | |
| 65 | // function to the symbol's name. | |
| 66 | class GdbHashTab final { | |
| 67 | 40 | public: |
| 68 | std::pair<bool, GdbSymbol *> add(uint32_t Hash, size_t Offset); | |
| 69 | ||
| 70 | void finalizeContents(); | |
| 71 | size_t getCapacity() { return Table.size(); } | |
| 72 | GdbSymbol *getSymbol(size_t I) { return Table[I]; } | |
| 73 | ||
| 74 | private: | |
| 75 | llvm::DenseMap<size_t, GdbSymbol *> Map; | |
| 76 | std::vector<GdbSymbol *> Table; | |
| 41 | explicit LLDDwarfObj(ObjFile<ELFT> *Obj); | |
| 42 | const llvm::DWARFSection &getInfoSection() const override { | |
| 43 | return InfoSection; | |
| 44 | } | |
| 45 | const llvm::DWARFSection &getRangeSection() const override { | |
| 46 | return RangeSection; | |
| 47 | } | |
| 48 | const llvm::DWARFSection &getLineSection() const override { | |
| 49 | return LineSection; | |
| 50 | } | |
| 51 | StringRef getFileName() const override { return ""; } | |
| 52 | StringRef getCUIndexSection() const override { return ""; } | |
| 53 | StringRef getAbbrevSection() const override { return AbbrevSection; } | |
| 54 | StringRef getStringSection() const override { return StrSection; } | |
| 55 | StringRef getGnuPubNamesSection() const override { | |
| 56 | return GnuPubNamesSection; | |
| 57 | } | |
| 58 | StringRef getGnuPubTypesSection() const override { | |
| 59 | return GnuPubTypesSection; | |
| 60 | } | |
| 61 | bool isLittleEndian() const override { | |
| 62 | return ELFT::TargetEndianness == llvm::support::little; | |
| 63 | } | |
| 64 | llvm::Optional<llvm::RelocAddrEntry> find(const llvm::DWARFSection &Sec, | |
| 65 | uint64_t Pos) const override; | |
| 77 | 66 | }; |
| 78 | 67 | |
| 79 | 68 | } // namespace elf |
deps/lld/ELF/ICF.cpp+59-40| ... | ... | @@ -76,7 +76,8 @@ |
| 76 | 76 | #include "ICF.h" |
| 77 | 77 | #include "Config.h" |
| 78 | 78 | #include "SymbolTable.h" |
| 79 | #include "Threads.h" | |
| 79 | #include "Symbols.h" | |
| 80 | #include "lld/Common/Threads.h" | |
| 80 | 81 | #include "llvm/ADT/Hashing.h" |
| 81 | 82 | #include "llvm/BinaryFormat/ELF.h" |
| 82 | 83 | #include "llvm/Object/ELF.h" |
| ... | ... | @@ -155,16 +156,20 @@ private: |
| 155 | 156 | // Returns a hash value for S. Note that the information about |
| 156 | 157 | // relocation targets is not included in the hash value. |
| 157 | 158 | template <class ELFT> static uint32_t getHash(InputSection *S) { |
| 158 | return hash_combine(S->Flags, S->getSize(), S->NumRelocations); | |
| 159 | return hash_combine(S->Flags, S->getSize(), S->NumRelocations, S->Data); | |
| 159 | 160 | } |
| 160 | 161 | |
| 161 | 162 | // Returns true if section S is subject of ICF. |
| 162 | 163 | static bool isEligible(InputSection *S) { |
| 164 | // Don't merge read only data sections unless --icf-data was passed. | |
| 165 | if (!(S->Flags & SHF_EXECINSTR) && !Config->ICFData) | |
| 166 | return false; | |
| 167 | ||
| 163 | 168 | // .init and .fini contains instructions that must be executed to |
| 164 | 169 | // initialize and finalize the process. They cannot and should not |
| 165 | 170 | // be merged. |
| 166 | return S->Live && (S->Flags & SHF_ALLOC) && (S->Flags & SHF_EXECINSTR) && | |
| 167 | !(S->Flags & SHF_WRITE) && S->Name != ".init" && S->Name != ".fini"; | |
| 171 | return S->Live && (S->Flags & SHF_ALLOC) && !(S->Flags & SHF_WRITE) && | |
| 172 | S->Name != ".init" && S->Name != ".fini"; | |
| 168 | 173 | } |
| 169 | 174 | |
| 170 | 175 | // Split an equivalence class into smaller classes. |
| ... | ... | @@ -207,38 +212,49 @@ void ICF<ELFT>::segregate(size_t Begin, size_t End, bool Constant) { |
| 207 | 212 | // Compare two lists of relocations. |
| 208 | 213 | template <class ELFT> |
| 209 | 214 | template <class RelTy> |
| 210 | bool ICF<ELFT>::constantEq(const InputSection *A, ArrayRef<RelTy> RelsA, | |
| 211 | const InputSection *B, ArrayRef<RelTy> RelsB) { | |
| 212 | auto Eq = [&](const RelTy &RA, const RelTy &RB) { | |
| 213 | if (RA.r_offset != RB.r_offset || | |
| 214 | RA.getType(Config->IsMips64EL) != RB.getType(Config->IsMips64EL)) | |
| 215 | bool ICF<ELFT>::constantEq(const InputSection *SecA, ArrayRef<RelTy> RA, | |
| 216 | 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) { | |
| 221 | if (RA[I].r_offset != RB[I].r_offset || | |
| 222 | RA[I].getType(Config->IsMips64EL) != RB[I].getType(Config->IsMips64EL)) | |
| 215 | 223 | return false; |
| 216 | uint64_t AddA = getAddend<ELFT>(RA); | |
| 217 | uint64_t AddB = getAddend<ELFT>(RB); | |
| 218 | 224 | |
| 219 | SymbolBody &SA = A->template getFile<ELFT>()->getRelocTargetSym(RA); | |
| 220 | SymbolBody &SB = B->template getFile<ELFT>()->getRelocTargetSym(RB); | |
| 221 | if (&SA == &SB) | |
| 222 | return AddA == AddB; | |
| 225 | uint64_t AddA = getAddend<ELFT>(RA[I]); | |
| 226 | uint64_t AddB = getAddend<ELFT>(RB[I]); | |
| 223 | 227 | |
| 224 | auto *DA = dyn_cast<DefinedRegular>(&SA); | |
| 225 | auto *DB = dyn_cast<DefinedRegular>(&SB); | |
| 228 | Symbol &SA = SecA->template getFile<ELFT>()->getRelocTargetSym(RA[I]); | |
| 229 | Symbol &SB = SecB->template getFile<ELFT>()->getRelocTargetSym(RB[I]); | |
| 230 | if (&SA == &SB) { | |
| 231 | if (AddA == AddB) | |
| 232 | continue; | |
| 233 | return false; | |
| 234 | } | |
| 235 | ||
| 236 | auto *DA = dyn_cast<Defined>(&SA); | |
| 237 | auto *DB = dyn_cast<Defined>(&SB); | |
| 226 | 238 | if (!DA || !DB) |
| 227 | 239 | return false; |
| 228 | 240 | |
| 229 | 241 | // Relocations referring to absolute symbols are constant-equal if their |
| 230 | 242 | // values are equal. |
| 243 | if (!DA->Section && !DB->Section && DA->Value + AddA == DB->Value + AddB) | |
| 244 | continue; | |
| 231 | 245 | if (!DA->Section || !DB->Section) |
| 232 | return !DA->Section && !DB->Section && | |
| 233 | DA->Value + AddA == DB->Value + AddB; | |
| 246 | return false; | |
| 234 | 247 | |
| 235 | 248 | if (DA->Section->kind() != DB->Section->kind()) |
| 236 | 249 | return false; |
| 237 | 250 | |
| 238 | 251 | // Relocations referring to InputSections are constant-equal if their |
| 239 | 252 | // section offsets are equal. |
| 240 | if (isa<InputSection>(DA->Section)) | |
| 241 | return DA->Value + AddA == DB->Value + AddB; | |
| 253 | if (isa<InputSection>(DA->Section)) { | |
| 254 | if (DA->Value + AddA == DB->Value + AddB) | |
| 255 | continue; | |
| 256 | return false; | |
| 257 | } | |
| 242 | 258 | |
| 243 | 259 | // Relocations referring to MergeInputSections are constant-equal if their |
| 244 | 260 | // offsets in the output section are equal. |
| ... | ... | @@ -253,11 +269,11 @@ bool ICF<ELFT>::constantEq(const InputSection *A, ArrayRef<RelTy> RelsA, |
| 253 | 269 | SA.isSection() ? X->getOffset(AddA) : X->getOffset(DA->Value) + AddA; |
| 254 | 270 | uint64_t OffsetB = |
| 255 | 271 | SB.isSection() ? Y->getOffset(AddB) : Y->getOffset(DB->Value) + AddB; |
| 256 | return OffsetA == OffsetB; | |
| 257 | }; | |
| 272 | if (OffsetA != OffsetB) | |
| 273 | return false; | |
| 274 | } | |
| 258 | 275 | |
| 259 | return RelsA.size() == RelsB.size() && | |
| 260 | std::equal(RelsA.begin(), RelsA.end(), RelsB.begin(), Eq); | |
| 276 | return true; | |
| 261 | 277 | } |
| 262 | 278 | |
| 263 | 279 | // Compare "non-moving" part of two InputSections, namely everything |
| ... | ... | @@ -278,37 +294,39 @@ bool ICF<ELFT>::equalsConstant(const InputSection *A, const InputSection *B) { |
| 278 | 294 | // relocations point to the same section in terms of ICF. |
| 279 | 295 | template <class ELFT> |
| 280 | 296 | template <class RelTy> |
| 281 | bool ICF<ELFT>::variableEq(const InputSection *A, ArrayRef<RelTy> RelsA, | |
| 282 | const InputSection *B, ArrayRef<RelTy> RelsB) { | |
| 283 | auto Eq = [&](const RelTy &RA, const RelTy &RB) { | |
| 297 | bool ICF<ELFT>::variableEq(const InputSection *SecA, ArrayRef<RelTy> RA, | |
| 298 | const InputSection *SecB, ArrayRef<RelTy> RB) { | |
| 299 | assert(RA.size() == RB.size()); | |
| 300 | ||
| 301 | for (size_t I = 0; I < RA.size(); ++I) { | |
| 284 | 302 | // The two sections must be identical. |
| 285 | SymbolBody &SA = A->template getFile<ELFT>()->getRelocTargetSym(RA); | |
| 286 | SymbolBody &SB = B->template getFile<ELFT>()->getRelocTargetSym(RB); | |
| 303 | Symbol &SA = SecA->template getFile<ELFT>()->getRelocTargetSym(RA[I]); | |
| 304 | Symbol &SB = SecB->template getFile<ELFT>()->getRelocTargetSym(RB[I]); | |
| 287 | 305 | if (&SA == &SB) |
| 288 | return true; | |
| 306 | continue; | |
| 289 | 307 | |
| 290 | auto *DA = cast<DefinedRegular>(&SA); | |
| 291 | auto *DB = cast<DefinedRegular>(&SB); | |
| 308 | auto *DA = cast<Defined>(&SA); | |
| 309 | auto *DB = cast<Defined>(&SB); | |
| 292 | 310 | |
| 293 | 311 | // We already dealt with absolute and non-InputSection symbols in |
| 294 | 312 | // constantEq, and for InputSections we have already checked everything |
| 295 | 313 | // except the equivalence class. |
| 296 | 314 | if (!DA->Section) |
| 297 | return true; | |
| 315 | continue; | |
| 298 | 316 | auto *X = dyn_cast<InputSection>(DA->Section); |
| 299 | 317 | if (!X) |
| 300 | return true; | |
| 318 | continue; | |
| 301 | 319 | auto *Y = cast<InputSection>(DB->Section); |
| 302 | 320 | |
| 303 | 321 | // Ineligible sections are in the special equivalence class 0. |
| 304 | 322 | // They can never be the same in terms of the equivalence class. |
| 305 | 323 | if (X->Class[Current] == 0) |
| 306 | 324 | return false; |
| 307 | ||
| 308 | return X->Class[Current] == Y->Class[Current]; | |
| 325 | if (X->Class[Current] != Y->Class[Current]) | |
| 326 | return false; | |
| 309 | 327 | }; |
| 310 | 328 | |
| 311 | return std::equal(RelsA.begin(), RelsA.end(), RelsB.begin(), Eq); | |
| 329 | return true; | |
| 312 | 330 | } |
| 313 | 331 | |
| 314 | 332 | // Compare "moving" part of two InputSections, namely relocation targets. |
| ... | ... | @@ -353,7 +371,7 @@ template <class ELFT> |
| 353 | 371 | void ICF<ELFT>::forEachClass(std::function<void(size_t, size_t)> Fn) { |
| 354 | 372 | // If threading is disabled or the number of sections are |
| 355 | 373 | // too small to use threading, call Fn sequentially. |
| 356 | if (!Config->Threads || Sections.size() < 1024) { | |
| 374 | if (!ThreadsEnabled || Sections.size() < 1024) { | |
| 357 | 375 | forEachClassRange(0, Sections.size(), Fn); |
| 358 | 376 | ++Cnt; |
| 359 | 377 | return; |
| ... | ... | @@ -381,9 +399,10 @@ template <class ELFT> void ICF<ELFT>::run() { |
| 381 | 399 | Sections.push_back(S); |
| 382 | 400 | |
| 383 | 401 | // Initially, we use hash values to partition sections. |
| 384 | for (InputSection *S : Sections) | |
| 402 | parallelForEach(Sections, [&](InputSection *S) { | |
| 385 | 403 | // Set MSB to 1 to avoid collisions with non-hash IDs. |
| 386 | 404 | S->Class[0] = getHash<ELFT>(S) | (1 << 31); |
| 405 | }); | |
| 387 | 406 | |
| 388 | 407 | // From now on, sections in Sections vector are ordered so that sections |
| 389 | 408 | // in the same equivalence class are consecutive in the vector. |
deps/lld/ELF/InputFiles.cpp+360-271| ... | ... | @@ -8,13 +8,13 @@ |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | 10 | #include "InputFiles.h" |
| 11 | #include "Error.h" | |
| 12 | 11 | #include "InputSection.h" |
| 13 | 12 | #include "LinkerScript.h" |
| 14 | #include "Memory.h" | |
| 15 | 13 | #include "SymbolTable.h" |
| 16 | 14 | #include "Symbols.h" |
| 17 | 15 | #include "SyntheticSections.h" |
| 16 | #include "lld/Common/ErrorHandler.h" | |
| 17 | #include "lld/Common/Memory.h" | |
| 18 | 18 | #include "llvm/ADT/STLExtras.h" |
| 19 | 19 | #include "llvm/CodeGen/Analysis.h" |
| 20 | 20 | #include "llvm/DebugInfo/DWARF/DWARFContext.h" |
| ... | ... | @@ -23,6 +23,8 @@ |
| 23 | 23 | #include "llvm/LTO/LTO.h" |
| 24 | 24 | #include "llvm/MC/StringTableBuilder.h" |
| 25 | 25 | #include "llvm/Object/ELFObjectFile.h" |
| 26 | #include "llvm/Support/ARMAttributeParser.h" | |
| 27 | #include "llvm/Support/ARMBuildAttributes.h" | |
| 26 | 28 | #include "llvm/Support/Path.h" |
| 27 | 29 | #include "llvm/Support/TarWriter.h" |
| 28 | 30 | #include "llvm/Support/raw_ostream.h" |
| ... | ... | @@ -30,31 +32,29 @@ |
| 30 | 32 | using namespace llvm; |
| 31 | 33 | using namespace llvm::ELF; |
| 32 | 34 | using namespace llvm::object; |
| 35 | using namespace llvm::sys; | |
| 33 | 36 | using namespace llvm::sys::fs; |
| 34 | 37 | |
| 35 | 38 | using namespace lld; |
| 36 | 39 | using namespace lld::elf; |
| 37 | 40 | |
| 41 | std::vector<BinaryFile *> elf::BinaryFiles; | |
| 42 | std::vector<BitcodeFile *> elf::BitcodeFiles; | |
| 43 | std::vector<InputFile *> elf::ObjectFiles; | |
| 44 | std::vector<InputFile *> elf::SharedFiles; | |
| 45 | ||
| 38 | 46 | TarWriter *elf::Tar; |
| 39 | 47 | |
| 40 | 48 | InputFile::InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} |
| 41 | 49 | |
| 42 | namespace { | |
| 43 | // In ELF object file all section addresses are zero. If we have multiple | |
| 44 | // .text sections (when using -ffunction-section or comdat group) then | |
| 45 | // LLVM DWARF parser will not be able to parse .debug_line correctly, unless | |
| 46 | // we assign each section some unique address. This callback method assigns | |
| 47 | // each section an address equal to its offset in ELF object file. | |
| 48 | class ObjectInfo : public LoadedObjectInfoHelper<ObjectInfo> { | |
| 49 | public: | |
| 50 | uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const override { | |
| 51 | return static_cast<const ELFSectionRef &>(Sec).getOffset(); | |
| 52 | } | |
| 53 | }; | |
| 54 | } | |
| 55 | ||
| 56 | 50 | Optional<MemoryBufferRef> elf::readFile(StringRef Path) { |
| 51 | // The --chroot option changes our virtual root directory. | |
| 52 | // This is useful when you are dealing with files created by --reproduce. | |
| 53 | if (!Config->Chroot.empty() && Path.startswith("/")) | |
| 54 | Path = Saver.save(Config->Chroot + Path); | |
| 55 | ||
| 57 | 56 | log(Path); |
| 57 | ||
| 58 | 58 | auto MBOrErr = MemoryBuffer::getFile(Path); |
| 59 | 59 | if (auto EC = MBOrErr.getError()) { |
| 60 | 60 | error("cannot open " + Path + ": " + EC.message()); |
| ... | ... | @@ -70,28 +70,132 @@ Optional<MemoryBufferRef> elf::readFile(StringRef Path) { |
| 70 | 70 | return MBRef; |
| 71 | 71 | } |
| 72 | 72 | |
| 73 | template <class ELFT> void elf::ObjectFile<ELFT>::initializeDwarfLine() { | |
| 74 | std::unique_ptr<object::ObjectFile> Obj = | |
| 75 | check(object::ObjectFile::createObjectFile(this->MB), toString(this)); | |
| 73 | // Concatenates arguments to construct a string representing an error location. | |
| 74 | static std::string createFileLineMsg(StringRef Path, unsigned Line) { | |
| 75 | std::string Filename = path::filename(Path); | |
| 76 | std::string Lineno = ":" + std::to_string(Line); | |
| 77 | if (Filename == Path) | |
| 78 | return Filename + Lineno; | |
| 79 | return Filename + Lineno + " (" + Path.str() + Lineno + ")"; | |
| 80 | } | |
| 76 | 81 | |
| 77 | ObjectInfo ObjInfo; | |
| 78 | DWARFContextInMemory Dwarf(*Obj, &ObjInfo); | |
| 82 | template <class ELFT> | |
| 83 | static std::string getSrcMsgAux(ObjFile<ELFT> &File, const Symbol &Sym, | |
| 84 | InputSectionBase &Sec, uint64_t Offset) { | |
| 85 | // In DWARF, functions and variables are stored to different places. | |
| 86 | // First, lookup a function for a given offset. | |
| 87 | if (Optional<DILineInfo> Info = File.getDILineInfo(&Sec, Offset)) | |
| 88 | return createFileLineMsg(Info->FileName, Info->Line); | |
| 89 | ||
| 90 | // If it failed, lookup again as a variable. | |
| 91 | if (Optional<std::pair<std::string, unsigned>> FileLine = | |
| 92 | File.getVariableLoc(Sym.getName())) | |
| 93 | return createFileLineMsg(FileLine->first, FileLine->second); | |
| 94 | ||
| 95 | // File.SourceFile contains STT_FILE symbol, and that is a last resort. | |
| 96 | return File.SourceFile; | |
| 97 | } | |
| 98 | ||
| 99 | std::string InputFile::getSrcMsg(const Symbol &Sym, InputSectionBase &Sec, | |
| 100 | uint64_t Offset) { | |
| 101 | if (kind() != ObjKind) | |
| 102 | return ""; | |
| 103 | switch (Config->EKind) { | |
| 104 | default: | |
| 105 | llvm_unreachable("Invalid kind"); | |
| 106 | case ELF32LEKind: | |
| 107 | return getSrcMsgAux(cast<ObjFile<ELF32LE>>(*this), Sym, Sec, Offset); | |
| 108 | case ELF32BEKind: | |
| 109 | return getSrcMsgAux(cast<ObjFile<ELF32BE>>(*this), Sym, Sec, Offset); | |
| 110 | case ELF64LEKind: | |
| 111 | return getSrcMsgAux(cast<ObjFile<ELF64LE>>(*this), Sym, Sec, Offset); | |
| 112 | case ELF64BEKind: | |
| 113 | return getSrcMsgAux(cast<ObjFile<ELF64BE>>(*this), Sym, Sec, Offset); | |
| 114 | } | |
| 115 | } | |
| 116 | ||
| 117 | template <class ELFT> void ObjFile<ELFT>::initializeDwarf() { | |
| 118 | DWARFContext Dwarf(make_unique<LLDDwarfObj<ELFT>>(this)); | |
| 119 | const DWARFObject &Obj = Dwarf.getDWARFObj(); | |
| 79 | 120 | DwarfLine.reset(new DWARFDebugLine); |
| 80 | DWARFDataExtractor LineData(Dwarf.getLineSection(), Config->IsLE, | |
| 121 | DWARFDataExtractor LineData(Obj, Obj.getLineSection(), Config->IsLE, | |
| 81 | 122 | Config->Wordsize); |
| 82 | 123 | |
| 83 | 124 | // The second parameter is offset in .debug_line section |
| 84 | 125 | // for compilation unit (CU) of interest. We have only one |
| 85 | 126 | // CU (object file), so offset is always 0. |
| 86 | DwarfLine->getOrParseLineTable(LineData, 0); | |
| 127 | // FIXME: Provide the associated DWARFUnit if there is one. DWARF v5 | |
| 128 | // needs it in order to find indirect strings. | |
| 129 | const DWARFDebugLine::LineTable *LT = | |
| 130 | DwarfLine->getOrParseLineTable(LineData, 0, nullptr); | |
| 131 | ||
| 132 | // Return if there is no debug information about CU available. | |
| 133 | if (!Dwarf.getNumCompileUnits()) | |
| 134 | return; | |
| 135 | ||
| 136 | // Loop over variable records and insert them to VariableLoc. | |
| 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; | |
| 143 | ||
| 144 | // Skip if a local variable because we don't need them for generating error | |
| 145 | // messages. In general, only non-local symbols can fail to be linked. | |
| 146 | if (!dwarf::toUnsigned(Die.find(dwarf::DW_AT_external), 0)) | |
| 147 | continue; | |
| 148 | ||
| 149 | // Get the source filename index for the variable. | |
| 150 | unsigned File = dwarf::toUnsigned(Die.find(dwarf::DW_AT_decl_file), 0); | |
| 151 | if (!LT->hasFileAtIndex(File)) | |
| 152 | continue; | |
| 153 | ||
| 154 | // Get the line number on which the variable is declared. | |
| 155 | unsigned Line = dwarf::toUnsigned(Die.find(dwarf::DW_AT_decl_line), 0); | |
| 156 | ||
| 157 | // Get the name of the variable and add the collected information to | |
| 158 | // VariableLoc. Usually Name is non-empty, but it can be empty if the input | |
| 159 | // object file lacks some debug info. | |
| 160 | StringRef Name = dwarf::toString(Die.find(dwarf::DW_AT_name), ""); | |
| 161 | if (!Name.empty()) | |
| 162 | VariableLoc.insert({Name, {File, Line}}); | |
| 163 | } | |
| 164 | } | |
| 165 | ||
| 166 | // Returns the pair of file name and line number describing location of data | |
| 167 | // object (variable, array, etc) definition. | |
| 168 | template <class ELFT> | |
| 169 | Optional<std::pair<std::string, unsigned>> | |
| 170 | ObjFile<ELFT>::getVariableLoc(StringRef Name) { | |
| 171 | llvm::call_once(InitDwarfLine, [this]() { initializeDwarf(); }); | |
| 172 | ||
| 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. | |
| 179 | auto It = VariableLoc.find(Name); | |
| 180 | if (It == VariableLoc.end()) | |
| 181 | return None; | |
| 182 | ||
| 183 | // Take file name string from line table. | |
| 184 | std::string FileName; | |
| 185 | if (!LT->getFileNameByIndex( | |
| 186 | It->second.first /* File */, nullptr, | |
| 187 | DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, FileName)) | |
| 188 | return None; | |
| 189 | ||
| 190 | return std::make_pair(FileName, It->second.second /*Line*/); | |
| 87 | 191 | } |
| 88 | 192 | |
| 89 | 193 | // Returns source line information for a given offset |
| 90 | 194 | // using DWARF debug info. |
| 91 | 195 | template <class ELFT> |
| 92 | Optional<DILineInfo> elf::ObjectFile<ELFT>::getDILineInfo(InputSectionBase *S, | |
| 93 | uint64_t Offset) { | |
| 94 | llvm::call_once(InitDwarfLine, [this]() { initializeDwarfLine(); }); | |
| 196 | Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *S, | |
| 197 | uint64_t Offset) { | |
| 198 | llvm::call_once(InitDwarfLine, [this]() { initializeDwarf(); }); | |
| 95 | 199 | |
| 96 | 200 | // The offset to CU is 0. |
| 97 | 201 | const DWARFDebugLine::LineTable *Tbl = DwarfLine->getLineTable(0); |
| ... | ... | @@ -112,8 +216,7 @@ Optional<DILineInfo> elf::ObjectFile<ELFT>::getDILineInfo(InputSectionBase *S, |
| 112 | 216 | // Returns source line information for a given offset |
| 113 | 217 | // using DWARF debug info. |
| 114 | 218 | template <class ELFT> |
| 115 | std::string elf::ObjectFile<ELFT>::getLineInfo(InputSectionBase *S, | |
| 116 | uint64_t Offset) { | |
| 219 | std::string ObjFile<ELFT>::getLineInfo(InputSectionBase *S, uint64_t Offset) { | |
| 117 | 220 | if (Optional<DILineInfo> Info = getDILineInfo(S, Offset)) |
| 118 | 221 | return Info->FileName + ":" + std::to_string(Info->Line); |
| 119 | 222 | return ""; |
| ... | ... | @@ -145,50 +248,41 @@ ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) { |
| 145 | 248 | } |
| 146 | 249 | |
| 147 | 250 | template <class ELFT> |
| 148 | typename ELFT::SymRange ELFFileBase<ELFT>::getGlobalSymbols() { | |
| 149 | return makeArrayRef(Symbols.begin() + FirstNonLocal, Symbols.end()); | |
| 251 | typename ELFT::SymRange ELFFileBase<ELFT>::getGlobalELFSyms() { | |
| 252 | return makeArrayRef(ELFSyms.begin() + FirstNonLocal, ELFSyms.end()); | |
| 150 | 253 | } |
| 151 | 254 | |
| 152 | 255 | template <class ELFT> |
| 153 | 256 | uint32_t ELFFileBase<ELFT>::getSectionIndex(const Elf_Sym &Sym) const { |
| 154 | return check(getObj().getSectionIndex(&Sym, Symbols, SymtabSHNDX), | |
| 155 | toString(this)); | |
| 257 | return CHECK(getObj().getSectionIndex(&Sym, ELFSyms, SymtabSHNDX), this); | |
| 156 | 258 | } |
| 157 | 259 | |
| 158 | 260 | template <class ELFT> |
| 159 | 261 | void ELFFileBase<ELFT>::initSymtab(ArrayRef<Elf_Shdr> Sections, |
| 160 | 262 | const Elf_Shdr *Symtab) { |
| 161 | 263 | FirstNonLocal = Symtab->sh_info; |
| 162 | Symbols = check(getObj().symbols(Symtab), toString(this)); | |
| 163 | if (FirstNonLocal == 0 || FirstNonLocal > Symbols.size()) | |
| 264 | ELFSyms = CHECK(getObj().symbols(Symtab), this); | |
| 265 | if (FirstNonLocal == 0 || FirstNonLocal > ELFSyms.size()) | |
| 164 | 266 | fatal(toString(this) + ": invalid sh_info in symbol table"); |
| 165 | 267 | |
| 166 | StringTable = check(getObj().getStringTableForSymtab(*Symtab, Sections), | |
| 167 | toString(this)); | |
| 268 | StringTable = | |
| 269 | CHECK(getObj().getStringTableForSymtab(*Symtab, Sections), this); | |
| 168 | 270 | } |
| 169 | 271 | |
| 170 | 272 | template <class ELFT> |
| 171 | elf::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M, StringRef ArchiveName) | |
| 172 | : ELFFileBase<ELFT>(Base::ObjectKind, M) { | |
| 273 | ObjFile<ELFT>::ObjFile(MemoryBufferRef M, StringRef ArchiveName) | |
| 274 | : ELFFileBase<ELFT>(Base::ObjKind, M) { | |
| 173 | 275 | this->ArchiveName = ArchiveName; |
| 174 | 276 | } |
| 175 | 277 | |
| 176 | template <class ELFT> | |
| 177 | ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getLocalSymbols() { | |
| 178 | if (this->SymbolBodies.empty()) | |
| 179 | return this->SymbolBodies; | |
| 180 | return makeArrayRef(this->SymbolBodies).slice(1, this->FirstNonLocal - 1); | |
| 181 | } | |
| 182 | ||
| 183 | template <class ELFT> | |
| 184 | ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getSymbols() { | |
| 185 | if (this->SymbolBodies.empty()) | |
| 186 | return this->SymbolBodies; | |
| 187 | return makeArrayRef(this->SymbolBodies).slice(1); | |
| 278 | template <class ELFT> ArrayRef<Symbol *> ObjFile<ELFT>::getLocalSymbols() { | |
| 279 | if (this->Symbols.empty()) | |
| 280 | return {}; | |
| 281 | return makeArrayRef(this->Symbols).slice(1, this->FirstNonLocal - 1); | |
| 188 | 282 | } |
| 189 | 283 | |
| 190 | 284 | template <class ELFT> |
| 191 | void elf::ObjectFile<ELFT>::parse(DenseSet<CachedHashStringRef> &ComdatGroups) { | |
| 285 | void ObjFile<ELFT>::parse(DenseSet<CachedHashStringRef> &ComdatGroups) { | |
| 192 | 286 | // Read section and symbol tables. |
| 193 | 287 | initializeSections(ComdatGroups); |
| 194 | 288 | initializeSymbols(); |
| ... | ... | @@ -198,19 +292,17 @@ void elf::ObjectFile<ELFT>::parse(DenseSet<CachedHashStringRef> &ComdatGroups) { |
| 198 | 292 | // They are identified and deduplicated by group name. This function |
| 199 | 293 | // returns a group name. |
| 200 | 294 | template <class ELFT> |
| 201 | StringRef | |
| 202 | elf::ObjectFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections, | |
| 203 | const Elf_Shdr &Sec) { | |
| 295 | StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections, | |
| 296 | const Elf_Shdr &Sec) { | |
| 204 | 297 | // Group signatures are stored as symbol names in object files. |
| 205 | 298 | // sh_info contains a symbol index, so we fetch a symbol and read its name. |
| 206 | if (this->Symbols.empty()) | |
| 299 | if (this->ELFSyms.empty()) | |
| 207 | 300 | this->initSymtab( |
| 208 | Sections, | |
| 209 | check(object::getSection<ELFT>(Sections, Sec.sh_link), toString(this))); | |
| 301 | Sections, CHECK(object::getSection<ELFT>(Sections, Sec.sh_link), this)); | |
| 210 | 302 | |
| 211 | const Elf_Sym *Sym = check( | |
| 212 | object::getSymbol<ELFT>(this->Symbols, Sec.sh_info), toString(this)); | |
| 213 | StringRef Signature = check(Sym->getName(this->StringTable), toString(this)); | |
| 303 | const Elf_Sym *Sym = | |
| 304 | CHECK(object::getSymbol<ELFT>(this->ELFSyms, Sec.sh_info), this); | |
| 305 | StringRef Signature = CHECK(Sym->getName(this->StringTable), this); | |
| 214 | 306 | |
| 215 | 307 | // As a special case, if a symbol is a section symbol and has no name, |
| 216 | 308 | // we use a section name as a signature. |
| ... | ... | @@ -225,32 +317,22 @@ elf::ObjectFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections, |
| 225 | 317 | } |
| 226 | 318 | |
| 227 | 319 | template <class ELFT> |
| 228 | ArrayRef<typename elf::ObjectFile<ELFT>::Elf_Word> | |
| 229 | elf::ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) { | |
| 320 | ArrayRef<typename ObjFile<ELFT>::Elf_Word> | |
| 321 | ObjFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) { | |
| 230 | 322 | const ELFFile<ELFT> &Obj = this->getObj(); |
| 231 | ArrayRef<Elf_Word> Entries = check( | |
| 232 | Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), toString(this)); | |
| 323 | ArrayRef<Elf_Word> Entries = | |
| 324 | CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this); | |
| 233 | 325 | if (Entries.empty() || Entries[0] != GRP_COMDAT) |
| 234 | 326 | fatal(toString(this) + ": unsupported SHT_GROUP format"); |
| 235 | 327 | return Entries.slice(1); |
| 236 | 328 | } |
| 237 | 329 | |
| 238 | template <class ELFT> | |
| 239 | bool elf::ObjectFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) { | |
| 330 | template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) { | |
| 240 | 331 | // We don't merge sections if -O0 (default is -O1). This makes sometimes |
| 241 | 332 | // the linker significantly faster, although the output will be bigger. |
| 242 | 333 | if (Config->Optimize == 0) |
| 243 | 334 | return false; |
| 244 | 335 | |
| 245 | // Do not merge sections if generating a relocatable object. It makes | |
| 246 | // the code simpler because we do not need to update relocation addends | |
| 247 | // to reflect changes introduced by merging. Instead of that we write | |
| 248 | // such "merge" sections into separate OutputSections and keep SHF_MERGE | |
| 249 | // / SHF_STRINGS flags and sh_entsize value to be able to perform merging | |
| 250 | // later during a final linking. | |
| 251 | if (Config->Relocatable) | |
| 252 | return false; | |
| 253 | ||
| 254 | 336 | // A mergeable section with size 0 is useless because they don't have |
| 255 | 337 | // any data to merge. A mergeable string section with size 0 can be |
| 256 | 338 | // argued as invalid because it doesn't end with a null character. |
| ... | ... | @@ -276,29 +358,19 @@ bool elf::ObjectFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) { |
| 276 | 358 | if (Flags & SHF_WRITE) |
| 277 | 359 | fatal(toString(this) + ": writable SHF_MERGE section is not supported"); |
| 278 | 360 | |
| 279 | // Don't try to merge if the alignment is larger than the sh_entsize and this | |
| 280 | // is not SHF_STRINGS. | |
| 281 | // | |
| 282 | // Since this is not a SHF_STRINGS, we would need to pad after every entity. | |
| 283 | // It would be equivalent for the producer of the .o to just set a larger | |
| 284 | // sh_entsize. | |
| 285 | if (Flags & SHF_STRINGS) | |
| 286 | return true; | |
| 287 | ||
| 288 | return Sec.sh_addralign <= EntSize; | |
| 361 | return true; | |
| 289 | 362 | } |
| 290 | 363 | |
| 291 | 364 | template <class ELFT> |
| 292 | void elf::ObjectFile<ELFT>::initializeSections( | |
| 365 | void ObjFile<ELFT>::initializeSections( | |
| 293 | 366 | DenseSet<CachedHashStringRef> &ComdatGroups) { |
| 294 | 367 | const ELFFile<ELFT> &Obj = this->getObj(); |
| 295 | 368 | |
| 296 | ArrayRef<Elf_Shdr> ObjSections = | |
| 297 | check(this->getObj().sections(), toString(this)); | |
| 369 | ArrayRef<Elf_Shdr> ObjSections = CHECK(this->getObj().sections(), this); | |
| 298 | 370 | uint64_t Size = ObjSections.size(); |
| 299 | 371 | this->Sections.resize(Size); |
| 300 | 372 | this->SectionStringTable = |
| 301 | check(Obj.getSectionStringTable(ObjSections), toString(this)); | |
| 373 | CHECK(Obj.getSectionStringTable(ObjSections), this); | |
| 302 | 374 | |
| 303 | 375 | for (size_t I = 0, E = ObjSections.size(); I < E; I++) { |
| 304 | 376 | if (this->Sections[I] == &InputSection::Discarded) |
| ... | ... | @@ -344,8 +416,7 @@ void elf::ObjectFile<ELFT>::initializeSections( |
| 344 | 416 | this->initSymtab(ObjSections, &Sec); |
| 345 | 417 | break; |
| 346 | 418 | case SHT_SYMTAB_SHNDX: |
| 347 | this->SymtabSHNDX = | |
| 348 | check(Obj.getSHNDXTable(Sec, ObjSections), toString(this)); | |
| 419 | this->SymtabSHNDX = CHECK(Obj.getSHNDXTable(Sec, ObjSections), this); | |
| 349 | 420 | break; |
| 350 | 421 | case SHT_STRTAB: |
| 351 | 422 | case SHT_NULL: |
| ... | ... | @@ -358,16 +429,58 @@ void elf::ObjectFile<ELFT>::initializeSections( |
| 358 | 429 | // have a SHF_LINK_ORDER dependency, this is identified by the sh_link. |
| 359 | 430 | if (Sec.sh_flags & SHF_LINK_ORDER) { |
| 360 | 431 | if (Sec.sh_link >= this->Sections.size()) |
| 361 | fatal(toString(this) + ": invalid sh_link index: " + | |
| 362 | Twine(Sec.sh_link)); | |
| 432 | fatal(toString(this) + | |
| 433 | ": invalid sh_link index: " + Twine(Sec.sh_link)); | |
| 363 | 434 | this->Sections[Sec.sh_link]->DependentSections.push_back( |
| 364 | this->Sections[I]); | |
| 435 | cast<InputSection>(this->Sections[I])); | |
| 365 | 436 | } |
| 366 | 437 | } |
| 367 | 438 | } |
| 368 | 439 | |
| 440 | // The ARM support in lld makes some use of instructions that are not available | |
| 441 | // on all ARM architectures. Namely: | |
| 442 | // - Use of BLX instruction for interworking between ARM and Thumb state. | |
| 443 | // - Use of the extended Thumb branch encoding in relocation. | |
| 444 | // - Use of the MOVT/MOVW instructions in Thumb Thunks. | |
| 445 | // The ARM Attributes section contains information about the architecture chosen | |
| 446 | // at compile time. We follow the convention that if at least one input object | |
| 447 | // is compiled with an architecture that supports these features then lld is | |
| 448 | // permitted to use them. | |
| 449 | static void updateSupportedARMFeatures(const ARMAttributeParser &Attributes) { | |
| 450 | if (!Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) | |
| 451 | return; | |
| 452 | auto Arch = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch); | |
| 453 | switch (Arch) { | |
| 454 | case ARMBuildAttrs::Pre_v4: | |
| 455 | case ARMBuildAttrs::v4: | |
| 456 | case ARMBuildAttrs::v4T: | |
| 457 | // Architectures prior to v5 do not support BLX instruction | |
| 458 | break; | |
| 459 | case ARMBuildAttrs::v5T: | |
| 460 | case ARMBuildAttrs::v5TE: | |
| 461 | case ARMBuildAttrs::v5TEJ: | |
| 462 | case ARMBuildAttrs::v6: | |
| 463 | case ARMBuildAttrs::v6KZ: | |
| 464 | case ARMBuildAttrs::v6K: | |
| 465 | Config->ARMHasBlx = true; | |
| 466 | // Architectures used in pre-Cortex processors do not support | |
| 467 | // The J1 = 1 J2 = 1 Thumb branch range extension, with the exception | |
| 468 | // of Architecture v6T2 (arm1156t2-s and arm1156t2f-s) that do. | |
| 469 | break; | |
| 470 | default: | |
| 471 | // All other Architectures have BLX and extended branch encoding | |
| 472 | Config->ARMHasBlx = true; | |
| 473 | Config->ARMJ1J2BranchEncoding = true; | |
| 474 | if (Arch != ARMBuildAttrs::v6_M && Arch != ARMBuildAttrs::v6S_M) | |
| 475 | // All Architectures used in Cortex processors with the exception | |
| 476 | // of v6-M and v6S-M have the MOVT and MOVW instructions. | |
| 477 | Config->ARMHasMovtMovw = true; | |
| 478 | break; | |
| 479 | } | |
| 480 | } | |
| 481 | ||
| 369 | 482 | template <class ELFT> |
| 370 | InputSectionBase *elf::ObjectFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) { | |
| 483 | InputSectionBase *ObjFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) { | |
| 371 | 484 | uint32_t Idx = Sec.sh_info; |
| 372 | 485 | if (Idx >= this->Sections.size()) |
| 373 | 486 | fatal(toString(this) + ": invalid relocated section index: " + Twine(Idx)); |
| ... | ... | @@ -386,29 +499,32 @@ InputSectionBase *elf::ObjectFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) { |
| 386 | 499 | |
| 387 | 500 | // Create a regular InputSection class that has the same contents |
| 388 | 501 | // as a given section. |
| 389 | InputSectionBase *toRegularSection(MergeInputSection *Sec) { | |
| 390 | auto *Ret = make<InputSection>(Sec->Flags, Sec->Type, Sec->Alignment, | |
| 391 | Sec->Data, Sec->Name); | |
| 392 | Ret->File = Sec->File; | |
| 393 | return Ret; | |
| 502 | static InputSection *toRegularSection(MergeInputSection *Sec) { | |
| 503 | return make<InputSection>(Sec->File, Sec->Flags, Sec->Type, Sec->Alignment, | |
| 504 | Sec->Data, Sec->Name); | |
| 394 | 505 | } |
| 395 | 506 | |
| 396 | 507 | template <class ELFT> |
| 397 | InputSectionBase * | |
| 398 | elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { | |
| 508 | InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { | |
| 399 | 509 | StringRef Name = getSectionName(Sec); |
| 400 | 510 | |
| 401 | 511 | switch (Sec.sh_type) { |
| 402 | case SHT_ARM_ATTRIBUTES: | |
| 403 | // FIXME: ARM meta-data section. Retain the first attribute section | |
| 404 | // we see. The eglibc ARM dynamic loaders require the presence of an | |
| 405 | // attribute section for dlopen to work. | |
| 406 | // In a full implementation we would merge all attribute sections. | |
| 512 | case SHT_ARM_ATTRIBUTES: { | |
| 513 | if (Config->EMachine != EM_ARM) | |
| 514 | break; | |
| 515 | ARMAttributeParser Attributes; | |
| 516 | ArrayRef<uint8_t> Contents = check(this->getObj().getSectionContents(&Sec)); | |
| 517 | Attributes.Parse(Contents, /*isLittle*/ Config->EKind == ELF32LEKind); | |
| 518 | updateSupportedARMFeatures(Attributes); | |
| 519 | // FIXME: Retain the first attribute section we see. The eglibc ARM | |
| 520 | // dynamic loaders require the presence of an attribute section for dlopen | |
| 521 | // to work. In a full implementation we would merge all attribute sections. | |
| 407 | 522 | if (InX::ARMAttributes == nullptr) { |
| 408 | InX::ARMAttributes = make<InputSection>(this, &Sec, Name); | |
| 523 | InX::ARMAttributes = make<InputSection>(*this, Sec, Name); | |
| 409 | 524 | return InX::ARMAttributes; |
| 410 | 525 | } |
| 411 | 526 | return &InputSection::Discarded; |
| 527 | } | |
| 412 | 528 | case SHT_RELA: |
| 413 | 529 | case SHT_REL: { |
| 414 | 530 | // Find the relocation target section and associate this |
| ... | ... | @@ -423,7 +539,7 @@ elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { |
| 423 | 539 | // If -r is given, we do not interpret or apply relocation |
| 424 | 540 | // but just copy relocation sections to output. |
| 425 | 541 | if (Config->Relocatable) |
| 426 | return make<InputSection>(this, &Sec, Name); | |
| 542 | return make<InputSection>(*this, Sec, Name); | |
| 427 | 543 | |
| 428 | 544 | if (Target->FirstRelocation) |
| 429 | 545 | fatal(toString(this) + |
| ... | ... | @@ -443,13 +559,12 @@ elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { |
| 443 | 559 | |
| 444 | 560 | size_t NumRelocations; |
| 445 | 561 | if (Sec.sh_type == SHT_RELA) { |
| 446 | ArrayRef<Elf_Rela> Rels = | |
| 447 | check(this->getObj().relas(&Sec), toString(this)); | |
| 562 | ArrayRef<Elf_Rela> Rels = CHECK(this->getObj().relas(&Sec), this); | |
| 448 | 563 | Target->FirstRelocation = Rels.begin(); |
| 449 | 564 | NumRelocations = Rels.size(); |
| 450 | 565 | Target->AreRelocsRela = true; |
| 451 | 566 | } else { |
| 452 | ArrayRef<Elf_Rel> Rels = check(this->getObj().rels(&Sec), toString(this)); | |
| 567 | ArrayRef<Elf_Rel> Rels = CHECK(this->getObj().rels(&Sec), this); | |
| 453 | 568 | Target->FirstRelocation = Rels.begin(); |
| 454 | 569 | NumRelocations = Rels.size(); |
| 455 | 570 | Target->AreRelocsRela = false; |
| ... | ... | @@ -462,7 +577,7 @@ elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { |
| 462 | 577 | // However, if -emit-relocs is given, we need to leave them in the output. |
| 463 | 578 | // (Some post link analysis tools need this information.) |
| 464 | 579 | if (Config->EmitRelocs) { |
| 465 | InputSection *RelocSec = make<InputSection>(this, &Sec, Name); | |
| 580 | InputSection *RelocSec = make<InputSection>(*this, Sec, Name); | |
| 466 | 581 | // We will not emit relocation section if target was discarded. |
| 467 | 582 | Target->DependentSections.push_back(RelocSec); |
| 468 | 583 | return RelocSec; |
| ... | ... | @@ -497,18 +612,6 @@ elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { |
| 497 | 612 | return &InputSection::Discarded; |
| 498 | 613 | } |
| 499 | 614 | |
| 500 | if (Config->Strip != StripPolicy::None && Name.startswith(".debug")) | |
| 501 | return &InputSection::Discarded; | |
| 502 | ||
| 503 | // If -gdb-index is given, LLD creates .gdb_index section, and that | |
| 504 | // section serves the same purpose as .debug_gnu_pub{names,types} sections. | |
| 505 | // If that's the case, we want to eliminate .debug_gnu_pub{names,types} | |
| 506 | // because they are redundant and can waste large amount of disk space | |
| 507 | // (for example, they are about 400 MiB in total for a clang debug build.) | |
| 508 | if (Config->GdbIndex && | |
| 509 | (Name == ".debug_gnu_pubnames" || Name == ".debug_gnu_pubtypes")) | |
| 510 | return &InputSection::Discarded; | |
| 511 | ||
| 512 | 615 | // The linkonce feature is a sort of proto-comdat. Some glibc i386 object |
| 513 | 616 | // files contain definitions of symbol "__x86.get_pc_thunk.bx" in linkonce |
| 514 | 617 | // sections. Drop those sections to avoid duplicate symbol errors. |
| ... | ... | @@ -521,54 +624,32 @@ elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { |
| 521 | 624 | // .eh_frame_hdr section for runtime. So we handle them with a special |
| 522 | 625 | // class. For relocatable outputs, they are just passed through. |
| 523 | 626 | if (Name == ".eh_frame" && !Config->Relocatable) |
| 524 | return make<EhInputSection>(this, &Sec, Name); | |
| 627 | return make<EhInputSection>(*this, Sec, Name); | |
| 525 | 628 | |
| 526 | 629 | if (shouldMerge(Sec)) |
| 527 | return make<MergeInputSection>(this, &Sec, Name); | |
| 528 | return make<InputSection>(this, &Sec, Name); | |
| 630 | return make<MergeInputSection>(*this, Sec, Name); | |
| 631 | return make<InputSection>(*this, Sec, Name); | |
| 529 | 632 | } |
| 530 | 633 | |
| 531 | 634 | template <class ELFT> |
| 532 | StringRef elf::ObjectFile<ELFT>::getSectionName(const Elf_Shdr &Sec) { | |
| 533 | return check(this->getObj().getSectionName(&Sec, SectionStringTable), | |
| 534 | toString(this)); | |
| 535 | } | |
| 536 | ||
| 537 | template <class ELFT> void elf::ObjectFile<ELFT>::initializeSymbols() { | |
| 538 | SymbolBodies.reserve(this->Symbols.size()); | |
| 539 | for (const Elf_Sym &Sym : this->Symbols) | |
| 540 | SymbolBodies.push_back(createSymbolBody(&Sym)); | |
| 635 | StringRef ObjFile<ELFT>::getSectionName(const Elf_Shdr &Sec) { | |
| 636 | return CHECK(this->getObj().getSectionName(&Sec, SectionStringTable), this); | |
| 541 | 637 | } |
| 542 | 638 | |
| 543 | template <class ELFT> | |
| 544 | InputSectionBase *elf::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const { | |
| 545 | uint32_t Index = this->getSectionIndex(Sym); | |
| 546 | if (Index >= this->Sections.size()) | |
| 547 | fatal(toString(this) + ": invalid section index: " + Twine(Index)); | |
| 548 | InputSectionBase *S = this->Sections[Index]; | |
| 549 | ||
| 550 | // We found that GNU assembler 2.17.50 [FreeBSD] 2007-07-03 could | |
| 551 | // generate broken objects. STT_SECTION/STT_NOTYPE symbols can be | |
| 552 | // associated with SHT_REL[A]/SHT_SYMTAB/SHT_STRTAB sections. | |
| 553 | // In this case it is fine for section to be null here as we do not | |
| 554 | // allocate sections of these types. | |
| 555 | if (!S) { | |
| 556 | if (Index == 0 || Sym.getType() == STT_SECTION || | |
| 557 | Sym.getType() == STT_NOTYPE) | |
| 558 | return nullptr; | |
| 559 | fatal(toString(this) + ": invalid section index: " + Twine(Index)); | |
| 560 | } | |
| 561 | ||
| 562 | if (S == &InputSection::Discarded) | |
| 563 | return S; | |
| 564 | return S->Repl; | |
| 639 | template <class ELFT> void ObjFile<ELFT>::initializeSymbols() { | |
| 640 | this->Symbols.reserve(this->ELFSyms.size()); | |
| 641 | for (const Elf_Sym &Sym : this->ELFSyms) | |
| 642 | this->Symbols.push_back(createSymbol(&Sym)); | |
| 565 | 643 | } |
| 566 | 644 | |
| 567 | template <class ELFT> | |
| 568 | SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) { | |
| 645 | template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) { | |
| 569 | 646 | int Binding = Sym->getBinding(); |
| 570 | InputSectionBase *Sec = getSection(*Sym); | |
| 571 | 647 | |
| 648 | uint32_t SecIdx = this->getSectionIndex(*Sym); | |
| 649 | if (SecIdx >= this->Sections.size()) | |
| 650 | fatal(toString(this) + ": invalid section index: " + Twine(SecIdx)); | |
| 651 | ||
| 652 | InputSectionBase *Sec = this->Sections[SecIdx]; | |
| 572 | 653 | uint8_t StOther = Sym->st_other; |
| 573 | 654 | uint8_t Type = Sym->getType(); |
| 574 | 655 | uint64_t Value = Sym->st_value; |
| ... | ... | @@ -576,34 +657,29 @@ SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) { |
| 576 | 657 | |
| 577 | 658 | if (Binding == STB_LOCAL) { |
| 578 | 659 | if (Sym->getType() == STT_FILE) |
| 579 | SourceFile = check(Sym->getName(this->StringTable), toString(this)); | |
| 660 | SourceFile = CHECK(Sym->getName(this->StringTable), this); | |
| 580 | 661 | |
| 581 | 662 | if (this->StringTable.size() <= Sym->st_name) |
| 582 | 663 | fatal(toString(this) + ": invalid symbol name offset"); |
| 583 | 664 | |
| 584 | 665 | StringRefZ Name = this->StringTable.data() + Sym->st_name; |
| 585 | 666 | if (Sym->st_shndx == SHN_UNDEF) |
| 586 | return make<Undefined>(Name, /*IsLocal=*/true, StOther, Type, this); | |
| 667 | return make<Undefined>(this, Name, Binding, StOther, Type); | |
| 587 | 668 | |
| 588 | return make<DefinedRegular>(Name, /*IsLocal=*/true, StOther, Type, Value, | |
| 589 | Size, Sec, this); | |
| 669 | return make<Defined>(this, Name, Binding, StOther, Type, Value, Size, Sec); | |
| 590 | 670 | } |
| 591 | 671 | |
| 592 | StringRef Name = check(Sym->getName(this->StringTable), toString(this)); | |
| 672 | StringRef Name = CHECK(Sym->getName(this->StringTable), this); | |
| 593 | 673 | |
| 594 | 674 | switch (Sym->st_shndx) { |
| 595 | 675 | case SHN_UNDEF: |
| 596 | return elf::Symtab<ELFT>::X | |
| 597 | ->addUndefined(Name, /*IsLocal=*/false, Binding, StOther, Type, | |
| 598 | /*CanOmitFromDynSym=*/false, this) | |
| 599 | ->body(); | |
| 676 | return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type, | |
| 677 | /*CanOmitFromDynSym=*/false, this); | |
| 600 | 678 | case SHN_COMMON: |
| 601 | 679 | if (Value == 0 || Value >= UINT32_MAX) |
| 602 | 680 | fatal(toString(this) + ": common symbol '" + Name + |
| 603 | 681 | "' has invalid alignment: " + Twine(Value)); |
| 604 | return elf::Symtab<ELFT>::X | |
| 605 | ->addCommon(Name, Size, Value, Binding, StOther, Type, this) | |
| 606 | ->body(); | |
| 682 | return Symtab->addCommon(Name, Size, Value, Binding, StOther, Type, *this); | |
| 607 | 683 | } |
| 608 | 684 | |
| 609 | 685 | switch (Binding) { |
| ... | ... | @@ -613,13 +689,10 @@ SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) { |
| 613 | 689 | case STB_WEAK: |
| 614 | 690 | case STB_GNU_UNIQUE: |
| 615 | 691 | if (Sec == &InputSection::Discarded) |
| 616 | return elf::Symtab<ELFT>::X | |
| 617 | ->addUndefined(Name, /*IsLocal=*/false, Binding, StOther, Type, | |
| 618 | /*CanOmitFromDynSym=*/false, this) | |
| 619 | ->body(); | |
| 620 | return elf::Symtab<ELFT>::X | |
| 621 | ->addRegular(Name, StOther, Type, Value, Size, Binding, Sec, this) | |
| 622 | ->body(); | |
| 692 | return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type, | |
| 693 | /*CanOmitFromDynSym=*/false, this); | |
| 694 | return Symtab->addRegular(Name, StOther, Type, Value, Size, Binding, Sec, | |
| 695 | this); | |
| 623 | 696 | } |
| 624 | 697 | } |
| 625 | 698 | |
| ... | ... | @@ -630,14 +703,14 @@ ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File) |
| 630 | 703 | template <class ELFT> void ArchiveFile::parse() { |
| 631 | 704 | Symbols.reserve(File->getNumberOfSymbols()); |
| 632 | 705 | for (const Archive::Symbol &Sym : File->symbols()) |
| 633 | Symbols.push_back(Symtab<ELFT>::X->addLazyArchive(this, Sym)); | |
| 706 | Symbols.push_back(Symtab->addLazyArchive<ELFT>(Sym.getName(), *this, Sym)); | |
| 634 | 707 | } |
| 635 | 708 | |
| 636 | 709 | // Returns a buffer pointing to a member file containing a given symbol. |
| 637 | 710 | std::pair<MemoryBufferRef, uint64_t> |
| 638 | 711 | ArchiveFile::getMember(const Archive::Symbol *Sym) { |
| 639 | 712 | Archive::Child C = |
| 640 | check(Sym->getMember(), toString(this) + | |
| 713 | CHECK(Sym->getMember(), toString(this) + | |
| 641 | 714 | ": could not get the member for symbol " + |
| 642 | 715 | Sym->getName()); |
| 643 | 716 | |
| ... | ... | @@ -645,14 +718,13 @@ ArchiveFile::getMember(const Archive::Symbol *Sym) { |
| 645 | 718 | return {MemoryBufferRef(), 0}; |
| 646 | 719 | |
| 647 | 720 | MemoryBufferRef Ret = |
| 648 | check(C.getMemoryBufferRef(), | |
| 721 | CHECK(C.getMemoryBufferRef(), | |
| 649 | 722 | toString(this) + |
| 650 | 723 | ": could not get the buffer for the member defining symbol " + |
| 651 | 724 | Sym->getName()); |
| 652 | 725 | |
| 653 | 726 | if (C.getParent()->isThin() && Tar) |
| 654 | Tar->append(relativeToRoot(check(C.getFullName(), toString(this))), | |
| 655 | Ret.getBuffer()); | |
| 727 | Tar->append(relativeToRoot(CHECK(C.getFullName(), this)), Ret.getBuffer()); | |
| 656 | 728 | if (C.getParent()->isThin()) |
| 657 | 729 | return {Ret, 0}; |
| 658 | 730 | return {Ret, C.getChildOffset()}; |
| ... | ... | @@ -661,22 +733,14 @@ ArchiveFile::getMember(const Archive::Symbol *Sym) { |
| 661 | 733 | template <class ELFT> |
| 662 | 734 | SharedFile<ELFT>::SharedFile(MemoryBufferRef M, StringRef DefaultSoName) |
| 663 | 735 | : ELFFileBase<ELFT>(Base::SharedKind, M), SoName(DefaultSoName), |
| 664 | AsNeeded(Config->AsNeeded) {} | |
| 665 | ||
| 666 | template <class ELFT> | |
| 667 | const typename ELFT::Shdr * | |
| 668 | SharedFile<ELFT>::getSection(const Elf_Sym &Sym) const { | |
| 669 | return check( | |
| 670 | this->getObj().getSection(&Sym, this->Symbols, this->SymtabSHNDX), | |
| 671 | toString(this)); | |
| 672 | } | |
| 736 | IsNeeded(!Config->AsNeeded) {} | |
| 673 | 737 | |
| 674 | 738 | // Partially parse the shared object file so that we can call |
| 675 | 739 | // getSoName on this object. |
| 676 | 740 | template <class ELFT> void SharedFile<ELFT>::parseSoName() { |
| 677 | 741 | const Elf_Shdr *DynamicSec = nullptr; |
| 678 | 742 | const ELFFile<ELFT> Obj = this->getObj(); |
| 679 | ArrayRef<Elf_Shdr> Sections = check(Obj.sections(), toString(this)); | |
| 743 | ArrayRef<Elf_Shdr> Sections = CHECK(Obj.sections(), this); | |
| 680 | 744 | |
| 681 | 745 | // Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d. |
| 682 | 746 | for (const Elf_Shdr &Sec : Sections) { |
| ... | ... | @@ -690,8 +754,7 @@ template <class ELFT> void SharedFile<ELFT>::parseSoName() { |
| 690 | 754 | DynamicSec = &Sec; |
| 691 | 755 | break; |
| 692 | 756 | case SHT_SYMTAB_SHNDX: |
| 693 | this->SymtabSHNDX = | |
| 694 | check(Obj.getSHNDXTable(Sec, Sections), toString(this)); | |
| 757 | this->SymtabSHNDX = CHECK(Obj.getSHNDXTable(Sec, Sections), this); | |
| 695 | 758 | break; |
| 696 | 759 | case SHT_GNU_versym: |
| 697 | 760 | this->VersymSec = &Sec; |
| ... | ... | @@ -702,15 +765,14 @@ template <class ELFT> void SharedFile<ELFT>::parseSoName() { |
| 702 | 765 | } |
| 703 | 766 | } |
| 704 | 767 | |
| 705 | if (this->VersymSec && this->Symbols.empty()) | |
| 768 | if (this->VersymSec && this->ELFSyms.empty()) | |
| 706 | 769 | error("SHT_GNU_versym should be associated with symbol table"); |
| 707 | 770 | |
| 708 | 771 | // Search for a DT_SONAME tag to initialize this->SoName. |
| 709 | 772 | if (!DynamicSec) |
| 710 | 773 | return; |
| 711 | 774 | ArrayRef<Elf_Dyn> Arr = |
| 712 | check(Obj.template getSectionContentsAsArray<Elf_Dyn>(DynamicSec), | |
| 713 | toString(this)); | |
| 775 | CHECK(Obj.template getSectionContentsAsArray<Elf_Dyn>(DynamicSec), this); | |
| 714 | 776 | for (const Elf_Dyn &Dyn : Arr) { |
| 715 | 777 | if (Dyn.d_tag == DT_SONAME) { |
| 716 | 778 | uint64_t Val = Dyn.getVal(); |
| ... | ... | @@ -767,11 +829,14 @@ SharedFile<ELFT>::parseVerdefs(const Elf_Versym *&Versym) { |
| 767 | 829 | template <class ELFT> void SharedFile<ELFT>::parseRest() { |
| 768 | 830 | // Create mapping from version identifiers to Elf_Verdef entries. |
| 769 | 831 | const Elf_Versym *Versym = nullptr; |
| 770 | std::vector<const Elf_Verdef *> Verdefs = parseVerdefs(Versym); | |
| 832 | Verdefs = parseVerdefs(Versym); | |
| 771 | 833 | |
| 772 | Elf_Sym_Range Syms = this->getGlobalSymbols(); | |
| 834 | ArrayRef<Elf_Shdr> Sections = CHECK(this->getObj().sections(), this); | |
| 835 | ||
| 836 | // Add symbols to the symbol table. | |
| 837 | Elf_Sym_Range Syms = this->getGlobalELFSyms(); | |
| 773 | 838 | for (const Elf_Sym &Sym : Syms) { |
| 774 | unsigned VersymIndex = 0; | |
| 839 | unsigned VersymIndex = VER_NDX_GLOBAL; | |
| 775 | 840 | if (Versym) { |
| 776 | 841 | VersymIndex = Versym->vs_index; |
| 777 | 842 | ++Versym; |
| ... | ... | @@ -779,28 +844,62 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() { |
| 779 | 844 | bool Hidden = VersymIndex & VERSYM_HIDDEN; |
| 780 | 845 | VersymIndex = VersymIndex & ~VERSYM_HIDDEN; |
| 781 | 846 | |
| 782 | StringRef Name = check(Sym.getName(this->StringTable), toString(this)); | |
| 847 | StringRef Name = CHECK(Sym.getName(this->StringTable), this); | |
| 783 | 848 | if (Sym.isUndefined()) { |
| 784 | 849 | Undefs.push_back(Name); |
| 785 | 850 | continue; |
| 786 | 851 | } |
| 787 | 852 | |
| 788 | // Ignore local symbols. | |
| 789 | if (Versym && VersymIndex == VER_NDX_LOCAL) | |
| 853 | if (Sym.getBinding() == STB_LOCAL) { | |
| 854 | warn("found local symbol '" + Name + | |
| 855 | "' in global part of symbol table in file " + toString(this)); | |
| 790 | 856 | continue; |
| 857 | } | |
| 791 | 858 | |
| 792 | const Elf_Verdef *V = | |
| 793 | VersymIndex == VER_NDX_GLOBAL ? nullptr : Verdefs[VersymIndex]; | |
| 859 | if (Config->EMachine == EM_MIPS) { | |
| 860 | // FIXME: MIPS BFD linker puts _gp_disp symbol into DSO files | |
| 861 | // and incorrectly assigns VER_NDX_LOCAL to this section global | |
| 862 | // symbol. Here is a workaround for this bug. | |
| 863 | if (Versym && VersymIndex == VER_NDX_LOCAL && Name == "_gp_disp") | |
| 864 | continue; | |
| 865 | } | |
| 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); | |
| 794 | 893 | |
| 795 | 894 | if (!Hidden) |
| 796 | elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V); | |
| 895 | Symtab->addShared(Name, *this, Sym, Alignment, VersymIndex); | |
| 797 | 896 | |
| 798 | 897 | // Also add the symbol with the versioned name to handle undefined symbols |
| 799 | 898 | // with explicit versions. |
| 800 | if (V) { | |
| 801 | StringRef VerName = this->StringTable.data() + V->getAux()->vda_name; | |
| 899 | if (Ver) { | |
| 900 | StringRef VerName = this->StringTable.data() + Ver->getAux()->vda_name; | |
| 802 | 901 | Name = Saver.save(Name + "@" + VerName); |
| 803 | elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V); | |
| 902 | Symtab->addShared(Name, *this, Sym, Alignment, VersymIndex); | |
| 804 | 903 | } |
| 805 | 904 | } |
| 806 | 905 | } |
| ... | ... | @@ -855,7 +954,7 @@ BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName, |
| 855 | 954 | MemoryBufferRef MBRef(MB.getBuffer(), |
| 856 | 955 | Saver.save(ArchiveName + MB.getBufferIdentifier() + |
| 857 | 956 | utostr(OffsetInArchive))); |
| 858 | Obj = check(lto::InputFile::create(MBRef), toString(this)); | |
| 957 | Obj = CHECK(lto::InputFile::create(MBRef), this); | |
| 859 | 958 | |
| 860 | 959 | Triple T(Obj->getTargetTriple()); |
| 861 | 960 | EKind = getBitcodeELFKind(T); |
| ... | ... | @@ -877,7 +976,7 @@ static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) { |
| 877 | 976 | template <class ELFT> |
| 878 | 977 | static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats, |
| 879 | 978 | const lto::InputFile::Symbol &ObjSym, |
| 880 | BitcodeFile *F) { | |
| 979 | BitcodeFile &F) { | |
| 881 | 980 | StringRef NameRef = Saver.save(ObjSym.getName()); |
| 882 | 981 | uint32_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL; |
| 883 | 982 | |
| ... | ... | @@ -887,22 +986,20 @@ static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats, |
| 887 | 986 | |
| 888 | 987 | int C = ObjSym.getComdatIndex(); |
| 889 | 988 | if (C != -1 && !KeptComdats[C]) |
| 890 | return Symtab<ELFT>::X->addUndefined(NameRef, /*IsLocal=*/false, Binding, | |
| 891 | Visibility, Type, CanOmitFromDynSym, | |
| 892 | F); | |
| 989 | return Symtab->addUndefined<ELFT>(NameRef, Binding, Visibility, Type, | |
| 990 | CanOmitFromDynSym, &F); | |
| 893 | 991 | |
| 894 | 992 | if (ObjSym.isUndefined()) |
| 895 | return Symtab<ELFT>::X->addUndefined(NameRef, /*IsLocal=*/false, Binding, | |
| 896 | Visibility, Type, CanOmitFromDynSym, | |
| 897 | F); | |
| 993 | return Symtab->addUndefined<ELFT>(NameRef, Binding, Visibility, Type, | |
| 994 | CanOmitFromDynSym, &F); | |
| 898 | 995 | |
| 899 | 996 | if (ObjSym.isCommon()) |
| 900 | return Symtab<ELFT>::X->addCommon(NameRef, ObjSym.getCommonSize(), | |
| 901 | ObjSym.getCommonAlignment(), Binding, | |
| 902 | Visibility, STT_OBJECT, F); | |
| 997 | return Symtab->addCommon(NameRef, ObjSym.getCommonSize(), | |
| 998 | ObjSym.getCommonAlignment(), Binding, Visibility, | |
| 999 | STT_OBJECT, F); | |
| 903 | 1000 | |
| 904 | return Symtab<ELFT>::X->addBitcode(NameRef, Binding, Visibility, Type, | |
| 905 | CanOmitFromDynSym, F); | |
| 1001 | return Symtab->addBitcode(NameRef, Binding, Visibility, Type, | |
| 1002 | CanOmitFromDynSym, F); | |
| 906 | 1003 | } |
| 907 | 1004 | |
| 908 | 1005 | template <class ELFT> |
| ... | ... | @@ -912,7 +1009,7 @@ void BitcodeFile::parse(DenseSet<CachedHashStringRef> &ComdatGroups) { |
| 912 | 1009 | KeptComdats.push_back(ComdatGroups.insert(CachedHashStringRef(S)).second); |
| 913 | 1010 | |
| 914 | 1011 | for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) |
| 915 | Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, this)); | |
| 1012 | Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, *this)); | |
| 916 | 1013 | } |
| 917 | 1014 | |
| 918 | 1015 | static ELFKind getELFKind(MemoryBufferRef MB) { |
| ... | ... | @@ -935,10 +1032,10 @@ static ELFKind getELFKind(MemoryBufferRef MB) { |
| 935 | 1032 | return (Endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind; |
| 936 | 1033 | } |
| 937 | 1034 | |
| 938 | template <class ELFT> void BinaryFile::parse() { | |
| 1035 | void BinaryFile::parse() { | |
| 939 | 1036 | ArrayRef<uint8_t> Data = toArrayRef(MB.getBuffer()); |
| 940 | auto *Section = | |
| 941 | make<InputSection>(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, 8, Data, ".data"); | |
| 1037 | auto *Section = make<InputSection>(nullptr, SHF_ALLOC | SHF_WRITE, | |
| 1038 | SHT_PROGBITS, 8, Data, ".data"); | |
| 942 | 1039 | Sections.push_back(Section); |
| 943 | 1040 | |
| 944 | 1041 | // For each input file foo that is embedded to a result as a binary |
| ... | ... | @@ -947,18 +1044,15 @@ template <class ELFT> void BinaryFile::parse() { |
| 947 | 1044 | // characters in a filename are replaced with underscore. |
| 948 | 1045 | std::string S = "_binary_" + MB.getBufferIdentifier().str(); |
| 949 | 1046 | for (size_t I = 0; I < S.size(); ++I) |
| 950 | if (!isalnum(S[I])) | |
| 1047 | if (!isAlnum(S[I])) | |
| 951 | 1048 | S[I] = '_'; |
| 952 | 1049 | |
| 953 | elf::Symtab<ELFT>::X->addRegular(Saver.save(S + "_start"), STV_DEFAULT, | |
| 954 | STT_OBJECT, 0, 0, STB_GLOBAL, Section, | |
| 955 | nullptr); | |
| 956 | elf::Symtab<ELFT>::X->addRegular(Saver.save(S + "_end"), STV_DEFAULT, | |
| 957 | STT_OBJECT, Data.size(), 0, STB_GLOBAL, | |
| 958 | Section, nullptr); | |
| 959 | elf::Symtab<ELFT>::X->addRegular(Saver.save(S + "_size"), STV_DEFAULT, | |
| 960 | STT_OBJECT, Data.size(), 0, STB_GLOBAL, | |
| 961 | nullptr, nullptr); | |
| 1050 | Symtab->addRegular(Saver.save(S + "_start"), STV_DEFAULT, STT_OBJECT, 0, 0, | |
| 1051 | STB_GLOBAL, Section, nullptr); | |
| 1052 | Symtab->addRegular(Saver.save(S + "_end"), STV_DEFAULT, STT_OBJECT, | |
| 1053 | Data.size(), 0, STB_GLOBAL, Section, nullptr); | |
| 1054 | Symtab->addRegular(Saver.save(S + "_size"), STV_DEFAULT, STT_OBJECT, | |
| 1055 | Data.size(), 0, STB_GLOBAL, nullptr, nullptr); | |
| 962 | 1056 | } |
| 963 | 1057 | |
| 964 | 1058 | static bool isBitcode(MemoryBufferRef MB) { |
| ... | ... | @@ -973,13 +1067,13 @@ InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName, |
| 973 | 1067 | |
| 974 | 1068 | switch (getELFKind(MB)) { |
| 975 | 1069 | case ELF32LEKind: |
| 976 | return make<ObjectFile<ELF32LE>>(MB, ArchiveName); | |
| 1070 | return make<ObjFile<ELF32LE>>(MB, ArchiveName); | |
| 977 | 1071 | case ELF32BEKind: |
| 978 | return make<ObjectFile<ELF32BE>>(MB, ArchiveName); | |
| 1072 | return make<ObjFile<ELF32BE>>(MB, ArchiveName); | |
| 979 | 1073 | case ELF64LEKind: |
| 980 | return make<ObjectFile<ELF64LE>>(MB, ArchiveName); | |
| 1074 | return make<ObjFile<ELF64LE>>(MB, ArchiveName); | |
| 981 | 1075 | case ELF64BEKind: |
| 982 | return make<ObjectFile<ELF64BE>>(MB, ArchiveName); | |
| 1076 | return make<ObjFile<ELF64BE>>(MB, ArchiveName); | |
| 983 | 1077 | default: |
| 984 | 1078 | llvm_unreachable("getELFKind"); |
| 985 | 1079 | } |
| ... | ... | @@ -1000,53 +1094,53 @@ InputFile *elf::createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName) { |
| 1000 | 1094 | } |
| 1001 | 1095 | } |
| 1002 | 1096 | |
| 1003 | MemoryBufferRef LazyObjectFile::getBuffer() { | |
| 1097 | MemoryBufferRef LazyObjFile::getBuffer() { | |
| 1004 | 1098 | if (Seen) |
| 1005 | 1099 | return MemoryBufferRef(); |
| 1006 | 1100 | Seen = true; |
| 1007 | 1101 | return MB; |
| 1008 | 1102 | } |
| 1009 | 1103 | |
| 1010 | InputFile *LazyObjectFile::fetch() { | |
| 1104 | InputFile *LazyObjFile::fetch() { | |
| 1011 | 1105 | MemoryBufferRef MBRef = getBuffer(); |
| 1012 | 1106 | if (MBRef.getBuffer().empty()) |
| 1013 | 1107 | return nullptr; |
| 1014 | 1108 | return createObjectFile(MBRef, ArchiveName, OffsetInArchive); |
| 1015 | 1109 | } |
| 1016 | 1110 | |
| 1017 | template <class ELFT> void LazyObjectFile::parse() { | |
| 1018 | for (StringRef Sym : getSymbols()) | |
| 1019 | Symtab<ELFT>::X->addLazyObject(Sym, *this); | |
| 1111 | template <class ELFT> void LazyObjFile::parse() { | |
| 1112 | for (StringRef Sym : getSymbolNames()) | |
| 1113 | Symtab->addLazyObject<ELFT>(Sym, *this); | |
| 1020 | 1114 | } |
| 1021 | 1115 | |
| 1022 | template <class ELFT> std::vector<StringRef> LazyObjectFile::getElfSymbols() { | |
| 1116 | template <class ELFT> std::vector<StringRef> LazyObjFile::getElfSymbols() { | |
| 1023 | 1117 | typedef typename ELFT::Shdr Elf_Shdr; |
| 1024 | 1118 | typedef typename ELFT::Sym Elf_Sym; |
| 1025 | 1119 | typedef typename ELFT::SymRange Elf_Sym_Range; |
| 1026 | 1120 | |
| 1027 | const ELFFile<ELFT> Obj(this->MB.getBuffer()); | |
| 1028 | ArrayRef<Elf_Shdr> Sections = check(Obj.sections(), toString(this)); | |
| 1121 | ELFFile<ELFT> Obj = check(ELFFile<ELFT>::create(this->MB.getBuffer())); | |
| 1122 | ArrayRef<Elf_Shdr> Sections = CHECK(Obj.sections(), this); | |
| 1029 | 1123 | for (const Elf_Shdr &Sec : Sections) { |
| 1030 | 1124 | if (Sec.sh_type != SHT_SYMTAB) |
| 1031 | 1125 | continue; |
| 1032 | 1126 | |
| 1033 | Elf_Sym_Range Syms = check(Obj.symbols(&Sec), toString(this)); | |
| 1127 | Elf_Sym_Range Syms = CHECK(Obj.symbols(&Sec), this); | |
| 1034 | 1128 | uint32_t FirstNonLocal = Sec.sh_info; |
| 1035 | 1129 | StringRef StringTable = |
| 1036 | check(Obj.getStringTableForSymtab(Sec, Sections), toString(this)); | |
| 1130 | CHECK(Obj.getStringTableForSymtab(Sec, Sections), this); | |
| 1037 | 1131 | std::vector<StringRef> V; |
| 1038 | 1132 | |
| 1039 | 1133 | for (const Elf_Sym &Sym : Syms.slice(FirstNonLocal)) |
| 1040 | 1134 | if (Sym.st_shndx != SHN_UNDEF) |
| 1041 | V.push_back(check(Sym.getName(StringTable), toString(this))); | |
| 1135 | V.push_back(CHECK(Sym.getName(StringTable), this)); | |
| 1042 | 1136 | return V; |
| 1043 | 1137 | } |
| 1044 | 1138 | return {}; |
| 1045 | 1139 | } |
| 1046 | 1140 | |
| 1047 | std::vector<StringRef> LazyObjectFile::getBitcodeSymbols() { | |
| 1141 | std::vector<StringRef> LazyObjFile::getBitcodeSymbols() { | |
| 1048 | 1142 | std::unique_ptr<lto::InputFile> Obj = |
| 1049 | check(lto::InputFile::create(this->MB), toString(this)); | |
| 1143 | CHECK(lto::InputFile::create(this->MB), this); | |
| 1050 | 1144 | std::vector<StringRef> V; |
| 1051 | 1145 | for (const lto::InputFile::Symbol &Sym : Obj->symbols()) |
| 1052 | 1146 | if (!Sym.isUndefined()) |
| ... | ... | @@ -1055,7 +1149,7 @@ std::vector<StringRef> LazyObjectFile::getBitcodeSymbols() { |
| 1055 | 1149 | } |
| 1056 | 1150 | |
| 1057 | 1151 | // Returns a vector of globally-visible defined symbol names. |
| 1058 | std::vector<StringRef> LazyObjectFile::getSymbols() { | |
| 1152 | std::vector<StringRef> LazyObjFile::getSymbolNames() { | |
| 1059 | 1153 | if (isBitcode(this->MB)) |
| 1060 | 1154 | return getBitcodeSymbols(); |
| 1061 | 1155 | |
| ... | ... | @@ -1083,27 +1177,22 @@ template void BitcodeFile::parse<ELF32BE>(DenseSet<CachedHashStringRef> &); |
| 1083 | 1177 | template void BitcodeFile::parse<ELF64LE>(DenseSet<CachedHashStringRef> &); |
| 1084 | 1178 | template void BitcodeFile::parse<ELF64BE>(DenseSet<CachedHashStringRef> &); |
| 1085 | 1179 | |
| 1086 | template void LazyObjectFile::parse<ELF32LE>(); | |
| 1087 | template void LazyObjectFile::parse<ELF32BE>(); | |
| 1088 | template void LazyObjectFile::parse<ELF64LE>(); | |
| 1089 | template void LazyObjectFile::parse<ELF64BE>(); | |
| 1180 | template void LazyObjFile::parse<ELF32LE>(); | |
| 1181 | template void LazyObjFile::parse<ELF32BE>(); | |
| 1182 | template void LazyObjFile::parse<ELF64LE>(); | |
| 1183 | template void LazyObjFile::parse<ELF64BE>(); | |
| 1090 | 1184 | |
| 1091 | 1185 | template class elf::ELFFileBase<ELF32LE>; |
| 1092 | 1186 | template class elf::ELFFileBase<ELF32BE>; |
| 1093 | 1187 | template class elf::ELFFileBase<ELF64LE>; |
| 1094 | 1188 | template class elf::ELFFileBase<ELF64BE>; |
| 1095 | 1189 | |
| 1096 | template class elf::ObjectFile<ELF32LE>; | |
| 1097 | template class elf::ObjectFile<ELF32BE>; | |
| 1098 | template class elf::ObjectFile<ELF64LE>; | |
| 1099 | template class elf::ObjectFile<ELF64BE>; | |
| 1190 | template class elf::ObjFile<ELF32LE>; | |
| 1191 | template class elf::ObjFile<ELF32BE>; | |
| 1192 | template class elf::ObjFile<ELF64LE>; | |
| 1193 | template class elf::ObjFile<ELF64BE>; | |
| 1100 | 1194 | |
| 1101 | 1195 | template class elf::SharedFile<ELF32LE>; |
| 1102 | 1196 | template class elf::SharedFile<ELF32BE>; |
| 1103 | 1197 | template class elf::SharedFile<ELF64LE>; |
| 1104 | 1198 | template class elf::SharedFile<ELF64BE>; |
| 1105 | ||
| 1106 | template void BinaryFile::parse<ELF32LE>(); | |
| 1107 | template void BinaryFile::parse<ELF32BE>(); | |
| 1108 | template void BinaryFile::parse<ELF64LE>(); | |
| 1109 | template void BinaryFile::parse<ELF64BE>(); |
deps/lld/ELF/InputFiles.h+60-58| ... | ... | @@ -11,12 +11,10 @@ |
| 11 | 11 | #define LLD_ELF_INPUT_FILES_H |
| 12 | 12 | |
| 13 | 13 | #include "Config.h" |
| 14 | #include "Error.h" | |
| 15 | #include "InputSection.h" | |
| 16 | #include "Symbols.h" | |
| 14 | #include "lld/Common/ErrorHandler.h" | |
| 17 | 15 | |
| 18 | #include "lld/Core/LLVM.h" | |
| 19 | #include "lld/Core/Reproduce.h" | |
| 16 | #include "lld/Common/LLVM.h" | |
| 17 | #include "lld/Common/Reproduce.h" | |
| 20 | 18 | #include "llvm/ADT/CachedHashString.h" |
| 21 | 19 | #include "llvm/ADT/DenseSet.h" |
| 22 | 20 | #include "llvm/ADT/STLExtras.h" |
| ... | ... | @@ -40,9 +38,10 @@ class InputFile; |
| 40 | 38 | namespace lld { |
| 41 | 39 | namespace elf { |
| 42 | 40 | class InputFile; |
| 41 | class InputSectionBase; | |
| 43 | 42 | } |
| 44 | 43 | |
| 45 | // Returns "(internal)", "foo.a(bar.o)" or "baz.o". | |
| 44 | // Returns "<internal>", "foo.a(bar.o)" or "baz.o". | |
| 46 | 45 | std::string toString(const elf::InputFile *F); |
| 47 | 46 | |
| 48 | 47 | namespace elf { |
| ... | ... | @@ -50,7 +49,7 @@ namespace elf { |
| 50 | 49 | using llvm::object::Archive; |
| 51 | 50 | |
| 52 | 51 | class Lazy; |
| 53 | class SymbolBody; | |
| 52 | class Symbol; | |
| 54 | 53 | |
| 55 | 54 | // If -reproduce option is given, all input files are written |
| 56 | 55 | // to this tar archive. |
| ... | ... | @@ -63,9 +62,9 @@ llvm::Optional<MemoryBufferRef> readFile(StringRef Path); |
| 63 | 62 | class InputFile { |
| 64 | 63 | public: |
| 65 | 64 | enum Kind { |
| 66 | ObjectKind, | |
| 65 | ObjKind, | |
| 67 | 66 | SharedKind, |
| 68 | LazyObjectKind, | |
| 67 | LazyObjKind, | |
| 69 | 68 | ArchiveKind, |
| 70 | 69 | BitcodeKind, |
| 71 | 70 | BinaryKind, |
| ... | ... | @@ -73,16 +72,29 @@ public: |
| 73 | 72 | |
| 74 | 73 | Kind kind() const { return FileKind; } |
| 75 | 74 | |
| 75 | bool isElf() const { | |
| 76 | Kind K = kind(); | |
| 77 | return K == ObjKind || K == SharedKind; | |
| 78 | } | |
| 79 | ||
| 76 | 80 | StringRef getName() const { return MB.getBufferIdentifier(); } |
| 77 | 81 | MemoryBufferRef MB; |
| 78 | 82 | |
| 79 | 83 | // Returns sections. It is a runtime error to call this function |
| 80 | 84 | // on files that don't have the notion of sections. |
| 81 | 85 | ArrayRef<InputSectionBase *> getSections() const { |
| 82 | assert(FileKind == ObjectKind || FileKind == BinaryKind); | |
| 86 | assert(FileKind == ObjKind || FileKind == BinaryKind); | |
| 83 | 87 | return Sections; |
| 84 | 88 | } |
| 85 | 89 | |
| 90 | // Returns object file symbols. It is a runtime error to call this | |
| 91 | // function on files of other types. | |
| 92 | ArrayRef<Symbol *> getSymbols() { | |
| 93 | assert(FileKind == ObjKind || FileKind == BitcodeKind || | |
| 94 | FileKind == ArchiveKind); | |
| 95 | return Symbols; | |
| 96 | } | |
| 97 | ||
| 86 | 98 | // Filename of .a which contained this file. If this file was |
| 87 | 99 | // not in an archive file, it is the empty string. We use this |
| 88 | 100 | // string for creating error messages. |
| ... | ... | @@ -97,9 +109,13 @@ public: |
| 97 | 109 | // Cache for toString(). Only toString() should use this member. |
| 98 | 110 | mutable std::string ToStringCache; |
| 99 | 111 | |
| 112 | std::string getSrcMsg(const Symbol &Sym, InputSectionBase &Sec, | |
| 113 | uint64_t Offset); | |
| 114 | ||
| 100 | 115 | protected: |
| 101 | 116 | InputFile(Kind K, MemoryBufferRef M); |
| 102 | 117 | std::vector<InputSectionBase *> Sections; |
| 118 | std::vector<Symbol *> Symbols; | |
| 103 | 119 | |
| 104 | 120 | private: |
| 105 | 121 | const Kind FileKind; |
| ... | ... | @@ -113,23 +129,21 @@ public: |
| 113 | 129 | typedef typename ELFT::SymRange Elf_Sym_Range; |
| 114 | 130 | |
| 115 | 131 | ELFFileBase(Kind K, MemoryBufferRef M); |
| 116 | static bool classof(const InputFile *F) { | |
| 117 | Kind K = F->kind(); | |
| 118 | return K == ObjectKind || K == SharedKind; | |
| 119 | } | |
| 132 | static bool classof(const InputFile *F) { return F->isElf(); } | |
| 120 | 133 | |
| 121 | 134 | llvm::object::ELFFile<ELFT> getObj() const { |
| 122 | return llvm::object::ELFFile<ELFT>(MB.getBuffer()); | |
| 135 | return check(llvm::object::ELFFile<ELFT>::create(MB.getBuffer())); | |
| 123 | 136 | } |
| 124 | 137 | |
| 125 | 138 | StringRef getStringTable() const { return StringTable; } |
| 126 | 139 | |
| 127 | 140 | uint32_t getSectionIndex(const Elf_Sym &Sym) const; |
| 128 | 141 | |
| 129 | Elf_Sym_Range getGlobalSymbols(); | |
| 142 | Elf_Sym_Range getGlobalELFSyms(); | |
| 143 | Elf_Sym_Range getELFSyms() const { return ELFSyms; } | |
| 130 | 144 | |
| 131 | 145 | protected: |
| 132 | ArrayRef<Elf_Sym> Symbols; | |
| 146 | ArrayRef<Elf_Sym> ELFSyms; | |
| 133 | 147 | uint32_t FirstNonLocal = 0; |
| 134 | 148 | ArrayRef<Elf_Word> SymtabSHNDX; |
| 135 | 149 | StringRef StringTable; |
| ... | ... | @@ -137,7 +151,7 @@ protected: |
| 137 | 151 | }; |
| 138 | 152 | |
| 139 | 153 | // .o file. |
| 140 | template <class ELFT> class ObjectFile : public ELFFileBase<ELFT> { | |
| 154 | template <class ELFT> class ObjFile : public ELFFileBase<ELFT> { | |
| 141 | 155 | typedef ELFFileBase<ELFT> Base; |
| 142 | 156 | typedef typename ELFT::Rel Elf_Rel; |
| 143 | 157 | typedef typename ELFT::Rela Elf_Rela; |
| ... | ... | @@ -150,34 +164,29 @@ template <class ELFT> class ObjectFile : public ELFFileBase<ELFT> { |
| 150 | 164 | ArrayRef<Elf_Word> getShtGroupEntries(const Elf_Shdr &Sec); |
| 151 | 165 | |
| 152 | 166 | public: |
| 153 | static bool classof(const InputFile *F) { | |
| 154 | return F->kind() == Base::ObjectKind; | |
| 155 | } | |
| 167 | static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; } | |
| 156 | 168 | |
| 157 | ArrayRef<SymbolBody *> getSymbols(); | |
| 158 | ArrayRef<SymbolBody *> getLocalSymbols(); | |
| 169 | ArrayRef<Symbol *> getLocalSymbols(); | |
| 159 | 170 | |
| 160 | ObjectFile(MemoryBufferRef M, StringRef ArchiveName); | |
| 171 | ObjFile(MemoryBufferRef M, StringRef ArchiveName); | |
| 161 | 172 | void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups); |
| 162 | 173 | |
| 163 | InputSectionBase *getSection(const Elf_Sym &Sym) const; | |
| 164 | ||
| 165 | SymbolBody &getSymbolBody(uint32_t SymbolIndex) const { | |
| 166 | if (SymbolIndex >= SymbolBodies.size()) | |
| 174 | Symbol &getSymbol(uint32_t SymbolIndex) const { | |
| 175 | if (SymbolIndex >= this->Symbols.size()) | |
| 167 | 176 | fatal(toString(this) + ": invalid symbol index"); |
| 168 | return *SymbolBodies[SymbolIndex]; | |
| 177 | return *this->Symbols[SymbolIndex]; | |
| 169 | 178 | } |
| 170 | 179 | |
| 171 | template <typename RelT> | |
| 172 | SymbolBody &getRelocTargetSym(const RelT &Rel) const { | |
| 180 | template <typename RelT> Symbol &getRelocTargetSym(const RelT &Rel) const { | |
| 173 | 181 | uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL); |
| 174 | return getSymbolBody(SymIndex); | |
| 182 | return getSymbol(SymIndex); | |
| 175 | 183 | } |
| 176 | 184 | |
| 177 | 185 | // Returns source line information for a given offset. |
| 178 | 186 | // If no information is available, returns "". |
| 179 | 187 | std::string getLineInfo(InputSectionBase *S, uint64_t Offset); |
| 180 | 188 | llvm::Optional<llvm::DILineInfo> getDILineInfo(InputSectionBase *, uint64_t); |
| 189 | llvm::Optional<std::pair<std::string, unsigned>> getVariableLoc(StringRef Name); | |
| 181 | 190 | |
| 182 | 191 | // MIPS GP0 value defined by this file. This value represents the gp value |
| 183 | 192 | // used to create the relocatable object and required to support |
| ... | ... | @@ -193,16 +202,13 @@ private: |
| 193 | 202 | void |
| 194 | 203 | initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups); |
| 195 | 204 | void initializeSymbols(); |
| 196 | void initializeDwarfLine(); | |
| 205 | void initializeDwarf(); | |
| 197 | 206 | InputSectionBase *getRelocTarget(const Elf_Shdr &Sec); |
| 198 | 207 | InputSectionBase *createInputSection(const Elf_Shdr &Sec); |
| 199 | 208 | StringRef getSectionName(const Elf_Shdr &Sec); |
| 200 | 209 | |
| 201 | 210 | bool shouldMerge(const Elf_Shdr &Sec); |
| 202 | SymbolBody *createSymbolBody(const Elf_Sym *Sym); | |
| 203 | ||
| 204 | // List of all symbols referenced or defined by this file. | |
| 205 | std::vector<SymbolBody *> SymbolBodies; | |
| 211 | Symbol *createSymbol(const Elf_Sym *Sym); | |
| 206 | 212 | |
| 207 | 213 | // .shstrtab contents. |
| 208 | 214 | StringRef SectionStringTable; |
| ... | ... | @@ -212,34 +218,33 @@ private: |
| 212 | 218 | // single object file, so we cache debugging information in order to |
| 213 | 219 | // parse it only once for each object file we link. |
| 214 | 220 | std::unique_ptr<llvm::DWARFDebugLine> DwarfLine; |
| 221 | llvm::DenseMap<StringRef, std::pair<unsigned, unsigned>> VariableLoc; | |
| 215 | 222 | llvm::once_flag InitDwarfLine; |
| 216 | 223 | }; |
| 217 | 224 | |
| 218 | // LazyObjectFile is analogous to ArchiveFile in the sense that | |
| 225 | // LazyObjFile is analogous to ArchiveFile in the sense that | |
| 219 | 226 | // the file contains lazy symbols. The difference is that |
| 220 | // LazyObjectFile wraps a single file instead of multiple files. | |
| 227 | // LazyObjFile wraps a single file instead of multiple files. | |
| 221 | 228 | // |
| 222 | 229 | // This class is used for --start-lib and --end-lib options which |
| 223 | 230 | // instruct the linker to link object files between them with the |
| 224 | 231 | // archive file semantics. |
| 225 | class LazyObjectFile : public InputFile { | |
| 232 | class LazyObjFile : public InputFile { | |
| 226 | 233 | public: |
| 227 | LazyObjectFile(MemoryBufferRef M, StringRef ArchiveName, | |
| 228 | uint64_t OffsetInArchive) | |
| 229 | : InputFile(LazyObjectKind, M), OffsetInArchive(OffsetInArchive) { | |
| 234 | LazyObjFile(MemoryBufferRef M, StringRef ArchiveName, | |
| 235 | uint64_t OffsetInArchive) | |
| 236 | : InputFile(LazyObjKind, M), OffsetInArchive(OffsetInArchive) { | |
| 230 | 237 | this->ArchiveName = ArchiveName; |
| 231 | 238 | } |
| 232 | 239 | |
| 233 | static bool classof(const InputFile *F) { | |
| 234 | return F->kind() == LazyObjectKind; | |
| 235 | } | |
| 240 | static bool classof(const InputFile *F) { return F->kind() == LazyObjKind; } | |
| 236 | 241 | |
| 237 | 242 | template <class ELFT> void parse(); |
| 238 | 243 | MemoryBufferRef getBuffer(); |
| 239 | 244 | InputFile *fetch(); |
| 240 | 245 | |
| 241 | 246 | private: |
| 242 | std::vector<StringRef> getSymbols(); | |
| 247 | std::vector<StringRef> getSymbolNames(); | |
| 243 | 248 | template <class ELFT> std::vector<StringRef> getElfSymbols(); |
| 244 | 249 | std::vector<StringRef> getBitcodeSymbols(); |
| 245 | 250 | |
| ... | ... | @@ -253,7 +258,6 @@ public: |
| 253 | 258 | explicit ArchiveFile(std::unique_ptr<Archive> &&File); |
| 254 | 259 | static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; } |
| 255 | 260 | template <class ELFT> void parse(); |
| 256 | ArrayRef<Symbol *> getSymbols() { return Symbols; } | |
| 257 | 261 | |
| 258 | 262 | // Returns a memory buffer for a given symbol and the offset in the archive |
| 259 | 263 | // for the member. An empty memory buffer and an offset of zero |
| ... | ... | @@ -264,7 +268,6 @@ public: |
| 264 | 268 | private: |
| 265 | 269 | std::unique_ptr<Archive> File; |
| 266 | 270 | llvm::DenseSet<uint64_t> Seen; |
| 267 | std::vector<Symbol *> Symbols; | |
| 268 | 271 | }; |
| 269 | 272 | |
| 270 | 273 | class BitcodeFile : public InputFile { |
| ... | ... | @@ -274,11 +277,7 @@ public: |
| 274 | 277 | static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; } |
| 275 | 278 | template <class ELFT> |
| 276 | 279 | void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups); |
| 277 | ArrayRef<Symbol *> getSymbols() { return Symbols; } | |
| 278 | 280 | std::unique_ptr<llvm::lto::InputFile> Obj; |
| 279 | ||
| 280 | private: | |
| 281 | std::vector<Symbol *> Symbols; | |
| 282 | 281 | }; |
| 283 | 282 | |
| 284 | 283 | // .so file. |
| ... | ... | @@ -296,9 +295,9 @@ template <class ELFT> class SharedFile : public ELFFileBase<ELFT> { |
| 296 | 295 | const Elf_Shdr *VerdefSec = nullptr; |
| 297 | 296 | |
| 298 | 297 | public: |
| 298 | std::vector<const Elf_Verdef *> Verdefs; | |
| 299 | 299 | std::string SoName; |
| 300 | 300 | |
| 301 | const Elf_Shdr *getSection(const Elf_Sym &Sym) const; | |
| 302 | 301 | llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; } |
| 303 | 302 | |
| 304 | 303 | static bool classof(const InputFile *F) { |
| ... | ... | @@ -324,22 +323,25 @@ public: |
| 324 | 323 | std::map<const Elf_Verdef *, NeededVer> VerdefMap; |
| 325 | 324 | |
| 326 | 325 | // Used for --as-needed |
| 327 | bool AsNeeded = false; | |
| 328 | bool IsUsed = false; | |
| 329 | bool isNeeded() const { return !AsNeeded || IsUsed; } | |
| 326 | bool IsNeeded; | |
| 330 | 327 | }; |
| 331 | 328 | |
| 332 | 329 | class BinaryFile : public InputFile { |
| 333 | 330 | public: |
| 334 | 331 | explicit BinaryFile(MemoryBufferRef M) : InputFile(BinaryKind, M) {} |
| 335 | 332 | static bool classof(const InputFile *F) { return F->kind() == BinaryKind; } |
| 336 | template <class ELFT> void parse(); | |
| 333 | void parse(); | |
| 337 | 334 | }; |
| 338 | 335 | |
| 339 | 336 | InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "", |
| 340 | 337 | uint64_t OffsetInArchive = 0); |
| 341 | 338 | InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName); |
| 342 | 339 | |
| 340 | extern std::vector<BinaryFile *> BinaryFiles; | |
| 341 | extern std::vector<BitcodeFile *> BitcodeFiles; | |
| 342 | extern std::vector<InputFile *> ObjectFiles; | |
| 343 | extern std::vector<InputFile *> SharedFiles; | |
| 344 | ||
| 343 | 345 | } // namespace elf |
| 344 | 346 | } // namespace lld |
| 345 | 347 |
deps/lld/ELF/InputSection.cpp+260-276| ... | ... | @@ -10,21 +10,22 @@ |
| 10 | 10 | #include "InputSection.h" |
| 11 | 11 | #include "Config.h" |
| 12 | 12 | #include "EhFrame.h" |
| 13 | #include "Error.h" | |
| 14 | 13 | #include "InputFiles.h" |
| 15 | 14 | #include "LinkerScript.h" |
| 16 | #include "Memory.h" | |
| 17 | 15 | #include "OutputSections.h" |
| 18 | 16 | #include "Relocations.h" |
| 17 | #include "Symbols.h" | |
| 19 | 18 | #include "SyntheticSections.h" |
| 20 | 19 | #include "Target.h" |
| 21 | 20 | #include "Thunks.h" |
| 21 | #include "lld/Common/ErrorHandler.h" | |
| 22 | #include "lld/Common/Memory.h" | |
| 22 | 23 | #include "llvm/Object/Decompressor.h" |
| 23 | 24 | #include "llvm/Support/Compiler.h" |
| 24 | 25 | #include "llvm/Support/Compression.h" |
| 25 | 26 | #include "llvm/Support/Endian.h" |
| 26 | #include "llvm/Support/Path.h" | |
| 27 | 27 | #include "llvm/Support/Threading.h" |
| 28 | #include "llvm/Support/xxhash.h" | |
| 28 | 29 | #include <mutex> |
| 29 | 30 | |
| 30 | 31 | using namespace llvm; |
| ... | ... | @@ -44,12 +45,38 @@ std::string lld::toString(const InputSectionBase *Sec) { |
| 44 | 45 | return (toString(Sec->File) + ":(" + Sec->Name + ")").str(); |
| 45 | 46 | } |
| 46 | 47 | |
| 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 | ||
| 47 | 74 | template <class ELFT> |
| 48 | static ArrayRef<uint8_t> getSectionContents(elf::ObjectFile<ELFT> *File, | |
| 49 | const typename ELFT::Shdr *Hdr) { | |
| 50 | if (!File || Hdr->sh_type == SHT_NOBITS) | |
| 51 | return makeArrayRef<uint8_t>(nullptr, Hdr->sh_size); | |
| 52 | return check(File->getObj().getSectionContents(Hdr)); | |
| 75 | static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> &File, | |
| 76 | const typename ELFT::Shdr &Hdr) { | |
| 77 | if (Hdr.sh_type == SHT_NOBITS) | |
| 78 | return makeArrayRef<uint8_t>(nullptr, Hdr.sh_size); | |
| 79 | return check(File.getObj().getSectionContents(&Hdr)); | |
| 53 | 80 | } |
| 54 | 81 | |
| 55 | 82 | InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags, |
| ... | ... | @@ -59,9 +86,13 @@ InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags, |
| 59 | 86 | StringRef Name, Kind SectionKind) |
| 60 | 87 | : SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info, |
| 61 | 88 | Link), |
| 62 | File(File), Data(Data), Repl(this) { | |
| 63 | Live = !Config->GcSections || !(Flags & SHF_ALLOC); | |
| 64 | Assigned = false; | |
| 89 | File(File), Data(Data) { | |
| 90 | // In order to reduce memory allocation, we assume that mergeable | |
| 91 | // sections are smaller than 4 GiB, which is not an unreasonable | |
| 92 | // assumption as of 2017. | |
| 93 | if (SectionKind == SectionBase::Merge && Data.size() > UINT32_MAX) | |
| 94 | error(toString(this) + ": section too large"); | |
| 95 | ||
| 65 | 96 | NumRelocations = 0; |
| 66 | 97 | AreRelocsRela = false; |
| 67 | 98 | |
| ... | ... | @@ -102,18 +133,18 @@ static uint64_t getType(uint64_t Type, StringRef Name) { |
| 102 | 133 | } |
| 103 | 134 | |
| 104 | 135 | template <class ELFT> |
| 105 | InputSectionBase::InputSectionBase(elf::ObjectFile<ELFT> *File, | |
| 106 | const typename ELFT::Shdr *Hdr, | |
| 136 | InputSectionBase::InputSectionBase(ObjFile<ELFT> &File, | |
| 137 | const typename ELFT::Shdr &Hdr, | |
| 107 | 138 | StringRef Name, Kind SectionKind) |
| 108 | : InputSectionBase(File, getFlags(Hdr->sh_flags), | |
| 109 | getType(Hdr->sh_type, Name), Hdr->sh_entsize, | |
| 110 | Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign, | |
| 139 | : InputSectionBase(&File, getFlags(Hdr.sh_flags), | |
| 140 | getType(Hdr.sh_type, Name), Hdr.sh_entsize, Hdr.sh_link, | |
| 141 | Hdr.sh_info, Hdr.sh_addralign, | |
| 111 | 142 | getSectionContents(File, Hdr), Name, SectionKind) { |
| 112 | 143 | // We reject object files having insanely large alignments even though |
| 113 | 144 | // they are allowed by the spec. I think 4GB is a reasonable limitation. |
| 114 | 145 | // We might want to relax this in the future. |
| 115 | if (Hdr->sh_addralign > UINT32_MAX) | |
| 116 | fatal(toString(File) + ": section sh_addralign is too large"); | |
| 146 | if (Hdr.sh_addralign > UINT32_MAX) | |
| 147 | fatal(toString(&File) + ": section sh_addralign is too large"); | |
| 117 | 148 | } |
| 118 | 149 | |
| 119 | 150 | size_t InputSectionBase::getSize() const { |
| ... | ... | @@ -160,7 +191,7 @@ uint64_t SectionBase::getOffset(uint64_t Offset) const { |
| 160 | 191 | OutputSection *SectionBase::getOutputSection() { |
| 161 | 192 | InputSection *Sec; |
| 162 | 193 | if (auto *IS = dyn_cast<InputSection>(this)) |
| 163 | Sec = IS; | |
| 194 | return IS->getParent(); | |
| 164 | 195 | else if (auto *MS = dyn_cast<MergeInputSection>(this)) |
| 165 | 196 | Sec = MS->getParent(); |
| 166 | 197 | else if (auto *EH = dyn_cast<EhInputSection>(this)) |
| ... | ... | @@ -170,29 +201,23 @@ OutputSection *SectionBase::getOutputSection() { |
| 170 | 201 | return Sec ? Sec->getParent() : nullptr; |
| 171 | 202 | } |
| 172 | 203 | |
| 173 | // Uncompress section contents. Note that this function is called | |
| 174 | // from parallel_for_each, so it must be thread-safe. | |
| 175 | void InputSectionBase::uncompress() { | |
| 204 | // Uncompress section contents if required. Note that this function | |
| 205 | // is called from parallelForEach, so it must be thread-safe. | |
| 206 | void InputSectionBase::maybeUncompress() { | |
| 207 | if (UncompressBuf || !Decompressor::isCompressedELFSection(Flags, Name)) | |
| 208 | return; | |
| 209 | ||
| 176 | 210 | Decompressor Dec = check(Decompressor::create(Name, toStringRef(Data), |
| 177 | 211 | Config->IsLE, Config->Is64)); |
| 178 | 212 | |
| 179 | 213 | size_t Size = Dec.getDecompressedSize(); |
| 180 | char *OutputBuf; | |
| 181 | { | |
| 182 | static std::mutex Mu; | |
| 183 | std::lock_guard<std::mutex> Lock(Mu); | |
| 184 | OutputBuf = BAlloc.Allocate<char>(Size); | |
| 185 | } | |
| 186 | ||
| 187 | if (Error E = Dec.decompress({OutputBuf, Size})) | |
| 214 | UncompressBuf.reset(new char[Size]()); | |
| 215 | if (Error E = Dec.decompress({UncompressBuf.get(), Size})) | |
| 188 | 216 | fatal(toString(this) + |
| 189 | 217 | ": decompress failed: " + llvm::toString(std::move(E))); |
| 190 | this->Data = ArrayRef<uint8_t>((uint8_t *)OutputBuf, Size); | |
| 191 | this->Flags &= ~(uint64_t)SHF_COMPRESSED; | |
| 192 | } | |
| 193 | 218 | |
| 194 | uint64_t SectionBase::getOffset(const DefinedRegular &Sym) const { | |
| 195 | return getOffset(Sym.Value); | |
| 219 | Data = makeArrayRef((uint8_t *)UncompressBuf.get(), Size); | |
| 220 | Flags &= ~(uint64_t)SHF_COMPRESSED; | |
| 196 | 221 | } |
| 197 | 222 | |
| 198 | 223 | InputSection *InputSectionBase::getLinkOrderDep() const { |
| ... | ... | @@ -200,9 +225,9 @@ InputSection *InputSectionBase::getLinkOrderDep() const { |
| 200 | 225 | InputSectionBase *L = File->getSections()[Link]; |
| 201 | 226 | if (auto *IS = dyn_cast<InputSection>(L)) |
| 202 | 227 | return IS; |
| 203 | error( | |
| 204 | "Merge and .eh_frame sections are not supported with SHF_LINK_ORDER " + | |
| 205 | toString(L)); | |
| 228 | error("a section with SHF_LINK_ORDER should not refer a non-regular " | |
| 229 | "section: " + | |
| 230 | toString(L)); | |
| 206 | 231 | } |
| 207 | 232 | return nullptr; |
| 208 | 233 | } |
| ... | ... | @@ -227,8 +252,8 @@ std::string InputSectionBase::getLocation(uint64_t Offset) { |
| 227 | 252 | SrcFile = toString(File); |
| 228 | 253 | |
| 229 | 254 | // Find a function symbol that encloses a given location. |
| 230 | for (SymbolBody *B : getFile<ELFT>()->getSymbols()) | |
| 231 | if (auto *D = dyn_cast<DefinedRegular>(B)) | |
| 255 | for (Symbol *B : File->getSymbols()) | |
| 256 | if (auto *D = dyn_cast<Defined>(B)) | |
| 232 | 257 | if (D->Section == this && D->Type == STT_FUNC) |
| 233 | 258 | if (D->Value <= Offset && Offset < D->Value + D->Size) |
| 234 | 259 | return SrcFile + ":(function " + toString(*D) + ")"; |
| ... | ... | @@ -237,31 +262,17 @@ std::string InputSectionBase::getLocation(uint64_t Offset) { |
| 237 | 262 | return (SrcFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")").str(); |
| 238 | 263 | } |
| 239 | 264 | |
| 240 | // Returns a source location string. This function is intended to be | |
| 241 | // used for constructing an error message. The returned message looks | |
| 242 | // like this: | |
| 265 | // This function is intended to be used for constructing an error message. | |
| 266 | // The returned message looks like this: | |
| 243 | 267 | // |
| 244 | 268 | // foo.c:42 (/home/alice/possibly/very/long/path/foo.c:42) |
| 245 | 269 | // |
| 246 | // Returns an empty string if there's no way to get line info. | |
| 247 | template <class ELFT> std::string InputSectionBase::getSrcMsg(uint64_t Offset) { | |
| 270 | // Returns an empty string if there's no way to get line info. | |
| 271 | std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) { | |
| 248 | 272 | // Synthetic sections don't have input files. |
| 249 | elf::ObjectFile<ELFT> *File = getFile<ELFT>(); | |
| 250 | 273 | if (!File) |
| 251 | 274 | return ""; |
| 252 | ||
| 253 | Optional<DILineInfo> Info = File->getDILineInfo(this, Offset); | |
| 254 | ||
| 255 | // File->SourceFile contains STT_FILE symbol, and that is a last resort. | |
| 256 | if (!Info) | |
| 257 | return File->SourceFile; | |
| 258 | ||
| 259 | std::string Path = Info->FileName; | |
| 260 | std::string Filename = path::filename(Path); | |
| 261 | std::string Lineno = ":" + std::to_string(Info->Line); | |
| 262 | if (Filename == Path) | |
| 263 | return Filename + Lineno; | |
| 264 | return Filename + Lineno + " (" + Path + Lineno + ")"; | |
| 275 | return File->getSrcMsg(Sym, *this, Offset); | |
| 265 | 276 | } |
| 266 | 277 | |
| 267 | 278 | // Returns a filename string along with an optional section name. This |
| ... | ... | @@ -273,11 +284,10 @@ template <class ELFT> std::string InputSectionBase::getSrcMsg(uint64_t Offset) { |
| 273 | 284 | // or |
| 274 | 285 | // |
| 275 | 286 | // path/to/foo.o:(function bar) in archive path/to/bar.a |
| 276 | template <class ELFT> std::string InputSectionBase::getObjMsg(uint64_t Off) { | |
| 287 | std::string InputSectionBase::getObjMsg(uint64_t Off) { | |
| 277 | 288 | // Synthetic sections don't have input files. |
| 278 | elf::ObjectFile<ELFT> *File = getFile<ELFT>(); | |
| 279 | 289 | if (!File) |
| 280 | return ("(internal):(" + Name + "+0x" + utohexstr(Off) + ")").str(); | |
| 290 | return ("<internal>:(" + Name + "+0x" + utohexstr(Off) + ")").str(); | |
| 281 | 291 | std::string Filename = File->getName(); |
| 282 | 292 | |
| 283 | 293 | std::string Archive; |
| ... | ... | @@ -285,8 +295,8 @@ template <class ELFT> std::string InputSectionBase::getObjMsg(uint64_t Off) { |
| 285 | 295 | Archive = (" in archive " + File->ArchiveName).str(); |
| 286 | 296 | |
| 287 | 297 | // Find a symbol that encloses a given location. |
| 288 | for (SymbolBody *B : getFile<ELFT>()->getSymbols()) | |
| 289 | if (auto *D = dyn_cast<DefinedRegular>(B)) | |
| 298 | for (Symbol *B : File->getSymbols()) | |
| 299 | if (auto *D = dyn_cast<Defined>(B)) | |
| 290 | 300 | if (D->Section == this && D->Value <= Off && Off < D->Value + D->Size) |
| 291 | 301 | return Filename + ":(" + toString(*D) + ")" + Archive; |
| 292 | 302 | |
| ... | ... | @@ -295,17 +305,18 @@ template <class ELFT> std::string InputSectionBase::getObjMsg(uint64_t Off) { |
| 295 | 305 | .str(); |
| 296 | 306 | } |
| 297 | 307 | |
| 298 | InputSectionBase InputSectionBase::Discarded; | |
| 308 | InputSection InputSection::Discarded(nullptr, 0, 0, 0, ArrayRef<uint8_t>(), ""); | |
| 299 | 309 | |
| 300 | InputSection::InputSection(uint64_t Flags, uint32_t Type, uint32_t Alignment, | |
| 301 | ArrayRef<uint8_t> Data, StringRef Name, Kind K) | |
| 302 | : InputSectionBase(nullptr, Flags, Type, | |
| 310 | InputSection::InputSection(InputFile *F, uint64_t Flags, uint32_t Type, | |
| 311 | uint32_t Alignment, ArrayRef<uint8_t> Data, | |
| 312 | StringRef Name, Kind K) | |
| 313 | : InputSectionBase(F, Flags, Type, | |
| 303 | 314 | /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, Alignment, Data, |
| 304 | 315 | Name, K) {} |
| 305 | 316 | |
| 306 | 317 | template <class ELFT> |
| 307 | InputSection::InputSection(elf::ObjectFile<ELFT> *F, | |
| 308 | const typename ELFT::Shdr *Header, StringRef Name) | |
| 318 | InputSection::InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header, | |
| 319 | StringRef Name) | |
| 309 | 320 | : InputSectionBase(F, Header, Name, InputSectionBase::Regular) {} |
| 310 | 321 | |
| 311 | 322 | bool InputSection::classof(const SectionBase *S) { |
| ... | ... | @@ -313,10 +324,6 @@ bool InputSection::classof(const SectionBase *S) { |
| 313 | 324 | S->kind() == SectionBase::Synthetic; |
| 314 | 325 | } |
| 315 | 326 | |
| 316 | bool InputSectionBase::classof(const SectionBase *S) { | |
| 317 | return S->kind() != Output; | |
| 318 | } | |
| 319 | ||
| 320 | 327 | OutputSection *InputSection::getParent() const { |
| 321 | 328 | return cast_or_null<OutputSection>(Parent); |
| 322 | 329 | } |
| ... | ... | @@ -333,15 +340,15 @@ template <class ELFT> void InputSection::copyShtGroup(uint8_t *Buf) { |
| 333 | 340 | |
| 334 | 341 | // Adjust section numbers because section numbers in an input object |
| 335 | 342 | // files are different in the output. |
| 336 | ArrayRef<InputSectionBase *> Sections = this->File->getSections(); | |
| 343 | ArrayRef<InputSectionBase *> Sections = File->getSections(); | |
| 337 | 344 | for (uint32_t Idx : From.slice(1)) |
| 338 | 345 | *To++ = Sections[Idx]->getOutputSection()->SectionIndex; |
| 339 | 346 | } |
| 340 | 347 | |
| 341 | 348 | InputSectionBase *InputSection::getRelocatedSection() { |
| 342 | assert(this->Type == SHT_RELA || this->Type == SHT_REL); | |
| 343 | ArrayRef<InputSectionBase *> Sections = this->File->getSections(); | |
| 344 | return Sections[this->Info]; | |
| 349 | assert(Type == SHT_RELA || Type == SHT_REL); | |
| 350 | ArrayRef<InputSectionBase *> Sections = File->getSections(); | |
| 351 | return Sections[Info]; | |
| 345 | 352 | } |
| 346 | 353 | |
| 347 | 354 | // This is used for -r and --emit-relocs. We can't use memcpy to copy |
| ... | ... | @@ -349,15 +356,11 @@ InputSectionBase *InputSection::getRelocatedSection() { |
| 349 | 356 | // for each relocation. So we copy relocations one by one. |
| 350 | 357 | template <class ELFT, class RelTy> |
| 351 | 358 | void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { |
| 352 | InputSectionBase *RelocatedSection = getRelocatedSection(); | |
| 359 | InputSectionBase *Sec = getRelocatedSection(); | |
| 353 | 360 | |
| 354 | // Loop is slow and have complexity O(N*M), where N - amount of | |
| 355 | // relocations and M - amount of symbols in symbol table. | |
| 356 | // That happens because getSymbolIndex(...) call below performs | |
| 357 | // simple linear search. | |
| 358 | 361 | for (const RelTy &Rel : Rels) { |
| 359 | uint32_t Type = Rel.getType(Config->IsMips64EL); | |
| 360 | SymbolBody &Body = this->getFile<ELFT>()->getRelocTargetSym(Rel); | |
| 362 | RelType Type = Rel.getType(Config->IsMips64EL); | |
| 363 | Symbol &Sym = getFile<ELFT>()->getRelocTargetSym(Rel); | |
| 361 | 364 | |
| 362 | 365 | auto *P = reinterpret_cast<typename ELFT::Rela *>(Buf); |
| 363 | 366 | Buf += sizeof(RelTy); |
| ... | ... | @@ -367,12 +370,11 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { |
| 367 | 370 | |
| 368 | 371 | // Output section VA is zero for -r, so r_offset is an offset within the |
| 369 | 372 | // section, but for --emit-relocs it is an virtual address. |
| 370 | P->r_offset = RelocatedSection->getOutputSection()->Addr + | |
| 371 | RelocatedSection->getOffset(Rel.r_offset); | |
| 372 | P->setSymbolAndType(InX::SymTab->getSymbolIndex(&Body), Type, | |
| 373 | P->r_offset = Sec->getOutputSection()->Addr + Sec->getOffset(Rel.r_offset); | |
| 374 | P->setSymbolAndType(InX::SymTab->getSymbolIndex(&Sym), Type, | |
| 373 | 375 | Config->IsMips64EL); |
| 374 | 376 | |
| 375 | if (Body.Type == STT_SECTION) { | |
| 377 | if (Sym.Type == STT_SECTION) { | |
| 376 | 378 | // We combine multiple section symbols into only one per |
| 377 | 379 | // section. This means we have to update the addend. That is |
| 378 | 380 | // trivial for Elf_Rela, but for Elf_Rel we have to write to the |
| ... | ... | @@ -382,19 +384,25 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { |
| 382 | 384 | // avoid having to parse and recreate .eh_frame, we just replace any |
| 383 | 385 | // relocation in it pointing to discarded sections with R_*_NONE, which |
| 384 | 386 | // hopefully creates a frame that is ignored at runtime. |
| 385 | SectionBase *Section = cast<DefinedRegular>(Body).Section; | |
| 387 | auto *D = dyn_cast<Defined>(&Sym); | |
| 388 | if (!D) { | |
| 389 | error("STT_SECTION symbol should be defined"); | |
| 390 | continue; | |
| 391 | } | |
| 392 | SectionBase *Section = D->Section; | |
| 386 | 393 | if (Section == &InputSection::Discarded) { |
| 387 | 394 | P->setSymbolAndType(0, 0, false); |
| 388 | 395 | continue; |
| 389 | 396 | } |
| 390 | 397 | |
| 391 | 398 | if (Config->IsRela) { |
| 392 | P->r_addend += Body.getVA() - Section->getOutputSection()->Addr; | |
| 399 | P->r_addend = | |
| 400 | Sym.getVA(getAddend<ELFT>(Rel)) - Section->getOutputSection()->Addr; | |
| 393 | 401 | } else if (Config->Relocatable) { |
| 394 | const uint8_t *BufLoc = RelocatedSection->Data.begin() + Rel.r_offset; | |
| 395 | RelocatedSection->Relocations.push_back( | |
| 396 | {R_ABS, Type, Rel.r_offset, Target->getImplicitAddend(BufLoc, Type), | |
| 397 | &Body}); | |
| 402 | const uint8_t *BufLoc = Sec->Data.begin() + Rel.r_offset; | |
| 403 | Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset, | |
| 404 | Target->getImplicitAddend(BufLoc, Type), | |
| 405 | &Sym}); | |
| 398 | 406 | } |
| 399 | 407 | } |
| 400 | 408 | |
| ... | ... | @@ -406,7 +414,7 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { |
| 406 | 414 | // this context is the address of the place P. A further special case is that |
| 407 | 415 | // branch relocations to an undefined weak reference resolve to the next |
| 408 | 416 | // instruction. |
| 409 | static uint32_t getARMUndefinedRelativeWeakVA(uint32_t Type, uint32_t A, | |
| 417 | static uint32_t getARMUndefinedRelativeWeakVA(RelType Type, uint32_t A, | |
| 410 | 418 | uint32_t P) { |
| 411 | 419 | switch (Type) { |
| 412 | 420 | // Unresolved branch relocations to weak references resolve to next |
| ... | ... | @@ -453,6 +461,7 @@ static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t Type, uint64_t A, |
| 453 | 461 | case R_AARCH64_PREL32: |
| 454 | 462 | case R_AARCH64_PREL64: |
| 455 | 463 | case R_AARCH64_ADR_PREL_LO21: |
| 464 | case R_AARCH64_LD_PREL_LO19: | |
| 456 | 465 | return P + A; |
| 457 | 466 | } |
| 458 | 467 | llvm_unreachable("AArch64 pc-relative relocation expected\n"); |
| ... | ... | @@ -461,53 +470,55 @@ static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t Type, uint64_t A, |
| 461 | 470 | // ARM SBREL relocations are of the form S + A - B where B is the static base |
| 462 | 471 | // The ARM ABI defines base to be "addressing origin of the output segment |
| 463 | 472 | // defining the symbol S". We defined the "addressing origin"/static base to be |
| 464 | // the base of the PT_LOAD segment containing the Body. | |
| 473 | // the base of the PT_LOAD segment containing the Sym. | |
| 465 | 474 | // The procedure call standard only defines a Read Write Position Independent |
| 466 | 475 | // RWPI variant so in practice we should expect the static base to be the base |
| 467 | 476 | // of the RW segment. |
| 468 | static uint64_t getARMStaticBase(const SymbolBody &Body) { | |
| 469 | OutputSection *OS = Body.getOutputSection(); | |
| 470 | if (!OS || !OS->FirstInPtLoad) | |
| 471 | fatal("SBREL relocation to " + Body.getName() + " without static base"); | |
| 472 | return OS->FirstInPtLoad->Addr; | |
| 477 | static uint64_t getARMStaticBase(const Symbol &Sym) { | |
| 478 | OutputSection *OS = Sym.getOutputSection(); | |
| 479 | if (!OS || !OS->PtLoad || !OS->PtLoad->FirstSec) | |
| 480 | fatal("SBREL relocation to " + Sym.getName() + " without static base"); | |
| 481 | return OS->PtLoad->FirstSec->Addr; | |
| 473 | 482 | } |
| 474 | 483 | |
| 475 | static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P, | |
| 476 | const SymbolBody &Body, RelExpr Expr) { | |
| 484 | static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P, | |
| 485 | const Symbol &Sym, RelExpr Expr) { | |
| 477 | 486 | switch (Expr) { |
| 487 | case R_INVALID: | |
| 488 | return 0; | |
| 478 | 489 | case R_ABS: |
| 479 | 490 | case R_RELAX_GOT_PC_NOPIC: |
| 480 | return Body.getVA(A); | |
| 491 | return Sym.getVA(A); | |
| 481 | 492 | case R_ARM_SBREL: |
| 482 | return Body.getVA(A) - getARMStaticBase(Body); | |
| 493 | return Sym.getVA(A) - getARMStaticBase(Sym); | |
| 483 | 494 | case R_GOT: |
| 484 | 495 | case R_RELAX_TLS_GD_TO_IE_ABS: |
| 485 | return Body.getGotVA() + A; | |
| 496 | return Sym.getGotVA() + A; | |
| 486 | 497 | case R_GOTONLY_PC: |
| 487 | 498 | return InX::Got->getVA() + A - P; |
| 488 | 499 | case R_GOTONLY_PC_FROM_END: |
| 489 | 500 | return InX::Got->getVA() + A - P + InX::Got->getSize(); |
| 490 | 501 | case R_GOTREL: |
| 491 | return Body.getVA(A) - InX::Got->getVA(); | |
| 502 | return Sym.getVA(A) - InX::Got->getVA(); | |
| 492 | 503 | case R_GOTREL_FROM_END: |
| 493 | return Body.getVA(A) - InX::Got->getVA() - InX::Got->getSize(); | |
| 504 | return Sym.getVA(A) - InX::Got->getVA() - InX::Got->getSize(); | |
| 494 | 505 | case R_GOT_FROM_END: |
| 495 | 506 | case R_RELAX_TLS_GD_TO_IE_END: |
| 496 | return Body.getGotOffset() + A - InX::Got->getSize(); | |
| 507 | return Sym.getGotOffset() + A - InX::Got->getSize(); | |
| 497 | 508 | case R_GOT_OFF: |
| 498 | return Body.getGotOffset() + A; | |
| 509 | return Sym.getGotOffset() + A; | |
| 499 | 510 | case R_GOT_PAGE_PC: |
| 500 | 511 | case R_RELAX_TLS_GD_TO_IE_PAGE_PC: |
| 501 | return getAArch64Page(Body.getGotVA() + A) - getAArch64Page(P); | |
| 512 | return getAArch64Page(Sym.getGotVA() + A) - getAArch64Page(P); | |
| 502 | 513 | case R_GOT_PC: |
| 503 | 514 | case R_RELAX_TLS_GD_TO_IE: |
| 504 | return Body.getGotVA() + A - P; | |
| 515 | return Sym.getGotVA() + A - P; | |
| 505 | 516 | case R_HINT: |
| 506 | 517 | case R_NONE: |
| 507 | 518 | case R_TLSDESC_CALL: |
| 508 | 519 | llvm_unreachable("cannot relocate hint relocs"); |
| 509 | 520 | case R_MIPS_GOTREL: |
| 510 | return Body.getVA(A) - InX::MipsGot->getGp(); | |
| 521 | return Sym.getVA(A) - InX::MipsGot->getGp(); | |
| 511 | 522 | case R_MIPS_GOT_GP: |
| 512 | 523 | return InX::MipsGot->getGp() + A; |
| 513 | 524 | case R_MIPS_GOT_GP_PC: { |
| ... | ... | @@ -515,42 +526,47 @@ static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P, |
| 515 | 526 | // is _gp_disp symbol. In that case we should use the following |
| 516 | 527 | // formula for calculation "AHL + GP - P + 4". For details see p. 4-19 at |
| 517 | 528 | // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf |
| 529 | // microMIPS variants of these relocations use slightly different | |
| 530 | // 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. | |
| 518 | 532 | uint64_t V = InX::MipsGot->getGp() + A - P; |
| 519 | if (Type == R_MIPS_LO16) | |
| 533 | if (Type == R_MIPS_LO16 || Type == R_MICROMIPS_LO16) | |
| 520 | 534 | V += 4; |
| 535 | if (Type == R_MICROMIPS_LO16 || Type == R_MICROMIPS_HI16) | |
| 536 | V -= 1; | |
| 521 | 537 | return V; |
| 522 | 538 | } |
| 523 | 539 | case R_MIPS_GOT_LOCAL_PAGE: |
| 524 | 540 | // If relocation against MIPS local symbol requires GOT entry, this entry |
| 525 | 541 | // should be initialized by 'page address'. This address is high 16-bits |
| 526 | 542 | // of sum the symbol's value and the addend. |
| 527 | return InX::MipsGot->getVA() + InX::MipsGot->getPageEntryOffset(Body, A) - | |
| 543 | return InX::MipsGot->getVA() + InX::MipsGot->getPageEntryOffset(Sym, A) - | |
| 528 | 544 | InX::MipsGot->getGp(); |
| 529 | 545 | case R_MIPS_GOT_OFF: |
| 530 | 546 | case R_MIPS_GOT_OFF32: |
| 531 | 547 | // In case of MIPS if a GOT relocation has non-zero addend this addend |
| 532 | 548 | // should be applied to the GOT entry content not to the GOT entry offset. |
| 533 | 549 | // That is why we use separate expression type. |
| 534 | return InX::MipsGot->getVA() + InX::MipsGot->getBodyEntryOffset(Body, A) - | |
| 550 | return InX::MipsGot->getVA() + InX::MipsGot->getSymEntryOffset(Sym, A) - | |
| 535 | 551 | InX::MipsGot->getGp(); |
| 536 | 552 | case R_MIPS_TLSGD: |
| 537 | 553 | return InX::MipsGot->getVA() + InX::MipsGot->getTlsOffset() + |
| 538 | InX::MipsGot->getGlobalDynOffset(Body) - InX::MipsGot->getGp(); | |
| 554 | InX::MipsGot->getGlobalDynOffset(Sym) - InX::MipsGot->getGp(); | |
| 539 | 555 | case R_MIPS_TLSLD: |
| 540 | 556 | return InX::MipsGot->getVA() + InX::MipsGot->getTlsOffset() + |
| 541 | 557 | InX::MipsGot->getTlsIndexOff() - InX::MipsGot->getGp(); |
| 542 | 558 | case R_PAGE_PC: |
| 543 | 559 | case R_PLT_PAGE_PC: { |
| 544 | 560 | uint64_t Dest; |
| 545 | if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) | |
| 561 | if (Sym.isUndefWeak()) | |
| 546 | 562 | Dest = getAArch64Page(A); |
| 547 | 563 | else |
| 548 | Dest = getAArch64Page(Body.getVA(A)); | |
| 564 | Dest = getAArch64Page(Sym.getVA(A)); | |
| 549 | 565 | return Dest - getAArch64Page(P); |
| 550 | 566 | } |
| 551 | 567 | case R_PC: { |
| 552 | 568 | uint64_t Dest; |
| 553 | if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) { | |
| 569 | if (Sym.isUndefWeak()) { | |
| 554 | 570 | // On ARM and AArch64 a branch to an undefined weak resolves to the |
| 555 | 571 | // next instruction, otherwise the place. |
| 556 | 572 | if (Config->EMachine == EM_ARM) |
| ... | ... | @@ -558,19 +574,19 @@ static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P, |
| 558 | 574 | else if (Config->EMachine == EM_AARCH64) |
| 559 | 575 | Dest = getAArch64UndefinedRelativeWeakVA(Type, A, P); |
| 560 | 576 | else |
| 561 | Dest = Body.getVA(A); | |
| 577 | Dest = Sym.getVA(A); | |
| 562 | 578 | } else { |
| 563 | Dest = Body.getVA(A); | |
| 579 | Dest = Sym.getVA(A); | |
| 564 | 580 | } |
| 565 | 581 | return Dest - P; |
| 566 | 582 | } |
| 567 | 583 | case R_PLT: |
| 568 | return Body.getPltVA() + A; | |
| 584 | return Sym.getPltVA() + A; | |
| 569 | 585 | case R_PLT_PC: |
| 570 | 586 | case R_PPC_PLT_OPD: |
| 571 | return Body.getPltVA() + A - P; | |
| 587 | return Sym.getPltVA() + A - P; | |
| 572 | 588 | case R_PPC_OPD: { |
| 573 | uint64_t SymVA = Body.getVA(A); | |
| 589 | uint64_t SymVA = Sym.getVA(A); | |
| 574 | 590 | // If we have an undefined weak symbol, we might get here with a symbol |
| 575 | 591 | // address of zero. That could overflow, but the code must be unreachable, |
| 576 | 592 | // so don't bother doing anything at all. |
| ... | ... | @@ -590,7 +606,7 @@ static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P, |
| 590 | 606 | case R_PPC_TOC: |
| 591 | 607 | return getPPC64TocBase() + A; |
| 592 | 608 | case R_RELAX_GOT_PC: |
| 593 | return Body.getVA(A) - P; | |
| 609 | return Sym.getVA(A) - P; | |
| 594 | 610 | case R_RELAX_TLS_GD_TO_LE: |
| 595 | 611 | case R_RELAX_TLS_IE_TO_LE: |
| 596 | 612 | case R_RELAX_TLS_LD_TO_LE: |
| ... | ... | @@ -600,26 +616,25 @@ static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P, |
| 600 | 616 | // lld and .tbss is not referenced, it gets reclaimed and we don't |
| 601 | 617 | // create a TLS program header. Therefore, we resolve this |
| 602 | 618 | // statically to zero. |
| 603 | if (Body.isTls() && (Body.isLazy() || Body.isUndefined()) && | |
| 604 | Body.symbol()->isWeak()) | |
| 619 | if (Sym.isTls() && Sym.isUndefWeak()) | |
| 605 | 620 | return 0; |
| 606 | 621 | if (Target->TcbSize) |
| 607 | return Body.getVA(A) + alignTo(Target->TcbSize, Out::TlsPhdr->p_align); | |
| 608 | return Body.getVA(A) - Out::TlsPhdr->p_memsz; | |
| 622 | return Sym.getVA(A) + alignTo(Target->TcbSize, Out::TlsPhdr->p_align); | |
| 623 | return Sym.getVA(A) - Out::TlsPhdr->p_memsz; | |
| 609 | 624 | case R_RELAX_TLS_GD_TO_LE_NEG: |
| 610 | 625 | case R_NEG_TLS: |
| 611 | return Out::TlsPhdr->p_memsz - Body.getVA(A); | |
| 626 | return Out::TlsPhdr->p_memsz - Sym.getVA(A); | |
| 612 | 627 | case R_SIZE: |
| 613 | return A; // Body.getSize was already folded into the addend. | |
| 628 | return A; // Sym.getSize was already folded into the addend. | |
| 614 | 629 | case R_TLSDESC: |
| 615 | return InX::Got->getGlobalDynAddr(Body) + A; | |
| 630 | return InX::Got->getGlobalDynAddr(Sym) + A; | |
| 616 | 631 | case R_TLSDESC_PAGE: |
| 617 | return getAArch64Page(InX::Got->getGlobalDynAddr(Body) + A) - | |
| 632 | return getAArch64Page(InX::Got->getGlobalDynAddr(Sym) + A) - | |
| 618 | 633 | getAArch64Page(P); |
| 619 | 634 | case R_TLSGD: |
| 620 | return InX::Got->getGlobalDynOffset(Body) + A - InX::Got->getSize(); | |
| 635 | return InX::Got->getGlobalDynOffset(Sym) + A - InX::Got->getSize(); | |
| 621 | 636 | case R_TLSGD_PC: |
| 622 | return InX::Got->getGlobalDynAddr(Body) + A - P; | |
| 637 | return InX::Got->getGlobalDynAddr(Sym) + A - P; | |
| 623 | 638 | case R_TLSLD: |
| 624 | 639 | return InX::Got->getTlsIndexOff() + A - InX::Got->getSize(); |
| 625 | 640 | case R_TLSLD_PC: |
| ... | ... | @@ -637,64 +652,62 @@ static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P, |
| 637 | 652 | // function as a performance optimization. |
| 638 | 653 | template <class ELFT, class RelTy> |
| 639 | 654 | void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) { |
| 655 | const unsigned Bits = sizeof(typename ELFT::uint) * 8; | |
| 656 | ||
| 640 | 657 | for (const RelTy &Rel : Rels) { |
| 641 | uint32_t Type = Rel.getType(Config->IsMips64EL); | |
| 658 | RelType Type = Rel.getType(Config->IsMips64EL); | |
| 642 | 659 | uint64_t Offset = getOffset(Rel.r_offset); |
| 643 | 660 | uint8_t *BufLoc = Buf + Offset; |
| 644 | 661 | int64_t Addend = getAddend<ELFT>(Rel); |
| 645 | 662 | if (!RelTy::IsRela) |
| 646 | 663 | Addend += Target->getImplicitAddend(BufLoc, Type); |
| 647 | 664 | |
| 648 | SymbolBody &Sym = this->getFile<ELFT>()->getRelocTargetSym(Rel); | |
| 665 | Symbol &Sym = getFile<ELFT>()->getRelocTargetSym(Rel); | |
| 649 | 666 | RelExpr Expr = Target->getRelExpr(Type, Sym, BufLoc); |
| 650 | 667 | if (Expr == R_NONE) |
| 651 | 668 | continue; |
| 652 | 669 | if (Expr != R_ABS) { |
| 653 | error(this->getLocation<ELFT>(Offset) + ": has non-ABS reloc"); | |
| 670 | // GCC 8.0 or earlier have a bug that it emits R_386_GOTPC relocations | |
| 671 | // against _GLOBAL_OFFSET_TABLE for .debug_info. The bug seems to have | |
| 672 | // been fixed in 2017: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82630, | |
| 673 | // but we need to keep this bug-compatible code for a while. | |
| 674 | if (Config->EMachine == EM_386 && Type == R_386_GOTPC) | |
| 675 | continue; | |
| 676 | ||
| 677 | error(getLocation<ELFT>(Offset) + ": has non-ABS relocation " + | |
| 678 | toString(Type) + " against symbol '" + toString(Sym) + "'"); | |
| 654 | 679 | return; |
| 655 | 680 | } |
| 656 | 681 | |
| 657 | uint64_t AddrLoc = getParent()->Addr + Offset; | |
| 658 | uint64_t SymVA = 0; | |
| 659 | if (!Sym.isTls() || Out::TlsPhdr) | |
| 660 | SymVA = SignExtend64<sizeof(typename ELFT::uint) * 8>( | |
| 661 | getRelocTargetVA(Type, Addend, AddrLoc, Sym, R_ABS)); | |
| 662 | Target->relocateOne(BufLoc, Type, SymVA); | |
| 682 | if (Sym.isTls() && !Out::TlsPhdr) | |
| 683 | Target->relocateOne(BufLoc, Type, 0); | |
| 684 | else | |
| 685 | Target->relocateOne(BufLoc, Type, SignExtend64<Bits>(Sym.getVA(Addend))); | |
| 663 | 686 | } |
| 664 | 687 | } |
| 665 | 688 | |
| 666 | template <class ELFT> elf::ObjectFile<ELFT> *InputSectionBase::getFile() const { | |
| 667 | return cast_or_null<elf::ObjectFile<ELFT>>(File); | |
| 668 | } | |
| 669 | ||
| 670 | 689 | template <class ELFT> |
| 671 | 690 | void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) { |
| 672 | if (Flags & SHF_ALLOC) | |
| 691 | if (Flags & SHF_ALLOC) { | |
| 673 | 692 | relocateAlloc(Buf, BufEnd); |
| 674 | else | |
| 675 | relocateNonAlloc<ELFT>(Buf, BufEnd); | |
| 676 | } | |
| 693 | return; | |
| 694 | } | |
| 677 | 695 | |
| 678 | template <class ELFT> | |
| 679 | void InputSectionBase::relocateNonAlloc(uint8_t *Buf, uint8_t *BufEnd) { | |
| 680 | // scanReloc function in Writer.cpp constructs Relocations | |
| 681 | // vector only for SHF_ALLOC'ed sections. For other sections, | |
| 682 | // we handle relocations directly here. | |
| 683 | auto *IS = cast<InputSection>(this); | |
| 684 | assert(!(IS->Flags & SHF_ALLOC)); | |
| 685 | if (IS->AreRelocsRela) | |
| 686 | IS->relocateNonAlloc<ELFT>(Buf, IS->template relas<ELFT>()); | |
| 696 | auto *Sec = cast<InputSection>(this); | |
| 697 | if (Sec->AreRelocsRela) | |
| 698 | Sec->relocateNonAlloc<ELFT>(Buf, Sec->template relas<ELFT>()); | |
| 687 | 699 | else |
| 688 | IS->relocateNonAlloc<ELFT>(Buf, IS->template rels<ELFT>()); | |
| 700 | Sec->relocateNonAlloc<ELFT>(Buf, Sec->template rels<ELFT>()); | |
| 689 | 701 | } |
| 690 | 702 | |
| 691 | 703 | void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) { |
| 692 | 704 | assert(Flags & SHF_ALLOC); |
| 693 | 705 | const unsigned Bits = Config->Wordsize * 8; |
| 706 | ||
| 694 | 707 | for (const Relocation &Rel : Relocations) { |
| 695 | 708 | uint64_t Offset = getOffset(Rel.Offset); |
| 696 | 709 | uint8_t *BufLoc = Buf + Offset; |
| 697 | uint32_t Type = Rel.Type; | |
| 710 | RelType Type = Rel.Type; | |
| 698 | 711 | |
| 699 | 712 | uint64_t AddrLoc = getOutputSection()->Addr + Offset; |
| 700 | 713 | RelExpr Expr = Rel.Expr; |
| ... | ... | @@ -735,7 +748,7 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) { |
| 735 | 748 | } |
| 736 | 749 | |
| 737 | 750 | template <class ELFT> void InputSection::writeTo(uint8_t *Buf) { |
| 738 | if (this->Type == SHT_NOBITS) | |
| 751 | if (Type == SHT_NOBITS) | |
| 739 | 752 | return; |
| 740 | 753 | |
| 741 | 754 | if (auto *S = dyn_cast<SyntheticSection>(this)) { |
| ... | ... | @@ -745,19 +758,17 @@ template <class ELFT> void InputSection::writeTo(uint8_t *Buf) { |
| 745 | 758 | |
| 746 | 759 | // If -r or --emit-relocs is given, then an InputSection |
| 747 | 760 | // may be a relocation section. |
| 748 | if (this->Type == SHT_RELA) { | |
| 749 | copyRelocations<ELFT>(Buf + OutSecOff, | |
| 750 | this->template getDataAs<typename ELFT::Rela>()); | |
| 761 | if (Type == SHT_RELA) { | |
| 762 | copyRelocations<ELFT>(Buf + OutSecOff, getDataAs<typename ELFT::Rela>()); | |
| 751 | 763 | return; |
| 752 | 764 | } |
| 753 | if (this->Type == SHT_REL) { | |
| 754 | copyRelocations<ELFT>(Buf + OutSecOff, | |
| 755 | this->template getDataAs<typename ELFT::Rel>()); | |
| 765 | if (Type == SHT_REL) { | |
| 766 | copyRelocations<ELFT>(Buf + OutSecOff, getDataAs<typename ELFT::Rel>()); | |
| 756 | 767 | return; |
| 757 | 768 | } |
| 758 | 769 | |
| 759 | 770 | // If -r is given, we may have a SHT_GROUP section. |
| 760 | if (this->Type == SHT_GROUP) { | |
| 771 | if (Type == SHT_GROUP) { | |
| 761 | 772 | copyShtGroup<ELFT>(Buf + OutSecOff); |
| 762 | 773 | return; |
| 763 | 774 | } |
| ... | ... | @@ -766,34 +777,25 @@ template <class ELFT> void InputSection::writeTo(uint8_t *Buf) { |
| 766 | 777 | // and then apply relocations. |
| 767 | 778 | memcpy(Buf + OutSecOff, Data.data(), Data.size()); |
| 768 | 779 | uint8_t *BufEnd = Buf + OutSecOff + Data.size(); |
| 769 | this->relocate<ELFT>(Buf, BufEnd); | |
| 780 | relocate<ELFT>(Buf, BufEnd); | |
| 770 | 781 | } |
| 771 | 782 | |
| 772 | 783 | void InputSection::replace(InputSection *Other) { |
| 773 | this->Alignment = std::max(this->Alignment, Other->Alignment); | |
| 774 | Other->Repl = this->Repl; | |
| 784 | Alignment = std::max(Alignment, Other->Alignment); | |
| 785 | Other->Repl = Repl; | |
| 775 | 786 | Other->Live = false; |
| 776 | 787 | } |
| 777 | 788 | |
| 778 | 789 | template <class ELFT> |
| 779 | EhInputSection::EhInputSection(elf::ObjectFile<ELFT> *F, | |
| 780 | const typename ELFT::Shdr *Header, | |
| 790 | EhInputSection::EhInputSection(ObjFile<ELFT> &F, | |
| 791 | const typename ELFT::Shdr &Header, | |
| 781 | 792 | StringRef Name) |
| 782 | : InputSectionBase(F, Header, Name, InputSectionBase::EHFrame) { | |
| 783 | // Mark .eh_frame sections as live by default because there are | |
| 784 | // usually no relocations that point to .eh_frames. Otherwise, | |
| 785 | // the garbage collector would drop all .eh_frame sections. | |
| 786 | this->Live = true; | |
| 787 | } | |
| 793 | : InputSectionBase(F, Header, Name, InputSectionBase::EHFrame) {} | |
| 788 | 794 | |
| 789 | 795 | SyntheticSection *EhInputSection::getParent() const { |
| 790 | 796 | return cast_or_null<SyntheticSection>(Parent); |
| 791 | 797 | } |
| 792 | 798 | |
| 793 | bool EhInputSection::classof(const SectionBase *S) { | |
| 794 | return S->kind() == InputSectionBase::EHFrame; | |
| 795 | } | |
| 796 | ||
| 797 | 799 | // Returns the index of the first relocation that points to a region between |
| 798 | 800 | // Begin and Begin+Size. |
| 799 | 801 | template <class IntTy, class RelTy> |
| ... | ... | @@ -817,26 +819,21 @@ static unsigned getReloc(IntTy Begin, IntTy Size, const ArrayRef<RelTy> &Rels, |
| 817 | 819 | // This function splits an input section into records and returns them. |
| 818 | 820 | template <class ELFT> void EhInputSection::split() { |
| 819 | 821 | // Early exit if already split. |
| 820 | if (!this->Pieces.empty()) | |
| 822 | if (!Pieces.empty()) | |
| 821 | 823 | return; |
| 822 | 824 | |
| 823 | if (this->NumRelocations) { | |
| 824 | if (this->AreRelocsRela) | |
| 825 | split<ELFT>(this->relas<ELFT>()); | |
| 826 | else | |
| 827 | split<ELFT>(this->rels<ELFT>()); | |
| 828 | return; | |
| 829 | } | |
| 830 | split<ELFT>(makeArrayRef<typename ELFT::Rela>(nullptr, nullptr)); | |
| 825 | if (AreRelocsRela) | |
| 826 | split<ELFT>(relas<ELFT>()); | |
| 827 | else | |
| 828 | split<ELFT>(rels<ELFT>()); | |
| 831 | 829 | } |
| 832 | 830 | |
| 833 | 831 | template <class ELFT, class RelTy> |
| 834 | 832 | void EhInputSection::split(ArrayRef<RelTy> Rels) { |
| 835 | ArrayRef<uint8_t> Data = this->Data; | |
| 836 | 833 | unsigned RelI = 0; |
| 837 | 834 | for (size_t Off = 0, End = Data.size(); Off != End;) { |
| 838 | size_t Size = readEhRecordSize<ELFT>(this, Off); | |
| 839 | this->Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI)); | |
| 835 | size_t Size = readEhRecordSize(this, Off); | |
| 836 | Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI)); | |
| 840 | 837 | // The empty record is the end marker. |
| 841 | 838 | if (Size == 4) |
| 842 | 839 | break; |
| ... | ... | @@ -844,9 +841,8 @@ void EhInputSection::split(ArrayRef<RelTy> Rels) { |
| 844 | 841 | } |
| 845 | 842 | } |
| 846 | 843 | |
| 847 | static size_t findNull(ArrayRef<uint8_t> A, size_t EntSize) { | |
| 844 | static size_t findNull(StringRef S, size_t EntSize) { | |
| 848 | 845 | // Optimize the common case. |
| 849 | StringRef S((const char *)A.data(), A.size()); | |
| 850 | 846 | if (EntSize == 1) |
| 851 | 847 | return S.find(0); |
| 852 | 848 | |
| ... | ... | @@ -866,15 +862,17 @@ SyntheticSection *MergeInputSection::getParent() const { |
| 866 | 862 | // null-terminated strings. |
| 867 | 863 | void MergeInputSection::splitStrings(ArrayRef<uint8_t> Data, size_t EntSize) { |
| 868 | 864 | size_t Off = 0; |
| 869 | bool IsAlloc = this->Flags & SHF_ALLOC; | |
| 870 | while (!Data.empty()) { | |
| 871 | size_t End = findNull(Data, EntSize); | |
| 865 | bool IsAlloc = Flags & SHF_ALLOC; | |
| 866 | StringRef S = toStringRef(Data); | |
| 867 | ||
| 868 | while (!S.empty()) { | |
| 869 | size_t End = findNull(S, EntSize); | |
| 872 | 870 | if (End == StringRef::npos) |
| 873 | 871 | fatal(toString(this) + ": string is not null terminated"); |
| 874 | 872 | size_t Size = End + EntSize; |
| 875 | Pieces.emplace_back(Off, !IsAlloc); | |
| 876 | Hashes.push_back(hash_value(toStringRef(Data.slice(0, Size)))); | |
| 877 | Data = Data.slice(Size); | |
| 873 | ||
| 874 | Pieces.emplace_back(Off, xxHash64(S.substr(0, Size)), !IsAlloc); | |
| 875 | S = S.substr(Size); | |
| 878 | 876 | Off += Size; |
| 879 | 877 | } |
| 880 | 878 | } |
| ... | ... | @@ -885,40 +883,42 @@ void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> Data, |
| 885 | 883 | size_t EntSize) { |
| 886 | 884 | size_t Size = Data.size(); |
| 887 | 885 | assert((Size % EntSize) == 0); |
| 888 | bool IsAlloc = this->Flags & SHF_ALLOC; | |
| 889 | for (unsigned I = 0, N = Size; I != N; I += EntSize) { | |
| 890 | Hashes.push_back(hash_value(toStringRef(Data.slice(I, EntSize)))); | |
| 891 | Pieces.emplace_back(I, !IsAlloc); | |
| 892 | } | |
| 886 | bool IsAlloc = Flags & SHF_ALLOC; | |
| 887 | ||
| 888 | for (size_t I = 0; I != Size; I += EntSize) | |
| 889 | Pieces.emplace_back(I, xxHash64(toStringRef(Data.slice(I, EntSize))), | |
| 890 | !IsAlloc); | |
| 893 | 891 | } |
| 894 | 892 | |
| 895 | 893 | template <class ELFT> |
| 896 | MergeInputSection::MergeInputSection(elf::ObjectFile<ELFT> *F, | |
| 897 | const typename ELFT::Shdr *Header, | |
| 894 | MergeInputSection::MergeInputSection(ObjFile<ELFT> &F, | |
| 895 | const typename ELFT::Shdr &Header, | |
| 898 | 896 | StringRef Name) |
| 899 | 897 | : InputSectionBase(F, Header, Name, InputSectionBase::Merge) {} |
| 900 | 898 | |
| 899 | MergeInputSection::MergeInputSection(uint64_t Flags, uint32_t Type, | |
| 900 | uint64_t Entsize, ArrayRef<uint8_t> Data, | |
| 901 | StringRef Name) | |
| 902 | : InputSectionBase(nullptr, Flags, Type, Entsize, /*Link*/ 0, /*Info*/ 0, | |
| 903 | /*Alignment*/ Entsize, Data, Name, SectionBase::Merge) {} | |
| 904 | ||
| 901 | 905 | // This function is called after we obtain a complete list of input sections |
| 902 | 906 | // that need to be linked. This is responsible to split section contents |
| 903 | 907 | // into small chunks for further processing. |
| 904 | 908 | // |
| 905 | // Note that this function is called from parallel_for_each. This must be | |
| 909 | // Note that this function is called from parallelForEach. This must be | |
| 906 | 910 | // thread-safe (i.e. no memory allocation from the pools). |
| 907 | 911 | void MergeInputSection::splitIntoPieces() { |
| 908 | ArrayRef<uint8_t> Data = this->Data; | |
| 909 | uint64_t EntSize = this->Entsize; | |
| 910 | if (this->Flags & SHF_STRINGS) | |
| 911 | splitStrings(Data, EntSize); | |
| 912 | assert(Pieces.empty()); | |
| 913 | ||
| 914 | if (Flags & SHF_STRINGS) | |
| 915 | splitStrings(Data, Entsize); | |
| 912 | 916 | else |
| 913 | splitNonStrings(Data, EntSize); | |
| 917 | splitNonStrings(Data, Entsize); | |
| 914 | 918 | |
| 915 | if (Config->GcSections && (this->Flags & SHF_ALLOC)) | |
| 919 | if (Config->GcSections && (Flags & SHF_ALLOC)) | |
| 916 | 920 | for (uint64_t Off : LiveOffsets) |
| 917 | this->getSectionPiece(Off)->Live = true; | |
| 918 | } | |
| 919 | ||
| 920 | bool MergeInputSection::classof(const SectionBase *S) { | |
| 921 | return S->kind() == InputSectionBase::Merge; | |
| 921 | getSectionPiece(Off)->Live = true; | |
| 922 | 922 | } |
| 923 | 923 | |
| 924 | 924 | // Do binary search to get a section piece at a given input offset. |
| ... | ... | @@ -941,8 +941,7 @@ static It fastUpperBound(It First, It Last, const T &Value, Compare Comp) { |
| 941 | 941 | } |
| 942 | 942 | |
| 943 | 943 | const SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) const { |
| 944 | uint64_t Size = this->Data.size(); | |
| 945 | if (Offset >= Size) | |
| 944 | if (Data.size() <= Offset) | |
| 946 | 945 | fatal(toString(this) + ": entry is past the end of the section"); |
| 947 | 946 | |
| 948 | 947 | // Find the element this offset points to. |
| ... | ... | @@ -957,24 +956,24 @@ const SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) const { |
| 957 | 956 | // Because contents of a mergeable section is not contiguous in output, |
| 958 | 957 | // it is not just an addition to a base output offset. |
| 959 | 958 | uint64_t MergeInputSection::getOffset(uint64_t Offset) const { |
| 959 | if (!Live) | |
| 960 | return 0; | |
| 961 | ||
| 960 | 962 | // Initialize OffsetMap lazily. |
| 961 | 963 | llvm::call_once(InitOffsetMap, [&] { |
| 962 | 964 | OffsetMap.reserve(Pieces.size()); |
| 963 | for (const SectionPiece &Piece : Pieces) | |
| 964 | OffsetMap[Piece.InputOff] = Piece.OutputOff; | |
| 965 | for (size_t I = 0; I < Pieces.size(); ++I) | |
| 966 | OffsetMap[Pieces[I].InputOff] = I; | |
| 965 | 967 | }); |
| 966 | 968 | |
| 967 | 969 | // Find a string starting at a given offset. |
| 968 | 970 | auto It = OffsetMap.find(Offset); |
| 969 | 971 | if (It != OffsetMap.end()) |
| 970 | return It->second; | |
| 971 | ||
| 972 | if (!this->Live) | |
| 973 | return 0; | |
| 972 | return Pieces[It->second].OutputOff; | |
| 974 | 973 | |
| 975 | 974 | // If Offset is not at beginning of a section piece, it is not in the map. |
| 976 | 975 | // In that case we need to search from the original section piece vector. |
| 977 | const SectionPiece &Piece = *this->getSectionPiece(Offset); | |
| 976 | const SectionPiece &Piece = *getSectionPiece(Offset); | |
| 978 | 977 | if (!Piece.Live) |
| 979 | 978 | return 0; |
| 980 | 979 | |
| ... | ... | @@ -982,57 +981,42 @@ uint64_t MergeInputSection::getOffset(uint64_t Offset) const { |
| 982 | 981 | return Piece.OutputOff + Addend; |
| 983 | 982 | } |
| 984 | 983 | |
| 985 | template InputSection::InputSection(elf::ObjectFile<ELF32LE> *, | |
| 986 | const ELF32LE::Shdr *, StringRef); | |
| 987 | template InputSection::InputSection(elf::ObjectFile<ELF32BE> *, | |
| 988 | const ELF32BE::Shdr *, StringRef); | |
| 989 | template InputSection::InputSection(elf::ObjectFile<ELF64LE> *, | |
| 990 | const ELF64LE::Shdr *, StringRef); | |
| 991 | template InputSection::InputSection(elf::ObjectFile<ELF64BE> *, | |
| 992 | const ELF64BE::Shdr *, StringRef); | |
| 984 | template InputSection::InputSection(ObjFile<ELF32LE> &, const ELF32LE::Shdr &, | |
| 985 | StringRef); | |
| 986 | template InputSection::InputSection(ObjFile<ELF32BE> &, const ELF32BE::Shdr &, | |
| 987 | StringRef); | |
| 988 | template InputSection::InputSection(ObjFile<ELF64LE> &, const ELF64LE::Shdr &, | |
| 989 | StringRef); | |
| 990 | template InputSection::InputSection(ObjFile<ELF64BE> &, const ELF64BE::Shdr &, | |
| 991 | StringRef); | |
| 993 | 992 | |
| 994 | 993 | template std::string InputSectionBase::getLocation<ELF32LE>(uint64_t); |
| 995 | 994 | template std::string InputSectionBase::getLocation<ELF32BE>(uint64_t); |
| 996 | 995 | template std::string InputSectionBase::getLocation<ELF64LE>(uint64_t); |
| 997 | 996 | template std::string InputSectionBase::getLocation<ELF64BE>(uint64_t); |
| 998 | 997 | |
| 999 | template std::string InputSectionBase::getSrcMsg<ELF32LE>(uint64_t); | |
| 1000 | template std::string InputSectionBase::getSrcMsg<ELF32BE>(uint64_t); | |
| 1001 | template std::string InputSectionBase::getSrcMsg<ELF64LE>(uint64_t); | |
| 1002 | template std::string InputSectionBase::getSrcMsg<ELF64BE>(uint64_t); | |
| 1003 | ||
| 1004 | template std::string InputSectionBase::getObjMsg<ELF32LE>(uint64_t); | |
| 1005 | template std::string InputSectionBase::getObjMsg<ELF32BE>(uint64_t); | |
| 1006 | template std::string InputSectionBase::getObjMsg<ELF64LE>(uint64_t); | |
| 1007 | template std::string InputSectionBase::getObjMsg<ELF64BE>(uint64_t); | |
| 1008 | ||
| 1009 | 998 | template void InputSection::writeTo<ELF32LE>(uint8_t *); |
| 1010 | 999 | template void InputSection::writeTo<ELF32BE>(uint8_t *); |
| 1011 | 1000 | template void InputSection::writeTo<ELF64LE>(uint8_t *); |
| 1012 | 1001 | template void InputSection::writeTo<ELF64BE>(uint8_t *); |
| 1013 | 1002 | |
| 1014 | template elf::ObjectFile<ELF32LE> *InputSectionBase::getFile<ELF32LE>() const; | |
| 1015 | template elf::ObjectFile<ELF32BE> *InputSectionBase::getFile<ELF32BE>() const; | |
| 1016 | template elf::ObjectFile<ELF64LE> *InputSectionBase::getFile<ELF64LE>() const; | |
| 1017 | template elf::ObjectFile<ELF64BE> *InputSectionBase::getFile<ELF64BE>() const; | |
| 1018 | ||
| 1019 | template MergeInputSection::MergeInputSection(elf::ObjectFile<ELF32LE> *, | |
| 1020 | const ELF32LE::Shdr *, StringRef); | |
| 1021 | template MergeInputSection::MergeInputSection(elf::ObjectFile<ELF32BE> *, | |
| 1022 | const ELF32BE::Shdr *, StringRef); | |
| 1023 | template MergeInputSection::MergeInputSection(elf::ObjectFile<ELF64LE> *, | |
| 1024 | const ELF64LE::Shdr *, StringRef); | |
| 1025 | template MergeInputSection::MergeInputSection(elf::ObjectFile<ELF64BE> *, | |
| 1026 | const ELF64BE::Shdr *, StringRef); | |
| 1027 | ||
| 1028 | template EhInputSection::EhInputSection(elf::ObjectFile<ELF32LE> *, | |
| 1029 | const ELF32LE::Shdr *, StringRef); | |
| 1030 | template EhInputSection::EhInputSection(elf::ObjectFile<ELF32BE> *, | |
| 1031 | const ELF32BE::Shdr *, StringRef); | |
| 1032 | template EhInputSection::EhInputSection(elf::ObjectFile<ELF64LE> *, | |
| 1033 | const ELF64LE::Shdr *, StringRef); | |
| 1034 | template EhInputSection::EhInputSection(elf::ObjectFile<ELF64BE> *, | |
| 1035 | const ELF64BE::Shdr *, StringRef); | |
| 1003 | template MergeInputSection::MergeInputSection(ObjFile<ELF32LE> &, | |
| 1004 | const ELF32LE::Shdr &, StringRef); | |
| 1005 | template MergeInputSection::MergeInputSection(ObjFile<ELF32BE> &, | |
| 1006 | const ELF32BE::Shdr &, StringRef); | |
| 1007 | template MergeInputSection::MergeInputSection(ObjFile<ELF64LE> &, | |
| 1008 | const ELF64LE::Shdr &, StringRef); | |
| 1009 | template MergeInputSection::MergeInputSection(ObjFile<ELF64BE> &, | |
| 1010 | const ELF64BE::Shdr &, StringRef); | |
| 1011 | ||
| 1012 | template EhInputSection::EhInputSection(ObjFile<ELF32LE> &, | |
| 1013 | const ELF32LE::Shdr &, StringRef); | |
| 1014 | template EhInputSection::EhInputSection(ObjFile<ELF32BE> &, | |
| 1015 | const ELF32BE::Shdr &, StringRef); | |
| 1016 | template EhInputSection::EhInputSection(ObjFile<ELF64LE> &, | |
| 1017 | const ELF64LE::Shdr &, StringRef); | |
| 1018 | template EhInputSection::EhInputSection(ObjFile<ELF64BE> &, | |
| 1019 | const ELF64BE::Shdr &, StringRef); | |
| 1036 | 1020 | |
| 1037 | 1021 | template void EhInputSection::split<ELF32LE>(); |
| 1038 | 1022 | template void EhInputSection::split<ELF32BE>(); |
deps/lld/ELF/InputSection.h+109-94| ... | ... | @@ -13,7 +13,7 @@ |
| 13 | 13 | #include "Config.h" |
| 14 | 14 | #include "Relocations.h" |
| 15 | 15 | #include "Thunks.h" |
| 16 | #include "lld/Core/LLVM.h" | |
| 16 | #include "lld/Common/LLVM.h" | |
| 17 | 17 | #include "llvm/ADT/CachedHashString.h" |
| 18 | 18 | #include "llvm/ADT/DenseSet.h" |
| 19 | 19 | #include "llvm/ADT/TinyPtrVector.h" |
| ... | ... | @@ -24,15 +24,13 @@ |
| 24 | 24 | namespace lld { |
| 25 | 25 | namespace elf { |
| 26 | 26 | |
| 27 | class DefinedCommon; | |
| 28 | class SymbolBody; | |
| 27 | class Symbol; | |
| 29 | 28 | struct SectionPiece; |
| 30 | 29 | |
| 31 | class DefinedRegular; | |
| 30 | class Defined; | |
| 32 | 31 | class SyntheticSection; |
| 33 | template <class ELFT> class EhFrameSection; | |
| 34 | 32 | class MergeSyntheticSection; |
| 35 | template <class ELFT> class ObjectFile; | |
| 33 | template <class ELFT> class ObjFile; | |
| 36 | 34 | class OutputSection; |
| 37 | 35 | |
| 38 | 36 | // This is the base class of all sections that lld handles. Some are sections in |
| ... | ... | @@ -47,6 +45,13 @@ public: |
| 47 | 45 | |
| 48 | 46 | StringRef Name; |
| 49 | 47 | |
| 48 | // This pointer points to the "real" instance of this instance. | |
| 49 | // Usually Repl == this. However, if ICF merges two sections, | |
| 50 | // Repl pointer of one section points to another section. So, | |
| 51 | // if you need to get a pointer to this instance, do not use | |
| 52 | // this but instead this->Repl. | |
| 53 | SectionBase *Repl; | |
| 54 | ||
| 50 | 55 | unsigned SectionKind : 3; |
| 51 | 56 | |
| 52 | 57 | // The next two bit fields are only used by InputSectionBase, but we |
| ... | ... | @@ -54,12 +59,12 @@ public: |
| 54 | 59 | |
| 55 | 60 | // The garbage collector sets sections' Live bits. |
| 56 | 61 | // If GC is disabled, all sections are considered live by default. |
| 57 | unsigned Live : 1; // for garbage collection | |
| 58 | unsigned Assigned : 1; // for linker script | |
| 62 | unsigned Live : 1; | |
| 59 | 63 | |
| 60 | uint32_t Alignment; | |
| 64 | unsigned Bss : 1; | |
| 61 | 65 | |
| 62 | 66 | // These corresponds to the fields in Elf_Shdr. |
| 67 | uint32_t Alignment; | |
| 63 | 68 | uint64_t Flags; |
| 64 | 69 | uint64_t Entsize; |
| 65 | 70 | uint32_t Type; |
| ... | ... | @@ -75,45 +80,20 @@ public: |
| 75 | 80 | // section. |
| 76 | 81 | uint64_t getOffset(uint64_t Offset) const; |
| 77 | 82 | |
| 78 | uint64_t getOffset(const DefinedRegular &Sym) const; | |
| 79 | ||
| 80 | 83 | protected: |
| 81 | 84 | SectionBase(Kind SectionKind, StringRef Name, uint64_t Flags, |
| 82 | 85 | uint64_t Entsize, uint64_t Alignment, uint32_t Type, |
| 83 | 86 | uint32_t Info, uint32_t Link) |
| 84 | : Name(Name), SectionKind(SectionKind), Alignment(Alignment), | |
| 85 | Flags(Flags), Entsize(Entsize), Type(Type), Link(Link), Info(Info) { | |
| 86 | Live = false; | |
| 87 | Assigned = false; | |
| 88 | } | |
| 87 | : Name(Name), Repl(this), SectionKind(SectionKind), Live(false), | |
| 88 | Bss(false), Alignment(Alignment), Flags(Flags), Entsize(Entsize), | |
| 89 | Type(Type), Link(Link), Info(Info) {} | |
| 89 | 90 | }; |
| 90 | 91 | |
| 91 | 92 | // This corresponds to a section of an input file. |
| 92 | 93 | class InputSectionBase : public SectionBase { |
| 93 | 94 | public: |
| 94 | static bool classof(const SectionBase *S); | |
| 95 | ||
| 96 | // The file this section is from. | |
| 97 | InputFile *File; | |
| 98 | ||
| 99 | ArrayRef<uint8_t> Data; | |
| 100 | uint64_t getOffsetInFile() const; | |
| 101 | ||
| 102 | static InputSectionBase Discarded; | |
| 103 | ||
| 104 | InputSectionBase() | |
| 105 | : SectionBase(Regular, "", /*Flags*/ 0, /*Entsize*/ 0, /*Alignment*/ 0, | |
| 106 | /*Type*/ 0, | |
| 107 | /*Info*/ 0, /*Link*/ 0), | |
| 108 | Repl(this) { | |
| 109 | Live = false; | |
| 110 | Assigned = false; | |
| 111 | NumRelocations = 0; | |
| 112 | AreRelocsRela = false; | |
| 113 | } | |
| 114 | ||
| 115 | 95 | template <class ELFT> |
| 116 | InputSectionBase(ObjectFile<ELFT> *File, const typename ELFT::Shdr *Header, | |
| 96 | InputSectionBase(ObjFile<ELFT> &File, const typename ELFT::Shdr &Header, | |
| 117 | 97 | StringRef Name, Kind SectionKind); |
| 118 | 98 | |
| 119 | 99 | InputSectionBase(InputFile *File, uint64_t Flags, uint32_t Type, |
| ... | ... | @@ -121,6 +101,33 @@ public: |
| 121 | 101 | uint32_t Alignment, ArrayRef<uint8_t> Data, StringRef Name, |
| 122 | 102 | Kind SectionKind); |
| 123 | 103 | |
| 104 | static bool classof(const SectionBase *S) { return S->kind() != Output; } | |
| 105 | ||
| 106 | // The file which contains this section. It's dynamic type is always | |
| 107 | // ObjFile<ELFT>, but in order to avoid ELFT, we use InputFile as | |
| 108 | // its static type. | |
| 109 | InputFile *File; | |
| 110 | ||
| 111 | template <class ELFT> ObjFile<ELFT> *getFile() const { | |
| 112 | return cast_or_null<ObjFile<ELFT>>(File); | |
| 113 | } | |
| 114 | ||
| 115 | ArrayRef<uint8_t> Data; | |
| 116 | uint64_t getOffsetInFile() const; | |
| 117 | ||
| 118 | // True if this section has already been placed to a linker script | |
| 119 | // output section. This is needed because, in a linker script, you | |
| 120 | // can refer to the same section more than once. For example, in | |
| 121 | // the following linker script, | |
| 122 | // | |
| 123 | // .foo : { *(.text) } | |
| 124 | // .bar : { *(.text) } | |
| 125 | // | |
| 126 | // .foo takes all .text sections, and .bar becomes empty. To achieve | |
| 127 | // this, we need to memorize whether a section has been placed or | |
| 128 | // not for each input section. | |
| 129 | bool Assigned = false; | |
| 130 | ||
| 124 | 131 | // Input sections are part of an output section. Special sections |
| 125 | 132 | // like .eh_frame and merge sections are first combined into a |
| 126 | 133 | // synthetic section that is then added to an output section. In all |
| ... | ... | @@ -131,12 +138,14 @@ public: |
| 131 | 138 | const void *FirstRelocation = nullptr; |
| 132 | 139 | unsigned NumRelocations : 31; |
| 133 | 140 | unsigned AreRelocsRela : 1; |
| 141 | ||
| 134 | 142 | template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const { |
| 135 | 143 | assert(!AreRelocsRela); |
| 136 | 144 | return llvm::makeArrayRef( |
| 137 | 145 | static_cast<const typename ELFT::Rel *>(FirstRelocation), |
| 138 | 146 | NumRelocations); |
| 139 | 147 | } |
| 148 | ||
| 140 | 149 | template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const { |
| 141 | 150 | assert(AreRelocsRela); |
| 142 | 151 | return llvm::makeArrayRef( |
| ... | ... | @@ -144,38 +153,33 @@ public: |
| 144 | 153 | NumRelocations); |
| 145 | 154 | } |
| 146 | 155 | |
| 147 | // This pointer points to the "real" instance of this instance. | |
| 148 | // Usually Repl == this. However, if ICF merges two sections, | |
| 149 | // Repl pointer of one section points to another section. So, | |
| 150 | // if you need to get a pointer to this instance, do not use | |
| 151 | // this but instead this->Repl. | |
| 152 | InputSectionBase *Repl; | |
| 153 | ||
| 154 | 156 | // InputSections that are dependent on us (reverse dependency for GC) |
| 155 | llvm::TinyPtrVector<InputSectionBase *> DependentSections; | |
| 157 | llvm::TinyPtrVector<InputSection *> DependentSections; | |
| 156 | 158 | |
| 157 | 159 | // Returns the size of this section (even if this is a common or BSS.) |
| 158 | 160 | size_t getSize() const; |
| 159 | 161 | |
| 160 | template <class ELFT> ObjectFile<ELFT> *getFile() const; | |
| 161 | ||
| 162 | template <class ELFT> llvm::object::ELFFile<ELFT> getObj() const { | |
| 163 | return getFile<ELFT>()->getObj(); | |
| 164 | } | |
| 165 | ||
| 166 | 162 | InputSection *getLinkOrderDep() const; |
| 167 | 163 | |
| 168 | void uncompress(); | |
| 164 | // Compilers emit zlib-compressed debug sections if the -gz option | |
| 165 | // is given. This function checks if this section is compressed, and | |
| 166 | // if so, decompress in memory. | |
| 167 | void maybeUncompress(); | |
| 169 | 168 | |
| 170 | 169 | // Returns a source location string. Used to construct an error message. |
| 171 | 170 | template <class ELFT> std::string getLocation(uint64_t Offset); |
| 172 | template <class ELFT> std::string getSrcMsg(uint64_t Offset); | |
| 173 | template <class ELFT> std::string getObjMsg(uint64_t Offset); | |
| 171 | std::string getSrcMsg(const Symbol &Sym, uint64_t Offset); | |
| 172 | std::string getObjMsg(uint64_t Offset); | |
| 174 | 173 | |
| 174 | // Each section knows how to relocate itself. These functions apply | |
| 175 | // relocations, assuming that Buf points to this section's copy in | |
| 176 | // the mmap'ed output buffer. | |
| 175 | 177 | template <class ELFT> void relocate(uint8_t *Buf, uint8_t *BufEnd); |
| 176 | 178 | void relocateAlloc(uint8_t *Buf, uint8_t *BufEnd); |
| 177 | template <class ELFT> void relocateNonAlloc(uint8_t *Buf, uint8_t *BufEnd); | |
| 178 | 179 | |
| 180 | // The native ELF reloc data type is not very convenient to handle. | |
| 181 | // So we convert ELF reloc records to our own records in Relocations.cpp. | |
| 182 | // This vector contains such "cooked" relocations. | |
| 179 | 183 | std::vector<Relocation> Relocations; |
| 180 | 184 | |
| 181 | 185 | template <typename T> llvm::ArrayRef<T> getDataAs() const { |
| ... | ... | @@ -183,36 +187,46 @@ public: |
| 183 | 187 | assert(S % sizeof(T) == 0); |
| 184 | 188 | return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T)); |
| 185 | 189 | } |
| 190 | ||
| 191 | private: | |
| 192 | // A pointer that owns uncompressed data if a section is compressed by zlib. | |
| 193 | // Since the feature is not used often, this is usually a nullptr. | |
| 194 | std::unique_ptr<char[]> UncompressBuf; | |
| 186 | 195 | }; |
| 187 | 196 | |
| 188 | 197 | // SectionPiece represents a piece of splittable section contents. |
| 189 | 198 | // We allocate a lot of these and binary search on them. This means that they |
| 190 | 199 | // have to be as compact as possible, which is why we don't store the size (can |
| 191 | // be found by looking at the next one) and put the hash in a side table. | |
| 200 | // be found by looking at the next one). | |
| 192 | 201 | struct SectionPiece { |
| 193 | SectionPiece(size_t Off, bool Live = false) | |
| 194 | : InputOff(Off), OutputOff(-1), Live(Live || !Config->GcSections) {} | |
| 195 | ||
| 196 | size_t InputOff; | |
| 197 | ssize_t OutputOff : 8 * sizeof(ssize_t) - 1; | |
| 198 | size_t Live : 1; | |
| 202 | SectionPiece(size_t Off, uint32_t Hash, bool Live) | |
| 203 | : InputOff(Off), Hash(Hash), OutputOff(-1), | |
| 204 | Live(Live || !Config->GcSections) {} | |
| 205 | ||
| 206 | uint32_t InputOff; | |
| 207 | uint32_t Hash; | |
| 208 | int64_t OutputOff : 63; | |
| 209 | uint64_t Live : 1; | |
| 199 | 210 | }; |
| 200 | static_assert(sizeof(SectionPiece) == 2 * sizeof(size_t), | |
| 201 | "SectionPiece is too big"); | |
| 211 | ||
| 212 | static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big"); | |
| 202 | 213 | |
| 203 | 214 | // This corresponds to a SHF_MERGE section of an input file. |
| 204 | 215 | class MergeInputSection : public InputSectionBase { |
| 205 | 216 | public: |
| 206 | 217 | template <class ELFT> |
| 207 | MergeInputSection(ObjectFile<ELFT> *F, const typename ELFT::Shdr *Header, | |
| 218 | MergeInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header, | |
| 208 | 219 | StringRef Name); |
| 209 | static bool classof(const SectionBase *S); | |
| 220 | MergeInputSection(uint64_t Flags, uint32_t Type, uint64_t Entsize, | |
| 221 | ArrayRef<uint8_t> Data, StringRef Name); | |
| 222 | ||
| 223 | static bool classof(const SectionBase *S) { return S->kind() == Merge; } | |
| 210 | 224 | void splitIntoPieces(); |
| 211 | 225 | |
| 212 | 226 | // Mark the piece at a given offset live. Used by GC. |
| 213 | 227 | void markLiveAt(uint64_t Offset) { |
| 214 | assert(this->Flags & llvm::ELF::SHF_ALLOC); | |
| 215 | LiveOffsets.insert(Offset); | |
| 228 | if (this->Flags & llvm::ELF::SHF_ALLOC) | |
| 229 | LiveOffsets.insert(Offset); | |
| 216 | 230 | } |
| 217 | 231 | |
| 218 | 232 | // Translate an offset in the input section to an offset |
| ... | ... | @@ -228,14 +242,9 @@ public: |
| 228 | 242 | LLVM_ATTRIBUTE_ALWAYS_INLINE |
| 229 | 243 | llvm::CachedHashStringRef getData(size_t I) const { |
| 230 | 244 | size_t Begin = Pieces[I].InputOff; |
| 231 | size_t End; | |
| 232 | if (Pieces.size() - 1 == I) | |
| 233 | End = this->Data.size(); | |
| 234 | else | |
| 235 | End = Pieces[I + 1].InputOff; | |
| 236 | ||
| 237 | StringRef S = {(const char *)(this->Data.data() + Begin), End - Begin}; | |
| 238 | return {S, Hashes[I]}; | |
| 245 | size_t End = | |
| 246 | (Pieces.size() - 1 == I) ? Data.size() : Pieces[I + 1].InputOff; | |
| 247 | return {toStringRef(Data.slice(Begin, End - Begin)), Pieces[I].Hash}; | |
| 239 | 248 | } |
| 240 | 249 | |
| 241 | 250 | // Returns the SectionPiece at a given input section offset. |
| ... | ... | @@ -248,24 +257,23 @@ private: |
| 248 | 257 | void splitStrings(ArrayRef<uint8_t> A, size_t Size); |
| 249 | 258 | void splitNonStrings(ArrayRef<uint8_t> A, size_t Size); |
| 250 | 259 | |
| 251 | std::vector<uint32_t> Hashes; | |
| 252 | ||
| 253 | mutable llvm::DenseMap<uint64_t, uint64_t> OffsetMap; | |
| 260 | mutable llvm::DenseMap<uint32_t, uint32_t> OffsetMap; | |
| 254 | 261 | mutable llvm::once_flag InitOffsetMap; |
| 255 | 262 | |
| 256 | 263 | llvm::DenseSet<uint64_t> LiveOffsets; |
| 257 | 264 | }; |
| 258 | 265 | |
| 259 | struct EhSectionPiece : public SectionPiece { | |
| 260 | EhSectionPiece(size_t Off, InputSectionBase *ID, uint32_t Size, | |
| 266 | struct EhSectionPiece { | |
| 267 | EhSectionPiece(size_t Off, InputSectionBase *Sec, uint32_t Size, | |
| 261 | 268 | unsigned FirstRelocation) |
| 262 | : SectionPiece(Off, false), ID(ID), Size(Size), | |
| 263 | FirstRelocation(FirstRelocation) {} | |
| 264 | InputSectionBase *ID; | |
| 265 | uint32_t Size; | |
| 266 | uint32_t size() const { return Size; } | |
| 269 | : InputOff(Off), Sec(Sec), Size(Size), FirstRelocation(FirstRelocation) {} | |
| 267 | 270 | |
| 268 | ArrayRef<uint8_t> data() { return {ID->Data.data() + this->InputOff, Size}; } | |
| 271 | ArrayRef<uint8_t> data() { return {Sec->Data.data() + this->InputOff, Size}; } | |
| 272 | ||
| 273 | size_t InputOff; | |
| 274 | ssize_t OutputOff = -1; | |
| 275 | InputSectionBase *Sec; | |
| 276 | uint32_t Size; | |
| 269 | 277 | unsigned FirstRelocation; |
| 270 | 278 | }; |
| 271 | 279 | |
| ... | ... | @@ -273,9 +281,9 @@ struct EhSectionPiece : public SectionPiece { |
| 273 | 281 | class EhInputSection : public InputSectionBase { |
| 274 | 282 | public: |
| 275 | 283 | template <class ELFT> |
| 276 | EhInputSection(ObjectFile<ELFT> *F, const typename ELFT::Shdr *Header, | |
| 284 | EhInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header, | |
| 277 | 285 | StringRef Name); |
| 278 | static bool classof(const SectionBase *S); | |
| 286 | static bool classof(const SectionBase *S) { return S->kind() == EHFrame; } | |
| 279 | 287 | template <class ELFT> void split(); |
| 280 | 288 | template <class ELFT, class RelTy> void split(ArrayRef<RelTy> Rels); |
| 281 | 289 | |
| ... | ... | @@ -292,10 +300,10 @@ public: |
| 292 | 300 | // .eh_frame. It also includes the synthetic sections themselves. |
| 293 | 301 | class InputSection : public InputSectionBase { |
| 294 | 302 | public: |
| 295 | InputSection(uint64_t Flags, uint32_t Type, uint32_t Alignment, | |
| 303 | InputSection(InputFile *F, uint64_t Flags, uint32_t Type, uint32_t Alignment, | |
| 296 | 304 | ArrayRef<uint8_t> Data, StringRef Name, Kind K = Regular); |
| 297 | 305 | template <class ELFT> |
| 298 | InputSection(ObjectFile<ELFT> *F, const typename ELFT::Shdr *Header, | |
| 306 | InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header, | |
| 299 | 307 | StringRef Name); |
| 300 | 308 | |
| 301 | 309 | // Write this section to a mmap'ed file, assuming Buf is pointing to |
| ... | ... | @@ -304,8 +312,10 @@ public: |
| 304 | 312 | |
| 305 | 313 | OutputSection *getParent() const; |
| 306 | 314 | |
| 307 | // The offset from beginning of the output sections this section was assigned | |
| 308 | // to. The writer sets a value. | |
| 315 | // This variable has two usages. Initially, it represents an index in the | |
| 316 | // OutputSection's InputSection list, and is used when ordering SHF_LINK_ORDER | |
| 317 | // sections. After assignAddresses is called, it represents the offset from | |
| 318 | // the beginning of the output section this section was assigned to. | |
| 309 | 319 | uint64_t OutSecOff = 0; |
| 310 | 320 | |
| 311 | 321 | static bool classof(const SectionBase *S); |
| ... | ... | @@ -321,6 +331,8 @@ public: |
| 321 | 331 | // Called by ICF to merge two input sections. |
| 322 | 332 | void replace(InputSection *Other); |
| 323 | 333 | |
| 334 | static InputSection Discarded; | |
| 335 | ||
| 324 | 336 | private: |
| 325 | 337 | template <class ELFT, class RelTy> |
| 326 | 338 | void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels); |
| ... | ... | @@ -331,6 +343,9 @@ private: |
| 331 | 343 | // The list of all input sections. |
| 332 | 344 | extern std::vector<InputSectionBase *> InputSections; |
| 333 | 345 | |
| 346 | // Builds section order for handling --symbol-ordering-file. | |
| 347 | llvm::DenseMap<SectionBase *, int> buildSectionOrder(); | |
| 348 | ||
| 334 | 349 | } // namespace elf |
| 335 | 350 | |
| 336 | 351 | std::string toString(const elf::InputSectionBase *); |
deps/lld/ELF/LTO.cpp+45-18| ... | ... | @@ -9,10 +9,12 @@ |
| 9 | 9 | |
| 10 | 10 | #include "LTO.h" |
| 11 | 11 | #include "Config.h" |
| 12 | #include "Error.h" | |
| 13 | 12 | #include "InputFiles.h" |
| 13 | #include "LinkerScript.h" | |
| 14 | #include "SymbolTable.h" | |
| 14 | 15 | #include "Symbols.h" |
| 15 | #include "lld/Core/TargetOptionsCommandFlags.h" | |
| 16 | #include "lld/Common/ErrorHandler.h" | |
| 17 | #include "lld/Common/TargetOptionsCommandFlags.h" | |
| 16 | 18 | #include "llvm/ADT/STLExtras.h" |
| 17 | 19 | #include "llvm/ADT/SmallString.h" |
| 18 | 20 | #include "llvm/ADT/StringRef.h" |
| ... | ... | @@ -60,10 +62,8 @@ static void diagnosticHandler(const DiagnosticInfo &DI) { |
| 60 | 62 | } |
| 61 | 63 | |
| 62 | 64 | static void checkError(Error E) { |
| 63 | handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) -> Error { | |
| 64 | error(EIB.message()); | |
| 65 | return Error::success(); | |
| 66 | }); | |
| 65 | handleAllErrors(std::move(E), | |
| 66 | [&](ErrorInfoBase &EIB) { error(EIB.message()); }); | |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | 69 | static std::unique_ptr<lto::LTO> createLTO() { |
| ... | ... | @@ -73,6 +73,10 @@ static std::unique_ptr<lto::LTO> createLTO() { |
| 73 | 73 | Conf.Options = InitTargetOptionsFromCodeGenFlags(); |
| 74 | 74 | Conf.Options.RelaxELFRelocations = true; |
| 75 | 75 | |
| 76 | // Always emit a section per function/datum with LTO. | |
| 77 | Conf.Options.FunctionSections = true; | |
| 78 | Conf.Options.DataSections = true; | |
| 79 | ||
| 76 | 80 | if (Config->Relocatable) |
| 77 | 81 | Conf.RelocModel = None; |
| 78 | 82 | else if (Config->Pic) |
| ... | ... | @@ -103,13 +107,20 @@ static std::unique_ptr<lto::LTO> createLTO() { |
| 103 | 107 | Config->LTOPartitions); |
| 104 | 108 | } |
| 105 | 109 | |
| 106 | BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {} | |
| 110 | BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) { | |
| 111 | for (Symbol *Sym : Symtab->getSymbols()) { | |
| 112 | StringRef Name = Sym->getName(); | |
| 113 | for (StringRef Prefix : {"__start_", "__stop_"}) | |
| 114 | if (Name.startswith(Prefix)) | |
| 115 | UsedStartStop.insert(Name.substr(Prefix.size())); | |
| 116 | } | |
| 117 | } | |
| 107 | 118 | |
| 108 | 119 | BitcodeCompiler::~BitcodeCompiler() = default; |
| 109 | 120 | |
| 110 | 121 | static void undefine(Symbol *S) { |
| 111 | replaceBody<Undefined>(S, S->body()->getName(), /*IsLocal=*/false, | |
| 112 | STV_DEFAULT, S->body()->Type, nullptr); | |
| 122 | replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_GLOBAL, STV_DEFAULT, | |
| 123 | S->Type); | |
| 113 | 124 | } |
| 114 | 125 | |
| 115 | 126 | void BitcodeCompiler::add(BitcodeFile &F) { |
| ... | ... | @@ -118,25 +129,42 @@ void BitcodeCompiler::add(BitcodeFile &F) { |
| 118 | 129 | std::vector<Symbol *> Syms = F.getSymbols(); |
| 119 | 130 | std::vector<lto::SymbolResolution> Resols(Syms.size()); |
| 120 | 131 | |
| 132 | DenseSet<StringRef> ScriptSymbols; | |
| 133 | for (BaseCommand *Base : Script->SectionCommands) | |
| 134 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) | |
| 135 | ScriptSymbols.insert(Cmd->Name); | |
| 136 | ||
| 121 | 137 | // Provide a resolution to the LTO API for each symbol. |
| 122 | 138 | for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) { |
| 123 | 139 | Symbol *Sym = Syms[SymNum]; |
| 124 | 140 | lto::SymbolResolution &R = Resols[SymNum]; |
| 125 | 141 | ++SymNum; |
| 126 | SymbolBody *B = Sym->body(); | |
| 127 | 142 | |
| 128 | 143 | // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile |
| 129 | 144 | // reports two symbols for module ASM defined. Without this check, lld |
| 130 | 145 | // flags an undefined in IR with a definition in ASM as prevailing. |
| 131 | 146 | // Once IRObjectFile is fixed to report only one symbol this hack can |
| 132 | 147 | // be removed. |
| 133 | R.Prevailing = !ObjSym.isUndefined() && B->File == &F; | |
| 134 | ||
| 135 | R.VisibleToRegularObj = | |
| 136 | Sym->IsUsedInRegularObj || (R.Prevailing && Sym->includeInDynsym()); | |
| 148 | R.Prevailing = !ObjSym.isUndefined() && Sym->File == &F; | |
| 149 | ||
| 150 | // We ask LTO to preserve following global symbols: | |
| 151 | // 1) All symbols when doing relocatable link, so that them can be used | |
| 152 | // for doing final link. | |
| 153 | // 2) Symbols that are used in regular objects. | |
| 154 | // 3) C named sections if we have corresponding __start_/__stop_ symbol. | |
| 155 | // 4) Symbols that are defined in bitcode files and used for dynamic linking. | |
| 156 | R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj || | |
| 157 | (R.Prevailing && Sym->includeInDynsym()) || | |
| 158 | UsedStartStop.count(ObjSym.getSectionName()); | |
| 137 | 159 | if (R.Prevailing) |
| 138 | 160 | undefine(Sym); |
| 139 | R.LinkerRedefined = Config->RenamedSymbols.count(Sym); | |
| 161 | ||
| 162 | // We tell LTO to not apply interprocedural optimization for following | |
| 163 | // symbols because otherwise LTO would inline them while their values are | |
| 164 | // still not final: | |
| 165 | // 1) Aliased (with --defsym) or wrapped (with --wrap) symbols. | |
| 166 | // 2) Symbols redefined in linker script. | |
| 167 | R.LinkerRedefined = !Sym->CanInline || ScriptSymbols.count(Sym->getName()); | |
| 140 | 168 | } |
| 141 | 169 | checkError(LTOObj->add(std::move(F.Obj), Resols)); |
| 142 | 170 | } |
| ... | ... | @@ -156,9 +184,8 @@ std::vector<InputFile *> BitcodeCompiler::compile() { |
| 156 | 184 | if (!Config->ThinLTOCacheDir.empty()) |
| 157 | 185 | Cache = check( |
| 158 | 186 | lto::localCache(Config->ThinLTOCacheDir, |
| 159 | [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) { | |
| 160 | Files[Task] = std::move(MB); | |
| 161 | })); | |
| 187 | [&](size_t Task, std::unique_ptr<MemoryBuffer> MB, | |
| 188 | StringRef Path) { Files[Task] = std::move(MB); })); | |
| 162 | 189 | |
| 163 | 190 | checkError(LTOObj->run( |
| 164 | 191 | [&](size_t Task) { |
deps/lld/ELF/LTO.h+3-1| ... | ... | @@ -21,7 +21,8 @@ |
| 21 | 21 | #ifndef LLD_ELF_LTO_H |
| 22 | 22 | #define LLD_ELF_LTO_H |
| 23 | 23 | |
| 24 | #include "lld/Core/LLVM.h" | |
| 24 | #include "lld/Common/LLVM.h" | |
| 25 | #include "llvm/ADT/DenseSet.h" | |
| 25 | 26 | #include "llvm/ADT/SmallString.h" |
| 26 | 27 | #include <memory> |
| 27 | 28 | #include <vector> |
| ... | ... | @@ -50,6 +51,7 @@ private: |
| 50 | 51 | std::unique_ptr<llvm::lto::LTO> LTOObj; |
| 51 | 52 | std::vector<SmallString<0>> Buff; |
| 52 | 53 | std::vector<std::unique_ptr<MemoryBuffer>> Files; |
| 54 | llvm::DenseSet<StringRef> UsedStartStop; | |
| 53 | 55 | }; |
| 54 | 56 | } // namespace elf |
| 55 | 57 | } // namespace lld |
deps/lld/ELF/LinkerScript.cpp+591-816| ... | ... | @@ -14,20 +14,19 @@ |
| 14 | 14 | #include "LinkerScript.h" |
| 15 | 15 | #include "Config.h" |
| 16 | 16 | #include "InputSection.h" |
| 17 | #include "Memory.h" | |
| 18 | 17 | #include "OutputSections.h" |
| 19 | 18 | #include "Strings.h" |
| 20 | 19 | #include "SymbolTable.h" |
| 21 | 20 | #include "Symbols.h" |
| 22 | 21 | #include "SyntheticSections.h" |
| 23 | 22 | #include "Target.h" |
| 24 | #include "Threads.h" | |
| 25 | 23 | #include "Writer.h" |
| 24 | #include "lld/Common/Memory.h" | |
| 25 | #include "lld/Common/Threads.h" | |
| 26 | 26 | #include "llvm/ADT/STLExtras.h" |
| 27 | 27 | #include "llvm/ADT/StringRef.h" |
| 28 | 28 | #include "llvm/BinaryFormat/ELF.h" |
| 29 | 29 | #include "llvm/Support/Casting.h" |
| 30 | #include "llvm/Support/Compression.h" | |
| 31 | 30 | #include "llvm/Support/Endian.h" |
| 32 | 31 | #include "llvm/Support/ErrorHandling.h" |
| 33 | 32 | #include "llvm/Support/FileSystem.h" |
| ... | ... | @@ -50,62 +49,56 @@ using namespace lld::elf; |
| 50 | 49 | |
| 51 | 50 | LinkerScript *elf::Script; |
| 52 | 51 | |
| 52 | static uint64_t getOutputSectionVA(SectionBase *InputSec, StringRef Loc) { | |
| 53 | if (OutputSection *OS = InputSec->getOutputSection()) | |
| 54 | return OS->Addr; | |
| 55 | error(Loc + ": unable to evaluate expression: input section " + | |
| 56 | InputSec->Name + " has no output section assigned"); | |
| 57 | return 0; | |
| 58 | } | |
| 59 | ||
| 53 | 60 | uint64_t ExprValue::getValue() const { |
| 54 | if (Sec) { | |
| 55 | if (OutputSection *OS = Sec->getOutputSection()) | |
| 56 | return alignTo(Sec->getOffset(Val) + OS->Addr, Alignment); | |
| 57 | error(Loc + ": unable to evaluate expression: input section " + Sec->Name + | |
| 58 | " has no output section assigned"); | |
| 59 | } | |
| 61 | if (Sec) | |
| 62 | return alignTo(Sec->getOffset(Val) + getOutputSectionVA(Sec, Loc), | |
| 63 | Alignment); | |
| 60 | 64 | return alignTo(Val, Alignment); |
| 61 | 65 | } |
| 62 | 66 | |
| 63 | 67 | uint64_t ExprValue::getSecAddr() const { |
| 64 | 68 | if (Sec) |
| 65 | return Sec->getOffset(0) + Sec->getOutputSection()->Addr; | |
| 69 | return Sec->getOffset(0) + getOutputSectionVA(Sec, Loc); | |
| 66 | 70 | return 0; |
| 67 | 71 | } |
| 68 | 72 | |
| 69 | template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) { | |
| 70 | Symbol *Sym; | |
| 71 | uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; | |
| 72 | std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert( | |
| 73 | Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false, | |
| 74 | /*File*/ nullptr); | |
| 75 | Sym->Binding = STB_GLOBAL; | |
| 76 | ExprValue Value = Cmd->Expression(); | |
| 77 | SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec; | |
| 78 | ||
| 79 | // We want to set symbol values early if we can. This allows us to use symbols | |
| 80 | // as variables in linker scripts. Doing so allows us to write expressions | |
| 81 | // like this: `alignment = 16; . = ALIGN(., alignment)` | |
| 82 | uint64_t SymValue = Value.isAbsolute() ? Value.getValue() : 0; | |
| 83 | replaceBody<DefinedRegular>(Sym, Cmd->Name, /*IsLocal=*/false, Visibility, | |
| 84 | STT_NOTYPE, SymValue, 0, Sec, nullptr); | |
| 85 | return Sym->body(); | |
| 73 | uint64_t ExprValue::getSectionOffset() const { | |
| 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 | |
| 76 | // cases where the output section is not yet known. | |
| 77 | if (Alignment == 1) | |
| 78 | return Val; | |
| 79 | return getValue() - getSecAddr(); | |
| 86 | 80 | } |
| 87 | 81 | |
| 88 | OutputSectionCommand * | |
| 89 | LinkerScript::createOutputSectionCommand(StringRef Name, StringRef Location) { | |
| 90 | OutputSectionCommand *&CmdRef = NameToOutputSectionCommand[Name]; | |
| 91 | OutputSectionCommand *Cmd; | |
| 92 | if (CmdRef && CmdRef->Location.empty()) { | |
| 82 | OutputSection *LinkerScript::createOutputSection(StringRef Name, | |
| 83 | StringRef Location) { | |
| 84 | OutputSection *&SecRef = NameToOutputSection[Name]; | |
| 85 | OutputSection *Sec; | |
| 86 | if (SecRef && SecRef->Location.empty()) { | |
| 93 | 87 | // There was a forward reference. |
| 94 | Cmd = CmdRef; | |
| 88 | Sec = SecRef; | |
| 95 | 89 | } else { |
| 96 | Cmd = make<OutputSectionCommand>(Name); | |
| 97 | if (!CmdRef) | |
| 98 | CmdRef = Cmd; | |
| 90 | Sec = make<OutputSection>(Name, SHT_NOBITS, 0); | |
| 91 | if (!SecRef) | |
| 92 | SecRef = Sec; | |
| 99 | 93 | } |
| 100 | Cmd->Location = Location; | |
| 101 | return Cmd; | |
| 94 | Sec->Location = Location; | |
| 95 | return Sec; | |
| 102 | 96 | } |
| 103 | 97 | |
| 104 | OutputSectionCommand * | |
| 105 | LinkerScript::getOrCreateOutputSectionCommand(StringRef Name) { | |
| 106 | OutputSectionCommand *&CmdRef = NameToOutputSectionCommand[Name]; | |
| 98 | OutputSection *LinkerScript::getOrCreateOutputSection(StringRef Name) { | |
| 99 | OutputSection *&CmdRef = NameToOutputSection[Name]; | |
| 107 | 100 | if (!CmdRef) |
| 108 | CmdRef = make<OutputSectionCommand>(Name); | |
| 101 | CmdRef = make<OutputSection>(Name, SHT_PROGBITS, 0); | |
| 109 | 102 | return CmdRef; |
| 110 | 103 | } |
| 111 | 104 | |
| ... | ... | @@ -113,135 +106,95 @@ void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) { |
| 113 | 106 | uint64_t Val = E().getValue(); |
| 114 | 107 | if (Val < Dot && InSec) |
| 115 | 108 | error(Loc + ": unable to move location counter backward for: " + |
| 116 | CurAddressState->OutSec->Name); | |
| 109 | Ctx->OutSec->Name); | |
| 117 | 110 | Dot = Val; |
| 111 | ||
| 118 | 112 | // Update to location counter means update to section size. |
| 119 | 113 | if (InSec) |
| 120 | CurAddressState->OutSec->Size = Dot - CurAddressState->OutSec->Addr; | |
| 121 | } | |
| 122 | ||
| 123 | // Sets value of a symbol. Two kinds of symbols are processed: synthetic | |
| 124 | // symbols, whose value is an offset from beginning of section and regular | |
| 125 | // symbols whose value is absolute. | |
| 126 | void LinkerScript::assignSymbol(SymbolAssignment *Cmd, bool InSec) { | |
| 127 | if (Cmd->Name == ".") { | |
| 128 | setDot(Cmd->Expression, Cmd->Location, InSec); | |
| 129 | return; | |
| 130 | } | |
| 131 | ||
| 132 | if (!Cmd->Sym) | |
| 133 | return; | |
| 134 | ||
| 135 | auto *Sym = cast<DefinedRegular>(Cmd->Sym); | |
| 136 | ExprValue V = Cmd->Expression(); | |
| 137 | if (V.isAbsolute()) { | |
| 138 | Sym->Value = V.getValue(); | |
| 139 | } else { | |
| 140 | Sym->Section = V.Sec; | |
| 141 | Sym->Value = alignTo(V.Val, V.Alignment); | |
| 142 | } | |
| 143 | } | |
| 144 | ||
| 145 | static SymbolBody *findSymbol(StringRef S) { | |
| 146 | switch (Config->EKind) { | |
| 147 | case ELF32LEKind: | |
| 148 | return Symtab<ELF32LE>::X->find(S); | |
| 149 | case ELF32BEKind: | |
| 150 | return Symtab<ELF32BE>::X->find(S); | |
| 151 | case ELF64LEKind: | |
| 152 | return Symtab<ELF64LE>::X->find(S); | |
| 153 | case ELF64BEKind: | |
| 154 | return Symtab<ELF64BE>::X->find(S); | |
| 155 | default: | |
| 156 | llvm_unreachable("unknown Config->EKind"); | |
| 157 | } | |
| 158 | } | |
| 159 | ||
| 160 | static SymbolBody *addRegularSymbol(SymbolAssignment *Cmd) { | |
| 161 | switch (Config->EKind) { | |
| 162 | case ELF32LEKind: | |
| 163 | return addRegular<ELF32LE>(Cmd); | |
| 164 | case ELF32BEKind: | |
| 165 | return addRegular<ELF32BE>(Cmd); | |
| 166 | case ELF64LEKind: | |
| 167 | return addRegular<ELF64LE>(Cmd); | |
| 168 | case ELF64BEKind: | |
| 169 | return addRegular<ELF64BE>(Cmd); | |
| 170 | default: | |
| 171 | llvm_unreachable("unknown Config->EKind"); | |
| 172 | } | |
| 114 | Ctx->OutSec->Size = Dot - Ctx->OutSec->Addr; | |
| 173 | 115 | } |
| 174 | 116 | |
| 117 | // This function is called from processSectionCommands, | |
| 118 | // while we are fixing the output section layout. | |
| 175 | 119 | void LinkerScript::addSymbol(SymbolAssignment *Cmd) { |
| 176 | 120 | if (Cmd->Name == ".") |
| 177 | 121 | return; |
| 178 | 122 | |
| 179 | 123 | // If a symbol was in PROVIDE(), we need to define it only when |
| 180 | 124 | // it is a referenced undefined symbol. |
| 181 | SymbolBody *B = findSymbol(Cmd->Name); | |
| 125 | Symbol *B = Symtab->find(Cmd->Name); | |
| 182 | 126 | if (Cmd->Provide && (!B || B->isDefined())) |
| 183 | 127 | return; |
| 184 | 128 | |
| 185 | Cmd->Sym = addRegularSymbol(Cmd); | |
| 186 | } | |
| 187 | ||
| 188 | bool SymbolAssignment::classof(const BaseCommand *C) { | |
| 189 | return C->Kind == AssignmentKind; | |
| 190 | } | |
| 191 | ||
| 192 | bool OutputSectionCommand::classof(const BaseCommand *C) { | |
| 193 | return C->Kind == OutputSectionKind; | |
| 194 | } | |
| 129 | // Define a symbol. | |
| 130 | Symbol *Sym; | |
| 131 | uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; | |
| 132 | std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, /*Type*/ 0, Visibility, | |
| 133 | /*CanOmitFromDynSym*/ false, | |
| 134 | /*File*/ nullptr); | |
| 135 | ExprValue Value = Cmd->Expression(); | |
| 136 | SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec; | |
| 195 | 137 | |
| 196 | // Fill [Buf, Buf + Size) with Filler. | |
| 197 | // This is used for linker script "=fillexp" command. | |
| 198 | static void fill(uint8_t *Buf, size_t Size, uint32_t Filler) { | |
| 199 | size_t I = 0; | |
| 200 | for (; I + 4 < Size; I += 4) | |
| 201 | memcpy(Buf + I, &Filler, 4); | |
| 202 | memcpy(Buf + I, &Filler, Size - I); | |
| 138 | // When this function is called, section addresses have not been | |
| 139 | // fixed yet. So, we may or may not know the value of the RHS | |
| 140 | // expression. | |
| 141 | // | |
| 142 | // For example, if an expression is `x = 42`, we know x is always 42. | |
| 143 | // However, if an expression is `x = .`, there's no way to know its | |
| 144 | // value at the moment. | |
| 145 | // | |
| 146 | // We want to set symbol values early if we can. This allows us to | |
| 147 | // use symbols as variables in linker scripts. Doing so allows us to | |
| 148 | // write expressions like this: `alignment = 16; . = ALIGN(., alignment)`. | |
| 149 | uint64_t SymValue = Value.Sec ? 0 : Value.getValue(); | |
| 150 | ||
| 151 | replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility, | |
| 152 | STT_NOTYPE, SymValue, 0, Sec); | |
| 153 | Cmd->Sym = cast<Defined>(Sym); | |
| 203 | 154 | } |
| 204 | 155 | |
| 205 | bool InputSectionDescription::classof(const BaseCommand *C) { | |
| 206 | return C->Kind == InputSectionKind; | |
| 207 | } | |
| 156 | // This function is called from assignAddresses, while we are | |
| 157 | // fixing the output section addresses. This function is supposed | |
| 158 | // to set the final value for a given symbol assignment. | |
| 159 | void LinkerScript::assignSymbol(SymbolAssignment *Cmd, bool InSec) { | |
| 160 | if (Cmd->Name == ".") { | |
| 161 | setDot(Cmd->Expression, Cmd->Location, InSec); | |
| 162 | return; | |
| 163 | } | |
| 208 | 164 | |
| 209 | bool AssertCommand::classof(const BaseCommand *C) { | |
| 210 | return C->Kind == AssertKind; | |
| 211 | } | |
| 165 | if (!Cmd->Sym) | |
| 166 | return; | |
| 212 | 167 | |
| 213 | bool BytesDataCommand::classof(const BaseCommand *C) { | |
| 214 | return C->Kind == BytesDataKind; | |
| 168 | ExprValue V = Cmd->Expression(); | |
| 169 | if (V.isAbsolute()) { | |
| 170 | Cmd->Sym->Section = nullptr; | |
| 171 | Cmd->Sym->Value = V.getValue(); | |
| 172 | } else { | |
| 173 | Cmd->Sym->Section = V.Sec; | |
| 174 | Cmd->Sym->Value = V.getSectionOffset(); | |
| 175 | } | |
| 215 | 176 | } |
| 216 | 177 | |
| 217 | static StringRef basename(InputSectionBase *S) { | |
| 218 | if (S->File) | |
| 219 | return sys::path::filename(S->File->getName()); | |
| 220 | return ""; | |
| 178 | static std::string getFilename(InputFile *File) { | |
| 179 | if (!File) | |
| 180 | return ""; | |
| 181 | if (File->ArchiveName.empty()) | |
| 182 | return File->getName(); | |
| 183 | return (File->ArchiveName + "(" + File->getName() + ")").str(); | |
| 221 | 184 | } |
| 222 | 185 | |
| 223 | 186 | bool LinkerScript::shouldKeep(InputSectionBase *S) { |
| 224 | for (InputSectionDescription *ID : Opt.KeptSections) | |
| 225 | if (ID->FilePat.match(basename(S))) | |
| 187 | if (KeptSections.empty()) | |
| 188 | return false; | |
| 189 | std::string Filename = getFilename(S->File); | |
| 190 | for (InputSectionDescription *ID : KeptSections) | |
| 191 | if (ID->FilePat.match(Filename)) | |
| 226 | 192 | for (SectionPattern &P : ID->SectionPatterns) |
| 227 | 193 | if (P.SectionPat.match(S->Name)) |
| 228 | 194 | return true; |
| 229 | 195 | return false; |
| 230 | 196 | } |
| 231 | 197 | |
| 232 | // If an input string is in the form of "foo.N" where N is a number, | |
| 233 | // return N. Otherwise, returns 65536, which is one greater than the | |
| 234 | // lowest priority. | |
| 235 | static int getPriority(StringRef S) { | |
| 236 | size_t Pos = S.rfind('.'); | |
| 237 | if (Pos == StringRef::npos) | |
| 238 | return 65536; | |
| 239 | int V; | |
| 240 | if (!to_integer(S.substr(Pos + 1), V, 10)) | |
| 241 | return 65536; | |
| 242 | return V; | |
| 243 | } | |
| 244 | ||
| 245 | 198 | // A helper function for the SORT() command. |
| 246 | 199 | static std::function<bool(InputSectionBase *, InputSectionBase *)> |
| 247 | 200 | getComparator(SortSectionPolicy K) { |
| ... | ... | @@ -267,28 +220,63 @@ getComparator(SortSectionPolicy K) { |
| 267 | 220 | } |
| 268 | 221 | |
| 269 | 222 | // A helper function for the SORT() command. |
| 270 | static bool matchConstraints(ArrayRef<InputSectionBase *> Sections, | |
| 223 | static bool matchConstraints(ArrayRef<InputSection *> Sections, | |
| 271 | 224 | ConstraintKind Kind) { |
| 272 | 225 | if (Kind == ConstraintKind::NoConstraint) |
| 273 | 226 | return true; |
| 274 | 227 | |
| 275 | bool IsRW = llvm::any_of(Sections, [](InputSectionBase *Sec) { | |
| 276 | return static_cast<InputSectionBase *>(Sec)->Flags & SHF_WRITE; | |
| 277 | }); | |
| 228 | bool IsRW = llvm::any_of( | |
| 229 | Sections, [](InputSection *Sec) { return Sec->Flags & SHF_WRITE; }); | |
| 278 | 230 | |
| 279 | 231 | return (IsRW && Kind == ConstraintKind::ReadWrite) || |
| 280 | 232 | (!IsRW && Kind == ConstraintKind::ReadOnly); |
| 281 | 233 | } |
| 282 | 234 | |
| 283 | static void sortSections(InputSection **Begin, InputSection **End, | |
| 235 | static void sortSections(MutableArrayRef<InputSection *> Vec, | |
| 284 | 236 | SortSectionPolicy K) { |
| 285 | 237 | if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None) |
| 286 | std::stable_sort(Begin, End, getComparator(K)); | |
| 238 | std::stable_sort(Vec.begin(), Vec.end(), getComparator(K)); | |
| 239 | } | |
| 240 | ||
| 241 | // Sort sections as instructed by SORT-family commands and --sort-section | |
| 242 | // option. Because SORT-family commands can be nested at most two depth | |
| 243 | // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command | |
| 244 | // line option is respected even if a SORT command is given, the exact | |
| 245 | // behavior we have here is a bit complicated. Here are the rules. | |
| 246 | // | |
| 247 | // 1. If two SORT commands are given, --sort-section is ignored. | |
| 248 | // 2. If one SORT command is given, and if it is not SORT_NONE, | |
| 249 | // --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. | |
| 251 | // 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, | |
| 253 | // apply sorting provided by --symbol-ordering-file if any exist. | |
| 254 | static void sortInputSections( | |
| 255 | MutableArrayRef<InputSection *> Vec, const SectionPattern &Pat, | |
| 256 | const DenseMap<SectionBase *, int> &Order) { | |
| 257 | if (Pat.SortOuter == SortSectionPolicy::None) | |
| 258 | return; | |
| 259 | ||
| 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) | |
| 270 | sortSections(Vec, Config->SortSection); | |
| 271 | else | |
| 272 | sortSections(Vec, Pat.SortInner); | |
| 273 | sortSections(Vec, Pat.SortOuter); | |
| 287 | 274 | } |
| 288 | 275 | |
| 289 | 276 | // Compute and remember which sections the InputSectionDescription matches. |
| 290 | 277 | std::vector<InputSection *> |
| 291 | LinkerScript::computeInputSections(const InputSectionDescription *Cmd) { | |
| 278 | LinkerScript::computeInputSections(const InputSectionDescription *Cmd, | |
| 279 | const DenseMap<SectionBase *, int> &Order) { | |
| 292 | 280 | std::vector<InputSection *> Ret; |
| 293 | 281 | |
| 294 | 282 | // Collects all sections that satisfy constraints of Cmd. |
| ... | ... | @@ -296,81 +284,60 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd) { |
| 296 | 284 | size_t SizeBefore = Ret.size(); |
| 297 | 285 | |
| 298 | 286 | for (InputSectionBase *Sec : InputSections) { |
| 299 | if (Sec->Assigned) | |
| 287 | if (!Sec->Live || Sec->Assigned) | |
| 300 | 288 | continue; |
| 301 | 289 | |
| 302 | if (!Sec->Live) { | |
| 303 | reportDiscarded(Sec); | |
| 304 | continue; | |
| 305 | } | |
| 306 | ||
| 307 | 290 | // For -emit-relocs we have to ignore entries like |
| 308 | 291 | // .rela.dyn : { *(.rela.data) } |
| 309 | 292 | // which are common because they are in the default bfd script. |
| 310 | 293 | if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA) |
| 311 | 294 | continue; |
| 312 | 295 | |
| 313 | StringRef Filename = basename(Sec); | |
| 296 | std::string Filename = getFilename(Sec->File); | |
| 314 | 297 | if (!Cmd->FilePat.match(Filename) || |
| 315 | 298 | Pat.ExcludedFilePat.match(Filename) || |
| 316 | 299 | !Pat.SectionPat.match(Sec->Name)) |
| 317 | 300 | continue; |
| 318 | 301 | |
| 302 | // It is safe to assume that Sec is an InputSection | |
| 303 | // because mergeable or EH input sections have already been | |
| 304 | // handled and eliminated. | |
| 319 | 305 | Ret.push_back(cast<InputSection>(Sec)); |
| 320 | 306 | Sec->Assigned = true; |
| 321 | 307 | } |
| 322 | 308 | |
| 323 | // Sort sections as instructed by SORT-family commands and --sort-section | |
| 324 | // option. Because SORT-family commands can be nested at most two depth | |
| 325 | // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command | |
| 326 | // line option is respected even if a SORT command is given, the exact | |
| 327 | // behavior we have here is a bit complicated. Here are the rules. | |
| 328 | // | |
| 329 | // 1. If two SORT commands are given, --sort-section is ignored. | |
| 330 | // 2. If one SORT command is given, and if it is not SORT_NONE, | |
| 331 | // --sort-section is handled as an inner SORT command. | |
| 332 | // 3. If one SORT command is given, and if it is SORT_NONE, don't sort. | |
| 333 | // 4. If no SORT command is given, sort according to --sort-section. | |
| 334 | InputSection **Begin = Ret.data() + SizeBefore; | |
| 335 | InputSection **End = Ret.data() + Ret.size(); | |
| 336 | if (Pat.SortOuter != SortSectionPolicy::None) { | |
| 337 | if (Pat.SortInner == SortSectionPolicy::Default) | |
| 338 | sortSections(Begin, End, Config->SortSection); | |
| 339 | else | |
| 340 | sortSections(Begin, End, Pat.SortInner); | |
| 341 | sortSections(Begin, End, Pat.SortOuter); | |
| 342 | } | |
| 309 | sortInputSections(MutableArrayRef<InputSection *>(Ret).slice(SizeBefore), | |
| 310 | Pat, Order); | |
| 343 | 311 | } |
| 344 | 312 | return Ret; |
| 345 | 313 | } |
| 346 | 314 | |
| 347 | void LinkerScript::discard(ArrayRef<InputSectionBase *> V) { | |
| 348 | for (InputSectionBase *S : V) { | |
| 349 | S->Live = false; | |
| 315 | void LinkerScript::discard(ArrayRef<InputSection *> V) { | |
| 316 | for (InputSection *S : V) { | |
| 350 | 317 | if (S == InX::ShStrTab || S == InX::Dynamic || S == InX::DynSymTab || |
| 351 | 318 | S == InX::DynStrTab) |
| 352 | 319 | error("discarding " + S->Name + " section is not allowed"); |
| 320 | ||
| 321 | S->Assigned = false; | |
| 322 | S->Live = false; | |
| 353 | 323 | discard(S->DependentSections); |
| 354 | 324 | } |
| 355 | 325 | } |
| 356 | 326 | |
| 357 | std::vector<InputSectionBase *> | |
| 358 | LinkerScript::createInputSectionList(OutputSectionCommand &OutCmd) { | |
| 359 | std::vector<InputSectionBase *> Ret; | |
| 360 | ||
| 361 | for (BaseCommand *Base : OutCmd.Commands) { | |
| 362 | auto *Cmd = dyn_cast<InputSectionDescription>(Base); | |
| 363 | if (!Cmd) | |
| 364 | continue; | |
| 327 | std::vector<InputSection *> LinkerScript::createInputSectionList( | |
| 328 | OutputSection &OutCmd, const DenseMap<SectionBase *, int> &Order) { | |
| 329 | std::vector<InputSection *> Ret; | |
| 365 | 330 | |
| 366 | Cmd->Sections = computeInputSections(Cmd); | |
| 367 | Ret.insert(Ret.end(), Cmd->Sections.begin(), Cmd->Sections.end()); | |
| 331 | for (BaseCommand *Base : OutCmd.SectionCommands) { | |
| 332 | if (auto *Cmd = dyn_cast<InputSectionDescription>(Base)) { | |
| 333 | Cmd->Sections = computeInputSections(Cmd, Order); | |
| 334 | Ret.insert(Ret.end(), Cmd->Sections.begin(), Cmd->Sections.end()); | |
| 335 | } | |
| 368 | 336 | } |
| 369 | ||
| 370 | 337 | return Ret; |
| 371 | 338 | } |
| 372 | 339 | |
| 373 | void LinkerScript::processCommands(OutputSectionFactory &Factory) { | |
| 340 | void LinkerScript::processSectionCommands() { | |
| 374 | 341 | // A symbol can be assigned before any section is mentioned in the linker |
| 375 | 342 | // script. In an DSO, the symbol values are addresses, so the only important |
| 376 | 343 | // section values are: |
| ... | ... | @@ -382,28 +349,31 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) { |
| 382 | 349 | // which will map to whatever the first actual section is. |
| 383 | 350 | Aether = make<OutputSection>("", 0, SHF_ALLOC); |
| 384 | 351 | Aether->SectionIndex = 1; |
| 385 | auto State = make_unique<AddressState>(Opt); | |
| 386 | // CurAddressState captures the local AddressState and makes it accessible | |
| 387 | // deliberately. This is needed as there are some cases where we cannot just | |
| 352 | ||
| 353 | // Ctx captures the local AddressState and makes it accessible deliberately. | |
| 354 | // This is needed as there are some cases where we cannot just | |
| 388 | 355 | // thread the current state through to a lambda function created by the |
| 389 | 356 | // script parser. |
| 390 | CurAddressState = State.get(); | |
| 391 | CurAddressState->OutSec = Aether; | |
| 392 | Dot = 0; | |
| 357 | auto Deleter = make_unique<AddressState>(); | |
| 358 | Ctx = Deleter.get(); | |
| 359 | Ctx->OutSec = Aether; | |
| 393 | 360 | |
| 394 | for (size_t I = 0; I < Opt.Commands.size(); ++I) { | |
| 361 | size_t I = 0; | |
| 362 | DenseMap<SectionBase *, int> Order = buildSectionOrder(); | |
| 363 | // Add input sections to output sections. | |
| 364 | for (BaseCommand *Base : SectionCommands) { | |
| 395 | 365 | // Handle symbol assignments outside of any output section. |
| 396 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Opt.Commands[I])) { | |
| 366 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) { | |
| 397 | 367 | addSymbol(Cmd); |
| 398 | 368 | continue; |
| 399 | 369 | } |
| 400 | 370 | |
| 401 | if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I])) { | |
| 402 | std::vector<InputSectionBase *> V = createInputSectionList(*Cmd); | |
| 371 | if (auto *Sec = dyn_cast<OutputSection>(Base)) { | |
| 372 | std::vector<InputSection *> V = createInputSectionList(*Sec, Order); | |
| 403 | 373 | |
| 404 | 374 | // The output section name `/DISCARD/' is special. |
| 405 | 375 | // Any input section assigned to it is discarded. |
| 406 | if (Cmd->Name == "/DISCARD/") { | |
| 376 | if (Sec->Name == "/DISCARD/") { | |
| 407 | 377 | discard(V); |
| 408 | 378 | continue; |
| 409 | 379 | } |
| ... | ... | @@ -413,250 +383,261 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) { |
| 413 | 383 | // sections satisfy a given constraint. If not, a directive is handled |
| 414 | 384 | // as if it wasn't present from the beginning. |
| 415 | 385 | // |
| 416 | // Because we'll iterate over Commands many more times, the easiest | |
| 417 | // way to "make it as if it wasn't present" is to just remove it. | |
| 418 | if (!matchConstraints(V, Cmd->Constraint)) { | |
| 386 | // Because we'll iterate over SectionCommands many more times, the easy | |
| 387 | // way to "make it as if it wasn't present" is to make it empty. | |
| 388 | if (!matchConstraints(V, Sec->Constraint)) { | |
| 419 | 389 | for (InputSectionBase *S : V) |
| 420 | 390 | S->Assigned = false; |
| 421 | Opt.Commands.erase(Opt.Commands.begin() + I); | |
| 422 | --I; | |
| 391 | Sec->SectionCommands.clear(); | |
| 423 | 392 | continue; |
| 424 | 393 | } |
| 425 | 394 | |
| 426 | 395 | // A directive may contain symbol definitions like this: |
| 427 | 396 | // ".foo : { ...; bar = .; }". Handle them. |
| 428 | for (BaseCommand *Base : Cmd->Commands) | |
| 397 | for (BaseCommand *Base : Sec->SectionCommands) | |
| 429 | 398 | if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base)) |
| 430 | 399 | addSymbol(OutCmd); |
| 431 | 400 | |
| 432 | 401 | // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign |
| 433 | 402 | // is given, input sections are aligned to that value, whether the |
| 434 | 403 | // given value is larger or smaller than the original section alignment. |
| 435 | if (Cmd->SubalignExpr) { | |
| 436 | uint32_t Subalign = Cmd->SubalignExpr().getValue(); | |
| 404 | if (Sec->SubalignExpr) { | |
| 405 | uint32_t Subalign = Sec->SubalignExpr().getValue(); | |
| 437 | 406 | for (InputSectionBase *S : V) |
| 438 | 407 | S->Alignment = Subalign; |
| 439 | 408 | } |
| 440 | 409 | |
| 441 | 410 | // Add input sections to an output section. |
| 442 | for (InputSectionBase *S : V) | |
| 443 | Factory.addInputSec(S, Cmd->Name, Cmd->Sec); | |
| 444 | if (OutputSection *Sec = Cmd->Sec) { | |
| 445 | assert(Sec->SectionIndex == INT_MAX); | |
| 446 | Sec->SectionIndex = I; | |
| 447 | if (Cmd->Noload) | |
| 448 | Sec->Type = SHT_NOBITS; | |
| 449 | SecToCommand[Sec] = Cmd; | |
| 450 | } | |
| 411 | for (InputSection *S : V) | |
| 412 | Sec->addSection(S); | |
| 413 | ||
| 414 | Sec->SectionIndex = I++; | |
| 415 | if (Sec->Noload) | |
| 416 | Sec->Type = SHT_NOBITS; | |
| 451 | 417 | } |
| 452 | 418 | } |
| 453 | CurAddressState = nullptr; | |
| 419 | Ctx = nullptr; | |
| 454 | 420 | } |
| 455 | 421 | |
| 456 | void LinkerScript::fabricateDefaultCommands() { | |
| 457 | std::vector<BaseCommand *> Commands; | |
| 422 | static OutputSection *findByName(ArrayRef<BaseCommand *> Vec, | |
| 423 | StringRef Name) { | |
| 424 | for (BaseCommand *Base : Vec) | |
| 425 | if (auto *Sec = dyn_cast<OutputSection>(Base)) | |
| 426 | if (Sec->Name == Name) | |
| 427 | return Sec; | |
| 428 | return nullptr; | |
| 429 | } | |
| 458 | 430 | |
| 459 | // Define start address | |
| 460 | uint64_t StartAddr = -1; | |
| 431 | static OutputSection *createSection(InputSectionBase *IS, | |
| 432 | StringRef OutsecName) { | |
| 433 | OutputSection *Sec = Script->createOutputSection(OutsecName, "<internal>"); | |
| 434 | Sec->addSection(cast<InputSection>(IS)); | |
| 435 | return Sec; | |
| 436 | } | |
| 461 | 437 | |
| 462 | // The Sections with -T<section> have been sorted in order of ascending | |
| 463 | // address. We must lower StartAddr if the lowest -T<section address> as | |
| 464 | // calls to setDot() must be monotonically increasing. | |
| 465 | for (auto &KV : Config->SectionStartMap) | |
| 466 | StartAddr = std::min(StartAddr, KV.second); | |
| 438 | static OutputSection *addInputSec(StringMap<OutputSection *> &Map, | |
| 439 | InputSectionBase *IS, StringRef OutsecName) { | |
| 440 | // Sections with SHT_GROUP or SHF_GROUP attributes reach here only when the -r | |
| 441 | // option is given. A section with SHT_GROUP defines a "section group", and | |
| 442 | // its members have SHF_GROUP attribute. Usually these flags have already been | |
| 443 | // stripped by InputFiles.cpp as section groups are processed and uniquified. | |
| 444 | // However, for the -r option, we want to pass through all section groups | |
| 445 | // as-is because adding/removing members or merging them with other groups | |
| 446 | // change their semantics. | |
| 447 | if (IS->Type == SHT_GROUP || (IS->Flags & SHF_GROUP)) | |
| 448 | return createSection(IS, OutsecName); | |
| 449 | ||
| 450 | // Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have | |
| 451 | // relocation sections .rela.foo and .rela.bar for example. Most tools do | |
| 452 | // not allow multiple REL[A] sections for output section. Hence we | |
| 453 | // should combine these relocation sections into single output. | |
| 454 | // We skip synthetic sections because it can be .rela.dyn/.rela.plt or any | |
| 455 | // other REL[A] sections created by linker itself. | |
| 456 | if (!isa<SyntheticSection>(IS) && | |
| 457 | (IS->Type == SHT_REL || IS->Type == SHT_RELA)) { | |
| 458 | auto *Sec = cast<InputSection>(IS); | |
| 459 | OutputSection *Out = Sec->getRelocatedSection()->getOutputSection(); | |
| 460 | ||
| 461 | if (Out->RelocationSection) { | |
| 462 | Out->RelocationSection->addSection(Sec); | |
| 463 | return nullptr; | |
| 464 | } | |
| 467 | 465 | |
| 468 | Commands.push_back(make<SymbolAssignment>( | |
| 469 | ".", | |
| 470 | [=] { | |
| 471 | return std::min(StartAddr, Config->ImageBase + elf::getHeaderSize()); | |
| 472 | }, | |
| 473 | "")); | |
| 466 | Out->RelocationSection = createSection(IS, OutsecName); | |
| 467 | return Out->RelocationSection; | |
| 468 | } | |
| 474 | 469 | |
| 475 | // For each OutputSection that needs a VA fabricate an OutputSectionCommand | |
| 476 | // with an InputSectionDescription describing the InputSections | |
| 477 | for (OutputSection *Sec : OutputSections) { | |
| 478 | auto *OSCmd = createOutputSectionCommand(Sec->Name, "<internal>"); | |
| 479 | OSCmd->Sec = Sec; | |
| 480 | SecToCommand[Sec] = OSCmd; | |
| 481 | ||
| 482 | Commands.push_back(OSCmd); | |
| 483 | if (Sec->Sections.size()) { | |
| 484 | auto *ISD = make<InputSectionDescription>(""); | |
| 485 | OSCmd->Commands.push_back(ISD); | |
| 486 | for (InputSection *ISec : Sec->Sections) { | |
| 487 | ISD->Sections.push_back(ISec); | |
| 488 | ISec->Assigned = true; | |
| 489 | } | |
| 490 | } | |
| 470 | // When control reaches here, mergeable sections have already been merged into | |
| 471 | // synthetic sections. For relocatable case we want to create one output | |
| 472 | // section per syntetic section so that they have a valid sh_entsize. | |
| 473 | if (Config->Relocatable && (IS->Flags & SHF_MERGE)) | |
| 474 | return createSection(IS, OutsecName); | |
| 475 | ||
| 476 | // The ELF spec just says | |
| 477 | // ---------------------------------------------------------------- | |
| 478 | // In the first phase, input sections that match in name, type and | |
| 479 | // attribute flags should be concatenated into single sections. | |
| 480 | // ---------------------------------------------------------------- | |
| 481 | // | |
| 482 | // However, it is clear that at least some flags have to be ignored for | |
| 483 | // section merging. At the very least SHF_GROUP and SHF_COMPRESSED have to be | |
| 484 | // ignored. We should not have two output .text sections just because one was | |
| 485 | // in a group and another was not for example. | |
| 486 | // | |
| 487 | // It also seems that that wording was a late addition and didn't get the | |
| 488 | // necessary scrutiny. | |
| 489 | // | |
| 490 | // Merging sections with different flags is expected by some users. One | |
| 491 | // reason is that if one file has | |
| 492 | // | |
| 493 | // int *const bar __attribute__((section(".foo"))) = (int *)0; | |
| 494 | // | |
| 495 | // gcc with -fPIC will produce a read only .foo section. But if another | |
| 496 | // file has | |
| 497 | // | |
| 498 | // int zed; | |
| 499 | // int *const bar __attribute__((section(".foo"))) = (int *)&zed; | |
| 500 | // | |
| 501 | // gcc with -fPIC will produce a read write section. | |
| 502 | // | |
| 503 | // Last but not least, when using linker script the merge rules are forced by | |
| 504 | // the script. Unfortunately, linker scripts are name based. This means that | |
| 505 | // expressions like *(.foo*) can refer to multiple input sections with | |
| 506 | // different flags. We cannot put them in different output sections or we | |
| 507 | // would produce wrong results for | |
| 508 | // | |
| 509 | // start = .; *(.foo.*) end = .; *(.bar) | |
| 510 | // | |
| 511 | // and a mapping of .foo1 and .bar1 to one section and .foo2 and .bar2 to | |
| 512 | // another. The problem is that there is no way to layout those output | |
| 513 | // sections such that the .foo sections are the only thing between the start | |
| 514 | // and end symbols. | |
| 515 | // | |
| 516 | // Given the above issues, we instead merge sections by name and error on | |
| 517 | // incompatible types and flags. | |
| 518 | OutputSection *&Sec = Map[OutsecName]; | |
| 519 | if (Sec) { | |
| 520 | Sec->addSection(cast<InputSection>(IS)); | |
| 521 | return nullptr; | |
| 491 | 522 | } |
| 492 | // SECTIONS commands run before other non SECTIONS commands | |
| 493 | Commands.insert(Commands.end(), Opt.Commands.begin(), Opt.Commands.end()); | |
| 494 | Opt.Commands = std::move(Commands); | |
| 523 | ||
| 524 | Sec = createSection(IS, OutsecName); | |
| 525 | return Sec; | |
| 495 | 526 | } |
| 496 | 527 | |
| 497 | 528 | // Add sections that didn't match any sections command. |
| 498 | void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) { | |
| 499 | unsigned NumCommands = Opt.Commands.size(); | |
| 529 | void LinkerScript::addOrphanSections() { | |
| 530 | unsigned End = SectionCommands.size(); | |
| 531 | StringMap<OutputSection *> Map; | |
| 532 | ||
| 533 | std::vector<OutputSection *> V; | |
| 500 | 534 | for (InputSectionBase *S : InputSections) { |
| 501 | 535 | if (!S->Live || S->Parent) |
| 502 | 536 | continue; |
| 503 | StringRef Name = getOutputSectionName(S->Name); | |
| 504 | auto End = Opt.Commands.begin() + NumCommands; | |
| 505 | auto I = std::find_if(Opt.Commands.begin(), End, [&](BaseCommand *Base) { | |
| 506 | if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) | |
| 507 | return Cmd->Name == Name; | |
| 508 | return false; | |
| 509 | }); | |
| 510 | OutputSectionCommand *Cmd; | |
| 511 | if (I == End) { | |
| 512 | Factory.addInputSec(S, Name); | |
| 513 | OutputSection *Sec = S->getOutputSection(); | |
| 514 | assert(Sec->SectionIndex == INT_MAX); | |
| 515 | OutputSectionCommand *&CmdRef = SecToCommand[Sec]; | |
| 516 | if (!CmdRef) { | |
| 517 | CmdRef = createOutputSectionCommand(Sec->Name, "<internal>"); | |
| 518 | CmdRef->Sec = Sec; | |
| 519 | Opt.Commands.push_back(CmdRef); | |
| 520 | } | |
| 521 | Cmd = CmdRef; | |
| 522 | } else { | |
| 523 | Cmd = cast<OutputSectionCommand>(*I); | |
| 524 | Factory.addInputSec(S, Name, Cmd->Sec); | |
| 525 | if (OutputSection *Sec = Cmd->Sec) { | |
| 526 | SecToCommand[Sec] = Cmd; | |
| 527 | unsigned Index = std::distance(Opt.Commands.begin(), I); | |
| 528 | assert(Sec->SectionIndex == INT_MAX || Sec->SectionIndex == Index); | |
| 529 | Sec->SectionIndex = Index; | |
| 530 | } | |
| 537 | ||
| 538 | StringRef Name = getOutputSectionName(S); | |
| 539 | ||
| 540 | if (Config->OrphanHandling == OrphanHandlingPolicy::Error) | |
| 541 | error(toString(S) + " is being placed in '" + Name + "'"); | |
| 542 | else if (Config->OrphanHandling == OrphanHandlingPolicy::Warn) | |
| 543 | warn(toString(S) + " is being placed in '" + Name + "'"); | |
| 544 | ||
| 545 | if (OutputSection *Sec = | |
| 546 | findByName(makeArrayRef(SectionCommands).slice(0, End), Name)) { | |
| 547 | Sec->addSection(cast<InputSection>(S)); | |
| 548 | continue; | |
| 531 | 549 | } |
| 532 | auto *ISD = make<InputSectionDescription>(""); | |
| 533 | ISD->Sections.push_back(cast<InputSection>(S)); | |
| 534 | Cmd->Commands.push_back(ISD); | |
| 550 | ||
| 551 | if (OutputSection *OS = addInputSec(Map, S, Name)) | |
| 552 | V.push_back(OS); | |
| 553 | assert(S->getOutputSection()->SectionIndex == INT_MAX); | |
| 535 | 554 | } |
| 555 | ||
| 556 | // If no SECTIONS command was given, we should insert sections commands | |
| 557 | // before others, so that we can handle scripts which refers them, | |
| 558 | // for example: "foo = ABSOLUTE(ADDR(.text)));". | |
| 559 | // When SECTIONS command is present we just add all orphans to the end. | |
| 560 | if (HasSectionsCommand) | |
| 561 | SectionCommands.insert(SectionCommands.end(), V.begin(), V.end()); | |
| 562 | else | |
| 563 | SectionCommands.insert(SectionCommands.begin(), V.begin(), V.end()); | |
| 536 | 564 | } |
| 537 | 565 | |
| 538 | uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) { | |
| 539 | bool IsTbss = (CurAddressState->OutSec->Flags & SHF_TLS) && | |
| 540 | CurAddressState->OutSec->Type == SHT_NOBITS; | |
| 541 | uint64_t Start = IsTbss ? Dot + CurAddressState->ThreadBssOffset : Dot; | |
| 542 | Start = alignTo(Start, Align); | |
| 566 | uint64_t LinkerScript::advance(uint64_t Size, unsigned Alignment) { | |
| 567 | bool IsTbss = | |
| 568 | (Ctx->OutSec->Flags & SHF_TLS) && Ctx->OutSec->Type == SHT_NOBITS; | |
| 569 | uint64_t Start = IsTbss ? Dot + Ctx->ThreadBssOffset : Dot; | |
| 570 | Start = alignTo(Start, Alignment); | |
| 543 | 571 | uint64_t End = Start + Size; |
| 544 | 572 | |
| 545 | 573 | if (IsTbss) |
| 546 | CurAddressState->ThreadBssOffset = End - Dot; | |
| 574 | Ctx->ThreadBssOffset = End - Dot; | |
| 547 | 575 | else |
| 548 | 576 | Dot = End; |
| 549 | 577 | return End; |
| 550 | 578 | } |
| 551 | 579 | |
| 552 | 580 | void LinkerScript::output(InputSection *S) { |
| 581 | uint64_t Before = advance(0, 1); | |
| 553 | 582 | uint64_t Pos = advance(S->getSize(), S->Alignment); |
| 554 | S->OutSecOff = Pos - S->getSize() - CurAddressState->OutSec->Addr; | |
| 583 | S->OutSecOff = Pos - S->getSize() - Ctx->OutSec->Addr; | |
| 555 | 584 | |
| 556 | 585 | // Update output section size after adding each section. This is so that |
| 557 | 586 | // SIZEOF works correctly in the case below: |
| 558 | 587 | // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } |
| 559 | CurAddressState->OutSec->Size = Pos - CurAddressState->OutSec->Addr; | |
| 588 | Ctx->OutSec->Size = Pos - Ctx->OutSec->Addr; | |
| 560 | 589 | |
| 561 | 590 | // If there is a memory region associated with this input section, then |
| 562 | 591 | // place the section in that region and update the region index. |
| 563 | if (CurAddressState->MemRegion) { | |
| 564 | uint64_t &CurOffset = | |
| 565 | CurAddressState->MemRegionOffset[CurAddressState->MemRegion]; | |
| 566 | CurOffset += CurAddressState->OutSec->Size; | |
| 567 | uint64_t CurSize = CurOffset - CurAddressState->MemRegion->Origin; | |
| 568 | if (CurSize > CurAddressState->MemRegion->Length) { | |
| 569 | uint64_t OverflowAmt = CurSize - CurAddressState->MemRegion->Length; | |
| 570 | error("section '" + CurAddressState->OutSec->Name + | |
| 571 | "' will not fit in region '" + CurAddressState->MemRegion->Name + | |
| 572 | "': overflowed by " + Twine(OverflowAmt) + " bytes"); | |
| 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"); | |
| 573 | 605 | } |
| 574 | 606 | } |
| 575 | 607 | } |
| 576 | 608 | |
| 577 | 609 | void LinkerScript::switchTo(OutputSection *Sec) { |
| 578 | if (CurAddressState->OutSec == Sec) | |
| 610 | if (Ctx->OutSec == Sec) | |
| 579 | 611 | return; |
| 580 | 612 | |
| 581 | CurAddressState->OutSec = Sec; | |
| 582 | CurAddressState->OutSec->Addr = | |
| 583 | advance(0, CurAddressState->OutSec->Alignment); | |
| 584 | ||
| 585 | // If neither AT nor AT> is specified for an allocatable section, the linker | |
| 586 | // will set the LMA such that the difference between VMA and LMA for the | |
| 587 | // section is the same as the preceding output section in the same region | |
| 588 | // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html | |
| 589 | if (CurAddressState->LMAOffset) | |
| 590 | CurAddressState->OutSec->LMAOffset = CurAddressState->LMAOffset(); | |
| 591 | } | |
| 592 | ||
| 593 | void LinkerScript::process(BaseCommand &Base) { | |
| 594 | // This handles the assignments to symbol or to the dot. | |
| 595 | if (auto *Cmd = dyn_cast<SymbolAssignment>(&Base)) { | |
| 596 | assignSymbol(Cmd, true); | |
| 597 | return; | |
| 598 | } | |
| 599 | ||
| 600 | // Handle BYTE(), SHORT(), LONG(), or QUAD(). | |
| 601 | if (auto *Cmd = dyn_cast<BytesDataCommand>(&Base)) { | |
| 602 | Cmd->Offset = Dot - CurAddressState->OutSec->Addr; | |
| 603 | Dot += Cmd->Size; | |
| 604 | CurAddressState->OutSec->Size = Dot - CurAddressState->OutSec->Addr; | |
| 605 | return; | |
| 606 | } | |
| 607 | ||
| 608 | // Handle ASSERT(). | |
| 609 | if (auto *Cmd = dyn_cast<AssertCommand>(&Base)) { | |
| 610 | Cmd->Expression(); | |
| 611 | return; | |
| 612 | } | |
| 613 | ||
| 614 | // Handle a single input section description command. | |
| 615 | // It calculates and assigns the offsets for each section and also | |
| 616 | // updates the output section size. | |
| 617 | auto &Cmd = cast<InputSectionDescription>(Base); | |
| 618 | for (InputSection *Sec : Cmd.Sections) { | |
| 619 | // We tentatively added all synthetic sections at the beginning and removed | |
| 620 | // empty ones afterwards (because there is no way to know whether they were | |
| 621 | // going be empty or not other than actually running linker scripts.) | |
| 622 | // We need to ignore remains of empty sections. | |
| 623 | if (auto *S = dyn_cast<SyntheticSection>(Sec)) | |
| 624 | if (S->empty()) | |
| 625 | continue; | |
| 626 | ||
| 627 | if (!Sec->Live) | |
| 628 | continue; | |
| 629 | assert(CurAddressState->OutSec == Sec->getParent()); | |
| 630 | output(Sec); | |
| 631 | } | |
| 613 | Ctx->OutSec = Sec; | |
| 614 | Ctx->OutSec->Addr = advance(0, Ctx->OutSec->Alignment); | |
| 632 | 615 | } |
| 633 | 616 | |
| 634 | 617 | // This function searches for a memory region to place the given output |
| 635 | 618 | // section in. If found, a pointer to the appropriate memory region is |
| 636 | 619 | // returned. Otherwise, a nullptr is returned. |
| 637 | MemoryRegion *LinkerScript::findMemoryRegion(OutputSectionCommand *Cmd) { | |
| 620 | MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *Sec) { | |
| 638 | 621 | // If a memory region name was specified in the output section command, |
| 639 | 622 | // then try to find that region first. |
| 640 | if (!Cmd->MemoryRegionName.empty()) { | |
| 641 | auto It = Opt.MemoryRegions.find(Cmd->MemoryRegionName); | |
| 642 | if (It != Opt.MemoryRegions.end()) | |
| 643 | return &It->second; | |
| 644 | error("memory region '" + Cmd->MemoryRegionName + "' not declared"); | |
| 623 | if (!Sec->MemoryRegionName.empty()) { | |
| 624 | if (MemoryRegion *M = MemoryRegions.lookup(Sec->MemoryRegionName)) | |
| 625 | return M; | |
| 626 | error("memory region '" + Sec->MemoryRegionName + "' not declared"); | |
| 645 | 627 | return nullptr; |
| 646 | 628 | } |
| 647 | 629 | |
| 648 | 630 | // If at least one memory region is defined, all sections must |
| 649 | 631 | // belong to some memory region. Otherwise, we don't need to do |
| 650 | 632 | // anything for memory regions. |
| 651 | if (Opt.MemoryRegions.empty()) | |
| 633 | if (MemoryRegions.empty()) | |
| 652 | 634 | return nullptr; |
| 653 | 635 | |
| 654 | OutputSection *Sec = Cmd->Sec; | |
| 655 | 636 | // See if a region can be found by matching section flags. |
| 656 | for (auto &Pair : Opt.MemoryRegions) { | |
| 657 | MemoryRegion &M = Pair.second; | |
| 658 | if ((M.Flags & Sec->Flags) && (M.NegFlags & Sec->Flags) == 0) | |
| 659 | return &M; | |
| 637 | for (auto &Pair : MemoryRegions) { | |
| 638 | MemoryRegion *M = Pair.second; | |
| 639 | if ((M->Flags & Sec->Flags) && (M->NegFlags & Sec->Flags) == 0) | |
| 640 | return M; | |
| 660 | 641 | } |
| 661 | 642 | |
| 662 | 643 | // Otherwise, no suitable region was found. |
| ... | ... | @@ -667,33 +648,84 @@ MemoryRegion *LinkerScript::findMemoryRegion(OutputSectionCommand *Cmd) { |
| 667 | 648 | |
| 668 | 649 | // This function assigns offsets to input sections and an output section |
| 669 | 650 | // for a single sections command (e.g. ".text { *(.text); }"). |
| 670 | void LinkerScript::assignOffsets(OutputSectionCommand *Cmd) { | |
| 671 | OutputSection *Sec = Cmd->Sec; | |
| 672 | if (!Sec) | |
| 673 | return; | |
| 674 | ||
| 651 | void LinkerScript::assignOffsets(OutputSection *Sec) { | |
| 675 | 652 | if (!(Sec->Flags & SHF_ALLOC)) |
| 676 | 653 | Dot = 0; |
| 677 | else if (Cmd->AddrExpr) | |
| 678 | setDot(Cmd->AddrExpr, Cmd->Location, false); | |
| 654 | else if (Sec->AddrExpr) | |
| 655 | setDot(Sec->AddrExpr, Sec->Location, false); | |
| 679 | 656 | |
| 680 | if (Cmd->LMAExpr) { | |
| 681 | uint64_t D = Dot; | |
| 682 | CurAddressState->LMAOffset = [=] { return Cmd->LMAExpr().getValue() - D; }; | |
| 683 | } | |
| 657 | Ctx->MemRegion = Sec->MemRegion; | |
| 658 | Ctx->LMARegion = Sec->LMARegion; | |
| 659 | if (Ctx->MemRegion) | |
| 660 | Dot = Ctx->MemRegion->CurPos; | |
| 684 | 661 | |
| 685 | CurAddressState->MemRegion = Cmd->MemRegion; | |
| 686 | if (CurAddressState->MemRegion) | |
| 687 | Dot = CurAddressState->MemRegionOffset[CurAddressState->MemRegion]; | |
| 688 | 662 | switchTo(Sec); |
| 689 | 663 | |
| 690 | // We do not support custom layout for compressed debug sectons. | |
| 691 | // At this point we already know their size and have compressed content. | |
| 692 | if (CurAddressState->OutSec->Flags & SHF_COMPRESSED) | |
| 693 | return; | |
| 664 | if (Sec->LMAExpr) | |
| 665 | Ctx->LMAOffset = Sec->LMAExpr().getValue() - Dot; | |
| 666 | ||
| 667 | if (MemoryRegion *MR = Sec->LMARegion) | |
| 668 | Ctx->LMAOffset = MR->CurPos - Dot; | |
| 669 | ||
| 670 | // If neither AT nor AT> is specified for an allocatable section, the linker | |
| 671 | // will set the LMA such that the difference between VMA and LMA for the | |
| 672 | // section is the same as the preceding output section in the same region | |
| 673 | // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html | |
| 674 | if (PhdrEntry *L = Ctx->OutSec->PtLoad) | |
| 675 | L->LMAOffset = Ctx->LMAOffset; | |
| 676 | ||
| 677 | // The Size previously denoted how many InputSections had been added to this | |
| 678 | // section, and was used for sorting SHF_LINK_ORDER sections. Reset it to | |
| 679 | // compute the actual size value. | |
| 680 | Sec->Size = 0; | |
| 681 | ||
| 682 | // We visited SectionsCommands from processSectionCommands to | |
| 683 | // layout sections. Now, we visit SectionsCommands again to fix | |
| 684 | // section offsets. | |
| 685 | for (BaseCommand *Base : Sec->SectionCommands) { | |
| 686 | // This handles the assignments to symbol or to the dot. | |
| 687 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) { | |
| 688 | assignSymbol(Cmd, true); | |
| 689 | continue; | |
| 690 | } | |
| 691 | ||
| 692 | // Handle BYTE(), SHORT(), LONG(), or QUAD(). | |
| 693 | if (auto *Cmd = dyn_cast<ByteCommand>(Base)) { | |
| 694 | Cmd->Offset = Dot - Ctx->OutSec->Addr; | |
| 695 | Dot += Cmd->Size; | |
| 696 | if (Ctx->MemRegion) | |
| 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 | } | |
| 694 | 703 | |
| 695 | for (BaseCommand *C : Cmd->Commands) | |
| 696 | process(*C); | |
| 704 | // Handle ASSERT(). | |
| 705 | if (auto *Cmd = dyn_cast<AssertCommand>(Base)) { | |
| 706 | Cmd->Expression(); | |
| 707 | continue; | |
| 708 | } | |
| 709 | ||
| 710 | // Handle a single input section description command. | |
| 711 | // It calculates and assigns the offsets for each section and also | |
| 712 | // updates the output section size. | |
| 713 | auto *Cmd = cast<InputSectionDescription>(Base); | |
| 714 | for (InputSection *Sec : Cmd->Sections) { | |
| 715 | // We tentatively added all synthetic sections at the beginning and | |
| 716 | // removed empty ones afterwards (because there is no way to know | |
| 717 | // whether they were going be empty or not other than actually running | |
| 718 | // linker scripts.) We need to ignore remains of empty sections. | |
| 719 | if (auto *S = dyn_cast<SyntheticSection>(Sec)) | |
| 720 | if (S->empty()) | |
| 721 | continue; | |
| 722 | ||
| 723 | if (!Sec->Live) | |
| 724 | continue; | |
| 725 | assert(Ctx->OutSec == Sec->getParent()); | |
| 726 | output(Sec); | |
| 727 | } | |
| 728 | } | |
| 697 | 729 | } |
| 698 | 730 | |
| 699 | 731 | void LinkerScript::removeEmptyCommands() { |
| ... | ... | @@ -703,17 +735,15 @@ void LinkerScript::removeEmptyCommands() { |
| 703 | 735 | // clutter the output. |
| 704 | 736 | // We instead remove trivially empty sections. The bfd linker seems even |
| 705 | 737 | // more aggressive at removing them. |
| 706 | auto Pos = std::remove_if( | |
| 707 | Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) { | |
| 708 | if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) | |
| 709 | return Cmd->Sec == nullptr; | |
| 710 | return false; | |
| 711 | }); | |
| 712 | Opt.Commands.erase(Pos, Opt.Commands.end()); | |
| 738 | llvm::erase_if(SectionCommands, [&](BaseCommand *Base) { | |
| 739 | if (auto *Sec = dyn_cast<OutputSection>(Base)) | |
| 740 | return !Sec->Live; | |
| 741 | return false; | |
| 742 | }); | |
| 713 | 743 | } |
| 714 | 744 | |
| 715 | static bool isAllSectionDescription(const OutputSectionCommand &Cmd) { | |
| 716 | for (BaseCommand *Base : Cmd.Commands) | |
| 745 | static bool isAllSectionDescription(const OutputSection &Cmd) { | |
| 746 | for (BaseCommand *Base : Cmd.SectionCommands) | |
| 717 | 747 | if (!isa<InputSectionDescription>(*Base)) |
| 718 | 748 | return false; |
| 719 | 749 | return true; |
| ... | ... | @@ -721,38 +751,61 @@ static bool isAllSectionDescription(const OutputSectionCommand &Cmd) { |
| 721 | 751 | |
| 722 | 752 | void LinkerScript::adjustSectionsBeforeSorting() { |
| 723 | 753 | // If the output section contains only symbol assignments, create a |
| 724 | // corresponding output section. The bfd linker seems to only create them if | |
| 725 | // '.' is assigned to, but creating these section should not have any bad | |
| 726 | // consequeces and gives us a section to put the symbol in. | |
| 754 | // corresponding output section. The issue is what to do with linker script | |
| 755 | // like ".foo : { symbol = 42; }". One option would be to convert it to | |
| 756 | // "symbol = 42;". That is, move the symbol out of the empty section | |
| 757 | // description. That seems to be what bfd does for this simple case. The | |
| 758 | // problem is that this is not completely general. bfd will give up and | |
| 759 | // create a dummy section too if there is a ". = . + 1" inside the section | |
| 760 | // for example. | |
| 761 | // 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 | |
| 763 | // 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 | |
| 765 | // other parts of the linker, but unfortunately there are quite a few places | |
| 766 | // that would need to change: | |
| 767 | // * The program header creation. | |
| 768 | // * The orphan section placement. | |
| 769 | // * The address assignment. | |
| 770 | // The other option is to pick flags that minimize the impact the section | |
| 771 | // will have on the rest of the linker. That is why we copy the flags from | |
| 772 | // the previous sections. Only a few flags are needed to keep the impact low. | |
| 727 | 773 | uint64_t Flags = SHF_ALLOC; |
| 728 | 774 | |
| 729 | for (int I = 0, E = Opt.Commands.size(); I != E; ++I) { | |
| 730 | auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I]); | |
| 731 | if (!Cmd) | |
| 775 | for (BaseCommand *Cmd : SectionCommands) { | |
| 776 | auto *Sec = dyn_cast<OutputSection>(Cmd); | |
| 777 | if (!Sec) | |
| 732 | 778 | continue; |
| 733 | if (OutputSection *Sec = Cmd->Sec) { | |
| 734 | Flags = Sec->Flags; | |
| 779 | if (Sec->Live) { | |
| 780 | Flags = Sec->Flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR); | |
| 735 | 781 | continue; |
| 736 | 782 | } |
| 737 | 783 | |
| 738 | if (isAllSectionDescription(*Cmd)) | |
| 784 | if (isAllSectionDescription(*Sec)) | |
| 739 | 785 | continue; |
| 740 | 786 | |
| 741 | auto *OutSec = make<OutputSection>(Cmd->Name, SHT_PROGBITS, Flags); | |
| 742 | OutSec->SectionIndex = I; | |
| 743 | Cmd->Sec = OutSec; | |
| 744 | SecToCommand[OutSec] = Cmd; | |
| 787 | Sec->Live = true; | |
| 788 | Sec->Flags = Flags; | |
| 745 | 789 | } |
| 746 | 790 | } |
| 747 | 791 | |
| 748 | 792 | void LinkerScript::adjustSectionsAfterSorting() { |
| 749 | 793 | // Try and find an appropriate memory region to assign offsets in. |
| 750 | for (BaseCommand *Base : Opt.Commands) { | |
| 751 | if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) { | |
| 752 | Cmd->MemRegion = findMemoryRegion(Cmd); | |
| 794 | for (BaseCommand *Base : SectionCommands) { | |
| 795 | if (auto *Sec = dyn_cast<OutputSection>(Base)) { | |
| 796 | if (!Sec->Live) | |
| 797 | continue; | |
| 798 | if (!Sec->LMARegionName.empty()) { | |
| 799 | if (MemoryRegion *M = MemoryRegions.lookup(Sec->LMARegionName)) | |
| 800 | Sec->LMARegion = M; | |
| 801 | else | |
| 802 | error("memory region '" + Sec->LMARegionName + "' not declared"); | |
| 803 | } | |
| 804 | Sec->MemRegion = findMemoryRegion(Sec); | |
| 753 | 805 | // Handle align (e.g. ".foo : ALIGN(16) { ... }"). |
| 754 | if (Cmd->AlignExpr && Cmd->Sec) | |
| 755 | Cmd->Sec->updateAlignment(Cmd->AlignExpr().getValue()); | |
| 806 | if (Sec->AlignExpr) | |
| 807 | Sec->Alignment = | |
| 808 | std::max<uint32_t>(Sec->Alignment, Sec->AlignExpr().getValue()); | |
| 756 | 809 | } |
| 757 | 810 | } |
| 758 | 811 | |
| ... | ... | @@ -764,108 +817,112 @@ void LinkerScript::adjustSectionsAfterSorting() { |
| 764 | 817 | // SECTIONS { .aaa : { *(.aaa) } } |
| 765 | 818 | std::vector<StringRef> DefPhdrs; |
| 766 | 819 | auto FirstPtLoad = |
| 767 | std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(), | |
| 820 | std::find_if(PhdrsCommands.begin(), PhdrsCommands.end(), | |
| 768 | 821 | [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; }); |
| 769 | if (FirstPtLoad != Opt.PhdrsCommands.end()) | |
| 822 | if (FirstPtLoad != PhdrsCommands.end()) | |
| 770 | 823 | DefPhdrs.push_back(FirstPtLoad->Name); |
| 771 | 824 | |
| 772 | 825 | // Walk the commands and propagate the program headers to commands that don't |
| 773 | 826 | // explicitly specify them. |
| 774 | for (BaseCommand *Base : Opt.Commands) { | |
| 775 | auto *Cmd = dyn_cast<OutputSectionCommand>(Base); | |
| 776 | if (!Cmd) | |
| 827 | for (BaseCommand *Base : SectionCommands) { | |
| 828 | auto *Sec = dyn_cast<OutputSection>(Base); | |
| 829 | if (!Sec) | |
| 777 | 830 | continue; |
| 778 | 831 | |
| 779 | if (Cmd->Phdrs.empty()) { | |
| 780 | OutputSection *Sec = Cmd->Sec; | |
| 832 | if (Sec->Phdrs.empty()) { | |
| 781 | 833 | // To match the bfd linker script behaviour, only propagate program |
| 782 | 834 | // headers to sections that are allocated. |
| 783 | if (Sec && (Sec->Flags & SHF_ALLOC)) | |
| 784 | Cmd->Phdrs = DefPhdrs; | |
| 835 | if (Sec->Flags & SHF_ALLOC) | |
| 836 | Sec->Phdrs = DefPhdrs; | |
| 785 | 837 | } else { |
| 786 | DefPhdrs = Cmd->Phdrs; | |
| 838 | DefPhdrs = Sec->Phdrs; | |
| 787 | 839 | } |
| 788 | 840 | } |
| 789 | ||
| 790 | removeEmptyCommands(); | |
| 791 | 841 | } |
| 792 | 842 | |
| 793 | void LinkerScript::processNonSectionCommands() { | |
| 794 | for (BaseCommand *Base : Opt.Commands) { | |
| 795 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) | |
| 796 | assignSymbol(Cmd, false); | |
| 797 | else if (auto *Cmd = dyn_cast<AssertCommand>(Base)) | |
| 798 | Cmd->Expression(); | |
| 799 | } | |
| 843 | static OutputSection *findFirstSection(PhdrEntry *Load) { | |
| 844 | for (OutputSection *Sec : OutputSections) | |
| 845 | if (Sec->PtLoad == Load) | |
| 846 | return Sec; | |
| 847 | return nullptr; | |
| 800 | 848 | } |
| 801 | 849 | |
| 802 | void LinkerScript::allocateHeaders(std::vector<PhdrEntry> &Phdrs) { | |
| 850 | // 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. | |
| 852 | // | |
| 853 | // When using the default layout, we check if the headers fit below the first | |
| 854 | // allocated section. When using a linker script, we also check if the headers | |
| 855 | // are covered by the output section. This allows omitting the headers by not | |
| 856 | // leaving enough space for them in the linker script; this pattern is common | |
| 857 | // in embedded systems. | |
| 858 | // | |
| 859 | // If there isn't enough space for these sections, we'll remove them from the | |
| 860 | // PT_LOAD segment, and we'll also remove the PT_PHDR segment. | |
| 861 | void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &Phdrs) { | |
| 803 | 862 | uint64_t Min = std::numeric_limits<uint64_t>::max(); |
| 804 | for (OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 805 | OutputSection *Sec = Cmd->Sec; | |
| 863 | for (OutputSection *Sec : OutputSections) | |
| 806 | 864 | if (Sec->Flags & SHF_ALLOC) |
| 807 | 865 | Min = std::min<uint64_t>(Min, Sec->Addr); |
| 808 | } | |
| 809 | 866 | |
| 810 | auto FirstPTLoad = llvm::find_if( | |
| 811 | Phdrs, [](const PhdrEntry &E) { return E.p_type == PT_LOAD; }); | |
| 812 | if (FirstPTLoad == Phdrs.end()) | |
| 867 | auto It = llvm::find_if( | |
| 868 | Phdrs, [](const PhdrEntry *E) { return E->p_type == PT_LOAD; }); | |
| 869 | if (It == Phdrs.end()) | |
| 813 | 870 | return; |
| 871 | PhdrEntry *FirstPTLoad = *It; | |
| 814 | 872 | |
| 815 | 873 | uint64_t HeaderSize = getHeaderSize(); |
| 816 | if (HeaderSize <= Min || Script->hasPhdrsCommands()) { | |
| 874 | // When linker script with SECTIONS is being used, don't output headers | |
| 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()) { | |
| 817 | 878 | Min = alignDown(Min - HeaderSize, Config->MaxPageSize); |
| 818 | 879 | Out::ElfHeader->Addr = Min; |
| 819 | 880 | Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size; |
| 820 | 881 | return; |
| 821 | 882 | } |
| 822 | 883 | |
| 823 | assert(FirstPTLoad->First == Out::ElfHeader); | |
| 824 | OutputSection *ActualFirst = nullptr; | |
| 825 | for (OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 826 | OutputSection *Sec = Cmd->Sec; | |
| 827 | if (Sec->FirstInPtLoad == Out::ElfHeader) { | |
| 828 | ActualFirst = Sec; | |
| 829 | break; | |
| 830 | } | |
| 831 | } | |
| 832 | if (ActualFirst) { | |
| 833 | for (OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 834 | OutputSection *Sec = Cmd->Sec; | |
| 835 | if (Sec->FirstInPtLoad == Out::ElfHeader) | |
| 836 | Sec->FirstInPtLoad = ActualFirst; | |
| 837 | } | |
| 838 | FirstPTLoad->First = ActualFirst; | |
| 839 | } else { | |
| 840 | Phdrs.erase(FirstPTLoad); | |
| 841 | } | |
| 884 | Out::ElfHeader->PtLoad = nullptr; | |
| 885 | Out::ProgramHeaders->PtLoad = nullptr; | |
| 886 | FirstPTLoad->FirstSec = findFirstSection(FirstPTLoad); | |
| 842 | 887 | |
| 843 | auto PhdrI = llvm::find_if( | |
| 844 | Phdrs, [](const PhdrEntry &E) { return E.p_type == PT_PHDR; }); | |
| 845 | if (PhdrI != Phdrs.end()) | |
| 846 | Phdrs.erase(PhdrI); | |
| 888 | llvm::erase_if(Phdrs, | |
| 889 | [](const PhdrEntry *E) { return E->p_type == PT_PHDR; }); | |
| 847 | 890 | } |
| 848 | 891 | |
| 849 | LinkerScript::AddressState::AddressState(const ScriptConfiguration &Opt) { | |
| 850 | for (auto &MRI : Opt.MemoryRegions) { | |
| 851 | const MemoryRegion *MR = &MRI.second; | |
| 852 | MemRegionOffset[MR] = MR->Origin; | |
| 892 | LinkerScript::AddressState::AddressState() { | |
| 893 | for (auto &MRI : Script->MemoryRegions) { | |
| 894 | MemoryRegion *MR = MRI.second; | |
| 895 | MR->CurPos = MR->Origin; | |
| 853 | 896 | } |
| 854 | 897 | } |
| 855 | 898 | |
| 899 | static uint64_t getInitialDot() { | |
| 900 | // By default linker scripts use an initial value of 0 for '.', | |
| 901 | // but prefer -image-base if set. | |
| 902 | if (Script->HasSectionsCommand) | |
| 903 | return Config->ImageBase ? *Config->ImageBase : 0; | |
| 904 | ||
| 905 | uint64_t StartAddr = UINT64_MAX; | |
| 906 | // The Sections with -T<section> have been sorted in order of ascending | |
| 907 | // address. We must lower StartAddr if the lowest -T<section address> as | |
| 908 | // calls to setDot() must be monotonically increasing. | |
| 909 | for (auto &KV : Config->SectionStartMap) | |
| 910 | StartAddr = std::min(StartAddr, KV.second); | |
| 911 | return std::min(StartAddr, Target->getImageBase() + elf::getHeaderSize()); | |
| 912 | } | |
| 913 | ||
| 914 | // Here we assign addresses as instructed by linker script SECTIONS | |
| 915 | // sub-commands. Doing that allows us to use final VA values, so here | |
| 916 | // we also handle rest commands like symbol assignments and ASSERTs. | |
| 856 | 917 | void LinkerScript::assignAddresses() { |
| 857 | // Assign addresses as instructed by linker script SECTIONS sub-commands. | |
| 858 | Dot = 0; | |
| 859 | auto State = make_unique<AddressState>(Opt); | |
| 860 | // CurAddressState captures the local AddressState and makes it accessible | |
| 861 | // deliberately. This is needed as there are some cases where we cannot just | |
| 862 | // thread the current state through to a lambda function created by the | |
| 863 | // script parser. | |
| 864 | CurAddressState = State.get(); | |
| 918 | Dot = getInitialDot(); | |
| 919 | ||
| 920 | auto Deleter = make_unique<AddressState>(); | |
| 921 | Ctx = Deleter.get(); | |
| 865 | 922 | ErrorOnMissingSection = true; |
| 866 | 923 | switchTo(Aether); |
| 867 | 924 | |
| 868 | for (BaseCommand *Base : Opt.Commands) { | |
| 925 | for (BaseCommand *Base : SectionCommands) { | |
| 869 | 926 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) { |
| 870 | 927 | assignSymbol(Cmd, false); |
| 871 | 928 | continue; |
| ... | ... | @@ -876,380 +933,98 @@ void LinkerScript::assignAddresses() { |
| 876 | 933 | continue; |
| 877 | 934 | } |
| 878 | 935 | |
| 879 | auto *Cmd = cast<OutputSectionCommand>(Base); | |
| 880 | assignOffsets(Cmd); | |
| 936 | assignOffsets(cast<OutputSection>(Base)); | |
| 881 | 937 | } |
| 882 | CurAddressState = nullptr; | |
| 938 | Ctx = nullptr; | |
| 883 | 939 | } |
| 884 | 940 | |
| 885 | 941 | // Creates program headers as instructed by PHDRS linker script command. |
| 886 | std::vector<PhdrEntry> LinkerScript::createPhdrs() { | |
| 887 | std::vector<PhdrEntry> Ret; | |
| 942 | std::vector<PhdrEntry *> LinkerScript::createPhdrs() { | |
| 943 | std::vector<PhdrEntry *> Ret; | |
| 888 | 944 | |
| 889 | 945 | // Process PHDRS and FILEHDR keywords because they are not |
| 890 | 946 | // real output sections and cannot be added in the following loop. |
| 891 | for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { | |
| 892 | Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); | |
| 893 | PhdrEntry &Phdr = Ret.back(); | |
| 947 | for (const PhdrsCommand &Cmd : PhdrsCommands) { | |
| 948 | PhdrEntry *Phdr = make<PhdrEntry>(Cmd.Type, Cmd.Flags ? *Cmd.Flags : PF_R); | |
| 894 | 949 | |
| 895 | 950 | if (Cmd.HasFilehdr) |
| 896 | Phdr.add(Out::ElfHeader); | |
| 951 | Phdr->add(Out::ElfHeader); | |
| 897 | 952 | if (Cmd.HasPhdrs) |
| 898 | Phdr.add(Out::ProgramHeaders); | |
| 953 | Phdr->add(Out::ProgramHeaders); | |
| 899 | 954 | |
| 900 | 955 | if (Cmd.LMAExpr) { |
| 901 | Phdr.p_paddr = Cmd.LMAExpr().getValue(); | |
| 902 | Phdr.HasLMA = true; | |
| 956 | Phdr->p_paddr = Cmd.LMAExpr().getValue(); | |
| 957 | Phdr->HasLMA = true; | |
| 903 | 958 | } |
| 959 | Ret.push_back(Phdr); | |
| 904 | 960 | } |
| 905 | 961 | |
| 906 | 962 | // Add output sections to program headers. |
| 907 | for (OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 963 | for (OutputSection *Sec : OutputSections) { | |
| 908 | 964 | // Assign headers specified by linker script |
| 909 | for (size_t Id : getPhdrIndices(Cmd)) { | |
| 910 | OutputSection *Sec = Cmd->Sec; | |
| 911 | Ret[Id].add(Sec); | |
| 912 | if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) | |
| 913 | Ret[Id].p_flags |= Sec->getPhdrFlags(); | |
| 965 | for (size_t Id : getPhdrIndices(Sec)) { | |
| 966 | Ret[Id]->add(Sec); | |
| 967 | if (!PhdrsCommands[Id].Flags.hasValue()) | |
| 968 | Ret[Id]->p_flags |= Sec->getPhdrFlags(); | |
| 914 | 969 | } |
| 915 | 970 | } |
| 916 | 971 | return Ret; |
| 917 | 972 | } |
| 918 | 973 | |
| 919 | bool LinkerScript::ignoreInterpSection() { | |
| 920 | // Ignore .interp section in case we have PHDRS specification | |
| 921 | // and PT_INTERP isn't listed. | |
| 922 | if (Opt.PhdrsCommands.empty()) | |
| 923 | return false; | |
| 924 | for (PhdrsCommand &Cmd : Opt.PhdrsCommands) | |
| 925 | if (Cmd.Type == PT_INTERP) | |
| 926 | return false; | |
| 927 | return true; | |
| 928 | } | |
| 929 | ||
| 930 | OutputSectionCommand *LinkerScript::getCmd(OutputSection *Sec) const { | |
| 931 | auto I = SecToCommand.find(Sec); | |
| 932 | if (I == SecToCommand.end()) | |
| 933 | return nullptr; | |
| 934 | return I->second; | |
| 935 | } | |
| 936 | ||
| 937 | void OutputSectionCommand::sort(std::function<int(InputSectionBase *S)> Order) { | |
| 938 | typedef std::pair<unsigned, InputSection *> Pair; | |
| 939 | auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; }; | |
| 940 | ||
| 941 | std::vector<Pair> V; | |
| 942 | assert(Commands.size() == 1); | |
| 943 | auto *ISD = cast<InputSectionDescription>(Commands[0]); | |
| 944 | for (InputSection *S : ISD->Sections) | |
| 945 | V.push_back({Order(S), S}); | |
| 946 | std::stable_sort(V.begin(), V.end(), Comp); | |
| 947 | ISD->Sections.clear(); | |
| 948 | for (Pair &P : V) | |
| 949 | ISD->Sections.push_back(P.second); | |
| 950 | } | |
| 951 | ||
| 952 | // Returns true if S matches /Filename.?\.o$/. | |
| 953 | static bool isCrtBeginEnd(StringRef S, StringRef Filename) { | |
| 954 | if (!S.endswith(".o")) | |
| 955 | return false; | |
| 956 | S = S.drop_back(2); | |
| 957 | if (S.endswith(Filename)) | |
| 958 | return true; | |
| 959 | return !S.empty() && S.drop_back().endswith(Filename); | |
| 960 | } | |
| 961 | ||
| 962 | static bool isCrtbegin(StringRef S) { return isCrtBeginEnd(S, "crtbegin"); } | |
| 963 | static bool isCrtend(StringRef S) { return isCrtBeginEnd(S, "crtend"); } | |
| 964 | ||
| 965 | // .ctors and .dtors are sorted by this priority from highest to lowest. | |
| 966 | // | |
| 967 | // 1. The section was contained in crtbegin (crtbegin contains | |
| 968 | // some sentinel value in its .ctors and .dtors so that the runtime | |
| 969 | // can find the beginning of the sections.) | |
| 974 | // Returns true if we should emit an .interp section. | |
| 970 | 975 | // |
| 971 | // 2. The section has an optional priority value in the form of ".ctors.N" | |
| 972 | // or ".dtors.N" where N is a number. Unlike .{init,fini}_array, | |
| 973 | // they are compared as string rather than number. | |
| 974 | // | |
| 975 | // 3. The section is just ".ctors" or ".dtors". | |
| 976 | // | |
| 977 | // 4. The section was contained in crtend, which contains an end marker. | |
| 978 | // | |
| 979 | // In an ideal world, we don't need this function because .init_array and | |
| 980 | // .ctors are duplicate features (and .init_array is newer.) However, there | |
| 981 | // are too many real-world use cases of .ctors, so we had no choice to | |
| 982 | // support that with this rather ad-hoc semantics. | |
| 983 | static bool compCtors(const InputSection *A, const InputSection *B) { | |
| 984 | bool BeginA = isCrtbegin(A->File->getName()); | |
| 985 | bool BeginB = isCrtbegin(B->File->getName()); | |
| 986 | if (BeginA != BeginB) | |
| 987 | return BeginA; | |
| 988 | bool EndA = isCrtend(A->File->getName()); | |
| 989 | bool EndB = isCrtend(B->File->getName()); | |
| 990 | if (EndA != EndB) | |
| 991 | return EndB; | |
| 992 | StringRef X = A->Name; | |
| 993 | StringRef Y = B->Name; | |
| 994 | assert(X.startswith(".ctors") || X.startswith(".dtors")); | |
| 995 | assert(Y.startswith(".ctors") || Y.startswith(".dtors")); | |
| 996 | X = X.substr(6); | |
| 997 | Y = Y.substr(6); | |
| 998 | if (X.empty() && Y.empty()) | |
| 999 | return false; | |
| 1000 | return X < Y; | |
| 1001 | } | |
| 1002 | ||
| 1003 | // Sorts input sections by the special rules for .ctors and .dtors. | |
| 1004 | // Unfortunately, the rules are different from the one for .{init,fini}_array. | |
| 1005 | // Read the comment above. | |
| 1006 | void OutputSectionCommand::sortCtorsDtors() { | |
| 1007 | assert(Commands.size() == 1); | |
| 1008 | auto *ISD = cast<InputSectionDescription>(Commands[0]); | |
| 1009 | std::stable_sort(ISD->Sections.begin(), ISD->Sections.end(), compCtors); | |
| 1010 | } | |
| 1011 | ||
| 1012 | // Sorts input sections by section name suffixes, so that .foo.N comes | |
| 1013 | // before .foo.M if N < M. Used to sort .{init,fini}_array.N sections. | |
| 1014 | // We want to keep the original order if the priorities are the same | |
| 1015 | // because the compiler keeps the original initialization order in a | |
| 1016 | // translation unit and we need to respect that. | |
| 1017 | // For more detail, read the section of the GCC's manual about init_priority. | |
| 1018 | void OutputSectionCommand::sortInitFini() { | |
| 1019 | // Sort sections by priority. | |
| 1020 | sort([](InputSectionBase *S) { return getPriority(S->Name); }); | |
| 1021 | } | |
| 1022 | ||
| 1023 | uint32_t OutputSectionCommand::getFiller() { | |
| 1024 | if (Filler) | |
| 1025 | return *Filler; | |
| 1026 | if (Sec->Flags & SHF_EXECINSTR) | |
| 1027 | return Target->TrapInstr; | |
| 1028 | return 0; | |
| 1029 | } | |
| 1030 | ||
| 1031 | static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) { | |
| 1032 | if (Size == 1) | |
| 1033 | *Buf = Data; | |
| 1034 | else if (Size == 2) | |
| 1035 | write16(Buf, Data, Config->Endianness); | |
| 1036 | else if (Size == 4) | |
| 1037 | write32(Buf, Data, Config->Endianness); | |
| 1038 | else if (Size == 8) | |
| 1039 | write64(Buf, Data, Config->Endianness); | |
| 1040 | else | |
| 1041 | llvm_unreachable("unsupported Size argument"); | |
| 1042 | } | |
| 1043 | ||
| 1044 | static bool compareByFilePosition(InputSection *A, InputSection *B) { | |
| 1045 | // Synthetic doesn't have link order dependecy, stable_sort will keep it last | |
| 1046 | if (A->kind() == InputSectionBase::Synthetic || | |
| 1047 | B->kind() == InputSectionBase::Synthetic) | |
| 1048 | return false; | |
| 1049 | InputSection *LA = A->getLinkOrderDep(); | |
| 1050 | InputSection *LB = B->getLinkOrderDep(); | |
| 1051 | OutputSection *AOut = LA->getParent(); | |
| 1052 | OutputSection *BOut = LB->getParent(); | |
| 1053 | if (AOut != BOut) | |
| 1054 | return AOut->SectionIndex < BOut->SectionIndex; | |
| 1055 | return LA->OutSecOff < LB->OutSecOff; | |
| 1056 | } | |
| 1057 | ||
| 1058 | template <class ELFT> | |
| 1059 | static void finalizeShtGroup(OutputSection *OS, | |
| 1060 | ArrayRef<InputSection *> Sections) { | |
| 1061 | assert(Config->Relocatable && Sections.size() == 1); | |
| 1062 | ||
| 1063 | // sh_link field for SHT_GROUP sections should contain the section index of | |
| 1064 | // the symbol table. | |
| 1065 | OS->Link = InX::SymTab->getParent()->SectionIndex; | |
| 1066 | ||
| 1067 | // sh_info then contain index of an entry in symbol table section which | |
| 1068 | // provides signature of the section group. | |
| 1069 | elf::ObjectFile<ELFT> *Obj = Sections[0]->getFile<ELFT>(); | |
| 1070 | ArrayRef<SymbolBody *> Symbols = Obj->getSymbols(); | |
| 1071 | OS->Info = InX::SymTab->getSymbolIndex(Symbols[Sections[0]->Info - 1]); | |
| 976 | // We usually do. But if PHDRS commands are given, and | |
| 977 | // no PT_INTERP is there, there's no place to emit an | |
| 978 | // .interp, so we don't do that in that case. | |
| 979 | bool LinkerScript::needsInterpSection() { | |
| 980 | if (PhdrsCommands.empty()) | |
| 981 | return true; | |
| 982 | for (PhdrsCommand &Cmd : PhdrsCommands) | |
| 983 | if (Cmd.Type == PT_INTERP) | |
| 984 | return true; | |
| 985 | return false; | |
| 1072 | 986 | } |
| 1073 | 987 | |
| 1074 | template <class ELFT> void OutputSectionCommand::finalize() { | |
| 1075 | // Link order may be distributed across several InputSectionDescriptions | |
| 1076 | // but sort must consider them all at once. | |
| 1077 | std::vector<InputSection **> ScriptSections; | |
| 1078 | std::vector<InputSection *> Sections; | |
| 1079 | for (BaseCommand *Base : Commands) | |
| 1080 | if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) | |
| 1081 | for (InputSection *&IS : ISD->Sections) { | |
| 1082 | ScriptSections.push_back(&IS); | |
| 1083 | Sections.push_back(IS); | |
| 1084 | } | |
| 1085 | ||
| 1086 | if ((Sec->Flags & SHF_LINK_ORDER)) { | |
| 1087 | std::stable_sort(Sections.begin(), Sections.end(), compareByFilePosition); | |
| 1088 | for (int I = 0, N = Sections.size(); I < N; ++I) | |
| 1089 | *ScriptSections[I] = Sections[I]; | |
| 1090 | ||
| 1091 | // We must preserve the link order dependency of sections with the | |
| 1092 | // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We | |
| 1093 | // need to translate the InputSection sh_link to the OutputSection sh_link, | |
| 1094 | // all InputSections in the OutputSection have the same dependency. | |
| 1095 | if (auto *D = Sections.front()->getLinkOrderDep()) | |
| 1096 | Sec->Link = D->getParent()->SectionIndex; | |
| 988 | ExprValue LinkerScript::getSymbolValue(StringRef Name, const Twine &Loc) { | |
| 989 | if (Name == ".") { | |
| 990 | if (Ctx) | |
| 991 | return {Ctx->OutSec, false, Dot - Ctx->OutSec->Addr, Loc}; | |
| 992 | error(Loc + ": unable to get location counter value"); | |
| 993 | return 0; | |
| 1097 | 994 | } |
| 1098 | 995 | |
| 1099 | uint32_t Type = Sec->Type; | |
| 1100 | if (Type == SHT_GROUP) { | |
| 1101 | finalizeShtGroup<ELFT>(Sec, Sections); | |
| 1102 | return; | |
| 996 | if (Symbol *Sym = Symtab->find(Name)) { | |
| 997 | if (auto *DS = dyn_cast<Defined>(Sym)) | |
| 998 | return {DS->Section, false, DS->Value, Loc}; | |
| 999 | if (auto *SS = dyn_cast<SharedSymbol>(Sym)) | |
| 1000 | if (!ErrorOnMissingSection || SS->CopyRelSec) | |
| 1001 | return {SS->CopyRelSec, false, 0, Loc}; | |
| 1103 | 1002 | } |
| 1104 | 1003 | |
| 1105 | if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL)) | |
| 1106 | return; | |
| 1107 | ||
| 1108 | InputSection *First = Sections[0]; | |
| 1109 | if (isa<SyntheticSection>(First)) | |
| 1110 | return; | |
| 1111 | ||
| 1112 | Sec->Link = InX::SymTab->getParent()->SectionIndex; | |
| 1113 | // sh_info for SHT_REL[A] sections should contain the section header index of | |
| 1114 | // the section to which the relocation applies. | |
| 1115 | InputSectionBase *S = First->getRelocatedSection(); | |
| 1116 | Sec->Info = S->getOutputSection()->SectionIndex; | |
| 1117 | Sec->Flags |= SHF_INFO_LINK; | |
| 1118 | } | |
| 1119 | ||
| 1120 | // Compress section contents if this section contains debug info. | |
| 1121 | template <class ELFT> void OutputSectionCommand::maybeCompress() { | |
| 1122 | typedef typename ELFT::Chdr Elf_Chdr; | |
| 1123 | ||
| 1124 | // Compress only DWARF debug sections. | |
| 1125 | if (!Config->CompressDebugSections || (Sec->Flags & SHF_ALLOC) || | |
| 1126 | !Name.startswith(".debug_")) | |
| 1127 | return; | |
| 1128 | ||
| 1129 | // Create a section header. | |
| 1130 | Sec->ZDebugHeader.resize(sizeof(Elf_Chdr)); | |
| 1131 | auto *Hdr = reinterpret_cast<Elf_Chdr *>(Sec->ZDebugHeader.data()); | |
| 1132 | Hdr->ch_type = ELFCOMPRESS_ZLIB; | |
| 1133 | Hdr->ch_size = Sec->Size; | |
| 1134 | Hdr->ch_addralign = Sec->Alignment; | |
| 1135 | ||
| 1136 | // Write section contents to a temporary buffer and compress it. | |
| 1137 | std::vector<uint8_t> Buf(Sec->Size); | |
| 1138 | writeTo<ELFT>(Buf.data()); | |
| 1139 | if (Error E = zlib::compress(toStringRef(Buf), Sec->CompressedData)) | |
| 1140 | fatal("compress failed: " + llvm::toString(std::move(E))); | |
| 1141 | ||
| 1142 | // Update section headers. | |
| 1143 | Sec->Size = sizeof(Elf_Chdr) + Sec->CompressedData.size(); | |
| 1144 | Sec->Flags |= SHF_COMPRESSED; | |
| 1145 | } | |
| 1146 | ||
| 1147 | template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) { | |
| 1148 | if (Sec->Type == SHT_NOBITS) | |
| 1149 | return; | |
| 1150 | ||
| 1151 | Sec->Loc = Buf; | |
| 1152 | ||
| 1153 | // If -compress-debug-section is specified and if this is a debug seciton, | |
| 1154 | // we've already compressed section contents. If that's the case, | |
| 1155 | // just write it down. | |
| 1156 | if (!Sec->CompressedData.empty()) { | |
| 1157 | memcpy(Buf, Sec->ZDebugHeader.data(), Sec->ZDebugHeader.size()); | |
| 1158 | memcpy(Buf + Sec->ZDebugHeader.size(), Sec->CompressedData.data(), | |
| 1159 | Sec->CompressedData.size()); | |
| 1160 | return; | |
| 1161 | } | |
| 1162 | ||
| 1163 | // Write leading padding. | |
| 1164 | std::vector<InputSection *> Sections; | |
| 1165 | for (BaseCommand *Cmd : Commands) | |
| 1166 | if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd)) | |
| 1167 | for (InputSection *IS : ISD->Sections) | |
| 1168 | if (IS->Live) | |
| 1169 | Sections.push_back(IS); | |
| 1170 | uint32_t Filler = getFiller(); | |
| 1171 | if (Filler) | |
| 1172 | fill(Buf, Sections.empty() ? Sec->Size : Sections[0]->OutSecOff, Filler); | |
| 1173 | ||
| 1174 | parallelForEachN(0, Sections.size(), [=](size_t I) { | |
| 1175 | InputSection *IS = Sections[I]; | |
| 1176 | IS->writeTo<ELFT>(Buf); | |
| 1177 | ||
| 1178 | // Fill gaps between sections. | |
| 1179 | if (Filler) { | |
| 1180 | uint8_t *Start = Buf + IS->OutSecOff + IS->getSize(); | |
| 1181 | uint8_t *End; | |
| 1182 | if (I + 1 == Sections.size()) | |
| 1183 | End = Buf + Sec->Size; | |
| 1184 | else | |
| 1185 | End = Buf + Sections[I + 1]->OutSecOff; | |
| 1186 | fill(Start, End - Start, Filler); | |
| 1187 | } | |
| 1188 | }); | |
| 1189 | ||
| 1190 | // Linker scripts may have BYTE()-family commands with which you | |
| 1191 | // can write arbitrary bytes to the output. Process them if any. | |
| 1192 | for (BaseCommand *Base : Commands) | |
| 1193 | if (auto *Data = dyn_cast<BytesDataCommand>(Base)) | |
| 1194 | writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size); | |
| 1195 | } | |
| 1196 | ||
| 1197 | ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) { | |
| 1198 | if (S == ".") | |
| 1199 | return {CurAddressState->OutSec, Dot - CurAddressState->OutSec->Addr, Loc}; | |
| 1200 | if (SymbolBody *B = findSymbol(S)) { | |
| 1201 | if (auto *D = dyn_cast<DefinedRegular>(B)) | |
| 1202 | return {D->Section, D->Value, Loc}; | |
| 1203 | if (auto *C = dyn_cast<DefinedCommon>(B)) | |
| 1204 | return {InX::Common, C->Offset, Loc}; | |
| 1205 | } | |
| 1206 | error(Loc + ": symbol not found: " + S); | |
| 1004 | error(Loc + ": symbol not found: " + Name); | |
| 1207 | 1005 | return 0; |
| 1208 | 1006 | } |
| 1209 | 1007 | |
| 1210 | bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; } | |
| 1211 | ||
| 1212 | static const size_t NoPhdr = -1; | |
| 1008 | // Returns the index of the segment named Name. | |
| 1009 | static Optional<size_t> getPhdrIndex(ArrayRef<PhdrsCommand> Vec, | |
| 1010 | StringRef Name) { | |
| 1011 | for (size_t I = 0; I < Vec.size(); ++I) | |
| 1012 | if (Vec[I].Name == Name) | |
| 1013 | return I; | |
| 1014 | return None; | |
| 1015 | } | |
| 1213 | 1016 | |
| 1214 | 1017 | // Returns indices of ELF headers containing specific section. Each index is a |
| 1215 | 1018 | // zero based number of ELF header listed within PHDRS {} script block. |
| 1216 | std::vector<size_t> LinkerScript::getPhdrIndices(OutputSectionCommand *Cmd) { | |
| 1019 | std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *Cmd) { | |
| 1217 | 1020 | std::vector<size_t> Ret; |
| 1218 | for (StringRef PhdrName : Cmd->Phdrs) { | |
| 1219 | size_t Index = getPhdrIndex(Cmd->Location, PhdrName); | |
| 1220 | if (Index != NoPhdr) | |
| 1221 | Ret.push_back(Index); | |
| 1222 | } | |
| 1223 | return Ret; | |
| 1224 | } | |
| 1225 | 1021 | |
| 1226 | // Returns the index of the segment named PhdrName if found otherwise | |
| 1227 | // NoPhdr. When not found, if PhdrName is not the special case value 'NONE' | |
| 1228 | // (which can be used to explicitly specify that a section isn't assigned to a | |
| 1229 | // segment) then error. | |
| 1230 | size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) { | |
| 1231 | size_t I = 0; | |
| 1232 | for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { | |
| 1233 | if (Cmd.Name == PhdrName) | |
| 1234 | return I; | |
| 1235 | ++I; | |
| 1022 | for (StringRef S : Cmd->Phdrs) { | |
| 1023 | if (Optional<size_t> Idx = getPhdrIndex(PhdrsCommands, S)) | |
| 1024 | Ret.push_back(*Idx); | |
| 1025 | else if (S != "NONE") | |
| 1026 | error(Cmd->Location + ": section header '" + S + | |
| 1027 | "' is not listed in PHDRS"); | |
| 1236 | 1028 | } |
| 1237 | if (PhdrName != "NONE") | |
| 1238 | error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS"); | |
| 1239 | return NoPhdr; | |
| 1029 | return Ret; | |
| 1240 | 1030 | } |
| 1241 | ||
| 1242 | template void OutputSectionCommand::writeTo<ELF32LE>(uint8_t *Buf); | |
| 1243 | template void OutputSectionCommand::writeTo<ELF32BE>(uint8_t *Buf); | |
| 1244 | template void OutputSectionCommand::writeTo<ELF64LE>(uint8_t *Buf); | |
| 1245 | template void OutputSectionCommand::writeTo<ELF64BE>(uint8_t *Buf); | |
| 1246 | ||
| 1247 | template void OutputSectionCommand::maybeCompress<ELF32LE>(); | |
| 1248 | template void OutputSectionCommand::maybeCompress<ELF32BE>(); | |
| 1249 | template void OutputSectionCommand::maybeCompress<ELF64LE>(); | |
| 1250 | template void OutputSectionCommand::maybeCompress<ELF64BE>(); | |
| 1251 | ||
| 1252 | template void OutputSectionCommand::finalize<ELF32LE>(); | |
| 1253 | template void OutputSectionCommand::finalize<ELF32BE>(); | |
| 1254 | template void OutputSectionCommand::finalize<ELF64LE>(); | |
| 1255 | template void OutputSectionCommand::finalize<ELF64BE>(); |
deps/lld/ELF/LinkerScript.h+106-115| ... | ... | @@ -13,10 +13,11 @@ |
| 13 | 13 | #include "Config.h" |
| 14 | 14 | #include "Strings.h" |
| 15 | 15 | #include "Writer.h" |
| 16 | #include "lld/Core/LLVM.h" | |
| 16 | #include "lld/Common/LLVM.h" | |
| 17 | 17 | #include "llvm/ADT/ArrayRef.h" |
| 18 | 18 | #include "llvm/ADT/DenseMap.h" |
| 19 | 19 | #include "llvm/ADT/DenseSet.h" |
| 20 | #include "llvm/ADT/MapVector.h" | |
| 20 | 21 | #include "llvm/ADT/StringRef.h" |
| 21 | 22 | #include "llvm/Support/MemoryBuffer.h" |
| 22 | 23 | #include <cstddef> |
| ... | ... | @@ -28,31 +29,39 @@ |
| 28 | 29 | namespace lld { |
| 29 | 30 | namespace elf { |
| 30 | 31 | |
| 31 | class DefinedCommon; | |
| 32 | class SymbolBody; | |
| 32 | class Defined; | |
| 33 | class Symbol; | |
| 33 | 34 | class InputSectionBase; |
| 34 | 35 | class InputSection; |
| 35 | 36 | class OutputSection; |
| 36 | class OutputSectionFactory; | |
| 37 | 37 | class InputSectionBase; |
| 38 | 38 | class SectionBase; |
| 39 | 39 | |
| 40 | // This represents an r-value in the linker script. | |
| 40 | 41 | struct ExprValue { |
| 41 | SectionBase *Sec; | |
| 42 | uint64_t Val; | |
| 43 | bool ForceAbsolute; | |
| 44 | uint64_t Alignment = 1; | |
| 45 | std::string Loc; | |
| 46 | ||
| 47 | 42 | ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val, |
| 48 | 43 | const Twine &Loc) |
| 49 | : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Loc(Loc.str()) {} | |
| 50 | ExprValue(SectionBase *Sec, uint64_t Val, const Twine &Loc) | |
| 51 | : ExprValue(Sec, false, Val, Loc) {} | |
| 52 | ExprValue(uint64_t Val) : ExprValue(nullptr, Val, "") {} | |
| 44 | : Sec(Sec), ForceAbsolute(ForceAbsolute), Val(Val), Loc(Loc.str()) {} | |
| 45 | ||
| 46 | ExprValue(uint64_t Val) : ExprValue(nullptr, false, Val, "") {} | |
| 47 | ||
| 53 | 48 | bool isAbsolute() const { return ForceAbsolute || Sec == nullptr; } |
| 54 | 49 | uint64_t getValue() const; |
| 55 | 50 | uint64_t getSecAddr() const; |
| 51 | uint64_t getSectionOffset() const; | |
| 52 | ||
| 53 | // If a value is relative to a section, it has a non-null Sec. | |
| 54 | SectionBase *Sec; | |
| 55 | ||
| 56 | // True if this expression is enclosed in ABSOLUTE(). | |
| 57 | // This flag affects the return value of getValue(). | |
| 58 | bool ForceAbsolute; | |
| 59 | ||
| 60 | uint64_t Val; | |
| 61 | uint64_t Alignment = 1; | |
| 62 | ||
| 63 | // Original source location. Used for error messages. | |
| 64 | std::string Loc; | |
| 56 | 65 | }; |
| 57 | 66 | |
| 58 | 67 | // This represents an expression in the linker script. |
| ... | ... | @@ -66,8 +75,8 @@ enum SectionsCommandKind { |
| 66 | 75 | AssignmentKind, // . = expr or <sym> = expr |
| 67 | 76 | OutputSectionKind, |
| 68 | 77 | InputSectionKind, |
| 69 | AssertKind, // ASSERT(expr) | |
| 70 | BytesDataKind // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr) | |
| 78 | AssertKind, // ASSERT(expr) | |
| 79 | ByteKind // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr) | |
| 71 | 80 | }; |
| 72 | 81 | |
| 73 | 82 | struct BaseCommand { |
| ... | ... | @@ -80,11 +89,13 @@ struct SymbolAssignment : BaseCommand { |
| 80 | 89 | SymbolAssignment(StringRef Name, Expr E, std::string Loc) |
| 81 | 90 | : BaseCommand(AssignmentKind), Name(Name), Expression(E), Location(Loc) {} |
| 82 | 91 | |
| 83 | static bool classof(const BaseCommand *C); | |
| 92 | static bool classof(const BaseCommand *C) { | |
| 93 | return C->Kind == AssignmentKind; | |
| 94 | } | |
| 84 | 95 | |
| 85 | 96 | // The LHS of an expression. Name is either a symbol name or ".". |
| 86 | 97 | StringRef Name; |
| 87 | SymbolBody *Sym = nullptr; | |
| 98 | Defined *Sym = nullptr; | |
| 88 | 99 | |
| 89 | 100 | // The RHS of an expression. |
| 90 | 101 | Expr Expression; |
| ... | ... | @@ -107,42 +118,17 @@ enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite }; |
| 107 | 118 | // target memory. Instances of the struct are created by parsing the |
| 108 | 119 | // MEMORY command. |
| 109 | 120 | struct MemoryRegion { |
| 121 | MemoryRegion(StringRef Name, uint64_t Origin, uint64_t Length, uint32_t Flags, | |
| 122 | uint32_t NegFlags) | |
| 123 | : Name(Name), Origin(Origin), Length(Length), Flags(Flags), | |
| 124 | NegFlags(NegFlags) {} | |
| 125 | ||
| 110 | 126 | std::string Name; |
| 111 | 127 | uint64_t Origin; |
| 112 | 128 | uint64_t Length; |
| 113 | 129 | uint32_t Flags; |
| 114 | 130 | uint32_t NegFlags; |
| 115 | }; | |
| 116 | ||
| 117 | struct OutputSectionCommand : BaseCommand { | |
| 118 | OutputSectionCommand(StringRef Name) | |
| 119 | : BaseCommand(OutputSectionKind), Name(Name) {} | |
| 120 | ||
| 121 | static bool classof(const BaseCommand *C); | |
| 122 | ||
| 123 | OutputSection *Sec = nullptr; | |
| 124 | MemoryRegion *MemRegion = nullptr; | |
| 125 | StringRef Name; | |
| 126 | Expr AddrExpr; | |
| 127 | Expr AlignExpr; | |
| 128 | Expr LMAExpr; | |
| 129 | Expr SubalignExpr; | |
| 130 | std::vector<BaseCommand *> Commands; | |
| 131 | std::vector<StringRef> Phdrs; | |
| 132 | llvm::Optional<uint32_t> Filler; | |
| 133 | ConstraintKind Constraint = ConstraintKind::NoConstraint; | |
| 134 | std::string Location; | |
| 135 | std::string MemoryRegionName; | |
| 136 | bool Noload = false; | |
| 137 | ||
| 138 | template <class ELFT> void finalize(); | |
| 139 | template <class ELFT> void writeTo(uint8_t *Buf); | |
| 140 | template <class ELFT> void maybeCompress(); | |
| 141 | uint32_t getFiller(); | |
| 142 | ||
| 143 | void sort(std::function<int(InputSectionBase *S)> Order); | |
| 144 | void sortInitFini(); | |
| 145 | void sortCtorsDtors(); | |
| 131 | uint64_t CurPos = 0; | |
| 146 | 132 | }; |
| 147 | 133 | |
| 148 | 134 | // This struct represents one section match pattern in SECTIONS() command. |
| ... | ... | @@ -158,11 +144,14 @@ struct SectionPattern { |
| 158 | 144 | SortSectionPolicy SortInner; |
| 159 | 145 | }; |
| 160 | 146 | |
| 147 | class ThunkSection; | |
| 161 | 148 | struct InputSectionDescription : BaseCommand { |
| 162 | 149 | InputSectionDescription(StringRef FilePattern) |
| 163 | 150 | : BaseCommand(InputSectionKind), FilePat(FilePattern) {} |
| 164 | 151 | |
| 165 | static bool classof(const BaseCommand *C); | |
| 152 | static bool classof(const BaseCommand *C) { | |
| 153 | return C->Kind == InputSectionKind; | |
| 154 | } | |
| 166 | 155 | |
| 167 | 156 | StringMatcher FilePat; |
| 168 | 157 | |
| ... | ... | @@ -171,23 +160,28 @@ struct InputSectionDescription : BaseCommand { |
| 171 | 160 | std::vector<SectionPattern> SectionPatterns; |
| 172 | 161 | |
| 173 | 162 | std::vector<InputSection *> Sections; |
| 163 | ||
| 164 | // Temporary record of synthetic ThunkSection instances and the pass that | |
| 165 | // they were created in. This is used to insert newly created ThunkSections | |
| 166 | // into Sections at the end of a createThunks() pass. | |
| 167 | std::vector<std::pair<ThunkSection *, uint32_t>> ThunkSections; | |
| 174 | 168 | }; |
| 175 | 169 | |
| 176 | 170 | // Represents an ASSERT(). |
| 177 | 171 | struct AssertCommand : BaseCommand { |
| 178 | 172 | AssertCommand(Expr E) : BaseCommand(AssertKind), Expression(E) {} |
| 179 | 173 | |
| 180 | static bool classof(const BaseCommand *C); | |
| 174 | static bool classof(const BaseCommand *C) { return C->Kind == AssertKind; } | |
| 181 | 175 | |
| 182 | 176 | Expr Expression; |
| 183 | 177 | }; |
| 184 | 178 | |
| 185 | 179 | // Represents BYTE(), SHORT(), LONG(), or QUAD(). |
| 186 | struct BytesDataCommand : BaseCommand { | |
| 187 | BytesDataCommand(Expr E, unsigned Size) | |
| 188 | : BaseCommand(BytesDataKind), Expression(E), Size(Size) {} | |
| 180 | struct ByteCommand : BaseCommand { | |
| 181 | ByteCommand(Expr E, unsigned Size) | |
| 182 | : BaseCommand(ByteKind), Expression(E), Size(Size) {} | |
| 189 | 183 | |
| 190 | static bool classof(const BaseCommand *C); | |
| 184 | static bool classof(const BaseCommand *C) { return C->Kind == ByteKind; } | |
| 191 | 185 | |
| 192 | 186 | Expr Expression; |
| 193 | 187 | unsigned Offset; |
| ... | ... | @@ -196,106 +190,103 @@ struct BytesDataCommand : BaseCommand { |
| 196 | 190 | |
| 197 | 191 | struct PhdrsCommand { |
| 198 | 192 | StringRef Name; |
| 199 | unsigned Type; | |
| 200 | bool HasFilehdr; | |
| 201 | bool HasPhdrs; | |
| 202 | unsigned Flags; | |
| 203 | Expr LMAExpr; | |
| 204 | }; | |
| 205 | ||
| 206 | // ScriptConfiguration holds linker script parse results. | |
| 207 | struct ScriptConfiguration { | |
| 208 | // Used to assign addresses to sections. | |
| 209 | std::vector<BaseCommand *> Commands; | |
| 210 | ||
| 211 | // Used to assign sections to headers. | |
| 212 | std::vector<PhdrsCommand> PhdrsCommands; | |
| 213 | ||
| 214 | bool HasSections = false; | |
| 215 | ||
| 216 | // List of section patterns specified with KEEP commands. They will | |
| 217 | // be kept even if they are unused and --gc-sections is specified. | |
| 218 | std::vector<InputSectionDescription *> KeptSections; | |
| 219 | ||
| 220 | // A map from memory region name to a memory region descriptor. | |
| 221 | llvm::DenseMap<llvm::StringRef, MemoryRegion> MemoryRegions; | |
| 222 | ||
| 223 | // A list of symbols referenced by the script. | |
| 224 | std::vector<llvm::StringRef> ReferencedSymbols; | |
| 193 | unsigned Type = llvm::ELF::PT_NULL; | |
| 194 | bool HasFilehdr = false; | |
| 195 | bool HasPhdrs = false; | |
| 196 | llvm::Optional<unsigned> Flags; | |
| 197 | Expr LMAExpr = nullptr; | |
| 225 | 198 | }; |
| 226 | 199 | |
| 227 | 200 | class LinkerScript final { |
| 228 | // Temporary state used in processCommands() and assignAddresses() | |
| 201 | // Temporary state used in processSectionCommands() and assignAddresses() | |
| 229 | 202 | // that must be reinitialized for each call to the above functions, and must |
| 230 | 203 | // not be used outside of the scope of a call to the above functions. |
| 231 | 204 | struct AddressState { |
| 205 | AddressState(); | |
| 232 | 206 | uint64_t ThreadBssOffset = 0; |
| 233 | 207 | OutputSection *OutSec = nullptr; |
| 234 | 208 | MemoryRegion *MemRegion = nullptr; |
| 235 | llvm::DenseMap<const MemoryRegion *, uint64_t> MemRegionOffset; | |
| 236 | std::function<uint64_t()> LMAOffset; | |
| 237 | AddressState(const ScriptConfiguration &Opt); | |
| 209 | MemoryRegion *LMARegion = nullptr; | |
| 210 | uint64_t LMAOffset = 0; | |
| 238 | 211 | }; |
| 239 | llvm::DenseMap<OutputSection *, OutputSectionCommand *> SecToCommand; | |
| 240 | llvm::DenseMap<StringRef, OutputSectionCommand *> NameToOutputSectionCommand; | |
| 241 | 212 | |
| 213 | llvm::DenseMap<StringRef, OutputSection *> NameToOutputSection; | |
| 214 | ||
| 215 | void addSymbol(SymbolAssignment *Cmd); | |
| 242 | 216 | void assignSymbol(SymbolAssignment *Cmd, bool InSec); |
| 243 | 217 | void setDot(Expr E, const Twine &Loc, bool InSec); |
| 244 | 218 | |
| 245 | 219 | std::vector<InputSection *> |
| 246 | computeInputSections(const InputSectionDescription *); | |
| 220 | computeInputSections(const InputSectionDescription *, | |
| 221 | const llvm::DenseMap<SectionBase *, int> &Order); | |
| 247 | 222 | |
| 248 | std::vector<InputSectionBase *> | |
| 249 | createInputSectionList(OutputSectionCommand &Cmd); | |
| 223 | std::vector<InputSection *> | |
| 224 | createInputSectionList(OutputSection &Cmd, | |
| 225 | const llvm::DenseMap<SectionBase *, int> &Order); | |
| 250 | 226 | |
| 251 | std::vector<size_t> getPhdrIndices(OutputSectionCommand *Cmd); | |
| 252 | size_t getPhdrIndex(const Twine &Loc, StringRef PhdrName); | |
| 227 | std::vector<size_t> getPhdrIndices(OutputSection *Sec); | |
| 253 | 228 | |
| 254 | MemoryRegion *findMemoryRegion(OutputSectionCommand *Cmd); | |
| 229 | MemoryRegion *findMemoryRegion(OutputSection *Sec); | |
| 255 | 230 | |
| 256 | 231 | void switchTo(OutputSection *Sec); |
| 257 | 232 | uint64_t advance(uint64_t Size, unsigned Align); |
| 258 | 233 | void output(InputSection *Sec); |
| 259 | void process(BaseCommand &Base); | |
| 260 | 234 | |
| 261 | AddressState *CurAddressState = nullptr; | |
| 235 | void assignOffsets(OutputSection *Sec); | |
| 236 | ||
| 237 | // Ctx captures the local AddressState and makes it accessible | |
| 238 | // deliberately. This is needed as there are some cases where we cannot just | |
| 239 | // thread the current state through to a lambda function created by the | |
| 240 | // script parser. | |
| 241 | // This should remain a plain pointer as its lifetime is smaller than | |
| 242 | // LinkerScript. | |
| 243 | AddressState *Ctx = nullptr; | |
| 244 | ||
| 262 | 245 | OutputSection *Aether; |
| 263 | 246 | |
| 264 | 247 | uint64_t Dot; |
| 265 | 248 | |
| 266 | 249 | public: |
| 267 | bool ErrorOnMissingSection = false; | |
| 268 | OutputSectionCommand *createOutputSectionCommand(StringRef Name, | |
| 269 | StringRef Location); | |
| 270 | OutputSectionCommand *getOrCreateOutputSectionCommand(StringRef Name); | |
| 250 | OutputSection *createOutputSection(StringRef Name, StringRef Location); | |
| 251 | OutputSection *getOrCreateOutputSection(StringRef Name); | |
| 271 | 252 | |
| 272 | OutputSectionCommand *getCmd(OutputSection *Sec) const; | |
| 273 | bool hasPhdrsCommands() { return !Opt.PhdrsCommands.empty(); } | |
| 253 | bool hasPhdrsCommands() { return !PhdrsCommands.empty(); } | |
| 274 | 254 | uint64_t getDot() { return Dot; } |
| 275 | void discard(ArrayRef<InputSectionBase *> V); | |
| 255 | void discard(ArrayRef<InputSection *> V); | |
| 276 | 256 | |
| 277 | ExprValue getSymbolValue(const Twine &Loc, StringRef S); | |
| 278 | bool isDefined(StringRef S); | |
| 257 | ExprValue getSymbolValue(StringRef Name, const Twine &Loc); | |
| 279 | 258 | |
| 280 | void fabricateDefaultCommands(); | |
| 281 | void addOrphanSections(OutputSectionFactory &Factory); | |
| 259 | void addOrphanSections(); | |
| 282 | 260 | void removeEmptyCommands(); |
| 283 | 261 | void adjustSectionsBeforeSorting(); |
| 284 | 262 | void adjustSectionsAfterSorting(); |
| 285 | 263 | |
| 286 | std::vector<PhdrEntry> createPhdrs(); | |
| 287 | bool ignoreInterpSection(); | |
| 264 | std::vector<PhdrEntry *> createPhdrs(); | |
| 265 | bool needsInterpSection(); | |
| 288 | 266 | |
| 289 | 267 | bool shouldKeep(InputSectionBase *S); |
| 290 | void assignOffsets(OutputSectionCommand *Cmd); | |
| 291 | void processNonSectionCommands(); | |
| 292 | 268 | void assignAddresses(); |
| 293 | void allocateHeaders(std::vector<PhdrEntry> &Phdrs); | |
| 294 | void addSymbol(SymbolAssignment *Cmd); | |
| 295 | void processCommands(OutputSectionFactory &Factory); | |
| 269 | void allocateHeaders(std::vector<PhdrEntry *> &Phdrs); | |
| 270 | void processSectionCommands(); | |
| 271 | ||
| 272 | // SECTIONS command list. | |
| 273 | std::vector<BaseCommand *> SectionCommands; | |
| 274 | ||
| 275 | // PHDRS command list. | |
| 276 | std::vector<PhdrsCommand> PhdrsCommands; | |
| 277 | ||
| 278 | bool HasSectionsCommand = false; | |
| 279 | bool ErrorOnMissingSection = false; | |
| 296 | 280 | |
| 297 | // Parsed linker script configurations are set to this struct. | |
| 298 | ScriptConfiguration Opt; | |
| 281 | // List of section patterns specified with KEEP commands. They will | |
| 282 | // be kept even if they are unused and --gc-sections is specified. | |
| 283 | std::vector<InputSectionDescription *> KeptSections; | |
| 284 | ||
| 285 | // A map from memory region name to a memory region descriptor. | |
| 286 | llvm::MapVector<llvm::StringRef, MemoryRegion *> MemoryRegions; | |
| 287 | ||
| 288 | // A list of symbols referenced by the script. | |
| 289 | std::vector<llvm::StringRef> ReferencedSymbols; | |
| 299 | 290 | }; |
| 300 | 291 | |
| 301 | 292 | extern LinkerScript *Script; |
deps/lld/ELF/MapFile.cpp+49-46| ... | ... | @@ -25,8 +25,9 @@ |
| 25 | 25 | #include "OutputSections.h" |
| 26 | 26 | #include "Strings.h" |
| 27 | 27 | #include "SymbolTable.h" |
| 28 | #include "Threads.h" | |
| 29 | ||
| 28 | #include "Symbols.h" | |
| 29 | #include "SyntheticSections.h" | |
| 30 | #include "lld/Common/Threads.h" | |
| 30 | 31 | #include "llvm/Support/raw_ostream.h" |
| 31 | 32 | |
| 32 | 33 | using namespace llvm; |
| ... | ... | @@ -35,46 +36,57 @@ using namespace llvm::object; |
| 35 | 36 | using namespace lld; |
| 36 | 37 | using namespace lld::elf; |
| 37 | 38 | |
| 38 | typedef DenseMap<const SectionBase *, SmallVector<DefinedRegular *, 4>> | |
| 39 | SymbolMapTy; | |
| 39 | typedef DenseMap<const SectionBase *, SmallVector<Symbol *, 4>> SymbolMapTy; | |
| 40 | 40 | |
| 41 | 41 | // Print out the first three columns of a line. |
| 42 | template <class ELFT> | |
| 43 | 42 | static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size, |
| 44 | 43 | uint64_t Align) { |
| 45 | int W = ELFT::Is64Bits ? 16 : 8; | |
| 44 | int W = Config->Is64 ? 16 : 8; | |
| 46 | 45 | OS << format("%0*llx %0*llx %5lld ", W, Addr, W, Size, Align); |
| 47 | 46 | } |
| 48 | 47 | |
| 49 | 48 | static std::string indent(int Depth) { return std::string(Depth * 8, ' '); } |
| 50 | 49 | |
| 51 | 50 | // Returns a list of all symbols that we want to print out. |
| 52 | template <class ELFT> std::vector<DefinedRegular *> getSymbols() { | |
| 53 | std::vector<DefinedRegular *> V; | |
| 54 | for (elf::ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles()) | |
| 55 | for (SymbolBody *B : File->getSymbols()) | |
| 56 | if (B->File == File && !B->isSection()) | |
| 57 | if (auto *Sym = dyn_cast<DefinedRegular>(B)) | |
| 58 | if (Sym->Section && Sym->Section->Live) | |
| 59 | V.push_back(Sym); | |
| 51 | static std::vector<Symbol *> getSymbols() { | |
| 52 | std::vector<Symbol *> V; | |
| 53 | for (InputFile *File : ObjectFiles) { | |
| 54 | 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)) | |
| 59 | if (DR->File == File && !DR->isSection() && DR->Section && | |
| 60 | DR->Section->Live) | |
| 61 | V.push_back(DR); | |
| 62 | } | |
| 63 | } | |
| 60 | 64 | return V; |
| 61 | 65 | } |
| 62 | 66 | |
| 63 | 67 | // Returns a map from sections to their symbols. |
| 64 | template <class ELFT> | |
| 65 | SymbolMapTy getSectionSyms(ArrayRef<DefinedRegular *> Syms) { | |
| 68 | static SymbolMapTy getSectionSyms(ArrayRef<Symbol *> Syms) { | |
| 66 | 69 | SymbolMapTy Ret; |
| 67 | for (DefinedRegular *S : Syms) | |
| 68 | Ret[S->Section].push_back(S); | |
| 70 | for (Symbol *S : Syms) { | |
| 71 | if (auto *DR = dyn_cast<Defined>(S)) { | |
| 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 | } | |
| 69 | 82 | |
| 70 | 83 | // Sort symbols by address. We want to print out symbols in the |
| 71 | 84 | // order in the output file rather than the order they appeared |
| 72 | 85 | // in the input files. |
| 73 | 86 | for (auto &It : Ret) { |
| 74 | SmallVectorImpl<DefinedRegular *> &V = It.second; | |
| 75 | std::sort(V.begin(), V.end(), [](DefinedRegular *A, DefinedRegular *B) { | |
| 76 | return A->getVA() < B->getVA(); | |
| 77 | }); | |
| 87 | SmallVectorImpl<Symbol *> &V = It.second; | |
| 88 | std::sort(V.begin(), V.end(), | |
| 89 | [](Symbol *A, Symbol *B) { return A->getVA() < B->getVA(); }); | |
| 78 | 90 | } |
| 79 | 91 | return Ret; |
| 80 | 92 | } |
| ... | ... | @@ -82,25 +94,22 @@ SymbolMapTy getSectionSyms(ArrayRef<DefinedRegular *> Syms) { |
| 82 | 94 | // Construct a map from symbols to their stringified representations. |
| 83 | 95 | // Demangling symbols (which is what toString() does) is slow, so |
| 84 | 96 | // we do that in batch using parallel-for. |
| 85 | template <class ELFT> | |
| 86 | DenseMap<DefinedRegular *, std::string> | |
| 87 | getSymbolStrings(ArrayRef<DefinedRegular *> Syms) { | |
| 97 | static DenseMap<Symbol *, std::string> | |
| 98 | getSymbolStrings(ArrayRef<Symbol *> Syms) { | |
| 88 | 99 | std::vector<std::string> Str(Syms.size()); |
| 89 | 100 | parallelForEachN(0, Syms.size(), [&](size_t I) { |
| 90 | 101 | raw_string_ostream OS(Str[I]); |
| 91 | writeHeader<ELFT>(OS, Syms[I]->getVA(), Syms[I]->template getSize<ELFT>(), | |
| 92 | 0); | |
| 102 | writeHeader(OS, Syms[I]->getVA(), Syms[I]->getSize(), 0); | |
| 93 | 103 | OS << indent(2) << toString(*Syms[I]); |
| 94 | 104 | }); |
| 95 | 105 | |
| 96 | DenseMap<DefinedRegular *, std::string> Ret; | |
| 106 | DenseMap<Symbol *, std::string> Ret; | |
| 97 | 107 | for (size_t I = 0, E = Syms.size(); I < E; ++I) |
| 98 | 108 | Ret[Syms[I]] = std::move(Str[I]); |
| 99 | 109 | return Ret; |
| 100 | 110 | } |
| 101 | 111 | |
| 102 | template <class ELFT> | |
| 103 | void elf::writeMapFile(llvm::ArrayRef<OutputSectionCommand *> Script) { | |
| 112 | void elf::writeMapFile() { | |
| 104 | 113 | if (Config->MapFile.empty()) |
| 105 | 114 | return; |
| 106 | 115 | |
| ... | ... | @@ -113,38 +122,32 @@ void elf::writeMapFile(llvm::ArrayRef<OutputSectionCommand *> Script) { |
| 113 | 122 | } |
| 114 | 123 | |
| 115 | 124 | // Collect symbol info that we want to print out. |
| 116 | std::vector<DefinedRegular *> Syms = getSymbols<ELFT>(); | |
| 117 | SymbolMapTy SectionSyms = getSectionSyms<ELFT>(Syms); | |
| 118 | DenseMap<DefinedRegular *, std::string> SymStr = getSymbolStrings<ELFT>(Syms); | |
| 125 | std::vector<Symbol *> Syms = getSymbols(); | |
| 126 | SymbolMapTy SectionSyms = getSectionSyms(Syms); | |
| 127 | DenseMap<Symbol *, std::string> SymStr = getSymbolStrings(Syms); | |
| 119 | 128 | |
| 120 | 129 | // Print out the header line. |
| 121 | int W = ELFT::Is64Bits ? 16 : 8; | |
| 130 | int W = Config->Is64 ? 16 : 8; | |
| 122 | 131 | OS << left_justify("Address", W) << ' ' << left_justify("Size", W) |
| 123 | 132 | << " Align Out In Symbol\n"; |
| 124 | 133 | |
| 125 | 134 | // Print out file contents. |
| 126 | for (OutputSectionCommand *Cmd : Script) { | |
| 127 | OutputSection *OSec = Cmd->Sec; | |
| 128 | writeHeader<ELFT>(OS, OSec->Addr, OSec->Size, OSec->Alignment); | |
| 135 | for (OutputSection *OSec : OutputSections) { | |
| 136 | writeHeader(OS, OSec->Addr, OSec->Size, OSec->Alignment); | |
| 129 | 137 | OS << OSec->Name << '\n'; |
| 130 | 138 | |
| 131 | 139 | // Dump symbols for each input section. |
| 132 | for (BaseCommand *Base : Cmd->Commands) { | |
| 140 | for (BaseCommand *Base : OSec->SectionCommands) { | |
| 133 | 141 | auto *ISD = dyn_cast<InputSectionDescription>(Base); |
| 134 | 142 | if (!ISD) |
| 135 | 143 | continue; |
| 136 | 144 | for (InputSection *IS : ISD->Sections) { |
| 137 | writeHeader<ELFT>(OS, OSec->Addr + IS->OutSecOff, IS->getSize(), | |
| 138 | IS->Alignment); | |
| 145 | writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(), | |
| 146 | IS->Alignment); | |
| 139 | 147 | OS << indent(1) << toString(IS) << '\n'; |
| 140 | for (DefinedRegular *Sym : SectionSyms[IS]) | |
| 148 | for (Symbol *Sym : SectionSyms[IS]) | |
| 141 | 149 | OS << SymStr[Sym] << '\n'; |
| 142 | 150 | } |
| 143 | 151 | } |
| 144 | 152 | } |
| 145 | 153 | } |
| 146 | ||
| 147 | template void elf::writeMapFile<ELF32LE>(ArrayRef<OutputSectionCommand *>); | |
| 148 | template void elf::writeMapFile<ELF32BE>(ArrayRef<OutputSectionCommand *>); | |
| 149 | template void elf::writeMapFile<ELF64LE>(ArrayRef<OutputSectionCommand *>); | |
| 150 | template void elf::writeMapFile<ELF64BE>(ArrayRef<OutputSectionCommand *>); |
deps/lld/ELF/MapFile.h+1-5| ... | ... | @@ -10,13 +10,9 @@ |
| 10 | 10 | #ifndef LLD_ELF_MAPFILE_H |
| 11 | 11 | #define LLD_ELF_MAPFILE_H |
| 12 | 12 | |
| 13 | #include <llvm/ADT/ArrayRef.h> | |
| 14 | ||
| 15 | 13 | namespace lld { |
| 16 | 14 | namespace elf { |
| 17 | struct OutputSectionCommand; | |
| 18 | template <class ELFT> | |
| 19 | void writeMapFile(llvm::ArrayRef<OutputSectionCommand *> Script); | |
| 15 | void writeMapFile(); | |
| 20 | 16 | } // namespace elf |
| 21 | 17 | } // namespace lld |
| 22 | 18 |
deps/lld/ELF/MarkLive.cpp+119-72| ... | ... | @@ -22,13 +22,13 @@ |
| 22 | 22 | |
| 23 | 23 | #include "InputSection.h" |
| 24 | 24 | #include "LinkerScript.h" |
| 25 | #include "Memory.h" | |
| 26 | 25 | #include "OutputSections.h" |
| 27 | 26 | #include "Strings.h" |
| 28 | 27 | #include "SymbolTable.h" |
| 29 | 28 | #include "Symbols.h" |
| 30 | 29 | #include "Target.h" |
| 31 | 30 | #include "Writer.h" |
| 31 | #include "lld/Common/Memory.h" | |
| 32 | 32 | #include "llvm/ADT/STLExtras.h" |
| 33 | 33 | #include "llvm/Object/ELF.h" |
| 34 | 34 | #include <functional> |
| ... | ... | @@ -42,15 +42,6 @@ using namespace llvm::support::endian; |
| 42 | 42 | using namespace lld; |
| 43 | 43 | using namespace lld::elf; |
| 44 | 44 | |
| 45 | namespace { | |
| 46 | // A resolved relocation. The Sec and Offset fields are set if the relocation | |
| 47 | // was resolved to an offset within a section. | |
| 48 | struct ResolvedReloc { | |
| 49 | InputSectionBase *Sec; | |
| 50 | uint64_t Offset; | |
| 51 | }; | |
| 52 | } // end anonymous namespace | |
| 53 | ||
| 54 | 45 | template <class ELFT> |
| 55 | 46 | static typename ELFT::uint getAddend(InputSectionBase &Sec, |
| 56 | 47 | const typename ELFT::Rel &Rel) { |
| ... | ... | @@ -70,25 +61,36 @@ static DenseMap<StringRef, std::vector<InputSectionBase *>> CNamedSections; |
| 70 | 61 | |
| 71 | 62 | template <class ELFT, class RelT> |
| 72 | 63 | static void resolveReloc(InputSectionBase &Sec, RelT &Rel, |
| 73 | std::function<void(ResolvedReloc)> Fn) { | |
| 74 | SymbolBody &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel); | |
| 75 | if (auto *D = dyn_cast<DefinedRegular>(&B)) { | |
| 76 | if (!D->Section) | |
| 64 | std::function<void(InputSectionBase *, uint64_t)> Fn) { | |
| 65 | Symbol &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel); | |
| 66 | ||
| 67 | // If a symbol is referenced in a live section, it is used. | |
| 68 | B.Used = true; | |
| 69 | if (auto *SS = dyn_cast<SharedSymbol>(&B)) | |
| 70 | if (!SS->isWeak()) | |
| 71 | SS->getFile<ELFT>().IsNeeded = true; | |
| 72 | ||
| 73 | if (auto *D = dyn_cast<Defined>(&B)) { | |
| 74 | auto *RelSec = dyn_cast_or_null<InputSectionBase>(D->Section); | |
| 75 | if (!RelSec) | |
| 77 | 76 | return; |
| 78 | typename ELFT::uint Offset = D->Value; | |
| 77 | uint64_t Offset = D->Value; | |
| 79 | 78 | if (D->isSection()) |
| 80 | 79 | Offset += getAddend<ELFT>(Sec, Rel); |
| 81 | Fn({cast<InputSectionBase>(D->Section), Offset}); | |
| 82 | } else if (auto *U = dyn_cast<Undefined>(&B)) { | |
| 83 | for (InputSectionBase *Sec : CNamedSections.lookup(U->getName())) | |
| 84 | Fn({Sec, 0}); | |
| 80 | Fn(RelSec, Offset); | |
| 81 | return; | |
| 85 | 82 | } |
| 83 | ||
| 84 | if (!B.isDefined()) | |
| 85 | for (InputSectionBase *Sec : CNamedSections.lookup(B.getName())) | |
| 86 | Fn(Sec, 0); | |
| 86 | 87 | } |
| 87 | 88 | |
| 88 | 89 | // Calls Fn for each section that Sec refers to via relocations. |
| 89 | 90 | template <class ELFT> |
| 90 | static void forEachSuccessor(InputSection &Sec, | |
| 91 | std::function<void(ResolvedReloc)> Fn) { | |
| 91 | static void | |
| 92 | forEachSuccessor(InputSection &Sec, | |
| 93 | std::function<void(InputSectionBase *, uint64_t)> Fn) { | |
| 92 | 94 | if (Sec.AreRelocsRela) { |
| 93 | 95 | for (const typename ELFT::Rela &Rel : Sec.template relas<ELFT>()) |
| 94 | 96 | resolveReloc<ELFT>(Sec, Rel, Fn); |
| ... | ... | @@ -96,8 +98,9 @@ static void forEachSuccessor(InputSection &Sec, |
| 96 | 98 | for (const typename ELFT::Rel &Rel : Sec.template rels<ELFT>()) |
| 97 | 99 | resolveReloc<ELFT>(Sec, Rel, Fn); |
| 98 | 100 | } |
| 101 | ||
| 99 | 102 | for (InputSectionBase *IS : Sec.DependentSections) |
| 100 | Fn({IS, 0}); | |
| 103 | Fn(IS, 0); | |
| 101 | 104 | } |
| 102 | 105 | |
| 103 | 106 | // The .eh_frame section is an unfortunate special case. |
| ... | ... | @@ -115,9 +118,11 @@ static void forEachSuccessor(InputSection &Sec, |
| 115 | 118 | // the gc pass. With that we would be able to also gc some sections holding |
| 116 | 119 | // LSDAs and personality functions if we found that they were unused. |
| 117 | 120 | template <class ELFT, class RelTy> |
| 118 | static void scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels, | |
| 119 | std::function<void(ResolvedReloc)> Enqueue) { | |
| 121 | static void | |
| 122 | scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels, | |
| 123 | std::function<void(InputSectionBase *, uint64_t)> Fn) { | |
| 120 | 124 | const endianness E = ELFT::TargetEndianness; |
| 125 | ||
| 121 | 126 | for (unsigned I = 0, N = EH.Pieces.size(); I < N; ++I) { |
| 122 | 127 | EhSectionPiece &Piece = EH.Pieces[I]; |
| 123 | 128 | unsigned FirstRelI = Piece.FirstRelocation; |
| ... | ... | @@ -126,31 +131,31 @@ static void scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels, |
| 126 | 131 | if (read32<E>(Piece.data().data() + 4) == 0) { |
| 127 | 132 | // This is a CIE, we only need to worry about the first relocation. It is |
| 128 | 133 | // known to point to the personality function. |
| 129 | resolveReloc<ELFT>(EH, Rels[FirstRelI], Enqueue); | |
| 134 | resolveReloc<ELFT>(EH, Rels[FirstRelI], Fn); | |
| 130 | 135 | continue; |
| 131 | 136 | } |
| 132 | 137 | // This is a FDE. The relocations point to the described function or to |
| 133 | 138 | // a LSDA. We only need to keep the LSDA alive, so ignore anything that |
| 134 | 139 | // points to executable sections. |
| 135 | typename ELFT::uint PieceEnd = Piece.InputOff + Piece.size(); | |
| 140 | typename ELFT::uint PieceEnd = Piece.InputOff + Piece.Size; | |
| 136 | 141 | for (unsigned I2 = FirstRelI, N2 = Rels.size(); I2 < N2; ++I2) { |
| 137 | 142 | const RelTy &Rel = Rels[I2]; |
| 138 | 143 | if (Rel.r_offset >= PieceEnd) |
| 139 | 144 | break; |
| 140 | resolveReloc<ELFT>(EH, Rels[I2], [&](ResolvedReloc R) { | |
| 141 | if (!R.Sec || R.Sec == &InputSection::Discarded) | |
| 142 | return; | |
| 143 | if (R.Sec->Flags & SHF_EXECINSTR) | |
| 144 | return; | |
| 145 | Enqueue({R.Sec, 0}); | |
| 146 | }); | |
| 145 | resolveReloc<ELFT>(EH, Rels[I2], | |
| 146 | [&](InputSectionBase *Sec, uint64_t Offset) { | |
| 147 | if (Sec && Sec != &InputSection::Discarded && | |
| 148 | !(Sec->Flags & SHF_EXECINSTR)) | |
| 149 | Fn(Sec, 0); | |
| 150 | }); | |
| 147 | 151 | } |
| 148 | 152 | } |
| 149 | 153 | } |
| 150 | 154 | |
| 151 | 155 | template <class ELFT> |
| 152 | static void scanEhFrameSection(EhInputSection &EH, | |
| 153 | std::function<void(ResolvedReloc)> Enqueue) { | |
| 156 | static void | |
| 157 | scanEhFrameSection(EhInputSection &EH, | |
| 158 | std::function<void(InputSectionBase *, uint64_t)> Fn) { | |
| 154 | 159 | if (!EH.NumRelocations) |
| 155 | 160 | return; |
| 156 | 161 | |
| ... | ... | @@ -159,14 +164,14 @@ static void scanEhFrameSection(EhInputSection &EH, |
| 159 | 164 | EH.split<ELFT>(); |
| 160 | 165 | |
| 161 | 166 | if (EH.AreRelocsRela) |
| 162 | scanEhFrameSection<ELFT>(EH, EH.template relas<ELFT>(), Enqueue); | |
| 167 | scanEhFrameSection<ELFT>(EH, EH.template relas<ELFT>(), Fn); | |
| 163 | 168 | else |
| 164 | scanEhFrameSection<ELFT>(EH, EH.template rels<ELFT>(), Enqueue); | |
| 169 | scanEhFrameSection<ELFT>(EH, EH.template rels<ELFT>(), Fn); | |
| 165 | 170 | } |
| 166 | 171 | |
| 167 | // We do not garbage-collect two types of sections: | |
| 168 | // 1) Sections used by the loader (.init, .fini, .ctors, .dtors or .jcr) | |
| 169 | // 2) Non-allocatable sections which typically contain debugging information | |
| 172 | // Some sections are used directly by the loader, so they should never be | |
| 173 | // garbage-collected. This function returns true if a given section is such | |
| 174 | // section. | |
| 170 | 175 | template <class ELFT> static bool isReserved(InputSectionBase *Sec) { |
| 171 | 176 | switch (Sec->Type) { |
| 172 | 177 | case SHT_FINI_ARRAY: |
| ... | ... | @@ -175,9 +180,6 @@ template <class ELFT> static bool isReserved(InputSectionBase *Sec) { |
| 175 | 180 | case SHT_PREINIT_ARRAY: |
| 176 | 181 | return true; |
| 177 | 182 | default: |
| 178 | if (!(Sec->Flags & SHF_ALLOC)) | |
| 179 | return true; | |
| 180 | ||
| 181 | 183 | StringRef S = Sec->Name; |
| 182 | 184 | return S.startswith(".ctors") || S.startswith(".dtors") || |
| 183 | 185 | S.startswith(".init") || S.startswith(".fini") || |
| ... | ... | @@ -188,72 +190,74 @@ template <class ELFT> static bool isReserved(InputSectionBase *Sec) { |
| 188 | 190 | // This is the main function of the garbage collector. |
| 189 | 191 | // Starting from GC-root sections, this function visits all reachable |
| 190 | 192 | // sections to set their "Live" bits. |
| 191 | template <class ELFT> void elf::markLive() { | |
| 193 | template <class ELFT> static void doGcSections() { | |
| 192 | 194 | SmallVector<InputSection *, 256> Q; |
| 193 | 195 | CNamedSections.clear(); |
| 194 | 196 | |
| 195 | auto Enqueue = [&](ResolvedReloc R) { | |
| 197 | auto Enqueue = [&](InputSectionBase *Sec, uint64_t Offset) { | |
| 196 | 198 | // Skip over discarded sections. This in theory shouldn't happen, because |
| 197 | 199 | // the ELF spec doesn't allow a relocation to point to a deduplicated |
| 198 | 200 | // COMDAT section directly. Unfortunately this happens in practice (e.g. |
| 199 | 201 | // .eh_frame) so we need to add a check. |
| 200 | if (R.Sec == &InputSection::Discarded) | |
| 202 | if (Sec == &InputSection::Discarded) | |
| 201 | 203 | return; |
| 202 | 204 | |
| 203 | // We don't gc non alloc sections. | |
| 204 | if (!(R.Sec->Flags & SHF_ALLOC)) | |
| 205 | return; | |
| 206 | 205 | |
| 207 | 206 | // Usually, a whole section is marked as live or dead, but in mergeable |
| 208 | 207 | // (splittable) sections, each piece of data has independent liveness bit. |
| 209 | 208 | // So we explicitly tell it which offset is in use. |
| 210 | if (auto *MS = dyn_cast<MergeInputSection>(R.Sec)) | |
| 211 | MS->markLiveAt(R.Offset); | |
| 209 | if (auto *MS = dyn_cast<MergeInputSection>(Sec)) | |
| 210 | MS->markLiveAt(Offset); | |
| 212 | 211 | |
| 213 | if (R.Sec->Live) | |
| 212 | if (Sec->Live) | |
| 214 | 213 | return; |
| 215 | R.Sec->Live = true; | |
| 214 | Sec->Live = true; | |
| 215 | ||
| 216 | 216 | // Add input section to the queue. |
| 217 | if (InputSection *S = dyn_cast<InputSection>(R.Sec)) | |
| 217 | if (InputSection *S = dyn_cast<InputSection>(Sec)) | |
| 218 | 218 | Q.push_back(S); |
| 219 | 219 | }; |
| 220 | 220 | |
| 221 | auto MarkSymbol = [&](const SymbolBody *Sym) { | |
| 222 | if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym)) | |
| 223 | if (auto *IS = cast_or_null<InputSectionBase>(D->Section)) | |
| 224 | Enqueue({IS, D->Value}); | |
| 221 | auto MarkSymbol = [&](Symbol *Sym) { | |
| 222 | if (auto *D = dyn_cast_or_null<Defined>(Sym)) | |
| 223 | if (auto *IS = dyn_cast_or_null<InputSectionBase>(D->Section)) | |
| 224 | Enqueue(IS, D->Value); | |
| 225 | 225 | }; |
| 226 | 226 | |
| 227 | 227 | // Add GC root symbols. |
| 228 | MarkSymbol(Symtab<ELFT>::X->find(Config->Entry)); | |
| 229 | MarkSymbol(Symtab<ELFT>::X->find(Config->Init)); | |
| 230 | MarkSymbol(Symtab<ELFT>::X->find(Config->Fini)); | |
| 228 | MarkSymbol(Symtab->find(Config->Entry)); | |
| 229 | MarkSymbol(Symtab->find(Config->Init)); | |
| 230 | MarkSymbol(Symtab->find(Config->Fini)); | |
| 231 | 231 | for (StringRef S : Config->Undefined) |
| 232 | MarkSymbol(Symtab<ELFT>::X->find(S)); | |
| 233 | for (StringRef S : Script->Opt.ReferencedSymbols) | |
| 234 | MarkSymbol(Symtab<ELFT>::X->find(S)); | |
| 232 | MarkSymbol(Symtab->find(S)); | |
| 233 | for (StringRef S : Script->ReferencedSymbols) | |
| 234 | MarkSymbol(Symtab->find(S)); | |
| 235 | 235 | |
| 236 | 236 | // Preserve externally-visible symbols if the symbols defined by this |
| 237 | 237 | // file can interrupt other ELF file's symbols at runtime. |
| 238 | for (const Symbol *S : Symtab<ELFT>::X->getSymbols()) | |
| 238 | for (Symbol *S : Symtab->getSymbols()) | |
| 239 | 239 | if (S->includeInDynsym()) |
| 240 | MarkSymbol(S->body()); | |
| 240 | MarkSymbol(S); | |
| 241 | 241 | |
| 242 | 242 | // Preserve special sections and those which are specified in linker |
| 243 | 243 | // script KEEP command. |
| 244 | 244 | for (InputSectionBase *Sec : InputSections) { |
| 245 | // .eh_frame is always marked as live now, but also it can reference to | |
| 246 | // sections that contain personality. We preserve all non-text sections | |
| 247 | // referred by .eh_frame here. | |
| 248 | if (auto *EH = dyn_cast_or_null<EhInputSection>(Sec)) | |
| 245 | // Mark .eh_frame sections as live because there are usually no relocations | |
| 246 | // that point to .eh_frames. Otherwise, the garbage collector would drop | |
| 247 | // all of them. We also want to preserve personality routines and LSDA | |
| 248 | // referenced by .eh_frame sections, so we scan them for that here. | |
| 249 | if (auto *EH = dyn_cast<EhInputSection>(Sec)) { | |
| 250 | EH->Live = true; | |
| 249 | 251 | scanEhFrameSection<ELFT>(*EH, Enqueue); |
| 252 | } | |
| 253 | ||
| 250 | 254 | if (Sec->Flags & SHF_LINK_ORDER) |
| 251 | 255 | continue; |
| 252 | 256 | if (isReserved<ELFT>(Sec) || Script->shouldKeep(Sec)) |
| 253 | Enqueue({Sec, 0}); | |
| 257 | Enqueue(Sec, 0); | |
| 254 | 258 | else if (isValidCIdentifier(Sec->Name)) { |
| 255 | 259 | CNamedSections[Saver.save("__start_" + Sec->Name)].push_back(Sec); |
| 256 | CNamedSections[Saver.save("__end_" + Sec->Name)].push_back(Sec); | |
| 260 | CNamedSections[Saver.save("__stop_" + Sec->Name)].push_back(Sec); | |
| 257 | 261 | } |
| 258 | 262 | } |
| 259 | 263 | |
| ... | ... | @@ -262,6 +266,49 @@ template <class ELFT> void elf::markLive() { |
| 262 | 266 | forEachSuccessor<ELFT>(*Q.pop_back_val(), Enqueue); |
| 263 | 267 | } |
| 264 | 268 | |
| 269 | // Before calling this function, Live bits are off for all | |
| 270 | // input sections. This function make some or all of them on | |
| 271 | // so that they are emitted to the output file. | |
| 272 | template <class ELFT> void elf::markLive() { | |
| 273 | // If -gc-sections is missing, no sections are removed. | |
| 274 | if (!Config->GcSections) { | |
| 275 | for (InputSectionBase *Sec : InputSections) | |
| 276 | Sec->Live = true; | |
| 277 | return; | |
| 278 | } | |
| 279 | ||
| 280 | // The -gc-sections option works only for SHF_ALLOC sections | |
| 281 | // (sections that are memory-mapped at runtime). So we can | |
| 282 | // unconditionally make non-SHF_ALLOC sections alive. | |
| 283 | // | |
| 284 | // Non SHF_ALLOC sections are not removed even if they are | |
| 285 | // unreachable through relocations because reachability is not | |
| 286 | // a good signal whether they are garbage or not (e.g. there is | |
| 287 | // usually no section referring to a .comment section, but we | |
| 288 | // want to keep it.) | |
| 289 | // | |
| 290 | // Note on SHF_REL{,A}: Such sections reach here only when -r | |
| 291 | // or -emit-reloc were given. And they are subject of garbage | |
| 292 | // collection because, if we remove a text section, we also | |
| 293 | // remove its relocation section. | |
| 294 | for (InputSectionBase *Sec : InputSections) { | |
| 295 | bool IsAlloc = (Sec->Flags & SHF_ALLOC); | |
| 296 | bool IsRel = (Sec->Type == SHT_REL || Sec->Type == SHT_RELA); | |
| 297 | if (!IsAlloc && !IsRel) | |
| 298 | Sec->Live = true; | |
| 299 | } | |
| 300 | ||
| 301 | // Follow the graph to mark all live sections. | |
| 302 | doGcSections<ELFT>(); | |
| 303 | ||
| 304 | // Report garbage-collected sections. | |
| 305 | if (Config->PrintGcSections) | |
| 306 | for (InputSectionBase *Sec : InputSections) | |
| 307 | if (!Sec->Live) | |
| 308 | message("removing unused section from '" + Sec->Name + "' in file '" + | |
| 309 | Sec->File->getName() + "'"); | |
| 310 | } | |
| 311 | ||
| 265 | 312 | template void elf::markLive<ELF32LE>(); |
| 266 | 313 | template void elf::markLive<ELF32BE>(); |
| 267 | 314 | template void elf::markLive<ELF64LE>(); |
deps/lld/ELF/Memory.h deleted-67| ... | ... | @@ -1,67 +0,0 @@ |
| 1 | //===- Memory.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 defines arena allocators. | |
| 11 | // | |
| 12 | // Almost all large objects, such as files, sections or symbols, are | |
| 13 | // used for the entire lifetime of the linker once they are created. | |
| 14 | // This usage characteristic makes arena allocator an attractive choice | |
| 15 | // where the entire linker is one arena. With an arena, newly created | |
| 16 | // objects belong to the arena and freed all at once when everything is done. | |
| 17 | // Arena allocators are efficient and easy to understand. | |
| 18 | // Most objects are allocated using the arena allocators defined by this file. | |
| 19 | // | |
| 20 | // If you edit this file, please edit COFF/Memory.h too. | |
| 21 | // | |
| 22 | //===----------------------------------------------------------------------===// | |
| 23 | ||
| 24 | #ifndef LLD_ELF_MEMORY_H | |
| 25 | #define LLD_ELF_MEMORY_H | |
| 26 | ||
| 27 | #include "llvm/Support/Allocator.h" | |
| 28 | #include "llvm/Support/StringSaver.h" | |
| 29 | #include <vector> | |
| 30 | ||
| 31 | namespace lld { | |
| 32 | namespace elf { | |
| 33 | ||
| 34 | // Use this arena if your object doesn't have a destructor. | |
| 35 | extern llvm::BumpPtrAllocator BAlloc; | |
| 36 | extern llvm::StringSaver Saver; | |
| 37 | ||
| 38 | // These two classes are hack to keep track of all | |
| 39 | // SpecificBumpPtrAllocator instances. | |
| 40 | struct SpecificAllocBase { | |
| 41 | SpecificAllocBase() { Instances.push_back(this); } | |
| 42 | virtual ~SpecificAllocBase() = default; | |
| 43 | virtual void reset() = 0; | |
| 44 | static std::vector<SpecificAllocBase *> Instances; | |
| 45 | }; | |
| 46 | ||
| 47 | template <class T> struct SpecificAlloc : public SpecificAllocBase { | |
| 48 | void reset() override { Alloc.DestroyAll(); } | |
| 49 | llvm::SpecificBumpPtrAllocator<T> Alloc; | |
| 50 | }; | |
| 51 | ||
| 52 | // Use this arena if your object has a destructor. | |
| 53 | // Your destructor will be invoked from freeArena(). | |
| 54 | template <typename T, typename... U> T *make(U &&... Args) { | |
| 55 | static SpecificAlloc<T> Alloc; | |
| 56 | return new (Alloc.Alloc.Allocate()) T(std::forward<U>(Args)...); | |
| 57 | } | |
| 58 | ||
| 59 | inline void freeArena() { | |
| 60 | for (SpecificAllocBase *Alloc : SpecificAllocBase::Instances) | |
| 61 | Alloc->reset(); | |
| 62 | BAlloc.Reset(); | |
| 63 | } | |
| 64 | } // namespace elf | |
| 65 | } // namespace lld | |
| 66 | ||
| 67 | #endif |
deps/lld/ELF/Options.td+100-77| ... | ... | @@ -5,7 +5,11 @@ include "llvm/Option/OptParser.td" |
| 5 | 5 | class F<string name>: Flag<["--", "-"], name>; |
| 6 | 6 | class J<string name>: Joined<["--", "-"], name>; |
| 7 | 7 | class S<string name>: Separate<["--", "-"], name>; |
| 8 | class JS<string name>: JoinedOrSeparate<["--", "-"], name>; | |
| 8 | ||
| 9 | multiclass Eq<string name> { | |
| 10 | def "": Separate<["--", "-"], name>; | |
| 11 | def _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>; | |
| 12 | } | |
| 9 | 13 | |
| 10 | 14 | def auxiliary: S<"auxiliary">, HelpText<"Set DT_AUXILIARY field to the specified name">; |
| 11 | 15 | |
| ... | ... | @@ -22,21 +26,24 @@ def build_id: F<"build-id">, HelpText<"Generate build ID note">; |
| 22 | 26 | |
| 23 | 27 | def build_id_eq: J<"build-id=">, HelpText<"Generate build ID note">; |
| 24 | 28 | |
| 25 | def compress_debug_sections : J<"compress-debug-sections=">, | |
| 29 | defm compress_debug_sections : Eq<"compress-debug-sections">, | |
| 26 | 30 | HelpText<"Compress DWARF debug sections">; |
| 27 | 31 | |
| 28 | def defsym: J<"defsym=">, HelpText<"Define a symbol alias">; | |
| 32 | defm defsym: Eq<"defsym">, HelpText<"Define a symbol alias">; | |
| 29 | 33 | |
| 30 | def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">, | |
| 31 | HelpText<"Add a directory to the library search path">; | |
| 34 | defm library_path: Eq<"library-path">, | |
| 35 | HelpText<"Add a directory to the library search path">, MetaVarName<"<dir>">; | |
| 32 | 36 | |
| 33 | def O: Joined<["-"], "O">, HelpText<"Optimize output file size">; | |
| 37 | def O: JoinedOrSeparate<["-"], "O">, HelpText<"Optimize output file size">; | |
| 34 | 38 | |
| 35 | def Tbss: S<"Tbss">, HelpText<"Same as --section-start with .bss as the sectionname">; | |
| 39 | defm Tbss: Eq<"Tbss">, | |
| 40 | HelpText<"Same as --section-start with .bss as the sectionname">; | |
| 36 | 41 | |
| 37 | def Tdata: S<"Tdata">, HelpText<"Same as --section-start with .data as the sectionname">; | |
| 42 | defm Tdata: Eq<"Tdata">, | |
| 43 | HelpText<"Same as --section-start with .data as the sectionname">; | |
| 38 | 44 | |
| 39 | def Ttext: S<"Ttext">, HelpText<"Same as --section-start with .text as the sectionname">; | |
| 45 | defm Ttext: Eq<"Ttext">, | |
| 46 | HelpText<"Same as --section-start with .text as the sectionname">; | |
| 40 | 47 | |
| 41 | 48 | def allow_multiple_definition: F<"allow-multiple-definition">, |
| 42 | 49 | HelpText<"Allow multiple definitions">; |
| ... | ... | @@ -44,6 +51,9 @@ def allow_multiple_definition: F<"allow-multiple-definition">, |
| 44 | 51 | def as_needed: F<"as-needed">, |
| 45 | 52 | HelpText<"Only set DT_NEEDED for shared libraries if used">; |
| 46 | 53 | |
| 54 | // -chroot doesn't have a help text because it is an internal option. | |
| 55 | def chroot: S<"chroot">; | |
| 56 | ||
| 47 | 57 | def color_diagnostics: F<"color-diagnostics">, |
| 48 | 58 | HelpText<"Use colors in diagnostics">; |
| 49 | 59 | |
| ... | ... | @@ -69,7 +79,7 @@ def discard_none: F<"discard-none">, |
| 69 | 79 | def dynamic_linker: S<"dynamic-linker">, |
| 70 | 80 | HelpText<"Which dynamic linker to use">; |
| 71 | 81 | |
| 72 | def dynamic_list: S<"dynamic-list">, | |
| 82 | defm dynamic_list: Eq<"dynamic-list">, | |
| 73 | 83 | HelpText<"Read a list of dynamic symbols">; |
| 74 | 84 | |
| 75 | 85 | def eh_frame_hdr: F<"eh-frame-hdr">, |
| ... | ... | @@ -83,37 +93,42 @@ def enable_new_dtags: F<"enable-new-dtags">, |
| 83 | 93 | def end_lib: F<"end-lib">, |
| 84 | 94 | HelpText<"End a grouping of objects that should be treated as if they were together in an archive">; |
| 85 | 95 | |
| 86 | def entry: S<"entry">, MetaVarName<"<entry>">, | |
| 87 | HelpText<"Name of entry point symbol">; | |
| 96 | defm entry: Eq<"entry">, HelpText<"Name of entry point symbol">, | |
| 97 | MetaVarName<"<entry>">; | |
| 88 | 98 | |
| 89 | def error_limit: S<"error-limit">, | |
| 99 | defm error_limit: Eq<"error-limit">, | |
| 90 | 100 | HelpText<"Maximum number of errors to emit before stopping (0 = no limit)">; |
| 91 | 101 | |
| 92 | 102 | def error_unresolved_symbols: F<"error-unresolved-symbols">, |
| 93 | 103 | HelpText<"Report unresolved symbols as errors">; |
| 94 | 104 | |
| 95 | def exclude_libs: S<"exclude-libs">, | |
| 105 | defm exclude_libs: Eq<"exclude-libs">, | |
| 96 | 106 | HelpText<"Exclude static libraries from automatic export">; |
| 97 | 107 | |
| 98 | 108 | def export_dynamic: F<"export-dynamic">, |
| 99 | 109 | HelpText<"Put symbols in the dynamic symbol table">; |
| 100 | 110 | |
| 101 | def export_dynamic_symbol: S<"export-dynamic-symbol">, | |
| 111 | defm export_dynamic_symbol: Eq<"export-dynamic-symbol">, | |
| 102 | 112 | HelpText<"Put a symbol in the dynamic symbol table">; |
| 103 | 113 | |
| 104 | 114 | def fatal_warnings: F<"fatal-warnings">, |
| 105 | 115 | HelpText<"Treat warnings as errors">; |
| 106 | 116 | |
| 107 | def filter: J<"filter=">, HelpText<"Set DT_FILTER field to the specified name">; | |
| 117 | defm filter: Eq<"filter">, | |
| 118 | HelpText<"Set DT_FILTER field to the specified name">; | |
| 108 | 119 | |
| 109 | def fini: S<"fini">, MetaVarName<"<symbol>">, | |
| 110 | HelpText<"Specify a finalizer function">; | |
| 120 | defm fini: Eq<"fini">, | |
| 121 | HelpText<"Specify a finalizer function">, MetaVarName<"<symbol>">; | |
| 122 | ||
| 123 | def fix_cortex_a53_843419: F<"fix-cortex-a53-843419">, | |
| 124 | HelpText<"Apply fixes for AArch64 Cortex-A53 erratum 843419">; | |
| 111 | 125 | |
| 112 | 126 | def full_shutdown : F<"full-shutdown">, |
| 113 | 127 | HelpText<"Perform a full shutdown instead of calling _exit">; |
| 114 | 128 | |
| 115 | def format: J<"format=">, MetaVarName<"<input-format>">, | |
| 116 | HelpText<"Change the input format of the inputs following this option">; | |
| 129 | defm format: Eq<"format">, | |
| 130 | HelpText<"Change the input format of the inputs following this option">, | |
| 131 | MetaVarName<"<input-format>">; | |
| 117 | 132 | |
| 118 | 133 | def gc_sections: F<"gc-sections">, |
| 119 | 134 | HelpText<"Enable garbage collection of unused sections">; |
| ... | ... | @@ -121,29 +136,35 @@ def gc_sections: F<"gc-sections">, |
| 121 | 136 | def gdb_index: F<"gdb-index">, |
| 122 | 137 | HelpText<"Generate .gdb_index section">; |
| 123 | 138 | |
| 124 | def hash_style: S<"hash-style">, | |
| 139 | defm hash_style: Eq<"hash-style">, | |
| 125 | 140 | HelpText<"Specify hash style (sysv, gnu or both)">; |
| 126 | 141 | |
| 127 | 142 | def help: F<"help">, HelpText<"Print option help">; |
| 128 | 143 | |
| 129 | 144 | def icf_all: F<"icf=all">, HelpText<"Enable identical code folding">; |
| 130 | 145 | |
| 146 | def icf_data: F<"icf-data">, | |
| 147 | HelpText<"Enable ICF to also fold identical read only data">; | |
| 148 | ||
| 131 | 149 | def icf_none: F<"icf=none">, HelpText<"Disable identical code folding">; |
| 132 | 150 | |
| 133 | def image_base : J<"image-base=">, HelpText<"Set the base address">; | |
| 151 | defm image_base : Eq<"image-base">, HelpText<"Set the base address">; | |
| 134 | 152 | |
| 135 | def init: S<"init">, MetaVarName<"<symbol>">, | |
| 136 | HelpText<"Specify an initializer function">; | |
| 153 | defm init: Eq<"init">, HelpText<"Specify an initializer function">, | |
| 154 | MetaVarName<"<symbol>">; | |
| 137 | 155 | |
| 138 | def l: JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">, | |
| 139 | HelpText<"Root name of library to use">; | |
| 156 | defm library: Eq<"library">, HelpText<"Root name of library to use">, | |
| 157 | MetaVarName<"<libName>">; | |
| 140 | 158 | |
| 141 | 159 | def lto_O: J<"lto-O">, MetaVarName<"<opt-level>">, |
| 142 | 160 | HelpText<"Optimization level for LTO">; |
| 143 | 161 | |
| 144 | 162 | def m: JoinedOrSeparate<["-"], "m">, HelpText<"Set target emulation">; |
| 145 | 163 | |
| 146 | def Map: JS<"Map">, HelpText<"Print a link map to the specified file">; | |
| 164 | defm Map: Eq<"Map">, HelpText<"Print a link map to the specified file">; | |
| 165 | ||
| 166 | def merge_exidx_entries: F<"merge-exidx-entries">, | |
| 167 | HelpText<"Enable merging .ARM.exidx entries">; | |
| 147 | 168 | |
| 148 | 169 | def nostdlib: F<"nostdlib">, |
| 149 | 170 | HelpText<"Only search directories specified on the command line">; |
| ... | ... | @@ -163,15 +184,24 @@ def no_demangle: F<"no-demangle">, |
| 163 | 184 | def no_dynamic_linker: F<"no-dynamic-linker">, |
| 164 | 185 | HelpText<"Inhibit output of .interp section">; |
| 165 | 186 | |
| 187 | def no_eh_frame_hdr: F<"no-eh-frame-hdr">, | |
| 188 | HelpText<"Do not create .eh_frame_hdr section">; | |
| 189 | ||
| 166 | 190 | def no_export_dynamic: F<"no-export-dynamic">; |
| 167 | 191 | def no_fatal_warnings: F<"no-fatal-warnings">; |
| 168 | 192 | |
| 169 | 193 | def no_gc_sections: F<"no-gc-sections">, |
| 170 | 194 | HelpText<"Disable garbage collection of unused sections">; |
| 171 | 195 | |
| 196 | def no_gdb_index: F<"no-gdb-index">, | |
| 197 | HelpText<"Do not generate .gdb_index section">; | |
| 198 | ||
| 172 | 199 | def no_gnu_unique: F<"no-gnu-unique">, |
| 173 | 200 | HelpText<"Disable STB_GNU_UNIQUE symbol binding">; |
| 174 | 201 | |
| 202 | def no_merge_exidx_entries: F<"no-merge-exidx-entries">, | |
| 203 | HelpText<"Disable merging .ARM.exidx entries">; | |
| 204 | ||
| 175 | 205 | def no_threads: F<"no-threads">, |
| 176 | 206 | HelpText<"Do not run the linker multi-threaded">; |
| 177 | 207 | |
| ... | ... | @@ -183,7 +213,14 @@ def noinhibit_exec: F<"noinhibit-exec">, |
| 183 | 213 | |
| 184 | 214 | def nopie: F<"nopie">, HelpText<"Do not create a position independent executable">; |
| 185 | 215 | |
| 186 | def no_rosegment: F<"no-rosegment">, HelpText<"Do not put read-only non-executable sections in their own segment">; | |
| 216 | def no_omagic: Flag<["--"], "no-omagic">, MetaVarName<"<magic>">, | |
| 217 | HelpText<"Do not set the text data sections to be writable">; | |
| 218 | ||
| 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">, | |
| 223 | HelpText<"Do not put read-only non-executable sections in their own segment">; | |
| 187 | 224 | |
| 188 | 225 | def no_undefined: F<"no-undefined">, |
| 189 | 226 | HelpText<"Report unresolved symbols even if the linker is creating a shared library">; |
| ... | ... | @@ -200,6 +237,12 @@ def oformat: Separate<["--"], "oformat">, MetaVarName<"<format>">, |
| 200 | 237 | def omagic: Flag<["--"], "omagic">, MetaVarName<"<magic>">, |
| 201 | 238 | HelpText<"Set the text and data sections to be readable and writable">; |
| 202 | 239 | |
| 240 | defm orphan_handling: Eq<"orphan-handling">, | |
| 241 | HelpText<"Control how orphan sections are handled when linker script used">; | |
| 242 | ||
| 243 | def pack_dyn_relocs_eq: J<"pack-dyn-relocs=">, MetaVarName<"<format>">, | |
| 244 | HelpText<"Pack dynamic relocations in the given format (none or android)">; | |
| 245 | ||
| 203 | 246 | def pie: F<"pie">, HelpText<"Create a position independent executable">; |
| 204 | 247 | |
| 205 | 248 | def print_gc_sections: F<"print-gc-sections">, |
| ... | ... | @@ -208,26 +251,28 @@ def print_gc_sections: F<"print-gc-sections">, |
| 208 | 251 | def print_map: F<"print-map">, |
| 209 | 252 | HelpText<"Print a link map to the standard output">; |
| 210 | 253 | |
| 211 | def reproduce: S<"reproduce">, | |
| 254 | defm reproduce: Eq<"reproduce">, | |
| 212 | 255 | HelpText<"Dump linker invocation and input files for debugging">; |
| 213 | 256 | |
| 214 | def rpath: S<"rpath">, HelpText<"Add a DT_RUNPATH to the output">; | |
| 257 | defm rpath: Eq<"rpath">, HelpText<"Add a DT_RUNPATH to the output">; | |
| 215 | 258 | |
| 216 | 259 | def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">; |
| 217 | 260 | |
| 218 | def retain_symbols_file: J<"retain-symbols-file=">, MetaVarName<"<file>">, | |
| 219 | HelpText<"Retain only the symbols listed in the file">; | |
| 261 | defm retain_symbols_file: Eq<"retain-symbols-file">, | |
| 262 | HelpText<"Retain only the symbols listed in the file">, | |
| 263 | MetaVarName<"<file>">; | |
| 220 | 264 | |
| 221 | def script: S<"script">, HelpText<"Read linker script">; | |
| 265 | defm script: Eq<"script">, HelpText<"Read linker script">; | |
| 222 | 266 | |
| 223 | 267 | def section_start: S<"section-start">, MetaVarName<"<address>">, |
| 224 | 268 | HelpText<"Set address of section">; |
| 225 | 269 | |
| 226 | 270 | def shared: F<"shared">, HelpText<"Build a shared object">; |
| 227 | 271 | |
| 228 | def soname: J<"soname=">, HelpText<"Set DT_SONAME">; | |
| 272 | defm soname: Eq<"soname">, HelpText<"Set DT_SONAME">; | |
| 229 | 273 | |
| 230 | def sort_section: S<"sort-section">, HelpText<"Specifies sections sorting rule when linkerscript is used">; | |
| 274 | defm sort_section: Eq<"sort-section">, | |
| 275 | HelpText<"Specifies sections sorting rule when linkerscript is used">; | |
| 231 | 276 | |
| 232 | 277 | def start_lib: F<"start-lib">, |
| 233 | 278 | HelpText<"Start a grouping of objects that should be treated as if they were together in an archive">; |
| ... | ... | @@ -239,27 +284,29 @@ def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">; |
| 239 | 284 | def symbol_ordering_file: S<"symbol-ordering-file">, |
| 240 | 285 | HelpText<"Layout sections in the order specified by symbol file">; |
| 241 | 286 | |
| 242 | def sysroot: J<"sysroot=">, HelpText<"Set the system root">; | |
| 287 | defm sysroot: Eq<"sysroot">, HelpText<"Set the system root">; | |
| 243 | 288 | |
| 244 | 289 | def target1_rel: F<"target1-rel">, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_REL32">; |
| 245 | 290 | |
| 246 | 291 | def target1_abs: F<"target1-abs">, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_ABS32">; |
| 247 | 292 | |
| 248 | def target2: J<"target2=">, MetaVarName<"<type>">, HelpText<"Interpret R_ARM_TARGET2 as <type>, where <type> is one of rel, abs, or got-rel">; | |
| 293 | defm target2: Eq<"target2">, | |
| 294 | HelpText<"Interpret R_ARM_TARGET2 as <type>, where <type> is one of rel, abs, or got-rel">, | |
| 295 | MetaVarName<"<type>">; | |
| 249 | 296 | |
| 250 | 297 | def threads: F<"threads">, HelpText<"Run the linker multi-threaded">; |
| 251 | 298 | |
| 252 | 299 | def trace: F<"trace">, HelpText<"Print the names of the input files">; |
| 253 | 300 | |
| 254 | def trace_symbol : S<"trace-symbol">, HelpText<"Trace references to symbols">; | |
| 301 | defm trace_symbol : Eq<"trace-symbol">, HelpText<"Trace references to symbols">; | |
| 255 | 302 | |
| 256 | def undefined: S<"undefined">, | |
| 303 | defm undefined: Eq<"undefined">, | |
| 257 | 304 | HelpText<"Force undefined symbol during linking">; |
| 258 | 305 | |
| 259 | def unresolved_symbols: J<"unresolved-symbols=">, | |
| 306 | defm unresolved_symbols: Eq<"unresolved-symbols">, | |
| 260 | 307 | HelpText<"Determine how to handle unresolved symbols">; |
| 261 | 308 | |
| 262 | def rsp_quoting: J<"rsp-quoting=">, | |
| 309 | defm rsp_quoting: Eq<"rsp-quoting">, | |
| 263 | 310 | HelpText<"Quoting style for response files. Values supported: windows|posix">; |
| 264 | 311 | |
| 265 | 312 | def v: Flag<["-"], "v">, HelpText<"Display the version number">; |
| ... | ... | @@ -268,8 +315,7 @@ def verbose: F<"verbose">, HelpText<"Verbose mode">; |
| 268 | 315 | |
| 269 | 316 | def version: F<"version">, HelpText<"Display the version number and exit">; |
| 270 | 317 | |
| 271 | def version_script: S<"version-script">, | |
| 272 | HelpText<"Read a version script">; | |
| 318 | defm version_script: Eq<"version-script">, HelpText<"Read a version script">; | |
| 273 | 319 | |
| 274 | 320 | def warn_common: F<"warn-common">, |
| 275 | 321 | HelpText<"Warn about duplicate common symbols">; |
| ... | ... | @@ -280,8 +326,8 @@ def warn_unresolved_symbols: F<"warn-unresolved-symbols">, |
| 280 | 326 | def whole_archive: F<"whole-archive">, |
| 281 | 327 | HelpText<"Force load of all members in a static library">; |
| 282 | 328 | |
| 283 | def wrap: S<"wrap">, MetaVarName<"<symbol>">, | |
| 284 | HelpText<"Use wrapper functions for symbol">; | |
| 329 | defm wrap: Eq<"wrap">, HelpText<"Use wrapper functions for symbol">, | |
| 330 | MetaVarName<"<symbol>">; | |
| 285 | 331 | |
| 286 | 332 | def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">, |
| 287 | 333 | HelpText<"Linker option extensions">; |
| ... | ... | @@ -293,60 +339,36 @@ def alias_Bdynamic_dy: F<"dy">, Alias<Bdynamic>; |
| 293 | 339 | def alias_Bstatic_dn: F<"dn">, Alias<Bstatic>; |
| 294 | 340 | def alias_Bstatic_non_shared: F<"non_shared">, Alias<Bstatic>; |
| 295 | 341 | def alias_Bstatic_static: F<"static">, Alias<Bstatic>; |
| 296 | def alias_L__library_path: J<"library-path=">, Alias<L>; | |
| 297 | 342 | def alias_define_common_d: Flag<["-"], "d">, Alias<define_common>; |
| 298 | 343 | def alias_define_common_dc: F<"dc">, Alias<define_common>; |
| 299 | 344 | def alias_define_common_dp: F<"dp">, Alias<define_common>; |
| 300 | def alias_defsym: S<"defsym">, Alias<defsym>; | |
| 301 | 345 | def alias_discard_all_x: Flag<["-"], "x">, Alias<discard_all>; |
| 302 | 346 | def alias_discard_locals_X: Flag<["-"], "X">, Alias<discard_locals>; |
| 303 | def alias_dynamic_list: J<"dynamic-list=">, Alias<dynamic_list>; | |
| 304 | 347 | def alias_emit_relocs: Flag<["-"], "q">, Alias<emit_relocs>; |
| 305 | 348 | def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>; |
| 306 | def alias_entry_entry: J<"entry=">, Alias<entry>; | |
| 307 | def alias_error_limit: J<"error-limit=">, Alias<error_limit>; | |
| 308 | def alias_exclude_libs: J<"exclude-libs=">, Alias<exclude_libs>; | |
| 309 | 349 | def alias_export_dynamic_E: Flag<["-"], "E">, Alias<export_dynamic>; |
| 310 | def alias_export_dynamic_symbol: J<"export-dynamic-symbol=">, | |
| 311 | Alias<export_dynamic_symbol>; | |
| 312 | 350 | def alias_filter: Separate<["-"], "F">, Alias<filter>; |
| 313 | def alias_fini_fini: J<"fini=">, Alias<fini>; | |
| 314 | 351 | def alias_format_b: S<"b">, Alias<format>; |
| 315 | def alias_hash_style_hash_style: J<"hash-style=">, Alias<hash_style>; | |
| 316 | def alias_init_init: J<"init=">, Alias<init>; | |
| 317 | def alias_l__library: J<"library=">, Alias<l>; | |
| 318 | def alias_Map_eq: J<"Map=">, Alias<Map>; | |
| 352 | def alias_library: JoinedOrSeparate<["-"], "l">, Alias<library>; | |
| 353 | def alias_library_path: JoinedOrSeparate<["-"], "L">, Alias<library_path>; | |
| 319 | 354 | def alias_omagic: Flag<["-"], "N">, Alias<omagic>; |
| 320 | 355 | def alias_o_output: Joined<["--"], "output=">, Alias<o>; |
| 321 | 356 | def alias_o_output2 : Separate<["--"], "output">, Alias<o>; |
| 322 | 357 | def alias_pie_pic_executable: F<"pic-executable">, Alias<pie>; |
| 323 | 358 | def alias_print_map_M: Flag<["-"], "M">, Alias<print_map>; |
| 324 | 359 | def alias_relocatable_r: Flag<["-"], "r">, Alias<relocatable>; |
| 325 | def alias_reproduce_eq: J<"reproduce=">, Alias<reproduce>; | |
| 326 | def alias_retain_symbols_file: S<"retain-symbols-file">, Alias<retain_symbols_file>; | |
| 327 | 360 | def alias_rpath_R: JoinedOrSeparate<["-"], "R">, Alias<rpath>; |
| 328 | def alias_rpath_rpath: J<"rpath=">, Alias<rpath>; | |
| 329 | 361 | def alias_script_T: JoinedOrSeparate<["-"], "T">, Alias<script>; |
| 330 | 362 | def alias_shared_Bshareable: F<"Bshareable">, Alias<shared>; |
| 331 | 363 | def alias_soname_h: JoinedOrSeparate<["-"], "h">, Alias<soname>; |
| 332 | def alias_soname_soname: S<"soname">, Alias<soname>; | |
| 333 | def alias_sort_section: J<"sort-section=">, Alias<sort_section>; | |
| 334 | def alias_script: J<"script=">, Alias<script>; | |
| 335 | 364 | def alias_strip_all: Flag<["-"], "s">, Alias<strip_all>; |
| 336 | 365 | def alias_strip_debug_S: Flag<["-"], "S">, Alias<strip_debug>; |
| 337 | def alias_Tbss: J<"Tbss=">, Alias<Tbss>; | |
| 338 | def alias_Tdata: J<"Tdata=">, Alias<Tdata>; | |
| 339 | 366 | def alias_trace: Flag<["-"], "t">, Alias<trace>; |
| 340 | def trace_trace_symbol_eq : J<"trace-symbol=">, Alias<trace_symbol>; | |
| 341 | 367 | def alias_trace_symbol_y : JoinedOrSeparate<["-"], "y">, Alias<trace_symbol>; |
| 342 | def alias_Ttext: J<"Ttext=">, Alias<Ttext>; | |
| 343 | 368 | def alias_Ttext_segment: S<"Ttext-segment">, Alias<Ttext>; |
| 344 | 369 | def alias_Ttext_segment_eq: J<"Ttext-segment=">, Alias<Ttext>; |
| 345 | def alias_undefined_eq: J<"undefined=">, Alias<undefined>; | |
| 346 | 370 | def alias_undefined_u: JoinedOrSeparate<["-"], "u">, Alias<undefined>; |
| 347 | def alias_version_script_eq: J<"version-script=">, Alias<version_script>; | |
| 348 | 371 | def alias_version_V: Flag<["-"], "V">, Alias<version>; |
| 349 | def alias_wrap_wrap: J<"wrap=">, Alias<wrap>; | |
| 350 | 372 | |
| 351 | 373 | // Our symbol resolution algorithm handles symbols in archive files differently |
| 352 | 374 | // than traditional linkers, so we don't need --start-group and --end-group. |
| ... | ... | @@ -369,6 +391,8 @@ def opt_remarks_filename: Separate<["--"], "opt-remarks-filename">, |
| 369 | 391 | HelpText<"YAML output file for optimization remarks">; |
| 370 | 392 | def opt_remarks_with_hotness: Flag<["--"], "opt-remarks-with-hotness">, |
| 371 | 393 | HelpText<"Include hotness informations in the optimization remarks file">; |
| 394 | defm plugin_opt: Eq<"plugin-opt">, | |
| 395 | HelpText<"specifies LTO options for compatibility with GNU linkers">; | |
| 372 | 396 | def save_temps: F<"save-temps">; |
| 373 | 397 | def thinlto_cache_dir: J<"thinlto-cache-dir=">, |
| 374 | 398 | HelpText<"Path to ThinLTO cached object file directory">; |
| ... | ... | @@ -385,18 +409,17 @@ def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">; |
| 385 | 409 | // --version output. |
| 386 | 410 | def plugin: S<"plugin">; |
| 387 | 411 | def plugin_eq: J<"plugin=">; |
| 388 | def plugin_opt: S<"plugin-opt">; | |
| 389 | def plugin_opt_eq: J<"plugin-opt=">; | |
| 390 | 412 | |
| 391 | 413 | // Options listed below are silently ignored for now for compatibility. |
| 392 | 414 | def allow_shlib_undefined: F<"allow-shlib-undefined">; |
| 393 | def cref: Flag<["--"], "cref">; | |
| 415 | def cref: F<"cref">; | |
| 394 | 416 | def detect_odr_violations: F<"detect-odr-violations">; |
| 395 | 417 | def g: Flag<["-"], "g">; |
| 418 | def long_plt: F<"long-plt">; | |
| 396 | 419 | def no_add_needed: F<"no-add-needed">; |
| 397 | 420 | def no_allow_shlib_undefined: F<"no-allow-shlib-undefined">; |
| 398 | def no_copy_dt_needed_entries: F<"no-copy-dt-needed-entries">, | |
| 399 | Alias<no_add_needed>; | |
| 421 | def no_copy_dt_needed_entries: F<"no-copy-dt-needed-entries">; | |
| 422 | def no_ctors_in_init_array: F<"no-ctors-in-init-array">; | |
| 400 | 423 | def no_keep_memory: F<"no-keep-memory">; |
| 401 | 424 | def no_mmap_output_file: F<"no-mmap-output-file">; |
| 402 | 425 | def no_warn_common: F<"no-warn-common">; |
| ... | ... | @@ -406,9 +429,9 @@ def rpath_link_eq: J<"rpath-link=">; |
| 406 | 429 | def sort_common: F<"sort-common">; |
| 407 | 430 | def stats: F<"stats">; |
| 408 | 431 | def warn_execstack: F<"warn-execstack">; |
| 432 | def warn_once: F<"warn-once">; | |
| 409 | 433 | def warn_shared_textrel: F<"warn-shared-textrel">; |
| 410 | 434 | def EB : F<"EB">; |
| 411 | 435 | def EL : F<"EL">; |
| 412 | 436 | def G: JoinedOrSeparate<["-"], "G">; |
| 413 | 437 | def Qy : F<"Qy">; |
| 414 |
deps/lld/ELF/OutputSections.cpp+318-161| ... | ... | @@ -10,13 +10,14 @@ |
| 10 | 10 | #include "OutputSections.h" |
| 11 | 11 | #include "Config.h" |
| 12 | 12 | #include "LinkerScript.h" |
| 13 | #include "Memory.h" | |
| 14 | 13 | #include "Strings.h" |
| 15 | 14 | #include "SymbolTable.h" |
| 16 | 15 | #include "SyntheticSections.h" |
| 17 | 16 | #include "Target.h" |
| 18 | #include "Threads.h" | |
| 17 | #include "lld/Common/Memory.h" | |
| 18 | #include "lld/Common/Threads.h" | |
| 19 | 19 | #include "llvm/BinaryFormat/Dwarf.h" |
| 20 | #include "llvm/Support/Compression.h" | |
| 20 | 21 | #include "llvm/Support/MD5.h" |
| 21 | 22 | #include "llvm/Support/MathExtras.h" |
| 22 | 23 | #include "llvm/Support/SHA1.h" |
| ... | ... | @@ -42,7 +43,6 @@ OutputSection *Out::InitArray; |
| 42 | 43 | OutputSection *Out::FiniArray; |
| 43 | 44 | |
| 44 | 45 | std::vector<OutputSection *> elf::OutputSections; |
| 45 | std::vector<OutputSectionCommand *> elf::OutputSectionCommands; | |
| 46 | 46 | |
| 47 | 47 | uint32_t OutputSection::getPhdrFlags() const { |
| 48 | 48 | uint32_t Ret = PF_R; |
| ... | ... | @@ -68,210 +68,367 @@ void OutputSection::writeHeaderTo(typename ELFT::Shdr *Shdr) { |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | 70 | OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags) |
| 71 | : SectionBase(Output, Name, Flags, /*Entsize*/ 0, /*Alignment*/ 1, Type, | |
| 71 | : BaseCommand(OutputSectionKind), | |
| 72 | SectionBase(Output, Name, Flags, /*Entsize*/ 0, /*Alignment*/ 1, Type, | |
| 72 | 73 | /*Info*/ 0, |
| 73 | 74 | /*Link*/ 0), |
| 74 | SectionIndex(INT_MAX) {} | |
| 75 | SectionIndex(INT_MAX) { | |
| 76 | Live = false; | |
| 77 | } | |
| 75 | 78 | |
| 76 | static uint64_t updateOffset(uint64_t Off, InputSection *S) { | |
| 77 | Off = alignTo(Off, S->Alignment); | |
| 78 | S->OutSecOff = Off; | |
| 79 | return Off + S->getSize(); | |
| 79 | // We allow sections of types listed below to merged into a | |
| 80 | // single progbits section. This is typically done by linker | |
| 81 | // scripts. Merging nobits and progbits will force disk space | |
| 82 | // to be allocated for nobits sections. Other ones don't require | |
| 83 | // any special treatment on top of progbits, so there doesn't | |
| 84 | // seem to be a harm in merging them. | |
| 85 | static bool canMergeToProgbits(unsigned Type) { | |
| 86 | return Type == SHT_NOBITS || Type == SHT_PROGBITS || Type == SHT_INIT_ARRAY || | |
| 87 | Type == SHT_PREINIT_ARRAY || Type == SHT_FINI_ARRAY || | |
| 88 | Type == SHT_NOTE; | |
| 80 | 89 | } |
| 81 | 90 | |
| 82 | void OutputSection::addSection(InputSection *S) { | |
| 83 | assert(S->Live); | |
| 84 | Sections.push_back(S); | |
| 85 | S->Parent = this; | |
| 86 | this->updateAlignment(S->Alignment); | |
| 91 | void OutputSection::addSection(InputSection *IS) { | |
| 92 | if (!Live) { | |
| 93 | // If IS is the first section to be added to this section, | |
| 94 | // initialize Type and Entsize from IS. | |
| 95 | Live = true; | |
| 96 | Type = IS->Type; | |
| 97 | Entsize = IS->Entsize; | |
| 98 | } else { | |
| 99 | // 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))) | |
| 101 | error("incompatible section flags for " + Name + "\n>>> " + toString(IS) + | |
| 102 | ": 0x" + utohexstr(IS->Flags) + "\n>>> output section " + Name + | |
| 103 | ": 0x" + utohexstr(Flags)); | |
| 104 | ||
| 105 | if (Type != IS->Type) { | |
| 106 | if (!canMergeToProgbits(Type) || !canMergeToProgbits(IS->Type)) | |
| 107 | error("section type mismatch for " + IS->Name + "\n>>> " + | |
| 108 | toString(IS) + ": " + | |
| 109 | getELFSectionTypeName(Config->EMachine, IS->Type) + | |
| 110 | "\n>>> output section " + Name + ": " + | |
| 111 | getELFSectionTypeName(Config->EMachine, Type)); | |
| 112 | Type = SHT_PROGBITS; | |
| 113 | } | |
| 114 | } | |
| 87 | 115 | |
| 88 | // The actual offsets will be computed by assignAddresses. For now, use | |
| 89 | // crude approximation so that it is at least easy for other code to know the | |
| 90 | // section order. It is also used to calculate the output section size early | |
| 91 | // for compressed debug sections. | |
| 92 | this->Size = updateOffset(Size, S); | |
| 116 | IS->Parent = this; | |
| 117 | Flags |= IS->Flags; | |
| 118 | Alignment = std::max(Alignment, IS->Alignment); | |
| 119 | IS->OutSecOff = Size++; | |
| 93 | 120 | |
| 94 | 121 | // If this section contains a table of fixed-size entries, sh_entsize |
| 95 | // holds the element size. Consequently, if this contains two or more | |
| 96 | // input sections, all of them must have the same sh_entsize. However, | |
| 97 | // you can put different types of input sections into one output | |
| 98 | // sectin by using linker scripts. I don't know what to do here. | |
| 99 | // Probably we sholuld handle that as an error. But for now we just | |
| 100 | // pick the largest sh_entsize. | |
| 101 | this->Entsize = std::max(this->Entsize, S->Entsize); | |
| 122 | // holds the element size. If it contains elements of different size we | |
| 123 | // set sh_entsize to 0. | |
| 124 | if (Entsize != IS->Entsize) | |
| 125 | Entsize = 0; | |
| 126 | ||
| 127 | if (!IS->Assigned) { | |
| 128 | IS->Assigned = true; | |
| 129 | if (SectionCommands.empty() || | |
| 130 | !isa<InputSectionDescription>(SectionCommands.back())) | |
| 131 | SectionCommands.push_back(make<InputSectionDescription>("")); | |
| 132 | auto *ISD = cast<InputSectionDescription>(SectionCommands.back()); | |
| 133 | ISD->Sections.push_back(IS); | |
| 134 | } | |
| 102 | 135 | } |
| 103 | 136 | |
| 104 | static SectionKey createKey(InputSectionBase *C, StringRef OutsecName) { | |
| 105 | // The ELF spec just says | |
| 106 | // ---------------------------------------------------------------- | |
| 107 | // In the first phase, input sections that match in name, type and | |
| 108 | // attribute flags should be concatenated into single sections. | |
| 109 | // ---------------------------------------------------------------- | |
| 110 | // | |
| 111 | // However, it is clear that at least some flags have to be ignored for | |
| 112 | // section merging. At the very least SHF_GROUP and SHF_COMPRESSED have to be | |
| 113 | // ignored. We should not have two output .text sections just because one was | |
| 114 | // in a group and another was not for example. | |
| 115 | // | |
| 116 | // It also seems that that wording was a late addition and didn't get the | |
| 117 | // necessary scrutiny. | |
| 118 | // | |
| 119 | // Merging sections with different flags is expected by some users. One | |
| 120 | // reason is that if one file has | |
| 121 | // | |
| 122 | // int *const bar __attribute__((section(".foo"))) = (int *)0; | |
| 123 | // | |
| 124 | // gcc with -fPIC will produce a read only .foo section. But if another | |
| 125 | // file has | |
| 126 | // | |
| 127 | // int zed; | |
| 128 | // int *const bar __attribute__((section(".foo"))) = (int *)&zed; | |
| 129 | // | |
| 130 | // gcc with -fPIC will produce a read write section. | |
| 131 | // | |
| 132 | // Last but not least, when using linker script the merge rules are forced by | |
| 133 | // the script. Unfortunately, linker scripts are name based. This means that | |
| 134 | // expressions like *(.foo*) can refer to multiple input sections with | |
| 135 | // different flags. We cannot put them in different output sections or we | |
| 136 | // would produce wrong results for | |
| 137 | // | |
| 138 | // start = .; *(.foo.*) end = .; *(.bar) | |
| 139 | // | |
| 140 | // and a mapping of .foo1 and .bar1 to one section and .foo2 and .bar2 to | |
| 141 | // another. The problem is that there is no way to layout those output | |
| 142 | // sections such that the .foo sections are the only thing between the start | |
| 143 | // and end symbols. | |
| 144 | // | |
| 145 | // Given the above issues, we instead merge sections by name and error on | |
| 146 | // incompatible types and flags. | |
| 147 | ||
| 148 | uint32_t Alignment = 0; | |
| 149 | uint64_t Flags = 0; | |
| 150 | if (Config->Relocatable && (C->Flags & SHF_MERGE)) { | |
| 151 | Alignment = std::max<uint64_t>(C->Alignment, C->Entsize); | |
| 152 | Flags = C->Flags & (SHF_MERGE | SHF_STRINGS); | |
| 153 | } | |
| 137 | void elf::sortByOrder(MutableArrayRef<InputSection *> In, | |
| 138 | std::function<int(InputSectionBase *S)> Order) { | |
| 139 | typedef std::pair<int, InputSection *> Pair; | |
| 140 | auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; }; | |
| 141 | ||
| 142 | std::vector<Pair> V; | |
| 143 | for (InputSection *S : In) | |
| 144 | V.push_back({Order(S), S}); | |
| 145 | std::stable_sort(V.begin(), V.end(), Comp); | |
| 154 | 146 | |
| 155 | return SectionKey{OutsecName, Flags, Alignment}; | |
| 147 | for (size_t I = 0; I < V.size(); ++I) | |
| 148 | In[I] = V[I].second; | |
| 156 | 149 | } |
| 157 | 150 | |
| 158 | OutputSectionFactory::OutputSectionFactory() {} | |
| 151 | uint64_t elf::getHeaderSize() { | |
| 152 | if (Config->OFormatBinary) | |
| 153 | return 0; | |
| 154 | return Out::ElfHeader->Size + Out::ProgramHeaders->Size; | |
| 155 | } | |
| 159 | 156 | |
| 160 | static uint64_t getIncompatibleFlags(uint64_t Flags) { | |
| 161 | return Flags & (SHF_ALLOC | SHF_TLS); | |
| 157 | bool OutputSection::classof(const BaseCommand *C) { | |
| 158 | return C->Kind == OutputSectionKind; | |
| 162 | 159 | } |
| 163 | 160 | |
| 164 | // We allow sections of types listed below to merged into a | |
| 165 | // single progbits section. This is typically done by linker | |
| 166 | // scripts. Merging nobits and progbits will force disk space | |
| 167 | // to be allocated for nobits sections. Other ones don't require | |
| 168 | // any special treatment on top of progbits, so there doesn't | |
| 169 | // seem to be a harm in merging them. | |
| 170 | static bool canMergeToProgbits(unsigned Type) { | |
| 171 | return Type == SHT_NOBITS || Type == SHT_PROGBITS || Type == SHT_INIT_ARRAY || | |
| 172 | Type == SHT_PREINIT_ARRAY || Type == SHT_FINI_ARRAY || | |
| 173 | Type == SHT_NOTE; | |
| 161 | void OutputSection::sort(std::function<int(InputSectionBase *S)> Order) { | |
| 162 | assert(Live); | |
| 163 | assert(SectionCommands.size() == 1); | |
| 164 | sortByOrder(cast<InputSectionDescription>(SectionCommands[0])->Sections, | |
| 165 | Order); | |
| 174 | 166 | } |
| 175 | 167 | |
| 176 | void elf::reportDiscarded(InputSectionBase *IS) { | |
| 177 | if (!Config->PrintGcSections) | |
| 178 | return; | |
| 179 | message("removing unused section from '" + IS->Name + "' in file '" + | |
| 180 | IS->File->getName() + "'"); | |
| 168 | // Fill [Buf, Buf + Size) with Filler. | |
| 169 | // This is used for linker script "=fillexp" command. | |
| 170 | static void fill(uint8_t *Buf, size_t Size, uint32_t Filler) { | |
| 171 | size_t I = 0; | |
| 172 | for (; I + 4 < Size; I += 4) | |
| 173 | memcpy(Buf + I, &Filler, 4); | |
| 174 | memcpy(Buf + I, &Filler, Size - I); | |
| 181 | 175 | } |
| 182 | 176 | |
| 183 | void OutputSectionFactory::addInputSec(InputSectionBase *IS, | |
| 184 | StringRef OutsecName) { | |
| 185 | // Sections with the SHT_GROUP attribute reach here only when the - r option | |
| 186 | // is given. Such sections define "section groups", and InputFiles.cpp has | |
| 187 | // dedup'ed section groups by their signatures. For the -r, we want to pass | |
| 188 | // through all SHT_GROUP sections without merging them because merging them | |
| 189 | // creates broken section contents. | |
| 190 | if (IS->Type == SHT_GROUP) { | |
| 191 | OutputSection *Out = nullptr; | |
| 192 | addInputSec(IS, OutsecName, Out); | |
| 193 | return; | |
| 194 | } | |
| 177 | // Compress section contents if this section contains debug info. | |
| 178 | template <class ELFT> void OutputSection::maybeCompress() { | |
| 179 | typedef typename ELFT::Chdr Elf_Chdr; | |
| 195 | 180 | |
| 196 | // Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have | |
| 197 | // relocation sections .rela.foo and .rela.bar for example. Most tools do | |
| 198 | // not allow multiple REL[A] sections for output section. Hence we | |
| 199 | // should combine these relocation sections into single output. | |
| 200 | // We skip synthetic sections because it can be .rela.dyn/.rela.plt or any | |
| 201 | // other REL[A] sections created by linker itself. | |
| 202 | if (!isa<SyntheticSection>(IS) && | |
| 203 | (IS->Type == SHT_REL || IS->Type == SHT_RELA)) { | |
| 204 | auto *Sec = cast<InputSection>(IS); | |
| 205 | OutputSection *Out = Sec->getRelocatedSection()->getOutputSection(); | |
| 206 | addInputSec(IS, OutsecName, Out->RelocationSection); | |
| 181 | // Compress only DWARF debug sections. | |
| 182 | if (!Config->CompressDebugSections || (Flags & SHF_ALLOC) || | |
| 183 | !Name.startswith(".debug_")) | |
| 207 | 184 | return; |
| 208 | } | |
| 209 | 185 | |
| 210 | SectionKey Key = createKey(IS, OutsecName); | |
| 211 | OutputSection *&Sec = Map[Key]; | |
| 212 | addInputSec(IS, OutsecName, Sec); | |
| 186 | // Create a section header. | |
| 187 | ZDebugHeader.resize(sizeof(Elf_Chdr)); | |
| 188 | auto *Hdr = reinterpret_cast<Elf_Chdr *>(ZDebugHeader.data()); | |
| 189 | Hdr->ch_type = ELFCOMPRESS_ZLIB; | |
| 190 | Hdr->ch_size = Size; | |
| 191 | Hdr->ch_addralign = Alignment; | |
| 192 | ||
| 193 | // Write section contents to a temporary buffer and compress it. | |
| 194 | std::vector<uint8_t> Buf(Size); | |
| 195 | writeTo<ELFT>(Buf.data()); | |
| 196 | if (Error E = zlib::compress(toStringRef(Buf), CompressedData)) | |
| 197 | fatal("compress failed: " + llvm::toString(std::move(E))); | |
| 198 | ||
| 199 | // Update section headers. | |
| 200 | Size = sizeof(Elf_Chdr) + CompressedData.size(); | |
| 201 | Flags |= SHF_COMPRESSED; | |
| 213 | 202 | } |
| 214 | 203 | |
| 215 | void OutputSectionFactory::addInputSec(InputSectionBase *IS, | |
| 216 | StringRef OutsecName, | |
| 217 | OutputSection *&Sec) { | |
| 218 | if (!IS->Live) { | |
| 219 | reportDiscarded(IS); | |
| 204 | static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) { | |
| 205 | if (Size == 1) | |
| 206 | *Buf = Data; | |
| 207 | else if (Size == 2) | |
| 208 | write16(Buf, Data, Config->Endianness); | |
| 209 | else if (Size == 4) | |
| 210 | write32(Buf, Data, Config->Endianness); | |
| 211 | else if (Size == 8) | |
| 212 | write64(Buf, Data, Config->Endianness); | |
| 213 | else | |
| 214 | llvm_unreachable("unsupported Size argument"); | |
| 215 | } | |
| 216 | ||
| 217 | template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) { | |
| 218 | if (Type == SHT_NOBITS) | |
| 219 | return; | |
| 220 | ||
| 221 | Loc = Buf; | |
| 222 | ||
| 223 | // If -compress-debug-section is specified and if this is a debug seciton, | |
| 224 | // we've already compressed section contents. If that's the case, | |
| 225 | // just write it down. | |
| 226 | if (!CompressedData.empty()) { | |
| 227 | memcpy(Buf, ZDebugHeader.data(), ZDebugHeader.size()); | |
| 228 | memcpy(Buf + ZDebugHeader.size(), CompressedData.data(), | |
| 229 | CompressedData.size()); | |
| 220 | 230 | return; |
| 221 | 231 | } |
| 222 | 232 | |
| 223 | if (Sec) { | |
| 224 | if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags)) | |
| 225 | error("incompatible section flags for " + Sec->Name + "\n>>> " + | |
| 226 | toString(IS) + ": 0x" + utohexstr(IS->Flags) + | |
| 227 | "\n>>> output section " + Sec->Name + ": 0x" + | |
| 228 | utohexstr(Sec->Flags)); | |
| 229 | if (Sec->Type != IS->Type) { | |
| 230 | if (canMergeToProgbits(Sec->Type) && canMergeToProgbits(IS->Type)) | |
| 231 | Sec->Type = SHT_PROGBITS; | |
| 233 | // Write leading padding. | |
| 234 | std::vector<InputSection *> Sections; | |
| 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(); | |
| 241 | if (Filler) | |
| 242 | fill(Buf, Sections.empty() ? Size : Sections[0]->OutSecOff, Filler); | |
| 243 | ||
| 244 | parallelForEachN(0, Sections.size(), [&](size_t I) { | |
| 245 | InputSection *IS = Sections[I]; | |
| 246 | IS->writeTo<ELFT>(Buf); | |
| 247 | ||
| 248 | // Fill gaps between sections. | |
| 249 | if (Filler) { | |
| 250 | uint8_t *Start = Buf + IS->OutSecOff + IS->getSize(); | |
| 251 | uint8_t *End; | |
| 252 | if (I + 1 == Sections.size()) | |
| 253 | End = Buf + Size; | |
| 232 | 254 | else |
| 233 | error("section type mismatch for " + IS->Name + "\n>>> " + | |
| 234 | toString(IS) + ": " + | |
| 235 | getELFSectionTypeName(Config->EMachine, IS->Type) + | |
| 236 | "\n>>> output section " + Sec->Name + ": " + | |
| 237 | getELFSectionTypeName(Config->EMachine, Sec->Type)); | |
| 255 | End = Buf + Sections[I + 1]->OutSecOff; | |
| 256 | fill(Start, End - Start, Filler); | |
| 238 | 257 | } |
| 239 | Sec->Flags |= IS->Flags; | |
| 240 | } else { | |
| 241 | Sec = make<OutputSection>(OutsecName, IS->Type, IS->Flags); | |
| 242 | OutputSections.push_back(Sec); | |
| 258 | }); | |
| 259 | ||
| 260 | // Linker scripts may have BYTE()-family commands with which you | |
| 261 | // can write arbitrary bytes to the output. Process them if any. | |
| 262 | for (BaseCommand *Base : SectionCommands) | |
| 263 | if (auto *Data = dyn_cast<ByteCommand>(Base)) | |
| 264 | writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size); | |
| 265 | } | |
| 266 | ||
| 267 | template <class ELFT> | |
| 268 | static void finalizeShtGroup(OutputSection *OS, | |
| 269 | InputSection *Section) { | |
| 270 | assert(Config->Relocatable); | |
| 271 | ||
| 272 | // sh_link field for SHT_GROUP sections should contain the section index of | |
| 273 | // the symbol table. | |
| 274 | OS->Link = InX::SymTab->getParent()->SectionIndex; | |
| 275 | ||
| 276 | // sh_info then contain index of an entry in symbol table section which | |
| 277 | // provides signature of the section group. | |
| 278 | ObjFile<ELFT> *Obj = Section->getFile<ELFT>(); | |
| 279 | ArrayRef<Symbol *> Symbols = Obj->getSymbols(); | |
| 280 | OS->Info = InX::SymTab->getSymbolIndex(Symbols[Section->Info]); | |
| 281 | } | |
| 282 | ||
| 283 | template <class ELFT> void OutputSection::finalize() { | |
| 284 | InputSection *First = nullptr; | |
| 285 | for (BaseCommand *Base : SectionCommands) { | |
| 286 | if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) { | |
| 287 | if (ISD->Sections.empty()) | |
| 288 | continue; | |
| 289 | if (First == nullptr) | |
| 290 | First = ISD->Sections.front(); | |
| 291 | } | |
| 292 | if (isa<ByteCommand>(Base) && Type == SHT_NOBITS) | |
| 293 | Type = SHT_PROGBITS; | |
| 294 | } | |
| 295 | ||
| 296 | if (Flags & SHF_LINK_ORDER) { | |
| 297 | // We must preserve the link order dependency of sections with the | |
| 298 | // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We | |
| 299 | // need to translate the InputSection sh_link to the OutputSection sh_link, | |
| 300 | // all InputSections in the OutputSection have the same dependency. | |
| 301 | if (auto *D = First->getLinkOrderDep()) | |
| 302 | Link = D->getParent()->SectionIndex; | |
| 303 | } | |
| 304 | ||
| 305 | if (Type == SHT_GROUP) { | |
| 306 | finalizeShtGroup<ELFT>(this, First); | |
| 307 | return; | |
| 243 | 308 | } |
| 244 | 309 | |
| 245 | Sec->addSection(cast<InputSection>(IS)); | |
| 310 | if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL)) | |
| 311 | return; | |
| 312 | ||
| 313 | if (isa<SyntheticSection>(First)) | |
| 314 | return; | |
| 315 | ||
| 316 | Link = InX::SymTab->getParent()->SectionIndex; | |
| 317 | // sh_info for SHT_REL[A] sections should contain the section header index of | |
| 318 | // the section to which the relocation applies. | |
| 319 | InputSectionBase *S = First->getRelocatedSection(); | |
| 320 | Info = S->getOutputSection()->SectionIndex; | |
| 321 | Flags |= SHF_INFO_LINK; | |
| 322 | } | |
| 323 | ||
| 324 | // Returns true if S matches /Filename.?\.o$/. | |
| 325 | static bool isCrtBeginEnd(StringRef S, StringRef Filename) { | |
| 326 | if (!S.endswith(".o")) | |
| 327 | return false; | |
| 328 | S = S.drop_back(2); | |
| 329 | if (S.endswith(Filename)) | |
| 330 | return true; | |
| 331 | return !S.empty() && S.drop_back().endswith(Filename); | |
| 246 | 332 | } |
| 247 | 333 | |
| 248 | OutputSectionFactory::~OutputSectionFactory() {} | |
| 334 | static bool isCrtbegin(StringRef S) { return isCrtBeginEnd(S, "crtbegin"); } | |
| 335 | static bool isCrtend(StringRef S) { return isCrtBeginEnd(S, "crtend"); } | |
| 249 | 336 | |
| 250 | SectionKey DenseMapInfo<SectionKey>::getEmptyKey() { | |
| 251 | return SectionKey{DenseMapInfo<StringRef>::getEmptyKey(), 0, 0}; | |
| 337 | // .ctors and .dtors are sorted by this priority from highest to lowest. | |
| 338 | // | |
| 339 | // 1. The section was contained in crtbegin (crtbegin contains | |
| 340 | // some sentinel value in its .ctors and .dtors so that the runtime | |
| 341 | // can find the beginning of the sections.) | |
| 342 | // | |
| 343 | // 2. The section has an optional priority value in the form of ".ctors.N" | |
| 344 | // or ".dtors.N" where N is a number. Unlike .{init,fini}_array, | |
| 345 | // they are compared as string rather than number. | |
| 346 | // | |
| 347 | // 3. The section is just ".ctors" or ".dtors". | |
| 348 | // | |
| 349 | // 4. The section was contained in crtend, which contains an end marker. | |
| 350 | // | |
| 351 | // In an ideal world, we don't need this function because .init_array and | |
| 352 | // .ctors are duplicate features (and .init_array is newer.) However, there | |
| 353 | // are too many real-world use cases of .ctors, so we had no choice to | |
| 354 | // support that with this rather ad-hoc semantics. | |
| 355 | static bool compCtors(const InputSection *A, const InputSection *B) { | |
| 356 | bool BeginA = isCrtbegin(A->File->getName()); | |
| 357 | bool BeginB = isCrtbegin(B->File->getName()); | |
| 358 | if (BeginA != BeginB) | |
| 359 | return BeginA; | |
| 360 | bool EndA = isCrtend(A->File->getName()); | |
| 361 | bool EndB = isCrtend(B->File->getName()); | |
| 362 | if (EndA != EndB) | |
| 363 | return EndB; | |
| 364 | StringRef X = A->Name; | |
| 365 | StringRef Y = B->Name; | |
| 366 | assert(X.startswith(".ctors") || X.startswith(".dtors")); | |
| 367 | assert(Y.startswith(".ctors") || Y.startswith(".dtors")); | |
| 368 | X = X.substr(6); | |
| 369 | Y = Y.substr(6); | |
| 370 | if (X.empty() && Y.empty()) | |
| 371 | return false; | |
| 372 | return X < Y; | |
| 252 | 373 | } |
| 253 | 374 | |
| 254 | SectionKey DenseMapInfo<SectionKey>::getTombstoneKey() { | |
| 255 | return SectionKey{DenseMapInfo<StringRef>::getTombstoneKey(), 0, 0}; | |
| 375 | // Sorts input sections by the special rules for .ctors and .dtors. | |
| 376 | // Unfortunately, the rules are different from the one for .{init,fini}_array. | |
| 377 | // Read the comment above. | |
| 378 | void OutputSection::sortCtorsDtors() { | |
| 379 | assert(SectionCommands.size() == 1); | |
| 380 | auto *ISD = cast<InputSectionDescription>(SectionCommands[0]); | |
| 381 | std::stable_sort(ISD->Sections.begin(), ISD->Sections.end(), compCtors); | |
| 256 | 382 | } |
| 257 | 383 | |
| 258 | unsigned DenseMapInfo<SectionKey>::getHashValue(const SectionKey &Val) { | |
| 259 | return hash_combine(Val.Name, Val.Flags, Val.Alignment); | |
| 384 | // If an input string is in the form of "foo.N" where N is a number, | |
| 385 | // return N. Otherwise, returns 65536, which is one greater than the | |
| 386 | // lowest priority. | |
| 387 | int elf::getPriority(StringRef S) { | |
| 388 | size_t Pos = S.rfind('.'); | |
| 389 | if (Pos == StringRef::npos) | |
| 390 | return 65536; | |
| 391 | int V; | |
| 392 | if (!to_integer(S.substr(Pos + 1), V, 10)) | |
| 393 | return 65536; | |
| 394 | return V; | |
| 260 | 395 | } |
| 261 | 396 | |
| 262 | bool DenseMapInfo<SectionKey>::isEqual(const SectionKey &LHS, | |
| 263 | const SectionKey &RHS) { | |
| 264 | return DenseMapInfo<StringRef>::isEqual(LHS.Name, RHS.Name) && | |
| 265 | LHS.Flags == RHS.Flags && LHS.Alignment == RHS.Alignment; | |
| 397 | // 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 | // We want to keep the original order if the priorities are the same | |
| 400 | // because the compiler keeps the original initialization order in a | |
| 401 | // translation unit and we need to respect that. | |
| 402 | // For more detail, read the section of the GCC's manual about init_priority. | |
| 403 | void OutputSection::sortInitFini() { | |
| 404 | // Sort sections by priority. | |
| 405 | sort([](InputSectionBase *S) { return getPriority(S->Name); }); | |
| 266 | 406 | } |
| 267 | 407 | |
| 268 | uint64_t elf::getHeaderSize() { | |
| 269 | if (Config->OFormatBinary) | |
| 270 | return 0; | |
| 271 | return Out::ElfHeader->Size + Out::ProgramHeaders->Size; | |
| 408 | uint32_t OutputSection::getFiller() { | |
| 409 | if (Filler) | |
| 410 | return *Filler; | |
| 411 | if (Flags & SHF_EXECINSTR) | |
| 412 | return Target->TrapInstr; | |
| 413 | return 0; | |
| 272 | 414 | } |
| 273 | 415 | |
| 274 | 416 | template void OutputSection::writeHeaderTo<ELF32LE>(ELF32LE::Shdr *Shdr); |
| 275 | 417 | template void OutputSection::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr); |
| 276 | 418 | template void OutputSection::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr); |
| 277 | 419 | template void OutputSection::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr); |
| 420 | ||
| 421 | template void OutputSection::writeTo<ELF32LE>(uint8_t *Buf); | |
| 422 | template void OutputSection::writeTo<ELF32BE>(uint8_t *Buf); | |
| 423 | template void OutputSection::writeTo<ELF64LE>(uint8_t *Buf); | |
| 424 | template void OutputSection::writeTo<ELF64BE>(uint8_t *Buf); | |
| 425 | ||
| 426 | template void OutputSection::maybeCompress<ELF32LE>(); | |
| 427 | template void OutputSection::maybeCompress<ELF32BE>(); | |
| 428 | template void OutputSection::maybeCompress<ELF64LE>(); | |
| 429 | template void OutputSection::maybeCompress<ELF64BE>(); | |
| 430 | ||
| 431 | template void OutputSection::finalize<ELF32LE>(); | |
| 432 | template void OutputSection::finalize<ELF32BE>(); | |
| 433 | template void OutputSection::finalize<ELF64LE>(); | |
| 434 | template void OutputSection::finalize<ELF64BE>(); |
deps/lld/ELF/OutputSections.h+57-57| ... | ... | @@ -12,9 +12,10 @@ |
| 12 | 12 | |
| 13 | 13 | #include "Config.h" |
| 14 | 14 | #include "InputSection.h" |
| 15 | #include "LinkerScript.h" | |
| 15 | 16 | #include "Relocations.h" |
| 16 | 17 | |
| 17 | #include "lld/Core/LLVM.h" | |
| 18 | #include "lld/Common/LLVM.h" | |
| 18 | 19 | #include "llvm/MC/StringTableBuilder.h" |
| 19 | 20 | #include "llvm/Object/ELF.h" |
| 20 | 21 | |
| ... | ... | @@ -22,23 +23,23 @@ namespace lld { |
| 22 | 23 | namespace elf { |
| 23 | 24 | |
| 24 | 25 | struct PhdrEntry; |
| 25 | class SymbolBody; | |
| 26 | class Symbol; | |
| 26 | 27 | struct EhSectionPiece; |
| 27 | 28 | class EhInputSection; |
| 28 | 29 | class InputSection; |
| 29 | 30 | class InputSectionBase; |
| 30 | 31 | class MergeInputSection; |
| 31 | 32 | class OutputSection; |
| 32 | template <class ELFT> class ObjectFile; | |
| 33 | template <class ELFT> class ObjFile; | |
| 33 | 34 | template <class ELFT> class SharedFile; |
| 34 | 35 | class SharedSymbol; |
| 35 | class DefinedRegular; | |
| 36 | class Defined; | |
| 36 | 37 | |
| 37 | 38 | // This represents a section in an output file. |
| 38 | 39 | // It is composed of multiple InputSections. |
| 39 | 40 | // The writer creates multiple OutputSections and assign them unique, |
| 40 | 41 | // non-overlapping file offsets and VAs. |
| 41 | class OutputSection final : public SectionBase { | |
| 42 | class OutputSection final : public BaseCommand, public SectionBase { | |
| 42 | 43 | public: |
| 43 | 44 | OutputSection(StringRef Name, uint32_t Type, uint64_t Flags); |
| 44 | 45 | |
| ... | ... | @@ -46,7 +47,9 @@ public: |
| 46 | 47 | return S->kind() == SectionBase::Output; |
| 47 | 48 | } |
| 48 | 49 | |
| 49 | uint64_t getLMA() const { return Addr + LMAOffset; } | |
| 50 | static bool classof(const BaseCommand *C); | |
| 51 | ||
| 52 | uint64_t getLMA() const { return PtLoad ? Addr + PtLoad->LMAOffset : Addr; } | |
| 50 | 53 | template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr); |
| 51 | 54 | |
| 52 | 55 | unsigned SectionIndex; |
| ... | ... | @@ -54,42 +57,69 @@ public: |
| 54 | 57 | |
| 55 | 58 | uint32_t getPhdrFlags() const; |
| 56 | 59 | |
| 57 | void updateAlignment(uint32_t Val) { | |
| 58 | if (Val > Alignment) | |
| 59 | Alignment = Val; | |
| 60 | } | |
| 61 | ||
| 62 | // Pointer to the first section in PT_LOAD segment, which this section | |
| 63 | // also resides in. This field is used to correctly compute file offset | |
| 64 | // of a section. When two sections share the same load segment, difference | |
| 65 | // between their file offsets should be equal to difference between their | |
| 66 | // virtual addresses. To compute some section offset we use the following | |
| 67 | // formula: Off = Off_first + VA - VA_first. | |
| 68 | OutputSection *FirstInPtLoad = nullptr; | |
| 60 | // Pointer to the PT_LOAD segment, which this section resides in. This field | |
| 61 | // is used to correctly compute file offset of a section. When two sections | |
| 62 | // share the same load segment, difference between their file offsets should | |
| 63 | // be equal to difference between their virtual addresses. To compute some | |
| 64 | // section offset we use the following formula: Off = Off_first + VA - | |
| 65 | // VA_first, where Off_first and VA_first is file offset and VA of first | |
| 66 | // section in PT_LOAD. | |
| 67 | PhdrEntry *PtLoad = nullptr; | |
| 69 | 68 | |
| 70 | 69 | // Pointer to a relocation section for this section. Usually nullptr because |
| 71 | 70 | // we consume relocations, but if --emit-relocs is specified (which is rare), |
| 72 | 71 | // it may have a non-null value. |
| 73 | 72 | OutputSection *RelocationSection = nullptr; |
| 74 | 73 | |
| 75 | // The following fields correspond to Elf_Shdr members. | |
| 74 | // Initially this field is the number of InputSections that have been added to | |
| 75 | // the OutputSection so far. Later on, after a call to assignAddresses, it | |
| 76 | // corresponds to the Elf_Shdr member. | |
| 76 | 77 | uint64_t Size = 0; |
| 78 | ||
| 79 | // The following fields correspond to Elf_Shdr members. | |
| 77 | 80 | uint64_t Offset = 0; |
| 78 | uint64_t LMAOffset = 0; | |
| 79 | 81 | uint64_t Addr = 0; |
| 80 | 82 | uint32_t ShName = 0; |
| 81 | 83 | |
| 82 | void addSection(InputSection *S); | |
| 83 | std::vector<InputSection *> Sections; | |
| 84 | void addSection(InputSection *IS); | |
| 84 | 85 | |
| 86 | // Location in the output buffer. | |
| 87 | uint8_t *Loc = nullptr; | |
| 88 | ||
| 89 | // The following members are normally only used in linker scripts. | |
| 90 | MemoryRegion *MemRegion = nullptr; | |
| 91 | MemoryRegion *LMARegion = nullptr; | |
| 92 | Expr AddrExpr; | |
| 93 | Expr AlignExpr; | |
| 94 | Expr LMAExpr; | |
| 95 | Expr SubalignExpr; | |
| 96 | std::vector<BaseCommand *> SectionCommands; | |
| 97 | std::vector<StringRef> Phdrs; | |
| 98 | llvm::Optional<uint32_t> Filler; | |
| 99 | ConstraintKind Constraint = ConstraintKind::NoConstraint; | |
| 100 | std::string Location; | |
| 101 | std::string MemoryRegionName; | |
| 102 | std::string LMARegionName; | |
| 103 | bool Noload = false; | |
| 104 | ||
| 105 | template <class ELFT> void finalize(); | |
| 106 | template <class ELFT> void writeTo(uint8_t *Buf); | |
| 107 | template <class ELFT> void maybeCompress(); | |
| 108 | ||
| 109 | void sort(std::function<int(InputSectionBase *S)> Order); | |
| 110 | void sortInitFini(); | |
| 111 | void sortCtorsDtors(); | |
| 112 | ||
| 113 | private: | |
| 85 | 114 | // Used for implementation of --compress-debug-sections option. |
| 86 | 115 | std::vector<uint8_t> ZDebugHeader; |
| 87 | 116 | llvm::SmallVector<char, 1> CompressedData; |
| 88 | 117 | |
| 89 | // Location in the output buffer. | |
| 90 | uint8_t *Loc = nullptr; | |
| 118 | uint32_t getFiller(); | |
| 91 | 119 | }; |
| 92 | 120 | |
| 121 | int getPriority(StringRef S); | |
| 122 | ||
| 93 | 123 | // All output sections that are handled by the linker specially are |
| 94 | 124 | // globally accessible. Writer initializes them, so don't use them |
| 95 | 125 | // until Writer is initialized. |
| ... | ... | @@ -106,47 +136,17 @@ struct Out { |
| 106 | 136 | static OutputSection *FiniArray; |
| 107 | 137 | }; |
| 108 | 138 | |
| 109 | struct SectionKey { | |
| 110 | StringRef Name; | |
| 111 | uint64_t Flags; | |
| 112 | uint32_t Alignment; | |
| 113 | }; | |
| 114 | 139 | } // namespace elf |
| 115 | 140 | } // namespace lld |
| 116 | namespace llvm { | |
| 117 | template <> struct DenseMapInfo<lld::elf::SectionKey> { | |
| 118 | static lld::elf::SectionKey getEmptyKey(); | |
| 119 | static lld::elf::SectionKey getTombstoneKey(); | |
| 120 | static unsigned getHashValue(const lld::elf::SectionKey &Val); | |
| 121 | static bool isEqual(const lld::elf::SectionKey &LHS, | |
| 122 | const lld::elf::SectionKey &RHS); | |
| 123 | }; | |
| 124 | } // namespace llvm | |
| 141 | ||
| 125 | 142 | namespace lld { |
| 126 | 143 | namespace elf { |
| 127 | 144 | |
| 128 | // This class knows how to create an output section for a given | |
| 129 | // input section. Output section type is determined by various | |
| 130 | // factors, including input section's sh_flags, sh_type and | |
| 131 | // linker scripts. | |
| 132 | class OutputSectionFactory { | |
| 133 | public: | |
| 134 | OutputSectionFactory(); | |
| 135 | ~OutputSectionFactory(); | |
| 136 | ||
| 137 | void addInputSec(InputSectionBase *IS, StringRef OutsecName); | |
| 138 | void addInputSec(InputSectionBase *IS, StringRef OutsecName, | |
| 139 | OutputSection *&Sec); | |
| 140 | ||
| 141 | private: | |
| 142 | llvm::SmallDenseMap<SectionKey, OutputSection *> Map; | |
| 143 | }; | |
| 144 | ||
| 145 | 145 | uint64_t getHeaderSize(); |
| 146 | void reportDiscarded(InputSectionBase *IS); | |
| 146 | void sortByOrder(llvm::MutableArrayRef<InputSection *> In, | |
| 147 | std::function<int(InputSectionBase *S)> Order); | |
| 147 | 148 | |
| 148 | 149 | extern std::vector<OutputSection *> OutputSections; |
| 149 | extern std::vector<OutputSectionCommand *> OutputSectionCommands; | |
| 150 | 150 | } // namespace elf |
| 151 | 151 | } // namespace lld |
| 152 | 152 |
deps/lld/ELF/Relocations.cpp+718-437| ... | ... | @@ -44,13 +44,14 @@ |
| 44 | 44 | #include "Relocations.h" |
| 45 | 45 | #include "Config.h" |
| 46 | 46 | #include "LinkerScript.h" |
| 47 | #include "Memory.h" | |
| 48 | 47 | #include "OutputSections.h" |
| 49 | 48 | #include "Strings.h" |
| 50 | 49 | #include "SymbolTable.h" |
| 50 | #include "Symbols.h" | |
| 51 | 51 | #include "SyntheticSections.h" |
| 52 | 52 | #include "Target.h" |
| 53 | 53 | #include "Thunks.h" |
| 54 | #include "lld/Common/Memory.h" | |
| 54 | 55 | |
| 55 | 56 | #include "llvm/Support/Endian.h" |
| 56 | 57 | #include "llvm/Support/raw_ostream.h" |
| ... | ... | @@ -69,31 +70,35 @@ using namespace lld::elf; |
| 69 | 70 | // >>> defined in /home/alice/src/foo.o |
| 70 | 71 | // >>> referenced by bar.c:12 (/home/alice/src/bar.c:12) |
| 71 | 72 | // >>> /home/alice/src/bar.o:(.text+0x1) |
| 72 | template <class ELFT> | |
| 73 | static std::string getLocation(InputSectionBase &S, const SymbolBody &Sym, | |
| 73 | static std::string getLocation(InputSectionBase &S, const Symbol &Sym, | |
| 74 | 74 | uint64_t Off) { |
| 75 | 75 | std::string Msg = |
| 76 | 76 | "\n>>> defined in " + toString(Sym.File) + "\n>>> referenced by "; |
| 77 | std::string Src = S.getSrcMsg<ELFT>(Off); | |
| 77 | std::string Src = S.getSrcMsg(Sym, Off); | |
| 78 | 78 | if (!Src.empty()) |
| 79 | 79 | Msg += Src + "\n>>> "; |
| 80 | return Msg + S.getObjMsg<ELFT>(Off); | |
| 80 | return Msg + S.getObjMsg(Off); | |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | static bool isPreemptible(const SymbolBody &Body, uint32_t Type) { | |
| 84 | // In case of MIPS GP-relative relocations always resolve to a definition | |
| 85 | // in a regular input file, ignoring the one-definition rule. So we, | |
| 86 | // for example, should not attempt to create a dynamic relocation even | |
| 87 | // if the target symbol is preemptible. There are two two MIPS GP-relative | |
| 88 | // relocations R_MIPS_GPREL16 and R_MIPS_GPREL32. But only R_MIPS_GPREL16 | |
| 89 | // can be against a preemptible symbol. | |
| 90 | // To get MIPS relocation type we apply 0xff mask. In case of O32 ABI all | |
| 91 | // relocation types occupy eight bit. In case of N64 ABI we extract first | |
| 92 | // relocation from 3-in-1 packet because only the first relocation can | |
| 93 | // be against a real symbol. | |
| 94 | if (Config->EMachine == EM_MIPS && (Type & 0xff) == R_MIPS_GPREL16) | |
| 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) | |
| 95 | 98 | return false; |
| 96 | return Body.isPreemptible(); | |
| 99 | Type &= 0xff; | |
| 100 | return Type == R_MIPS_GPREL16 || Type == R_MICROMIPS_GPREL16 || | |
| 101 | Type == R_MICROMIPS_GPREL7_S2; | |
| 97 | 102 | } |
| 98 | 103 | |
| 99 | 104 | // This function is similar to the `handleTlsRelocation`. MIPS does not |
| ... | ... | @@ -103,28 +108,28 @@ static bool isPreemptible(const SymbolBody &Body, uint32_t Type) { |
| 103 | 108 | // Mips has a custom MipsGotSection that handles the writing of GOT entries |
| 104 | 109 | // without dynamic relocations. |
| 105 | 110 | template <class ELFT> |
| 106 | static unsigned handleMipsTlsRelocation(uint32_t Type, SymbolBody &Body, | |
| 111 | static unsigned handleMipsTlsRelocation(RelType Type, Symbol &Sym, | |
| 107 | 112 | InputSectionBase &C, uint64_t Offset, |
| 108 | 113 | int64_t Addend, RelExpr Expr) { |
| 109 | 114 | if (Expr == R_MIPS_TLSLD) { |
| 110 | 115 | if (InX::MipsGot->addTlsIndex() && Config->Pic) |
| 111 | In<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, InX::MipsGot, | |
| 112 | InX::MipsGot->getTlsIndexOff(), false, | |
| 113 | nullptr, 0}); | |
| 114 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); | |
| 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}); | |
| 115 | 120 | return 1; |
| 116 | 121 | } |
| 117 | 122 | |
| 118 | 123 | if (Expr == R_MIPS_TLSGD) { |
| 119 | if (InX::MipsGot->addDynTlsEntry(Body) && Body.isPreemptible()) { | |
| 120 | uint64_t Off = InX::MipsGot->getGlobalDynOffset(Body); | |
| 121 | In<ELFT>::RelaDyn->addReloc( | |
| 122 | {Target->TlsModuleIndexRel, InX::MipsGot, Off, false, &Body, 0}); | |
| 123 | if (Body.isPreemptible()) | |
| 124 | In<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, InX::MipsGot, | |
| 125 | Off + Config->Wordsize, false, &Body, 0}); | |
| 124 | if (InX::MipsGot->addDynTlsEntry(Sym) && Sym.IsPreemptible) { | |
| 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}); | |
| 126 | 131 | } |
| 127 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); | |
| 132 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | |
| 128 | 133 | return 1; |
| 129 | 134 | } |
| 130 | 135 | return 0; |
| ... | ... | @@ -145,19 +150,18 @@ static unsigned handleMipsTlsRelocation(uint32_t Type, SymbolBody &Body, |
| 145 | 150 | // GOT[e0] Module Index (Used to find pointer to TLS block at run-time) |
| 146 | 151 | // GOT[e1] Offset of symbol in TLS block |
| 147 | 152 | template <class ELFT> |
| 148 | static unsigned handleARMTlsRelocation(uint32_t Type, SymbolBody &Body, | |
| 153 | static unsigned handleARMTlsRelocation(RelType Type, Symbol &Sym, | |
| 149 | 154 | InputSectionBase &C, uint64_t Offset, |
| 150 | 155 | int64_t Addend, RelExpr Expr) { |
| 151 | 156 | // The Dynamic TLS Module Index Relocation for a symbol defined in an |
| 152 | // executable is always 1. If the target Symbol is not preemtible then | |
| 157 | // executable is always 1. If the target Symbol is not preemptible then | |
| 153 | 158 | // we know the offset into the TLS block at static link time. |
| 154 | bool NeedDynId = Body.isPreemptible() || Config->Shared; | |
| 155 | bool NeedDynOff = Body.isPreemptible(); | |
| 159 | bool NeedDynId = Sym.IsPreemptible || Config->Shared; | |
| 160 | bool NeedDynOff = Sym.IsPreemptible; | |
| 156 | 161 | |
| 157 | auto AddTlsReloc = [&](uint64_t Off, uint32_t Type, SymbolBody *Dest, | |
| 158 | bool Dyn) { | |
| 162 | auto AddTlsReloc = [&](uint64_t Off, RelType Type, Symbol *Dest, bool Dyn) { | |
| 159 | 163 | if (Dyn) |
| 160 | In<ELFT>::RelaDyn->addReloc({Type, InX::Got, Off, false, Dest, 0}); | |
| 164 | InX::RelaDyn->addReloc({Type, InX::Got, Off, false, Dest, 0}); | |
| 161 | 165 | else |
| 162 | 166 | InX::Got->Relocations.push_back({R_ABS, Type, Off, 0, Dest}); |
| 163 | 167 | }; |
| ... | ... | @@ -168,8 +172,8 @@ static unsigned handleARMTlsRelocation(uint32_t Type, SymbolBody &Body, |
| 168 | 172 | // module. GOT[e1] is unused. There only needs to be one module index entry. |
| 169 | 173 | if (Expr == R_TLSLD_PC && InX::Got->addTlsIndex()) { |
| 170 | 174 | AddTlsReloc(InX::Got->getTlsIndexOff(), Target->TlsModuleIndexRel, |
| 171 | NeedDynId ? nullptr : &Body, NeedDynId); | |
| 172 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); | |
| 175 | NeedDynId ? nullptr : &Sym, NeedDynId); | |
| 176 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | |
| 173 | 177 | return 1; |
| 174 | 178 | } |
| 175 | 179 | |
| ... | ... | @@ -177,13 +181,13 @@ static unsigned handleARMTlsRelocation(uint32_t Type, SymbolBody &Body, |
| 177 | 181 | // the module index and offset of symbol in TLS block we can fill these in |
| 178 | 182 | // using static GOT relocations. |
| 179 | 183 | if (Expr == R_TLSGD_PC) { |
| 180 | if (InX::Got->addDynTlsEntry(Body)) { | |
| 181 | uint64_t Off = InX::Got->getGlobalDynOffset(Body); | |
| 182 | AddTlsReloc(Off, Target->TlsModuleIndexRel, &Body, NeedDynId); | |
| 183 | AddTlsReloc(Off + Config->Wordsize, Target->TlsOffsetRel, &Body, | |
| 184 | if (InX::Got->addDynTlsEntry(Sym)) { | |
| 185 | uint64_t Off = InX::Got->getGlobalDynOffset(Sym); | |
| 186 | AddTlsReloc(Off, Target->TlsModuleIndexRel, &Sym, NeedDynId); | |
| 187 | AddTlsReloc(Off + Config->Wordsize, Target->TlsOffsetRel, &Sym, | |
| 184 | 188 | NeedDynOff); |
| 185 | 189 | } |
| 186 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); | |
| 190 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | |
| 187 | 191 | return 1; |
| 188 | 192 | } |
| 189 | 193 | return 0; |
| ... | ... | @@ -192,29 +196,28 @@ static unsigned handleARMTlsRelocation(uint32_t Type, SymbolBody &Body, |
| 192 | 196 | // Returns the number of relocations processed. |
| 193 | 197 | template <class ELFT> |
| 194 | 198 | static unsigned |
| 195 | handleTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase &C, | |
| 199 | handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, | |
| 196 | 200 | typename ELFT::uint Offset, int64_t Addend, RelExpr Expr) { |
| 197 | 201 | if (!(C.Flags & SHF_ALLOC)) |
| 198 | 202 | return 0; |
| 199 | 203 | |
| 200 | if (!Body.isTls()) | |
| 204 | if (!Sym.isTls()) | |
| 201 | 205 | return 0; |
| 202 | 206 | |
| 203 | 207 | if (Config->EMachine == EM_ARM) |
| 204 | return handleARMTlsRelocation<ELFT>(Type, Body, C, Offset, Addend, Expr); | |
| 208 | return handleARMTlsRelocation<ELFT>(Type, Sym, C, Offset, Addend, Expr); | |
| 205 | 209 | if (Config->EMachine == EM_MIPS) |
| 206 | return handleMipsTlsRelocation<ELFT>(Type, Body, C, Offset, Addend, Expr); | |
| 210 | return handleMipsTlsRelocation<ELFT>(Type, Sym, C, Offset, Addend, Expr); | |
| 207 | 211 | |
| 208 | bool IsPreemptible = isPreemptible(Body, Type); | |
| 209 | 212 | if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL>(Expr) && |
| 210 | 213 | Config->Shared) { |
| 211 | if (InX::Got->addDynTlsEntry(Body)) { | |
| 212 | uint64_t Off = InX::Got->getGlobalDynOffset(Body); | |
| 213 | In<ELFT>::RelaDyn->addReloc( | |
| 214 | {Target->TlsDescRel, InX::Got, Off, !IsPreemptible, &Body, 0}); | |
| 214 | if (InX::Got->addDynTlsEntry(Sym)) { | |
| 215 | uint64_t Off = InX::Got->getGlobalDynOffset(Sym); | |
| 216 | InX::RelaDyn->addReloc( | |
| 217 | {Target->TlsDescRel, InX::Got, Off, !Sym.IsPreemptible, &Sym, 0}); | |
| 215 | 218 | } |
| 216 | 219 | if (Expr != R_TLSDESC_CALL) |
| 217 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); | |
| 220 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | |
| 218 | 221 | return 1; |
| 219 | 222 | } |
| 220 | 223 | |
| ... | ... | @@ -222,61 +225,59 @@ handleTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase &C, |
| 222 | 225 | // Local-Dynamic relocs can be relaxed to Local-Exec. |
| 223 | 226 | if (!Config->Shared) { |
| 224 | 227 | C.Relocations.push_back( |
| 225 | {R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Body}); | |
| 228 | {R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Sym}); | |
| 226 | 229 | return 2; |
| 227 | 230 | } |
| 228 | 231 | if (InX::Got->addTlsIndex()) |
| 229 | In<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, InX::Got, | |
| 230 | InX::Got->getTlsIndexOff(), false, nullptr, | |
| 231 | 0}); | |
| 232 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); | |
| 232 | InX::RelaDyn->addReloc({Target->TlsModuleIndexRel, InX::Got, | |
| 233 | InX::Got->getTlsIndexOff(), false, nullptr, 0}); | |
| 234 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | |
| 233 | 235 | return 1; |
| 234 | 236 | } |
| 235 | 237 | |
| 236 | 238 | // Local-Dynamic relocs can be relaxed to Local-Exec. |
| 237 | 239 | if (isRelExprOneOf<R_ABS, R_TLSLD, R_TLSLD_PC>(Expr) && !Config->Shared) { |
| 238 | C.Relocations.push_back( | |
| 239 | {R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Body}); | |
| 240 | C.Relocations.push_back({R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Sym}); | |
| 240 | 241 | return 1; |
| 241 | 242 | } |
| 242 | 243 | |
| 243 | 244 | if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL, R_TLSGD, |
| 244 | 245 | R_TLSGD_PC>(Expr)) { |
| 245 | 246 | if (Config->Shared) { |
| 246 | if (InX::Got->addDynTlsEntry(Body)) { | |
| 247 | uint64_t Off = InX::Got->getGlobalDynOffset(Body); | |
| 248 | In<ELFT>::RelaDyn->addReloc( | |
| 249 | {Target->TlsModuleIndexRel, InX::Got, Off, false, &Body, 0}); | |
| 247 | if (InX::Got->addDynTlsEntry(Sym)) { | |
| 248 | uint64_t Off = InX::Got->getGlobalDynOffset(Sym); | |
| 249 | InX::RelaDyn->addReloc( | |
| 250 | {Target->TlsModuleIndexRel, InX::Got, Off, false, &Sym, 0}); | |
| 250 | 251 | |
| 251 | 252 | // If the symbol is preemptible we need the dynamic linker to write |
| 252 | 253 | // the offset too. |
| 253 | 254 | uint64_t OffsetOff = Off + Config->Wordsize; |
| 254 | if (IsPreemptible) | |
| 255 | In<ELFT>::RelaDyn->addReloc( | |
| 256 | {Target->TlsOffsetRel, InX::Got, OffsetOff, false, &Body, 0}); | |
| 255 | if (Sym.IsPreemptible) | |
| 256 | InX::RelaDyn->addReloc( | |
| 257 | {Target->TlsOffsetRel, InX::Got, OffsetOff, false, &Sym, 0}); | |
| 257 | 258 | else |
| 258 | 259 | InX::Got->Relocations.push_back( |
| 259 | {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Body}); | |
| 260 | {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Sym}); | |
| 260 | 261 | } |
| 261 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); | |
| 262 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | |
| 262 | 263 | return 1; |
| 263 | 264 | } |
| 264 | 265 | |
| 265 | 266 | // Global-Dynamic relocs can be relaxed to Initial-Exec or Local-Exec |
| 266 | 267 | // depending on the symbol being locally defined or not. |
| 267 | if (IsPreemptible) { | |
| 268 | if (Sym.IsPreemptible) { | |
| 268 | 269 | C.Relocations.push_back( |
| 269 | 270 | {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_IE), Type, |
| 270 | Offset, Addend, &Body}); | |
| 271 | if (!Body.isInGot()) { | |
| 272 | InX::Got->addEntry(Body); | |
| 273 | In<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, InX::Got, | |
| 274 | Body.getGotOffset(), false, &Body, 0}); | |
| 271 | Offset, Addend, &Sym}); | |
| 272 | if (!Sym.isInGot()) { | |
| 273 | InX::Got->addEntry(Sym); | |
| 274 | InX::RelaDyn->addReloc( | |
| 275 | {Target->TlsGotRel, InX::Got, Sym.getGotOffset(), false, &Sym, 0}); | |
| 275 | 276 | } |
| 276 | 277 | } else { |
| 277 | 278 | C.Relocations.push_back( |
| 278 | 279 | {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_LE), Type, |
| 279 | Offset, Addend, &Body}); | |
| 280 | Offset, Addend, &Sym}); | |
| 280 | 281 | } |
| 281 | 282 | return Target->TlsGdRelaxSkip; |
| 282 | 283 | } |
| ... | ... | @@ -284,9 +285,8 @@ handleTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase &C, |
| 284 | 285 | // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally |
| 285 | 286 | // defined. |
| 286 | 287 | if (isRelExprOneOf<R_GOT, R_GOT_FROM_END, R_GOT_PC, R_GOT_PAGE_PC>(Expr) && |
| 287 | !Config->Shared && !IsPreemptible) { | |
| 288 | C.Relocations.push_back( | |
| 289 | {R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Body}); | |
| 288 | !Config->Shared && !Sym.IsPreemptible) { | |
| 289 | C.Relocations.push_back({R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Sym}); | |
| 290 | 290 | return 1; |
| 291 | 291 | } |
| 292 | 292 | |
| ... | ... | @@ -295,12 +295,22 @@ handleTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase &C, |
| 295 | 295 | return 0; |
| 296 | 296 | } |
| 297 | 297 | |
| 298 | static uint32_t getMipsPairType(uint32_t Type, const SymbolBody &Sym) { | |
| 298 | static RelType getMipsPairType(RelType Type, bool IsLocal) { | |
| 299 | 299 | switch (Type) { |
| 300 | 300 | case R_MIPS_HI16: |
| 301 | 301 | return R_MIPS_LO16; |
| 302 | 302 | case R_MIPS_GOT16: |
| 303 | return Sym.isLocal() ? R_MIPS_LO16 : R_MIPS_NONE; | |
| 303 | // In case of global symbol, the R_MIPS_GOT16 relocation does not | |
| 304 | // have a pair. Each global symbol has a unique entry in the GOT | |
| 305 | // and a corresponding instruction with help of the R_MIPS_GOT16 | |
| 306 | // relocation loads an address of the symbol. In case of local | |
| 307 | // symbol, the R_MIPS_GOT16 relocation creates a GOT entry to hold | |
| 308 | // the high 16 bits of the symbol's value. A paired R_MIPS_LO16 | |
| 309 | // relocations handle low 16 bits of the address. That allows | |
| 310 | // to allocate only one GOT entry for every 64 KBytes of local data. | |
| 311 | return IsLocal ? R_MIPS_LO16 : R_MIPS_NONE; | |
| 312 | case R_MICROMIPS_GOT16: | |
| 313 | return IsLocal ? R_MICROMIPS_LO16 : R_MIPS_NONE; | |
| 304 | 314 | case R_MIPS_PCHI16: |
| 305 | 315 | return R_MIPS_PCLO16; |
| 306 | 316 | case R_MICROMIPS_HI16: |
| ... | ... | @@ -312,16 +322,16 @@ static uint32_t getMipsPairType(uint32_t Type, const SymbolBody &Sym) { |
| 312 | 322 | |
| 313 | 323 | // True if non-preemptable symbol always has the same value regardless of where |
| 314 | 324 | // the DSO is loaded. |
| 315 | static bool isAbsolute(const SymbolBody &Body) { | |
| 316 | if (Body.isUndefined()) | |
| 317 | return !Body.isLocal() && Body.symbol()->isWeak(); | |
| 318 | if (const auto *DR = dyn_cast<DefinedRegular>(&Body)) | |
| 325 | static bool isAbsolute(const Symbol &Sym) { | |
| 326 | if (Sym.isUndefWeak()) | |
| 327 | return true; | |
| 328 | if (const auto *DR = dyn_cast<Defined>(&Sym)) | |
| 319 | 329 | return DR->Section == nullptr; // Absolute symbol. |
| 320 | 330 | return false; |
| 321 | 331 | } |
| 322 | 332 | |
| 323 | static bool isAbsoluteValue(const SymbolBody &Body) { | |
| 324 | return isAbsolute(Body) || Body.isTls(); | |
| 333 | static bool isAbsoluteValue(const Symbol &Sym) { | |
| 334 | return isAbsolute(Sym) || Sym.isTls(); | |
| 325 | 335 | } |
| 326 | 336 | |
| 327 | 337 | // Returns true if Expr refers a PLT entry. |
| ... | ... | @@ -354,12 +364,10 @@ static bool isRelExpr(RelExpr Expr) { |
| 354 | 364 | // |
| 355 | 365 | // If this function returns false, that means we need to emit a |
| 356 | 366 | // dynamic relocation so that the relocation will be fixed at load-time. |
| 357 | template <class ELFT> | |
| 358 | static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type, | |
| 359 | const SymbolBody &Body, | |
| 367 | static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym, | |
| 360 | 368 | InputSectionBase &S, uint64_t RelOff) { |
| 361 | 369 | // These expressions always compute a constant |
| 362 | if (isRelExprOneOf<R_SIZE, R_GOT_FROM_END, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, | |
| 370 | if (isRelExprOneOf<R_GOT_FROM_END, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, | |
| 363 | 371 | R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC, |
| 364 | 372 | R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, |
| 365 | 373 | R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_PC, R_TLSGD, |
| ... | ... | @@ -371,14 +379,18 @@ static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type, |
| 371 | 379 | if (E == R_GOT || E == R_PLT || E == R_TLSDESC) |
| 372 | 380 | return Target->usesOnlyLowPageBits(Type) || !Config->Pic; |
| 373 | 381 | |
| 374 | if (isPreemptible(Body, Type)) | |
| 382 | if (Sym.IsPreemptible) | |
| 375 | 383 | return false; |
| 376 | 384 | if (!Config->Pic) |
| 377 | 385 | return true; |
| 378 | 386 | |
| 387 | // The size of a non preemptible symbol is a constant. | |
| 388 | if (E == R_SIZE) | |
| 389 | return true; | |
| 390 | ||
| 379 | 391 | // For the target and the relocation, we want to know if they are |
| 380 | 392 | // absolute or relative. |
| 381 | bool AbsVal = isAbsoluteValue(Body); | |
| 393 | bool AbsVal = isAbsoluteValue(Sym); | |
| 382 | 394 | bool RelE = isRelExpr(E); |
| 383 | 395 | if (AbsVal && !RelE) |
| 384 | 396 | return true; |
| ... | ... | @@ -396,11 +408,11 @@ static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type, |
| 396 | 408 | // between start of a function and '_gp' value and defined as absolute just |
| 397 | 409 | // to simplify the code. |
| 398 | 410 | assert(AbsVal && RelE); |
| 399 | if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) | |
| 411 | if (Sym.isUndefWeak()) | |
| 400 | 412 | return true; |
| 401 | 413 | |
| 402 | 414 | error("relocation " + toString(Type) + " cannot refer to absolute symbol: " + |
| 403 | toString(Body) + getLocation<ELFT>(S, Body, RelOff)); | |
| 415 | toString(Sym) + getLocation(S, Sym, RelOff)); | |
| 404 | 416 | return true; |
| 405 | 417 | } |
| 406 | 418 | |
| ... | ... | @@ -431,14 +443,13 @@ static RelExpr fromPlt(RelExpr Expr) { |
| 431 | 443 | // Returns true if a given shared symbol is in a read-only segment in a DSO. |
| 432 | 444 | template <class ELFT> static bool isReadOnly(SharedSymbol *SS) { |
| 433 | 445 | typedef typename ELFT::Phdr Elf_Phdr; |
| 434 | uint64_t Value = SS->getValue<ELFT>(); | |
| 435 | 446 | |
| 436 | 447 | // Determine if the symbol is read-only by scanning the DSO's program headers. |
| 437 | auto *File = cast<SharedFile<ELFT>>(SS->File); | |
| 438 | for (const Elf_Phdr &Phdr : check(File->getObj().program_headers())) | |
| 448 | const SharedFile<ELFT> &File = SS->getFile<ELFT>(); | |
| 449 | for (const Elf_Phdr &Phdr : check(File.getObj().program_headers())) | |
| 439 | 450 | if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) && |
| 440 | !(Phdr.p_flags & ELF::PF_W) && Value >= Phdr.p_vaddr && | |
| 441 | Value < Phdr.p_vaddr + Phdr.p_memsz) | |
| 451 | !(Phdr.p_flags & ELF::PF_W) && SS->Value >= Phdr.p_vaddr && | |
| 452 | SS->Value < Phdr.p_vaddr + Phdr.p_memsz) | |
| 442 | 453 | return true; |
| 443 | 454 | return false; |
| 444 | 455 | } |
| ... | ... | @@ -452,16 +463,15 @@ template <class ELFT> |
| 452 | 463 | static std::vector<SharedSymbol *> getSymbolsAt(SharedSymbol *SS) { |
| 453 | 464 | typedef typename ELFT::Sym Elf_Sym; |
| 454 | 465 | |
| 455 | auto *File = cast<SharedFile<ELFT>>(SS->File); | |
| 456 | uint64_t Shndx = SS->getShndx<ELFT>(); | |
| 457 | uint64_t Value = SS->getValue<ELFT>(); | |
| 466 | SharedFile<ELFT> &File = SS->getFile<ELFT>(); | |
| 458 | 467 | |
| 459 | 468 | std::vector<SharedSymbol *> Ret; |
| 460 | for (const Elf_Sym &S : File->getGlobalSymbols()) { | |
| 461 | if (S.st_shndx != Shndx || S.st_value != Value) | |
| 469 | for (const Elf_Sym &S : File.getGlobalELFSyms()) { | |
| 470 | if (S.st_shndx == SHN_UNDEF || S.st_shndx == SHN_ABS || | |
| 471 | S.st_value != SS->Value) | |
| 462 | 472 | continue; |
| 463 | StringRef Name = check(S.getName(File->getStringTable())); | |
| 464 | SymbolBody *Sym = Symtab<ELFT>::X->find(Name); | |
| 473 | StringRef Name = check(S.getName(File.getStringTable())); | |
| 474 | Symbol *Sym = Symtab->find(Name); | |
| 465 | 475 | if (auto *Alias = dyn_cast_or_null<SharedSymbol>(Sym)) |
| 466 | 476 | Ret.push_back(Alias); |
| 467 | 477 | } |
| ... | ... | @@ -512,132 +522,153 @@ static std::vector<SharedSymbol *> getSymbolsAt(SharedSymbol *SS) { |
| 512 | 522 | // define an accessor getV(). |
| 513 | 523 | template <class ELFT> static void addCopyRelSymbol(SharedSymbol *SS) { |
| 514 | 524 | // Copy relocation against zero-sized symbol doesn't make sense. |
| 515 | uint64_t SymSize = SS->template getSize<ELFT>(); | |
| 525 | uint64_t SymSize = SS->getSize(); | |
| 516 | 526 | if (SymSize == 0) |
| 517 | 527 | fatal("cannot create a copy relocation for symbol " + toString(*SS)); |
| 518 | 528 | |
| 519 | 529 | // See if this symbol is in a read-only segment. If so, preserve the symbol's |
| 520 | 530 | // memory protection by reserving space in the .bss.rel.ro section. |
| 521 | 531 | bool IsReadOnly = isReadOnly<ELFT>(SS); |
| 522 | BssSection *Sec = IsReadOnly ? InX::BssRelRo : InX::Bss; | |
| 523 | uint64_t Off = Sec->reserveSpace(SymSize, SS->getAlignment<ELFT>()); | |
| 532 | BssSection *Sec = make<BssSection>(IsReadOnly ? ".bss.rel.ro" : ".bss", | |
| 533 | SymSize, SS->Alignment); | |
| 534 | if (IsReadOnly) | |
| 535 | InX::BssRelRo->getParent()->addSection(Sec); | |
| 536 | else | |
| 537 | InX::Bss->getParent()->addSection(Sec); | |
| 524 | 538 | |
| 525 | 539 | // Look through the DSO's dynamic symbol table for aliases and create a |
| 526 | 540 | // dynamic symbol for each one. This causes the copy relocation to correctly |
| 527 | 541 | // interpose any aliases. |
| 528 | 542 | for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS)) { |
| 529 | Sym->NeedsCopy = true; | |
| 530 | 543 | Sym->CopyRelSec = Sec; |
| 531 | Sym->CopyRelSecOff = Off; | |
| 532 | Sym->symbol()->IsUsedInRegularObj = true; | |
| 544 | Sym->IsPreemptible = false; | |
| 545 | Sym->IsUsedInRegularObj = true; | |
| 546 | Sym->Used = true; | |
| 533 | 547 | } |
| 534 | 548 | |
| 535 | In<ELFT>::RelaDyn->addReloc({Target->CopyRel, Sec, Off, false, SS, 0}); | |
| 549 | InX::RelaDyn->addReloc({Target->CopyRel, Sec, 0, false, SS, 0}); | |
| 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); | |
| 536 | 586 | } |
| 537 | 587 | |
| 588 | // This modifies the expression if we can use a copy relocation or point the | |
| 589 | // symbol to the PLT. | |
| 538 | 590 | template <class ELFT> |
| 539 | static RelExpr adjustExpr(SymbolBody &Body, RelExpr Expr, uint32_t Type, | |
| 540 | const uint8_t *Data, InputSectionBase &S, | |
| 541 | typename ELFT::uint RelOff) { | |
| 542 | if (Body.isGnuIFunc()) { | |
| 543 | Expr = toPlt(Expr); | |
| 544 | } else if (!isPreemptible(Body, Type)) { | |
| 545 | if (needsPlt(Expr)) | |
| 546 | Expr = fromPlt(Expr); | |
| 547 | if (Expr == R_GOT_PC && !isAbsoluteValue(Body)) | |
| 548 | Expr = Target->adjustRelaxExpr(Type, Data, Expr); | |
| 549 | } | |
| 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; | |
| 550 | 598 | |
| 551 | bool IsWrite = !Config->ZText || (S.Flags & SHF_WRITE); | |
| 552 | if (IsWrite || isStaticLinkTimeConstant<ELFT>(Expr, Type, Body, S, RelOff)) | |
| 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)) | |
| 553 | 603 | return Expr; |
| 554 | 604 | |
| 555 | // This relocation would require the dynamic linker to write a value to read | |
| 556 | // only memory. We can hack around it if we are producing an executable and | |
| 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 | |
| 557 | 618 | // the refered symbol can be preemepted to refer to the executable. |
| 558 | if (Config->Shared || (Config->Pic && !isRelExpr(Expr))) { | |
| 559 | error("can't create dynamic relocation " + toString(Type) + " against " + | |
| 560 | (Body.getName().empty() ? "local symbol" | |
| 561 | : "symbol: " + toString(Body)) + | |
| 562 | " in readonly segment" + getLocation<ELFT>(S, Body, RelOff)); | |
| 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)); | |
| 563 | 625 | return Expr; |
| 564 | 626 | } |
| 565 | 627 | |
| 566 | if (Body.getVisibility() != STV_DEFAULT) { | |
| 567 | error("cannot preempt symbol: " + toString(Body) + | |
| 568 | getLocation<ELFT>(S, Body, RelOff)); | |
| 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)); | |
| 569 | 636 | return Expr; |
| 570 | 637 | } |
| 571 | 638 | |
| 572 | if (Body.isObject()) { | |
| 639 | if (Sym.isObject()) { | |
| 573 | 640 | // Produce a copy relocation. |
| 574 | auto *B = cast<SharedSymbol>(&Body); | |
| 575 | if (!B->NeedsCopy) { | |
| 641 | auto *B = dyn_cast<SharedSymbol>(&Sym); | |
| 642 | if (B && !B->CopyRelSec) { | |
| 576 | 643 | if (Config->ZNocopyreloc) |
| 577 | 644 | error("unresolvable relocation " + toString(Type) + |
| 578 | 645 | " against symbol '" + toString(*B) + |
| 579 | 646 | "'; recompile with -fPIC or remove '-z nocopyreloc'" + |
| 580 | getLocation<ELFT>(S, Body, RelOff)); | |
| 647 | getLocation(S, Sym, RelOff)); | |
| 581 | 648 | |
| 582 | 649 | addCopyRelSymbol<ELFT>(B); |
| 583 | 650 | } |
| 651 | IsConstant = true; | |
| 584 | 652 | return Expr; |
| 585 | 653 | } |
| 586 | 654 | |
| 587 | if (Body.isFunc()) { | |
| 588 | // This handles a non PIC program call to function in a shared library. In | |
| 589 | // an ideal world, we could just report an error saying the relocation can | |
| 590 | // overflow at runtime. In the real world with glibc, crt1.o has a | |
| 591 | // R_X86_64_PC32 pointing to libc.so. | |
| 592 | // | |
| 593 | // The general idea on how to handle such cases is to create a PLT entry and | |
| 594 | // use that as the function value. | |
| 595 | // | |
| 596 | // For the static linking part, we just return a plt expr and everything | |
| 597 | // else will use the the PLT entry as the address. | |
| 598 | // | |
| 599 | // The remaining problem is making sure pointer equality still works. We | |
| 600 | // need the help of the dynamic linker for that. We let it know that we have | |
| 601 | // a direct reference to a so symbol by creating an undefined symbol with a | |
| 602 | // non zero st_value. Seeing that, the dynamic linker resolves the symbol to | |
| 603 | // the value of the symbol we created. This is true even for got entries, so | |
| 604 | // pointer equality is maintained. To avoid an infinite loop, the only entry | |
| 605 | // that points to the real function is a dedicated got entry used by the | |
| 606 | // plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT, | |
| 607 | // R_386_JMP_SLOT, etc). | |
| 608 | Body.NeedsPltAddr = true; | |
| 609 | return toPlt(Expr); | |
| 610 | } | |
| 655 | if (Sym.isFunc()) | |
| 656 | return getPltExpr(Sym, Expr, IsConstant); | |
| 611 | 657 | |
| 612 | error("symbol '" + toString(Body) + "' defined in " + toString(Body.File) + | |
| 613 | " has no type"); | |
| 658 | errorOrWarn("symbol '" + toString(Sym) + "' defined in " + | |
| 659 | toString(Sym.File) + " has no type"); | |
| 614 | 660 | return Expr; |
| 615 | 661 | } |
| 616 | 662 | |
| 617 | // Returns an addend of a given relocation. If it is RELA, an addend | |
| 618 | // is in a relocation itself. If it is REL, we need to read it from an | |
| 619 | // input section. | |
| 620 | template <class ELFT, class RelTy> | |
| 621 | static int64_t computeAddend(const RelTy &Rel, const uint8_t *Buf) { | |
| 622 | uint32_t Type = Rel.getType(Config->IsMips64EL); | |
| 623 | int64_t A = RelTy::IsRela | |
| 624 | ? getAddend<ELFT>(Rel) | |
| 625 | : Target->getImplicitAddend(Buf + Rel.r_offset, Type); | |
| 626 | ||
| 627 | if (Config->EMachine == EM_PPC64 && Config->Pic && Type == R_PPC64_TOC) | |
| 628 | A += getPPC64TocBase(); | |
| 629 | return A; | |
| 630 | } | |
| 631 | ||
| 632 | 663 | // MIPS has an odd notion of "paired" relocations to calculate addends. |
| 633 | 664 | // For example, if a relocation is of R_MIPS_HI16, there must be a |
| 634 | 665 | // R_MIPS_LO16 relocation after that, and an addend is calculated using |
| 635 | 666 | // the two relocations. |
| 636 | 667 | template <class ELFT, class RelTy> |
| 637 | static int64_t computeMipsAddend(const RelTy &Rel, InputSectionBase &Sec, | |
| 638 | RelExpr Expr, SymbolBody &Body, | |
| 639 | const RelTy *End) { | |
| 640 | if (Expr == R_MIPS_GOTREL && Body.isLocal()) | |
| 668 | static int64_t computeMipsAddend(const RelTy &Rel, const RelTy *End, | |
| 669 | InputSectionBase &Sec, RelExpr Expr, | |
| 670 | bool IsLocal) { | |
| 671 | if (Expr == R_MIPS_GOTREL && IsLocal) | |
| 641 | 672 | return Sec.getFile<ELFT>()->MipsGp0; |
| 642 | 673 | |
| 643 | 674 | // The ABI says that the paired relocation is used only for REL. |
| ... | ... | @@ -645,8 +676,8 @@ static int64_t computeMipsAddend(const RelTy &Rel, InputSectionBase &Sec, |
| 645 | 676 | if (RelTy::IsRela) |
| 646 | 677 | return 0; |
| 647 | 678 | |
| 648 | uint32_t Type = Rel.getType(Config->IsMips64EL); | |
| 649 | uint32_t PairTy = getMipsPairType(Type, Body); | |
| 679 | RelType Type = Rel.getType(Config->IsMips64EL); | |
| 680 | uint32_t PairTy = getMipsPairType(Type, IsLocal); | |
| 650 | 681 | if (PairTy == R_MIPS_NONE) |
| 651 | 682 | return 0; |
| 652 | 683 | |
| ... | ... | @@ -655,64 +686,87 @@ static int64_t computeMipsAddend(const RelTy &Rel, InputSectionBase &Sec, |
| 655 | 686 | |
| 656 | 687 | // To make things worse, paired relocations might not be contiguous in |
| 657 | 688 | // the relocation table, so we need to do linear search. *sigh* |
| 658 | for (const RelTy *RI = &Rel; RI != End; ++RI) { | |
| 659 | if (RI->getType(Config->IsMips64EL) != PairTy) | |
| 660 | continue; | |
| 661 | if (RI->getSymbol(Config->IsMips64EL) != SymIndex) | |
| 662 | continue; | |
| 663 | ||
| 664 | endianness E = Config->Endianness; | |
| 665 | int32_t Hi = (read32(Buf + Rel.r_offset, E) & 0xffff) << 16; | |
| 666 | int32_t Lo = SignExtend32<16>(read32(Buf + RI->r_offset, E)); | |
| 667 | return Hi + Lo; | |
| 668 | } | |
| 689 | for (const RelTy *RI = &Rel; RI != End; ++RI) | |
| 690 | if (RI->getType(Config->IsMips64EL) == PairTy && | |
| 691 | RI->getSymbol(Config->IsMips64EL) == SymIndex) | |
| 692 | return Target->getImplicitAddend(Buf + RI->r_offset, PairTy); | |
| 669 | 693 | |
| 670 | 694 | warn("can't find matching " + toString(PairTy) + " relocation for " + |
| 671 | 695 | toString(Type)); |
| 672 | 696 | return 0; |
| 673 | 697 | } |
| 674 | 698 | |
| 675 | template <class ELFT> | |
| 676 | static void reportUndefined(SymbolBody &Sym, InputSectionBase &S, | |
| 677 | uint64_t Offset) { | |
| 699 | // Returns an addend of a given relocation. If it is RELA, an addend | |
| 700 | // is in a relocation itself. If it is REL, we need to read it from an | |
| 701 | // input section. | |
| 702 | template <class ELFT, class RelTy> | |
| 703 | static int64_t computeAddend(const RelTy &Rel, const RelTy *End, | |
| 704 | InputSectionBase &Sec, RelExpr Expr, | |
| 705 | bool IsLocal) { | |
| 706 | int64_t Addend; | |
| 707 | RelType Type = Rel.getType(Config->IsMips64EL); | |
| 708 | ||
| 709 | if (RelTy::IsRela) { | |
| 710 | Addend = getAddend<ELFT>(Rel); | |
| 711 | } else { | |
| 712 | const uint8_t *Buf = Sec.Data.data(); | |
| 713 | Addend = Target->getImplicitAddend(Buf + Rel.r_offset, Type); | |
| 714 | } | |
| 715 | ||
| 716 | if (Config->EMachine == EM_PPC64 && Config->Pic && Type == R_PPC64_TOC) | |
| 717 | Addend += getPPC64TocBase(); | |
| 718 | if (Config->EMachine == EM_MIPS) | |
| 719 | Addend += computeMipsAddend<ELFT>(Rel, End, Sec, Expr, IsLocal); | |
| 720 | ||
| 721 | return Addend; | |
| 722 | } | |
| 723 | ||
| 724 | // Report an undefined symbol if necessary. | |
| 725 | // Returns true if this function printed out an error message. | |
| 726 | static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec, | |
| 727 | uint64_t Offset) { | |
| 678 | 728 | if (Config->UnresolvedSymbols == UnresolvedPolicy::IgnoreAll) |
| 679 | return; | |
| 729 | return false; | |
| 680 | 730 | |
| 681 | bool CanBeExternal = Sym.symbol()->computeBinding() != STB_LOCAL && | |
| 682 | Sym.getVisibility() == STV_DEFAULT; | |
| 731 | if (Sym.isLocal() || !Sym.isUndefined() || Sym.isWeak()) | |
| 732 | return false; | |
| 733 | ||
| 734 | bool CanBeExternal = | |
| 735 | Sym.computeBinding() != STB_LOCAL && Sym.getVisibility() == STV_DEFAULT; | |
| 683 | 736 | if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore && CanBeExternal) |
| 684 | return; | |
| 737 | return false; | |
| 685 | 738 | |
| 686 | 739 | std::string Msg = |
| 687 | 740 | "undefined symbol: " + toString(Sym) + "\n>>> referenced by "; |
| 688 | 741 | |
| 689 | std::string Src = S.getSrcMsg<ELFT>(Offset); | |
| 742 | std::string Src = Sec.getSrcMsg(Sym, Offset); | |
| 690 | 743 | if (!Src.empty()) |
| 691 | 744 | Msg += Src + "\n>>> "; |
| 692 | Msg += S.getObjMsg<ELFT>(Offset); | |
| 745 | Msg += Sec.getObjMsg(Offset); | |
| 693 | 746 | |
| 694 | if (Config->UnresolvedSymbols == UnresolvedPolicy::WarnAll || | |
| 695 | (Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal)) { | |
| 747 | if ((Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal) || | |
| 748 | Config->NoinhibitExec) { | |
| 696 | 749 | warn(Msg); |
| 697 | } else { | |
| 698 | error(Msg); | |
| 750 | return false; | |
| 699 | 751 | } |
| 752 | ||
| 753 | error(Msg); | |
| 754 | return true; | |
| 700 | 755 | } |
| 701 | 756 | |
| 702 | template <class RelTy> | |
| 703 | static std::pair<uint32_t, uint32_t> | |
| 704 | mergeMipsN32RelTypes(uint32_t Type, uint32_t Offset, RelTy *I, RelTy *E) { | |
| 705 | // MIPS N32 ABI treats series of successive relocations with the same offset | |
| 706 | // as a single relocation. The similar approach used by N64 ABI, but this ABI | |
| 707 | // packs all relocations into the single relocation record. Here we emulate | |
| 708 | // this for the N32 ABI. Iterate over relocation with the same offset and put | |
| 709 | // theirs types into the single bit-set. | |
| 710 | uint32_t Processed = 0; | |
| 711 | for (; I != E && Offset == I->r_offset; ++I) { | |
| 712 | ++Processed; | |
| 713 | Type |= I->getType(Config->IsMips64EL) << (8 * Processed); | |
| 714 | } | |
| 715 | return std::make_pair(Type, Processed); | |
| 757 | // MIPS N32 ABI treats series of successive relocations with the same offset | |
| 758 | // as a single relocation. The similar approach used by N64 ABI, but this ABI | |
| 759 | // packs all relocations into the single relocation record. Here we emulate | |
| 760 | // this for the N32 ABI. Iterate over relocation with the same offset and put | |
| 761 | // theirs types into the single bit-set. | |
| 762 | template <class RelTy> static RelType getMipsN32RelType(RelTy *&Rel, RelTy *End) { | |
| 763 | RelType Type = Rel->getType(Config->IsMips64EL); | |
| 764 | uint64_t Offset = Rel->r_offset; | |
| 765 | ||
| 766 | int N = 0; | |
| 767 | while (Rel + 1 != End && (Rel + 1)->r_offset == Offset) | |
| 768 | Type |= (++Rel)->getType(Config->IsMips64EL) << (8 * ++N); | |
| 769 | return Type; | |
| 716 | 770 | } |
| 717 | 771 | |
| 718 | 772 | // .eh_frame sections are mergeable input sections, so their input |
| ... | ... | @@ -730,73 +784,84 @@ namespace { |
| 730 | 784 | class OffsetGetter { |
| 731 | 785 | public: |
| 732 | 786 | explicit OffsetGetter(InputSectionBase &Sec) { |
| 733 | if (auto *Eh = dyn_cast<EhInputSection>(&Sec)) { | |
| 734 | P = Eh->Pieces; | |
| 735 | Size = Eh->Pieces.size(); | |
| 736 | } | |
| 787 | if (auto *Eh = dyn_cast<EhInputSection>(&Sec)) | |
| 788 | Pieces = Eh->Pieces; | |
| 737 | 789 | } |
| 738 | 790 | |
| 739 | 791 | // Translates offsets in input sections to offsets in output sections. |
| 740 | // Given offset must increase monotonically. We assume that P is | |
| 792 | // Given offset must increase monotonically. We assume that Piece is | |
| 741 | 793 | // sorted by InputOff. |
| 742 | 794 | uint64_t get(uint64_t Off) { |
| 743 | if (P.empty()) | |
| 795 | if (Pieces.empty()) | |
| 744 | 796 | return Off; |
| 745 | 797 | |
| 746 | while (I != Size && P[I].InputOff + P[I].size() <= Off) | |
| 798 | while (I != Pieces.size() && Pieces[I].InputOff + Pieces[I].Size <= Off) | |
| 747 | 799 | ++I; |
| 748 | if (I == Size) | |
| 800 | if (I == Pieces.size()) | |
| 749 | 801 | return Off; |
| 750 | 802 | |
| 751 | // P must be contiguous, so there must be no holes in between. | |
| 752 | assert(P[I].InputOff <= Off && "Relocation not in any piece"); | |
| 803 | // Pieces must be contiguous, so there must be no holes in between. | |
| 804 | assert(Pieces[I].InputOff <= Off && "Relocation not in any piece"); | |
| 753 | 805 | |
| 754 | 806 | // Offset -1 means that the piece is dead (i.e. garbage collected). |
| 755 | if (P[I].OutputOff == -1) | |
| 807 | if (Pieces[I].OutputOff == -1) | |
| 756 | 808 | return -1; |
| 757 | return P[I].OutputOff + Off - P[I].InputOff; | |
| 809 | return Pieces[I].OutputOff + Off - Pieces[I].InputOff; | |
| 758 | 810 | } |
| 759 | 811 | |
| 760 | 812 | private: |
| 761 | ArrayRef<EhSectionPiece> P; | |
| 813 | ArrayRef<EhSectionPiece> Pieces; | |
| 762 | 814 | size_t I = 0; |
| 763 | size_t Size; | |
| 764 | 815 | }; |
| 765 | 816 | } // namespace |
| 766 | 817 | |
| 767 | 818 | template <class ELFT, class GotPltSection> |
| 768 | 819 | static void addPltEntry(PltSection *Plt, GotPltSection *GotPlt, |
| 769 | RelocationSection<ELFT> *Rel, uint32_t Type, | |
| 770 | SymbolBody &Sym, bool UseSymVA) { | |
| 820 | RelocationBaseSection *Rel, RelType Type, Symbol &Sym, | |
| 821 | bool UseSymVA) { | |
| 771 | 822 | Plt->addEntry<ELFT>(Sym); |
| 772 | 823 | GotPlt->addEntry(Sym); |
| 773 | 824 | Rel->addReloc({Type, GotPlt, Sym.getGotPltOffset(), UseSymVA, &Sym, 0}); |
| 774 | 825 | } |
| 775 | 826 | |
| 776 | template <class ELFT> | |
| 777 | static void addGotEntry(SymbolBody &Sym, bool Preemptible) { | |
| 827 | template <class ELFT> static void addGotEntry(Symbol &Sym, bool Preemptible) { | |
| 778 | 828 | InX::Got->addEntry(Sym); |
| 779 | 829 | |
| 830 | RelExpr Expr = Sym.isTls() ? R_TLS : R_ABS; | |
| 780 | 831 | uint64_t Off = Sym.getGotOffset(); |
| 781 | uint32_t DynType; | |
| 782 | RelExpr Expr = R_ABS; | |
| 783 | ||
| 784 | if (Sym.isTls()) { | |
| 785 | DynType = Target->TlsGotRel; | |
| 786 | Expr = R_TLS; | |
| 787 | } else if (!Preemptible && Config->Pic && !isAbsolute(Sym)) { | |
| 788 | DynType = Target->RelativeRel; | |
| 789 | } else { | |
| 790 | DynType = Target->GotRel; | |
| 791 | } | |
| 792 | 832 | |
| 793 | bool Constant = !Preemptible && !(Config->Pic && !isAbsolute(Sym)); | |
| 794 | if (!Constant) | |
| 795 | In<ELFT>::RelaDyn->addReloc( | |
| 796 | {DynType, InX::Got, Off, !Preemptible, &Sym, 0}); | |
| 833 | // If a GOT slot value can be calculated at link-time, which is now, | |
| 834 | // we can just fill that out. | |
| 835 | // | |
| 836 | // (We don't actually write a value to a GOT slot right now, but we | |
| 837 | // add a static relocation to a Relocations vector so that | |
| 838 | // InputSection::relocate will do the work for us. We may be able | |
| 839 | // to just write a value now, but it is a TODO.) | |
| 840 | bool IsLinkTimeConstant = !Preemptible && (!Config->Pic || isAbsolute(Sym)); | |
| 841 | if (IsLinkTimeConstant) { | |
| 842 | InX::Got->Relocations.push_back({Expr, Target->GotRel, Off, 0, &Sym}); | |
| 843 | return; | |
| 844 | } | |
| 797 | 845 | |
| 798 | if (Constant || (!Config->IsRela && !Preemptible)) | |
| 799 | InX::Got->Relocations.push_back({Expr, DynType, Off, 0, &Sym}); | |
| 846 | // Otherwise, we emit a dynamic relocation to .rel[a].dyn so that | |
| 847 | // the GOT slot will be fixed at load-time. | |
| 848 | RelType Type; | |
| 849 | if (Sym.isTls()) | |
| 850 | Type = Target->TlsGotRel; | |
| 851 | else if (!Preemptible && Config->Pic && !isAbsolute(Sym)) | |
| 852 | Type = Target->RelativeRel; | |
| 853 | else | |
| 854 | Type = Target->GotRel; | |
| 855 | InX::RelaDyn->addReloc({Type, InX::Got, Off, !Preemptible, &Sym, 0}); | |
| 856 | ||
| 857 | // REL type relocations don't have addend fields unlike RELAs, and | |
| 858 | // their addends are stored to the section to which they are applied. | |
| 859 | // So, store addends if we need to. | |
| 860 | // | |
| 861 | // This is ugly -- the difference between REL and RELA should be | |
| 862 | // handled in a better way. It's a TODO. | |
| 863 | if (!Config->IsRela && !Preemptible) | |
| 864 | InX::Got->Relocations.push_back({R_ABS, Target->GotRel, Off, 0, &Sym}); | |
| 800 | 865 | } |
| 801 | 866 | |
| 802 | 867 | // The reason we have to do this early scan is as follows |
| ... | ... | @@ -816,41 +881,67 @@ template <class ELFT, class RelTy> |
| 816 | 881 | static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) { |
| 817 | 882 | OffsetGetter GetOffset(Sec); |
| 818 | 883 | |
| 884 | // Not all relocations end up in Sec.Relocations, but a lot do. | |
| 885 | Sec.Relocations.reserve(Rels.size()); | |
| 886 | ||
| 819 | 887 | for (auto I = Rels.begin(), End = Rels.end(); I != End; ++I) { |
| 820 | 888 | const RelTy &Rel = *I; |
| 821 | SymbolBody &Body = Sec.getFile<ELFT>()->getRelocTargetSym(Rel); | |
| 822 | uint32_t Type = Rel.getType(Config->IsMips64EL); | |
| 823 | ||
| 824 | if (Config->MipsN32Abi) { | |
| 825 | uint32_t Processed; | |
| 826 | std::tie(Type, Processed) = | |
| 827 | mergeMipsN32RelTypes(Type, Rel.r_offset, I + 1, End); | |
| 828 | I += Processed; | |
| 829 | } | |
| 889 | Symbol &Sym = Sec.getFile<ELFT>()->getRelocTargetSym(Rel); | |
| 890 | RelType Type = Rel.getType(Config->IsMips64EL); | |
| 830 | 891 | |
| 831 | // Compute the offset of this section in the output section. | |
| 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. | |
| 832 | 897 | uint64_t Offset = GetOffset.get(Rel.r_offset); |
| 833 | 898 | if (Offset == uint64_t(-1)) |
| 834 | 899 | continue; |
| 835 | 900 | |
| 836 | // Report undefined symbols. The fact that we report undefined | |
| 837 | // symbols here means that we report undefined symbols only when | |
| 838 | // they have relocations pointing to them. We don't care about | |
| 839 | // undefined symbols that are in dead-stripped sections. | |
| 840 | if (!Body.isLocal() && Body.isUndefined() && !Body.symbol()->isWeak()) | |
| 841 | reportUndefined<ELFT>(Body, Sec, Rel.r_offset); | |
| 901 | // Skip if the target symbol is an erroneous undefined symbol. | |
| 902 | if (maybeReportUndefined(Sym, Sec, Rel.r_offset)) | |
| 903 | continue; | |
| 842 | 904 | |
| 843 | 905 | RelExpr Expr = |
| 844 | Target->getRelExpr(Type, Body, Sec.Data.begin() + Rel.r_offset); | |
| 906 | Target->getRelExpr(Type, Sym, Sec.Data.begin() + Rel.r_offset); | |
| 845 | 907 | |
| 846 | 908 | // Ignore "hint" relocations because they are only markers for relaxation. |
| 847 | 909 | if (isRelExprOneOf<R_HINT, R_NONE>(Expr)) |
| 848 | 910 | continue; |
| 849 | 911 | |
| 850 | bool Preemptible = isPreemptible(Body, Type); | |
| 851 | Expr = adjustExpr<ELFT>(Body, Expr, Type, Sec.Data.data() + Rel.r_offset, | |
| 852 | Sec, Rel.r_offset); | |
| 853 | if (ErrorCount) | |
| 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()) | |
| 854 | 945 | continue; |
| 855 | 946 | |
| 856 | 947 | // This relocation does not require got entry, but it is relative to got and |
| ... | ... | @@ -860,26 +951,24 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) { |
| 860 | 951 | InX::Got->HasGotOffRel = true; |
| 861 | 952 | |
| 862 | 953 | // Read an addend. |
| 863 | int64_t Addend = computeAddend<ELFT>(Rel, Sec.Data.data()); | |
| 864 | if (Config->EMachine == EM_MIPS) | |
| 865 | Addend += computeMipsAddend<ELFT>(Rel, Sec, Expr, Body, End); | |
| 954 | int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal()); | |
| 866 | 955 | |
| 867 | 956 | // Process some TLS relocations, including relaxing TLS relocations. |
| 868 | 957 | // Note that this function does not handle all TLS relocations. |
| 869 | 958 | if (unsigned Processed = |
| 870 | handleTlsRelocation<ELFT>(Type, Body, Sec, Offset, Addend, Expr)) { | |
| 959 | handleTlsRelocation<ELFT>(Type, Sym, Sec, Offset, Addend, Expr)) { | |
| 871 | 960 | I += (Processed - 1); |
| 872 | 961 | continue; |
| 873 | 962 | } |
| 874 | 963 | |
| 875 | 964 | // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol. |
| 876 | if (needsPlt(Expr) && !Body.isInPlt()) { | |
| 877 | if (Body.isGnuIFunc() && !Preemptible) | |
| 878 | addPltEntry(InX::Iplt, InX::IgotPlt, In<ELFT>::RelaIplt, | |
| 879 | Target->IRelativeRel, Body, true); | |
| 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); | |
| 880 | 969 | else |
| 881 | addPltEntry(InX::Plt, InX::GotPlt, In<ELFT>::RelaPlt, Target->PltRel, | |
| 882 | Body, !Preemptible); | |
| 970 | addPltEntry<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel, | |
| 971 | Sym, !Preemptible); | |
| 883 | 972 | } |
| 884 | 973 | |
| 885 | 974 | // Create a GOT slot if a relocation needs GOT. |
| ... | ... | @@ -892,25 +981,26 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) { |
| 892 | 981 | // See "Global Offset Table" in Chapter 5 in the following document |
| 893 | 982 | // for detailed description: |
| 894 | 983 | // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf |
| 895 | InX::MipsGot->addEntry(Body, Addend, Expr); | |
| 896 | if (Body.isTls() && Body.isPreemptible()) | |
| 897 | In<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, InX::MipsGot, | |
| 898 | Body.getGotOffset(), false, &Body, 0}); | |
| 899 | } else if (!Body.isInGot()) { | |
| 900 | addGotEntry<ELFT>(Body, Preemptible); | |
| 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); | |
| 901 | 990 | } |
| 902 | 991 | } |
| 903 | 992 | |
| 904 | if (!needsPlt(Expr) && !needsGot(Expr) && isPreemptible(Body, Type)) { | |
| 993 | if (!needsPlt(Expr) && !needsGot(Expr) && Sym.IsPreemptible) { | |
| 905 | 994 | // We don't know anything about the finaly symbol. Just ask the dynamic |
| 906 | 995 | // linker to handle the relocation for us. |
| 907 | 996 | if (!Target->isPicRel(Type)) |
| 908 | error("relocation " + toString(Type) + | |
| 909 | " cannot be used against shared object; recompile with -fPIC" + | |
| 910 | getLocation<ELFT>(Sec, Body, Offset)); | |
| 997 | errorOrWarn( | |
| 998 | "relocation " + toString(Type) + | |
| 999 | " cannot be used against shared object; recompile with -fPIC" + | |
| 1000 | getLocation(Sec, Sym, Offset)); | |
| 911 | 1001 | |
| 912 | In<ELFT>::RelaDyn->addReloc( | |
| 913 | {Target->getDynRel(Type), &Sec, Offset, false, &Body, Addend}); | |
| 1002 | InX::RelaDyn->addReloc( | |
| 1003 | {Target->getDynRel(Type), &Sec, Offset, false, &Sym, Addend}); | |
| 914 | 1004 | |
| 915 | 1005 | // MIPS ABI turns using of GOT and dynamic relocations inside out. |
| 916 | 1006 | // While regular ABI uses dynamic relocations to fill up GOT entries |
| ... | ... | @@ -928,32 +1018,36 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) { |
| 928 | 1018 | // a dynamic relocation. |
| 929 | 1019 | // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19 |
| 930 | 1020 | if (Config->EMachine == EM_MIPS) |
| 931 | InX::MipsGot->addEntry(Body, Addend, Expr); | |
| 1021 | InX::MipsGot->addEntry(Sym, Addend, Expr); | |
| 932 | 1022 | continue; |
| 933 | 1023 | } |
| 934 | 1024 | |
| 935 | // If the relocation points to something in the file, we can process it. | |
| 936 | bool IsConstant = | |
| 937 | isStaticLinkTimeConstant<ELFT>(Expr, Type, Body, Sec, Rel.r_offset); | |
| 938 | ||
| 939 | 1025 | // The size is not going to change, so we fold it in here. |
| 940 | 1026 | if (Expr == R_SIZE) |
| 941 | Addend += Body.getSize<ELFT>(); | |
| 1027 | Addend += Sym.getSize(); | |
| 1028 | ||
| 1029 | // If the produced value is a constant, we just remember to write it | |
| 1030 | // when outputting this section. We also have to do it if the format | |
| 1031 | // uses Elf_Rel, since in that case the written value is the addend. | |
| 1032 | if (IsConstant) { | |
| 1033 | Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | |
| 1034 | continue; | |
| 1035 | } | |
| 942 | 1036 | |
| 943 | 1037 | // If the output being produced is position independent, the final value |
| 944 | 1038 | // is still not known. In that case we still need some help from the |
| 945 | 1039 | // dynamic linker. We can however do better than just copying the incoming |
| 946 | 1040 | // relocation. We can process some of it and and just ask the dynamic |
| 947 | 1041 | // linker to add the load address. |
| 948 | if (!IsConstant) | |
| 949 | In<ELFT>::RelaDyn->addReloc( | |
| 950 | {Target->RelativeRel, &Sec, Offset, true, &Body, Addend}); | |
| 951 | ||
| 952 | // If the produced value is a constant, we just remember to write it | |
| 953 | // when outputting this section. We also have to do it if the format | |
| 954 | // uses Elf_Rel, since in that case the written value is the addend. | |
| 955 | if (IsConstant || !RelTy::IsRela) | |
| 956 | Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); | |
| 1042 | if (Config->IsRela) { | |
| 1043 | InX::RelaDyn->addReloc( | |
| 1044 | {Target->RelativeRel, &Sec, Offset, true, &Sym, Addend}); | |
| 1045 | } else { | |
| 1046 | // In REL, addends are stored to the target section. | |
| 1047 | InX::RelaDyn->addReloc( | |
| 1048 | {Target->RelativeRel, &Sec, Offset, true, &Sym, 0}); | |
| 1049 | Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | |
| 1050 | } | |
| 957 | 1051 | } |
| 958 | 1052 | } |
| 959 | 1053 | |
| ... | ... | @@ -964,178 +1058,365 @@ template <class ELFT> void elf::scanRelocations(InputSectionBase &S) { |
| 964 | 1058 | scanRelocs<ELFT>(S, S.rels<ELFT>()); |
| 965 | 1059 | } |
| 966 | 1060 | |
| 1061 | // Thunk Implementation | |
| 1062 | // | |
| 1063 | // Thunks (sometimes called stubs, veneers or branch islands) are small pieces | |
| 1064 | // of code that the linker inserts inbetween a caller and a callee. The thunks | |
| 1065 | // are added at link time rather than compile time as the decision on whether | |
| 1066 | // a thunk is needed, such as the caller and callee being out of range, can only | |
| 1067 | // be made at link time. | |
| 1068 | // | |
| 1069 | // It is straightforward to tell given the current state of the program when a | |
| 1070 | // thunk is needed for a particular call. The more difficult part is that | |
| 1071 | // the thunk needs to be placed in the program such that the caller can reach | |
| 1072 | // the thunk and the thunk can reach the callee; furthermore, adding thunks to | |
| 1073 | // the program alters addresses, which can mean more thunks etc. | |
| 1074 | // | |
| 1075 | // In lld we have a synthetic ThunkSection that can hold many Thunks. | |
| 1076 | // The decision to have a ThunkSection act as a container means that we can | |
| 1077 | // more easily handle the most common case of a single block of contiguous | |
| 1078 | // Thunks by inserting just a single ThunkSection. | |
| 1079 | // | |
| 1080 | // The implementation of Thunks in lld is split across these areas | |
| 1081 | // Relocations.cpp : Framework for creating and placing thunks | |
| 1082 | // Thunks.cpp : The code generated for each supported thunk | |
| 1083 | // Target.cpp : Target specific hooks that the framework uses to decide when | |
| 1084 | // a thunk is used | |
| 1085 | // Synthetic.cpp : Implementation of ThunkSection | |
| 1086 | // Writer.cpp : Iteratively call framework until no more Thunks added | |
| 1087 | // | |
| 1088 | // Thunk placement requirements: | |
| 1089 | // Mips LA25 thunks. These must be placed immediately before the callee section | |
| 1090 | // We can assume that the caller is in range of the Thunk. These are modelled | |
| 1091 | // by Thunks that return the section they must precede with | |
| 1092 | // getTargetInputSection(). | |
| 1093 | // | |
| 1094 | // ARM interworking and range extension thunks. These thunks must be placed | |
| 1095 | // within range of the caller. All implemented ARM thunks can always reach the | |
| 1096 | // callee as they use an indirect jump via a register that has no range | |
| 1097 | // restrictions. | |
| 1098 | // | |
| 1099 | // Thunk placement algorithm: | |
| 1100 | // For Mips LA25 ThunkSections; the placement is explicit, it has to be before | |
| 1101 | // getTargetInputSection(). | |
| 1102 | // | |
| 1103 | // For thunks that must be placed within range of the caller there are many | |
| 1104 | // possible choices given that the maximum range from the caller is usually | |
| 1105 | // much larger than the average InputSection size. Desirable properties include: | |
| 1106 | // - Maximize reuse of thunks by multiple callers | |
| 1107 | // - Minimize number of ThunkSections to simplify insertion | |
| 1108 | // - Handle impact of already added Thunks on addresses | |
| 1109 | // - Simple to understand and implement | |
| 1110 | // | |
| 1111 | // In lld for the first pass, we pre-create one or more ThunkSections per | |
| 1112 | // InputSectionDescription at Target specific intervals. A ThunkSection is | |
| 1113 | // placed so that the estimated end of the ThunkSection is within range of the | |
| 1114 | // start of the InputSectionDescription or the previous ThunkSection. For | |
| 1115 | // example: | |
| 1116 | // InputSectionDescription | |
| 1117 | // Section 0 | |
| 1118 | // ... | |
| 1119 | // Section N | |
| 1120 | // ThunkSection 0 | |
| 1121 | // Section N + 1 | |
| 1122 | // ... | |
| 1123 | // Section N + K | |
| 1124 | // Thunk Section 1 | |
| 1125 | // | |
| 1126 | // The intention is that we can add a Thunk to a ThunkSection that is well | |
| 1127 | // spaced enough to service a number of callers without having to do a lot | |
| 1128 | // of work. An important principle is that it is not an error if a Thunk cannot | |
| 1129 | // be placed in a pre-created ThunkSection; when this happens we create a new | |
| 1130 | // ThunkSection placed next to the caller. This allows us to handle the vast | |
| 1131 | // majority of thunks simply, but also handle rare cases where the branch range | |
| 1132 | // is smaller than the target specific spacing. | |
| 1133 | // | |
| 1134 | // The algorithm is expected to create all the thunks that are needed in a | |
| 1135 | // single pass, with a small number of programs needing a second pass due to | |
| 1136 | // the insertion of thunks in the first pass increasing the offset between | |
| 1137 | // callers and callees that were only just in range. | |
| 1138 | // | |
| 1139 | // A consequence of allowing new ThunkSections to be created outside of the | |
| 1140 | // pre-created ThunkSections is that in rare cases calls to Thunks that were in | |
| 1141 | // range in pass K, are out of range in some pass > K due to the insertion of | |
| 1142 | // more Thunks in between the caller and callee. When this happens we retarget | |
| 1143 | // the relocation back to the original target and create another Thunk. | |
| 1144 | ||
| 1145 | // Remove ThunkSections that are empty, this should only be the initial set | |
| 1146 | // precreated on pass 0. | |
| 1147 | ||
| 967 | 1148 | // Insert the Thunks for OutputSection OS into their designated place |
| 968 | 1149 | // in the Sections vector, and recalculate the InputSection output section |
| 969 | 1150 | // offsets. |
| 970 | 1151 | // This may invalidate any output section offsets stored outside of InputSection |
| 971 | void ThunkCreator::mergeThunks() { | |
| 972 | for (auto &KV : ThunkSections) { | |
| 973 | std::vector<InputSection *> *ISR = KV.first; | |
| 974 | std::vector<ThunkSection *> &Thunks = KV.second; | |
| 975 | ||
| 976 | // Order Thunks in ascending OutSecOff | |
| 977 | auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) { | |
| 978 | return A->OutSecOff < B->OutSecOff; | |
| 979 | }; | |
| 980 | std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp); | |
| 981 | ||
| 982 | // Merge sorted vectors of Thunks and InputSections by OutSecOff | |
| 983 | std::vector<InputSection *> Tmp; | |
| 984 | Tmp.reserve(ISR->size() + Thunks.size()); | |
| 985 | auto MergeCmp = [](const InputSection *A, const InputSection *B) { | |
| 986 | // std::merge requires a strict weak ordering. | |
| 987 | if (A->OutSecOff < B->OutSecOff) | |
| 988 | return true; | |
| 989 | if (A->OutSecOff == B->OutSecOff) | |
| 990 | // Check if Thunk is immediately before any specific Target InputSection | |
| 991 | // for example Mips LA25 Thunks. | |
| 992 | if (auto *TA = dyn_cast<ThunkSection>(A)) | |
| 993 | if (TA && TA->getTargetInputSection() == B) | |
| 1152 | void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> OutputSections) { | |
| 1153 | forEachInputSectionDescription( | |
| 1154 | OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) { | |
| 1155 | if (ISD->ThunkSections.empty()) | |
| 1156 | return; | |
| 1157 | ||
| 1158 | // Remove any zero sized precreated Thunks. | |
| 1159 | llvm::erase_if(ISD->ThunkSections, | |
| 1160 | [](const std::pair<ThunkSection *, uint32_t> &TS) { | |
| 1161 | return TS.first->getSize() == 0; | |
| 1162 | }); | |
| 1163 | // ISD->ThunkSections contains all created ThunkSections, including | |
| 1164 | // those inserted in previous passes. Extract the Thunks created this | |
| 1165 | // pass and order them in ascending OutSecOff. | |
| 1166 | std::vector<ThunkSection *> NewThunks; | |
| 1167 | for (const std::pair<ThunkSection *, uint32_t> TS : ISD->ThunkSections) | |
| 1168 | if (TS.second == Pass) | |
| 1169 | NewThunks.push_back(TS.first); | |
| 1170 | std::stable_sort(NewThunks.begin(), NewThunks.end(), | |
| 1171 | [](const ThunkSection *A, const ThunkSection *B) { | |
| 1172 | return A->OutSecOff < B->OutSecOff; | |
| 1173 | }); | |
| 1174 | ||
| 1175 | // Merge sorted vectors of Thunks and InputSections by OutSecOff | |
| 1176 | std::vector<InputSection *> Tmp; | |
| 1177 | Tmp.reserve(ISD->Sections.size() + NewThunks.size()); | |
| 1178 | auto MergeCmp = [](const InputSection *A, const InputSection *B) { | |
| 1179 | // std::merge requires a strict weak ordering. | |
| 1180 | if (A->OutSecOff < B->OutSecOff) | |
| 994 | 1181 | return true; |
| 995 | return false; | |
| 996 | }; | |
| 997 | std::merge(ISR->begin(), ISR->end(), Thunks.begin(), Thunks.end(), | |
| 998 | std::back_inserter(Tmp), MergeCmp); | |
| 999 | *ISR = std::move(Tmp); | |
| 1000 | } | |
| 1182 | if (A->OutSecOff == B->OutSecOff) { | |
| 1183 | auto *TA = dyn_cast<ThunkSection>(A); | |
| 1184 | auto *TB = dyn_cast<ThunkSection>(B); | |
| 1185 | // Check if Thunk is immediately before any specific Target | |
| 1186 | // InputSection for example Mips LA25 Thunks. | |
| 1187 | if (TA && TA->getTargetInputSection() == B) | |
| 1188 | return true; | |
| 1189 | if (TA && !TB && !TA->getTargetInputSection()) | |
| 1190 | // Place Thunk Sections without specific targets before | |
| 1191 | // non-Thunk Sections. | |
| 1192 | return true; | |
| 1193 | } | |
| 1194 | return false; | |
| 1195 | }; | |
| 1196 | std::merge(ISD->Sections.begin(), ISD->Sections.end(), | |
| 1197 | NewThunks.begin(), NewThunks.end(), std::back_inserter(Tmp), | |
| 1198 | MergeCmp); | |
| 1199 | ISD->Sections = std::move(Tmp); | |
| 1200 | }); | |
| 1001 | 1201 | } |
| 1002 | 1202 | |
| 1003 | static uint32_t findEndOfFirstNonExec(OutputSectionCommand &Cmd) { | |
| 1004 | for (BaseCommand *Base : Cmd.Commands) | |
| 1005 | if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) | |
| 1006 | for (auto *IS : ISD->Sections) | |
| 1007 | if ((IS->Flags & SHF_EXECINSTR) == 0) | |
| 1008 | return IS->OutSecOff + IS->getSize(); | |
| 1009 | return 0; | |
| 1010 | } | |
| 1203 | // Find or create a ThunkSection within the InputSectionDescription (ISD) that | |
| 1204 | // is in range of Src. An ISD maps to a range of InputSections described by a | |
| 1205 | // linker script section pattern such as { .text .text.* }. | |
| 1206 | ThunkSection *ThunkCreator::getISDThunkSec(OutputSection *OS, InputSection *IS, | |
| 1207 | InputSectionDescription *ISD, | |
| 1208 | uint32_t Type, uint64_t Src) { | |
| 1209 | for (std::pair<ThunkSection *, uint32_t> TP : ISD->ThunkSections) { | |
| 1210 | ThunkSection *TS = TP.first; | |
| 1211 | uint64_t TSBase = OS->Addr + TS->OutSecOff; | |
| 1212 | uint64_t TSLimit = TSBase + TS->getSize(); | |
| 1213 | if (Target->inBranchRange(Type, Src, (Src > TSLimit) ? TSBase : TSLimit)) | |
| 1214 | return TS; | |
| 1215 | } | |
| 1011 | 1216 | |
| 1012 | ThunkSection *ThunkCreator::getOSThunkSec(OutputSectionCommand *Cmd, | |
| 1013 | std::vector<InputSection *> *ISR) { | |
| 1014 | if (CurTS == nullptr) { | |
| 1015 | uint32_t Off = findEndOfFirstNonExec(*Cmd); | |
| 1016 | CurTS = addThunkSection(Cmd->Sec, ISR, Off); | |
| 1217 | // No suitable ThunkSection exists. This can happen when there is a branch | |
| 1218 | // with lower range than the ThunkSection spacing or when there are too | |
| 1219 | // many Thunks. Create a new ThunkSection as close to the InputSection as | |
| 1220 | // possible. Error if InputSection is so large we cannot place ThunkSection | |
| 1221 | // anywhere in Range. | |
| 1222 | uint64_t ThunkSecOff = IS->OutSecOff; | |
| 1223 | if (!Target->inBranchRange(Type, Src, OS->Addr + ThunkSecOff)) { | |
| 1224 | ThunkSecOff = IS->OutSecOff + IS->getSize(); | |
| 1225 | if (!Target->inBranchRange(Type, Src, OS->Addr + ThunkSecOff)) | |
| 1226 | fatal("InputSection too large for range extension thunk " + | |
| 1227 | IS->getObjMsg(Src - (OS->Addr + IS->OutSecOff))); | |
| 1017 | 1228 | } |
| 1018 | return CurTS; | |
| 1229 | return addThunkSection(OS, ISD, ThunkSecOff); | |
| 1019 | 1230 | } |
| 1020 | 1231 | |
| 1021 | ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS, OutputSection *OS) { | |
| 1232 | // Add a Thunk that needs to be placed in a ThunkSection that immediately | |
| 1233 | // precedes its Target. | |
| 1234 | ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) { | |
| 1022 | 1235 | ThunkSection *TS = ThunkedSections.lookup(IS); |
| 1023 | 1236 | if (TS) |
| 1024 | 1237 | return TS; |
| 1025 | auto *TOS = IS->getParent(); | |
| 1026 | 1238 | |
| 1027 | // Find InputSectionRange within TOS that IS is in | |
| 1028 | OutputSectionCommand *C = Script->getCmd(TOS); | |
| 1029 | std::vector<InputSection *> *Range = nullptr; | |
| 1030 | for (BaseCommand *BC : C->Commands) | |
| 1239 | // Find InputSectionRange within Target Output Section (TOS) that the | |
| 1240 | // InputSection (IS) that we need to precede is in. | |
| 1241 | OutputSection *TOS = IS->getParent(); | |
| 1242 | for (BaseCommand *BC : TOS->SectionCommands) | |
| 1031 | 1243 | if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) { |
| 1244 | if (ISD->Sections.empty()) | |
| 1245 | continue; | |
| 1032 | 1246 | InputSection *first = ISD->Sections.front(); |
| 1033 | 1247 | InputSection *last = ISD->Sections.back(); |
| 1034 | 1248 | if (IS->OutSecOff >= first->OutSecOff && |
| 1035 | 1249 | IS->OutSecOff <= last->OutSecOff) { |
| 1036 | Range = &ISD->Sections; | |
| 1250 | TS = addThunkSection(TOS, ISD, IS->OutSecOff); | |
| 1251 | ThunkedSections[IS] = TS; | |
| 1037 | 1252 | break; |
| 1038 | 1253 | } |
| 1039 | 1254 | } |
| 1040 | TS = addThunkSection(TOS, Range, IS->OutSecOff); | |
| 1041 | ThunkedSections[IS] = TS; | |
| 1042 | 1255 | return TS; |
| 1043 | 1256 | } |
| 1044 | 1257 | |
| 1258 | // Create one or more ThunkSections per OS that can be used to place Thunks. | |
| 1259 | // We attempt to place the ThunkSections using the following desirable | |
| 1260 | // properties: | |
| 1261 | // - Within range of the maximum number of callers | |
| 1262 | // - Minimise the number of ThunkSections | |
| 1263 | // | |
| 1264 | // We follow a simple but conservative heuristic to place ThunkSections at | |
| 1265 | // offsets that are multiples of a Target specific branch range. | |
| 1266 | // For an InputSectionRange that is smaller than the range, a single | |
| 1267 | // ThunkSection at the end of the range will do. | |
| 1268 | void ThunkCreator::createInitialThunkSections( | |
| 1269 | ArrayRef<OutputSection *> OutputSections) { | |
| 1270 | forEachInputSectionDescription( | |
| 1271 | OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) { | |
| 1272 | if (ISD->Sections.empty()) | |
| 1273 | return; | |
| 1274 | uint32_t ISLimit; | |
| 1275 | uint32_t PrevISLimit = ISD->Sections.front()->OutSecOff; | |
| 1276 | uint32_t ThunkUpperBound = PrevISLimit + Target->ThunkSectionSpacing; | |
| 1277 | ||
| 1278 | for (const InputSection *IS : ISD->Sections) { | |
| 1279 | ISLimit = IS->OutSecOff + IS->getSize(); | |
| 1280 | if (ISLimit > ThunkUpperBound) { | |
| 1281 | addThunkSection(OS, ISD, PrevISLimit); | |
| 1282 | ThunkUpperBound = PrevISLimit + Target->ThunkSectionSpacing; | |
| 1283 | } | |
| 1284 | PrevISLimit = ISLimit; | |
| 1285 | } | |
| 1286 | addThunkSection(OS, ISD, ISLimit); | |
| 1287 | }); | |
| 1288 | } | |
| 1289 | ||
| 1045 | 1290 | ThunkSection *ThunkCreator::addThunkSection(OutputSection *OS, |
| 1046 | std::vector<InputSection *> *ISR, | |
| 1291 | InputSectionDescription *ISD, | |
| 1047 | 1292 | uint64_t Off) { |
| 1048 | 1293 | auto *TS = make<ThunkSection>(OS, Off); |
| 1049 | ThunkSections[ISR].push_back(TS); | |
| 1294 | ISD->ThunkSections.push_back(std::make_pair(TS, Pass)); | |
| 1050 | 1295 | return TS; |
| 1051 | 1296 | } |
| 1052 | 1297 | |
| 1053 | std::pair<Thunk *, bool> ThunkCreator::getThunk(SymbolBody &Body, | |
| 1054 | uint32_t Type) { | |
| 1055 | auto Res = ThunkedSymbols.insert({&Body, std::vector<Thunk *>()}); | |
| 1298 | std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type, | |
| 1299 | uint64_t Src) { | |
| 1300 | auto Res = ThunkedSymbols.insert({&Sym, std::vector<Thunk *>()}); | |
| 1056 | 1301 | if (!Res.second) { |
| 1057 | // Check existing Thunks for Body to see if they can be reused | |
| 1302 | // Check existing Thunks for Sym to see if they can be reused | |
| 1058 | 1303 | for (Thunk *ET : Res.first->second) |
| 1059 | if (ET->isCompatibleWith(Type)) | |
| 1304 | if (ET->isCompatibleWith(Type) && | |
| 1305 | Target->inBranchRange(Type, Src, ET->ThunkSym->getVA())) | |
| 1060 | 1306 | return std::make_pair(ET, false); |
| 1061 | 1307 | } |
| 1062 | 1308 | // No existing compatible Thunk in range, create a new one |
| 1063 | Thunk *T = addThunk(Type, Body); | |
| 1309 | Thunk *T = addThunk(Type, Sym); | |
| 1064 | 1310 | Res.first->second.push_back(T); |
| 1065 | 1311 | return std::make_pair(T, true); |
| 1066 | 1312 | } |
| 1067 | 1313 | |
| 1068 | 1314 | // Call Fn on every executable InputSection accessed via the linker script |
| 1069 | 1315 | // InputSectionDescription::Sections. |
| 1070 | void ThunkCreator::forEachExecInputSection( | |
| 1071 | ArrayRef<OutputSectionCommand *> OutputSections, | |
| 1072 | std::function<void(OutputSectionCommand *, std::vector<InputSection *> *, | |
| 1073 | InputSection *)> | |
| 1074 | Fn) { | |
| 1075 | for (OutputSectionCommand *Cmd : OutputSections) { | |
| 1076 | OutputSection *OS = Cmd->Sec; | |
| 1316 | void ThunkCreator::forEachInputSectionDescription( | |
| 1317 | ArrayRef<OutputSection *> OutputSections, | |
| 1318 | std::function<void(OutputSection *, InputSectionDescription *)> Fn) { | |
| 1319 | for (OutputSection *OS : OutputSections) { | |
| 1077 | 1320 | if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR)) |
| 1078 | 1321 | continue; |
| 1079 | for (BaseCommand *BC : Cmd->Commands) | |
| 1080 | if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) { | |
| 1081 | CurTS = nullptr; | |
| 1082 | for (InputSection *IS : ISD->Sections) | |
| 1083 | Fn(Cmd, &ISD->Sections, IS); | |
| 1084 | } | |
| 1322 | for (BaseCommand *BC : OS->SectionCommands) | |
| 1323 | if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) | |
| 1324 | Fn(OS, ISD); | |
| 1085 | 1325 | } |
| 1086 | 1326 | } |
| 1087 | 1327 | |
| 1328 | // Return true if the relocation target is an in range Thunk. | |
| 1329 | // Return false if the relocation is not to a Thunk. If the relocation target | |
| 1330 | // was originally to a Thunk, but is no longer in range we revert the | |
| 1331 | // relocation back to its original non-Thunk target. | |
| 1332 | bool ThunkCreator::normalizeExistingThunk(Relocation &Rel, uint64_t Src) { | |
| 1333 | if (Thunk *ET = Thunks.lookup(Rel.Sym)) { | |
| 1334 | if (Target->inBranchRange(Rel.Type, Src, Rel.Sym->getVA())) | |
| 1335 | return true; | |
| 1336 | Rel.Sym = &ET->Destination; | |
| 1337 | if (Rel.Sym->isInPlt()) | |
| 1338 | Rel.Expr = toPlt(Rel.Expr); | |
| 1339 | } | |
| 1340 | return false; | |
| 1341 | } | |
| 1342 | ||
| 1088 | 1343 | // Process all relocations from the InputSections that have been assigned |
| 1089 | // to OutputSections and redirect through Thunks if needed. | |
| 1344 | // to InputSectionDescriptions and redirect through Thunks if needed. The | |
| 1345 | // function should be called iteratively until it returns false. | |
| 1346 | // | |
| 1347 | // PreConditions: | |
| 1348 | // All InputSections that may need a Thunk are reachable from | |
| 1349 | // OutputSectionCommands. | |
| 1090 | 1350 | // |
| 1091 | // createThunks must be called after scanRelocs has created the Relocations for | |
| 1092 | // each InputSection. It must be called before the static symbol table is | |
| 1093 | // finalized. If any Thunks are added to an OutputSection the output section | |
| 1094 | // offsets of the InputSections will change. | |
| 1351 | // All OutputSections have an address and all InputSections have an offset | |
| 1352 | // within the OutputSection. | |
| 1095 | 1353 | // |
| 1096 | // FIXME: All Thunks are assumed to be in range of the relocation. Range | |
| 1097 | // extension Thunks are not yet supported. | |
| 1098 | bool ThunkCreator::createThunks( | |
| 1099 | ArrayRef<OutputSectionCommand *> OutputSections) { | |
| 1100 | if (Pass > 0) | |
| 1101 | ThunkSections.clear(); | |
| 1354 | // The offsets between caller (relocation place) and callee | |
| 1355 | // (relocation target) will not be modified outside of createThunks(). | |
| 1356 | // | |
| 1357 | // PostConditions: | |
| 1358 | // If return value is true then ThunkSections have been inserted into | |
| 1359 | // OutputSections. All relocations that needed a Thunk based on the information | |
| 1360 | // available to createThunks() on entry have been redirected to a Thunk. Note | |
| 1361 | // that adding Thunks changes offsets between caller and callee so more Thunks | |
| 1362 | // may be required. | |
| 1363 | // | |
| 1364 | // If return value is false then no more Thunks are needed, and createThunks has | |
| 1365 | // made no changes. If the target requires range extension thunks, currently | |
| 1366 | // ARM, then any future change in offset between caller and callee risks a | |
| 1367 | // relocation out of range error. | |
| 1368 | bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) { | |
| 1369 | bool AddressesChanged = false; | |
| 1370 | if (Pass == 0 && Target->ThunkSectionSpacing) | |
| 1371 | createInitialThunkSections(OutputSections); | |
| 1372 | else if (Pass == 10) | |
| 1373 | // With Thunk Size much smaller than branch range we expect to | |
| 1374 | // converge quickly; if we get to 10 something has gone wrong. | |
| 1375 | fatal("thunk creation not converged"); | |
| 1102 | 1376 | |
| 1103 | 1377 | // Create all the Thunks and insert them into synthetic ThunkSections. The |
| 1104 | // ThunkSections are later inserted back into the OutputSection. | |
| 1105 | ||
| 1378 | // ThunkSections are later inserted back into InputSectionDescriptions. | |
| 1106 | 1379 | // We separate the creation of ThunkSections from the insertion of the |
| 1107 | // ThunkSections back into the OutputSection as ThunkSections are not always | |
| 1108 | // inserted into the same OutputSection as the caller. | |
| 1109 | forEachExecInputSection(OutputSections, [&](OutputSectionCommand *Cmd, | |
| 1110 | std::vector<InputSection *> *ISR, | |
| 1111 | InputSection *IS) { | |
| 1112 | for (Relocation &Rel : IS->Relocations) { | |
| 1113 | SymbolBody &Body = *Rel.Sym; | |
| 1114 | if (Thunks.find(&Body) != Thunks.end() || | |
| 1115 | !Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Body)) | |
| 1116 | continue; | |
| 1117 | Thunk *T; | |
| 1118 | bool IsNew; | |
| 1119 | std::tie(T, IsNew) = getThunk(Body, Rel.Type); | |
| 1120 | if (IsNew) { | |
| 1121 | // Find or create a ThunkSection for the new Thunk | |
| 1122 | ThunkSection *TS; | |
| 1123 | if (auto *TIS = T->getTargetInputSection()) | |
| 1124 | TS = getISThunkSec(TIS, Cmd->Sec); | |
| 1125 | else | |
| 1126 | TS = getOSThunkSec(Cmd, ISR); | |
| 1127 | TS->addThunk(T); | |
| 1128 | Thunks[T->ThunkSym] = T; | |
| 1129 | } | |
| 1130 | // Redirect relocation to Thunk, we never go via the PLT to a Thunk | |
| 1131 | Rel.Sym = T->ThunkSym; | |
| 1132 | Rel.Expr = fromPlt(Rel.Expr); | |
| 1133 | } | |
| 1134 | }); | |
| 1380 | // ThunkSections as ThunkSections are not always inserted into the same | |
| 1381 | // InputSectionDescription as the caller. | |
| 1382 | forEachInputSectionDescription( | |
| 1383 | OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) { | |
| 1384 | for (InputSection *IS : ISD->Sections) | |
| 1385 | for (Relocation &Rel : IS->Relocations) { | |
| 1386 | uint64_t Src = OS->Addr + IS->OutSecOff + Rel.Offset; | |
| 1387 | ||
| 1388 | // 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 | |
| 1390 | // original target so another Thunk can be generated. | |
| 1391 | if (Pass > 0 && normalizeExistingThunk(Rel, Src)) | |
| 1392 | continue; | |
| 1393 | ||
| 1394 | if (!Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Src, | |
| 1395 | *Rel.Sym)) | |
| 1396 | continue; | |
| 1397 | Thunk *T; | |
| 1398 | bool IsNew; | |
| 1399 | std::tie(T, IsNew) = getThunk(*Rel.Sym, Rel.Type, Src); | |
| 1400 | if (IsNew) { | |
| 1401 | AddressesChanged = true; | |
| 1402 | // Find or create a ThunkSection for the new Thunk | |
| 1403 | ThunkSection *TS; | |
| 1404 | if (auto *TIS = T->getTargetInputSection()) | |
| 1405 | TS = getISThunkSec(TIS); | |
| 1406 | else | |
| 1407 | TS = getISDThunkSec(OS, IS, ISD, Rel.Type, Src); | |
| 1408 | TS->addThunk(T); | |
| 1409 | Thunks[T->ThunkSym] = T; | |
| 1410 | } | |
| 1411 | // Redirect relocation to Thunk, we never go via the PLT to a Thunk | |
| 1412 | Rel.Sym = T->ThunkSym; | |
| 1413 | Rel.Expr = fromPlt(Rel.Expr); | |
| 1414 | } | |
| 1415 | }); | |
| 1135 | 1416 | // Merge all created synthetic ThunkSections back into OutputSection |
| 1136 | mergeThunks(); | |
| 1417 | mergeThunks(OutputSections); | |
| 1137 | 1418 | ++Pass; |
| 1138 | return !ThunkSections.empty(); | |
| 1419 | return AddressesChanged; | |
| 1139 | 1420 | } |
| 1140 | 1421 | |
| 1141 | 1422 | template void elf::scanRelocations<ELF32LE>(InputSectionBase &); |
deps/lld/ELF/Relocations.h+34-30| ... | ... | @@ -10,23 +10,27 @@ |
| 10 | 10 | #ifndef LLD_ELF_RELOCATIONS_H |
| 11 | 11 | #define LLD_ELF_RELOCATIONS_H |
| 12 | 12 | |
| 13 | #include "lld/Core/LLVM.h" | |
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | 14 | #include "llvm/ADT/DenseMap.h" |
| 15 | 15 | #include <map> |
| 16 | 16 | #include <vector> |
| 17 | 17 | |
| 18 | 18 | namespace lld { |
| 19 | 19 | namespace elf { |
| 20 | class SymbolBody; | |
| 20 | class Symbol; | |
| 21 | 21 | class InputSection; |
| 22 | 22 | class InputSectionBase; |
| 23 | 23 | class OutputSection; |
| 24 | struct OutputSectionCommand; | |
| 24 | class OutputSection; | |
| 25 | ||
| 26 | // Represents a relocation type, such as R_X86_64_PC32 or R_ARM_THM_CALL. | |
| 27 | typedef uint32_t RelType; | |
| 25 | 28 | |
| 26 | 29 | // List of target-independent relocation types. Relocations read |
| 27 | 30 | // from files are converted to these types so that the main code |
| 28 | 31 | // doesn't have to know about architecture-specific details. |
| 29 | 32 | enum RelExpr { |
| 33 | R_INVALID, | |
| 30 | 34 | R_ABS, |
| 31 | 35 | R_ARM_SBREL, |
| 32 | 36 | R_GOT, |
| ... | ... | @@ -111,21 +115,22 @@ template <RelExpr... Exprs> bool isRelExprOneOf(RelExpr Expr) { |
| 111 | 115 | // Architecture-neutral representation of relocation. |
| 112 | 116 | struct Relocation { |
| 113 | 117 | RelExpr Expr; |
| 114 | uint32_t Type; | |
| 118 | RelType Type; | |
| 115 | 119 | uint64_t Offset; |
| 116 | 120 | int64_t Addend; |
| 117 | SymbolBody *Sym; | |
| 121 | Symbol *Sym; | |
| 118 | 122 | }; |
| 119 | 123 | |
| 120 | 124 | template <class ELFT> void scanRelocations(InputSectionBase &); |
| 121 | 125 | |
| 122 | 126 | class ThunkSection; |
| 123 | 127 | class Thunk; |
| 128 | struct InputSectionDescription; | |
| 124 | 129 | |
| 125 | 130 | class ThunkCreator { |
| 126 | 131 | public: |
| 127 | 132 | // Return true if Thunks have been added to OutputSections |
| 128 | bool createThunks(ArrayRef<OutputSectionCommand *> OutputSections); | |
| 133 | bool createThunks(ArrayRef<OutputSection *> OutputSections); | |
| 129 | 134 | |
| 130 | 135 | // The number of completed passes of createThunks this permits us |
| 131 | 136 | // to do one time initialization on Pass 0 and put a limit on the |
| ... | ... | @@ -133,40 +138,39 @@ public: |
| 133 | 138 | uint32_t Pass = 0; |
| 134 | 139 | |
| 135 | 140 | private: |
| 136 | void mergeThunks(); | |
| 137 | ThunkSection *getOSThunkSec(OutputSectionCommand *Cmd, | |
| 138 | std::vector<InputSection *> *ISR); | |
| 139 | ThunkSection *getISThunkSec(InputSection *IS, OutputSection *OS); | |
| 140 | void forEachExecInputSection( | |
| 141 | ArrayRef<OutputSectionCommand *> OutputSections, | |
| 142 | std::function<void(OutputSectionCommand *, std::vector<InputSection *> *, | |
| 143 | InputSection *)> | |
| 144 | Fn); | |
| 145 | std::pair<Thunk *, bool> getThunk(SymbolBody &Body, uint32_t Type); | |
| 146 | ThunkSection *addThunkSection(OutputSection *OS, | |
| 147 | std::vector<InputSection *> *, uint64_t Off); | |
| 141 | void mergeThunks(ArrayRef<OutputSection *> OutputSections); | |
| 142 | ||
| 143 | ThunkSection *getISDThunkSec(OutputSection *OS, InputSection *IS, | |
| 144 | InputSectionDescription *ISD, uint32_t Type, | |
| 145 | uint64_t Src); | |
| 146 | ||
| 147 | ThunkSection *getISThunkSec(InputSection *IS); | |
| 148 | ||
| 149 | void createInitialThunkSections(ArrayRef<OutputSection *> OutputSections); | |
| 150 | ||
| 151 | void forEachInputSectionDescription( | |
| 152 | ArrayRef<OutputSection *> OutputSections, | |
| 153 | std::function<void(OutputSection *, InputSectionDescription *)> Fn); | |
| 154 | ||
| 155 | std::pair<Thunk *, bool> getThunk(Symbol &Sym, RelType Type, uint64_t Src); | |
| 156 | ||
| 157 | ThunkSection *addThunkSection(OutputSection *OS, InputSectionDescription *, | |
| 158 | uint64_t Off); | |
| 159 | ||
| 160 | bool normalizeExistingThunk(Relocation &Rel, uint64_t Src); | |
| 161 | ||
| 148 | 162 | // Record all the available Thunks for a Symbol |
| 149 | llvm::DenseMap<SymbolBody *, std::vector<Thunk *>> ThunkedSymbols; | |
| 163 | llvm::DenseMap<Symbol *, std::vector<Thunk *>> ThunkedSymbols; | |
| 150 | 164 | |
| 151 | 165 | // Find a Thunk from the Thunks symbol definition, we can use this to find |
| 152 | 166 | // the Thunk from a relocation to the Thunks symbol definition. |
| 153 | llvm::DenseMap<SymbolBody *, Thunk *> Thunks; | |
| 167 | llvm::DenseMap<Symbol *, Thunk *> Thunks; | |
| 154 | 168 | |
| 155 | 169 | // Track InputSections that have an inline ThunkSection placed in front |
| 156 | 170 | // an inline ThunkSection may have control fall through to the section below |
| 157 | 171 | // so we need to make sure that there is only one of them. |
| 158 | 172 | // The Mips LA25 Thunk is an example of an inline ThunkSection. |
| 159 | 173 | llvm::DenseMap<InputSection *, ThunkSection *> ThunkedSections; |
| 160 | ||
| 161 | // All the ThunkSections that we have created, organised by OutputSection | |
| 162 | // will contain a mix of ThunkSections that have been created this pass, and | |
| 163 | // ThunkSections that have been merged into the OutputSection on previous | |
| 164 | // passes | |
| 165 | std::map<std::vector<InputSection *> *, std::vector<ThunkSection *>> | |
| 166 | ThunkSections; | |
| 167 | ||
| 168 | // The ThunkSection for this vector of InputSections | |
| 169 | ThunkSection *CurTS; | |
| 170 | 174 | }; |
| 171 | 175 | |
| 172 | 176 | // Return a int64_t to make sure we get the sign extension out of the way as |
deps/lld/ELF/ScriptLexer.cpp+31-23| ... | ... | @@ -33,7 +33,7 @@ |
| 33 | 33 | //===----------------------------------------------------------------------===// |
| 34 | 34 | |
| 35 | 35 | #include "ScriptLexer.h" |
| 36 | #include "Error.h" | |
| 36 | #include "lld/Common/ErrorHandler.h" | |
| 37 | 37 | #include "llvm/ADT/Twine.h" |
| 38 | 38 | |
| 39 | 39 | using namespace llvm; |
| ... | ... | @@ -75,19 +75,14 @@ ScriptLexer::ScriptLexer(MemoryBufferRef MB) { tokenize(MB); } |
| 75 | 75 | |
| 76 | 76 | // We don't want to record cascading errors. Keep only the first one. |
| 77 | 77 | void ScriptLexer::setError(const Twine &Msg) { |
| 78 | if (Error) | |
| 78 | if (errorCount()) | |
| 79 | 79 | return; |
| 80 | Error = true; | |
| 81 | 80 | |
| 82 | if (!Pos) { | |
| 83 | error(getCurrentLocation() + ": " + Msg); | |
| 84 | return; | |
| 85 | } | |
| 86 | ||
| 87 | std::string S = getCurrentLocation() + ": "; | |
| 88 | error(S + Msg); | |
| 89 | error(S + getLine()); | |
| 90 | error(S + std::string(getColumnNumber(), ' ') + "^"); | |
| 81 | std::string S = (getCurrentLocation() + ": " + Msg).str(); | |
| 82 | if (Pos) | |
| 83 | S += "\n>>> " + getLine().str() + "\n>>> " + | |
| 84 | std::string(getColumnNumber(), ' ') + "^"; | |
| 85 | error(S); | |
| 91 | 86 | } |
| 92 | 87 | |
| 93 | 88 | // Split S into linker script tokens. |
| ... | ... | @@ -120,11 +115,19 @@ void ScriptLexer::tokenize(MemoryBufferRef MB) { |
| 120 | 115 | continue; |
| 121 | 116 | } |
| 122 | 117 | |
| 118 | // ">foo" is parsed to ">" and "foo", but ">>" is parsed to ">>". | |
| 119 | if (S.startswith("<<") || S.startswith("<=") || S.startswith(">>") || | |
| 120 | S.startswith(">=")) { | |
| 121 | Vec.push_back(S.substr(0, 2)); | |
| 122 | S = S.substr(2); | |
| 123 | continue; | |
| 124 | } | |
| 125 | ||
| 123 | 126 | // Unquoted token. This is more relaxed than tokens in C-like language, |
| 124 | 127 | // so that you can write "file-name.cpp" as one bare token, for example. |
| 125 | 128 | size_t Pos = S.find_first_not_of( |
| 126 | 129 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" |
| 127 | "0123456789_.$/\\~=+[]*?-!<>^:"); | |
| 130 | "0123456789_.$/\\~=+[]*?-!^:"); | |
| 128 | 131 | |
| 129 | 132 | // A character that cannot start a word (which is usually a |
| 130 | 133 | // punctuation) forms a single character token. |
| ... | ... | @@ -164,18 +167,18 @@ StringRef ScriptLexer::skipSpace(StringRef S) { |
| 164 | 167 | } |
| 165 | 168 | |
| 166 | 169 | // An erroneous token is handled as if it were the last token before EOF. |
| 167 | bool ScriptLexer::atEOF() { return Error || Tokens.size() == Pos; } | |
| 170 | bool ScriptLexer::atEOF() { return errorCount() || Tokens.size() == Pos; } | |
| 168 | 171 | |
| 169 | 172 | // Split a given string as an expression. |
| 170 | 173 | // This function returns "3", "*" and "5" for "3*5" for example. |
| 171 | 174 | static std::vector<StringRef> tokenizeExpr(StringRef S) { |
| 172 | StringRef Ops = "+-*/:"; // List of operators | |
| 175 | StringRef Ops = "+-*/:!~"; // List of operators | |
| 173 | 176 | |
| 174 | 177 | // Quoted strings are literal strings, so we don't want to split it. |
| 175 | 178 | if (S.startswith("\"")) |
| 176 | 179 | return {S}; |
| 177 | 180 | |
| 178 | // Split S with +-*/ as separators. | |
| 181 | // Split S with operators as separators. | |
| 179 | 182 | std::vector<StringRef> Ret; |
| 180 | 183 | while (!S.empty()) { |
| 181 | 184 | size_t E = S.find_first_of(Ops); |
| ... | ... | @@ -190,9 +193,14 @@ static std::vector<StringRef> tokenizeExpr(StringRef S) { |
| 190 | 193 | if (E != 0) |
| 191 | 194 | Ret.push_back(S.substr(0, E)); |
| 192 | 195 | |
| 193 | // Get the operator as a token. | |
| 194 | Ret.push_back(S.substr(E, 1)); | |
| 195 | S = S.substr(E + 1); | |
| 196 | // Get the operator as a token. Keep != as one token. | |
| 197 | if (S.substr(E).startswith("!=")) { | |
| 198 | Ret.push_back(S.substr(E, 2)); | |
| 199 | S = S.substr(E + 2); | |
| 200 | } else { | |
| 201 | Ret.push_back(S.substr(E, 1)); | |
| 202 | S = S.substr(E + 1); | |
| 203 | } | |
| 196 | 204 | } |
| 197 | 205 | return Ret; |
| 198 | 206 | } |
| ... | ... | @@ -207,7 +215,7 @@ static std::vector<StringRef> tokenizeExpr(StringRef S) { |
| 207 | 215 | // |
| 208 | 216 | // This function may split the current token into multiple tokens. |
| 209 | 217 | void ScriptLexer::maybeSplitExpr() { |
| 210 | if (!InExpr || Error || atEOF()) | |
| 218 | if (!InExpr || errorCount() || atEOF()) | |
| 211 | 219 | return; |
| 212 | 220 | |
| 213 | 221 | std::vector<StringRef> V = tokenizeExpr(Tokens[Pos]); |
| ... | ... | @@ -220,7 +228,7 @@ void ScriptLexer::maybeSplitExpr() { |
| 220 | 228 | StringRef ScriptLexer::next() { |
| 221 | 229 | maybeSplitExpr(); |
| 222 | 230 | |
| 223 | if (Error) | |
| 231 | if (errorCount()) | |
| 224 | 232 | return ""; |
| 225 | 233 | if (atEOF()) { |
| 226 | 234 | setError("unexpected EOF"); |
| ... | ... | @@ -231,7 +239,7 @@ StringRef ScriptLexer::next() { |
| 231 | 239 | |
| 232 | 240 | StringRef ScriptLexer::peek() { |
| 233 | 241 | StringRef Tok = next(); |
| 234 | if (Error) | |
| 242 | if (errorCount()) | |
| 235 | 243 | return ""; |
| 236 | 244 | Pos = Pos - 1; |
| 237 | 245 | return Tok; |
| ... | ... | @@ -260,7 +268,7 @@ bool ScriptLexer::consumeLabel(StringRef Tok) { |
| 260 | 268 | void ScriptLexer::skip() { (void)next(); } |
| 261 | 269 | |
| 262 | 270 | void ScriptLexer::expect(StringRef Expect) { |
| 263 | if (Error) | |
| 271 | if (errorCount()) | |
| 264 | 272 | return; |
| 265 | 273 | StringRef Tok = next(); |
| 266 | 274 | if (Tok != Expect) |
deps/lld/ELF/ScriptLexer.h+1-2| ... | ... | @@ -10,7 +10,7 @@ |
| 10 | 10 | #ifndef LLD_ELF_SCRIPT_LEXER_H |
| 11 | 11 | #define LLD_ELF_SCRIPT_LEXER_H |
| 12 | 12 | |
| 13 | #include "lld/Core/LLVM.h" | |
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | 14 | #include "llvm/ADT/StringRef.h" |
| 15 | 15 | #include "llvm/Support/MemoryBuffer.h" |
| 16 | 16 | #include <utility> |
| ... | ... | @@ -39,7 +39,6 @@ public: |
| 39 | 39 | std::vector<StringRef> Tokens; |
| 40 | 40 | bool InExpr = false; |
| 41 | 41 | size_t Pos = 0; |
| 42 | bool Error = false; | |
| 43 | 42 | |
| 44 | 43 | private: |
| 45 | 44 | void maybeSplitExpr(); |
deps/lld/ELF/ScriptParser.cpp+206-108| ... | ... | @@ -17,13 +17,14 @@ |
| 17 | 17 | #include "Driver.h" |
| 18 | 18 | #include "InputSection.h" |
| 19 | 19 | #include "LinkerScript.h" |
| 20 | #include "Memory.h" | |
| 21 | 20 | #include "OutputSections.h" |
| 22 | 21 | #include "ScriptLexer.h" |
| 23 | 22 | #include "Symbols.h" |
| 24 | 23 | #include "Target.h" |
| 24 | #include "lld/Common/Memory.h" | |
| 25 | 25 | #include "llvm/ADT/SmallString.h" |
| 26 | 26 | #include "llvm/ADT/StringRef.h" |
| 27 | #include "llvm/ADT/StringSet.h" | |
| 27 | 28 | #include "llvm/ADT/StringSwitch.h" |
| 28 | 29 | #include "llvm/BinaryFormat/ELF.h" |
| 29 | 30 | #include "llvm/Support/Casting.h" |
| ... | ... | @@ -52,10 +53,10 @@ public: |
| 52 | 53 | void readLinkerScript(); |
| 53 | 54 | void readVersionScript(); |
| 54 | 55 | void readDynamicList(); |
| 56 | void readDefsym(StringRef Name); | |
| 55 | 57 | |
| 56 | 58 | private: |
| 57 | 59 | void addFile(StringRef Path); |
| 58 | OutputSection *checkSection(OutputSectionCommand *Cmd, StringRef Loccation); | |
| 59 | 60 | |
| 60 | 61 | void readAsNeeded(); |
| 61 | 62 | void readEntry(); |
| ... | ... | @@ -67,17 +68,18 @@ private: |
| 67 | 68 | void readOutputArch(); |
| 68 | 69 | void readOutputFormat(); |
| 69 | 70 | void readPhdrs(); |
| 71 | void readRegionAlias(); | |
| 70 | 72 | void readSearchDir(); |
| 71 | 73 | void readSections(); |
| 72 | 74 | void readVersion(); |
| 73 | 75 | void readVersionScriptCommand(); |
| 74 | 76 | |
| 75 | 77 | SymbolAssignment *readAssignment(StringRef Name); |
| 76 | BytesDataCommand *readBytesDataCommand(StringRef Tok); | |
| 78 | ByteCommand *readByteCommand(StringRef Tok); | |
| 77 | 79 | uint32_t readFill(); |
| 78 | 80 | uint32_t parseFill(StringRef Tok); |
| 79 | void readSectionAddressType(OutputSectionCommand *Cmd); | |
| 80 | OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); | |
| 81 | void readSectionAddressType(OutputSection *Cmd); | |
| 82 | OutputSection *readOutputSectionDescription(StringRef OutSec); | |
| 81 | 83 | std::vector<StringRef> readOutputSectionPhdrs(); |
| 82 | 84 | InputSectionDescription *readInputSectionDescription(StringRef Tok); |
| 83 | 85 | StringMatcher readFilePatterns(); |
| ... | ... | @@ -90,6 +92,8 @@ private: |
| 90 | 92 | void readSort(); |
| 91 | 93 | AssertCommand *readAssert(); |
| 92 | 94 | Expr readAssertExpr(); |
| 95 | Expr readConstant(); | |
| 96 | Expr getPageSize(); | |
| 93 | 97 | |
| 94 | 98 | uint64_t readMemoryAssignment(StringRef, StringRef, StringRef); |
| 95 | 99 | std::pair<uint32_t, uint32_t> readMemoryAttributes(); |
| ... | ... | @@ -109,7 +113,11 @@ private: |
| 109 | 113 | std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> |
| 110 | 114 | readSymbols(); |
| 111 | 115 | |
| 116 | // True if a script being read is in a subdirectory specified by -sysroot. | |
| 112 | 117 | bool IsUnderSysroot; |
| 118 | ||
| 119 | // A set to detect an INCLUDE() cycle. | |
| 120 | StringSet<> Seen; | |
| 113 | 121 | }; |
| 114 | 122 | } // namespace |
| 115 | 123 | |
| ... | ... | @@ -131,7 +139,7 @@ static bool isUnderSysroot(StringRef Path) { |
| 131 | 139 | // Some operations only support one non absolute value. Move the |
| 132 | 140 | // absolute one to the right hand side for convenience. |
| 133 | 141 | static void moveAbsRight(ExprValue &A, ExprValue &B) { |
| 134 | if (A.isAbsolute()) | |
| 142 | if (A.Sec == nullptr || (A.ForceAbsolute && !B.isAbsolute())) | |
| 135 | 143 | std::swap(A, B); |
| 136 | 144 | if (!B.isAbsolute()) |
| 137 | 145 | error(A.Loc + ": at least one side of the expression must be absolute"); |
| ... | ... | @@ -139,11 +147,14 @@ static void moveAbsRight(ExprValue &A, ExprValue &B) { |
| 139 | 147 | |
| 140 | 148 | static ExprValue add(ExprValue A, ExprValue B) { |
| 141 | 149 | moveAbsRight(A, B); |
| 142 | return {A.Sec, A.ForceAbsolute, A.Val + B.getValue(), A.Loc}; | |
| 150 | return {A.Sec, A.ForceAbsolute, A.getSectionOffset() + B.getValue(), A.Loc}; | |
| 143 | 151 | } |
| 144 | 152 | |
| 145 | 153 | static ExprValue sub(ExprValue A, ExprValue B) { |
| 146 | return {A.Sec, A.Val - B.getValue(), A.Loc}; | |
| 154 | // The distance between two symbols in sections is absolute. | |
| 155 | if (!A.isAbsolute() && !B.isAbsolute()) | |
| 156 | return A.getValue() - B.getValue(); | |
| 157 | return {A.Sec, false, A.getSectionOffset() - B.getValue(), A.Loc}; | |
| 147 | 158 | } |
| 148 | 159 | |
| 149 | 160 | static ExprValue mul(ExprValue A, ExprValue B) { |
| ... | ... | @@ -170,10 +181,24 @@ static ExprValue bitOr(ExprValue A, ExprValue B) { |
| 170 | 181 | } |
| 171 | 182 | |
| 172 | 183 | void ScriptParser::readDynamicList() { |
| 184 | Config->HasDynamicList = true; | |
| 173 | 185 | expect("{"); |
| 174 | readAnonymousDeclaration(); | |
| 175 | if (!atEOF()) | |
| 186 | std::vector<SymbolVersion> Locals; | |
| 187 | std::vector<SymbolVersion> Globals; | |
| 188 | std::tie(Locals, Globals) = readSymbols(); | |
| 189 | expect(";"); | |
| 190 | ||
| 191 | if (!atEOF()) { | |
| 176 | 192 | setError("EOF expected, but got " + next()); |
| 193 | return; | |
| 194 | } | |
| 195 | if (!Locals.empty()) { | |
| 196 | setError("\"local:\" scope not supported in --dynamic-list"); | |
| 197 | return; | |
| 198 | } | |
| 199 | ||
| 200 | for (SymbolVersion V : Globals) | |
| 201 | Config->DynamicList.push_back(V); | |
| 177 | 202 | } |
| 178 | 203 | |
| 179 | 204 | void ScriptParser::readVersionScript() { |
| ... | ... | @@ -188,7 +213,7 @@ void ScriptParser::readVersionScriptCommand() { |
| 188 | 213 | return; |
| 189 | 214 | } |
| 190 | 215 | |
| 191 | while (!atEOF() && !Error && peek() != "}") { | |
| 216 | while (!atEOF() && !errorCount() && peek() != "}") { | |
| 192 | 217 | StringRef VerStr = next(); |
| 193 | 218 | if (VerStr == "{") { |
| 194 | 219 | setError("anonymous version definition is used in " |
| ... | ... | @@ -213,7 +238,7 @@ void ScriptParser::readLinkerScript() { |
| 213 | 238 | continue; |
| 214 | 239 | |
| 215 | 240 | if (Tok == "ASSERT") { |
| 216 | Script->Opt.Commands.push_back(readAssert()); | |
| 241 | Script->SectionCommands.push_back(readAssert()); | |
| 217 | 242 | } else if (Tok == "ENTRY") { |
| 218 | 243 | readEntry(); |
| 219 | 244 | } else if (Tok == "EXTERN") { |
| ... | ... | @@ -232,6 +257,8 @@ void ScriptParser::readLinkerScript() { |
| 232 | 257 | readOutputFormat(); |
| 233 | 258 | } else if (Tok == "PHDRS") { |
| 234 | 259 | readPhdrs(); |
| 260 | } else if (Tok == "REGION_ALIAS") { | |
| 261 | readRegionAlias(); | |
| 235 | 262 | } else if (Tok == "SEARCH_DIR") { |
| 236 | 263 | readSearchDir(); |
| 237 | 264 | } else if (Tok == "SECTIONS") { |
| ... | ... | @@ -239,13 +266,21 @@ void ScriptParser::readLinkerScript() { |
| 239 | 266 | } else if (Tok == "VERSION") { |
| 240 | 267 | readVersion(); |
| 241 | 268 | } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) { |
| 242 | Script->Opt.Commands.push_back(Cmd); | |
| 269 | Script->SectionCommands.push_back(Cmd); | |
| 243 | 270 | } else { |
| 244 | 271 | setError("unknown directive: " + Tok); |
| 245 | 272 | } |
| 246 | 273 | } |
| 247 | 274 | } |
| 248 | 275 | |
| 276 | void ScriptParser::readDefsym(StringRef Name) { | |
| 277 | Expr E = readExpr(); | |
| 278 | if (!atEOF()) | |
| 279 | setError("EOF expected, but got " + next()); | |
| 280 | SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation()); | |
| 281 | Script->SectionCommands.push_back(Cmd); | |
| 282 | } | |
| 283 | ||
| 249 | 284 | void ScriptParser::addFile(StringRef S) { |
| 250 | 285 | if (IsUnderSysroot && S.startswith("/")) { |
| 251 | 286 | SmallString<128> PathData; |
| ... | ... | @@ -256,7 +291,7 @@ void ScriptParser::addFile(StringRef S) { |
| 256 | 291 | } |
| 257 | 292 | } |
| 258 | 293 | |
| 259 | if (sys::path::is_absolute(S)) { | |
| 294 | if (S.startswith("/")) { | |
| 260 | 295 | Driver->addFile(S, /*WithLOption=*/false); |
| 261 | 296 | } else if (S.startswith("=")) { |
| 262 | 297 | if (Config->Sysroot.empty()) |
| ... | ... | @@ -280,7 +315,7 @@ void ScriptParser::readAsNeeded() { |
| 280 | 315 | expect("("); |
| 281 | 316 | bool Orig = Config->AsNeeded; |
| 282 | 317 | Config->AsNeeded = true; |
| 283 | while (!Error && !consume(")")) | |
| 318 | while (!errorCount() && !consume(")")) | |
| 284 | 319 | addFile(unquote(next())); |
| 285 | 320 | Config->AsNeeded = Orig; |
| 286 | 321 | } |
| ... | ... | @@ -296,13 +331,13 @@ void ScriptParser::readEntry() { |
| 296 | 331 | |
| 297 | 332 | void ScriptParser::readExtern() { |
| 298 | 333 | expect("("); |
| 299 | while (!Error && !consume(")")) | |
| 334 | while (!errorCount() && !consume(")")) | |
| 300 | 335 | Config->Undefined.push_back(next()); |
| 301 | 336 | } |
| 302 | 337 | |
| 303 | 338 | void ScriptParser::readGroup() { |
| 304 | 339 | expect("("); |
| 305 | while (!Error && !consume(")")) { | |
| 340 | while (!errorCount() && !consume(")")) { | |
| 306 | 341 | if (consume("AS_NEEDED")) |
| 307 | 342 | readAsNeeded(); |
| 308 | 343 | else |
| ... | ... | @@ -313,20 +348,17 @@ void ScriptParser::readGroup() { |
| 313 | 348 | void ScriptParser::readInclude() { |
| 314 | 349 | StringRef Tok = unquote(next()); |
| 315 | 350 | |
| 316 | // https://sourceware.org/binutils/docs/ld/File-Commands.html: | |
| 317 | // The file will be searched for in the current directory, and in any | |
| 318 | // directory specified with the -L option. | |
| 319 | if (sys::fs::exists(Tok)) { | |
| 320 | if (Optional<MemoryBufferRef> MB = readFile(Tok)) | |
| 321 | tokenize(*MB); | |
| 351 | if (!Seen.insert(Tok).second) { | |
| 352 | setError("there is a cycle in linker script INCLUDEs"); | |
| 322 | 353 | return; |
| 323 | 354 | } |
| 324 | if (Optional<std::string> Path = findFromSearchPaths(Tok)) { | |
| 355 | ||
| 356 | if (Optional<std::string> Path = searchLinkerScript(Tok)) { | |
| 325 | 357 | if (Optional<MemoryBufferRef> MB = readFile(*Path)) |
| 326 | 358 | tokenize(*MB); |
| 327 | 359 | return; |
| 328 | 360 | } |
| 329 | setError("cannot open " + Tok); | |
| 361 | setError("cannot find linker script " + Tok); | |
| 330 | 362 | } |
| 331 | 363 | |
| 332 | 364 | void ScriptParser::readOutput() { |
| ... | ... | @@ -341,7 +373,7 @@ void ScriptParser::readOutput() { |
| 341 | 373 | void ScriptParser::readOutputArch() { |
| 342 | 374 | // OUTPUT_ARCH is ignored for now. |
| 343 | 375 | expect("("); |
| 344 | while (!Error && !consume(")")) | |
| 376 | while (!errorCount() && !consume(")")) | |
| 345 | 377 | skip(); |
| 346 | 378 | } |
| 347 | 379 | |
| ... | ... | @@ -360,28 +392,43 @@ void ScriptParser::readOutputFormat() { |
| 360 | 392 | |
| 361 | 393 | void ScriptParser::readPhdrs() { |
| 362 | 394 | expect("{"); |
| 363 | while (!Error && !consume("}")) { | |
| 364 | Script->Opt.PhdrsCommands.push_back( | |
| 365 | {next(), PT_NULL, false, false, UINT_MAX, nullptr}); | |
| 366 | 395 | |
| 367 | PhdrsCommand &PhdrCmd = Script->Opt.PhdrsCommands.back(); | |
| 368 | PhdrCmd.Type = readPhdrType(); | |
| 396 | while (!errorCount() && !consume("}")) { | |
| 397 | PhdrsCommand Cmd; | |
| 398 | Cmd.Name = next(); | |
| 399 | Cmd.Type = readPhdrType(); | |
| 369 | 400 | |
| 370 | while (!Error && !consume(";")) { | |
| 401 | while (!errorCount() && !consume(";")) { | |
| 371 | 402 | if (consume("FILEHDR")) |
| 372 | PhdrCmd.HasFilehdr = true; | |
| 403 | Cmd.HasFilehdr = true; | |
| 373 | 404 | else if (consume("PHDRS")) |
| 374 | PhdrCmd.HasPhdrs = true; | |
| 405 | Cmd.HasPhdrs = true; | |
| 375 | 406 | else if (consume("AT")) |
| 376 | PhdrCmd.LMAExpr = readParenExpr(); | |
| 407 | Cmd.LMAExpr = readParenExpr(); | |
| 377 | 408 | else if (consume("FLAGS")) |
| 378 | PhdrCmd.Flags = readParenExpr()().getValue(); | |
| 409 | Cmd.Flags = readParenExpr()().getValue(); | |
| 379 | 410 | else |
| 380 | 411 | setError("unexpected header attribute: " + next()); |
| 381 | 412 | } |
| 413 | ||
| 414 | Script->PhdrsCommands.push_back(Cmd); | |
| 382 | 415 | } |
| 383 | 416 | } |
| 384 | 417 | |
| 418 | void ScriptParser::readRegionAlias() { | |
| 419 | expect("("); | |
| 420 | StringRef Alias = unquote(next()); | |
| 421 | expect(","); | |
| 422 | StringRef Name = next(); | |
| 423 | expect(")"); | |
| 424 | ||
| 425 | if (Script->MemoryRegions.count(Alias)) | |
| 426 | setError("redefinition of memory region '" + Alias + "'"); | |
| 427 | if (!Script->MemoryRegions.count(Name)) | |
| 428 | setError("memory region '" + Name + "' is not defined"); | |
| 429 | Script->MemoryRegions.insert({Alias, Script->MemoryRegions[Name]}); | |
| 430 | } | |
| 431 | ||
| 385 | 432 | void ScriptParser::readSearchDir() { |
| 386 | 433 | expect("("); |
| 387 | 434 | StringRef Tok = next(); |
| ... | ... | @@ -391,7 +438,7 @@ void ScriptParser::readSearchDir() { |
| 391 | 438 | } |
| 392 | 439 | |
| 393 | 440 | void ScriptParser::readSections() { |
| 394 | Script->Opt.HasSections = true; | |
| 441 | Script->HasSectionsCommand = true; | |
| 395 | 442 | |
| 396 | 443 | // -no-rosegment is used to avoid placing read only non-executable sections in |
| 397 | 444 | // their own segment. We do the same if SECTIONS command is present in linker |
| ... | ... | @@ -399,7 +446,7 @@ void ScriptParser::readSections() { |
| 399 | 446 | Config->SingleRoRx = true; |
| 400 | 447 | |
| 401 | 448 | expect("{"); |
| 402 | while (!Error && !consume("}")) { | |
| 449 | while (!errorCount() && !consume("}")) { | |
| 403 | 450 | StringRef Tok = next(); |
| 404 | 451 | BaseCommand *Cmd = readProvideOrAssignment(Tok); |
| 405 | 452 | if (!Cmd) { |
| ... | ... | @@ -408,7 +455,7 @@ void ScriptParser::readSections() { |
| 408 | 455 | else |
| 409 | 456 | Cmd = readOutputSectionDescription(Tok); |
| 410 | 457 | } |
| 411 | Script->Opt.Commands.push_back(Cmd); | |
| 458 | Script->SectionCommands.push_back(Cmd); | |
| 412 | 459 | } |
| 413 | 460 | } |
| 414 | 461 | |
| ... | ... | @@ -424,7 +471,7 @@ static int precedence(StringRef Op) { |
| 424 | 471 | |
| 425 | 472 | StringMatcher ScriptParser::readFilePatterns() { |
| 426 | 473 | std::vector<StringRef> V; |
| 427 | while (!Error && !consume(")")) | |
| 474 | while (!errorCount() && !consume(")")) | |
| 428 | 475 | V.push_back(next()); |
| 429 | 476 | return StringMatcher(V); |
| 430 | 477 | } |
| ... | ... | @@ -456,7 +503,7 @@ SortSectionPolicy ScriptParser::readSortKind() { |
| 456 | 503 | // any file but a.o, and section .baz in any file but b.o. |
| 457 | 504 | std::vector<SectionPattern> ScriptParser::readInputSectionsList() { |
| 458 | 505 | std::vector<SectionPattern> Ret; |
| 459 | while (!Error && peek() != ")") { | |
| 506 | while (!errorCount() && peek() != ")") { | |
| 460 | 507 | StringMatcher ExcludeFilePat; |
| 461 | 508 | if (consume("EXCLUDE_FILE")) { |
| 462 | 509 | expect("("); |
| ... | ... | @@ -464,7 +511,7 @@ std::vector<SectionPattern> ScriptParser::readInputSectionsList() { |
| 464 | 511 | } |
| 465 | 512 | |
| 466 | 513 | std::vector<StringRef> V; |
| 467 | while (!Error && peek() != ")" && peek() != "EXCLUDE_FILE") | |
| 514 | while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE") | |
| 468 | 515 | V.push_back(next()); |
| 469 | 516 | |
| 470 | 517 | if (!V.empty()) |
| ... | ... | @@ -491,7 +538,7 @@ ScriptParser::readInputSectionRules(StringRef FilePattern) { |
| 491 | 538 | auto *Cmd = make<InputSectionDescription>(FilePattern); |
| 492 | 539 | expect("("); |
| 493 | 540 | |
| 494 | while (!Error && !consume(")")) { | |
| 541 | while (!errorCount() && !consume(")")) { | |
| 495 | 542 | SortSectionPolicy Outer = readSortKind(); |
| 496 | 543 | SortSectionPolicy Inner = SortSectionPolicy::Default; |
| 497 | 544 | std::vector<SectionPattern> V; |
| ... | ... | @@ -529,7 +576,7 @@ ScriptParser::readInputSectionDescription(StringRef Tok) { |
| 529 | 576 | StringRef FilePattern = next(); |
| 530 | 577 | InputSectionDescription *Cmd = readInputSectionRules(FilePattern); |
| 531 | 578 | expect(")"); |
| 532 | Script->Opt.KeptSections.push_back(Cmd); | |
| 579 | Script->KeptSections.push_back(Cmd); | |
| 533 | 580 | return Cmd; |
| 534 | 581 | } |
| 535 | 582 | return readInputSectionRules(Tok); |
| ... | ... | @@ -579,7 +626,7 @@ uint32_t ScriptParser::readFill() { |
| 579 | 626 | // |
| 580 | 627 | // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html |
| 581 | 628 | // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html |
| 582 | void ScriptParser::readSectionAddressType(OutputSectionCommand *Cmd) { | |
| 629 | void ScriptParser::readSectionAddressType(OutputSection *Cmd) { | |
| 583 | 630 | if (consume("(")) { |
| 584 | 631 | if (consume("NOLOAD")) { |
| 585 | 632 | expect(")"); |
| ... | ... | @@ -599,21 +646,32 @@ void ScriptParser::readSectionAddressType(OutputSectionCommand *Cmd) { |
| 599 | 646 | } |
| 600 | 647 | } |
| 601 | 648 | |
| 602 | OutputSectionCommand * | |
| 603 | ScriptParser::readOutputSectionDescription(StringRef OutSec) { | |
| 604 | OutputSectionCommand *Cmd = | |
| 605 | Script->createOutputSectionCommand(OutSec, getCurrentLocation()); | |
| 649 | static Expr checkAlignment(Expr E, std::string &Loc) { | |
| 650 | return [=] { | |
| 651 | uint64_t Alignment = std::max((uint64_t)1, E().getValue()); | |
| 652 | if (!isPowerOf2_64(Alignment)) { | |
| 653 | error(Loc + ": alignment must be power of 2"); | |
| 654 | return (uint64_t)1; // Return a dummy value. | |
| 655 | } | |
| 656 | return Alignment; | |
| 657 | }; | |
| 658 | } | |
| 659 | ||
| 660 | OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { | |
| 661 | OutputSection *Cmd = | |
| 662 | Script->createOutputSection(OutSec, getCurrentLocation()); | |
| 606 | 663 | |
| 607 | 664 | if (peek() != ":") |
| 608 | 665 | readSectionAddressType(Cmd); |
| 609 | 666 | expect(":"); |
| 610 | 667 | |
| 668 | std::string Location = getCurrentLocation(); | |
| 611 | 669 | if (consume("AT")) |
| 612 | 670 | Cmd->LMAExpr = readParenExpr(); |
| 613 | 671 | if (consume("ALIGN")) |
| 614 | Cmd->AlignExpr = readParenExpr(); | |
| 672 | Cmd->AlignExpr = checkAlignment(readParenExpr(), Location); | |
| 615 | 673 | if (consume("SUBALIGN")) |
| 616 | Cmd->SubalignExpr = readParenExpr(); | |
| 674 | Cmd->SubalignExpr = checkAlignment(readParenExpr(), Location); | |
| 617 | 675 | |
| 618 | 676 | // Parse constraints. |
| 619 | 677 | if (consume("ONLY_IF_RO")) |
| ... | ... | @@ -622,16 +680,16 @@ ScriptParser::readOutputSectionDescription(StringRef OutSec) { |
| 622 | 680 | Cmd->Constraint = ConstraintKind::ReadWrite; |
| 623 | 681 | expect("{"); |
| 624 | 682 | |
| 625 | while (!Error && !consume("}")) { | |
| 683 | while (!errorCount() && !consume("}")) { | |
| 626 | 684 | StringRef Tok = next(); |
| 627 | 685 | if (Tok == ";") { |
| 628 | 686 | // Empty commands are allowed. Do nothing here. |
| 629 | 687 | } else if (SymbolAssignment *Assign = readProvideOrAssignment(Tok)) { |
| 630 | Cmd->Commands.push_back(Assign); | |
| 631 | } else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) { | |
| 632 | Cmd->Commands.push_back(Data); | |
| 688 | Cmd->SectionCommands.push_back(Assign); | |
| 689 | } else if (ByteCommand *Data = readByteCommand(Tok)) { | |
| 690 | Cmd->SectionCommands.push_back(Data); | |
| 633 | 691 | } else if (Tok == "ASSERT") { |
| 634 | Cmd->Commands.push_back(readAssert()); | |
| 692 | Cmd->SectionCommands.push_back(readAssert()); | |
| 635 | 693 | expect(";"); |
| 636 | 694 | } else if (Tok == "CONSTRUCTORS") { |
| 637 | 695 | // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors |
| ... | ... | @@ -642,7 +700,7 @@ ScriptParser::readOutputSectionDescription(StringRef OutSec) { |
| 642 | 700 | } else if (Tok == "SORT") { |
| 643 | 701 | readSort(); |
| 644 | 702 | } else if (peek() == "(") { |
| 645 | Cmd->Commands.push_back(readInputSectionDescription(Tok)); | |
| 703 | Cmd->SectionCommands.push_back(readInputSectionDescription(Tok)); | |
| 646 | 704 | } else { |
| 647 | 705 | setError("unknown command " + Tok); |
| 648 | 706 | } |
| ... | ... | @@ -651,6 +709,14 @@ ScriptParser::readOutputSectionDescription(StringRef OutSec) { |
| 651 | 709 | if (consume(">")) |
| 652 | 710 | Cmd->MemoryRegionName = next(); |
| 653 | 711 | |
| 712 | if (consume("AT")) { | |
| 713 | expect(">"); | |
| 714 | Cmd->LMARegionName = next(); | |
| 715 | } | |
| 716 | ||
| 717 | if (Cmd->LMAExpr && !Cmd->LMARegionName.empty()) | |
| 718 | error("section can't have both LMA and a load region"); | |
| 719 | ||
| 654 | 720 | Cmd->Phdrs = readOutputSectionPhdrs(); |
| 655 | 721 | |
| 656 | 722 | if (consume("=")) |
| ... | ... | @@ -712,7 +778,7 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { |
| 712 | 778 | Expr E = readExpr(); |
| 713 | 779 | if (Op == "+=") { |
| 714 | 780 | std::string Loc = getCurrentLocation(); |
| 715 | E = [=] { return add(Script->getSymbolValue(Loc, Name), E()); }; | |
| 781 | E = [=] { return add(Script->getSymbolValue(Name, Loc), E()); }; | |
| 716 | 782 | } |
| 717 | 783 | return make<SymbolAssignment>(Name, E, getCurrentLocation()); |
| 718 | 784 | } |
| ... | ... | @@ -764,7 +830,7 @@ static Expr combine(StringRef Op, Expr L, Expr R) { |
| 764 | 830 | // This is a part of the operator-precedence parser. This function |
| 765 | 831 | // assumes that the remaining token stream starts with an operator. |
| 766 | 832 | Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { |
| 767 | while (!atEOF() && !Error) { | |
| 833 | while (!atEOF() && !errorCount()) { | |
| 768 | 834 | // Read an operator and an expression. |
| 769 | 835 | if (consume("?")) |
| 770 | 836 | return readTernary(Lhs); |
| ... | ... | @@ -790,13 +856,24 @@ Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { |
| 790 | 856 | return Lhs; |
| 791 | 857 | } |
| 792 | 858 | |
| 793 | uint64_t static getConstant(StringRef S) { | |
| 859 | Expr ScriptParser::getPageSize() { | |
| 860 | std::string Location = getCurrentLocation(); | |
| 861 | return [=]() -> uint64_t { | |
| 862 | if (Target) | |
| 863 | return Target->PageSize; | |
| 864 | error(Location + ": unable to calculate page size"); | |
| 865 | return 4096; // Return a dummy value. | |
| 866 | }; | |
| 867 | } | |
| 868 | ||
| 869 | Expr ScriptParser::readConstant() { | |
| 870 | StringRef S = readParenLiteral(); | |
| 794 | 871 | if (S == "COMMONPAGESIZE") |
| 795 | return Target->PageSize; | |
| 872 | return getPageSize(); | |
| 796 | 873 | if (S == "MAXPAGESIZE") |
| 797 | return Config->MaxPageSize; | |
| 798 | error("unknown constant: " + S); | |
| 799 | return 0; | |
| 874 | return [] { return Config->MaxPageSize; }; | |
| 875 | setError("unknown constant: " + S); | |
| 876 | return {}; | |
| 800 | 877 | } |
| 801 | 878 | |
| 802 | 879 | // Parses Tok as an integer. It recognizes hexadecimal (prefixed with |
| ... | ... | @@ -812,10 +889,16 @@ static Optional<uint64_t> parseInt(StringRef Tok) { |
| 812 | 889 | |
| 813 | 890 | // Hexadecimal |
| 814 | 891 | uint64_t Val; |
| 815 | if (Tok.startswith_lower("0x") && to_integer(Tok.substr(2), Val, 16)) | |
| 892 | if (Tok.startswith_lower("0x")) { | |
| 893 | if (!to_integer(Tok.substr(2), Val, 16)) | |
| 894 | return None; | |
| 816 | 895 | return Val; |
| 817 | if (Tok.endswith_lower("H") && to_integer(Tok.drop_back(), Val, 16)) | |
| 896 | } | |
| 897 | if (Tok.endswith_lower("H")) { | |
| 898 | if (!to_integer(Tok.drop_back(), Val, 16)) | |
| 899 | return None; | |
| 818 | 900 | return Val; |
| 901 | } | |
| 819 | 902 | |
| 820 | 903 | // Decimal |
| 821 | 904 | if (Tok.endswith_lower("K")) { |
| ... | ... | @@ -833,7 +916,7 @@ static Optional<uint64_t> parseInt(StringRef Tok) { |
| 833 | 916 | return Val; |
| 834 | 917 | } |
| 835 | 918 | |
| 836 | BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) { | |
| 919 | ByteCommand *ScriptParser::readByteCommand(StringRef Tok) { | |
| 837 | 920 | int Size = StringSwitch<int>(Tok) |
| 838 | 921 | .Case("BYTE", 1) |
| 839 | 922 | .Case("SHORT", 2) |
| ... | ... | @@ -842,25 +925,22 @@ BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) { |
| 842 | 925 | .Default(-1); |
| 843 | 926 | if (Size == -1) |
| 844 | 927 | return nullptr; |
| 845 | ||
| 846 | return make<BytesDataCommand>(readParenExpr(), Size); | |
| 928 | return make<ByteCommand>(readParenExpr(), Size); | |
| 847 | 929 | } |
| 848 | 930 | |
| 849 | 931 | StringRef ScriptParser::readParenLiteral() { |
| 850 | 932 | expect("("); |
| 933 | bool Orig = InExpr; | |
| 934 | InExpr = false; | |
| 851 | 935 | StringRef Tok = next(); |
| 936 | InExpr = Orig; | |
| 852 | 937 | expect(")"); |
| 853 | 938 | return Tok; |
| 854 | 939 | } |
| 855 | 940 | |
| 856 | OutputSection *ScriptParser::checkSection(OutputSectionCommand *Cmd, | |
| 857 | StringRef Location) { | |
| 941 | static void checkIfExists(OutputSection *Cmd, StringRef Location) { | |
| 858 | 942 | if (Cmd->Location.empty() && Script->ErrorOnMissingSection) |
| 859 | 943 | error(Location + ": undefined section " + Cmd->Name); |
| 860 | if (Cmd->Sec) | |
| 861 | return Cmd->Sec; | |
| 862 | static OutputSection Dummy("", 0, 0); | |
| 863 | return &Dummy; | |
| 864 | 944 | } |
| 865 | 945 | |
| 866 | 946 | Expr ScriptParser::readPrimary() { |
| ... | ... | @@ -871,6 +951,10 @@ Expr ScriptParser::readPrimary() { |
| 871 | 951 | Expr E = readPrimary(); |
| 872 | 952 | return [=] { return ~E().getValue(); }; |
| 873 | 953 | } |
| 954 | if (consume("!")) { | |
| 955 | Expr E = readPrimary(); | |
| 956 | return [=] { return !E().getValue(); }; | |
| 957 | } | |
| 874 | 958 | if (consume("-")) { |
| 875 | 959 | Expr E = readPrimary(); |
| 876 | 960 | return [=] { return -E().getValue(); }; |
| ... | ... | @@ -891,18 +975,21 @@ Expr ScriptParser::readPrimary() { |
| 891 | 975 | } |
| 892 | 976 | if (Tok == "ADDR") { |
| 893 | 977 | StringRef Name = readParenLiteral(); |
| 894 | OutputSectionCommand *Cmd = Script->getOrCreateOutputSectionCommand(Name); | |
| 978 | OutputSection *Sec = Script->getOrCreateOutputSection(Name); | |
| 895 | 979 | return [=]() -> ExprValue { |
| 896 | return {checkSection(Cmd, Location), 0, Location}; | |
| 980 | checkIfExists(Sec, Location); | |
| 981 | return {Sec, false, 0, Location}; | |
| 897 | 982 | }; |
| 898 | 983 | } |
| 899 | 984 | if (Tok == "ALIGN") { |
| 900 | 985 | expect("("); |
| 901 | 986 | Expr E = readExpr(); |
| 902 | if (consume(")")) | |
| 987 | if (consume(")")) { | |
| 988 | E = checkAlignment(E, Location); | |
| 903 | 989 | return [=] { return alignTo(Script->getDot(), E().getValue()); }; |
| 990 | } | |
| 904 | 991 | expect(","); |
| 905 | Expr E2 = readExpr(); | |
| 992 | Expr E2 = checkAlignment(readExpr(), Location); | |
| 906 | 993 | expect(")"); |
| 907 | 994 | return [=] { |
| 908 | 995 | ExprValue V = E(); |
| ... | ... | @@ -912,22 +999,25 @@ Expr ScriptParser::readPrimary() { |
| 912 | 999 | } |
| 913 | 1000 | if (Tok == "ALIGNOF") { |
| 914 | 1001 | StringRef Name = readParenLiteral(); |
| 915 | OutputSectionCommand *Cmd = Script->getOrCreateOutputSectionCommand(Name); | |
| 916 | return [=] { return checkSection(Cmd, Location)->Alignment; }; | |
| 1002 | OutputSection *Cmd = Script->getOrCreateOutputSection(Name); | |
| 1003 | return [=] { | |
| 1004 | checkIfExists(Cmd, Location); | |
| 1005 | return Cmd->Alignment; | |
| 1006 | }; | |
| 917 | 1007 | } |
| 918 | 1008 | if (Tok == "ASSERT") |
| 919 | 1009 | return readAssertExpr(); |
| 920 | if (Tok == "CONSTANT") { | |
| 921 | StringRef Name = readParenLiteral(); | |
| 922 | return [=] { return getConstant(Name); }; | |
| 923 | } | |
| 1010 | if (Tok == "CONSTANT") | |
| 1011 | return readConstant(); | |
| 924 | 1012 | if (Tok == "DATA_SEGMENT_ALIGN") { |
| 925 | 1013 | expect("("); |
| 926 | 1014 | Expr E = readExpr(); |
| 927 | 1015 | expect(","); |
| 928 | 1016 | readExpr(); |
| 929 | 1017 | expect(")"); |
| 930 | return [=] { return alignTo(Script->getDot(), E().getValue()); }; | |
| 1018 | return [=] { | |
| 1019 | return alignTo(Script->getDot(), std::max((uint64_t)1, E().getValue())); | |
| 1020 | }; | |
| 931 | 1021 | } |
| 932 | 1022 | if (Tok == "DATA_SEGMENT_END") { |
| 933 | 1023 | expect("("); |
| ... | ... | @@ -944,28 +1034,32 @@ Expr ScriptParser::readPrimary() { |
| 944 | 1034 | expect(","); |
| 945 | 1035 | readExpr(); |
| 946 | 1036 | expect(")"); |
| 947 | return [] { return alignTo(Script->getDot(), Target->PageSize); }; | |
| 1037 | Expr E = getPageSize(); | |
| 1038 | return [=] { return alignTo(Script->getDot(), E().getValue()); }; | |
| 948 | 1039 | } |
| 949 | 1040 | if (Tok == "DEFINED") { |
| 950 | 1041 | StringRef Name = readParenLiteral(); |
| 951 | return [=] { return Script->isDefined(Name) ? 1 : 0; }; | |
| 1042 | return [=] { return Symtab->find(Name) ? 1 : 0; }; | |
| 952 | 1043 | } |
| 953 | 1044 | if (Tok == "LENGTH") { |
| 954 | 1045 | StringRef Name = readParenLiteral(); |
| 955 | if (Script->Opt.MemoryRegions.count(Name) == 0) | |
| 1046 | if (Script->MemoryRegions.count(Name) == 0) | |
| 956 | 1047 | setError("memory region not defined: " + Name); |
| 957 | return [=] { return Script->Opt.MemoryRegions[Name].Length; }; | |
| 1048 | return [=] { return Script->MemoryRegions[Name]->Length; }; | |
| 958 | 1049 | } |
| 959 | 1050 | if (Tok == "LOADADDR") { |
| 960 | 1051 | StringRef Name = readParenLiteral(); |
| 961 | OutputSectionCommand *Cmd = Script->getOrCreateOutputSectionCommand(Name); | |
| 962 | return [=] { return checkSection(Cmd, Location)->getLMA(); }; | |
| 1052 | OutputSection *Cmd = Script->getOrCreateOutputSection(Name); | |
| 1053 | return [=] { | |
| 1054 | checkIfExists(Cmd, Location); | |
| 1055 | return Cmd->getLMA(); | |
| 1056 | }; | |
| 963 | 1057 | } |
| 964 | 1058 | if (Tok == "ORIGIN") { |
| 965 | 1059 | StringRef Name = readParenLiteral(); |
| 966 | if (Script->Opt.MemoryRegions.count(Name) == 0) | |
| 1060 | if (Script->MemoryRegions.count(Name) == 0) | |
| 967 | 1061 | setError("memory region not defined: " + Name); |
| 968 | return [=] { return Script->Opt.MemoryRegions[Name].Origin; }; | |
| 1062 | return [=] { return Script->MemoryRegions[Name]->Origin; }; | |
| 969 | 1063 | } |
| 970 | 1064 | if (Tok == "SEGMENT_START") { |
| 971 | 1065 | expect("("); |
| ... | ... | @@ -977,18 +1071,18 @@ Expr ScriptParser::readPrimary() { |
| 977 | 1071 | } |
| 978 | 1072 | if (Tok == "SIZEOF") { |
| 979 | 1073 | StringRef Name = readParenLiteral(); |
| 980 | OutputSectionCommand *Cmd = Script->getOrCreateOutputSectionCommand(Name); | |
| 1074 | OutputSection *Cmd = Script->getOrCreateOutputSection(Name); | |
| 981 | 1075 | // Linker script does not create an output section if its content is empty. |
| 982 | 1076 | // We want to allow SIZEOF(.foo) where .foo is a section which happened to |
| 983 | 1077 | // be empty. |
| 984 | return [=] { return Cmd->Sec ? Cmd->Sec->Size : 0; }; | |
| 1078 | return [=] { return Cmd->Size; }; | |
| 985 | 1079 | } |
| 986 | 1080 | if (Tok == "SIZEOF_HEADERS") |
| 987 | 1081 | return [=] { return elf::getHeaderSize(); }; |
| 988 | 1082 | |
| 989 | 1083 | // Tok is the dot. |
| 990 | 1084 | if (Tok == ".") |
| 991 | return [=] { return Script->getSymbolValue(Location, Tok); }; | |
| 1085 | return [=] { return Script->getSymbolValue(Tok, Location); }; | |
| 992 | 1086 | |
| 993 | 1087 | // Tok is a literal number. |
| 994 | 1088 | if (Optional<uint64_t> Val = parseInt(Tok)) |
| ... | ... | @@ -997,8 +1091,8 @@ Expr ScriptParser::readPrimary() { |
| 997 | 1091 | // Tok is a symbol name. |
| 998 | 1092 | if (!isValidCIdentifier(Tok)) |
| 999 | 1093 | setError("malformed number: " + Tok); |
| 1000 | Script->Opt.ReferencedSymbols.push_back(Tok); | |
| 1001 | return [=] { return Script->getSymbolValue(Location, Tok); }; | |
| 1094 | Script->ReferencedSymbols.push_back(Tok); | |
| 1095 | return [=] { return Script->getSymbolValue(Tok, Location); }; | |
| 1002 | 1096 | } |
| 1003 | 1097 | |
| 1004 | 1098 | Expr ScriptParser::readTernary(Expr Cond) { |
| ... | ... | @@ -1017,7 +1111,7 @@ Expr ScriptParser::readParenExpr() { |
| 1017 | 1111 | |
| 1018 | 1112 | std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { |
| 1019 | 1113 | std::vector<StringRef> Phdrs; |
| 1020 | while (!Error && peek().startswith(":")) { | |
| 1114 | while (!errorCount() && peek().startswith(":")) { | |
| 1021 | 1115 | StringRef Tok = next(); |
| 1022 | 1116 | Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1)); |
| 1023 | 1117 | } |
| ... | ... | @@ -1120,7 +1214,7 @@ ScriptParser::readSymbols() { |
| 1120 | 1214 | std::vector<SymbolVersion> Globals; |
| 1121 | 1215 | std::vector<SymbolVersion> *V = &Globals; |
| 1122 | 1216 | |
| 1123 | while (!Error) { | |
| 1217 | while (!errorCount()) { | |
| 1124 | 1218 | if (consume("}")) |
| 1125 | 1219 | break; |
| 1126 | 1220 | if (consumeLabel("local")) { |
| ... | ... | @@ -1154,7 +1248,7 @@ std::vector<SymbolVersion> ScriptParser::readVersionExtern() { |
| 1154 | 1248 | expect("{"); |
| 1155 | 1249 | |
| 1156 | 1250 | std::vector<SymbolVersion> Ret; |
| 1157 | while (!Error && peek() != "}") { | |
| 1251 | while (!errorCount() && peek() != "}") { | |
| 1158 | 1252 | StringRef Tok = next(); |
| 1159 | 1253 | bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok); |
| 1160 | 1254 | Ret.push_back({unquote(Tok), IsCXX, HasWildcard}); |
| ... | ... | @@ -1181,7 +1275,7 @@ uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2, |
| 1181 | 1275 | // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... } |
| 1182 | 1276 | void ScriptParser::readMemory() { |
| 1183 | 1277 | expect("{"); |
| 1184 | while (!Error && !consume("}")) { | |
| 1278 | while (!errorCount() && !consume("}")) { | |
| 1185 | 1279 | StringRef Name = next(); |
| 1186 | 1280 | |
| 1187 | 1281 | uint32_t Flags = 0; |
| ... | ... | @@ -1196,12 +1290,12 @@ void ScriptParser::readMemory() { |
| 1196 | 1290 | expect(","); |
| 1197 | 1291 | uint64_t Length = readMemoryAssignment("LENGTH", "len", "l"); |
| 1198 | 1292 | |
| 1199 | // Add the memory region to the region map (if it doesn't already exist). | |
| 1200 | auto It = Script->Opt.MemoryRegions.find(Name); | |
| 1201 | if (It != Script->Opt.MemoryRegions.end()) | |
| 1293 | // Add the memory region to the region map. | |
| 1294 | if (Script->MemoryRegions.count(Name)) | |
| 1202 | 1295 | setError("region '" + Name + "' already defined"); |
| 1203 | else | |
| 1204 | Script->Opt.MemoryRegions[Name] = {Name, Origin, Length, Flags, NegFlags}; | |
| 1296 | MemoryRegion *MR = | |
| 1297 | make<MemoryRegion>(Name, Origin, Length, Flags, NegFlags); | |
| 1298 | Script->MemoryRegions[Name] = MR; | |
| 1205 | 1299 | } |
| 1206 | 1300 | } |
| 1207 | 1301 | |
| ... | ... | @@ -1245,3 +1339,7 @@ void elf::readVersionScript(MemoryBufferRef MB) { |
| 1245 | 1339 | void elf::readDynamicList(MemoryBufferRef MB) { |
| 1246 | 1340 | ScriptParser(MB).readDynamicList(); |
| 1247 | 1341 | } |
| 1342 | ||
| 1343 | void elf::readDefsym(StringRef Name, MemoryBufferRef MB) { | |
| 1344 | ScriptParser(MB).readDefsym(Name); | |
| 1345 | } |
deps/lld/ELF/ScriptParser.h+4-1| ... | ... | @@ -10,7 +10,7 @@ |
| 10 | 10 | #ifndef LLD_ELF_SCRIPT_PARSER_H |
| 11 | 11 | #define LLD_ELF_SCRIPT_PARSER_H |
| 12 | 12 | |
| 13 | #include "lld/Core/LLVM.h" | |
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | 14 | #include "llvm/Support/MemoryBuffer.h" |
| 15 | 15 | |
| 16 | 16 | namespace lld { |
| ... | ... | @@ -25,6 +25,9 @@ void readVersionScript(MemoryBufferRef MB); |
| 25 | 25 | |
| 26 | 26 | void readDynamicList(MemoryBufferRef MB); |
| 27 | 27 | |
| 28 | // Parses the defsym expression. | |
| 29 | void readDefsym(StringRef Name, MemoryBufferRef MB); | |
| 30 | ||
| 28 | 31 | } // namespace elf |
| 29 | 32 | } // namespace lld |
| 30 | 33 |
deps/lld/ELF/Strings.cpp+4-27| ... | ... | @@ -9,7 +9,7 @@ |
| 9 | 9 | |
| 10 | 10 | #include "Strings.h" |
| 11 | 11 | #include "Config.h" |
| 12 | #include "Error.h" | |
| 12 | #include "lld/Common/ErrorHandler.h" | |
| 13 | 13 | #include "llvm/ADT/ArrayRef.h" |
| 14 | 14 | #include "llvm/ADT/StringRef.h" |
| 15 | 15 | #include "llvm/ADT/Twine.h" |
| ... | ... | @@ -54,32 +54,9 @@ std::vector<uint8_t> elf::parseHex(StringRef S) { |
| 54 | 54 | return Hex; |
| 55 | 55 | } |
| 56 | 56 | |
| 57 | static bool isAlpha(char C) { | |
| 58 | return ('a' <= C && C <= 'z') || ('A' <= C && C <= 'Z') || C == '_'; | |
| 59 | } | |
| 60 | ||
| 61 | static bool isAlnum(char C) { return isAlpha(C) || ('0' <= C && C <= '9'); } | |
| 62 | ||
| 63 | 57 | // Returns true if S is valid as a C language identifier. |
| 64 | 58 | bool elf::isValidCIdentifier(StringRef S) { |
| 65 | return !S.empty() && isAlpha(S[0]) && | |
| 66 | std::all_of(S.begin() + 1, S.end(), isAlnum); | |
| 67 | } | |
| 68 | ||
| 69 | // Returns the demangled C++ symbol name for Name. | |
| 70 | Optional<std::string> elf::demangle(StringRef Name) { | |
| 71 | // itaniumDemangle can be used to demangle strings other than symbol | |
| 72 | // names which do not necessarily start with "_Z". Name can be | |
| 73 | // either a C or C++ symbol. Don't call itaniumDemangle if the name | |
| 74 | // does not look like a C++ symbol name to avoid getting unexpected | |
| 75 | // result for a C symbol that happens to match a mangled type name. | |
| 76 | if (!Name.startswith("_Z")) | |
| 77 | return None; | |
| 78 | ||
| 79 | char *Buf = itaniumDemangle(Name.str().c_str(), nullptr, nullptr, nullptr); | |
| 80 | if (!Buf) | |
| 81 | return None; | |
| 82 | std::string S(Buf); | |
| 83 | free(Buf); | |
| 84 | return 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); }); | |
| 85 | 62 | } |
deps/lld/ELF/Strings.h+1-5| ... | ... | @@ -10,7 +10,7 @@ |
| 10 | 10 | #ifndef LLD_ELF_STRINGS_H |
| 11 | 11 | #define LLD_ELF_STRINGS_H |
| 12 | 12 | |
| 13 | #include "lld/Core/LLVM.h" | |
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | 14 | #include "llvm/ADT/ArrayRef.h" |
| 15 | 15 | #include "llvm/ADT/BitVector.h" |
| 16 | 16 | #include "llvm/ADT/Optional.h" |
| ... | ... | @@ -66,10 +66,6 @@ private: |
| 66 | 66 | std::vector<llvm::GlobPattern> Patterns; |
| 67 | 67 | }; |
| 68 | 68 | |
| 69 | // Returns a demangled C++ symbol name. If Name is not a mangled | |
| 70 | // name, it returns Optional::None. | |
| 71 | llvm::Optional<std::string> demangle(StringRef Name); | |
| 72 | ||
| 73 | 69 | inline ArrayRef<uint8_t> toArrayRef(StringRef S) { |
| 74 | 70 | return {(const uint8_t *)S.data(), S.size()}; |
| 75 | 71 | } |
deps/lld/ELF/SymbolTable.cpp+340-286| ... | ... | @@ -16,10 +16,12 @@ |
| 16 | 16 | |
| 17 | 17 | #include "SymbolTable.h" |
| 18 | 18 | #include "Config.h" |
| 19 | #include "Error.h" | |
| 20 | 19 | #include "LinkerScript.h" |
| 21 | #include "Memory.h" | |
| 22 | 20 | #include "Symbols.h" |
| 21 | #include "SyntheticSections.h" | |
| 22 | #include "lld/Common/ErrorHandler.h" | |
| 23 | #include "lld/Common/Memory.h" | |
| 24 | #include "lld/Common/Strings.h" | |
| 23 | 25 | #include "llvm/ADT/STLExtras.h" |
| 24 | 26 | |
| 25 | 27 | using namespace llvm; |
| ... | ... | @@ -29,11 +31,21 @@ using namespace llvm::ELF; |
| 29 | 31 | using namespace lld; |
| 30 | 32 | using namespace lld::elf; |
| 31 | 33 | |
| 34 | SymbolTable *elf::Symtab; | |
| 35 | ||
| 36 | static InputFile *getFirstElf() { | |
| 37 | if (!ObjectFiles.empty()) | |
| 38 | return ObjectFiles[0]; | |
| 39 | if (!SharedFiles.empty()) | |
| 40 | return SharedFiles[0]; | |
| 41 | return nullptr; | |
| 42 | } | |
| 43 | ||
| 32 | 44 | // All input object files must be for the same architecture |
| 33 | 45 | // (e.g. it does not make sense to link x86 object files with |
| 34 | 46 | // MIPS object files.) This function checks for that error. |
| 35 | template <class ELFT> static bool isCompatible(InputFile *F) { | |
| 36 | if (!isa<ELFFileBase<ELFT>>(F) && !isa<BitcodeFile>(F)) | |
| 47 | static bool isCompatible(InputFile *F) { | |
| 48 | if (!F->isElf() && !isa<BitcodeFile>(F)) | |
| 37 | 49 | return true; |
| 38 | 50 | |
| 39 | 51 | if (F->EKind == Config->EKind && F->EMachine == Config->EMachine) { |
| ... | ... | @@ -46,22 +58,19 @@ template <class ELFT> static bool isCompatible(InputFile *F) { |
| 46 | 58 | if (!Config->Emulation.empty()) |
| 47 | 59 | error(toString(F) + " is incompatible with " + Config->Emulation); |
| 48 | 60 | else |
| 49 | error(toString(F) + " is incompatible with " + toString(Config->FirstElf)); | |
| 61 | error(toString(F) + " is incompatible with " + toString(getFirstElf())); | |
| 50 | 62 | return false; |
| 51 | 63 | } |
| 52 | 64 | |
| 53 | 65 | // Add symbols in File to the symbol table. |
| 54 | template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) { | |
| 55 | if (!Config->FirstElf && isa<ELFFileBase<ELFT>>(File)) | |
| 56 | Config->FirstElf = File; | |
| 57 | ||
| 58 | if (!isCompatible<ELFT>(File)) | |
| 66 | template <class ELFT> void SymbolTable::addFile(InputFile *File) { | |
| 67 | if (!isCompatible(File)) | |
| 59 | 68 | return; |
| 60 | 69 | |
| 61 | 70 | // Binary file |
| 62 | 71 | if (auto *F = dyn_cast<BinaryFile>(File)) { |
| 63 | 72 | BinaryFiles.push_back(F); |
| 64 | F->parse<ELFT>(); | |
| 73 | F->parse(); | |
| 65 | 74 | return; |
| 66 | 75 | } |
| 67 | 76 | |
| ... | ... | @@ -72,7 +81,7 @@ template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) { |
| 72 | 81 | } |
| 73 | 82 | |
| 74 | 83 | // Lazy object file |
| 75 | if (auto *F = dyn_cast<LazyObjectFile>(File)) { | |
| 84 | if (auto *F = dyn_cast<LazyObjFile>(File)) { | |
| 76 | 85 | F->parse<ELFT>(); |
| 77 | 86 | return; |
| 78 | 87 | } |
| ... | ... | @@ -84,7 +93,7 @@ template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) { |
| 84 | 93 | if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) { |
| 85 | 94 | // DSOs are uniquified not by filename but by soname. |
| 86 | 95 | F->parseSoName(); |
| 87 | if (ErrorCount || !SoNames.insert(F->SoName).second) | |
| 96 | if (errorCount() || !SoNames.insert(F->SoName).second) | |
| 88 | 97 | return; |
| 89 | 98 | SharedFiles.push_back(F); |
| 90 | 99 | F->parseRest(); |
| ... | ... | @@ -99,9 +108,8 @@ template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) { |
| 99 | 108 | } |
| 100 | 109 | |
| 101 | 110 | // Regular object file |
| 102 | auto *F = cast<ObjectFile<ELFT>>(File); | |
| 103 | ObjectFiles.push_back(F); | |
| 104 | F->parse(ComdatGroups); | |
| 111 | ObjectFiles.push_back(File); | |
| 112 | cast<ObjFile<ELFT>>(File)->parse(ComdatGroups); | |
| 105 | 113 | } |
| 106 | 114 | |
| 107 | 115 | // This function is where all the optimizations of link-time |
| ... | ... | @@ -111,7 +119,7 @@ template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) { |
| 111 | 119 | // using LLVM functions and replaces bitcode symbols with the results. |
| 112 | 120 | // Because all bitcode files that consist of a program are passed |
| 113 | 121 | // to the compiler at once, it can do whole-program optimization. |
| 114 | template <class ELFT> void SymbolTable<ELFT>::addCombinedLTOObject() { | |
| 122 | template <class ELFT> void SymbolTable::addCombinedLTOObject() { | |
| 115 | 123 | if (BitcodeFiles.empty()) |
| 116 | 124 | return; |
| 117 | 125 | |
| ... | ... | @@ -121,82 +129,76 @@ template <class ELFT> void SymbolTable<ELFT>::addCombinedLTOObject() { |
| 121 | 129 | LTO->add(*F); |
| 122 | 130 | |
| 123 | 131 | for (InputFile *File : LTO->compile()) { |
| 124 | ObjectFile<ELFT> *Obj = cast<ObjectFile<ELFT>>(File); | |
| 125 | 132 | DenseSet<CachedHashStringRef> DummyGroups; |
| 126 | Obj->parse(DummyGroups); | |
| 127 | ObjectFiles.push_back(Obj); | |
| 133 | cast<ObjFile<ELFT>>(File)->parse(DummyGroups); | |
| 134 | ObjectFiles.push_back(File); | |
| 128 | 135 | } |
| 129 | 136 | } |
| 130 | 137 | |
| 131 | template <class ELFT> | |
| 132 | DefinedRegular *SymbolTable<ELFT>::addAbsolute(StringRef Name, | |
| 133 | uint8_t Visibility, | |
| 134 | uint8_t Binding) { | |
| 138 | Defined *SymbolTable::addAbsolute(StringRef Name, uint8_t Visibility, | |
| 139 | uint8_t Binding) { | |
| 135 | 140 | Symbol *Sym = |
| 136 | 141 | addRegular(Name, Visibility, STT_NOTYPE, 0, 0, Binding, nullptr, nullptr); |
| 137 | return cast<DefinedRegular>(Sym->body()); | |
| 138 | } | |
| 139 | ||
| 140 | // Add Name as an "ignored" symbol. An ignored symbol is a regular | |
| 141 | // linker-synthesized defined symbol, but is only defined if needed. | |
| 142 | template <class ELFT> | |
| 143 | DefinedRegular *SymbolTable<ELFT>::addIgnored(StringRef Name, | |
| 144 | uint8_t Visibility) { | |
| 145 | SymbolBody *S = find(Name); | |
| 146 | if (!S || S->isInCurrentDSO()) | |
| 147 | return nullptr; | |
| 148 | return addAbsolute(Name, Visibility); | |
| 142 | return cast<Defined>(Sym); | |
| 149 | 143 | } |
| 150 | 144 | |
| 151 | 145 | // Set a flag for --trace-symbol so that we can print out a log message |
| 152 | 146 | // if a new symbol with the same name is inserted into the symbol table. |
| 153 | template <class ELFT> void SymbolTable<ELFT>::trace(StringRef Name) { | |
| 154 | Symtab.insert({CachedHashStringRef(Name), {-1, true}}); | |
| 147 | void SymbolTable::trace(StringRef Name) { | |
| 148 | SymMap.insert({CachedHashStringRef(Name), -1}); | |
| 155 | 149 | } |
| 156 | 150 | |
| 157 | 151 | // Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM. |
| 158 | 152 | // Used to implement --wrap. |
| 159 | template <class ELFT> void SymbolTable<ELFT>::addSymbolWrap(StringRef Name) { | |
| 160 | SymbolBody *B = find(Name); | |
| 161 | if (!B) | |
| 153 | template <class ELFT> void SymbolTable::addSymbolWrap(StringRef Name) { | |
| 154 | Symbol *Sym = find(Name); | |
| 155 | if (!Sym) | |
| 162 | 156 | return; |
| 163 | Symbol *Sym = B->symbol(); | |
| 164 | Symbol *Real = addUndefined(Saver.save("__real_" + Name)); | |
| 165 | Symbol *Wrap = addUndefined(Saver.save("__wrap_" + Name)); | |
| 157 | Symbol *Real = addUndefined<ELFT>(Saver.save("__real_" + Name)); | |
| 158 | Symbol *Wrap = addUndefined<ELFT>(Saver.save("__wrap_" + Name)); | |
| 159 | WrappedSymbols.push_back({Sym, Real, Wrap}); | |
| 166 | 160 | |
| 167 | // Tell LTO not to eliminate this symbol | |
| 168 | Wrap->IsUsedInRegularObj = true; | |
| 169 | ||
| 170 | Config->RenamedSymbols[Real] = {Sym, Real->Binding}; | |
| 171 | Config->RenamedSymbols[Sym] = {Wrap, Sym->Binding}; | |
| 172 | } | |
| 173 | ||
| 174 | // Creates alias for symbol. Used to implement --defsym=ALIAS=SYM. | |
| 175 | template <class ELFT> | |
| 176 | void SymbolTable<ELFT>::addSymbolAlias(StringRef Alias, StringRef Name) { | |
| 177 | SymbolBody *B = find(Name); | |
| 178 | if (!B) { | |
| 179 | error("-defsym: undefined symbol: " + Name); | |
| 180 | return; | |
| 181 | } | |
| 182 | Symbol *Sym = B->symbol(); | |
| 183 | Symbol *AliasSym = addUndefined(Alias); | |
| 161 | // We want to tell LTO not to inline symbols to be overwritten | |
| 162 | // because LTO doesn't know the final symbol contents after renaming. | |
| 163 | Real->CanInline = false; | |
| 164 | Sym->CanInline = false; | |
| 184 | 165 | |
| 185 | // Tell LTO not to eliminate this symbol | |
| 166 | // Tell LTO not to eliminate these symbols. | |
| 186 | 167 | Sym->IsUsedInRegularObj = true; |
| 187 | Config->RenamedSymbols[AliasSym] = {Sym, AliasSym->Binding}; | |
| 168 | Wrap->IsUsedInRegularObj = true; | |
| 188 | 169 | } |
| 189 | 170 | |
| 190 | // Apply symbol renames created by -wrap and -defsym. The renames are created | |
| 191 | // before LTO in addSymbolWrap() and addSymbolAlias() to have a chance to inform | |
| 192 | // LTO (if LTO is running) not to include these symbols in IPO. Now that the | |
| 171 | // Apply symbol renames created by -wrap. The renames are created | |
| 172 | // before LTO in addSymbolWrap() to have a chance to inform LTO (if | |
| 173 | // LTO is running) not to include these symbols in IPO. Now that the | |
| 193 | 174 | // symbols are finalized, we can perform the replacement. |
| 194 | template <class ELFT> void SymbolTable<ELFT>::applySymbolRenames() { | |
| 195 | for (auto &KV : Config->RenamedSymbols) { | |
| 196 | Symbol *Dst = KV.first; | |
| 197 | Symbol *Src = KV.second.Target; | |
| 198 | Dst->body()->copy(Src->body()); | |
| 199 | Dst->Binding = KV.second.OriginalBinding; | |
| 175 | void SymbolTable::applySymbolWrap() { | |
| 176 | // This function rotates 3 symbols: | |
| 177 | // | |
| 178 | // __real_sym becomes sym | |
| 179 | // sym becomes __wrap_sym | |
| 180 | // __wrap_sym becomes __real_sym | |
| 181 | // | |
| 182 | // The last part is special in that we don't want to change what references to | |
| 183 | // __wrap_sym point to, we just want have __real_sym in the symbol table. | |
| 184 | ||
| 185 | for (WrappedSymbol &W : WrappedSymbols) { | |
| 186 | // First, make a copy of __real_sym. | |
| 187 | Symbol *Real = nullptr; | |
| 188 | if (W.Real->isDefined()) { | |
| 189 | Real = (Symbol *)make<SymbolUnion>(); | |
| 190 | memcpy(Real, W.Real, sizeof(SymbolUnion)); | |
| 191 | } | |
| 192 | ||
| 193 | // Replace __real_sym with sym and sym with __wrap_sym. | |
| 194 | memcpy(W.Real, W.Sym, sizeof(SymbolUnion)); | |
| 195 | memcpy(W.Sym, W.Wrap, sizeof(SymbolUnion)); | |
| 196 | ||
| 197 | // We now have two copies of __wrap_sym. Drop one. | |
| 198 | W.Wrap->IsUsedInRegularObj = false; | |
| 199 | ||
| 200 | if (Real) | |
| 201 | SymVector.push_back(Real); | |
| 200 | 202 | } |
| 201 | 203 | } |
| 202 | 204 | |
| ... | ... | @@ -209,48 +211,50 @@ static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) { |
| 209 | 211 | } |
| 210 | 212 | |
| 211 | 213 | // Find an existing symbol or create and insert a new one. |
| 212 | template <class ELFT> | |
| 213 | std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef Name) { | |
| 214 | std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { | |
| 214 | 215 | // <name>@@<version> means the symbol is the default version. In that |
| 215 | 216 | // case <name>@@<version> will be used to resolve references to <name>. |
| 216 | size_t Pos = Name.find("@@"); | |
| 217 | if (Pos != StringRef::npos) | |
| 217 | // | |
| 218 | // Since this is a hot path, the following string search code is | |
| 219 | // optimized for speed. StringRef::find(char) is much faster than | |
| 220 | // StringRef::find(StringRef). | |
| 221 | size_t Pos = Name.find('@'); | |
| 222 | if (Pos != StringRef::npos && Pos + 1 < Name.size() && Name[Pos + 1] == '@') | |
| 218 | 223 | Name = Name.take_front(Pos); |
| 219 | 224 | |
| 220 | auto P = Symtab.insert( | |
| 221 | {CachedHashStringRef(Name), SymIndex((int)SymVector.size(), false)}); | |
| 222 | SymIndex &V = P.first->second; | |
| 225 | auto P = SymMap.insert({CachedHashStringRef(Name), (int)SymVector.size()}); | |
| 226 | int &SymIndex = P.first->second; | |
| 223 | 227 | bool IsNew = P.second; |
| 228 | bool Traced = false; | |
| 224 | 229 | |
| 225 | if (V.Idx == -1) { | |
| 226 | IsNew = true; | |
| 227 | V = SymIndex((int)SymVector.size(), true); | |
| 230 | if (SymIndex == -1) { | |
| 231 | SymIndex = SymVector.size(); | |
| 232 | IsNew = Traced = true; | |
| 228 | 233 | } |
| 229 | 234 | |
| 230 | 235 | Symbol *Sym; |
| 231 | 236 | if (IsNew) { |
| 232 | Sym = make<Symbol>(); | |
| 237 | Sym = (Symbol *)make<SymbolUnion>(); | |
| 233 | 238 | Sym->InVersionScript = false; |
| 234 | Sym->Binding = STB_WEAK; | |
| 235 | 239 | Sym->Visibility = STV_DEFAULT; |
| 236 | 240 | Sym->IsUsedInRegularObj = false; |
| 237 | 241 | Sym->ExportDynamic = false; |
| 238 | Sym->Traced = V.Traced; | |
| 242 | Sym->CanInline = true; | |
| 243 | Sym->Traced = Traced; | |
| 239 | 244 | Sym->VersionId = Config->DefaultSymbolVersion; |
| 240 | 245 | SymVector.push_back(Sym); |
| 241 | 246 | } else { |
| 242 | Sym = SymVector[V.Idx]; | |
| 247 | Sym = SymVector[SymIndex]; | |
| 243 | 248 | } |
| 244 | 249 | return {Sym, IsNew}; |
| 245 | 250 | } |
| 246 | 251 | |
| 247 | 252 | // Find an existing symbol or create and insert a new one, then apply the given |
| 248 | 253 | // attributes. |
| 249 | template <class ELFT> | |
| 250 | std::pair<Symbol *, bool> | |
| 251 | SymbolTable<ELFT>::insert(StringRef Name, uint8_t Type, uint8_t Visibility, | |
| 252 | bool CanOmitFromDynSym, InputFile *File) { | |
| 253 | bool IsUsedInRegularObj = !File || File->kind() == InputFile::ObjectKind; | |
| 254 | std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, uint8_t Type, | |
| 255 | uint8_t Visibility, | |
| 256 | bool CanOmitFromDynSym, | |
| 257 | InputFile *File) { | |
| 254 | 258 | Symbol *S; |
| 255 | 259 | bool WasInserted; |
| 256 | 260 | std::tie(S, WasInserted) = insert(Name); |
| ... | ... | @@ -261,32 +265,30 @@ SymbolTable<ELFT>::insert(StringRef Name, uint8_t Type, uint8_t Visibility, |
| 261 | 265 | if (!CanOmitFromDynSym && (Config->Shared || Config->ExportDynamic)) |
| 262 | 266 | S->ExportDynamic = true; |
| 263 | 267 | |
| 264 | if (IsUsedInRegularObj) | |
| 268 | if (!File || File->kind() == InputFile::ObjKind) | |
| 265 | 269 | S->IsUsedInRegularObj = true; |
| 266 | 270 | |
| 267 | if (!WasInserted && S->body()->Type != SymbolBody::UnknownType && | |
| 268 | ((Type == STT_TLS) != S->body()->isTls())) { | |
| 269 | error("TLS attribute mismatch: " + toString(*S->body()) + | |
| 270 | "\n>>> defined in " + toString(S->body()->File) + | |
| 271 | "\n>>> defined in " + toString(File)); | |
| 271 | if (!WasInserted && S->Type != Symbol::UnknownType && | |
| 272 | ((Type == STT_TLS) != S->isTls())) { | |
| 273 | error("TLS attribute mismatch: " + toString(*S) + "\n>>> defined in " + | |
| 274 | toString(S->File) + "\n>>> defined in " + toString(File)); | |
| 272 | 275 | } |
| 273 | 276 | |
| 274 | 277 | return {S, WasInserted}; |
| 275 | 278 | } |
| 276 | 279 | |
| 277 | template <class ELFT> Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name) { | |
| 278 | return addUndefined(Name, /*IsLocal=*/false, STB_GLOBAL, STV_DEFAULT, | |
| 279 | /*Type*/ 0, | |
| 280 | /*CanOmitFromDynSym*/ false, /*File*/ nullptr); | |
| 280 | template <class ELFT> Symbol *SymbolTable::addUndefined(StringRef Name) { | |
| 281 | return addUndefined<ELFT>(Name, STB_GLOBAL, STV_DEFAULT, | |
| 282 | /*Type*/ 0, | |
| 283 | /*CanOmitFromDynSym*/ false, /*File*/ nullptr); | |
| 281 | 284 | } |
| 282 | 285 | |
| 283 | 286 | static uint8_t getVisibility(uint8_t StOther) { return StOther & 3; } |
| 284 | 287 | |
| 285 | 288 | template <class ELFT> |
| 286 | Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name, bool IsLocal, | |
| 287 | uint8_t Binding, uint8_t StOther, | |
| 288 | uint8_t Type, bool CanOmitFromDynSym, | |
| 289 | InputFile *File) { | |
| 289 | Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding, | |
| 290 | uint8_t StOther, uint8_t Type, | |
| 291 | bool CanOmitFromDynSym, InputFile *File) { | |
| 290 | 292 | Symbol *S; |
| 291 | 293 | bool WasInserted; |
| 292 | 294 | uint8_t Visibility = getVisibility(StOther); |
| ... | ... | @@ -294,26 +296,24 @@ Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name, bool IsLocal, |
| 294 | 296 | insert(Name, Type, Visibility, CanOmitFromDynSym, File); |
| 295 | 297 | // An undefined symbol with non default visibility must be satisfied |
| 296 | 298 | // in the same DSO. |
| 297 | if (WasInserted || | |
| 298 | (isa<SharedSymbol>(S->body()) && Visibility != STV_DEFAULT)) { | |
| 299 | S->Binding = Binding; | |
| 300 | replaceBody<Undefined>(S, Name, IsLocal, StOther, Type, File); | |
| 299 | if (WasInserted || (isa<SharedSymbol>(S) && Visibility != STV_DEFAULT)) { | |
| 300 | replaceSymbol<Undefined>(S, File, Name, Binding, StOther, Type); | |
| 301 | 301 | return S; |
| 302 | 302 | } |
| 303 | if (S->isShared() || S->isLazy() || (S->isUndefined() && Binding != STB_WEAK)) | |
| 304 | S->Binding = Binding; | |
| 303 | 305 | if (Binding != STB_WEAK) { |
| 304 | SymbolBody *B = S->body(); | |
| 305 | if (B->isShared() || B->isLazy() || B->isUndefined()) | |
| 306 | S->Binding = Binding; | |
| 307 | if (auto *SS = dyn_cast<SharedSymbol>(B)) | |
| 308 | cast<SharedFile<ELFT>>(SS->File)->IsUsed = true; | |
| 306 | if (auto *SS = dyn_cast<SharedSymbol>(S)) | |
| 307 | if (!Config->GcSections) | |
| 308 | SS->getFile<ELFT>().IsNeeded = true; | |
| 309 | 309 | } |
| 310 | if (auto *L = dyn_cast<Lazy>(S->body())) { | |
| 311 | // An undefined weak will not fetch archive members, but we have to remember | |
| 312 | // its type. See also comment in addLazyArchive. | |
| 313 | if (S->isWeak()) | |
| 310 | if (auto *L = dyn_cast<Lazy>(S)) { | |
| 311 | // An undefined weak will not fetch archive members. See comment on Lazy in | |
| 312 | // Symbols.h for the details. | |
| 313 | if (Binding == STB_WEAK) | |
| 314 | 314 | L->Type = Type; |
| 315 | 315 | else if (InputFile *F = L->fetch()) |
| 316 | addFile(F); | |
| 316 | addFile<ELFT>(F); | |
| 317 | 317 | } |
| 318 | 318 | return S; |
| 319 | 319 | } |
| ... | ... | @@ -325,11 +325,11 @@ Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name, bool IsLocal, |
| 325 | 325 | // .symver foo,foo@@@VER |
| 326 | 326 | // we can delete this hack. |
| 327 | 327 | static int compareVersion(Symbol *S, StringRef Name) { |
| 328 | if (Name.find("@@") != StringRef::npos && | |
| 329 | S->body()->getName().find("@@") == StringRef::npos) | |
| 328 | bool A = Name.contains("@@"); | |
| 329 | bool B = S->getName().contains("@@"); | |
| 330 | if (A && !B) | |
| 330 | 331 | return 1; |
| 331 | if (Name.find("@@") == StringRef::npos && | |
| 332 | S->body()->getName().find("@@") != StringRef::npos) | |
| 332 | if (!A && B) | |
| 333 | 333 | return -1; |
| 334 | 334 | return 0; |
| 335 | 335 | } |
| ... | ... | @@ -341,13 +341,10 @@ static int compareDefined(Symbol *S, bool WasInserted, uint8_t Binding, |
| 341 | 341 | StringRef Name) { |
| 342 | 342 | if (WasInserted) |
| 343 | 343 | return 1; |
| 344 | SymbolBody *Body = S->body(); | |
| 345 | if (!Body->isInCurrentDSO()) | |
| 344 | if (!S->isDefined()) | |
| 346 | 345 | return 1; |
| 347 | ||
| 348 | 346 | if (int R = compareVersion(S, Name)) |
| 349 | 347 | return R; |
| 350 | ||
| 351 | 348 | if (Binding == STB_WEAK) |
| 352 | 349 | return -1; |
| 353 | 350 | if (S->isWeak()) |
| ... | ... | @@ -358,22 +355,18 @@ static int compareDefined(Symbol *S, bool WasInserted, uint8_t Binding, |
| 358 | 355 | // We have a new non-common defined symbol with the specified binding. Return 1 |
| 359 | 356 | // if the new symbol should win, -1 if the new symbol should lose, or 0 if there |
| 360 | 357 | // is a conflict. If the new symbol wins, also update the binding. |
| 361 | template <typename ELFT> | |
| 362 | 358 | static int compareDefinedNonCommon(Symbol *S, bool WasInserted, uint8_t Binding, |
| 363 | bool IsAbsolute, typename ELFT::uint Value, | |
| 359 | bool IsAbsolute, uint64_t Value, | |
| 364 | 360 | StringRef Name) { |
| 365 | if (int Cmp = compareDefined(S, WasInserted, Binding, Name)) { | |
| 366 | if (Cmp > 0) | |
| 367 | S->Binding = Binding; | |
| 361 | if (int Cmp = compareDefined(S, WasInserted, Binding, Name)) | |
| 368 | 362 | return Cmp; |
| 369 | } | |
| 370 | SymbolBody *B = S->body(); | |
| 371 | if (isa<DefinedCommon>(B)) { | |
| 372 | // Non-common symbols take precedence over common symbols. | |
| 373 | if (Config->WarnCommon) | |
| 374 | warn("common " + S->body()->getName() + " is overridden"); | |
| 375 | return 1; | |
| 376 | } else if (auto *R = dyn_cast<DefinedRegular>(B)) { | |
| 363 | if (auto *R = dyn_cast<Defined>(S)) { | |
| 364 | if (R->Section && isa<BssSection>(R->Section)) { | |
| 365 | // Non-common symbols take precedence over common symbols. | |
| 366 | if (Config->WarnCommon) | |
| 367 | warn("common " + S->getName() + " is overridden"); | |
| 368 | return 1; | |
| 369 | } | |
| 377 | 370 | if (R->Section == nullptr && Binding == STB_GLOBAL && IsAbsolute && |
| 378 | 371 | R->Value == Value) |
| 379 | 372 | return -1; |
| ... | ... | @@ -381,34 +374,39 @@ static int compareDefinedNonCommon(Symbol *S, bool WasInserted, uint8_t Binding, |
| 381 | 374 | return 0; |
| 382 | 375 | } |
| 383 | 376 | |
| 384 | template <class ELFT> | |
| 385 | Symbol *SymbolTable<ELFT>::addCommon(StringRef N, uint64_t Size, | |
| 386 | uint32_t Alignment, uint8_t Binding, | |
| 387 | uint8_t StOther, uint8_t Type, | |
| 388 | InputFile *File) { | |
| 377 | Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment, | |
| 378 | uint8_t Binding, uint8_t StOther, uint8_t Type, | |
| 379 | InputFile &File) { | |
| 389 | 380 | Symbol *S; |
| 390 | 381 | bool WasInserted; |
| 391 | 382 | std::tie(S, WasInserted) = insert(N, Type, getVisibility(StOther), |
| 392 | /*CanOmitFromDynSym*/ false, File); | |
| 383 | /*CanOmitFromDynSym*/ false, &File); | |
| 393 | 384 | int Cmp = compareDefined(S, WasInserted, Binding, N); |
| 394 | 385 | if (Cmp > 0) { |
| 395 | S->Binding = Binding; | |
| 396 | replaceBody<DefinedCommon>(S, N, Size, Alignment, StOther, Type, File); | |
| 386 | auto *Bss = make<BssSection>("COMMON", Size, Alignment); | |
| 387 | Bss->File = &File; | |
| 388 | Bss->Live = !Config->GcSections; | |
| 389 | InputSections.push_back(Bss); | |
| 390 | ||
| 391 | replaceSymbol<Defined>(S, &File, N, Binding, StOther, Type, 0, Size, Bss); | |
| 397 | 392 | } else if (Cmp == 0) { |
| 398 | auto *C = dyn_cast<DefinedCommon>(S->body()); | |
| 399 | if (!C) { | |
| 393 | auto *D = cast<Defined>(S); | |
| 394 | auto *Bss = dyn_cast_or_null<BssSection>(D->Section); | |
| 395 | if (!Bss) { | |
| 400 | 396 | // Non-common symbols take precedence over common symbols. |
| 401 | 397 | if (Config->WarnCommon) |
| 402 | warn("common " + S->body()->getName() + " is overridden"); | |
| 398 | warn("common " + S->getName() + " is overridden"); | |
| 403 | 399 | return S; |
| 404 | 400 | } |
| 405 | 401 | |
| 406 | 402 | if (Config->WarnCommon) |
| 407 | warn("multiple common of " + S->body()->getName()); | |
| 403 | warn("multiple common of " + D->getName()); | |
| 408 | 404 | |
| 409 | Alignment = C->Alignment = std::max(C->Alignment, Alignment); | |
| 410 | if (Size > C->Size) | |
| 411 | replaceBody<DefinedCommon>(S, N, Size, Alignment, StOther, Type, File); | |
| 405 | Bss->Alignment = std::max(Bss->Alignment, Alignment); | |
| 406 | if (Size > Bss->Size) { | |
| 407 | D->File = Bss->File = &File; | |
| 408 | D->Size = Bss->Size = Size; | |
| 409 | } | |
| 412 | 410 | } |
| 413 | 411 | return S; |
| 414 | 412 | } |
| ... | ... | @@ -420,17 +418,16 @@ static void warnOrError(const Twine &Msg) { |
| 420 | 418 | error(Msg); |
| 421 | 419 | } |
| 422 | 420 | |
| 423 | static void reportDuplicate(SymbolBody *Sym, InputFile *NewFile) { | |
| 421 | static void reportDuplicate(Symbol *Sym, InputFile *NewFile) { | |
| 424 | 422 | warnOrError("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " + |
| 425 | 423 | toString(Sym->File) + "\n>>> defined in " + toString(NewFile)); |
| 426 | 424 | } |
| 427 | 425 | |
| 428 | template <class ELFT> | |
| 429 | static void reportDuplicate(SymbolBody *Sym, InputSectionBase *ErrSec, | |
| 430 | typename ELFT::uint ErrOffset) { | |
| 431 | DefinedRegular *D = dyn_cast<DefinedRegular>(Sym); | |
| 432 | if (!D || !D->Section || !ErrSec) { | |
| 433 | reportDuplicate(Sym, ErrSec ? ErrSec->getFile<ELFT>() : nullptr); | |
| 426 | static void reportDuplicate(Symbol *Sym, InputSectionBase *ErrSec, | |
| 427 | uint64_t ErrOffset) { | |
| 428 | Defined *D = cast<Defined>(Sym); | |
| 429 | if (!D->Section || !ErrSec) { | |
| 430 | reportDuplicate(Sym, ErrSec ? ErrSec->File : nullptr); | |
| 434 | 431 | return; |
| 435 | 432 | } |
| 436 | 433 | |
| ... | ... | @@ -442,10 +439,10 @@ static void reportDuplicate(SymbolBody *Sym, InputSectionBase *ErrSec, |
| 442 | 439 | // >>> defined at baz.c:563 |
| 443 | 440 | // >>> baz.o in archive libbaz.a |
| 444 | 441 | auto *Sec1 = cast<InputSectionBase>(D->Section); |
| 445 | std::string Src1 = Sec1->getSrcMsg<ELFT>(D->Value); | |
| 446 | std::string Obj1 = Sec1->getObjMsg<ELFT>(D->Value); | |
| 447 | std::string Src2 = ErrSec->getSrcMsg<ELFT>(ErrOffset); | |
| 448 | std::string Obj2 = ErrSec->getObjMsg<ELFT>(ErrOffset); | |
| 442 | std::string Src1 = Sec1->getSrcMsg(*Sym, D->Value); | |
| 443 | std::string Obj1 = Sec1->getObjMsg(D->Value); | |
| 444 | std::string Src2 = ErrSec->getSrcMsg(*Sym, ErrOffset); | |
| 445 | std::string Obj2 = ErrSec->getObjMsg(ErrOffset); | |
| 449 | 446 | |
| 450 | 447 | std::string Msg = "duplicate symbol: " + toString(*Sym) + "\n>>> defined at "; |
| 451 | 448 | if (!Src1.empty()) |
| ... | ... | @@ -457,145 +454,135 @@ static void reportDuplicate(SymbolBody *Sym, InputSectionBase *ErrSec, |
| 457 | 454 | warnOrError(Msg); |
| 458 | 455 | } |
| 459 | 456 | |
| 460 | template <typename ELFT> | |
| 461 | Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t StOther, | |
| 462 | uint8_t Type, uint64_t Value, | |
| 463 | uint64_t Size, uint8_t Binding, | |
| 464 | SectionBase *Section, InputFile *File) { | |
| 457 | Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type, | |
| 458 | uint64_t Value, uint64_t Size, uint8_t Binding, | |
| 459 | SectionBase *Section, InputFile *File) { | |
| 465 | 460 | Symbol *S; |
| 466 | 461 | bool WasInserted; |
| 467 | 462 | std::tie(S, WasInserted) = insert(Name, Type, getVisibility(StOther), |
| 468 | 463 | /*CanOmitFromDynSym*/ false, File); |
| 469 | int Cmp = compareDefinedNonCommon<ELFT>(S, WasInserted, Binding, | |
| 470 | Section == nullptr, Value, Name); | |
| 464 | int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr, | |
| 465 | Value, Name); | |
| 471 | 466 | if (Cmp > 0) |
| 472 | replaceBody<DefinedRegular>(S, Name, /*IsLocal=*/false, StOther, Type, | |
| 473 | Value, Size, Section, File); | |
| 467 | replaceSymbol<Defined>(S, File, Name, Binding, StOther, Type, Value, Size, | |
| 468 | Section); | |
| 474 | 469 | else if (Cmp == 0) |
| 475 | reportDuplicate<ELFT>(S->body(), | |
| 476 | dyn_cast_or_null<InputSectionBase>(Section), Value); | |
| 470 | reportDuplicate(S, dyn_cast_or_null<InputSectionBase>(Section), Value); | |
| 477 | 471 | return S; |
| 478 | 472 | } |
| 479 | 473 | |
| 480 | 474 | template <typename ELFT> |
| 481 | void SymbolTable<ELFT>::addShared(SharedFile<ELFT> *File, StringRef Name, | |
| 482 | const Elf_Sym &Sym, | |
| 483 | const typename ELFT::Verdef *Verdef) { | |
| 475 | void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File, | |
| 476 | const typename ELFT::Sym &Sym, uint32_t Alignment, | |
| 477 | uint32_t VerdefIndex) { | |
| 484 | 478 | // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT |
| 485 | 479 | // as the visibility, which will leave the visibility in the symbol table |
| 486 | 480 | // unchanged. |
| 487 | 481 | Symbol *S; |
| 488 | 482 | bool WasInserted; |
| 489 | 483 | std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT, |
| 490 | /*CanOmitFromDynSym*/ true, File); | |
| 484 | /*CanOmitFromDynSym*/ true, &File); | |
| 491 | 485 | // Make sure we preempt DSO symbols with default visibility. |
| 492 | 486 | if (Sym.getVisibility() == STV_DEFAULT) |
| 493 | 487 | S->ExportDynamic = true; |
| 494 | 488 | |
| 495 | SymbolBody *Body = S->body(); | |
| 496 | 489 | // An undefined symbol with non default visibility must be satisfied |
| 497 | 490 | // in the same DSO. |
| 498 | if (WasInserted || | |
| 499 | (isa<Undefined>(Body) && Body->getVisibility() == STV_DEFAULT)) { | |
| 500 | replaceBody<SharedSymbol>(S, File, Name, Sym.st_other, Sym.getType(), &Sym, | |
| 501 | Verdef); | |
| 502 | if (!S->isWeak()) | |
| 503 | File->IsUsed = true; | |
| 491 | if (WasInserted || ((S->isUndefined() || S->isLazy()) && | |
| 492 | S->getVisibility() == STV_DEFAULT)) { | |
| 493 | uint8_t Binding = S->Binding; | |
| 494 | bool WasUndefined = S->isUndefined(); | |
| 495 | replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other, | |
| 496 | Sym.getType(), Sym.st_value, Sym.st_size, | |
| 497 | Alignment, VerdefIndex); | |
| 498 | if (!WasInserted) { | |
| 499 | S->Binding = Binding; | |
| 500 | if (!S->isWeak() && !Config->GcSections && WasUndefined) | |
| 501 | File.IsNeeded = true; | |
| 502 | } | |
| 504 | 503 | } |
| 505 | 504 | } |
| 506 | 505 | |
| 507 | template <class ELFT> | |
| 508 | Symbol *SymbolTable<ELFT>::addBitcode(StringRef Name, uint8_t Binding, | |
| 509 | uint8_t StOther, uint8_t Type, | |
| 510 | bool CanOmitFromDynSym, BitcodeFile *F) { | |
| 506 | Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding, | |
| 507 | uint8_t StOther, uint8_t Type, | |
| 508 | bool CanOmitFromDynSym, BitcodeFile &F) { | |
| 511 | 509 | Symbol *S; |
| 512 | 510 | bool WasInserted; |
| 513 | 511 | std::tie(S, WasInserted) = |
| 514 | insert(Name, Type, getVisibility(StOther), CanOmitFromDynSym, F); | |
| 515 | int Cmp = compareDefinedNonCommon<ELFT>(S, WasInserted, Binding, | |
| 516 | /*IsAbs*/ false, /*Value*/ 0, Name); | |
| 512 | insert(Name, Type, getVisibility(StOther), CanOmitFromDynSym, &F); | |
| 513 | int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, | |
| 514 | /*IsAbs*/ false, /*Value*/ 0, Name); | |
| 517 | 515 | if (Cmp > 0) |
| 518 | replaceBody<DefinedRegular>(S, Name, /*IsLocal=*/false, StOther, Type, 0, 0, | |
| 519 | nullptr, F); | |
| 516 | replaceSymbol<Defined>(S, &F, Name, Binding, StOther, Type, 0, 0, nullptr); | |
| 520 | 517 | else if (Cmp == 0) |
| 521 | reportDuplicate(S->body(), F); | |
| 518 | reportDuplicate(S, &F); | |
| 522 | 519 | return S; |
| 523 | 520 | } |
| 524 | 521 | |
| 525 | template <class ELFT> SymbolBody *SymbolTable<ELFT>::find(StringRef Name) { | |
| 526 | auto It = Symtab.find(CachedHashStringRef(Name)); | |
| 527 | if (It == Symtab.end()) | |
| 522 | Symbol *SymbolTable::find(StringRef Name) { | |
| 523 | auto It = SymMap.find(CachedHashStringRef(Name)); | |
| 524 | if (It == SymMap.end()) | |
| 528 | 525 | return nullptr; |
| 529 | SymIndex V = It->second; | |
| 530 | if (V.Idx == -1) | |
| 526 | if (It->second == -1) | |
| 531 | 527 | return nullptr; |
| 532 | return SymVector[V.Idx]->body(); | |
| 528 | return SymVector[It->second]; | |
| 533 | 529 | } |
| 534 | 530 | |
| 535 | 531 | template <class ELFT> |
| 536 | SymbolBody *SymbolTable<ELFT>::findInCurrentDSO(StringRef Name) { | |
| 537 | if (SymbolBody *S = find(Name)) | |
| 538 | if (S->isInCurrentDSO()) | |
| 539 | return S; | |
| 540 | return nullptr; | |
| 541 | } | |
| 542 | ||
| 543 | template <class ELFT> | |
| 544 | Symbol *SymbolTable<ELFT>::addLazyArchive(ArchiveFile *F, | |
| 545 | const object::Archive::Symbol Sym) { | |
| 532 | Symbol *SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &F, | |
| 533 | const object::Archive::Symbol Sym) { | |
| 546 | 534 | Symbol *S; |
| 547 | 535 | bool WasInserted; |
| 548 | StringRef Name = Sym.getName(); | |
| 549 | 536 | std::tie(S, WasInserted) = insert(Name); |
| 550 | 537 | if (WasInserted) { |
| 551 | replaceBody<LazyArchive>(S, *F, Sym, SymbolBody::UnknownType); | |
| 538 | replaceSymbol<LazyArchive>(S, F, Sym, Symbol::UnknownType); | |
| 552 | 539 | return S; |
| 553 | 540 | } |
| 554 | if (!S->body()->isUndefined()) | |
| 541 | if (!S->isUndefined()) | |
| 555 | 542 | return S; |
| 556 | 543 | |
| 557 | // Weak undefined symbols should not fetch members from archives. If we were | |
| 558 | // to keep old symbol we would not know that an archive member was available | |
| 559 | // if a strong undefined symbol shows up afterwards in the link. If a strong | |
| 560 | // undefined symbol never shows up, this lazy symbol will get to the end of | |
| 561 | // the link and must be treated as the weak undefined one. We already marked | |
| 562 | // this symbol as used when we added it to the symbol table, but we also need | |
| 563 | // to preserve its type. FIXME: Move the Type field to Symbol. | |
| 544 | // An undefined weak will not fetch archive members. See comment on Lazy in | |
| 545 | // Symbols.h for the details. | |
| 564 | 546 | if (S->isWeak()) { |
| 565 | replaceBody<LazyArchive>(S, *F, Sym, S->body()->Type); | |
| 547 | replaceSymbol<LazyArchive>(S, F, Sym, S->Type); | |
| 548 | S->Binding = STB_WEAK; | |
| 566 | 549 | return S; |
| 567 | 550 | } |
| 568 | std::pair<MemoryBufferRef, uint64_t> MBInfo = F->getMember(&Sym); | |
| 551 | std::pair<MemoryBufferRef, uint64_t> MBInfo = F.getMember(&Sym); | |
| 569 | 552 | if (!MBInfo.first.getBuffer().empty()) |
| 570 | addFile(createObjectFile(MBInfo.first, F->getName(), MBInfo.second)); | |
| 553 | addFile<ELFT>(createObjectFile(MBInfo.first, F.getName(), MBInfo.second)); | |
| 571 | 554 | return S; |
| 572 | 555 | } |
| 573 | 556 | |
| 574 | 557 | template <class ELFT> |
| 575 | void SymbolTable<ELFT>::addLazyObject(StringRef Name, LazyObjectFile &Obj) { | |
| 558 | void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &Obj) { | |
| 576 | 559 | Symbol *S; |
| 577 | 560 | bool WasInserted; |
| 578 | 561 | std::tie(S, WasInserted) = insert(Name); |
| 579 | 562 | if (WasInserted) { |
| 580 | replaceBody<LazyObject>(S, Name, Obj, SymbolBody::UnknownType); | |
| 563 | replaceSymbol<LazyObject>(S, Obj, Name, Symbol::UnknownType); | |
| 581 | 564 | return; |
| 582 | 565 | } |
| 583 | if (!S->body()->isUndefined()) | |
| 566 | if (!S->isUndefined()) | |
| 584 | 567 | return; |
| 585 | 568 | |
| 586 | 569 | // See comment for addLazyArchive above. |
| 587 | 570 | if (S->isWeak()) |
| 588 | replaceBody<LazyObject>(S, Name, Obj, S->body()->Type); | |
| 571 | replaceSymbol<LazyObject>(S, Obj, Name, S->Type); | |
| 589 | 572 | else if (InputFile *F = Obj.fetch()) |
| 590 | addFile(F); | |
| 573 | addFile<ELFT>(F); | |
| 591 | 574 | } |
| 592 | 575 | |
| 593 | // Process undefined (-u) flags by loading lazy symbols named by those flags. | |
| 594 | template <class ELFT> void SymbolTable<ELFT>::scanUndefinedFlags() { | |
| 595 | for (StringRef S : Config->Undefined) | |
| 596 | if (auto *L = dyn_cast_or_null<Lazy>(find(S))) | |
| 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)) | |
| 597 | 583 | if (InputFile *File = L->fetch()) |
| 598 | addFile(File); | |
| 584 | addFile<ELFT>(File); | |
| 585 | } | |
| 599 | 586 | } |
| 600 | 587 | |
| 601 | 588 | // This function takes care of the case in which shared libraries depend on |
| ... | ... | @@ -605,19 +592,19 @@ template <class ELFT> void SymbolTable<ELFT>::scanUndefinedFlags() { |
| 605 | 592 | // We need to put such symbols to the main program's .dynsym so that |
| 606 | 593 | // shared libraries can find them. |
| 607 | 594 | // Except this, we ignore undefined symbols in DSOs. |
| 608 | template <class ELFT> void SymbolTable<ELFT>::scanShlibUndefined() { | |
| 609 | for (SharedFile<ELFT> *File : SharedFiles) { | |
| 610 | for (StringRef U : File->getUndefinedSymbols()) { | |
| 611 | SymbolBody *Sym = find(U); | |
| 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); | |
| 612 | 599 | if (!Sym || !Sym->isDefined()) |
| 613 | 600 | continue; |
| 614 | Sym->symbol()->ExportDynamic = true; | |
| 601 | Sym->ExportDynamic = true; | |
| 615 | 602 | |
| 616 | 603 | // If -dynamic-list is given, the default version is set to |
| 617 | 604 | // VER_NDX_LOCAL, which prevents a symbol to be exported via .dynsym. |
| 618 | 605 | // Set to VER_NDX_GLOBAL so the symbol will be handled as if it were |
| 619 | 606 | // specified by -dynamic-list. |
| 620 | Sym->symbol()->VersionId = VER_NDX_GLOBAL; | |
| 607 | Sym->VersionId = VER_NDX_GLOBAL; | |
| 621 | 608 | } |
| 622 | 609 | } |
| 623 | 610 | } |
| ... | ... | @@ -635,37 +622,32 @@ template <class ELFT> void SymbolTable<ELFT>::scanShlibUndefined() { |
| 635 | 622 | // other than trying to match a pattern against all demangled symbols. |
| 636 | 623 | // So, if "extern C++" feature is used, we need to demangle all known |
| 637 | 624 | // symbols. |
| 638 | template <class ELFT> | |
| 639 | StringMap<std::vector<SymbolBody *>> &SymbolTable<ELFT>::getDemangledSyms() { | |
| 625 | StringMap<std::vector<Symbol *>> &SymbolTable::getDemangledSyms() { | |
| 640 | 626 | if (!DemangledSyms) { |
| 641 | 627 | DemangledSyms.emplace(); |
| 642 | 628 | for (Symbol *Sym : SymVector) { |
| 643 | SymbolBody *B = Sym->body(); | |
| 644 | if (B->isUndefined()) | |
| 629 | if (!Sym->isDefined()) | |
| 645 | 630 | continue; |
| 646 | if (Optional<std::string> S = demangle(B->getName())) | |
| 647 | (*DemangledSyms)[*S].push_back(B); | |
| 631 | if (Optional<std::string> S = demangleItanium(Sym->getName())) | |
| 632 | (*DemangledSyms)[*S].push_back(Sym); | |
| 648 | 633 | else |
| 649 | (*DemangledSyms)[B->getName()].push_back(B); | |
| 634 | (*DemangledSyms)[Sym->getName()].push_back(Sym); | |
| 650 | 635 | } |
| 651 | 636 | } |
| 652 | 637 | return *DemangledSyms; |
| 653 | 638 | } |
| 654 | 639 | |
| 655 | template <class ELFT> | |
| 656 | std::vector<SymbolBody *> SymbolTable<ELFT>::findByVersion(SymbolVersion Ver) { | |
| 640 | std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion Ver) { | |
| 657 | 641 | if (Ver.IsExternCpp) |
| 658 | 642 | return getDemangledSyms().lookup(Ver.Name); |
| 659 | if (SymbolBody *B = find(Ver.Name)) | |
| 660 | if (!B->isUndefined()) | |
| 643 | if (Symbol *B = find(Ver.Name)) | |
| 644 | if (B->isDefined()) | |
| 661 | 645 | return {B}; |
| 662 | 646 | return {}; |
| 663 | 647 | } |
| 664 | 648 | |
| 665 | template <class ELFT> | |
| 666 | std::vector<SymbolBody *> | |
| 667 | SymbolTable<ELFT>::findAllByVersion(SymbolVersion Ver) { | |
| 668 | std::vector<SymbolBody *> Res; | |
| 649 | std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion Ver) { | |
| 650 | std::vector<Symbol *> Res; | |
| 669 | 651 | StringMatcher M(Ver.Name); |
| 670 | 652 | |
| 671 | 653 | if (Ver.IsExternCpp) { |
| ... | ... | @@ -675,18 +657,16 @@ SymbolTable<ELFT>::findAllByVersion(SymbolVersion Ver) { |
| 675 | 657 | return Res; |
| 676 | 658 | } |
| 677 | 659 | |
| 678 | for (Symbol *Sym : SymVector) { | |
| 679 | SymbolBody *B = Sym->body(); | |
| 680 | if (!B->isUndefined() && M.match(B->getName())) | |
| 681 | Res.push_back(B); | |
| 682 | } | |
| 660 | for (Symbol *Sym : SymVector) | |
| 661 | if (Sym->isDefined() && M.match(Sym->getName())) | |
| 662 | Res.push_back(Sym); | |
| 683 | 663 | return Res; |
| 684 | 664 | } |
| 685 | 665 | |
| 686 | 666 | // If there's only one anonymous version definition in a version |
| 687 | 667 | // script file, the script does not actually define any symbol version, |
| 688 | 668 | // but just specifies symbols visibilities. |
| 689 | template <class ELFT> void SymbolTable<ELFT>::handleAnonymousVersion() { | |
| 669 | void SymbolTable::handleAnonymousVersion() { | |
| 690 | 670 | for (SymbolVersion &Ver : Config->VersionScriptGlobals) |
| 691 | 671 | assignExactVersion(Ver, VER_NDX_GLOBAL, "global"); |
| 692 | 672 | for (SymbolVersion &Ver : Config->VersionScriptGlobals) |
| ... | ... | @@ -697,17 +677,33 @@ template <class ELFT> void SymbolTable<ELFT>::handleAnonymousVersion() { |
| 697 | 677 | assignWildcardVersion(Ver, VER_NDX_LOCAL); |
| 698 | 678 | } |
| 699 | 679 | |
| 680 | // Handles -dynamic-list. | |
| 681 | void SymbolTable::handleDynamicList() { | |
| 682 | for (SymbolVersion &Ver : Config->DynamicList) { | |
| 683 | std::vector<Symbol *> Syms; | |
| 684 | if (Ver.HasWildcard) | |
| 685 | Syms = findAllByVersion(Ver); | |
| 686 | else | |
| 687 | Syms = findByVersion(Ver); | |
| 688 | ||
| 689 | for (Symbol *B : Syms) { | |
| 690 | if (!Config->Shared) | |
| 691 | B->ExportDynamic = true; | |
| 692 | else if (B->includeInDynsym()) | |
| 693 | B->IsPreemptible = true; | |
| 694 | } | |
| 695 | } | |
| 696 | } | |
| 697 | ||
| 700 | 698 | // Set symbol versions to symbols. This function handles patterns |
| 701 | 699 | // containing no wildcard characters. |
| 702 | template <class ELFT> | |
| 703 | void SymbolTable<ELFT>::assignExactVersion(SymbolVersion Ver, | |
| 704 | uint16_t VersionId, | |
| 705 | StringRef VersionName) { | |
| 700 | void SymbolTable::assignExactVersion(SymbolVersion Ver, uint16_t VersionId, | |
| 701 | StringRef VersionName) { | |
| 706 | 702 | if (Ver.HasWildcard) |
| 707 | 703 | return; |
| 708 | 704 | |
| 709 | 705 | // Get a list of symbols which we need to assign the version to. |
| 710 | std::vector<SymbolBody *> Syms = findByVersion(Ver); | |
| 706 | std::vector<Symbol *> Syms = findByVersion(Ver); | |
| 711 | 707 | if (Syms.empty()) { |
| 712 | 708 | if (Config->NoUndefinedVersion) |
| 713 | 709 | error("version script assignment of '" + VersionName + "' to symbol '" + |
| ... | ... | @@ -716,14 +712,13 @@ void SymbolTable<ELFT>::assignExactVersion(SymbolVersion Ver, |
| 716 | 712 | } |
| 717 | 713 | |
| 718 | 714 | // Assign the version. |
| 719 | for (SymbolBody *B : Syms) { | |
| 715 | for (Symbol *Sym : Syms) { | |
| 720 | 716 | // Skip symbols containing version info because symbol versions |
| 721 | 717 | // specified by symbol names take precedence over version scripts. |
| 722 | 718 | // See parseSymbolVersion(). |
| 723 | if (B->getName().find('@') != StringRef::npos) | |
| 719 | if (Sym->getName().contains('@')) | |
| 724 | 720 | continue; |
| 725 | 721 | |
| 726 | Symbol *Sym = B->symbol(); | |
| 727 | 722 | if (Sym->InVersionScript) |
| 728 | 723 | warn("duplicate symbol '" + Ver.Name + "' in version script"); |
| 729 | 724 | Sym->VersionId = VersionId; |
| ... | ... | @@ -731,25 +726,24 @@ void SymbolTable<ELFT>::assignExactVersion(SymbolVersion Ver, |
| 731 | 726 | } |
| 732 | 727 | } |
| 733 | 728 | |
| 734 | template <class ELFT> | |
| 735 | void SymbolTable<ELFT>::assignWildcardVersion(SymbolVersion Ver, | |
| 736 | uint16_t VersionId) { | |
| 729 | void SymbolTable::assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId) { | |
| 737 | 730 | if (!Ver.HasWildcard) |
| 738 | 731 | return; |
| 739 | 732 | |
| 740 | 733 | // Exact matching takes precendence over fuzzy matching, |
| 741 | 734 | // so we set a version to a symbol only if no version has been assigned |
| 742 | 735 | // to the symbol. This behavior is compatible with GNU. |
| 743 | for (SymbolBody *B : findAllByVersion(Ver)) | |
| 744 | if (B->symbol()->VersionId == Config->DefaultSymbolVersion) | |
| 745 | B->symbol()->VersionId = VersionId; | |
| 736 | for (Symbol *B : findAllByVersion(Ver)) | |
| 737 | if (B->VersionId == Config->DefaultSymbolVersion) | |
| 738 | B->VersionId = VersionId; | |
| 746 | 739 | } |
| 747 | 740 | |
| 748 | 741 | // This function processes version scripts by updating VersionId |
| 749 | 742 | // member of symbols. |
| 750 | template <class ELFT> void SymbolTable<ELFT>::scanVersionScript() { | |
| 743 | void SymbolTable::scanVersionScript() { | |
| 751 | 744 | // Handle edge cases first. |
| 752 | 745 | handleAnonymousVersion(); |
| 746 | handleDynamicList(); | |
| 753 | 747 | |
| 754 | 748 | // Now we have version definitions, so we need to set version ids to symbols. |
| 755 | 749 | // Each version definition has a glob pattern, and all symbols that match |
| ... | ... | @@ -773,10 +767,70 @@ template <class ELFT> void SymbolTable<ELFT>::scanVersionScript() { |
| 773 | 767 | // can contain versions in the form of <name>@<version>. |
| 774 | 768 | // Let them parse and update their names to exclude version suffix. |
| 775 | 769 | for (Symbol *Sym : SymVector) |
| 776 | Sym->body()->parseSymbolVersion(); | |
| 777 | } | |
| 778 | ||
| 779 | template class elf::SymbolTable<ELF32LE>; | |
| 780 | template class elf::SymbolTable<ELF32BE>; | |
| 781 | template class elf::SymbolTable<ELF64LE>; | |
| 782 | template class elf::SymbolTable<ELF64BE>; | |
| 770 | Sym->parseSymbolVersion(); | |
| 771 | } | |
| 772 | ||
| 773 | template void SymbolTable::addSymbolWrap<ELF32LE>(StringRef); | |
| 774 | template void SymbolTable::addSymbolWrap<ELF32BE>(StringRef); | |
| 775 | template void SymbolTable::addSymbolWrap<ELF64LE>(StringRef); | |
| 776 | template void SymbolTable::addSymbolWrap<ELF64BE>(StringRef); | |
| 777 | ||
| 778 | template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef); | |
| 779 | template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef); | |
| 780 | template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef); | |
| 781 | template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef); | |
| 782 | ||
| 783 | template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef, uint8_t, uint8_t, | |
| 784 | uint8_t, bool, InputFile *); | |
| 785 | template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef, uint8_t, uint8_t, | |
| 786 | uint8_t, bool, InputFile *); | |
| 787 | template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef, uint8_t, uint8_t, | |
| 788 | uint8_t, bool, InputFile *); | |
| 789 | template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef, uint8_t, uint8_t, | |
| 790 | uint8_t, bool, InputFile *); | |
| 791 | ||
| 792 | template void SymbolTable::addCombinedLTOObject<ELF32LE>(); | |
| 793 | template void SymbolTable::addCombinedLTOObject<ELF32BE>(); | |
| 794 | template void SymbolTable::addCombinedLTOObject<ELF64LE>(); | |
| 795 | template void SymbolTable::addCombinedLTOObject<ELF64BE>(); | |
| 796 | ||
| 797 | template Symbol * | |
| 798 | SymbolTable::addLazyArchive<ELF32LE>(StringRef, ArchiveFile &, | |
| 799 | const object::Archive::Symbol); | |
| 800 | template Symbol * | |
| 801 | SymbolTable::addLazyArchive<ELF32BE>(StringRef, ArchiveFile &, | |
| 802 | const object::Archive::Symbol); | |
| 803 | template Symbol * | |
| 804 | SymbolTable::addLazyArchive<ELF64LE>(StringRef, ArchiveFile &, | |
| 805 | const object::Archive::Symbol); | |
| 806 | template Symbol * | |
| 807 | SymbolTable::addLazyArchive<ELF64BE>(StringRef, ArchiveFile &, | |
| 808 | const object::Archive::Symbol); | |
| 809 | ||
| 810 | template void SymbolTable::addLazyObject<ELF32LE>(StringRef, LazyObjFile &); | |
| 811 | template void SymbolTable::addLazyObject<ELF32BE>(StringRef, LazyObjFile &); | |
| 812 | template void SymbolTable::addLazyObject<ELF64LE>(StringRef, LazyObjFile &); | |
| 813 | template void SymbolTable::addLazyObject<ELF64BE>(StringRef, LazyObjFile &); | |
| 814 | ||
| 815 | template void SymbolTable::addShared<ELF32LE>(StringRef, SharedFile<ELF32LE> &, | |
| 816 | const typename ELF32LE::Sym &, | |
| 817 | uint32_t Alignment, uint32_t); | |
| 818 | template void SymbolTable::addShared<ELF32BE>(StringRef, SharedFile<ELF32BE> &, | |
| 819 | const typename ELF32BE::Sym &, | |
| 820 | uint32_t Alignment, uint32_t); | |
| 821 | template void SymbolTable::addShared<ELF64LE>(StringRef, SharedFile<ELF64LE> &, | |
| 822 | const typename ELF64LE::Sym &, | |
| 823 | uint32_t Alignment, uint32_t); | |
| 824 | template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile<ELF64BE> &, | |
| 825 | const typename ELF64BE::Sym &, | |
| 826 | 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+48-53| ... | ... | @@ -18,8 +18,8 @@ |
| 18 | 18 | |
| 19 | 19 | namespace lld { |
| 20 | 20 | namespace elf { |
| 21 | ||
| 22 | struct Symbol; | |
| 21 | class Defined; | |
| 22 | class SectionBase; | |
| 23 | 23 | |
| 24 | 24 | // SymbolTable is a bucket of all known symbols, including defined, |
| 25 | 25 | // undefined, or lazy symbols (the last one is symbols in archive |
| ... | ... | @@ -33,78 +33,71 @@ struct Symbol; |
| 33 | 33 | // to replace the lazy symbol. The logic is implemented in the |
| 34 | 34 | // add*() functions, which are called by input files as they are parsed. There |
| 35 | 35 | // is one add* function per symbol type. |
| 36 | template <class ELFT> class SymbolTable { | |
| 37 | typedef typename ELFT::Sym Elf_Sym; | |
| 38 | ||
| 36 | class SymbolTable { | |
| 39 | 37 | public: |
| 40 | void addFile(InputFile *File); | |
| 41 | void addCombinedLTOObject(); | |
| 42 | void addSymbolAlias(StringRef Alias, StringRef Name); | |
| 43 | void addSymbolWrap(StringRef Name); | |
| 44 | void applySymbolRenames(); | |
| 38 | template <class ELFT> void addFile(InputFile *File); | |
| 39 | template <class ELFT> void addCombinedLTOObject(); | |
| 40 | template <class ELFT> void addSymbolWrap(StringRef Name); | |
| 41 | void applySymbolWrap(); | |
| 45 | 42 | |
| 46 | 43 | ArrayRef<Symbol *> getSymbols() const { return SymVector; } |
| 47 | ArrayRef<ObjectFile<ELFT> *> getObjectFiles() const { return ObjectFiles; } | |
| 48 | ArrayRef<BinaryFile *> getBinaryFiles() const { return BinaryFiles; } | |
| 49 | ArrayRef<SharedFile<ELFT> *> getSharedFiles() const { return SharedFiles; } | |
| 50 | 44 | |
| 51 | DefinedRegular *addAbsolute(StringRef Name, | |
| 52 | uint8_t Visibility = llvm::ELF::STV_HIDDEN, | |
| 53 | uint8_t Binding = llvm::ELF::STB_GLOBAL); | |
| 54 | DefinedRegular *addIgnored(StringRef Name, | |
| 55 | uint8_t Visibility = llvm::ELF::STV_HIDDEN); | |
| 56 | ||
| 57 | Symbol *addUndefined(StringRef Name); | |
| 58 | Symbol *addUndefined(StringRef Name, bool IsLocal, uint8_t Binding, | |
| 59 | uint8_t StOther, uint8_t Type, bool CanOmitFromDynSym, | |
| 60 | InputFile *File); | |
| 45 | Defined *addAbsolute(StringRef Name, | |
| 46 | uint8_t Visibility = llvm::ELF::STV_HIDDEN, | |
| 47 | uint8_t Binding = llvm::ELF::STB_GLOBAL); | |
| 61 | 48 | |
| 49 | template <class ELFT> Symbol *addUndefined(StringRef Name); | |
| 50 | template <class ELFT> | |
| 51 | Symbol *addUndefined(StringRef Name, uint8_t Binding, uint8_t StOther, | |
| 52 | uint8_t Type, bool CanOmitFromDynSym, InputFile *File); | |
| 62 | 53 | Symbol *addRegular(StringRef Name, uint8_t StOther, uint8_t Type, |
| 63 | 54 | uint64_t Value, uint64_t Size, uint8_t Binding, |
| 64 | 55 | SectionBase *Section, InputFile *File); |
| 65 | 56 | |
| 66 | void addShared(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym, | |
| 67 | const typename ELFT::Verdef *Verdef); | |
| 57 | template <class ELFT> | |
| 58 | void addShared(StringRef Name, SharedFile<ELFT> &F, | |
| 59 | const typename ELFT::Sym &Sym, uint32_t Alignment, | |
| 60 | uint32_t VerdefIndex); | |
| 61 | ||
| 62 | template <class ELFT> | |
| 63 | Symbol *addLazyArchive(StringRef Name, ArchiveFile &F, | |
| 64 | const llvm::object::Archive::Symbol S); | |
| 65 | ||
| 66 | template <class ELFT> void addLazyObject(StringRef Name, LazyObjFile &Obj); | |
| 68 | 67 | |
| 69 | Symbol *addLazyArchive(ArchiveFile *F, const llvm::object::Archive::Symbol S); | |
| 70 | void addLazyObject(StringRef Name, LazyObjectFile &Obj); | |
| 71 | 68 | Symbol *addBitcode(StringRef Name, uint8_t Binding, uint8_t StOther, |
| 72 | uint8_t Type, bool CanOmitFromDynSym, BitcodeFile *File); | |
| 69 | uint8_t Type, bool CanOmitFromDynSym, BitcodeFile &File); | |
| 73 | 70 | |
| 74 | Symbol *addCommon(StringRef N, uint64_t Size, uint32_t Alignment, | |
| 71 | Symbol *addCommon(StringRef Name, uint64_t Size, uint32_t Alignment, | |
| 75 | 72 | uint8_t Binding, uint8_t StOther, uint8_t Type, |
| 76 | InputFile *File); | |
| 73 | InputFile &File); | |
| 77 | 74 | |
| 78 | 75 | std::pair<Symbol *, bool> insert(StringRef Name); |
| 79 | 76 | std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Type, |
| 80 | 77 | uint8_t Visibility, bool CanOmitFromDynSym, |
| 81 | 78 | InputFile *File); |
| 82 | 79 | |
| 83 | void scanUndefinedFlags(); | |
| 84 | void scanShlibUndefined(); | |
| 80 | template <class ELFT> void fetchIfLazy(StringRef Name); | |
| 81 | template <class ELFT> void scanShlibUndefined(); | |
| 85 | 82 | void scanVersionScript(); |
| 86 | 83 | |
| 87 | SymbolBody *find(StringRef Name); | |
| 88 | SymbolBody *findInCurrentDSO(StringRef Name); | |
| 84 | Symbol *find(StringRef Name); | |
| 89 | 85 | |
| 90 | 86 | void trace(StringRef Name); |
| 91 | 87 | |
| 88 | void handleDynamicList(); | |
| 89 | ||
| 92 | 90 | private: |
| 93 | std::vector<SymbolBody *> findByVersion(SymbolVersion Ver); | |
| 94 | std::vector<SymbolBody *> findAllByVersion(SymbolVersion Ver); | |
| 91 | std::vector<Symbol *> findByVersion(SymbolVersion Ver); | |
| 92 | std::vector<Symbol *> findAllByVersion(SymbolVersion Ver); | |
| 93 | void defsym(Symbol *Dst, Symbol *Src); | |
| 95 | 94 | |
| 96 | llvm::StringMap<std::vector<SymbolBody *>> &getDemangledSyms(); | |
| 95 | llvm::StringMap<std::vector<Symbol *>> &getDemangledSyms(); | |
| 97 | 96 | void handleAnonymousVersion(); |
| 98 | 97 | void assignExactVersion(SymbolVersion Ver, uint16_t VersionId, |
| 99 | 98 | StringRef VersionName); |
| 100 | 99 | void assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId); |
| 101 | 100 | |
| 102 | struct SymIndex { | |
| 103 | SymIndex(int Idx, bool Traced) : Idx(Idx), Traced(Traced) {} | |
| 104 | int Idx : 31; | |
| 105 | unsigned Traced : 1; | |
| 106 | }; | |
| 107 | ||
| 108 | 101 | // The order the global symbols are in is not defined. We can use an arbitrary |
| 109 | 102 | // order, but it has to be reproducible. That is true even when cross linking. |
| 110 | 103 | // The default hashing of StringRef produces different results on 32 and 64 |
| ... | ... | @@ -112,7 +105,7 @@ private: |
| 112 | 105 | // but a bit inefficient. |
| 113 | 106 | // FIXME: Experiment with passing in a custom hashing or sorting the symbols |
| 114 | 107 | // once symbol resolution is finished. |
| 115 | llvm::DenseMap<llvm::CachedHashStringRef, SymIndex> Symtab; | |
| 108 | llvm::DenseMap<llvm::CachedHashStringRef, int> SymMap; | |
| 116 | 109 | std::vector<Symbol *> SymVector; |
| 117 | 110 | |
| 118 | 111 | // Comdat groups define "link once" sections. If two comdat groups have the |
| ... | ... | @@ -120,11 +113,6 @@ private: |
| 120 | 113 | // is used to uniquify them. |
| 121 | 114 | llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups; |
| 122 | 115 | |
| 123 | std::vector<ObjectFile<ELFT> *> ObjectFiles; | |
| 124 | std::vector<SharedFile<ELFT> *> SharedFiles; | |
| 125 | std::vector<BitcodeFile *> BitcodeFiles; | |
| 126 | std::vector<BinaryFile *> BinaryFiles; | |
| 127 | ||
| 128 | 116 | // Set of .so files to not link the same shared object file more than once. |
| 129 | 117 | llvm::DenseSet<StringRef> SoNames; |
| 130 | 118 | |
| ... | ... | @@ -132,15 +120,22 @@ private: |
| 132 | 120 | // This mapping is 1:N because two symbols with different versions |
| 133 | 121 | // can have the same name. We use this map to handle "extern C++ {}" |
| 134 | 122 | // directive in version scripts. |
| 135 | llvm::Optional<llvm::StringMap<std::vector<SymbolBody *>>> DemangledSyms; | |
| 123 | llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> DemangledSyms; | |
| 124 | ||
| 125 | struct WrappedSymbol { | |
| 126 | Symbol *Sym; | |
| 127 | Symbol *Real; | |
| 128 | Symbol *Wrap; | |
| 129 | }; | |
| 130 | ||
| 131 | // For -wrap. | |
| 132 | std::vector<WrappedSymbol> WrappedSymbols; | |
| 136 | 133 | |
| 137 | 134 | // For LTO. |
| 138 | 135 | std::unique_ptr<BitcodeCompiler> LTO; |
| 139 | 136 | }; |
| 140 | 137 | |
| 141 | template <class ELFT> struct Symtab { static SymbolTable<ELFT> *X; }; | |
| 142 | template <class ELFT> SymbolTable<ELFT> *Symtab<ELFT>::X; | |
| 143 | ||
| 138 | extern SymbolTable *Symtab; | |
| 144 | 139 | } // namespace elf |
| 145 | 140 | } // namespace lld |
| 146 | 141 |
deps/lld/ELF/Symbols.cpp+67-184| ... | ... | @@ -8,15 +8,15 @@ |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | 10 | #include "Symbols.h" |
| 11 | #include "Error.h" | |
| 12 | 11 | #include "InputFiles.h" |
| 13 | 12 | #include "InputSection.h" |
| 14 | 13 | #include "OutputSections.h" |
| 15 | #include "Strings.h" | |
| 16 | 14 | #include "SyntheticSections.h" |
| 17 | 15 | #include "Target.h" |
| 18 | 16 | #include "Writer.h" |
| 19 | 17 | |
| 18 | #include "lld/Common/ErrorHandler.h" | |
| 19 | #include "lld/Common/Strings.h" | |
| 20 | 20 | #include "llvm/ADT/STLExtras.h" |
| 21 | 21 | #include "llvm/Support/Path.h" |
| 22 | 22 | #include <cstring> |
| ... | ... | @@ -28,25 +28,23 @@ using namespace llvm::ELF; |
| 28 | 28 | using namespace lld; |
| 29 | 29 | using namespace lld::elf; |
| 30 | 30 | |
| 31 | DefinedRegular *ElfSym::Bss; | |
| 32 | DefinedRegular *ElfSym::Etext1; | |
| 33 | DefinedRegular *ElfSym::Etext2; | |
| 34 | DefinedRegular *ElfSym::Edata1; | |
| 35 | DefinedRegular *ElfSym::Edata2; | |
| 36 | DefinedRegular *ElfSym::End1; | |
| 37 | DefinedRegular *ElfSym::End2; | |
| 38 | DefinedRegular *ElfSym::GlobalOffsetTable; | |
| 39 | DefinedRegular *ElfSym::MipsGp; | |
| 40 | DefinedRegular *ElfSym::MipsGpDisp; | |
| 41 | DefinedRegular *ElfSym::MipsLocalGp; | |
| 42 | ||
| 43 | static uint64_t getSymVA(const SymbolBody &Body, int64_t &Addend) { | |
| 44 | switch (Body.kind()) { | |
| 45 | case SymbolBody::DefinedRegularKind: { | |
| 46 | auto &D = cast<DefinedRegular>(Body); | |
| 31 | Defined *ElfSym::Bss; | |
| 32 | Defined *ElfSym::Etext1; | |
| 33 | Defined *ElfSym::Etext2; | |
| 34 | Defined *ElfSym::Edata1; | |
| 35 | Defined *ElfSym::Edata2; | |
| 36 | Defined *ElfSym::End1; | |
| 37 | Defined *ElfSym::End2; | |
| 38 | Defined *ElfSym::GlobalOffsetTable; | |
| 39 | Defined *ElfSym::MipsGp; | |
| 40 | Defined *ElfSym::MipsGpDisp; | |
| 41 | Defined *ElfSym::MipsLocalGp; | |
| 42 | ||
| 43 | static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) { | |
| 44 | switch (Sym.kind()) { | |
| 45 | case Symbol::DefinedKind: { | |
| 46 | auto &D = cast<Defined>(Sym); | |
| 47 | 47 | SectionBase *IS = D.Section; |
| 48 | if (auto *ISB = dyn_cast_or_null<InputSectionBase>(IS)) | |
| 49 | IS = ISB->Repl; | |
| 50 | 48 | |
| 51 | 49 | // According to the ELF spec reference to a local symbol from outside |
| 52 | 50 | // the group are not allowed. Unfortunately .eh_frame breaks that rule |
| ... | ... | @@ -59,6 +57,7 @@ static uint64_t getSymVA(const SymbolBody &Body, int64_t &Addend) { |
| 59 | 57 | if (!IS) |
| 60 | 58 | return D.Value; |
| 61 | 59 | |
| 60 | IS = IS->Repl; | |
| 62 | 61 | uint64_t Offset = D.Value; |
| 63 | 62 | |
| 64 | 63 | // An object in an SHF_MERGE section might be referenced via a |
| ... | ... | @@ -99,139 +98,79 @@ static uint64_t getSymVA(const SymbolBody &Body, int64_t &Addend) { |
| 99 | 98 | } |
| 100 | 99 | return VA; |
| 101 | 100 | } |
| 102 | case SymbolBody::DefinedCommonKind: | |
| 103 | if (!Config->DefineCommon) | |
| 104 | return 0; | |
| 105 | return InX::Common->getParent()->Addr + InX::Common->OutSecOff + | |
| 106 | cast<DefinedCommon>(Body).Offset; | |
| 107 | case SymbolBody::SharedKind: { | |
| 108 | auto &SS = cast<SharedSymbol>(Body); | |
| 109 | if (SS.NeedsCopy) | |
| 110 | return SS.CopyRelSec->getParent()->Addr + SS.CopyRelSec->OutSecOff + | |
| 111 | SS.CopyRelSecOff; | |
| 101 | case Symbol::SharedKind: { | |
| 102 | auto &SS = cast<SharedSymbol>(Sym); | |
| 103 | if (SS.CopyRelSec) | |
| 104 | return SS.CopyRelSec->getParent()->Addr + SS.CopyRelSec->OutSecOff; | |
| 112 | 105 | if (SS.NeedsPltAddr) |
| 113 | return Body.getPltVA(); | |
| 106 | return Sym.getPltVA(); | |
| 114 | 107 | return 0; |
| 115 | 108 | } |
| 116 | case SymbolBody::UndefinedKind: | |
| 109 | case Symbol::UndefinedKind: | |
| 117 | 110 | return 0; |
| 118 | case SymbolBody::LazyArchiveKind: | |
| 119 | case SymbolBody::LazyObjectKind: | |
| 120 | assert(Body.symbol()->IsUsedInRegularObj && "lazy symbol reached writer"); | |
| 111 | case Symbol::LazyArchiveKind: | |
| 112 | case Symbol::LazyObjectKind: | |
| 113 | assert(Sym.IsUsedInRegularObj && "lazy symbol reached writer"); | |
| 121 | 114 | return 0; |
| 122 | 115 | } |
| 123 | 116 | llvm_unreachable("invalid symbol kind"); |
| 124 | 117 | } |
| 125 | 118 | |
| 126 | SymbolBody::SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther, | |
| 127 | uint8_t Type) | |
| 128 | : SymbolKind(K), NeedsCopy(false), NeedsPltAddr(false), IsLocal(IsLocal), | |
| 129 | IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false), | |
| 130 | IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {} | |
| 131 | ||
| 132 | // Returns true if a symbol can be replaced at load-time by a symbol | |
| 133 | // with the same name defined in other ELF executable or DSO. | |
| 134 | bool SymbolBody::isPreemptible() const { | |
| 135 | if (isLocal()) | |
| 136 | return false; | |
| 137 | ||
| 138 | // Shared symbols resolve to the definition in the DSO. The exceptions are | |
| 139 | // symbols with copy relocations (which resolve to .bss) or preempt plt | |
| 140 | // entries (which resolve to that plt entry). | |
| 141 | if (isShared()) | |
| 142 | return !NeedsCopy && !NeedsPltAddr; | |
| 143 | ||
| 144 | // That's all that can be preempted in a non-DSO. | |
| 145 | if (!Config->Shared) | |
| 146 | return false; | |
| 147 | ||
| 148 | // Only symbols that appear in dynsym can be preempted. | |
| 149 | if (!symbol()->includeInDynsym()) | |
| 150 | return false; | |
| 151 | ||
| 152 | // Only default visibility symbols can be preempted. | |
| 153 | if (symbol()->Visibility != STV_DEFAULT) | |
| 154 | return false; | |
| 155 | ||
| 156 | // -Bsymbolic means that definitions are not preempted. | |
| 157 | if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc())) | |
| 158 | return !isDefined(); | |
| 159 | return true; | |
| 160 | } | |
| 161 | ||
| 162 | // Overwrites all attributes with Other's so that this symbol becomes | |
| 163 | // an alias to Other. This is useful for handling some options such as | |
| 164 | // --wrap. | |
| 165 | void SymbolBody::copy(SymbolBody *Other) { | |
| 166 | memcpy(symbol()->Body.buffer, Other->symbol()->Body.buffer, | |
| 167 | sizeof(Symbol::Body)); | |
| 168 | } | |
| 169 | ||
| 170 | uint64_t SymbolBody::getVA(int64_t Addend) const { | |
| 119 | uint64_t Symbol::getVA(int64_t Addend) const { | |
| 171 | 120 | uint64_t OutVA = getSymVA(*this, Addend); |
| 172 | 121 | return OutVA + Addend; |
| 173 | 122 | } |
| 174 | 123 | |
| 175 | uint64_t SymbolBody::getGotVA() const { | |
| 176 | return InX::Got->getVA() + getGotOffset(); | |
| 177 | } | |
| 124 | uint64_t Symbol::getGotVA() const { return InX::Got->getVA() + getGotOffset(); } | |
| 178 | 125 | |
| 179 | uint64_t SymbolBody::getGotOffset() const { | |
| 126 | uint64_t Symbol::getGotOffset() const { | |
| 180 | 127 | return GotIndex * Target->GotEntrySize; |
| 181 | 128 | } |
| 182 | 129 | |
| 183 | uint64_t SymbolBody::getGotPltVA() const { | |
| 130 | uint64_t Symbol::getGotPltVA() const { | |
| 184 | 131 | if (this->IsInIgot) |
| 185 | 132 | return InX::IgotPlt->getVA() + getGotPltOffset(); |
| 186 | 133 | return InX::GotPlt->getVA() + getGotPltOffset(); |
| 187 | 134 | } |
| 188 | 135 | |
| 189 | uint64_t SymbolBody::getGotPltOffset() const { | |
| 136 | uint64_t Symbol::getGotPltOffset() const { | |
| 190 | 137 | return GotPltIndex * Target->GotPltEntrySize; |
| 191 | 138 | } |
| 192 | 139 | |
| 193 | uint64_t SymbolBody::getPltVA() const { | |
| 140 | uint64_t Symbol::getPltVA() const { | |
| 194 | 141 | if (this->IsInIplt) |
| 195 | 142 | return InX::Iplt->getVA() + PltIndex * Target->PltEntrySize; |
| 196 | 143 | return InX::Plt->getVA() + Target->PltHeaderSize + |
| 197 | 144 | PltIndex * Target->PltEntrySize; |
| 198 | 145 | } |
| 199 | 146 | |
| 200 | template <class ELFT> typename ELFT::uint SymbolBody::getSize() const { | |
| 201 | if (const auto *C = dyn_cast<DefinedCommon>(this)) | |
| 202 | return C->Size; | |
| 203 | if (const auto *DR = dyn_cast<DefinedRegular>(this)) | |
| 147 | uint64_t Symbol::getSize() const { | |
| 148 | if (const auto *DR = dyn_cast<Defined>(this)) | |
| 204 | 149 | return DR->Size; |
| 205 | 150 | if (const auto *S = dyn_cast<SharedSymbol>(this)) |
| 206 | return S->getSize<ELFT>(); | |
| 151 | return S->Size; | |
| 207 | 152 | return 0; |
| 208 | 153 | } |
| 209 | 154 | |
| 210 | OutputSection *SymbolBody::getOutputSection() const { | |
| 211 | if (auto *S = dyn_cast<DefinedRegular>(this)) { | |
| 212 | if (S->Section) | |
| 213 | return S->Section->getOutputSection(); | |
| 155 | OutputSection *Symbol::getOutputSection() const { | |
| 156 | if (auto *S = dyn_cast<Defined>(this)) { | |
| 157 | if (auto *Sec = S->Section) | |
| 158 | return Sec->Repl->getOutputSection(); | |
| 214 | 159 | return nullptr; |
| 215 | 160 | } |
| 216 | 161 | |
| 217 | 162 | if (auto *S = dyn_cast<SharedSymbol>(this)) { |
| 218 | if (S->NeedsCopy) | |
| 163 | if (S->CopyRelSec) | |
| 219 | 164 | return S->CopyRelSec->getParent(); |
| 220 | 165 | return nullptr; |
| 221 | 166 | } |
| 222 | 167 | |
| 223 | if (isa<DefinedCommon>(this)) { | |
| 224 | if (Config->DefineCommon) | |
| 225 | return InX::Common->getParent(); | |
| 226 | return nullptr; | |
| 227 | } | |
| 228 | ||
| 229 | 168 | return nullptr; |
| 230 | 169 | } |
| 231 | 170 | |
| 232 | 171 | // If a symbol name contains '@', the characters after that is |
| 233 | 172 | // a symbol version name. This function parses that. |
| 234 | void SymbolBody::parseSymbolVersion() { | |
| 173 | void Symbol::parseSymbolVersion() { | |
| 235 | 174 | StringRef S = getName(); |
| 236 | 175 | size_t Pos = S.find('@'); |
| 237 | 176 | if (Pos == 0 || Pos == StringRef::npos) |
| ... | ... | @@ -244,7 +183,7 @@ void SymbolBody::parseSymbolVersion() { |
| 244 | 183 | Name = {S.data(), Pos}; |
| 245 | 184 | |
| 246 | 185 | // If this is not in this DSO, it is not a definition. |
| 247 | if (!isInCurrentDSO()) | |
| 186 | if (!isDefined()) | |
| 248 | 187 | return; |
| 249 | 188 | |
| 250 | 189 | // '@@' in a symbol name means the default version. |
| ... | ... | @@ -258,9 +197,9 @@ void SymbolBody::parseSymbolVersion() { |
| 258 | 197 | continue; |
| 259 | 198 | |
| 260 | 199 | if (IsDefault) |
| 261 | symbol()->VersionId = Ver.Id; | |
| 200 | VersionId = Ver.Id; | |
| 262 | 201 | else |
| 263 | symbol()->VersionId = Ver.Id | VERSYM_HIDDEN; | |
| 202 | VersionId = Ver.Id | VERSYM_HIDDEN; | |
| 264 | 203 | return; |
| 265 | 204 | } |
| 266 | 205 | |
| ... | ... | @@ -273,81 +212,34 @@ void SymbolBody::parseSymbolVersion() { |
| 273 | 212 | Verstr); |
| 274 | 213 | } |
| 275 | 214 | |
| 276 | Defined::Defined(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther, | |
| 277 | uint8_t Type) | |
| 278 | : SymbolBody(K, Name, IsLocal, StOther, Type) {} | |
| 279 | ||
| 280 | template <class ELFT> bool DefinedRegular::isMipsPIC() const { | |
| 281 | typedef typename ELFT::Ehdr Elf_Ehdr; | |
| 282 | if (!Section || !isFunc()) | |
| 283 | return false; | |
| 284 | ||
| 285 | auto *Sec = cast<InputSectionBase>(Section); | |
| 286 | const Elf_Ehdr *Hdr = Sec->template getFile<ELFT>()->getObj().getHeader(); | |
| 287 | return (this->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC || | |
| 288 | (Hdr->e_flags & EF_MIPS_PIC); | |
| 289 | } | |
| 290 | ||
| 291 | Undefined::Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther, | |
| 292 | uint8_t Type, InputFile *File) | |
| 293 | : SymbolBody(SymbolBody::UndefinedKind, Name, IsLocal, StOther, Type) { | |
| 294 | this->File = File; | |
| 295 | } | |
| 296 | ||
| 297 | DefinedCommon::DefinedCommon(StringRef Name, uint64_t Size, uint32_t Alignment, | |
| 298 | uint8_t StOther, uint8_t Type, InputFile *File) | |
| 299 | : Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther, | |
| 300 | Type), | |
| 301 | Alignment(Alignment), Size(Size) { | |
| 302 | this->File = File; | |
| 303 | } | |
| 304 | ||
| 305 | // If a shared symbol is referred via a copy relocation, its alignment | |
| 306 | // becomes part of the ABI. This function returns a symbol alignment. | |
| 307 | // Because symbols don't have alignment attributes, we need to infer that. | |
| 308 | template <class ELFT> uint32_t SharedSymbol::getAlignment() const { | |
| 309 | auto *File = cast<SharedFile<ELFT>>(this->File); | |
| 310 | uint32_t SecAlign = File->getSection(getSym<ELFT>())->sh_addralign; | |
| 311 | uint64_t SymValue = getSym<ELFT>().st_value; | |
| 312 | uint32_t SymAlign = uint32_t(1) << countTrailingZeros(SymValue); | |
| 313 | return std::min(SecAlign, SymAlign); | |
| 314 | } | |
| 315 | ||
| 316 | 215 | InputFile *Lazy::fetch() { |
| 317 | 216 | if (auto *S = dyn_cast<LazyArchive>(this)) |
| 318 | 217 | return S->fetch(); |
| 319 | 218 | return cast<LazyObject>(this)->fetch(); |
| 320 | 219 | } |
| 321 | 220 | |
| 322 | LazyArchive::LazyArchive(ArchiveFile &File, | |
| 323 | const llvm::object::Archive::Symbol S, uint8_t Type) | |
| 324 | : Lazy(LazyArchiveKind, S.getName(), Type), Sym(S) { | |
| 325 | this->File = &File; | |
| 326 | } | |
| 327 | ||
| 328 | LazyObject::LazyObject(StringRef Name, LazyObjectFile &File, uint8_t Type) | |
| 329 | : Lazy(LazyObjectKind, Name, Type) { | |
| 330 | this->File = &File; | |
| 331 | } | |
| 221 | ArchiveFile &LazyArchive::getFile() { return *cast<ArchiveFile>(File); } | |
| 332 | 222 | |
| 333 | 223 | InputFile *LazyArchive::fetch() { |
| 334 | std::pair<MemoryBufferRef, uint64_t> MBInfo = file()->getMember(&Sym); | |
| 224 | std::pair<MemoryBufferRef, uint64_t> MBInfo = getFile().getMember(&Sym); | |
| 335 | 225 | |
| 336 | 226 | // getMember returns an empty buffer if the member was already |
| 337 | 227 | // read from the library. |
| 338 | 228 | if (MBInfo.first.getBuffer().empty()) |
| 339 | 229 | return nullptr; |
| 340 | return createObjectFile(MBInfo.first, file()->getName(), MBInfo.second); | |
| 230 | return createObjectFile(MBInfo.first, getFile().getName(), MBInfo.second); | |
| 341 | 231 | } |
| 342 | 232 | |
| 343 | InputFile *LazyObject::fetch() { return file()->fetch(); } | |
| 233 | LazyObjFile &LazyObject::getFile() { return *cast<LazyObjFile>(File); } | |
| 234 | ||
| 235 | InputFile *LazyObject::fetch() { return getFile().fetch(); } | |
| 344 | 236 | |
| 345 | 237 | uint8_t Symbol::computeBinding() const { |
| 346 | 238 | if (Config->Relocatable) |
| 347 | 239 | return Binding; |
| 348 | 240 | if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED) |
| 349 | 241 | return STB_LOCAL; |
| 350 | if (VersionId == VER_NDX_LOCAL && body()->isInCurrentDSO()) | |
| 242 | if (VersionId == VER_NDX_LOCAL && isDefined()) | |
| 351 | 243 | return STB_LOCAL; |
| 352 | 244 | if (Config->NoGnuUnique && Binding == STB_GNU_UNIQUE) |
| 353 | 245 | return STB_GLOBAL; |
| ... | ... | @@ -355,45 +247,36 @@ uint8_t Symbol::computeBinding() const { |
| 355 | 247 | } |
| 356 | 248 | |
| 357 | 249 | bool Symbol::includeInDynsym() const { |
| 250 | if (!Config->HasDynSymTab) | |
| 251 | return false; | |
| 358 | 252 | if (computeBinding() == STB_LOCAL) |
| 359 | 253 | return false; |
| 360 | return ExportDynamic || body()->isShared() || | |
| 361 | (body()->isUndefined() && Config->Shared); | |
| 254 | if (!isDefined()) | |
| 255 | return true; | |
| 256 | return ExportDynamic; | |
| 362 | 257 | } |
| 363 | 258 | |
| 364 | 259 | // Print out a log message for --trace-symbol. |
| 365 | 260 | void elf::printTraceSymbol(Symbol *Sym) { |
| 366 | SymbolBody *B = Sym->body(); | |
| 367 | 261 | std::string S; |
| 368 | if (B->isUndefined()) | |
| 262 | if (Sym->isUndefined()) | |
| 369 | 263 | S = ": reference to "; |
| 370 | else if (B->isCommon()) | |
| 264 | else if (Sym->isLazy()) | |
| 265 | S = ": lazy definition of "; | |
| 266 | else if (Sym->isShared()) | |
| 267 | S = ": shared definition of "; | |
| 268 | else if (dyn_cast_or_null<BssSection>(cast<Defined>(Sym)->Section)) | |
| 371 | 269 | S = ": common definition of "; |
| 372 | 270 | else |
| 373 | 271 | S = ": definition of "; |
| 374 | 272 | |
| 375 | message(toString(B->File) + S + B->getName()); | |
| 273 | message(toString(Sym->File) + S + Sym->getName()); | |
| 376 | 274 | } |
| 377 | 275 | |
| 378 | 276 | // Returns a symbol for an error message. |
| 379 | std::string lld::toString(const SymbolBody &B) { | |
| 277 | std::string lld::toString(const Symbol &B) { | |
| 380 | 278 | if (Config->Demangle) |
| 381 | if (Optional<std::string> S = demangle(B.getName())) | |
| 279 | if (Optional<std::string> S = demangleItanium(B.getName())) | |
| 382 | 280 | return *S; |
| 383 | 281 | return B.getName(); |
| 384 | 282 | } |
| 385 | ||
| 386 | template uint32_t SymbolBody::template getSize<ELF32LE>() const; | |
| 387 | template uint32_t SymbolBody::template getSize<ELF32BE>() const; | |
| 388 | template uint64_t SymbolBody::template getSize<ELF64LE>() const; | |
| 389 | template uint64_t SymbolBody::template getSize<ELF64BE>() const; | |
| 390 | ||
| 391 | template bool DefinedRegular::template isMipsPIC<ELF32LE>() const; | |
| 392 | template bool DefinedRegular::template isMipsPIC<ELF32BE>() const; | |
| 393 | template bool DefinedRegular::template isMipsPIC<ELF64LE>() const; | |
| 394 | template bool DefinedRegular::template isMipsPIC<ELF64BE>() const; | |
| 395 | ||
| 396 | template uint32_t SharedSymbol::template getAlignment<ELF32LE>() const; | |
| 397 | template uint32_t SharedSymbol::template getAlignment<ELF32BE>() const; | |
| 398 | template uint32_t SharedSymbol::template getAlignment<ELF64LE>() const; | |
| 399 | template uint32_t SharedSymbol::template getAlignment<ELF64BE>() const; |
deps/lld/ELF/Symbols.h+184-216| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | #include "InputSection.h" |
| 19 | 19 | #include "Strings.h" |
| 20 | 20 | |
| 21 | #include "lld/Core/LLVM.h" | |
| 21 | #include "lld/Common/LLVM.h" | |
| 22 | 22 | #include "llvm/Object/Archive.h" |
| 23 | 23 | #include "llvm/Object/ELF.h" |
| 24 | 24 | |
| ... | ... | @@ -27,53 +27,89 @@ namespace elf { |
| 27 | 27 | |
| 28 | 28 | class ArchiveFile; |
| 29 | 29 | class BitcodeFile; |
| 30 | class BssSection; | |
| 30 | 31 | class InputFile; |
| 31 | class LazyObjectFile; | |
| 32 | template <class ELFT> class ObjectFile; | |
| 32 | class LazyObjFile; | |
| 33 | template <class ELFT> class ObjFile; | |
| 33 | 34 | class OutputSection; |
| 34 | 35 | template <class ELFT> class SharedFile; |
| 35 | 36 | |
| 36 | struct Symbol; | |
| 37 | ||
| 38 | 37 | // The base class for real symbol classes. |
| 39 | class SymbolBody { | |
| 38 | class Symbol { | |
| 40 | 39 | public: |
| 41 | 40 | enum Kind { |
| 42 | DefinedFirst, | |
| 43 | DefinedRegularKind = DefinedFirst, | |
| 41 | DefinedKind, | |
| 44 | 42 | SharedKind, |
| 45 | DefinedCommonKind, | |
| 46 | DefinedLast = DefinedCommonKind, | |
| 47 | 43 | UndefinedKind, |
| 48 | 44 | LazyArchiveKind, |
| 49 | 45 | LazyObjectKind, |
| 50 | 46 | }; |
| 51 | 47 | |
| 52 | SymbolBody(Kind K) : SymbolKind(K) {} | |
| 48 | Kind kind() const { return static_cast<Kind>(SymbolKind); } | |
| 53 | 49 | |
| 54 | Symbol *symbol(); | |
| 55 | const Symbol *symbol() const { | |
| 56 | return const_cast<SymbolBody *>(this)->symbol(); | |
| 57 | } | |
| 50 | // Symbol binding. This is not overwritten by replaceSymbol to track | |
| 51 | // changes during resolution. In particular: | |
| 52 | // - An undefined weak is still weak when it resolves to a shared library. | |
| 53 | // - An undefined weak will not fetch archive members, but we have to | |
| 54 | // remember it is weak. | |
| 55 | uint8_t Binding; | |
| 58 | 56 | |
| 59 | Kind kind() const { return static_cast<Kind>(SymbolKind); } | |
| 57 | // Version definition index. | |
| 58 | uint16_t VersionId; | |
| 59 | ||
| 60 | // Symbol visibility. This is the computed minimum visibility of all | |
| 61 | // observed non-DSO symbols. | |
| 62 | unsigned Visibility : 2; | |
| 63 | ||
| 64 | // True if the symbol was used for linking and thus need to be added to the | |
| 65 | // output file's symbol table. This is true for all symbols except for | |
| 66 | // unreferenced DSO symbols and bitcode symbols that are unreferenced except | |
| 67 | // by other bitcode objects. | |
| 68 | unsigned IsUsedInRegularObj : 1; | |
| 69 | ||
| 70 | // If this flag is true and the symbol has protected or default visibility, it | |
| 71 | // will appear in .dynsym. This flag is set by interposable DSO symbols in | |
| 72 | // executables, by most symbols in DSOs and executables built with | |
| 73 | // --export-dynamic, and by dynamic lists. | |
| 74 | unsigned ExportDynamic : 1; | |
| 75 | ||
| 76 | // False if LTO shouldn't inline whatever this symbol points to. If a symbol | |
| 77 | // is overwritten after LTO, LTO shouldn't inline the symbol because it | |
| 78 | // doesn't know the final contents of the symbol. | |
| 79 | unsigned CanInline : 1; | |
| 80 | ||
| 81 | // True if this symbol is specified by --trace-symbol option. | |
| 82 | unsigned Traced : 1; | |
| 83 | ||
| 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; | |
| 91 | uint8_t computeBinding() const; | |
| 92 | bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; } | |
| 60 | 93 | |
| 61 | 94 | bool isUndefined() const { return SymbolKind == UndefinedKind; } |
| 62 | bool isDefined() const { return SymbolKind <= DefinedLast; } | |
| 63 | bool isCommon() const { return SymbolKind == DefinedCommonKind; } | |
| 95 | bool isDefined() const { return SymbolKind == DefinedKind; } | |
| 96 | bool isShared() const { return SymbolKind == SharedKind; } | |
| 97 | bool isLocal() const { return Binding == llvm::ELF::STB_LOCAL; } | |
| 98 | ||
| 64 | 99 | bool isLazy() const { |
| 65 | 100 | return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind; |
| 66 | 101 | } |
| 67 | bool isShared() const { return SymbolKind == SharedKind; } | |
| 68 | bool isInCurrentDSO() const { | |
| 69 | return !isUndefined() && !isShared() && !isLazy(); | |
| 102 | ||
| 103 | // True is this is an undefined weak symbol. This only works once | |
| 104 | // all input files have been added. | |
| 105 | bool isUndefWeak() const { | |
| 106 | // See comment on Lazy the details. | |
| 107 | return isWeak() && (isUndefined() || isLazy()); | |
| 70 | 108 | } |
| 71 | bool isLocal() const { return IsLocal; } | |
| 72 | bool isPreemptible() const; | |
| 109 | ||
| 73 | 110 | StringRef getName() const { return Name; } |
| 74 | 111 | uint8_t getVisibility() const { return StOther & 0x3; } |
| 75 | 112 | void parseSymbolVersion(); |
| 76 | void copy(SymbolBody *Other); | |
| 77 | 113 | |
| 78 | 114 | bool isInGot() const { return GotIndex != -1U; } |
| 79 | 115 | bool isInPlt() const { return PltIndex != -1U; } |
| ... | ... | @@ -85,12 +121,9 @@ public: |
| 85 | 121 | uint64_t getGotPltOffset() const; |
| 86 | 122 | uint64_t getGotPltVA() const; |
| 87 | 123 | uint64_t getPltVA() const; |
| 88 | template <class ELFT> typename ELFT::uint getSize() const; | |
| 124 | uint64_t getSize() const; | |
| 89 | 125 | OutputSection *getOutputSection() const; |
| 90 | 126 | |
| 91 | // The file from which this symbol was created. | |
| 92 | InputFile *File = nullptr; | |
| 93 | ||
| 94 | 127 | uint32_t DynsymIndex = 0; |
| 95 | 128 | uint32_t GotIndex = -1; |
| 96 | 129 | uint32_t GotPltIndex = -1; |
| ... | ... | @@ -98,23 +131,19 @@ public: |
| 98 | 131 | uint32_t GlobalDynIndex = -1; |
| 99 | 132 | |
| 100 | 133 | protected: |
| 101 | SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther, | |
| 102 | uint8_t Type); | |
| 134 | Symbol(Kind K, InputFile *File, StringRefZ Name, uint8_t Binding, | |
| 135 | uint8_t StOther, uint8_t Type) | |
| 136 | : Binding(Binding), File(File), SymbolKind(K), NeedsPltAddr(false), | |
| 137 | IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false), | |
| 138 | IsInIgot(false), IsPreemptible(false), Used(!Config->GcSections), | |
| 139 | Type(Type), StOther(StOther), Name(Name) {} | |
| 103 | 140 | |
| 104 | 141 | const unsigned SymbolKind : 8; |
| 105 | 142 | |
| 106 | 143 | public: |
| 107 | // True if the linker has to generate a copy relocation. | |
| 108 | // For SharedSymbol only. | |
| 109 | unsigned NeedsCopy : 1; | |
| 110 | ||
| 111 | 144 | // True the symbol should point to its PLT entry. |
| 112 | 145 | // For SharedSymbol only. |
| 113 | 146 | unsigned NeedsPltAddr : 1; |
| 114 | ||
| 115 | // True if this is a local symbol. | |
| 116 | unsigned IsLocal : 1; | |
| 117 | ||
| 118 | 147 | // True if this symbol has an entry in the global part of MIPS GOT. |
| 119 | 148 | unsigned IsInGlobalMipsGot : 1; |
| 120 | 149 | |
| ... | ... | @@ -127,6 +156,11 @@ public: |
| 127 | 156 | // True if this symbol is in the Igot sub-section of the .got.plt or .got. |
| 128 | 157 | unsigned IsInIgot : 1; |
| 129 | 158 | |
| 159 | unsigned IsPreemptible : 1; | |
| 160 | ||
| 161 | // True if an undefined or shared symbol is used from a live section. | |
| 162 | unsigned Used : 1; | |
| 163 | ||
| 130 | 164 | // The following fields have the same meaning as the ELF symbol attributes. |
| 131 | 165 | uint8_t Type; // symbol type |
| 132 | 166 | uint8_t StOther; // st_other field value |
| ... | ... | @@ -149,139 +183,111 @@ protected: |
| 149 | 183 | StringRefZ Name; |
| 150 | 184 | }; |
| 151 | 185 | |
| 152 | // The base class for any defined symbols. | |
| 153 | class Defined : public SymbolBody { | |
| 154 | public: | |
| 155 | Defined(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type); | |
| 156 | static bool classof(const SymbolBody *S) { return S->isDefined(); } | |
| 157 | }; | |
| 158 | ||
| 159 | class DefinedCommon : public Defined { | |
| 186 | // Represents a symbol that is defined in the current output file. | |
| 187 | class Defined : public Symbol { | |
| 160 | 188 | public: |
| 161 | DefinedCommon(StringRef N, uint64_t Size, uint32_t Alignment, uint8_t StOther, | |
| 162 | uint8_t Type, InputFile *File); | |
| 163 | ||
| 164 | static bool classof(const SymbolBody *S) { | |
| 165 | return S->kind() == SymbolBody::DefinedCommonKind; | |
| 166 | } | |
| 189 | Defined(InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther, | |
| 190 | uint8_t Type, uint64_t Value, uint64_t Size, SectionBase *Section) | |
| 191 | : Symbol(DefinedKind, File, Name, Binding, StOther, Type), Value(Value), | |
| 192 | Size(Size), Section(Section) {} | |
| 167 | 193 | |
| 168 | // The output offset of this common symbol in the output bss. Computed by the | |
| 169 | // writer. | |
| 170 | uint64_t Offset; | |
| 171 | ||
| 172 | // The maximum alignment we have seen for this symbol. | |
| 173 | uint32_t Alignment; | |
| 174 | ||
| 175 | uint64_t Size; | |
| 176 | }; | |
| 177 | ||
| 178 | // Regular defined symbols read from object file symbol tables. | |
| 179 | class DefinedRegular : public Defined { | |
| 180 | public: | |
| 181 | DefinedRegular(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type, | |
| 182 | uint64_t Value, uint64_t Size, SectionBase *Section, | |
| 183 | InputFile *File) | |
| 184 | : Defined(SymbolBody::DefinedRegularKind, Name, IsLocal, StOther, Type), | |
| 185 | Value(Value), Size(Size), Section(Section) { | |
| 186 | this->File = File; | |
| 187 | } | |
| 188 | ||
| 189 | // Return true if the symbol is a PIC function. | |
| 190 | template <class ELFT> bool isMipsPIC() const; | |
| 191 | ||
| 192 | static bool classof(const SymbolBody *S) { | |
| 193 | return S->kind() == SymbolBody::DefinedRegularKind; | |
| 194 | } | |
| 194 | static bool classof(const Symbol *S) { return S->isDefined(); } | |
| 195 | 195 | |
| 196 | 196 | uint64_t Value; |
| 197 | 197 | uint64_t Size; |
| 198 | 198 | SectionBase *Section; |
| 199 | 199 | }; |
| 200 | 200 | |
| 201 | class Undefined : public SymbolBody { | |
| 201 | class Undefined : public Symbol { | |
| 202 | 202 | public: |
| 203 | Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type, | |
| 204 | InputFile *F); | |
| 203 | Undefined(InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther, | |
| 204 | uint8_t Type) | |
| 205 | : Symbol(UndefinedKind, File, Name, Binding, StOther, Type) {} | |
| 205 | 206 | |
| 206 | static bool classof(const SymbolBody *S) { | |
| 207 | return S->kind() == UndefinedKind; | |
| 208 | } | |
| 207 | static bool classof(const Symbol *S) { return S->kind() == UndefinedKind; } | |
| 209 | 208 | }; |
| 210 | 209 | |
| 211 | class SharedSymbol : public Defined { | |
| 210 | class SharedSymbol : public Symbol { | |
| 212 | 211 | public: |
| 213 | static bool classof(const SymbolBody *S) { | |
| 214 | return S->kind() == SymbolBody::SharedKind; | |
| 215 | } | |
| 216 | ||
| 217 | SharedSymbol(InputFile *File, StringRef Name, uint8_t StOther, uint8_t Type, | |
| 218 | const void *ElfSym, const void *Verdef) | |
| 219 | : Defined(SymbolBody::SharedKind, Name, /*IsLocal=*/false, StOther, Type), | |
| 220 | Verdef(Verdef), ElfSym(ElfSym) { | |
| 221 | // IFuncs defined in DSOs are treated as functions by the static linker. | |
| 222 | if (isGnuIFunc()) | |
| 212 | static bool classof(const Symbol *S) { return S->kind() == SharedKind; } | |
| 213 | ||
| 214 | SharedSymbol(InputFile &File, StringRef Name, uint8_t Binding, | |
| 215 | uint8_t StOther, uint8_t Type, uint64_t Value, uint64_t Size, | |
| 216 | uint32_t Alignment, uint32_t VerdefIndex) | |
| 217 | : Symbol(SharedKind, &File, Name, Binding, StOther, Type), Value(Value), | |
| 218 | Size(Size), VerdefIndex(VerdefIndex), Alignment(Alignment) { | |
| 219 | // GNU ifunc is a mechanism to allow user-supplied functions to | |
| 220 | // resolve PLT slot values at load-time. This is contrary to the | |
| 221 | // regular symbol resolution scheme in which symbols are resolved just | |
| 222 | // by name. Using this hook, you can program how symbols are solved | |
| 223 | // for you program. For example, you can make "memcpy" to be resolved | |
| 224 | // to a SSE-enabled version of memcpy only when a machine running the | |
| 225 | // program supports the SSE instruction set. | |
| 226 | // | |
| 227 | // Naturally, such symbols should always be called through their PLT | |
| 228 | // slots. What GNU ifunc symbols point to are resolver functions, and | |
| 229 | // calling them directly doesn't make sense (unless you are writing a | |
| 230 | // loader). | |
| 231 | // | |
| 232 | // For DSO symbols, we always call them through PLT slots anyway. | |
| 233 | // So there's no difference between GNU ifunc and regular function | |
| 234 | // symbols if they are in DSOs. So we can handle GNU_IFUNC as FUNC. | |
| 235 | if (this->Type == llvm::ELF::STT_GNU_IFUNC) | |
| 223 | 236 | this->Type = llvm::ELF::STT_FUNC; |
| 224 | this->File = File; | |
| 225 | 237 | } |
| 226 | 238 | |
| 227 | template <class ELFT> uint64_t getShndx() const { | |
| 228 | return getSym<ELFT>().st_shndx; | |
| 239 | template <class ELFT> SharedFile<ELFT> &getFile() const { | |
| 240 | return *cast<SharedFile<ELFT>>(File); | |
| 229 | 241 | } |
| 230 | 242 | |
| 231 | template <class ELFT> uint64_t getValue() const { | |
| 232 | return getSym<ELFT>().st_value; | |
| 233 | } | |
| 243 | // If not null, there is a copy relocation to this section. | |
| 244 | InputSection *CopyRelSec = nullptr; | |
| 234 | 245 | |
| 235 | template <class ELFT> uint64_t getSize() const { | |
| 236 | return getSym<ELFT>().st_size; | |
| 237 | } | |
| 238 | ||
| 239 | template <class ELFT> uint32_t getAlignment() const; | |
| 246 | uint64_t Value; // st_value | |
| 247 | uint64_t Size; // st_size | |
| 240 | 248 | |
| 241 | // This field is a pointer to the symbol's version definition. | |
| 242 | const void *Verdef; | |
| 249 | // This field is a index to the symbol's version definition. | |
| 250 | uint32_t VerdefIndex; | |
| 243 | 251 | |
| 244 | // CopyRelSec and CopyRelSecOff are significant only when NeedsCopy is true. | |
| 245 | InputSection *CopyRelSec; | |
| 246 | uint64_t CopyRelSecOff; | |
| 247 | ||
| 248 | private: | |
| 249 | template <class ELFT> const typename ELFT::Sym &getSym() const { | |
| 250 | return *(const typename ELFT::Sym *)ElfSym; | |
| 251 | } | |
| 252 | ||
| 253 | const void *ElfSym; | |
| 252 | uint32_t Alignment; | |
| 254 | 253 | }; |
| 255 | 254 | |
| 256 | // This class represents a symbol defined in an archive file. It is | |
| 257 | // created from an archive file header, and it knows how to load an | |
| 258 | // object file from an archive to replace itself with a defined | |
| 259 | // symbol. If the resolver finds both Undefined and Lazy for | |
| 260 | // the same name, it will ask the Lazy to load a file. | |
| 261 | class Lazy : public SymbolBody { | |
| 255 | // This represents a symbol that is not yet in the link, but we know where to | |
| 256 | // find it if needed. If the resolver finds both Undefined and Lazy for the same | |
| 257 | // name, it will ask the Lazy to load a file. | |
| 258 | // | |
| 259 | // 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 | |
| 261 | // 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 | |
| 263 | // symbols into consideration. | |
| 264 | class Lazy : public Symbol { | |
| 262 | 265 | public: |
| 263 | static bool classof(const SymbolBody *S) { return S->isLazy(); } | |
| 266 | static bool classof(const Symbol *S) { return S->isLazy(); } | |
| 264 | 267 | |
| 265 | 268 | // Returns an object file for this symbol, or a nullptr if the file |
| 266 | 269 | // was already returned. |
| 267 | 270 | InputFile *fetch(); |
| 268 | 271 | |
| 269 | 272 | protected: |
| 270 | Lazy(SymbolBody::Kind K, StringRef Name, uint8_t Type) | |
| 271 | : SymbolBody(K, Name, /*IsLocal=*/false, llvm::ELF::STV_DEFAULT, Type) {} | |
| 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) {} | |
| 272 | 276 | }; |
| 273 | 277 | |
| 274 | // LazyArchive symbols represents symbols in archive files. | |
| 278 | // 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 | |
| 280 | // object file from an archive to replace itself with a defined | |
| 281 | // symbol. | |
| 275 | 282 | class LazyArchive : public Lazy { |
| 276 | 283 | public: |
| 277 | LazyArchive(ArchiveFile &File, const llvm::object::Archive::Symbol S, | |
| 278 | uint8_t Type); | |
| 284 | LazyArchive(InputFile &File, const llvm::object::Archive::Symbol S, | |
| 285 | uint8_t Type) | |
| 286 | : Lazy(LazyArchiveKind, File, S.getName(), Type), Sym(S) {} | |
| 279 | 287 | |
| 280 | static bool classof(const SymbolBody *S) { | |
| 281 | return S->kind() == LazyArchiveKind; | |
| 282 | } | |
| 288 | static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; } | |
| 283 | 289 | |
| 284 | ArchiveFile *file() { return (ArchiveFile *)this->File; } | |
| 290 | ArchiveFile &getFile(); | |
| 285 | 291 | InputFile *fetch(); |
| 286 | 292 | |
| 287 | 293 | private: |
| ... | ... | @@ -292,123 +298,85 @@ private: |
| 292 | 298 | // --start-lib and --end-lib options. |
| 293 | 299 | class LazyObject : public Lazy { |
| 294 | 300 | public: |
| 295 | LazyObject(StringRef Name, LazyObjectFile &File, uint8_t Type); | |
| 301 | LazyObject(InputFile &File, StringRef Name, uint8_t Type) | |
| 302 | : Lazy(LazyObjectKind, File, Name, Type) {} | |
| 296 | 303 | |
| 297 | static bool classof(const SymbolBody *S) { | |
| 298 | return S->kind() == LazyObjectKind; | |
| 299 | } | |
| 304 | static bool classof(const Symbol *S) { return S->kind() == LazyObjectKind; } | |
| 300 | 305 | |
| 301 | LazyObjectFile *file() { return (LazyObjectFile *)this->File; } | |
| 306 | LazyObjFile &getFile(); | |
| 302 | 307 | InputFile *fetch(); |
| 303 | 308 | }; |
| 304 | 309 | |
| 305 | 310 | // Some linker-generated symbols need to be created as |
| 306 | // DefinedRegular symbols. | |
| 311 | // Defined symbols. | |
| 307 | 312 | struct ElfSym { |
| 308 | 313 | // __bss_start |
| 309 | static DefinedRegular *Bss; | |
| 314 | static Defined *Bss; | |
| 310 | 315 | |
| 311 | 316 | // etext and _etext |
| 312 | static DefinedRegular *Etext1; | |
| 313 | static DefinedRegular *Etext2; | |
| 317 | static Defined *Etext1; | |
| 318 | static Defined *Etext2; | |
| 314 | 319 | |
| 315 | 320 | // edata and _edata |
| 316 | static DefinedRegular *Edata1; | |
| 317 | static DefinedRegular *Edata2; | |
| 321 | static Defined *Edata1; | |
| 322 | static Defined *Edata2; | |
| 318 | 323 | |
| 319 | 324 | // end and _end |
| 320 | static DefinedRegular *End1; | |
| 321 | static DefinedRegular *End2; | |
| 325 | static Defined *End1; | |
| 326 | static Defined *End2; | |
| 322 | 327 | |
| 323 | 328 | // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to |
| 324 | 329 | // be at some offset from the base of the .got section, usually 0 or |
| 325 | 330 | // the end of the .got. |
| 326 | static DefinedRegular *GlobalOffsetTable; | |
| 331 | static Defined *GlobalOffsetTable; | |
| 327 | 332 | |
| 328 | 333 | // _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS. |
| 329 | static DefinedRegular *MipsGp; | |
| 330 | static DefinedRegular *MipsGpDisp; | |
| 331 | static DefinedRegular *MipsLocalGp; | |
| 334 | static Defined *MipsGp; | |
| 335 | static Defined *MipsGpDisp; | |
| 336 | static Defined *MipsLocalGp; | |
| 332 | 337 | }; |
| 333 | 338 | |
| 334 | // A real symbol object, SymbolBody, is usually stored within a Symbol. There's | |
| 335 | // always one Symbol for each symbol name. The resolver updates the SymbolBody | |
| 336 | // stored in the Body field of this object as it resolves symbols. Symbol also | |
| 337 | // holds computed properties of symbol names. | |
| 338 | struct Symbol { | |
| 339 | // Symbol binding. This is on the Symbol to track changes during resolution. | |
| 340 | // In particular: | |
| 341 | // An undefined weak is still weak when it resolves to a shared library. | |
| 342 | // An undefined weak will not fetch archive members, but we have to remember | |
| 343 | // it is weak. | |
| 344 | uint8_t Binding; | |
| 345 | ||
| 346 | // Version definition index. | |
| 347 | uint16_t VersionId; | |
| 348 | ||
| 349 | // Symbol visibility. This is the computed minimum visibility of all | |
| 350 | // observed non-DSO symbols. | |
| 351 | unsigned Visibility : 2; | |
| 352 | ||
| 353 | // True if the symbol was used for linking and thus need to be added to the | |
| 354 | // output file's symbol table. This is true for all symbols except for | |
| 355 | // unreferenced DSO symbols and bitcode symbols that are unreferenced except | |
| 356 | // by other bitcode objects. | |
| 357 | unsigned IsUsedInRegularObj : 1; | |
| 358 | ||
| 359 | // If this flag is true and the symbol has protected or default visibility, it | |
| 360 | // will appear in .dynsym. This flag is set by interposable DSO symbols in | |
| 361 | // executables, by most symbols in DSOs and executables built with | |
| 362 | // --export-dynamic, and by dynamic lists. | |
| 363 | unsigned ExportDynamic : 1; | |
| 364 | ||
| 365 | // True if this symbol is specified by --trace-symbol option. | |
| 366 | unsigned Traced : 1; | |
| 367 | ||
| 368 | // This symbol version was found in a version script. | |
| 369 | unsigned InVersionScript : 1; | |
| 370 | ||
| 371 | bool includeInDynsym() const; | |
| 372 | uint8_t computeBinding() const; | |
| 373 | bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; } | |
| 374 | ||
| 375 | // This field is used to store the Symbol's SymbolBody. This instantiation of | |
| 376 | // AlignedCharArrayUnion gives us a struct with a char array field that is | |
| 377 | // large and aligned enough to store any derived class of SymbolBody. | |
| 378 | llvm::AlignedCharArrayUnion<DefinedCommon, DefinedRegular, Undefined, | |
| 379 | SharedSymbol, LazyArchive, LazyObject> | |
| 380 | Body; | |
| 381 | ||
| 382 | SymbolBody *body() { return reinterpret_cast<SymbolBody *>(Body.buffer); } | |
| 383 | const SymbolBody *body() const { return const_cast<Symbol *>(this)->body(); } | |
| 339 | // A buffer class that is large enough to hold any Symbol-derived | |
| 340 | // object. We allocate memory using this class and instantiate a symbol | |
| 341 | // using the placement new. | |
| 342 | union SymbolUnion { | |
| 343 | alignas(Defined) char A[sizeof(Defined)]; | |
| 344 | alignas(Undefined) char C[sizeof(Undefined)]; | |
| 345 | alignas(SharedSymbol) char D[sizeof(SharedSymbol)]; | |
| 346 | alignas(LazyArchive) char E[sizeof(LazyArchive)]; | |
| 347 | alignas(LazyObject) char F[sizeof(LazyObject)]; | |
| 384 | 348 | }; |
| 385 | 349 | |
| 386 | 350 | void printTraceSymbol(Symbol *Sym); |
| 387 | 351 | |
| 388 | 352 | template <typename T, typename... ArgT> |
| 389 | void replaceBody(Symbol *S, ArgT &&... Arg) { | |
| 390 | static_assert(sizeof(T) <= sizeof(S->Body), "Body too small"); | |
| 391 | static_assert(alignof(T) <= alignof(decltype(S->Body)), | |
| 392 | "Body not aligned enough"); | |
| 393 | assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr && | |
| 394 | "Not a SymbolBody"); | |
| 353 | void replaceSymbol(Symbol *S, ArgT &&... Arg) { | |
| 354 | static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small"); | |
| 355 | static_assert(alignof(T) <= alignof(SymbolUnion), | |
| 356 | "SymbolUnion not aligned enough"); | |
| 357 | assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr && | |
| 358 | "Not a Symbol"); | |
| 359 | ||
| 360 | Symbol Sym = *S; | |
| 395 | 361 | |
| 396 | new (S->Body.buffer) T(std::forward<ArgT>(Arg)...); | |
| 362 | new (S) T(std::forward<ArgT>(Arg)...); | |
| 363 | ||
| 364 | S->VersionId = Sym.VersionId; | |
| 365 | S->Visibility = Sym.Visibility; | |
| 366 | S->IsUsedInRegularObj = Sym.IsUsedInRegularObj; | |
| 367 | S->ExportDynamic = Sym.ExportDynamic; | |
| 368 | S->CanInline = Sym.CanInline; | |
| 369 | S->Traced = Sym.Traced; | |
| 370 | S->InVersionScript = Sym.InVersionScript; | |
| 397 | 371 | |
| 398 | 372 | // Print out a log message if --trace-symbol was specified. |
| 399 | 373 | // This is for debugging. |
| 400 | 374 | if (S->Traced) |
| 401 | 375 | printTraceSymbol(S); |
| 402 | 376 | } |
| 403 | ||
| 404 | inline Symbol *SymbolBody::symbol() { | |
| 405 | assert(!isLocal()); | |
| 406 | return reinterpret_cast<Symbol *>(reinterpret_cast<char *>(this) - | |
| 407 | offsetof(Symbol, Body)); | |
| 408 | } | |
| 409 | 377 | } // namespace elf |
| 410 | 378 | |
| 411 | std::string toString(const elf::SymbolBody &B); | |
| 379 | std::string toString(const elf::Symbol &B); | |
| 412 | 380 | } // namespace lld |
| 413 | 381 | |
| 414 | 382 | #endif |
deps/lld/ELF/SyntheticSections.cpp+967-705| ... | ... | @@ -15,28 +15,32 @@ |
| 15 | 15 | //===----------------------------------------------------------------------===// |
| 16 | 16 | |
| 17 | 17 | #include "SyntheticSections.h" |
| 18 | #include "Bits.h" | |
| 18 | 19 | #include "Config.h" |
| 19 | #include "Error.h" | |
| 20 | 20 | #include "InputFiles.h" |
| 21 | 21 | #include "LinkerScript.h" |
| 22 | #include "Memory.h" | |
| 23 | 22 | #include "OutputSections.h" |
| 24 | 23 | #include "Strings.h" |
| 25 | 24 | #include "SymbolTable.h" |
| 25 | #include "Symbols.h" | |
| 26 | 26 | #include "Target.h" |
| 27 | #include "Threads.h" | |
| 28 | 27 | #include "Writer.h" |
| 29 | #include "lld/Config/Version.h" | |
| 28 | #include "lld/Common/ErrorHandler.h" | |
| 29 | #include "lld/Common/Memory.h" | |
| 30 | #include "lld/Common/Threads.h" | |
| 31 | #include "lld/Common/Version.h" | |
| 30 | 32 | #include "llvm/BinaryFormat/Dwarf.h" |
| 31 | 33 | #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h" |
| 32 | 34 | #include "llvm/Object/Decompressor.h" |
| 33 | 35 | #include "llvm/Object/ELFObjectFile.h" |
| 34 | 36 | #include "llvm/Support/Endian.h" |
| 37 | #include "llvm/Support/LEB128.h" | |
| 35 | 38 | #include "llvm/Support/MD5.h" |
| 36 | 39 | #include "llvm/Support/RandomNumberGenerator.h" |
| 37 | 40 | #include "llvm/Support/SHA1.h" |
| 38 | 41 | #include "llvm/Support/xxhash.h" |
| 39 | 42 | #include <cstdlib> |
| 43 | #include <thread> | |
| 40 | 44 | |
| 41 | 45 | using namespace llvm; |
| 42 | 46 | using namespace llvm::dwarf; |
| ... | ... | @@ -48,41 +52,18 @@ using namespace llvm::support::endian; |
| 48 | 52 | using namespace lld; |
| 49 | 53 | using namespace lld::elf; |
| 50 | 54 | |
| 55 | constexpr size_t MergeNoTailSection::NumShards; | |
| 56 | ||
| 57 | static void write32(void *Buf, uint32_t Val) { | |
| 58 | endian::write32(Buf, Val, Config->Endianness); | |
| 59 | } | |
| 60 | ||
| 51 | 61 | uint64_t SyntheticSection::getVA() const { |
| 52 | 62 | if (OutputSection *Sec = getParent()) |
| 53 | 63 | return Sec->Addr + OutSecOff; |
| 54 | 64 | return 0; |
| 55 | 65 | } |
| 56 | 66 | |
| 57 | template <class ELFT> static std::vector<DefinedCommon *> getCommonSymbols() { | |
| 58 | std::vector<DefinedCommon *> V; | |
| 59 | for (Symbol *S : Symtab<ELFT>::X->getSymbols()) | |
| 60 | if (auto *B = dyn_cast<DefinedCommon>(S->body())) | |
| 61 | V.push_back(B); | |
| 62 | return V; | |
| 63 | } | |
| 64 | ||
| 65 | // Find all common symbols and allocate space for them. | |
| 66 | template <class ELFT> InputSection *elf::createCommonSection() { | |
| 67 | if (!Config->DefineCommon) | |
| 68 | return nullptr; | |
| 69 | ||
| 70 | // Sort the common symbols by alignment as an heuristic to pack them better. | |
| 71 | std::vector<DefinedCommon *> Syms = getCommonSymbols<ELFT>(); | |
| 72 | if (Syms.empty()) | |
| 73 | return nullptr; | |
| 74 | ||
| 75 | std::stable_sort(Syms.begin(), Syms.end(), | |
| 76 | [](const DefinedCommon *A, const DefinedCommon *B) { | |
| 77 | return A->Alignment > B->Alignment; | |
| 78 | }); | |
| 79 | ||
| 80 | BssSection *Sec = make<BssSection>("COMMON"); | |
| 81 | for (DefinedCommon *Sym : Syms) | |
| 82 | Sym->Offset = Sec->reserveSpace(Sym->Size, Sym->Alignment); | |
| 83 | return Sec; | |
| 84 | } | |
| 85 | ||
| 86 | 67 | // Returns an LLD version string. |
| 87 | 68 | static ArrayRef<uint8_t> getVersion() { |
| 88 | 69 | // Check LLD_VERSION first for ease of testing. |
| ... | ... | @@ -100,18 +81,9 @@ static ArrayRef<uint8_t> getVersion() { |
| 100 | 81 | // With this feature, you can identify LLD-generated binaries easily |
| 101 | 82 | // by "readelf --string-dump .comment <file>". |
| 102 | 83 | // The returned object is a mergeable string section. |
| 103 | template <class ELFT> MergeInputSection *elf::createCommentSection() { | |
| 104 | typename ELFT::Shdr Hdr = {}; | |
| 105 | Hdr.sh_flags = SHF_MERGE | SHF_STRINGS; | |
| 106 | Hdr.sh_type = SHT_PROGBITS; | |
| 107 | Hdr.sh_entsize = 1; | |
| 108 | Hdr.sh_addralign = 1; | |
| 109 | ||
| 110 | auto *Ret = | |
| 111 | make<MergeInputSection>((ObjectFile<ELFT> *)nullptr, &Hdr, ".comment"); | |
| 112 | Ret->Data = getVersion(); | |
| 113 | Ret->splitIntoPieces(); | |
| 114 | return Ret; | |
| 84 | MergeInputSection *elf::createCommentSection() { | |
| 85 | return make<MergeInputSection>(SHF_MERGE | SHF_STRINGS, SHT_PROGBITS, 1, | |
| 86 | getVersion(), ".comment"); | |
| 115 | 87 | } |
| 116 | 88 | |
| 117 | 89 | // .MIPS.abiflags section. |
| ... | ... | @@ -137,7 +109,7 @@ MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() { |
| 137 | 109 | Sec->Live = false; |
| 138 | 110 | Create = true; |
| 139 | 111 | |
| 140 | std::string Filename = toString(Sec->getFile<ELFT>()); | |
| 112 | std::string Filename = toString(Sec->File); | |
| 141 | 113 | const size_t Size = Sec->Data.size(); |
| 142 | 114 | // Older version of BFD (such as the default FreeBSD linker) concatenate |
| 143 | 115 | // .MIPS.abiflags instead of merging. To allow for this case (or potential |
| ... | ... | @@ -154,7 +126,7 @@ MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() { |
| 154 | 126 | return nullptr; |
| 155 | 127 | } |
| 156 | 128 | |
| 157 | // LLD checks ISA compatibility in getMipsEFlags(). Here we just | |
| 129 | // LLD checks ISA compatibility in calcMipsEFlags(). Here we just | |
| 158 | 130 | // select the highest number of ISA/Rev/Ext. |
| 159 | 131 | Flags.isa_level = std::max(Flags.isa_level, S->isa_level); |
| 160 | 132 | Flags.isa_rev = std::max(Flags.isa_rev, S->isa_rev); |
| ... | ... | @@ -197,16 +169,19 @@ MipsOptionsSection<ELFT> *MipsOptionsSection<ELFT>::create() { |
| 197 | 169 | if (!ELFT::Is64Bits) |
| 198 | 170 | return nullptr; |
| 199 | 171 | |
| 200 | Elf_Mips_RegInfo Reginfo = {}; | |
| 201 | bool Create = false; | |
| 172 | std::vector<InputSectionBase *> Sections; | |
| 173 | for (InputSectionBase *Sec : InputSections) | |
| 174 | if (Sec->Type == SHT_MIPS_OPTIONS) | |
| 175 | Sections.push_back(Sec); | |
| 202 | 176 | |
| 203 | for (InputSectionBase *Sec : InputSections) { | |
| 204 | if (Sec->Type != SHT_MIPS_OPTIONS) | |
| 205 | continue; | |
| 177 | if (Sections.empty()) | |
| 178 | return nullptr; | |
| 179 | ||
| 180 | Elf_Mips_RegInfo Reginfo = {}; | |
| 181 | for (InputSectionBase *Sec : Sections) { | |
| 206 | 182 | Sec->Live = false; |
| 207 | Create = true; | |
| 208 | 183 | |
| 209 | std::string Filename = toString(Sec->getFile<ELFT>()); | |
| 184 | std::string Filename = toString(Sec->File); | |
| 210 | 185 | ArrayRef<uint8_t> D = Sec->Data; |
| 211 | 186 | |
| 212 | 187 | while (!D.empty()) { |
| ... | ... | @@ -230,9 +205,7 @@ MipsOptionsSection<ELFT> *MipsOptionsSection<ELFT>::create() { |
| 230 | 205 | } |
| 231 | 206 | }; |
| 232 | 207 | |
| 233 | if (Create) | |
| 234 | return make<MipsOptionsSection<ELFT>>(Reginfo); | |
| 235 | return nullptr; | |
| 208 | return make<MipsOptionsSection<ELFT>>(Reginfo); | |
| 236 | 209 | } |
| 237 | 210 | |
| 238 | 211 | // MIPS .reginfo section. |
| ... | ... | @@ -255,32 +228,31 @@ MipsReginfoSection<ELFT> *MipsReginfoSection<ELFT>::create() { |
| 255 | 228 | if (ELFT::Is64Bits) |
| 256 | 229 | return nullptr; |
| 257 | 230 | |
| 258 | Elf_Mips_RegInfo Reginfo = {}; | |
| 259 | bool Create = false; | |
| 231 | std::vector<InputSectionBase *> Sections; | |
| 232 | for (InputSectionBase *Sec : InputSections) | |
| 233 | if (Sec->Type == SHT_MIPS_REGINFO) | |
| 234 | Sections.push_back(Sec); | |
| 260 | 235 | |
| 261 | for (InputSectionBase *Sec : InputSections) { | |
| 262 | if (Sec->Type != SHT_MIPS_REGINFO) | |
| 263 | continue; | |
| 236 | if (Sections.empty()) | |
| 237 | return nullptr; | |
| 238 | ||
| 239 | Elf_Mips_RegInfo Reginfo = {}; | |
| 240 | for (InputSectionBase *Sec : Sections) { | |
| 264 | 241 | Sec->Live = false; |
| 265 | Create = true; | |
| 266 | 242 | |
| 267 | 243 | if (Sec->Data.size() != sizeof(Elf_Mips_RegInfo)) { |
| 268 | error(toString(Sec->getFile<ELFT>()) + | |
| 269 | ": invalid size of .reginfo section"); | |
| 244 | error(toString(Sec->File) + ": invalid size of .reginfo section"); | |
| 270 | 245 | return nullptr; |
| 271 | 246 | } |
| 272 | 247 | auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->Data.data()); |
| 273 | 248 | if (Config->Relocatable && R->ri_gp_value) |
| 274 | error(toString(Sec->getFile<ELFT>()) + | |
| 275 | ": unsupported non-zero ri_gp_value"); | |
| 249 | error(toString(Sec->File) + ": unsupported non-zero ri_gp_value"); | |
| 276 | 250 | |
| 277 | 251 | Reginfo.ri_gprmask |= R->ri_gprmask; |
| 278 | 252 | Sec->getFile<ELFT>()->MipsGp0 = R->ri_gp_value; |
| 279 | 253 | }; |
| 280 | 254 | |
| 281 | if (Create) | |
| 282 | return make<MipsReginfoSection<ELFT>>(Reginfo); | |
| 283 | return nullptr; | |
| 255 | return make<MipsReginfoSection<ELFT>>(Reginfo); | |
| 284 | 256 | } |
| 285 | 257 | |
| 286 | 258 | InputSection *elf::createInterpSection() { |
| ... | ... | @@ -288,16 +260,16 @@ InputSection *elf::createInterpSection() { |
| 288 | 260 | StringRef S = Saver.save(Config->DynamicLinker); |
| 289 | 261 | ArrayRef<uint8_t> Contents = {(const uint8_t *)S.data(), S.size() + 1}; |
| 290 | 262 | |
| 291 | auto *Sec = | |
| 292 | make<InputSection>(SHF_ALLOC, SHT_PROGBITS, 1, Contents, ".interp"); | |
| 263 | auto *Sec = make<InputSection>(nullptr, SHF_ALLOC, SHT_PROGBITS, 1, Contents, | |
| 264 | ".interp"); | |
| 293 | 265 | Sec->Live = true; |
| 294 | 266 | return Sec; |
| 295 | 267 | } |
| 296 | 268 | |
| 297 | SymbolBody *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, | |
| 298 | uint64_t Size, InputSectionBase *Section) { | |
| 299 | auto *S = make<DefinedRegular>(Name, /*IsLocal*/ true, STV_DEFAULT, Type, | |
| 300 | Value, Size, Section, nullptr); | |
| 269 | Symbol *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, | |
| 270 | uint64_t Size, InputSectionBase &Section) { | |
| 271 | auto *S = make<Defined>(Section.File, Name, STB_LOCAL, STV_DEFAULT, Type, | |
| 272 | Value, Size, &Section); | |
| 301 | 273 | if (InX::SymTab) |
| 302 | 274 | InX::SymTab->addSymbol(S); |
| 303 | 275 | return S; |
| ... | ... | @@ -320,14 +292,13 @@ static size_t getHashSize() { |
| 320 | 292 | } |
| 321 | 293 | |
| 322 | 294 | BuildIdSection::BuildIdSection() |
| 323 | : SyntheticSection(SHF_ALLOC, SHT_NOTE, 1, ".note.gnu.build-id"), | |
| 295 | : SyntheticSection(SHF_ALLOC, SHT_NOTE, 4, ".note.gnu.build-id"), | |
| 324 | 296 | HashSize(getHashSize()) {} |
| 325 | 297 | |
| 326 | 298 | void BuildIdSection::writeTo(uint8_t *Buf) { |
| 327 | endianness E = Config->Endianness; | |
| 328 | write32(Buf, 4, E); // Name size | |
| 329 | write32(Buf + 4, HashSize, E); // Content size | |
| 330 | write32(Buf + 8, NT_GNU_BUILD_ID, E); // Type | |
| 299 | write32(Buf, 4); // Name size | |
| 300 | write32(Buf + 4, HashSize); // Content size | |
| 301 | write32(Buf + 8, NT_GNU_BUILD_ID); // Type | |
| 331 | 302 | memcpy(Buf + 12, "GNU", 4); // Name string |
| 332 | 303 | HashBuf = Buf + 16; |
| 333 | 304 | } |
| ... | ... | @@ -364,15 +335,12 @@ void BuildIdSection::computeHash( |
| 364 | 335 | HashFn(HashBuf, Hashes); |
| 365 | 336 | } |
| 366 | 337 | |
| 367 | BssSection::BssSection(StringRef Name) | |
| 368 | : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 0, Name) {} | |
| 369 | ||
| 370 | size_t BssSection::reserveSpace(uint64_t Size, uint32_t Alignment) { | |
| 338 | BssSection::BssSection(StringRef Name, uint64_t Size, uint32_t Alignment) | |
| 339 | : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, Alignment, Name) { | |
| 340 | this->Bss = true; | |
| 371 | 341 | if (OutputSection *Sec = getParent()) |
| 372 | Sec->updateAlignment(Alignment); | |
| 373 | this->Size = alignTo(this->Size, Alignment) + Size; | |
| 374 | this->Alignment = std::max(this->Alignment, Alignment); | |
| 375 | return this->Size - Size; | |
| 342 | Sec->Alignment = std::max(Sec->Alignment, Alignment); | |
| 343 | this->Size = Size; | |
| 376 | 344 | } |
| 377 | 345 | |
| 378 | 346 | void BuildIdSection::writeBuildId(ArrayRef<uint8_t> Buf) { |
| ... | ... | @@ -393,8 +361,8 @@ void BuildIdSection::writeBuildId(ArrayRef<uint8_t> Buf) { |
| 393 | 361 | }); |
| 394 | 362 | break; |
| 395 | 363 | case BuildIdKind::Uuid: |
| 396 | if (getRandomBytes(HashBuf, HashSize)) | |
| 397 | error("entropy source failure"); | |
| 364 | if (auto EC = getRandomBytes(HashBuf, HashSize)) | |
| 365 | error("entropy source failure: " + EC.message()); | |
| 398 | 366 | break; |
| 399 | 367 | case BuildIdKind::Hexstring: |
| 400 | 368 | memcpy(HashBuf, Config->BuildIdVector.data(), Config->BuildIdVector.size()); |
| ... | ... | @@ -404,101 +372,99 @@ void BuildIdSection::writeBuildId(ArrayRef<uint8_t> Buf) { |
| 404 | 372 | } |
| 405 | 373 | } |
| 406 | 374 | |
| 407 | template <class ELFT> | |
| 408 | EhFrameSection<ELFT>::EhFrameSection() | |
| 375 | EhFrameSection::EhFrameSection() | |
| 409 | 376 | : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 1, ".eh_frame") {} |
| 410 | 377 | |
| 411 | 378 | // Search for an existing CIE record or create a new one. |
| 412 | 379 | // CIE records from input object files are uniquified by their contents |
| 413 | 380 | // and where their relocations point to. |
| 414 | template <class ELFT> | |
| 415 | template <class RelTy> | |
| 416 | CieRecord *EhFrameSection<ELFT>::addCie(EhSectionPiece &Piece, | |
| 417 | ArrayRef<RelTy> Rels) { | |
| 418 | auto *Sec = cast<EhInputSection>(Piece.ID); | |
| 419 | const endianness E = ELFT::TargetEndianness; | |
| 420 | if (read32<E>(Piece.data().data() + 4) != 0) | |
| 381 | template <class ELFT, class RelTy> | |
| 382 | 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) | |
| 421 | 385 | fatal(toString(Sec) + ": CIE expected at beginning of .eh_frame"); |
| 422 | 386 | |
| 423 | SymbolBody *Personality = nullptr; | |
| 424 | unsigned FirstRelI = Piece.FirstRelocation; | |
| 387 | Symbol *Personality = nullptr; | |
| 388 | unsigned FirstRelI = Cie.FirstRelocation; | |
| 425 | 389 | if (FirstRelI != (unsigned)-1) |
| 426 | 390 | Personality = |
| 427 | 391 | &Sec->template getFile<ELFT>()->getRelocTargetSym(Rels[FirstRelI]); |
| 428 | 392 | |
| 429 | 393 | // Search for an existing CIE by CIE contents/relocation target pair. |
| 430 | CieRecord *&Cie = CieMap[{Piece.data(), Personality}]; | |
| 394 | CieRecord *&Rec = CieMap[{Cie.data(), Personality}]; | |
| 431 | 395 | |
| 432 | 396 | // If not found, create a new one. |
| 433 | if (!Cie) { | |
| 434 | Cie = make<CieRecord>(); | |
| 435 | Cie->Piece = &Piece; | |
| 436 | Cies.push_back(Cie); | |
| 397 | if (!Rec) { | |
| 398 | Rec = make<CieRecord>(); | |
| 399 | Rec->Cie = &Cie; | |
| 400 | CieRecords.push_back(Rec); | |
| 437 | 401 | } |
| 438 | return Cie; | |
| 402 | return Rec; | |
| 439 | 403 | } |
| 440 | 404 | |
| 441 | 405 | // There is one FDE per function. Returns true if a given FDE |
| 442 | 406 | // points to a live function. |
| 443 | template <class ELFT> | |
| 444 | template <class RelTy> | |
| 445 | bool EhFrameSection<ELFT>::isFdeLive(EhSectionPiece &Piece, | |
| 446 | ArrayRef<RelTy> Rels) { | |
| 447 | auto *Sec = cast<EhInputSection>(Piece.ID); | |
| 448 | unsigned FirstRelI = Piece.FirstRelocation; | |
| 407 | template <class ELFT, class RelTy> | |
| 408 | bool EhFrameSection::isFdeLive(EhSectionPiece &Fde, ArrayRef<RelTy> Rels) { | |
| 409 | auto *Sec = cast<EhInputSection>(Fde.Sec); | |
| 410 | unsigned FirstRelI = Fde.FirstRelocation; | |
| 411 | ||
| 412 | // An FDE should point to some function because FDEs are to describe | |
| 413 | // functions. That's however not always the case due to an issue of | |
| 414 | // ld.gold with -r. ld.gold may discard only functions and leave their | |
| 415 | // corresponding FDEs, which results in creating bad .eh_frame sections. | |
| 416 | // To deal with that, we ignore such FDEs. | |
| 449 | 417 | if (FirstRelI == (unsigned)-1) |
| 450 | 418 | return false; |
| 419 | ||
| 451 | 420 | const RelTy &Rel = Rels[FirstRelI]; |
| 452 | SymbolBody &B = Sec->template getFile<ELFT>()->getRelocTargetSym(Rel); | |
| 453 | auto *D = dyn_cast<DefinedRegular>(&B); | |
| 454 | if (!D || !D->Section) | |
| 455 | return false; | |
| 456 | auto *Target = | |
| 457 | cast<InputSectionBase>(cast<InputSectionBase>(D->Section)->Repl); | |
| 458 | return Target && Target->Live; | |
| 421 | Symbol &B = Sec->template getFile<ELFT>()->getRelocTargetSym(Rel); | |
| 422 | ||
| 423 | // FDEs for garbage-collected or merged-by-ICF sections are dead. | |
| 424 | if (auto *D = dyn_cast<Defined>(&B)) | |
| 425 | if (SectionBase *Sec = D->Section) | |
| 426 | return Sec->Live; | |
| 427 | return false; | |
| 459 | 428 | } |
| 460 | 429 | |
| 461 | 430 | // .eh_frame is a sequence of CIE or FDE records. In general, there |
| 462 | 431 | // is one CIE record per input object file which is followed by |
| 463 | 432 | // a list of FDEs. This function searches an existing CIE or create a new |
| 464 | 433 | // one and associates FDEs to the CIE. |
| 465 | template <class ELFT> | |
| 466 | template <class RelTy> | |
| 467 | void EhFrameSection<ELFT>::addSectionAux(EhInputSection *Sec, | |
| 468 | ArrayRef<RelTy> Rels) { | |
| 469 | const endianness E = ELFT::TargetEndianness; | |
| 470 | ||
| 434 | template <class ELFT, class RelTy> | |
| 435 | void EhFrameSection::addSectionAux(EhInputSection *Sec, ArrayRef<RelTy> Rels) { | |
| 471 | 436 | DenseMap<size_t, CieRecord *> OffsetToCie; |
| 472 | 437 | for (EhSectionPiece &Piece : Sec->Pieces) { |
| 473 | 438 | // The empty record is the end marker. |
| 474 | if (Piece.size() == 4) | |
| 439 | if (Piece.Size == 4) | |
| 475 | 440 | return; |
| 476 | 441 | |
| 477 | 442 | size_t Offset = Piece.InputOff; |
| 478 | uint32_t ID = read32<E>(Piece.data().data() + 4); | |
| 443 | uint32_t ID = read32(Piece.data().data() + 4, Config->Endianness); | |
| 479 | 444 | if (ID == 0) { |
| 480 | OffsetToCie[Offset] = addCie(Piece, Rels); | |
| 445 | OffsetToCie[Offset] = addCie<ELFT>(Piece, Rels); | |
| 481 | 446 | continue; |
| 482 | 447 | } |
| 483 | 448 | |
| 484 | 449 | uint32_t CieOffset = Offset + 4 - ID; |
| 485 | CieRecord *Cie = OffsetToCie[CieOffset]; | |
| 486 | if (!Cie) | |
| 450 | CieRecord *Rec = OffsetToCie[CieOffset]; | |
| 451 | if (!Rec) | |
| 487 | 452 | fatal(toString(Sec) + ": invalid CIE reference"); |
| 488 | 453 | |
| 489 | if (!isFdeLive(Piece, Rels)) | |
| 454 | if (!isFdeLive<ELFT>(Piece, Rels)) | |
| 490 | 455 | continue; |
| 491 | Cie->FdePieces.push_back(&Piece); | |
| 456 | Rec->Fdes.push_back(&Piece); | |
| 492 | 457 | NumFdes++; |
| 493 | 458 | } |
| 494 | 459 | } |
| 495 | 460 | |
| 496 | template <class ELFT> | |
| 497 | void EhFrameSection<ELFT>::addSection(InputSectionBase *C) { | |
| 461 | template <class ELFT> void EhFrameSection::addSection(InputSectionBase *C) { | |
| 498 | 462 | auto *Sec = cast<EhInputSection>(C); |
| 499 | 463 | Sec->Parent = this; |
| 500 | updateAlignment(Sec->Alignment); | |
| 464 | ||
| 465 | Alignment = std::max(Alignment, Sec->Alignment); | |
| 501 | 466 | Sections.push_back(Sec); |
| 467 | ||
| 502 | 468 | for (auto *DS : Sec->DependentSections) |
| 503 | 469 | DependentSections.push_back(DS); |
| 504 | 470 | |
| ... | ... | @@ -509,42 +475,36 @@ void EhFrameSection<ELFT>::addSection(InputSectionBase *C) { |
| 509 | 475 | if (Sec->Pieces.empty()) |
| 510 | 476 | return; |
| 511 | 477 | |
| 512 | if (Sec->NumRelocations) { | |
| 513 | if (Sec->AreRelocsRela) | |
| 514 | addSectionAux(Sec, Sec->template relas<ELFT>()); | |
| 515 | else | |
| 516 | addSectionAux(Sec, Sec->template rels<ELFT>()); | |
| 517 | return; | |
| 518 | } | |
| 519 | addSectionAux(Sec, makeArrayRef<Elf_Rela>(nullptr, nullptr)); | |
| 478 | if (Sec->AreRelocsRela) | |
| 479 | addSectionAux<ELFT>(Sec, Sec->template relas<ELFT>()); | |
| 480 | else | |
| 481 | addSectionAux<ELFT>(Sec, Sec->template rels<ELFT>()); | |
| 520 | 482 | } |
| 521 | 483 | |
| 522 | template <class ELFT> | |
| 523 | 484 | static void writeCieFde(uint8_t *Buf, ArrayRef<uint8_t> D) { |
| 524 | 485 | memcpy(Buf, D.data(), D.size()); |
| 525 | 486 | |
| 526 | size_t Aligned = alignTo(D.size(), sizeof(typename ELFT::uint)); | |
| 487 | size_t Aligned = alignTo(D.size(), Config->Wordsize); | |
| 527 | 488 | |
| 528 | 489 | // Zero-clear trailing padding if it exists. |
| 529 | 490 | memset(Buf + D.size(), 0, Aligned - D.size()); |
| 530 | 491 | |
| 531 | 492 | // Fix the size field. -4 since size does not include the size field itself. |
| 532 | const endianness E = ELFT::TargetEndianness; | |
| 533 | write32<E>(Buf, Aligned - 4); | |
| 493 | write32(Buf, Aligned - 4); | |
| 534 | 494 | } |
| 535 | 495 | |
| 536 | template <class ELFT> void EhFrameSection<ELFT>::finalizeContents() { | |
| 496 | void EhFrameSection::finalizeContents() { | |
| 537 | 497 | if (this->Size) |
| 538 | 498 | return; // Already finalized. |
| 539 | 499 | |
| 540 | 500 | size_t Off = 0; |
| 541 | for (CieRecord *Cie : Cies) { | |
| 542 | Cie->Piece->OutputOff = Off; | |
| 543 | Off += alignTo(Cie->Piece->size(), Config->Wordsize); | |
| 501 | for (CieRecord *Rec : CieRecords) { | |
| 502 | Rec->Cie->OutputOff = Off; | |
| 503 | Off += alignTo(Rec->Cie->Size, Config->Wordsize); | |
| 544 | 504 | |
| 545 | for (EhSectionPiece *Fde : Cie->FdePieces) { | |
| 505 | for (EhSectionPiece *Fde : Rec->Fdes) { | |
| 546 | 506 | Fde->OutputOff = Off; |
| 547 | Off += alignTo(Fde->size(), Config->Wordsize); | |
| 507 | Off += alignTo(Fde->Size, Config->Wordsize); | |
| 548 | 508 | } |
| 549 | 509 | } |
| 550 | 510 | |
| ... | ... | @@ -557,32 +517,46 @@ template <class ELFT> void EhFrameSection<ELFT>::finalizeContents() { |
| 557 | 517 | this->Size = Off; |
| 558 | 518 | } |
| 559 | 519 | |
| 560 | template <class ELFT> static uint64_t readFdeAddr(uint8_t *Buf, int Size) { | |
| 561 | const endianness E = ELFT::TargetEndianness; | |
| 520 | // Returns data for .eh_frame_hdr. .eh_frame_hdr is a binary search table | |
| 521 | // to get an FDE from an address to which FDE is applied. This function | |
| 522 | // returns a list of such pairs. | |
| 523 | std::vector<EhFrameSection::FdeData> EhFrameSection::getFdeData() const { | |
| 524 | uint8_t *Buf = getParent()->Loc + OutSecOff; | |
| 525 | std::vector<FdeData> Ret; | |
| 526 | ||
| 527 | for (CieRecord *Rec : CieRecords) { | |
| 528 | uint8_t Enc = getFdeEncoding(Rec->Cie); | |
| 529 | for (EhSectionPiece *Fde : Rec->Fdes) { | |
| 530 | uint32_t Pc = getFdePc(Buf, Fde->OutputOff, Enc); | |
| 531 | uint32_t FdeVA = getParent()->Addr + Fde->OutputOff; | |
| 532 | Ret.push_back({Pc, FdeVA}); | |
| 533 | } | |
| 534 | } | |
| 535 | return Ret; | |
| 536 | } | |
| 537 | ||
| 538 | static uint64_t readFdeAddr(uint8_t *Buf, int Size) { | |
| 562 | 539 | switch (Size) { |
| 563 | 540 | case DW_EH_PE_udata2: |
| 564 | return read16<E>(Buf); | |
| 541 | return read16(Buf, Config->Endianness); | |
| 565 | 542 | case DW_EH_PE_udata4: |
| 566 | return read32<E>(Buf); | |
| 543 | return read32(Buf, Config->Endianness); | |
| 567 | 544 | case DW_EH_PE_udata8: |
| 568 | return read64<E>(Buf); | |
| 545 | return read64(Buf, Config->Endianness); | |
| 569 | 546 | case DW_EH_PE_absptr: |
| 570 | if (ELFT::Is64Bits) | |
| 571 | return read64<E>(Buf); | |
| 572 | return read32<E>(Buf); | |
| 547 | return readUint(Buf); | |
| 573 | 548 | } |
| 574 | 549 | fatal("unknown FDE size encoding"); |
| 575 | 550 | } |
| 576 | 551 | |
| 577 | 552 | // Returns the VA to which a given FDE (on a mmap'ed buffer) is applied to. |
| 578 | 553 | // We need it to create .eh_frame_hdr section. |
| 579 | template <class ELFT> | |
| 580 | uint64_t EhFrameSection<ELFT>::getFdePc(uint8_t *Buf, size_t FdeOff, | |
| 581 | uint8_t Enc) { | |
| 554 | uint64_t EhFrameSection::getFdePc(uint8_t *Buf, size_t FdeOff, | |
| 555 | uint8_t Enc) const { | |
| 582 | 556 | // The starting address to which this FDE applies is |
| 583 | 557 | // stored at FDE + 8 byte. |
| 584 | 558 | size_t Off = FdeOff + 8; |
| 585 | uint64_t Addr = readFdeAddr<ELFT>(Buf + Off, Enc & 0x7); | |
| 559 | uint64_t Addr = readFdeAddr(Buf + Off, Enc & 0x7); | |
| 586 | 560 | if ((Enc & 0x70) == DW_EH_PE_absptr) |
| 587 | 561 | return Addr; |
| 588 | 562 | if ((Enc & 0x70) == DW_EH_PE_pcrel) |
| ... | ... | @@ -590,50 +564,39 @@ uint64_t EhFrameSection<ELFT>::getFdePc(uint8_t *Buf, size_t FdeOff, |
| 590 | 564 | fatal("unknown FDE size relative encoding"); |
| 591 | 565 | } |
| 592 | 566 | |
| 593 | template <class ELFT> void EhFrameSection<ELFT>::writeTo(uint8_t *Buf) { | |
| 594 | const endianness E = ELFT::TargetEndianness; | |
| 595 | for (CieRecord *Cie : Cies) { | |
| 596 | size_t CieOffset = Cie->Piece->OutputOff; | |
| 597 | writeCieFde<ELFT>(Buf + CieOffset, Cie->Piece->data()); | |
| 567 | void EhFrameSection::writeTo(uint8_t *Buf) { | |
| 568 | // Write CIE and FDE records. | |
| 569 | for (CieRecord *Rec : CieRecords) { | |
| 570 | size_t CieOffset = Rec->Cie->OutputOff; | |
| 571 | writeCieFde(Buf + CieOffset, Rec->Cie->data()); | |
| 598 | 572 | |
| 599 | for (EhSectionPiece *Fde : Cie->FdePieces) { | |
| 573 | for (EhSectionPiece *Fde : Rec->Fdes) { | |
| 600 | 574 | size_t Off = Fde->OutputOff; |
| 601 | writeCieFde<ELFT>(Buf + Off, Fde->data()); | |
| 575 | writeCieFde(Buf + Off, Fde->data()); | |
| 602 | 576 | |
| 603 | 577 | // FDE's second word should have the offset to an associated CIE. |
| 604 | 578 | // Write it. |
| 605 | write32<E>(Buf + Off + 4, Off + 4 - CieOffset); | |
| 579 | write32(Buf + Off + 4, Off + 4 - CieOffset); | |
| 606 | 580 | } |
| 607 | 581 | } |
| 608 | 582 | |
| 583 | // Apply relocations. .eh_frame section contents are not contiguous | |
| 584 | // in the output buffer, but relocateAlloc() still works because | |
| 585 | // getOffset() takes care of discontiguous section pieces. | |
| 609 | 586 | for (EhInputSection *S : Sections) |
| 610 | 587 | S->relocateAlloc(Buf, nullptr); |
| 611 | ||
| 612 | // Construct .eh_frame_hdr. .eh_frame_hdr is a binary search table | |
| 613 | // to get a FDE from an address to which FDE is applied. So here | |
| 614 | // we obtain two addresses and pass them to EhFrameHdr object. | |
| 615 | if (In<ELFT>::EhFrameHdr) { | |
| 616 | for (CieRecord *Cie : Cies) { | |
| 617 | uint8_t Enc = getFdeEncoding<ELFT>(Cie->Piece); | |
| 618 | for (SectionPiece *Fde : Cie->FdePieces) { | |
| 619 | uint64_t Pc = getFdePc(Buf, Fde->OutputOff, Enc); | |
| 620 | uint64_t FdeVA = getParent()->Addr + Fde->OutputOff; | |
| 621 | In<ELFT>::EhFrameHdr->addFde(Pc, FdeVA); | |
| 622 | } | |
| 623 | } | |
| 624 | } | |
| 625 | 588 | } |
| 626 | 589 | |
| 627 | 590 | GotSection::GotSection() |
| 628 | 591 | : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, |
| 629 | 592 | Target->GotEntrySize, ".got") {} |
| 630 | 593 | |
| 631 | void GotSection::addEntry(SymbolBody &Sym) { | |
| 594 | void GotSection::addEntry(Symbol &Sym) { | |
| 632 | 595 | Sym.GotIndex = NumEntries; |
| 633 | 596 | ++NumEntries; |
| 634 | 597 | } |
| 635 | 598 | |
| 636 | bool GotSection::addDynTlsEntry(SymbolBody &Sym) { | |
| 599 | bool GotSection::addDynTlsEntry(Symbol &Sym) { | |
| 637 | 600 | if (Sym.GlobalDynIndex != -1U) |
| 638 | 601 | return false; |
| 639 | 602 | Sym.GlobalDynIndex = NumEntries; |
| ... | ... | @@ -652,20 +615,21 @@ bool GotSection::addTlsIndex() { |
| 652 | 615 | return true; |
| 653 | 616 | } |
| 654 | 617 | |
| 655 | uint64_t GotSection::getGlobalDynAddr(const SymbolBody &B) const { | |
| 618 | uint64_t GotSection::getGlobalDynAddr(const Symbol &B) const { | |
| 656 | 619 | return this->getVA() + B.GlobalDynIndex * Config->Wordsize; |
| 657 | 620 | } |
| 658 | 621 | |
| 659 | uint64_t GotSection::getGlobalDynOffset(const SymbolBody &B) const { | |
| 622 | uint64_t GotSection::getGlobalDynOffset(const Symbol &B) const { | |
| 660 | 623 | return B.GlobalDynIndex * Config->Wordsize; |
| 661 | 624 | } |
| 662 | 625 | |
| 663 | 626 | void GotSection::finalizeContents() { Size = NumEntries * Config->Wordsize; } |
| 664 | 627 | |
| 665 | 628 | bool GotSection::empty() const { |
| 666 | // If we have a relocation that is relative to GOT (such as GOTOFFREL), | |
| 667 | // we need to emit a GOT even if it's empty. | |
| 668 | return NumEntries == 0 && !HasGotOffRel; | |
| 629 | // 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 | |
| 631 | // (i.e. _GLOBAL_OFFSET_TABLE_). | |
| 632 | return NumEntries == 0 && !HasGotOffRel && !ElfSym::GlobalOffsetTable; | |
| 669 | 633 | } |
| 670 | 634 | |
| 671 | 635 | void GotSection::writeTo(uint8_t *Buf) { |
| ... | ... | @@ -679,7 +643,7 @@ MipsGotSection::MipsGotSection() |
| 679 | 643 | : SyntheticSection(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL, SHT_PROGBITS, 16, |
| 680 | 644 | ".got") {} |
| 681 | 645 | |
| 682 | void MipsGotSection::addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr) { | |
| 646 | void MipsGotSection::addEntry(Symbol &Sym, int64_t Addend, RelExpr Expr) { | |
| 683 | 647 | // For "true" local symbols which can be referenced from the same module |
| 684 | 648 | // only compiler creates two instructions for address loading: |
| 685 | 649 | // |
| ... | ... | @@ -721,7 +685,7 @@ void MipsGotSection::addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr) { |
| 721 | 685 | TlsEntries.push_back(&Sym); |
| 722 | 686 | return; |
| 723 | 687 | } |
| 724 | auto AddEntry = [&](SymbolBody &S, uint64_t A, GotEntries &Items) { | |
| 688 | auto AddEntry = [&](Symbol &S, uint64_t A, GotEntries &Items) { | |
| 725 | 689 | if (S.isInGot() && !A) |
| 726 | 690 | return; |
| 727 | 691 | size_t NewIndex = Items.size(); |
| ... | ... | @@ -731,7 +695,7 @@ void MipsGotSection::addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr) { |
| 731 | 695 | if (!A) |
| 732 | 696 | S.GotIndex = NewIndex; |
| 733 | 697 | }; |
| 734 | if (Sym.isPreemptible()) { | |
| 698 | if (Sym.IsPreemptible) { | |
| 735 | 699 | // Ignore addends for preemptible symbols. They got single GOT entry anyway. |
| 736 | 700 | AddEntry(Sym, 0, GlobalEntries); |
| 737 | 701 | Sym.IsInGlobalMipsGot = true; |
| ... | ... | @@ -746,7 +710,7 @@ void MipsGotSection::addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr) { |
| 746 | 710 | } |
| 747 | 711 | } |
| 748 | 712 | |
| 749 | bool MipsGotSection::addDynTlsEntry(SymbolBody &Sym) { | |
| 713 | bool MipsGotSection::addDynTlsEntry(Symbol &Sym) { | |
| 750 | 714 | if (Sym.GlobalDynIndex != -1U) |
| 751 | 715 | return false; |
| 752 | 716 | Sym.GlobalDynIndex = TlsEntries.size(); |
| ... | ... | @@ -775,7 +739,7 @@ static uint64_t getMipsPageCount(uint64_t Size) { |
| 775 | 739 | return (Size + 0xfffe) / 0xffff + 1; |
| 776 | 740 | } |
| 777 | 741 | |
| 778 | uint64_t MipsGotSection::getPageEntryOffset(const SymbolBody &B, | |
| 742 | uint64_t MipsGotSection::getPageEntryOffset(const Symbol &B, | |
| 779 | 743 | int64_t Addend) const { |
| 780 | 744 | const OutputSection *OutSec = B.getOutputSection(); |
| 781 | 745 | uint64_t SecAddr = getMipsPageAddr(OutSec->Addr); |
| ... | ... | @@ -785,8 +749,8 @@ uint64_t MipsGotSection::getPageEntryOffset(const SymbolBody &B, |
| 785 | 749 | return (HeaderEntriesNum + Index) * Config->Wordsize; |
| 786 | 750 | } |
| 787 | 751 | |
| 788 | uint64_t MipsGotSection::getBodyEntryOffset(const SymbolBody &B, | |
| 789 | int64_t Addend) const { | |
| 752 | uint64_t MipsGotSection::getSymEntryOffset(const Symbol &B, | |
| 753 | int64_t Addend) const { | |
| 790 | 754 | // Calculate offset of the GOT entries block: TLS, global, local. |
| 791 | 755 | uint64_t Index = HeaderEntriesNum + PageEntriesNum; |
| 792 | 756 | if (B.isTls()) |
| ... | ... | @@ -810,11 +774,11 @@ uint64_t MipsGotSection::getTlsOffset() const { |
| 810 | 774 | return (getLocalEntriesNum() + GlobalEntries.size()) * Config->Wordsize; |
| 811 | 775 | } |
| 812 | 776 | |
| 813 | uint64_t MipsGotSection::getGlobalDynOffset(const SymbolBody &B) const { | |
| 777 | uint64_t MipsGotSection::getGlobalDynOffset(const Symbol &B) const { | |
| 814 | 778 | return B.GlobalDynIndex * Config->Wordsize; |
| 815 | 779 | } |
| 816 | 780 | |
| 817 | const SymbolBody *MipsGotSection::getFirstGlobalEntry() const { | |
| 781 | const Symbol *MipsGotSection::getFirstGlobalEntry() const { | |
| 818 | 782 | return GlobalEntries.empty() ? nullptr : GlobalEntries.front().first; |
| 819 | 783 | } |
| 820 | 784 | |
| ... | ... | @@ -825,7 +789,7 @@ unsigned MipsGotSection::getLocalEntriesNum() const { |
| 825 | 789 | |
| 826 | 790 | void MipsGotSection::finalizeContents() { updateAllocSize(); } |
| 827 | 791 | |
| 828 | void MipsGotSection::updateAllocSize() { | |
| 792 | bool MipsGotSection::updateAllocSize() { | |
| 829 | 793 | PageEntriesNum = 0; |
| 830 | 794 | for (std::pair<const OutputSection *, size_t> &P : PageIndexMap) { |
| 831 | 795 | // For each output section referenced by GOT page relocations calculate |
| ... | ... | @@ -839,6 +803,7 @@ void MipsGotSection::updateAllocSize() { |
| 839 | 803 | } |
| 840 | 804 | Size = (getLocalEntriesNum() + GlobalEntries.size() + TlsEntries.size()) * |
| 841 | 805 | Config->Wordsize; |
| 806 | return false; | |
| 842 | 807 | } |
| 843 | 808 | |
| 844 | 809 | bool MipsGotSection::empty() const { |
| ... | ... | @@ -849,19 +814,6 @@ bool MipsGotSection::empty() const { |
| 849 | 814 | |
| 850 | 815 | uint64_t MipsGotSection::getGp() const { return ElfSym::MipsGp->getVA(0); } |
| 851 | 816 | |
| 852 | static uint64_t readUint(uint8_t *Buf) { | |
| 853 | if (Config->Is64) | |
| 854 | return read64(Buf, Config->Endianness); | |
| 855 | return read32(Buf, Config->Endianness); | |
| 856 | } | |
| 857 | ||
| 858 | static void writeUint(uint8_t *Buf, uint64_t Val) { | |
| 859 | if (Config->Is64) | |
| 860 | write64(Buf, Val, Config->Endianness); | |
| 861 | else | |
| 862 | write32(Buf, Val, Config->Endianness); | |
| 863 | } | |
| 864 | ||
| 865 | 817 | void MipsGotSection::writeTo(uint8_t *Buf) { |
| 866 | 818 | // Set the MSB of the second GOT slot. This is not required by any |
| 867 | 819 | // MIPS ABI documentation, though. |
| ... | ... | @@ -892,8 +844,10 @@ void MipsGotSection::writeTo(uint8_t *Buf) { |
| 892 | 844 | auto AddEntry = [&](const GotEntry &SA) { |
| 893 | 845 | uint8_t *Entry = Buf; |
| 894 | 846 | Buf += Config->Wordsize; |
| 895 | const SymbolBody *Body = SA.first; | |
| 896 | uint64_t VA = Body->getVA(SA.second); | |
| 847 | const Symbol *Sym = SA.first; | |
| 848 | uint64_t VA = Sym->getVA(SA.second); | |
| 849 | if (Sym->StOther & STO_MIPS_MICROMIPS) | |
| 850 | VA |= 1; | |
| 897 | 851 | writeUint(Entry, VA); |
| 898 | 852 | }; |
| 899 | 853 | std::for_each(std::begin(LocalEntries), std::end(LocalEntries), AddEntry); |
| ... | ... | @@ -906,8 +860,8 @@ void MipsGotSection::writeTo(uint8_t *Buf) { |
| 906 | 860 | // https://www.linux-mips.org/wiki/NPTL |
| 907 | 861 | if (TlsIndexOff != -1U && !Config->Pic) |
| 908 | 862 | writeUint(Buf + TlsIndexOff, 1); |
| 909 | for (const SymbolBody *B : TlsEntries) { | |
| 910 | if (!B || B->isPreemptible()) | |
| 863 | for (const Symbol *B : TlsEntries) { | |
| 864 | if (!B || B->IsPreemptible) | |
| 911 | 865 | continue; |
| 912 | 866 | uint64_t VA = B->getVA(); |
| 913 | 867 | if (B->GotIndex != -1U) { |
| ... | ... | @@ -927,7 +881,7 @@ GotPltSection::GotPltSection() |
| 927 | 881 | : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, |
| 928 | 882 | Target->GotPltEntrySize, ".got.plt") {} |
| 929 | 883 | |
| 930 | void GotPltSection::addEntry(SymbolBody &Sym) { | |
| 884 | void GotPltSection::addEntry(Symbol &Sym) { | |
| 931 | 885 | Sym.GotPltIndex = Target->GotPltHeaderEntriesNum + Entries.size(); |
| 932 | 886 | Entries.push_back(&Sym); |
| 933 | 887 | } |
| ... | ... | @@ -940,7 +894,7 @@ size_t GotPltSection::getSize() const { |
| 940 | 894 | void GotPltSection::writeTo(uint8_t *Buf) { |
| 941 | 895 | Target->writeGotPltHeader(Buf); |
| 942 | 896 | Buf += Target->GotPltHeaderEntriesNum * Target->GotPltEntrySize; |
| 943 | for (const SymbolBody *B : Entries) { | |
| 897 | for (const Symbol *B : Entries) { | |
| 944 | 898 | Target->writeGotPlt(Buf, *B); |
| 945 | 899 | Buf += Config->Wordsize; |
| 946 | 900 | } |
| ... | ... | @@ -953,7 +907,7 @@ IgotPltSection::IgotPltSection() |
| 953 | 907 | Target->GotPltEntrySize, |
| 954 | 908 | Config->EMachine == EM_ARM ? ".got" : ".got.plt") {} |
| 955 | 909 | |
| 956 | void IgotPltSection::addEntry(SymbolBody &Sym) { | |
| 910 | void IgotPltSection::addEntry(Symbol &Sym) { | |
| 957 | 911 | Sym.IsInIgot = true; |
| 958 | 912 | Sym.GotPltIndex = Entries.size(); |
| 959 | 913 | Entries.push_back(&Sym); |
| ... | ... | @@ -964,7 +918,7 @@ size_t IgotPltSection::getSize() const { |
| 964 | 918 | } |
| 965 | 919 | |
| 966 | 920 | void IgotPltSection::writeTo(uint8_t *Buf) { |
| 967 | for (const SymbolBody *B : Entries) { | |
| 921 | for (const Symbol *B : Entries) { | |
| 968 | 922 | Target->writeIgotPlt(Buf, *B); |
| 969 | 923 | Buf += Config->Wordsize; |
| 970 | 924 | } |
| ... | ... | @@ -996,6 +950,7 @@ unsigned StringTableSection::addString(StringRef S, bool HashIt) { |
| 996 | 950 | void StringTableSection::writeTo(uint8_t *Buf) { |
| 997 | 951 | for (StringRef S : Strings) { |
| 998 | 952 | memcpy(Buf, S.data(), S.size()); |
| 953 | Buf[S.size()] = '\0'; | |
| 999 | 954 | Buf += S.size() + 1; |
| 1000 | 955 | } |
| 1001 | 956 | } |
| ... | ... | @@ -1018,26 +973,61 @@ DynamicSection<ELFT>::DynamicSection() |
| 1018 | 973 | if (Config->EMachine == EM_MIPS || Config->ZRodynamic) |
| 1019 | 974 | this->Flags = SHF_ALLOC; |
| 1020 | 975 | |
| 1021 | addEntries(); | |
| 1022 | } | |
| 1023 | ||
| 1024 | // There are some dynamic entries that don't depend on other sections. | |
| 1025 | // Such entries can be set early. | |
| 1026 | template <class ELFT> void DynamicSection<ELFT>::addEntries() { | |
| 1027 | 976 | // Add strings to .dynstr early so that .dynstr's size will be |
| 1028 | 977 | // fixed early. |
| 1029 | 978 | for (StringRef S : Config->FilterList) |
| 1030 | add({DT_FILTER, InX::DynStrTab->addString(S)}); | |
| 979 | addInt(DT_FILTER, InX::DynStrTab->addString(S)); | |
| 1031 | 980 | for (StringRef S : Config->AuxiliaryList) |
| 1032 | add({DT_AUXILIARY, InX::DynStrTab->addString(S)}); | |
| 981 | addInt(DT_AUXILIARY, InX::DynStrTab->addString(S)); | |
| 982 | ||
| 1033 | 983 | if (!Config->Rpath.empty()) |
| 1034 | add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH, | |
| 1035 | InX::DynStrTab->addString(Config->Rpath)}); | |
| 1036 | for (SharedFile<ELFT> *F : Symtab<ELFT>::X->getSharedFiles()) | |
| 1037 | if (F->isNeeded()) | |
| 1038 | add({DT_NEEDED, InX::DynStrTab->addString(F->SoName)}); | |
| 984 | addInt(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH, | |
| 985 | InX::DynStrTab->addString(Config->Rpath)); | |
| 986 | ||
| 987 | for (InputFile *File : SharedFiles) { | |
| 988 | SharedFile<ELFT> *F = cast<SharedFile<ELFT>>(File); | |
| 989 | if (F->IsNeeded) | |
| 990 | addInt(DT_NEEDED, InX::DynStrTab->addString(F->SoName)); | |
| 991 | } | |
| 1039 | 992 | if (!Config->SoName.empty()) |
| 1040 | add({DT_SONAME, InX::DynStrTab->addString(Config->SoName)}); | |
| 993 | addInt(DT_SONAME, InX::DynStrTab->addString(Config->SoName)); | |
| 994 | } | |
| 995 | ||
| 996 | template <class ELFT> | |
| 997 | void DynamicSection<ELFT>::add(int32_t Tag, std::function<uint64_t()> Fn) { | |
| 998 | Entries.push_back({Tag, Fn}); | |
| 999 | } | |
| 1000 | ||
| 1001 | template <class ELFT> | |
| 1002 | void DynamicSection<ELFT>::addInt(int32_t Tag, uint64_t Val) { | |
| 1003 | Entries.push_back({Tag, [=] { return Val; }}); | |
| 1004 | } | |
| 1005 | ||
| 1006 | template <class ELFT> | |
| 1007 | void DynamicSection<ELFT>::addInSec(int32_t Tag, InputSection *Sec) { | |
| 1008 | Entries.push_back( | |
| 1009 | {Tag, [=] { return Sec->getParent()->Addr + Sec->OutSecOff; }}); | |
| 1010 | } | |
| 1011 | ||
| 1012 | template <class ELFT> | |
| 1013 | void DynamicSection<ELFT>::addOutSec(int32_t Tag, OutputSection *Sec) { | |
| 1014 | Entries.push_back({Tag, [=] { return Sec->Addr; }}); | |
| 1015 | } | |
| 1016 | ||
| 1017 | template <class ELFT> | |
| 1018 | void DynamicSection<ELFT>::addSize(int32_t Tag, OutputSection *Sec) { | |
| 1019 | Entries.push_back({Tag, [=] { return Sec->Size; }}); | |
| 1020 | } | |
| 1021 | ||
| 1022 | template <class ELFT> | |
| 1023 | void DynamicSection<ELFT>::addSym(int32_t Tag, Symbol *Sym) { | |
| 1024 | Entries.push_back({Tag, [=] { return Sym->getVA(); }}); | |
| 1025 | } | |
| 1026 | ||
| 1027 | // Add remaining entries to complete .dynamic contents. | |
| 1028 | template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { | |
| 1029 | if (this->Size) | |
| 1030 | return; // Already finalized. | |
| 1041 | 1031 | |
| 1042 | 1032 | // Set DT_FLAGS and DT_FLAGS_1. |
| 1043 | 1033 | uint32_t DtFlags = 0; |
| ... | ... | @@ -1058,9 +1048,9 @@ template <class ELFT> void DynamicSection<ELFT>::addEntries() { |
| 1058 | 1048 | } |
| 1059 | 1049 | |
| 1060 | 1050 | if (DtFlags) |
| 1061 | add({DT_FLAGS, DtFlags}); | |
| 1051 | addInt(DT_FLAGS, DtFlags); | |
| 1062 | 1052 | if (DtFlags1) |
| 1063 | add({DT_FLAGS_1, DtFlags1}); | |
| 1053 | addInt(DT_FLAGS_1, DtFlags1); | |
| 1064 | 1054 | |
| 1065 | 1055 | // DT_DEBUG is a pointer to debug informaion used by debuggers at runtime. We |
| 1066 | 1056 | // need it for each process, so we don't write it for DSOs. The loader writes |
| ... | ... | @@ -1071,133 +1061,121 @@ template <class ELFT> void DynamicSection<ELFT>::addEntries() { |
| 1071 | 1061 | // debugger this information. Such systems may choose make .dynamic read-only. |
| 1072 | 1062 | // If the target is such a system (used -z rodynamic) don't write DT_DEBUG. |
| 1073 | 1063 | if (!Config->Shared && !Config->Relocatable && !Config->ZRodynamic) |
| 1074 | add({DT_DEBUG, (uint64_t)0}); | |
| 1075 | } | |
| 1076 | ||
| 1077 | // Add remaining entries to complete .dynamic contents. | |
| 1078 | template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { | |
| 1079 | if (this->Size) | |
| 1080 | return; // Already finalized. | |
| 1064 | addInt(DT_DEBUG, 0); | |
| 1081 | 1065 | |
| 1082 | 1066 | this->Link = InX::DynStrTab->getParent()->SectionIndex; |
| 1083 | if (In<ELFT>::RelaDyn->getParent() && !In<ELFT>::RelaDyn->empty()) { | |
| 1067 | if (!InX::RelaDyn->empty()) { | |
| 1068 | addInSec(InX::RelaDyn->DynamicTag, InX::RelaDyn); | |
| 1069 | addSize(InX::RelaDyn->SizeDynamicTag, InX::RelaDyn->getParent()); | |
| 1070 | ||
| 1084 | 1071 | bool IsRela = Config->IsRela; |
| 1085 | add({IsRela ? DT_RELA : DT_REL, In<ELFT>::RelaDyn}); | |
| 1086 | add({IsRela ? DT_RELASZ : DT_RELSZ, In<ELFT>::RelaDyn->getParent(), | |
| 1087 | Entry::SecSize}); | |
| 1088 | add({IsRela ? DT_RELAENT : DT_RELENT, | |
| 1089 | uint64_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))}); | |
| 1072 | addInt(IsRela ? DT_RELAENT : DT_RELENT, | |
| 1073 | IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel)); | |
| 1090 | 1074 | |
| 1091 | 1075 | // MIPS dynamic loader does not support RELCOUNT tag. |
| 1092 | 1076 | // The problem is in the tight relation between dynamic |
| 1093 | 1077 | // relocations and GOT. So do not emit this tag on MIPS. |
| 1094 | 1078 | if (Config->EMachine != EM_MIPS) { |
| 1095 | size_t NumRelativeRels = In<ELFT>::RelaDyn->getRelativeRelocCount(); | |
| 1079 | size_t NumRelativeRels = InX::RelaDyn->getRelativeRelocCount(); | |
| 1096 | 1080 | if (Config->ZCombreloc && NumRelativeRels) |
| 1097 | add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels}); | |
| 1081 | addInt(IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels); | |
| 1098 | 1082 | } |
| 1099 | 1083 | } |
| 1100 | if (In<ELFT>::RelaPlt->getParent() && !In<ELFT>::RelaPlt->empty()) { | |
| 1101 | add({DT_JMPREL, In<ELFT>::RelaPlt}); | |
| 1102 | add({DT_PLTRELSZ, In<ELFT>::RelaPlt->getParent(), Entry::SecSize}); | |
| 1084 | // .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 | |
| 1086 | // output. In that case RelaPlt is empty and have zero offset, the same offset | |
| 1087 | // as RelaIplt have. And we still want to emit proper dynamic tags for that | |
| 1088 | // case, so here we always use RelaPlt as marker for the begining of | |
| 1089 | // .rel[a].plt section. | |
| 1090 | if (InX::RelaPlt->getParent()->Live) { | |
| 1091 | addInSec(DT_JMPREL, InX::RelaPlt); | |
| 1092 | addSize(DT_PLTRELSZ, InX::RelaPlt->getParent()); | |
| 1103 | 1093 | switch (Config->EMachine) { |
| 1104 | 1094 | case EM_MIPS: |
| 1105 | add({DT_MIPS_PLTGOT, In<ELFT>::GotPlt}); | |
| 1095 | addInSec(DT_MIPS_PLTGOT, InX::GotPlt); | |
| 1106 | 1096 | break; |
| 1107 | 1097 | case EM_SPARCV9: |
| 1108 | add({DT_PLTGOT, In<ELFT>::Plt}); | |
| 1098 | addInSec(DT_PLTGOT, InX::Plt); | |
| 1109 | 1099 | break; |
| 1110 | 1100 | default: |
| 1111 | add({DT_PLTGOT, In<ELFT>::GotPlt}); | |
| 1101 | addInSec(DT_PLTGOT, InX::GotPlt); | |
| 1112 | 1102 | break; |
| 1113 | 1103 | } |
| 1114 | add({DT_PLTREL, uint64_t(Config->IsRela ? DT_RELA : DT_REL)}); | |
| 1104 | addInt(DT_PLTREL, Config->IsRela ? DT_RELA : DT_REL); | |
| 1115 | 1105 | } |
| 1116 | 1106 | |
| 1117 | add({DT_SYMTAB, InX::DynSymTab}); | |
| 1118 | add({DT_SYMENT, sizeof(Elf_Sym)}); | |
| 1119 | add({DT_STRTAB, InX::DynStrTab}); | |
| 1120 | add({DT_STRSZ, InX::DynStrTab->getSize()}); | |
| 1107 | addInSec(DT_SYMTAB, InX::DynSymTab); | |
| 1108 | addInt(DT_SYMENT, sizeof(Elf_Sym)); | |
| 1109 | addInSec(DT_STRTAB, InX::DynStrTab); | |
| 1110 | addInt(DT_STRSZ, InX::DynStrTab->getSize()); | |
| 1121 | 1111 | if (!Config->ZText) |
| 1122 | add({DT_TEXTREL, (uint64_t)0}); | |
| 1112 | addInt(DT_TEXTREL, 0); | |
| 1123 | 1113 | if (InX::GnuHashTab) |
| 1124 | add({DT_GNU_HASH, InX::GnuHashTab}); | |
| 1125 | if (In<ELFT>::HashTab) | |
| 1126 | add({DT_HASH, In<ELFT>::HashTab}); | |
| 1114 | addInSec(DT_GNU_HASH, InX::GnuHashTab); | |
| 1115 | if (InX::HashTab) | |
| 1116 | addInSec(DT_HASH, InX::HashTab); | |
| 1127 | 1117 | |
| 1128 | 1118 | if (Out::PreinitArray) { |
| 1129 | add({DT_PREINIT_ARRAY, Out::PreinitArray}); | |
| 1130 | add({DT_PREINIT_ARRAYSZ, Out::PreinitArray, Entry::SecSize}); | |
| 1119 | addOutSec(DT_PREINIT_ARRAY, Out::PreinitArray); | |
| 1120 | addSize(DT_PREINIT_ARRAYSZ, Out::PreinitArray); | |
| 1131 | 1121 | } |
| 1132 | 1122 | if (Out::InitArray) { |
| 1133 | add({DT_INIT_ARRAY, Out::InitArray}); | |
| 1134 | add({DT_INIT_ARRAYSZ, Out::InitArray, Entry::SecSize}); | |
| 1123 | addOutSec(DT_INIT_ARRAY, Out::InitArray); | |
| 1124 | addSize(DT_INIT_ARRAYSZ, Out::InitArray); | |
| 1135 | 1125 | } |
| 1136 | 1126 | if (Out::FiniArray) { |
| 1137 | add({DT_FINI_ARRAY, Out::FiniArray}); | |
| 1138 | add({DT_FINI_ARRAYSZ, Out::FiniArray, Entry::SecSize}); | |
| 1127 | addOutSec(DT_FINI_ARRAY, Out::FiniArray); | |
| 1128 | addSize(DT_FINI_ARRAYSZ, Out::FiniArray); | |
| 1139 | 1129 | } |
| 1140 | 1130 | |
| 1141 | if (SymbolBody *B = Symtab<ELFT>::X->findInCurrentDSO(Config->Init)) | |
| 1142 | add({DT_INIT, B}); | |
| 1143 | if (SymbolBody *B = Symtab<ELFT>::X->findInCurrentDSO(Config->Fini)) | |
| 1144 | add({DT_FINI, B}); | |
| 1131 | if (Symbol *B = Symtab->find(Config->Init)) | |
| 1132 | if (B->isDefined()) | |
| 1133 | addSym(DT_INIT, B); | |
| 1134 | if (Symbol *B = Symtab->find(Config->Fini)) | |
| 1135 | if (B->isDefined()) | |
| 1136 | addSym(DT_FINI, B); | |
| 1145 | 1137 | |
| 1146 | 1138 | bool HasVerNeed = In<ELFT>::VerNeed->getNeedNum() != 0; |
| 1147 | 1139 | if (HasVerNeed || In<ELFT>::VerDef) |
| 1148 | add({DT_VERSYM, In<ELFT>::VerSym}); | |
| 1140 | addInSec(DT_VERSYM, In<ELFT>::VerSym); | |
| 1149 | 1141 | if (In<ELFT>::VerDef) { |
| 1150 | add({DT_VERDEF, In<ELFT>::VerDef}); | |
| 1151 | add({DT_VERDEFNUM, getVerDefNum()}); | |
| 1142 | addInSec(DT_VERDEF, In<ELFT>::VerDef); | |
| 1143 | addInt(DT_VERDEFNUM, getVerDefNum()); | |
| 1152 | 1144 | } |
| 1153 | 1145 | if (HasVerNeed) { |
| 1154 | add({DT_VERNEED, In<ELFT>::VerNeed}); | |
| 1155 | add({DT_VERNEEDNUM, In<ELFT>::VerNeed->getNeedNum()}); | |
| 1146 | addInSec(DT_VERNEED, In<ELFT>::VerNeed); | |
| 1147 | addInt(DT_VERNEEDNUM, In<ELFT>::VerNeed->getNeedNum()); | |
| 1156 | 1148 | } |
| 1157 | 1149 | |
| 1158 | 1150 | if (Config->EMachine == EM_MIPS) { |
| 1159 | add({DT_MIPS_RLD_VERSION, 1}); | |
| 1160 | add({DT_MIPS_FLAGS, RHF_NOTPOT}); | |
| 1161 | add({DT_MIPS_BASE_ADDRESS, Config->ImageBase}); | |
| 1162 | add({DT_MIPS_SYMTABNO, InX::DynSymTab->getNumSymbols()}); | |
| 1163 | add({DT_MIPS_LOCAL_GOTNO, InX::MipsGot->getLocalEntriesNum()}); | |
| 1164 | if (const SymbolBody *B = InX::MipsGot->getFirstGlobalEntry()) | |
| 1165 | add({DT_MIPS_GOTSYM, B->DynsymIndex}); | |
| 1151 | addInt(DT_MIPS_RLD_VERSION, 1); | |
| 1152 | addInt(DT_MIPS_FLAGS, RHF_NOTPOT); | |
| 1153 | addInt(DT_MIPS_BASE_ADDRESS, Target->getImageBase()); | |
| 1154 | addInt(DT_MIPS_SYMTABNO, InX::DynSymTab->getNumSymbols()); | |
| 1155 | ||
| 1156 | add(DT_MIPS_LOCAL_GOTNO, [] { return InX::MipsGot->getLocalEntriesNum(); }); | |
| 1157 | ||
| 1158 | if (const Symbol *B = InX::MipsGot->getFirstGlobalEntry()) | |
| 1159 | addInt(DT_MIPS_GOTSYM, B->DynsymIndex); | |
| 1166 | 1160 | else |
| 1167 | add({DT_MIPS_GOTSYM, InX::DynSymTab->getNumSymbols()}); | |
| 1168 | add({DT_PLTGOT, InX::MipsGot}); | |
| 1161 | addInt(DT_MIPS_GOTSYM, InX::DynSymTab->getNumSymbols()); | |
| 1162 | addInSec(DT_PLTGOT, InX::MipsGot); | |
| 1169 | 1163 | if (InX::MipsRldMap) |
| 1170 | add({DT_MIPS_RLD_MAP, InX::MipsRldMap}); | |
| 1164 | addInSec(DT_MIPS_RLD_MAP, InX::MipsRldMap); | |
| 1171 | 1165 | } |
| 1172 | 1166 | |
| 1173 | getParent()->Link = this->Link; | |
| 1167 | addInt(DT_NULL, 0); | |
| 1174 | 1168 | |
| 1175 | // +1 for DT_NULL | |
| 1176 | this->Size = (Entries.size() + 1) * this->Entsize; | |
| 1169 | getParent()->Link = this->Link; | |
| 1170 | this->Size = Entries.size() * this->Entsize; | |
| 1177 | 1171 | } |
| 1178 | 1172 | |
| 1179 | 1173 | template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) { |
| 1180 | 1174 | auto *P = reinterpret_cast<Elf_Dyn *>(Buf); |
| 1181 | 1175 | |
| 1182 | for (const Entry &E : Entries) { | |
| 1183 | P->d_tag = E.Tag; | |
| 1184 | switch (E.Kind) { | |
| 1185 | case Entry::SecAddr: | |
| 1186 | P->d_un.d_ptr = E.OutSec->Addr; | |
| 1187 | break; | |
| 1188 | case Entry::InSecAddr: | |
| 1189 | P->d_un.d_ptr = E.InSec->getParent()->Addr + E.InSec->OutSecOff; | |
| 1190 | break; | |
| 1191 | case Entry::SecSize: | |
| 1192 | P->d_un.d_val = E.OutSec->Size; | |
| 1193 | break; | |
| 1194 | case Entry::SymAddr: | |
| 1195 | P->d_un.d_ptr = E.Sym->getVA(); | |
| 1196 | break; | |
| 1197 | case Entry::PlainInt: | |
| 1198 | P->d_un.d_val = E.Val; | |
| 1199 | break; | |
| 1200 | } | |
| 1176 | for (std::pair<int32_t, std::function<uint64_t()>> &KV : Entries) { | |
| 1177 | P->d_tag = KV.first; | |
| 1178 | P->d_un.d_val = KV.second(); | |
| 1201 | 1179 | ++P; |
| 1202 | 1180 | } |
| 1203 | 1181 | } |
| ... | ... | @@ -1218,21 +1196,57 @@ uint32_t DynamicReloc::getSymIndex() const { |
| 1218 | 1196 | return 0; |
| 1219 | 1197 | } |
| 1220 | 1198 | |
| 1221 | template <class ELFT> | |
| 1222 | RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort) | |
| 1223 | : SyntheticSection(SHF_ALLOC, Config->IsRela ? SHT_RELA : SHT_REL, | |
| 1224 | Config->Wordsize, Name), | |
| 1225 | Sort(Sort) { | |
| 1226 | this->Entsize = Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); | |
| 1227 | } | |
| 1199 | RelocationBaseSection::RelocationBaseSection(StringRef Name, uint32_t Type, | |
| 1200 | int32_t DynamicTag, | |
| 1201 | int32_t SizeDynamicTag) | |
| 1202 | : SyntheticSection(SHF_ALLOC, Type, Config->Wordsize, Name), | |
| 1203 | DynamicTag(DynamicTag), SizeDynamicTag(SizeDynamicTag) {} | |
| 1228 | 1204 | |
| 1229 | template <class ELFT> | |
| 1230 | void RelocationSection<ELFT>::addReloc(const DynamicReloc &Reloc) { | |
| 1205 | void RelocationBaseSection::addReloc(const DynamicReloc &Reloc) { | |
| 1231 | 1206 | if (Reloc.Type == Target->RelativeRel) |
| 1232 | 1207 | ++NumRelativeRelocs; |
| 1233 | 1208 | Relocs.push_back(Reloc); |
| 1234 | 1209 | } |
| 1235 | 1210 | |
| 1211 | void RelocationBaseSection::finalizeContents() { | |
| 1212 | // If all relocations are R_*_RELATIVE they don't refer to any | |
| 1213 | // dynamic symbol and we don't need a dynamic symbol table. If that | |
| 1214 | // is the case, just use 0 as the link. | |
| 1215 | Link = InX::DynSymTab ? InX::DynSymTab->getParent()->SectionIndex : 0; | |
| 1216 | ||
| 1217 | // Set required output section properties. | |
| 1218 | getParent()->Link = Link; | |
| 1219 | } | |
| 1220 | ||
| 1221 | template <class ELFT> | |
| 1222 | static void encodeDynamicReloc(typename ELFT::Rela *P, | |
| 1223 | const DynamicReloc &Rel) { | |
| 1224 | if (Config->IsRela) | |
| 1225 | P->r_addend = Rel.getAddend(); | |
| 1226 | 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); | |
| 1239 | } | |
| 1240 | ||
| 1241 | template <class ELFT> | |
| 1242 | RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort) | |
| 1243 | : RelocationBaseSection(Name, Config->IsRela ? SHT_RELA : SHT_REL, | |
| 1244 | Config->IsRela ? DT_RELA : DT_REL, | |
| 1245 | Config->IsRela ? DT_RELASZ : DT_RELSZ), | |
| 1246 | Sort(Sort) { | |
| 1247 | this->Entsize = Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); | |
| 1248 | } | |
| 1249 | ||
| 1236 | 1250 | template <class ELFT, class RelTy> |
| 1237 | 1251 | static bool compRelocations(const RelTy &A, const RelTy &B) { |
| 1238 | 1252 | bool AIsRel = A.getType(Config->IsMips64EL) == Target->RelativeRel; |
| ... | ... | @@ -1246,18 +1260,8 @@ static bool compRelocations(const RelTy &A, const RelTy &B) { |
| 1246 | 1260 | template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { |
| 1247 | 1261 | uint8_t *BufBegin = Buf; |
| 1248 | 1262 | for (const DynamicReloc &Rel : Relocs) { |
| 1249 | auto *P = reinterpret_cast<Elf_Rela *>(Buf); | |
| 1263 | encodeDynamicReloc<ELFT>(reinterpret_cast<Elf_Rela *>(Buf), Rel); | |
| 1250 | 1264 | Buf += Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); |
| 1251 | ||
| 1252 | if (Config->IsRela) | |
| 1253 | P->r_addend = Rel.getAddend(); | |
| 1254 | P->r_offset = Rel.getOffset(); | |
| 1255 | if (Config->EMachine == EM_MIPS && Rel.getInputSec() == InX::MipsGot) | |
| 1256 | // Dynamic relocation against MIPS GOT section make deal TLS entries | |
| 1257 | // allocated in the end of the GOT. We need to adjust the offset to take | |
| 1258 | // in account 'local' and 'global' GOT entries. | |
| 1259 | P->r_offset += InX::MipsGot->getTlsOffset(); | |
| 1260 | P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->IsMips64EL); | |
| 1261 | 1265 | } |
| 1262 | 1266 | |
| 1263 | 1267 | if (Sort) { |
| ... | ... | @@ -1275,12 +1279,192 @@ template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() { |
| 1275 | 1279 | return this->Entsize * Relocs.size(); |
| 1276 | 1280 | } |
| 1277 | 1281 | |
| 1278 | template <class ELFT> void RelocationSection<ELFT>::finalizeContents() { | |
| 1279 | this->Link = InX::DynSymTab ? InX::DynSymTab->getParent()->SectionIndex | |
| 1280 | : InX::SymTab->getParent()->SectionIndex; | |
| 1282 | template <class ELFT> | |
| 1283 | AndroidPackedRelocationSection<ELFT>::AndroidPackedRelocationSection( | |
| 1284 | StringRef Name) | |
| 1285 | : RelocationBaseSection( | |
| 1286 | Name, Config->IsRela ? SHT_ANDROID_RELA : SHT_ANDROID_REL, | |
| 1287 | Config->IsRela ? DT_ANDROID_RELA : DT_ANDROID_REL, | |
| 1288 | Config->IsRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ) { | |
| 1289 | this->Entsize = 1; | |
| 1290 | } | |
| 1281 | 1291 | |
| 1282 | // Set required output section properties. | |
| 1283 | getParent()->Link = this->Link; | |
| 1292 | template <class ELFT> | |
| 1293 | bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() { | |
| 1294 | // This function computes the contents of an Android-format packed relocation | |
| 1295 | // section. | |
| 1296 | // | |
| 1297 | // This format compresses relocations by using relocation groups to factor out | |
| 1298 | // fields that are common between relocations and storing deltas from previous | |
| 1299 | // relocations in SLEB128 format (which has a short representation for small | |
| 1300 | // numbers). A good example of a relocation type with common fields is | |
| 1301 | // R_*_RELATIVE, which is normally used to represent function pointers in | |
| 1302 | // vtables. In the REL format, each relative relocation has the same r_info | |
| 1303 | // field, and is only different from other relative relocations in terms of | |
| 1304 | // the r_offset field. By sorting relocations by offset, grouping them by | |
| 1305 | // r_info and representing each relocation with only the delta from the | |
| 1306 | // previous offset, each 8-byte relocation can be compressed to as little as 1 | |
| 1307 | // byte (or less with run-length encoding). This relocation packer was able to | |
| 1308 | // reduce the size of the relocation section in an Android Chromium DSO from | |
| 1309 | // 2,911,184 bytes to 174,693 bytes, or 6% of the original size. | |
| 1310 | // | |
| 1311 | // A relocation section consists of a header containing the literal bytes | |
| 1312 | // 'APS2' followed by a sequence of SLEB128-encoded integers. The first two | |
| 1313 | // elements are the total number of relocations in the section and an initial | |
| 1314 | // r_offset value. The remaining elements define a sequence of relocation | |
| 1315 | // groups. Each relocation group starts with a header consisting of the | |
| 1316 | // following elements: | |
| 1317 | // | |
| 1318 | // - the number of relocations in the relocation group | |
| 1319 | // - flags for the relocation group | |
| 1320 | // - (if RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG is set) the r_offset delta | |
| 1321 | // for each relocation in the group. | |
| 1322 | // - (if RELOCATION_GROUPED_BY_INFO_FLAG is set) the value of the r_info | |
| 1323 | // field for each relocation in the group. | |
| 1324 | // - (if RELOCATION_GROUP_HAS_ADDEND_FLAG and | |
| 1325 | // RELOCATION_GROUPED_BY_ADDEND_FLAG are set) the r_addend delta for | |
| 1326 | // each relocation in the group. | |
| 1327 | // | |
| 1328 | // Following the relocation group header are descriptions of each of the | |
| 1329 | // relocations in the group. They consist of the following elements: | |
| 1330 | // | |
| 1331 | // - (if RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG is not set) the r_offset | |
| 1332 | // delta for this relocation. | |
| 1333 | // - (if RELOCATION_GROUPED_BY_INFO_FLAG is not set) the value of the r_info | |
| 1334 | // field for this relocation. | |
| 1335 | // - (if RELOCATION_GROUP_HAS_ADDEND_FLAG is set and | |
| 1336 | // RELOCATION_GROUPED_BY_ADDEND_FLAG is not set) the r_addend delta for | |
| 1337 | // this relocation. | |
| 1338 | ||
| 1339 | size_t OldSize = RelocData.size(); | |
| 1340 | ||
| 1341 | RelocData = {'A', 'P', 'S', '2'}; | |
| 1342 | raw_svector_ostream OS(RelocData); | |
| 1343 | auto Add = [&](int64_t V) { encodeSLEB128(V, OS); }; | |
| 1344 | ||
| 1345 | // The format header includes the number of relocations and the initial | |
| 1346 | // offset (we set this to zero because the first relocation group will | |
| 1347 | // perform the initial adjustment). | |
| 1348 | Add(Relocs.size()); | |
| 1349 | Add(0); | |
| 1350 | ||
| 1351 | std::vector<Elf_Rela> Relatives, NonRelatives; | |
| 1352 | ||
| 1353 | for (const DynamicReloc &Rel : Relocs) { | |
| 1354 | Elf_Rela R; | |
| 1355 | encodeDynamicReloc<ELFT>(&R, Rel); | |
| 1356 | ||
| 1357 | if (R.getType(Config->IsMips64EL) == Target->RelativeRel) | |
| 1358 | Relatives.push_back(R); | |
| 1359 | else | |
| 1360 | NonRelatives.push_back(R); | |
| 1361 | } | |
| 1362 | ||
| 1363 | std::sort(Relatives.begin(), Relatives.end(), | |
| 1364 | [](const Elf_Rel &A, const Elf_Rel &B) { | |
| 1365 | return A.r_offset < B.r_offset; | |
| 1366 | }); | |
| 1367 | ||
| 1368 | // Try to find groups of relative relocations which are spaced one word | |
| 1369 | // apart from one another. These generally correspond to vtable entries. The | |
| 1370 | // format allows these groups to be encoded using a sort of run-length | |
| 1371 | // encoding, but each group will cost 7 bytes in addition to the offset from | |
| 1372 | // the previous group, so it is only profitable to do this for groups of | |
| 1373 | // size 8 or larger. | |
| 1374 | std::vector<Elf_Rela> UngroupedRelatives; | |
| 1375 | std::vector<std::vector<Elf_Rela>> RelativeGroups; | |
| 1376 | for (auto I = Relatives.begin(), E = Relatives.end(); I != E;) { | |
| 1377 | std::vector<Elf_Rela> Group; | |
| 1378 | do { | |
| 1379 | Group.push_back(*I++); | |
| 1380 | } while (I != E && (I - 1)->r_offset + Config->Wordsize == I->r_offset); | |
| 1381 | ||
| 1382 | if (Group.size() < 8) | |
| 1383 | UngroupedRelatives.insert(UngroupedRelatives.end(), Group.begin(), | |
| 1384 | Group.end()); | |
| 1385 | else | |
| 1386 | RelativeGroups.emplace_back(std::move(Group)); | |
| 1387 | } | |
| 1388 | ||
| 1389 | unsigned HasAddendIfRela = | |
| 1390 | Config->IsRela ? RELOCATION_GROUP_HAS_ADDEND_FLAG : 0; | |
| 1391 | ||
| 1392 | uint64_t Offset = 0; | |
| 1393 | uint64_t Addend = 0; | |
| 1394 | ||
| 1395 | // Emit the run-length encoding for the groups of adjacent relative | |
| 1396 | // relocations. Each group is represented using two groups in the packed | |
| 1397 | // format. The first is used to set the current offset to the start of the | |
| 1398 | // group (and also encodes the first relocation), and the second encodes the | |
| 1399 | // remaining relocations. | |
| 1400 | for (std::vector<Elf_Rela> &G : RelativeGroups) { | |
| 1401 | // The first relocation in the group. | |
| 1402 | Add(1); | |
| 1403 | Add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG | | |
| 1404 | RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela); | |
| 1405 | Add(G[0].r_offset - Offset); | |
| 1406 | Add(Target->RelativeRel); | |
| 1407 | if (Config->IsRela) { | |
| 1408 | Add(G[0].r_addend - Addend); | |
| 1409 | Addend = G[0].r_addend; | |
| 1410 | } | |
| 1411 | ||
| 1412 | // The remaining relocations. | |
| 1413 | Add(G.size() - 1); | |
| 1414 | Add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG | | |
| 1415 | RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela); | |
| 1416 | Add(Config->Wordsize); | |
| 1417 | Add(Target->RelativeRel); | |
| 1418 | if (Config->IsRela) { | |
| 1419 | for (auto I = G.begin() + 1, E = G.end(); I != E; ++I) { | |
| 1420 | Add(I->r_addend - Addend); | |
| 1421 | Addend = I->r_addend; | |
| 1422 | } | |
| 1423 | } | |
| 1424 | ||
| 1425 | Offset = G.back().r_offset; | |
| 1426 | } | |
| 1427 | ||
| 1428 | // Now the ungrouped relatives. | |
| 1429 | if (!UngroupedRelatives.empty()) { | |
| 1430 | Add(UngroupedRelatives.size()); | |
| 1431 | Add(RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela); | |
| 1432 | Add(Target->RelativeRel); | |
| 1433 | for (Elf_Rela &R : UngroupedRelatives) { | |
| 1434 | Add(R.r_offset - Offset); | |
| 1435 | Offset = R.r_offset; | |
| 1436 | if (Config->IsRela) { | |
| 1437 | Add(R.r_addend - Addend); | |
| 1438 | Addend = R.r_addend; | |
| 1439 | } | |
| 1440 | } | |
| 1441 | } | |
| 1442 | ||
| 1443 | // Finally the non-relative relocations. | |
| 1444 | std::sort(NonRelatives.begin(), NonRelatives.end(), | |
| 1445 | [](const Elf_Rela &A, const Elf_Rela &B) { | |
| 1446 | return A.r_offset < B.r_offset; | |
| 1447 | }); | |
| 1448 | if (!NonRelatives.empty()) { | |
| 1449 | Add(NonRelatives.size()); | |
| 1450 | Add(HasAddendIfRela); | |
| 1451 | for (Elf_Rela &R : NonRelatives) { | |
| 1452 | Add(R.r_offset - Offset); | |
| 1453 | Offset = R.r_offset; | |
| 1454 | Add(R.r_info); | |
| 1455 | if (Config->IsRela) { | |
| 1456 | Add(R.r_addend - Addend); | |
| 1457 | Addend = R.r_addend; | |
| 1458 | } | |
| 1459 | } | |
| 1460 | } | |
| 1461 | ||
| 1462 | // Returns whether the section size changed. We need to keep recomputing both | |
| 1463 | // section layout and the contents of this section until the size converges | |
| 1464 | // because changing this section's size can affect section layout, which in | |
| 1465 | // turn can affect the sizes of the LEB-encoded integers stored in this | |
| 1466 | // section. | |
| 1467 | return RelocData.size() != OldSize; | |
| 1284 | 1468 | } |
| 1285 | 1469 | |
| 1286 | 1470 | SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &StrTabSec) |
| ... | ... | @@ -1299,17 +1483,13 @@ static bool sortMipsSymbols(const SymbolTableEntry &L, |
| 1299 | 1483 | const SymbolTableEntry &R) { |
| 1300 | 1484 | // Sort entries related to non-local preemptible symbols by GOT indexes. |
| 1301 | 1485 | // All other entries go to the first part of GOT in arbitrary order. |
| 1302 | bool LIsInLocalGot = !L.Symbol->IsInGlobalMipsGot; | |
| 1303 | bool RIsInLocalGot = !R.Symbol->IsInGlobalMipsGot; | |
| 1486 | bool LIsInLocalGot = !L.Sym->IsInGlobalMipsGot; | |
| 1487 | bool RIsInLocalGot = !R.Sym->IsInGlobalMipsGot; | |
| 1304 | 1488 | if (LIsInLocalGot || RIsInLocalGot) |
| 1305 | 1489 | return !RIsInLocalGot; |
| 1306 | return L.Symbol->GotIndex < R.Symbol->GotIndex; | |
| 1490 | return L.Sym->GotIndex < R.Sym->GotIndex; | |
| 1307 | 1491 | } |
| 1308 | 1492 | |
| 1309 | // Finalize a symbol table. The ELF spec requires that all local | |
| 1310 | // symbols precede global symbols, so we sort symbol entries in this | |
| 1311 | // function. (For .dynsym, we don't do that because symbols for | |
| 1312 | // dynamic linking are inherently all globals.) | |
| 1313 | 1493 | void SymbolTableBaseSection::finalizeContents() { |
| 1314 | 1494 | getParent()->Link = StrTabSec.getParent()->SectionIndex; |
| 1315 | 1495 | |
| ... | ... | @@ -1328,26 +1508,27 @@ void SymbolTableBaseSection::finalizeContents() { |
| 1328 | 1508 | } |
| 1329 | 1509 | |
| 1330 | 1510 | size_t I = 0; |
| 1331 | for (const SymbolTableEntry &S : Symbols) | |
| 1332 | S.Symbol->DynsymIndex = ++I; | |
| 1511 | for (const SymbolTableEntry &S : Symbols) S.Sym->DynsymIndex = ++I; | |
| 1333 | 1512 | return; |
| 1334 | 1513 | } |
| 1335 | 1514 | } |
| 1336 | 1515 | |
| 1516 | // 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 | |
| 1518 | // symbols for dynamic linking are inherently all globals.) | |
| 1337 | 1519 | void SymbolTableBaseSection::postThunkContents() { |
| 1338 | 1520 | if (this->Type == SHT_DYNSYM) |
| 1339 | 1521 | return; |
| 1340 | 1522 | // move all local symbols before global symbols. |
| 1341 | 1523 | auto It = std::stable_partition( |
| 1342 | 1524 | Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) { |
| 1343 | return S.Symbol->isLocal() || | |
| 1344 | S.Symbol->symbol()->computeBinding() == STB_LOCAL; | |
| 1525 | return S.Sym->isLocal() || S.Sym->computeBinding() == STB_LOCAL; | |
| 1345 | 1526 | }); |
| 1346 | 1527 | size_t NumLocals = It - Symbols.begin(); |
| 1347 | 1528 | getParent()->Info = NumLocals + 1; |
| 1348 | 1529 | } |
| 1349 | 1530 | |
| 1350 | void SymbolTableBaseSection::addSymbol(SymbolBody *B) { | |
| 1531 | void SymbolTableBaseSection::addSymbol(Symbol *B) { | |
| 1351 | 1532 | // Adding a local symbol to a .dynsym is a bug. |
| 1352 | 1533 | assert(this->Type != SHT_DYNSYM || !B->isLocal()); |
| 1353 | 1534 | |
| ... | ... | @@ -1355,19 +1536,25 @@ void SymbolTableBaseSection::addSymbol(SymbolBody *B) { |
| 1355 | 1536 | Symbols.push_back({B, StrTabSec.addString(B->getName(), HashIt)}); |
| 1356 | 1537 | } |
| 1357 | 1538 | |
| 1358 | size_t SymbolTableBaseSection::getSymbolIndex(SymbolBody *Body) { | |
| 1359 | auto I = llvm::find_if(Symbols, [&](const SymbolTableEntry &E) { | |
| 1360 | if (E.Symbol == Body) | |
| 1361 | return true; | |
| 1362 | // This is used for -r, so we have to handle multiple section | |
| 1363 | // symbols being combined. | |
| 1364 | if (Body->Type == STT_SECTION && E.Symbol->Type == STT_SECTION) | |
| 1365 | return Body->getOutputSection() == E.Symbol->getOutputSection(); | |
| 1366 | return false; | |
| 1539 | size_t SymbolTableBaseSection::getSymbolIndex(Symbol *Sym) { | |
| 1540 | // Initializes symbol lookup tables lazily. This is used only | |
| 1541 | // for -r or -emit-relocs. | |
| 1542 | llvm::call_once(OnceFlag, [&] { | |
| 1543 | SymbolIndexMap.reserve(Symbols.size()); | |
| 1544 | size_t I = 0; | |
| 1545 | for (const SymbolTableEntry &E : Symbols) { | |
| 1546 | if (E.Sym->Type == STT_SECTION) | |
| 1547 | SectionIndexMap[E.Sym->getOutputSection()] = ++I; | |
| 1548 | else | |
| 1549 | SymbolIndexMap[E.Sym] = ++I; | |
| 1550 | } | |
| 1367 | 1551 | }); |
| 1368 | if (I == Symbols.end()) | |
| 1369 | return 0; | |
| 1370 | return I - Symbols.begin() + 1; | |
| 1552 | ||
| 1553 | // Section symbols are mapped based on their output sections | |
| 1554 | // to maintain their semantics. | |
| 1555 | if (Sym->Type == STT_SECTION) | |
| 1556 | return SectionIndexMap.lookup(Sym->getOutputSection()); | |
| 1557 | return SymbolIndexMap.lookup(Sym); | |
| 1371 | 1558 | } |
| 1372 | 1559 | |
| 1373 | 1560 | template <class ELFT> |
| ... | ... | @@ -1379,46 +1566,56 @@ SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &StrTabSec) |
| 1379 | 1566 | // Write the internal symbol table contents to the output symbol table. |
| 1380 | 1567 | template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { |
| 1381 | 1568 | // The first entry is a null entry as per the ELF spec. |
| 1569 | memset(Buf, 0, sizeof(Elf_Sym)); | |
| 1382 | 1570 | Buf += sizeof(Elf_Sym); |
| 1383 | 1571 | |
| 1384 | 1572 | auto *ESym = reinterpret_cast<Elf_Sym *>(Buf); |
| 1385 | 1573 | |
| 1386 | 1574 | for (SymbolTableEntry &Ent : Symbols) { |
| 1387 | SymbolBody *Body = Ent.Symbol; | |
| 1575 | Symbol *Sym = Ent.Sym; | |
| 1388 | 1576 | |
| 1389 | 1577 | // Set st_info and st_other. |
| 1390 | if (Body->isLocal()) { | |
| 1391 | ESym->setBindingAndType(STB_LOCAL, Body->Type); | |
| 1578 | ESym->st_other = 0; | |
| 1579 | if (Sym->isLocal()) { | |
| 1580 | ESym->setBindingAndType(STB_LOCAL, Sym->Type); | |
| 1392 | 1581 | } else { |
| 1393 | ESym->setBindingAndType(Body->symbol()->computeBinding(), Body->Type); | |
| 1394 | ESym->setVisibility(Body->symbol()->Visibility); | |
| 1582 | ESym->setBindingAndType(Sym->computeBinding(), Sym->Type); | |
| 1583 | ESym->setVisibility(Sym->Visibility); | |
| 1395 | 1584 | } |
| 1396 | 1585 | |
| 1397 | 1586 | ESym->st_name = Ent.StrTabOffset; |
| 1398 | 1587 | |
| 1399 | 1588 | // Set a section index. |
| 1400 | if (const OutputSection *OutSec = Body->getOutputSection()) | |
| 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()) | |
| 1401 | 1596 | ESym->st_shndx = OutSec->SectionIndex; |
| 1402 | else if (isa<DefinedRegular>(Body)) | |
| 1597 | else if (isa<Defined>(Sym)) | |
| 1403 | 1598 | ESym->st_shndx = SHN_ABS; |
| 1404 | else if (isa<DefinedCommon>(Body)) | |
| 1405 | ESym->st_shndx = SHN_COMMON; | |
| 1599 | else | |
| 1600 | ESym->st_shndx = SHN_UNDEF; | |
| 1406 | 1601 | |
| 1407 | 1602 | // Copy symbol size if it is a defined symbol. st_size is not significant |
| 1408 | 1603 | // for undefined symbols, so whether copying it or not is up to us if that's |
| 1409 | 1604 | // the case. We'll leave it as zero because by not setting a value, we can |
| 1410 | 1605 | // get the exact same outputs for two sets of input files that differ only |
| 1411 | 1606 | // in undefined symbol size in DSOs. |
| 1412 | if (ESym->st_shndx != SHN_UNDEF) | |
| 1413 | ESym->st_size = Body->getSize<ELFT>(); | |
| 1607 | if (ESym->st_shndx == SHN_UNDEF) | |
| 1608 | ESym->st_size = 0; | |
| 1609 | else | |
| 1610 | ESym->st_size = Sym->getSize(); | |
| 1414 | 1611 | |
| 1415 | 1612 | // st_value is usually an address of a symbol, but that has a |
| 1416 | 1613 | // special meaining for uninstantiated common symbols (this can |
| 1417 | 1614 | // occur if -r is given). |
| 1418 | if (!Config->DefineCommon && isa<DefinedCommon>(Body)) | |
| 1419 | ESym->st_value = cast<DefinedCommon>(Body)->Alignment; | |
| 1615 | if (CommonSec) | |
| 1616 | ESym->st_value = CommonSec->Alignment; | |
| 1420 | 1617 | else |
| 1421 | ESym->st_value = Body->getVA(); | |
| 1618 | ESym->st_value = Sym->getVA(); | |
| 1422 | 1619 | |
| 1423 | 1620 | ++ESym; |
| 1424 | 1621 | } |
| ... | ... | @@ -1431,13 +1628,22 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { |
| 1431 | 1628 | auto *ESym = reinterpret_cast<Elf_Sym *>(Buf); |
| 1432 | 1629 | |
| 1433 | 1630 | for (SymbolTableEntry &Ent : Symbols) { |
| 1434 | SymbolBody *Body = Ent.Symbol; | |
| 1435 | if (Body->isInPlt() && Body->NeedsPltAddr) | |
| 1631 | Symbol *Sym = Ent.Sym; | |
| 1632 | if (Sym->isInPlt() && Sym->NeedsPltAddr) | |
| 1436 | 1633 | ESym->st_other |= STO_MIPS_PLT; |
| 1437 | ||
| 1634 | if (isMicroMips()) { | |
| 1635 | // Set STO_MIPS_MICROMIPS flag and less-significant bit for | |
| 1636 | // defined microMIPS symbols and shared symbols with PLT record. | |
| 1637 | if ((Sym->isDefined() && (Sym->StOther & STO_MIPS_MICROMIPS)) || | |
| 1638 | (Sym->isShared() && Sym->NeedsPltAddr)) { | |
| 1639 | if (StrTabSec.isDynamic()) | |
| 1640 | ESym->st_value |= 1; | |
| 1641 | ESym->st_other |= STO_MIPS_MICROMIPS; | |
| 1642 | } | |
| 1643 | } | |
| 1438 | 1644 | if (Config->Relocatable) |
| 1439 | if (auto *D = dyn_cast<DefinedRegular>(Body)) | |
| 1440 | if (D->isMipsPIC<ELFT>()) | |
| 1645 | if (auto *D = dyn_cast<Defined>(Sym)) | |
| 1646 | if (isMipsPIC<ELFT>(D)) | |
| 1441 | 1647 | ESym->st_other |= STO_MIPS_PIC; |
| 1442 | 1648 | ++ESym; |
| 1443 | 1649 | } |
| ... | ... | @@ -1496,12 +1702,16 @@ void GnuHashTableSection::finalizeContents() { |
| 1496 | 1702 | } |
| 1497 | 1703 | |
| 1498 | 1704 | void GnuHashTableSection::writeTo(uint8_t *Buf) { |
| 1705 | // The output buffer is not guaranteed to be zero-cleared because we pre- | |
| 1706 | // fill executable sections with trap instructions. This is a precaution | |
| 1707 | // for that case, which happens only when -no-rosegment is given. | |
| 1708 | memset(Buf, 0, Size); | |
| 1709 | ||
| 1499 | 1710 | // Write a header. |
| 1500 | write32(Buf, NBuckets, Config->Endianness); | |
| 1501 | write32(Buf + 4, InX::DynSymTab->getNumSymbols() - Symbols.size(), | |
| 1502 | Config->Endianness); | |
| 1503 | write32(Buf + 8, MaskWords, Config->Endianness); | |
| 1504 | write32(Buf + 12, getShift2(), Config->Endianness); | |
| 1711 | write32(Buf, NBuckets); | |
| 1712 | write32(Buf + 4, InX::DynSymTab->getNumSymbols() - Symbols.size()); | |
| 1713 | write32(Buf + 8, MaskWords); | |
| 1714 | write32(Buf + 12, getShift2()); | |
| 1505 | 1715 | Buf += 16; |
| 1506 | 1716 | |
| 1507 | 1717 | // Write a bloom filter and a hash table. |
| ... | ... | @@ -1529,29 +1739,24 @@ void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) { |
| 1529 | 1739 | } |
| 1530 | 1740 | |
| 1531 | 1741 | void GnuHashTableSection::writeHashTable(uint8_t *Buf) { |
| 1532 | // Group symbols by hash value. | |
| 1533 | std::vector<std::vector<Entry>> Syms(NBuckets); | |
| 1534 | for (const Entry &Ent : Symbols) | |
| 1535 | Syms[Ent.Hash % NBuckets].push_back(Ent); | |
| 1536 | ||
| 1537 | // Write hash buckets. Hash buckets contain indices in the following | |
| 1538 | // hash value table. | |
| 1539 | 1742 | uint32_t *Buckets = reinterpret_cast<uint32_t *>(Buf); |
| 1540 | for (size_t I = 0; I < NBuckets; ++I) | |
| 1541 | if (!Syms[I].empty()) | |
| 1542 | write32(Buckets + I, Syms[I][0].Body->DynsymIndex, Config->Endianness); | |
| 1543 | ||
| 1544 | // Write a hash value table. It represents a sequence of chains that | |
| 1545 | // share the same hash modulo value. The last element of each chain | |
| 1546 | // is terminated by LSB 1. | |
| 1743 | uint32_t OldBucket = -1; | |
| 1547 | 1744 | uint32_t *Values = Buckets + NBuckets; |
| 1548 | size_t I = 0; | |
| 1549 | for (std::vector<Entry> &Vec : Syms) { | |
| 1550 | if (Vec.empty()) | |
| 1745 | for (auto I = Symbols.begin(), E = Symbols.end(); I != E; ++I) { | |
| 1746 | // Write a hash value. It represents a sequence of chains that share the | |
| 1747 | // same hash modulo value. The last element of each chain is terminated by | |
| 1748 | // LSB 1. | |
| 1749 | uint32_t Hash = I->Hash; | |
| 1750 | bool IsLastInChain = (I + 1) == E || I->BucketIdx != (I + 1)->BucketIdx; | |
| 1751 | Hash = IsLastInChain ? Hash | 1 : Hash & ~1; | |
| 1752 | write32(Values++, Hash); | |
| 1753 | ||
| 1754 | if (I->BucketIdx == OldBucket) | |
| 1551 | 1755 | continue; |
| 1552 | for (const Entry &Ent : makeArrayRef(Vec).drop_back()) | |
| 1553 | write32(Values + I++, Ent.Hash & ~1, Config->Endianness); | |
| 1554 | write32(Values + I++, Vec.back().Hash | 1, Config->Endianness); | |
| 1756 | // Write a hash bucket. Hash buckets contain indices in the following hash | |
| 1757 | // value table. | |
| 1758 | write32(Buckets + I->BucketIdx, I->Sym->DynsymIndex); | |
| 1759 | OldBucket = I->BucketIdx; | |
| 1555 | 1760 | } |
| 1556 | 1761 | } |
| 1557 | 1762 | |
| ... | ... | @@ -1562,22 +1767,6 @@ static uint32_t hashGnu(StringRef Name) { |
| 1562 | 1767 | return H; |
| 1563 | 1768 | } |
| 1564 | 1769 | |
| 1565 | // Returns a number of hash buckets to accomodate given number of elements. | |
| 1566 | // We want to choose a moderate number that is not too small (which | |
| 1567 | // causes too many hash collisions) and not too large (which wastes | |
| 1568 | // disk space.) | |
| 1569 | // | |
| 1570 | // We return a prime number because it (is believed to) achieve good | |
| 1571 | // hash distribution. | |
| 1572 | static size_t getBucketSize(size_t NumSymbols) { | |
| 1573 | // List of largest prime numbers that are not greater than 2^n + 1. | |
| 1574 | for (size_t N : {131071, 65521, 32749, 16381, 8191, 4093, 2039, 1021, 509, | |
| 1575 | 251, 127, 61, 31, 13, 7, 3, 1}) | |
| 1576 | if (N <= NumSymbols) | |
| 1577 | return N; | |
| 1578 | return 0; | |
| 1579 | } | |
| 1580 | ||
| 1581 | 1770 | // Add symbols to this symbol hash table. Note that this function |
| 1582 | 1771 | // destructively sort a given vector -- which is needed because |
| 1583 | 1772 | // GNU-style hash table places some sorting requirements. |
| ... | ... | @@ -1586,66 +1775,73 @@ void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &V) { |
| 1586 | 1775 | // its type correctly. |
| 1587 | 1776 | std::vector<SymbolTableEntry>::iterator Mid = |
| 1588 | 1777 | std::stable_partition(V.begin(), V.end(), [](const SymbolTableEntry &S) { |
| 1589 | return S.Symbol->isUndefined(); | |
| 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(); | |
| 1590 | 1783 | }); |
| 1591 | 1784 | if (Mid == V.end()) |
| 1592 | 1785 | return; |
| 1593 | 1786 | |
| 1787 | // 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. | |
| 1789 | // Since the integer comparison is quite fast, we believe we can make | |
| 1790 | // the load factor even larger. 4 is just a conservative choice. | |
| 1791 | NBuckets = std::max<size_t>((V.end() - Mid) / 4, 1); | |
| 1792 | ||
| 1594 | 1793 | for (SymbolTableEntry &Ent : llvm::make_range(Mid, V.end())) { |
| 1595 | SymbolBody *B = Ent.Symbol; | |
| 1596 | Symbols.push_back({B, Ent.StrTabOffset, hashGnu(B->getName())}); | |
| 1794 | Symbol *B = Ent.Sym; | |
| 1795 | uint32_t Hash = hashGnu(B->getName()); | |
| 1796 | uint32_t BucketIdx = Hash % NBuckets; | |
| 1797 | Symbols.push_back({B, Ent.StrTabOffset, Hash, BucketIdx}); | |
| 1597 | 1798 | } |
| 1598 | 1799 | |
| 1599 | NBuckets = getBucketSize(Symbols.size()); | |
| 1600 | std::stable_sort(Symbols.begin(), Symbols.end(), | |
| 1601 | [&](const Entry &L, const Entry &R) { | |
| 1602 | return L.Hash % NBuckets < R.Hash % NBuckets; | |
| 1603 | }); | |
| 1800 | std::stable_sort( | |
| 1801 | Symbols.begin(), Symbols.end(), | |
| 1802 | [](const Entry &L, const Entry &R) { return L.BucketIdx < R.BucketIdx; }); | |
| 1604 | 1803 | |
| 1605 | 1804 | V.erase(Mid, V.end()); |
| 1606 | 1805 | for (const Entry &Ent : Symbols) |
| 1607 | V.push_back({Ent.Body, Ent.StrTabOffset}); | |
| 1806 | V.push_back({Ent.Sym, Ent.StrTabOffset}); | |
| 1608 | 1807 | } |
| 1609 | 1808 | |
| 1610 | template <class ELFT> | |
| 1611 | HashTableSection<ELFT>::HashTableSection() | |
| 1809 | HashTableSection::HashTableSection() | |
| 1612 | 1810 | : SyntheticSection(SHF_ALLOC, SHT_HASH, 4, ".hash") { |
| 1613 | 1811 | this->Entsize = 4; |
| 1614 | 1812 | } |
| 1615 | 1813 | |
| 1616 | template <class ELFT> void HashTableSection<ELFT>::finalizeContents() { | |
| 1814 | void HashTableSection::finalizeContents() { | |
| 1617 | 1815 | getParent()->Link = InX::DynSymTab->getParent()->SectionIndex; |
| 1618 | 1816 | |
| 1619 | 1817 | unsigned NumEntries = 2; // nbucket and nchain. |
| 1620 | 1818 | NumEntries += InX::DynSymTab->getNumSymbols(); // The chain entries. |
| 1621 | 1819 | |
| 1622 | 1820 | // Create as many buckets as there are symbols. |
| 1623 | // FIXME: This is simplistic. We can try to optimize it, but implementing | |
| 1624 | // support for SHT_GNU_HASH is probably even more profitable. | |
| 1625 | 1821 | NumEntries += InX::DynSymTab->getNumSymbols(); |
| 1626 | 1822 | this->Size = NumEntries * 4; |
| 1627 | 1823 | } |
| 1628 | 1824 | |
| 1629 | template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) { | |
| 1630 | // A 32-bit integer type in the target endianness. | |
| 1631 | typedef typename ELFT::Word Elf_Word; | |
| 1825 | void HashTableSection::writeTo(uint8_t *Buf) { | |
| 1826 | // See comment in GnuHashTableSection::writeTo. | |
| 1827 | memset(Buf, 0, Size); | |
| 1632 | 1828 | |
| 1633 | 1829 | unsigned NumSymbols = InX::DynSymTab->getNumSymbols(); |
| 1634 | 1830 | |
| 1635 | auto *P = reinterpret_cast<Elf_Word *>(Buf); | |
| 1636 | *P++ = NumSymbols; // nbucket | |
| 1637 | *P++ = NumSymbols; // nchain | |
| 1831 | uint32_t *P = reinterpret_cast<uint32_t *>(Buf); | |
| 1832 | write32(P++, NumSymbols); // nbucket | |
| 1833 | write32(P++, NumSymbols); // nchain | |
| 1638 | 1834 | |
| 1639 | Elf_Word *Buckets = P; | |
| 1640 | Elf_Word *Chains = P + NumSymbols; | |
| 1835 | uint32_t *Buckets = P; | |
| 1836 | uint32_t *Chains = P + NumSymbols; | |
| 1641 | 1837 | |
| 1642 | 1838 | for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) { |
| 1643 | SymbolBody *Body = S.Symbol; | |
| 1644 | StringRef Name = Body->getName(); | |
| 1645 | unsigned I = Body->DynsymIndex; | |
| 1839 | Symbol *Sym = S.Sym; | |
| 1840 | StringRef Name = Sym->getName(); | |
| 1841 | unsigned I = Sym->DynsymIndex; | |
| 1646 | 1842 | uint32_t Hash = hashSysV(Name) % NumSymbols; |
| 1647 | 1843 | Chains[I] = Buckets[Hash]; |
| 1648 | Buckets[Hash] = I; | |
| 1844 | write32(Buckets + Hash, I); | |
| 1649 | 1845 | } |
| 1650 | 1846 | } |
| 1651 | 1847 | |
| ... | ... | @@ -1668,7 +1864,7 @@ void PltSection::writeTo(uint8_t *Buf) { |
| 1668 | 1864 | unsigned PltOff = getPltRelocOff(); |
| 1669 | 1865 | |
| 1670 | 1866 | for (auto &I : Entries) { |
| 1671 | const SymbolBody *B = I.first; | |
| 1867 | const Symbol *B = I.first; | |
| 1672 | 1868 | unsigned RelOff = I.second + PltOff; |
| 1673 | 1869 | uint64_t Got = B->getGotPltVA(); |
| 1674 | 1870 | uint64_t Plt = this->getVA() + Off; |
| ... | ... | @@ -1677,14 +1873,15 @@ void PltSection::writeTo(uint8_t *Buf) { |
| 1677 | 1873 | } |
| 1678 | 1874 | } |
| 1679 | 1875 | |
| 1680 | template <class ELFT> void PltSection::addEntry(SymbolBody &Sym) { | |
| 1876 | template <class ELFT> void PltSection::addEntry(Symbol &Sym) { | |
| 1681 | 1877 | Sym.PltIndex = Entries.size(); |
| 1682 | RelocationSection<ELFT> *PltRelocSection = In<ELFT>::RelaPlt; | |
| 1878 | RelocationBaseSection *PltRelocSection = InX::RelaPlt; | |
| 1683 | 1879 | if (HeaderSize == 0) { |
| 1684 | PltRelocSection = In<ELFT>::RelaIplt; | |
| 1880 | PltRelocSection = InX::RelaIplt; | |
| 1685 | 1881 | Sym.IsInIplt = true; |
| 1686 | 1882 | } |
| 1687 | unsigned RelOff = PltRelocSection->getRelocOffset(); | |
| 1883 | unsigned RelOff = | |
| 1884 | static_cast<RelocationSection<ELFT> *>(PltRelocSection)->getRelocOffset(); | |
| 1688 | 1885 | Entries.push_back(std::make_pair(&Sym, RelOff)); |
| 1689 | 1886 | } |
| 1690 | 1887 | |
| ... | ... | @@ -1697,10 +1894,10 @@ size_t PltSection::getSize() const { |
| 1697 | 1894 | void PltSection::addSymbols() { |
| 1698 | 1895 | // The PLT may have symbols defined for the Header, the IPLT has no header |
| 1699 | 1896 | if (HeaderSize != 0) |
| 1700 | Target->addPltHeaderSymbols(this); | |
| 1897 | Target->addPltHeaderSymbols(*this); | |
| 1701 | 1898 | size_t Off = HeaderSize; |
| 1702 | 1899 | for (size_t I = 0; I < Entries.size(); ++I) { |
| 1703 | Target->addPltSymbols(this, Off); | |
| 1900 | Target->addPltSymbols(*this, Off); | |
| 1704 | 1901 | Off += Target->PltEntrySize; |
| 1705 | 1902 | } |
| 1706 | 1903 | } |
| ... | ... | @@ -1709,35 +1906,29 @@ unsigned PltSection::getPltRelocOff() const { |
| 1709 | 1906 | return (HeaderSize == 0) ? InX::Plt->getSize() : 0; |
| 1710 | 1907 | } |
| 1711 | 1908 | |
| 1712 | GdbIndexSection::GdbIndexSection(std::vector<GdbIndexChunk> &&Chunks) | |
| 1713 | : SyntheticSection(0, SHT_PROGBITS, 1, ".gdb_index"), | |
| 1714 | StringPool(llvm::StringTableBuilder::ELF), Chunks(std::move(Chunks)) {} | |
| 1715 | ||
| 1716 | // Iterative hash function for symbol's name is described in .gdb_index format | |
| 1717 | // specification. Note that we use one for version 5 to 7 here, it is different | |
| 1718 | // for version 4. | |
| 1719 | static uint32_t hash(StringRef Str) { | |
| 1720 | uint32_t R = 0; | |
| 1721 | for (uint8_t C : Str) | |
| 1722 | R = R * 67 + tolower(C) - 113; | |
| 1723 | return R; | |
| 1909 | // The string hash function for .gdb_index. | |
| 1910 | static uint32_t computeGdbHash(StringRef S) { | |
| 1911 | uint32_t H = 0; | |
| 1912 | for (uint8_t C : S) | |
| 1913 | H = H * 67 + tolower(C) - 113; | |
| 1914 | return H; | |
| 1724 | 1915 | } |
| 1725 | 1916 | |
| 1726 | static std::vector<CompilationUnitEntry> readCuList(DWARFContext &Dwarf) { | |
| 1727 | std::vector<CompilationUnitEntry> Ret; | |
| 1728 | for (std::unique_ptr<DWARFCompileUnit> &CU : Dwarf.compile_units()) | |
| 1729 | Ret.push_back({CU->getOffset(), CU->getLength() + 4}); | |
| 1917 | static std::vector<GdbIndexChunk::CuEntry> readCuList(DWARFContext &Dwarf) { | |
| 1918 | std::vector<GdbIndexChunk::CuEntry> Ret; | |
| 1919 | for (std::unique_ptr<DWARFCompileUnit> &Cu : Dwarf.compile_units()) | |
| 1920 | Ret.push_back({Cu->getOffset(), Cu->getLength() + 4}); | |
| 1730 | 1921 | return Ret; |
| 1731 | 1922 | } |
| 1732 | 1923 | |
| 1733 | static std::vector<AddressEntry> readAddressArea(DWARFContext &Dwarf, | |
| 1734 | InputSection *Sec) { | |
| 1735 | std::vector<AddressEntry> Ret; | |
| 1924 | static std::vector<GdbIndexChunk::AddressEntry> | |
| 1925 | readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) { | |
| 1926 | std::vector<GdbIndexChunk::AddressEntry> Ret; | |
| 1736 | 1927 | |
| 1737 | uint32_t CurrentCu = 0; | |
| 1738 | for (std::unique_ptr<DWARFCompileUnit> &CU : Dwarf.compile_units()) { | |
| 1928 | uint32_t CuIdx = 0; | |
| 1929 | for (std::unique_ptr<DWARFCompileUnit> &Cu : Dwarf.compile_units()) { | |
| 1739 | 1930 | DWARFAddressRangesVector Ranges; |
| 1740 | CU->collectAddressRanges(Ranges); | |
| 1931 | Cu->collectAddressRanges(Ranges); | |
| 1741 | 1932 | |
| 1742 | 1933 | ArrayRef<InputSectionBase *> Sections = Sec->File->getSections(); |
| 1743 | 1934 | for (DWARFAddressRange &R : Ranges) { |
| ... | ... | @@ -1747,24 +1938,29 @@ static std::vector<AddressEntry> readAddressArea(DWARFContext &Dwarf, |
| 1747 | 1938 | // Range list with zero size has no effect. |
| 1748 | 1939 | if (R.LowPC == R.HighPC) |
| 1749 | 1940 | continue; |
| 1750 | Ret.push_back({cast<InputSection>(S), R.LowPC, R.HighPC, CurrentCu}); | |
| 1941 | auto *IS = cast<InputSection>(S); | |
| 1942 | uint64_t Offset = IS->getOffsetInFile(); | |
| 1943 | Ret.push_back({IS, R.LowPC - Offset, R.HighPC - Offset, CuIdx}); | |
| 1751 | 1944 | } |
| 1752 | ++CurrentCu; | |
| 1945 | ++CuIdx; | |
| 1753 | 1946 | } |
| 1754 | 1947 | return Ret; |
| 1755 | 1948 | } |
| 1756 | 1949 | |
| 1757 | static std::vector<NameTypeEntry> readPubNamesAndTypes(DWARFContext &Dwarf, | |
| 1758 | bool IsLE) { | |
| 1759 | StringRef Data[] = {Dwarf.getGnuPubNamesSection(), | |
| 1760 | Dwarf.getGnuPubTypesSection()}; | |
| 1950 | static std::vector<GdbIndexChunk::NameTypeEntry> | |
| 1951 | readPubNamesAndTypes(DWARFContext &Dwarf) { | |
| 1952 | StringRef Sec1 = Dwarf.getDWARFObj().getGnuPubNamesSection(); | |
| 1953 | StringRef Sec2 = Dwarf.getDWARFObj().getGnuPubTypesSection(); | |
| 1761 | 1954 | |
| 1762 | std::vector<NameTypeEntry> Ret; | |
| 1763 | for (StringRef D : Data) { | |
| 1764 | DWARFDebugPubTable PubTable(D, IsLE, true); | |
| 1765 | for (const DWARFDebugPubTable::Set &Set : PubTable.getData()) | |
| 1766 | for (const DWARFDebugPubTable::Entry &Ent : Set.Entries) | |
| 1767 | Ret.push_back({Ent.Name, Ent.Descriptor.toBits()}); | |
| 1955 | std::vector<GdbIndexChunk::NameTypeEntry> Ret; | |
| 1956 | for (StringRef Sec : {Sec1, Sec2}) { | |
| 1957 | DWARFDebugPubTable Table(Sec, Config->IsLE, true); | |
| 1958 | for (const DWARFDebugPubTable::Set &Set : Table.getData()) { | |
| 1959 | for (const DWARFDebugPubTable::Entry &Ent : Set.Entries) { | |
| 1960 | CachedHashStringRef S(Ent.Name, computeGdbHash(Ent.Name)); | |
| 1961 | Ret.push_back({S, Ent.Descriptor.toBits()}); | |
| 1962 | } | |
| 1963 | } | |
| 1768 | 1964 | } |
| 1769 | 1965 | return Ret; |
| 1770 | 1966 | } |
| ... | ... | @@ -1778,119 +1974,140 @@ static std::vector<InputSection *> getDebugInfoSections() { |
| 1778 | 1974 | return Ret; |
| 1779 | 1975 | } |
| 1780 | 1976 | |
| 1781 | void GdbIndexSection::buildIndex() { | |
| 1782 | if (Chunks.empty()) | |
| 1783 | return; | |
| 1977 | void GdbIndexSection::fixCuIndex() { | |
| 1978 | uint32_t Idx = 0; | |
| 1979 | for (GdbIndexChunk &Chunk : Chunks) { | |
| 1980 | for (GdbIndexChunk::AddressEntry &Ent : Chunk.AddressAreas) | |
| 1981 | Ent.CuIndex += Idx; | |
| 1982 | Idx += Chunk.CompilationUnits.size(); | |
| 1983 | } | |
| 1984 | } | |
| 1784 | 1985 | |
| 1785 | uint32_t CuId = 0; | |
| 1786 | for (GdbIndexChunk &D : Chunks) { | |
| 1787 | for (AddressEntry &E : D.AddressArea) | |
| 1788 | E.CuIndex += CuId; | |
| 1789 | ||
| 1790 | // Populate constant pool area. | |
| 1791 | for (NameTypeEntry &NameType : D.NamesAndTypes) { | |
| 1792 | uint32_t Hash = hash(NameType.Name); | |
| 1793 | size_t Offset = StringPool.add(NameType.Name); | |
| 1794 | ||
| 1795 | bool IsNew; | |
| 1796 | GdbSymbol *Sym; | |
| 1797 | std::tie(IsNew, Sym) = SymbolTable.add(Hash, Offset); | |
| 1798 | if (IsNew) { | |
| 1799 | Sym->CuVectorIndex = CuVectors.size(); | |
| 1800 | CuVectors.resize(CuVectors.size() + 1); | |
| 1986 | std::vector<std::vector<uint32_t>> GdbIndexSection::createCuVectors() { | |
| 1987 | std::vector<std::vector<uint32_t>> Ret; | |
| 1988 | uint32_t Idx = 0; | |
| 1989 | uint32_t Off = 0; | |
| 1990 | ||
| 1991 | for (GdbIndexChunk &Chunk : Chunks) { | |
| 1992 | for (GdbIndexChunk::NameTypeEntry &Ent : Chunk.NamesAndTypes) { | |
| 1993 | GdbSymbol *&Sym = Symbols[Ent.Name]; | |
| 1994 | if (!Sym) { | |
| 1995 | Sym = make<GdbSymbol>(GdbSymbol{Ent.Name.hash(), Off, Ret.size()}); | |
| 1996 | Off += Ent.Name.size() + 1; | |
| 1997 | Ret.push_back({}); | |
| 1801 | 1998 | } |
| 1802 | 1999 | |
| 1803 | CuVectors[Sym->CuVectorIndex].insert(CuId | (NameType.Type << 24)); | |
| 2000 | // gcc 5.4.1 produces a buggy .debug_gnu_pubnames that contains | |
| 2001 | // duplicate entries, so we want to dedup them. | |
| 2002 | std::vector<uint32_t> &Vec = Ret[Sym->CuVectorIndex]; | |
| 2003 | uint32_t Val = (Ent.Type << 24) | Idx; | |
| 2004 | if (Vec.empty() || Vec.back() != Val) | |
| 2005 | Vec.push_back(Val); | |
| 1804 | 2006 | } |
| 1805 | ||
| 1806 | CuId += D.CompilationUnits.size(); | |
| 2007 | Idx += Chunk.CompilationUnits.size(); | |
| 1807 | 2008 | } |
| 1808 | } | |
| 1809 | 2009 | |
| 1810 | static GdbIndexChunk readDwarf(DWARFContextInMemory &Dwarf, InputSection *Sec) { | |
| 1811 | GdbIndexChunk Ret; | |
| 1812 | Ret.DebugInfoSec = Sec; | |
| 1813 | Ret.CompilationUnits = readCuList(Dwarf); | |
| 1814 | Ret.AddressArea = readAddressArea(Dwarf, Sec); | |
| 1815 | Ret.NamesAndTypes = readPubNamesAndTypes(Dwarf, Config->IsLE); | |
| 2010 | StringPoolSize = Off; | |
| 1816 | 2011 | return Ret; |
| 1817 | 2012 | } |
| 1818 | 2013 | |
| 1819 | 2014 | template <class ELFT> GdbIndexSection *elf::createGdbIndex() { |
| 1820 | std::vector<GdbIndexChunk> Chunks; | |
| 1821 | for (InputSection *Sec : getDebugInfoSections()) { | |
| 1822 | InputFile *F = Sec->File; | |
| 1823 | std::error_code EC; | |
| 1824 | ELFObjectFile<ELFT> Obj(F->MB, EC); | |
| 1825 | if (EC) | |
| 1826 | fatal(EC.message()); | |
| 1827 | DWARFContextInMemory Dwarf(Obj, nullptr, [&](Error E) { | |
| 1828 | error(toString(F) + ": error parsing DWARF data:\n>>> " + | |
| 1829 | toString(std::move(E))); | |
| 1830 | return ErrorPolicy::Continue; | |
| 1831 | }); | |
| 1832 | Chunks.push_back(readDwarf(Dwarf, Sec)); | |
| 1833 | } | |
| 2015 | // Gather debug info to create a .gdb_index section. | |
| 2016 | 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 | ||
| 2029 | // .debug_gnu_pub{names,types} are useless in executables. | |
| 2030 | // They are present in input object files solely for creating | |
| 2031 | // a .gdb_index. So we can remove it from the output. | |
| 2032 | for (InputSectionBase *S : InputSections) | |
| 2033 | if (S->Name == ".debug_gnu_pubnames" || S->Name == ".debug_gnu_pubtypes") | |
| 2034 | S->Live = false; | |
| 2035 | ||
| 2036 | // Create a .gdb_index and returns it. | |
| 1834 | 2037 | return make<GdbIndexSection>(std::move(Chunks)); |
| 1835 | 2038 | } |
| 1836 | 2039 | |
| 1837 | static size_t getCuSize(std::vector<GdbIndexChunk> &C) { | |
| 2040 | static size_t getCuSize(ArrayRef<GdbIndexChunk> Arr) { | |
| 1838 | 2041 | size_t Ret = 0; |
| 1839 | for (GdbIndexChunk &D : C) | |
| 2042 | for (const GdbIndexChunk &D : Arr) | |
| 1840 | 2043 | Ret += D.CompilationUnits.size(); |
| 1841 | 2044 | return Ret; |
| 1842 | 2045 | } |
| 1843 | 2046 | |
| 1844 | static size_t getAddressAreaSize(std::vector<GdbIndexChunk> &C) { | |
| 2047 | static size_t getAddressAreaSize(ArrayRef<GdbIndexChunk> Arr) { | |
| 1845 | 2048 | size_t Ret = 0; |
| 1846 | for (GdbIndexChunk &D : C) | |
| 1847 | Ret += D.AddressArea.size(); | |
| 2049 | for (const GdbIndexChunk &D : Arr) | |
| 2050 | Ret += D.AddressAreas.size(); | |
| 1848 | 2051 | return Ret; |
| 1849 | 2052 | } |
| 1850 | 2053 | |
| 1851 | void GdbIndexSection::finalizeContents() { | |
| 1852 | if (Finalized) | |
| 1853 | return; | |
| 1854 | Finalized = true; | |
| 2054 | std::vector<GdbSymbol *> GdbIndexSection::createGdbSymtab() { | |
| 2055 | uint32_t Size = NextPowerOf2(Symbols.size() * 4 / 3); | |
| 2056 | if (Size < 1024) | |
| 2057 | Size = 1024; | |
| 2058 | ||
| 2059 | uint32_t Mask = Size - 1; | |
| 2060 | std::vector<GdbSymbol *> Ret(Size); | |
| 1855 | 2061 | |
| 1856 | buildIndex(); | |
| 2062 | for (auto &KV : Symbols) { | |
| 2063 | GdbSymbol *Sym = KV.second; | |
| 2064 | uint32_t I = Sym->NameHash & Mask; | |
| 2065 | uint32_t Step = ((Sym->NameHash * 17) & Mask) | 1; | |
| 1857 | 2066 | |
| 1858 | SymbolTable.finalizeContents(); | |
| 2067 | while (Ret[I]) | |
| 2068 | I = (I + Step) & Mask; | |
| 2069 | Ret[I] = Sym; | |
| 2070 | } | |
| 2071 | return Ret; | |
| 2072 | } | |
| 1859 | 2073 | |
| 1860 | // GdbIndex header consist from version fields | |
| 1861 | // and 5 more fields with different kinds of offsets. | |
| 1862 | CuTypesOffset = CuListOffset + getCuSize(Chunks) * CompilationUnitSize; | |
| 1863 | SymTabOffset = CuTypesOffset + getAddressAreaSize(Chunks) * AddressEntrySize; | |
| 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(); | |
| 1864 | 2079 | |
| 1865 | ConstantPoolOffset = | |
| 1866 | SymTabOffset + SymbolTable.getCapacity() * SymTabEntrySize; | |
| 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; | |
| 1867 | 2085 | |
| 1868 | for (std::set<uint32_t> &CuVec : CuVectors) { | |
| 1869 | CuVectorsOffset.push_back(CuVectorsSize); | |
| 1870 | CuVectorsSize += OffsetTypeSize * (CuVec.size() + 1); | |
| 2086 | size_t Off = 0; | |
| 2087 | for (ArrayRef<uint32_t> Vec : CuVectors) { | |
| 2088 | CuVectorOffsets.push_back(Off); | |
| 2089 | Off += (Vec.size() + 1) * 4; | |
| 1871 | 2090 | } |
| 1872 | StringPoolOffset = ConstantPoolOffset + CuVectorsSize; | |
| 1873 | ||
| 1874 | StringPool.finalizeInOrder(); | |
| 2091 | StringPoolOffset = ConstantPoolOffset + Off; | |
| 1875 | 2092 | } |
| 1876 | 2093 | |
| 1877 | 2094 | size_t GdbIndexSection::getSize() const { |
| 1878 | const_cast<GdbIndexSection *>(this)->finalizeContents(); | |
| 1879 | return StringPoolOffset + StringPool.getSize(); | |
| 2095 | return StringPoolOffset + StringPoolSize; | |
| 1880 | 2096 | } |
| 1881 | 2097 | |
| 1882 | 2098 | void GdbIndexSection::writeTo(uint8_t *Buf) { |
| 1883 | write32le(Buf, 7); // Write version. | |
| 1884 | write32le(Buf + 4, CuListOffset); // CU list offset. | |
| 1885 | write32le(Buf + 8, CuTypesOffset); // Types CU list offset. | |
| 1886 | write32le(Buf + 12, CuTypesOffset); // Address area offset. | |
| 1887 | write32le(Buf + 16, SymTabOffset); // Symbol table offset. | |
| 1888 | write32le(Buf + 20, ConstantPoolOffset); // Constant pool offset. | |
| 2099 | // Write the section header. | |
| 2100 | write32le(Buf, 7); | |
| 2101 | write32le(Buf + 4, CuListOffset); | |
| 2102 | write32le(Buf + 8, CuTypesOffset); | |
| 2103 | write32le(Buf + 12, CuTypesOffset); | |
| 2104 | write32le(Buf + 16, SymtabOffset); | |
| 2105 | write32le(Buf + 20, ConstantPoolOffset); | |
| 1889 | 2106 | Buf += 24; |
| 1890 | 2107 | |
| 1891 | 2108 | // Write the CU list. |
| 1892 | 2109 | for (GdbIndexChunk &D : Chunks) { |
| 1893 | for (CompilationUnitEntry &Cu : D.CompilationUnits) { | |
| 2110 | for (GdbIndexChunk::CuEntry &Cu : D.CompilationUnits) { | |
| 1894 | 2111 | write64le(Buf, D.DebugInfoSec->OutSecOff + Cu.CuOffset); |
| 1895 | 2112 | write64le(Buf + 8, Cu.CuLength); |
| 1896 | 2113 | Buf += 16; |
| ... | ... | @@ -1899,7 +2116,7 @@ void GdbIndexSection::writeTo(uint8_t *Buf) { |
| 1899 | 2116 | |
| 1900 | 2117 | // Write the address area. |
| 1901 | 2118 | for (GdbIndexChunk &D : Chunks) { |
| 1902 | for (AddressEntry &E : D.AddressArea) { | |
| 2119 | for (GdbIndexChunk::AddressEntry &E : D.AddressAreas) { | |
| 1903 | 2120 | uint64_t BaseAddr = |
| 1904 | 2121 | E.Section->getParent()->Addr + E.Section->getOffset(0); |
| 1905 | 2122 | write64le(Buf, BaseAddr + E.LowAddress); |
| ... | ... | @@ -1910,43 +2127,47 @@ void GdbIndexSection::writeTo(uint8_t *Buf) { |
| 1910 | 2127 | } |
| 1911 | 2128 | |
| 1912 | 2129 | // Write the symbol table. |
| 1913 | for (size_t I = 0; I < SymbolTable.getCapacity(); ++I) { | |
| 1914 | GdbSymbol *Sym = SymbolTable.getSymbol(I); | |
| 2130 | for (GdbSymbol *Sym : GdbSymtab) { | |
| 1915 | 2131 | if (Sym) { |
| 1916 | size_t NameOffset = | |
| 1917 | Sym->NameOffset + StringPoolOffset - ConstantPoolOffset; | |
| 1918 | size_t CuVectorOffset = CuVectorsOffset[Sym->CuVectorIndex]; | |
| 1919 | write32le(Buf, NameOffset); | |
| 1920 | write32le(Buf + 4, CuVectorOffset); | |
| 2132 | write32le(Buf, Sym->NameOffset + StringPoolOffset - ConstantPoolOffset); | |
| 2133 | write32le(Buf + 4, CuVectorOffsets[Sym->CuVectorIndex]); | |
| 1921 | 2134 | } |
| 1922 | 2135 | Buf += 8; |
| 1923 | 2136 | } |
| 1924 | 2137 | |
| 1925 | // Write the CU vectors into the constant pool. | |
| 1926 | for (std::set<uint32_t> &CuVec : CuVectors) { | |
| 1927 | write32le(Buf, CuVec.size()); | |
| 2138 | // Write the CU vectors. | |
| 2139 | for (ArrayRef<uint32_t> Vec : CuVectors) { | |
| 2140 | write32le(Buf, Vec.size()); | |
| 1928 | 2141 | Buf += 4; |
| 1929 | for (uint32_t Val : CuVec) { | |
| 2142 | for (uint32_t Val : Vec) { | |
| 1930 | 2143 | write32le(Buf, Val); |
| 1931 | 2144 | Buf += 4; |
| 1932 | 2145 | } |
| 1933 | 2146 | } |
| 1934 | 2147 | |
| 1935 | StringPool.write(Buf); | |
| 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 | } | |
| 1936 | 2156 | } |
| 1937 | 2157 | |
| 1938 | 2158 | bool GdbIndexSection::empty() const { return !Out::DebugInfo; } |
| 1939 | 2159 | |
| 1940 | template <class ELFT> | |
| 1941 | EhFrameHeader<ELFT>::EhFrameHeader() | |
| 2160 | EhFrameHeader::EhFrameHeader() | |
| 1942 | 2161 | : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 1, ".eh_frame_hdr") {} |
| 1943 | 2162 | |
| 1944 | 2163 | // .eh_frame_hdr contains a binary search table of pointers to FDEs. |
| 1945 | 2164 | // Each entry of the search table consists of two values, |
| 1946 | 2165 | // the starting PC from where FDEs covers, and the FDE's address. |
| 1947 | 2166 | // It is sorted by PC. |
| 1948 | template <class ELFT> void EhFrameHeader<ELFT>::writeTo(uint8_t *Buf) { | |
| 1949 | const endianness E = ELFT::TargetEndianness; | |
| 2167 | void EhFrameHeader::writeTo(uint8_t *Buf) { | |
| 2168 | typedef EhFrameSection::FdeData FdeData; | |
| 2169 | ||
| 2170 | std::vector<FdeData> Fdes = InX::EhFrame->getFdeData(); | |
| 1950 | 2171 | |
| 1951 | 2172 | // Sort the FDE list by their PC and uniqueify. Usually there is only |
| 1952 | 2173 | // one FDE for a PC (i.e. function), but if ICF merges two functions |
| ... | ... | @@ -1960,31 +2181,24 @@ template <class ELFT> void EhFrameHeader<ELFT>::writeTo(uint8_t *Buf) { |
| 1960 | 2181 | Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; |
| 1961 | 2182 | Buf[2] = DW_EH_PE_udata4; |
| 1962 | 2183 | Buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; |
| 1963 | write32<E>(Buf + 4, In<ELFT>::EhFrame->getParent()->Addr - this->getVA() - 4); | |
| 1964 | write32<E>(Buf + 8, Fdes.size()); | |
| 2184 | write32(Buf + 4, InX::EhFrame->getParent()->Addr - this->getVA() - 4); | |
| 2185 | write32(Buf + 8, Fdes.size()); | |
| 1965 | 2186 | Buf += 12; |
| 1966 | 2187 | |
| 1967 | 2188 | uint64_t VA = this->getVA(); |
| 1968 | 2189 | for (FdeData &Fde : Fdes) { |
| 1969 | write32<E>(Buf, Fde.Pc - VA); | |
| 1970 | write32<E>(Buf + 4, Fde.FdeVA - VA); | |
| 2190 | write32(Buf, Fde.Pc - VA); | |
| 2191 | write32(Buf + 4, Fde.FdeVA - VA); | |
| 1971 | 2192 | Buf += 8; |
| 1972 | 2193 | } |
| 1973 | 2194 | } |
| 1974 | 2195 | |
| 1975 | template <class ELFT> size_t EhFrameHeader<ELFT>::getSize() const { | |
| 2196 | size_t EhFrameHeader::getSize() const { | |
| 1976 | 2197 | // .eh_frame_hdr has a 12 bytes header followed by an array of FDEs. |
| 1977 | return 12 + In<ELFT>::EhFrame->NumFdes * 8; | |
| 1978 | } | |
| 1979 | ||
| 1980 | template <class ELFT> | |
| 1981 | void EhFrameHeader<ELFT>::addFde(uint32_t Pc, uint32_t FdeVA) { | |
| 1982 | Fdes.push_back({Pc, FdeVA}); | |
| 2198 | return 12 + InX::EhFrame->NumFdes * 8; | |
| 1983 | 2199 | } |
| 1984 | 2200 | |
| 1985 | template <class ELFT> bool EhFrameHeader<ELFT>::empty() const { | |
| 1986 | return In<ELFT>::EhFrame->empty(); | |
| 1987 | } | |
| 2201 | bool EhFrameHeader::empty() const { return InX::EhFrame->empty(); } | |
| 1988 | 2202 | |
| 1989 | 2203 | template <class ELFT> |
| 1990 | 2204 | VersionDefinitionSection<ELFT>::VersionDefinitionSection() |
| ... | ... | @@ -2065,7 +2279,7 @@ template <class ELFT> size_t VersionTableSection<ELFT>::getSize() const { |
| 2065 | 2279 | template <class ELFT> void VersionTableSection<ELFT>::writeTo(uint8_t *Buf) { |
| 2066 | 2280 | auto *OutVersym = reinterpret_cast<Elf_Versym *>(Buf) + 1; |
| 2067 | 2281 | for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) { |
| 2068 | OutVersym->vs_index = S.Symbol->symbol()->VersionId; | |
| 2282 | OutVersym->vs_index = S.Sym->VersionId; | |
| 2069 | 2283 | ++OutVersym; |
| 2070 | 2284 | } |
| 2071 | 2285 | } |
| ... | ... | @@ -2086,29 +2300,28 @@ VersionNeedSection<ELFT>::VersionNeedSection() |
| 2086 | 2300 | |
| 2087 | 2301 | template <class ELFT> |
| 2088 | 2302 | void VersionNeedSection<ELFT>::addSymbol(SharedSymbol *SS) { |
| 2089 | auto *Ver = reinterpret_cast<const typename ELFT::Verdef *>(SS->Verdef); | |
| 2303 | SharedFile<ELFT> &File = SS->getFile<ELFT>(); | |
| 2304 | const typename ELFT::Verdef *Ver = File.Verdefs[SS->VerdefIndex]; | |
| 2090 | 2305 | if (!Ver) { |
| 2091 | SS->symbol()->VersionId = VER_NDX_GLOBAL; | |
| 2306 | SS->VersionId = VER_NDX_GLOBAL; | |
| 2092 | 2307 | return; |
| 2093 | 2308 | } |
| 2094 | 2309 | |
| 2095 | auto *File = cast<SharedFile<ELFT>>(SS->File); | |
| 2096 | ||
| 2097 | 2310 | // If we don't already know that we need an Elf_Verneed for this DSO, prepare |
| 2098 | 2311 | // to create one by adding it to our needed list and creating a dynstr entry |
| 2099 | 2312 | // for the soname. |
| 2100 | if (File->VerdefMap.empty()) | |
| 2101 | Needed.push_back({File, InX::DynStrTab->addString(File->SoName)}); | |
| 2102 | typename SharedFile<ELFT>::NeededVer &NV = File->VerdefMap[Ver]; | |
| 2313 | if (File.VerdefMap.empty()) | |
| 2314 | Needed.push_back({&File, InX::DynStrTab->addString(File.SoName)}); | |
| 2315 | typename SharedFile<ELFT>::NeededVer &NV = File.VerdefMap[Ver]; | |
| 2103 | 2316 | // If we don't already know that we need an Elf_Vernaux for this Elf_Verdef, |
| 2104 | 2317 | // prepare to create one by allocating a version identifier and creating a |
| 2105 | 2318 | // dynstr entry for the version name. |
| 2106 | 2319 | if (NV.Index == 0) { |
| 2107 | NV.StrTab = InX::DynStrTab->addString(File->getStringTable().data() + | |
| 2320 | NV.StrTab = InX::DynStrTab->addString(File.getStringTable().data() + | |
| 2108 | 2321 | Ver->getAux()->vda_name); |
| 2109 | 2322 | NV.Index = NextIndex++; |
| 2110 | 2323 | } |
| 2111 | SS->symbol()->VersionId = NV.Index; | |
| 2324 | SS->VersionId = NV.Index; | |
| 2112 | 2325 | } |
| 2113 | 2326 | |
| 2114 | 2327 | template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) { |
| ... | ... | @@ -2162,23 +2375,21 @@ template <class ELFT> bool VersionNeedSection<ELFT>::empty() const { |
| 2162 | 2375 | return getNeedNum() == 0; |
| 2163 | 2376 | } |
| 2164 | 2377 | |
| 2165 | MergeSyntheticSection::MergeSyntheticSection(StringRef Name, uint32_t Type, | |
| 2166 | uint64_t Flags, uint32_t Alignment) | |
| 2167 | : SyntheticSection(Flags, Type, Alignment, Name), | |
| 2168 | Builder(StringTableBuilder::RAW, Alignment) {} | |
| 2169 | ||
| 2170 | 2378 | void MergeSyntheticSection::addSection(MergeInputSection *MS) { |
| 2171 | 2379 | MS->Parent = this; |
| 2172 | 2380 | Sections.push_back(MS); |
| 2173 | 2381 | } |
| 2174 | 2382 | |
| 2175 | void MergeSyntheticSection::writeTo(uint8_t *Buf) { Builder.write(Buf); } | |
| 2383 | MergeTailSection::MergeTailSection(StringRef Name, uint32_t Type, | |
| 2384 | uint64_t Flags, uint32_t Alignment) | |
| 2385 | : MergeSyntheticSection(Name, Type, Flags, Alignment), | |
| 2386 | Builder(StringTableBuilder::RAW, Alignment) {} | |
| 2176 | 2387 | |
| 2177 | bool MergeSyntheticSection::shouldTailMerge() const { | |
| 2178 | return (this->Flags & SHF_STRINGS) && Config->Optimize >= 2; | |
| 2179 | } | |
| 2388 | size_t MergeTailSection::getSize() const { return Builder.getSize(); } | |
| 2180 | 2389 | |
| 2181 | void MergeSyntheticSection::finalizeTailMerge() { | |
| 2390 | void MergeTailSection::writeTo(uint8_t *Buf) { Builder.write(Buf); } | |
| 2391 | ||
| 2392 | void MergeTailSection::finalizeContents() { | |
| 2182 | 2393 | // Add all string pieces to the string table builder to create section |
| 2183 | 2394 | // contents. |
| 2184 | 2395 | for (MergeInputSection *Sec : Sections) |
| ... | ... | @@ -2198,46 +2409,96 @@ void MergeSyntheticSection::finalizeTailMerge() { |
| 2198 | 2409 | Sec->Pieces[I].OutputOff = Builder.getOffset(Sec->getData(I)); |
| 2199 | 2410 | } |
| 2200 | 2411 | |
| 2201 | void MergeSyntheticSection::finalizeNoTailMerge() { | |
| 2202 | // Add all string pieces to the string table builder to create section | |
| 2203 | // contents. Because we are not tail-optimizing, offsets of strings are | |
| 2204 | // fixed when they are added to the builder (string table builder contains | |
| 2205 | // a hash table from strings to offsets). | |
| 2206 | for (MergeInputSection *Sec : Sections) | |
| 2412 | void MergeNoTailSection::writeTo(uint8_t *Buf) { | |
| 2413 | for (size_t I = 0; I < NumShards; ++I) | |
| 2414 | Shards[I].write(Buf + ShardOffsets[I]); | |
| 2415 | } | |
| 2416 | ||
| 2417 | // This function is very hot (i.e. it can take several seconds to finish) | |
| 2418 | // because sometimes the number of inputs is in an order of magnitude of | |
| 2419 | // millions. So, we use multi-threading. | |
| 2420 | // | |
| 2421 | // For any strings S and T, we know S is not mergeable with T if S's hash | |
| 2422 | // value is different from T's. If that's the case, we can safely put S and | |
| 2423 | // T into different string builders without worrying about merge misses. | |
| 2424 | // We do it in parallel. | |
| 2425 | void MergeNoTailSection::finalizeContents() { | |
| 2426 | // Initializes string table builders. | |
| 2427 | for (size_t I = 0; I < NumShards; ++I) | |
| 2428 | Shards.emplace_back(StringTableBuilder::RAW, Alignment); | |
| 2429 | ||
| 2430 | // Concurrency level. Must be a power of 2 to avoid expensive modulo | |
| 2431 | // operations in the following tight loop. | |
| 2432 | size_t Concurrency = 1; | |
| 2433 | if (ThreadsEnabled) | |
| 2434 | Concurrency = | |
| 2435 | std::min<size_t>(PowerOf2Floor(hardware_concurrency()), NumShards); | |
| 2436 | ||
| 2437 | // Add section pieces to the builders. | |
| 2438 | parallelForEachN(0, Concurrency, [&](size_t ThreadId) { | |
| 2439 | for (MergeInputSection *Sec : Sections) { | |
| 2440 | for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I) { | |
| 2441 | size_t ShardId = getShardId(Sec->Pieces[I].Hash); | |
| 2442 | if ((ShardId & (Concurrency - 1)) == ThreadId && Sec->Pieces[I].Live) | |
| 2443 | Sec->Pieces[I].OutputOff = Shards[ShardId].add(Sec->getData(I)); | |
| 2444 | } | |
| 2445 | } | |
| 2446 | }); | |
| 2447 | ||
| 2448 | // Compute an in-section offset for each shard. | |
| 2449 | size_t Off = 0; | |
| 2450 | for (size_t I = 0; I < NumShards; ++I) { | |
| 2451 | Shards[I].finalizeInOrder(); | |
| 2452 | if (Shards[I].getSize() > 0) | |
| 2453 | Off = alignTo(Off, Alignment); | |
| 2454 | ShardOffsets[I] = Off; | |
| 2455 | Off += Shards[I].getSize(); | |
| 2456 | } | |
| 2457 | Size = Off; | |
| 2458 | ||
| 2459 | // So far, section pieces have offsets from beginning of shards, but | |
| 2460 | // we want offsets from beginning of the whole section. Fix them. | |
| 2461 | parallelForEach(Sections, [&](MergeInputSection *Sec) { | |
| 2207 | 2462 | for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I) |
| 2208 | 2463 | if (Sec->Pieces[I].Live) |
| 2209 | Sec->Pieces[I].OutputOff = Builder.add(Sec->getData(I)); | |
| 2464 | Sec->Pieces[I].OutputOff += | |
| 2465 | ShardOffsets[getShardId(Sec->Pieces[I].Hash)]; | |
| 2466 | }); | |
| 2467 | } | |
| 2210 | 2468 | |
| 2211 | Builder.finalizeInOrder(); | |
| 2469 | static MergeSyntheticSection *createMergeSynthetic(StringRef Name, | |
| 2470 | uint32_t Type, | |
| 2471 | uint64_t Flags, | |
| 2472 | uint32_t Alignment) { | |
| 2473 | bool ShouldTailMerge = (Flags & SHF_STRINGS) && Config->Optimize >= 2; | |
| 2474 | if (ShouldTailMerge) | |
| 2475 | return make<MergeTailSection>(Name, Type, Flags, Alignment); | |
| 2476 | return make<MergeNoTailSection>(Name, Type, Flags, Alignment); | |
| 2212 | 2477 | } |
| 2213 | 2478 | |
| 2214 | void MergeSyntheticSection::finalizeContents() { | |
| 2215 | if (shouldTailMerge()) | |
| 2216 | finalizeTailMerge(); | |
| 2217 | else | |
| 2218 | finalizeNoTailMerge(); | |
| 2219 | } | |
| 2220 | ||
| 2221 | size_t MergeSyntheticSection::getSize() const { return Builder.getSize(); } | |
| 2222 | ||
| 2223 | // This function decompresses compressed sections and scans over the input | |
| 2224 | // sections to create mergeable synthetic sections. It removes | |
| 2225 | // MergeInputSections from the input section array and adds new synthetic | |
| 2226 | // sections at the location of the first input section that it replaces. It then | |
| 2227 | // finalizes each synthetic section in order to compute an output offset for | |
| 2228 | // each piece of each input section. | |
| 2229 | void elf::decompressAndMergeSections() { | |
| 2230 | // splitIntoPieces needs to be called on each MergeInputSection before calling | |
| 2231 | // finalizeContents(). Do that first. | |
| 2232 | parallelForEach(InputSections.begin(), InputSections.end(), | |
| 2233 | [](InputSectionBase *S) { | |
| 2234 | if (!S->Live) | |
| 2235 | return; | |
| 2236 | if (Decompressor::isCompressedELFSection(S->Flags, S->Name)) | |
| 2237 | S->uncompress(); | |
| 2238 | if (auto *MS = dyn_cast<MergeInputSection>(S)) | |
| 2239 | MS->splitIntoPieces(); | |
| 2240 | }); | |
| 2479 | // Debug sections may be compressed by zlib. Uncompress if exists. | |
| 2480 | void elf::decompressSections() { | |
| 2481 | parallelForEach(InputSections, [](InputSectionBase *Sec) { | |
| 2482 | if (Sec->Live) | |
| 2483 | Sec->maybeUncompress(); | |
| 2484 | }); | |
| 2485 | } | |
| 2486 | ||
| 2487 | // This function scans over the inputsections to create mergeable | |
| 2488 | // synthetic sections. | |
| 2489 | // | |
| 2490 | // It removes MergeInputSections from the input section array and adds | |
| 2491 | // new synthetic sections at the location of the first input section | |
| 2492 | // that it replaces. It then finalizes each synthetic section in order | |
| 2493 | // to compute an output offset for each piece of each input section. | |
| 2494 | 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 | }); | |
| 2241 | 2502 | |
| 2242 | 2503 | std::vector<MergeSyntheticSection *> MergeSections; |
| 2243 | 2504 | for (InputSectionBase *&S : InputSections) { |
| ... | ... | @@ -2250,20 +2511,28 @@ void elf::decompressAndMergeSections() { |
| 2250 | 2511 | if (!MS->Live) |
| 2251 | 2512 | continue; |
| 2252 | 2513 | |
| 2253 | StringRef OutsecName = getOutputSectionName(MS->Name); | |
| 2254 | uint64_t Flags = MS->Flags & ~(uint64_t)SHF_GROUP; | |
| 2514 | StringRef OutsecName = getOutputSectionName(MS); | |
| 2255 | 2515 | uint32_t Alignment = std::max<uint32_t>(MS->Alignment, MS->Entsize); |
| 2256 | 2516 | |
| 2257 | 2517 | auto I = llvm::find_if(MergeSections, [=](MergeSyntheticSection *Sec) { |
| 2258 | return Sec->Name == OutsecName && Sec->Flags == Flags && | |
| 2259 | Sec->Alignment == Alignment; | |
| 2518 | // While we could create a single synthetic section for two different | |
| 2519 | // values of Entsize, it is better to take Entsize into consideration. | |
| 2520 | // | |
| 2521 | // With a single synthetic section no two pieces with different Entsize | |
| 2522 | // could be equal, so we may as well have two sections. | |
| 2523 | // | |
| 2524 | // Using Entsize in here also allows us to propagate it to the synthetic | |
| 2525 | // section. | |
| 2526 | return Sec->Name == OutsecName && Sec->Flags == MS->Flags && | |
| 2527 | Sec->Entsize == MS->Entsize && Sec->Alignment == Alignment; | |
| 2260 | 2528 | }); |
| 2261 | 2529 | if (I == MergeSections.end()) { |
| 2262 | 2530 | MergeSyntheticSection *Syn = |
| 2263 | make<MergeSyntheticSection>(OutsecName, MS->Type, Flags, Alignment); | |
| 2531 | createMergeSynthetic(OutsecName, MS->Type, MS->Flags, Alignment); | |
| 2264 | 2532 | MergeSections.push_back(Syn); |
| 2265 | 2533 | I = std::prev(MergeSections.end()); |
| 2266 | 2534 | S = Syn; |
| 2535 | Syn->Entsize = MS->Entsize; | |
| 2267 | 2536 | } else { |
| 2268 | 2537 | S = nullptr; |
| 2269 | 2538 | } |
| ... | ... | @@ -2291,22 +2560,23 @@ ARMExidxSentinelSection::ARMExidxSentinelSection() |
| 2291 | 2560 | // The sentinel must have the PREL31 value of an address higher than any |
| 2292 | 2561 | // address described by any other table entry. |
| 2293 | 2562 | void ARMExidxSentinelSection::writeTo(uint8_t *Buf) { |
| 2294 | // The Sections are sorted in order of ascending PREL31 address with the | |
| 2295 | // sentinel last. We need to find the InputSection that precedes the | |
| 2296 | // sentinel. By construction the Sentinel is in the last | |
| 2297 | // InputSectionDescription as the InputSection that precedes it. | |
| 2298 | OutputSectionCommand *C = Script->getCmd(getParent()); | |
| 2299 | auto ISD = std::find_if(C->Commands.rbegin(), C->Commands.rend(), | |
| 2300 | [](const BaseCommand *Base) { | |
| 2301 | return isa<InputSectionDescription>(Base); | |
| 2302 | }); | |
| 2303 | auto L = cast<InputSectionDescription>(*ISD); | |
| 2304 | InputSection *Highest = L->Sections[L->Sections.size() - 2]; | |
| 2305 | InputSection *LS = Highest->getLinkOrderDep(); | |
| 2306 | uint64_t S = LS->getParent()->Addr + LS->getOffset(LS->getSize()); | |
| 2563 | assert(Highest); | |
| 2564 | uint64_t S = | |
| 2565 | Highest->getParent()->Addr + Highest->getOffset(Highest->getSize()); | |
| 2307 | 2566 | uint64_t P = getVA(); |
| 2308 | 2567 | Target->relocateOne(Buf, R_ARM_PREL31, S - P); |
| 2309 | write32le(Buf + 4, 0x1); | |
| 2568 | write32le(Buf + 4, 1); | |
| 2569 | } | |
| 2570 | ||
| 2571 | // The sentinel has to be removed if there are no other .ARM.exidx entries. | |
| 2572 | bool ARMExidxSentinelSection::empty() const { | |
| 2573 | OutputSection *OS = getParent(); | |
| 2574 | for (auto *B : OS->SectionCommands) | |
| 2575 | if (auto *ISD = dyn_cast<InputSectionDescription>(B)) | |
| 2576 | for (auto *S : ISD->Sections) | |
| 2577 | if (!isa<ARMExidxSentinelSection>(S)) | |
| 2578 | return false; | |
| 2579 | return true; | |
| 2310 | 2580 | } |
| 2311 | 2581 | |
| 2312 | 2582 | ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off) |
| ... | ... | @@ -2330,6 +2600,8 @@ void ThunkSection::writeTo(uint8_t *Buf) { |
| 2330 | 2600 | } |
| 2331 | 2601 | |
| 2332 | 2602 | InputSection *ThunkSection::getTargetInputSection() const { |
| 2603 | if (Thunks.empty()) | |
| 2604 | return nullptr; | |
| 2333 | 2605 | const Thunk *T = Thunks.front(); |
| 2334 | 2606 | return T->getTargetInputSection(); |
| 2335 | 2607 | } |
| ... | ... | @@ -2338,7 +2610,8 @@ InputSection *InX::ARMAttributes; |
| 2338 | 2610 | BssSection *InX::Bss; |
| 2339 | 2611 | BssSection *InX::BssRelRo; |
| 2340 | 2612 | BuildIdSection *InX::BuildId; |
| 2341 | InputSection *InX::Common; | |
| 2613 | EhFrameHeader *InX::EhFrameHdr; | |
| 2614 | EhFrameSection *InX::EhFrame; | |
| 2342 | 2615 | SyntheticSection *InX::Dynamic; |
| 2343 | 2616 | StringTableSection *InX::DynStrTab; |
| 2344 | 2617 | SymbolTableBaseSection *InX::DynSymTab; |
| ... | ... | @@ -2347,11 +2620,15 @@ GdbIndexSection *InX::GdbIndex; |
| 2347 | 2620 | GotSection *InX::Got; |
| 2348 | 2621 | GotPltSection *InX::GotPlt; |
| 2349 | 2622 | GnuHashTableSection *InX::GnuHashTab; |
| 2623 | HashTableSection *InX::HashTab; | |
| 2350 | 2624 | IgotPltSection *InX::IgotPlt; |
| 2351 | 2625 | MipsGotSection *InX::MipsGot; |
| 2352 | 2626 | MipsRldMapSection *InX::MipsRldMap; |
| 2353 | 2627 | PltSection *InX::Plt; |
| 2354 | 2628 | PltSection *InX::Iplt; |
| 2629 | RelocationBaseSection *InX::RelaDyn; | |
| 2630 | RelocationBaseSection *InX::RelaPlt; | |
| 2631 | RelocationBaseSection *InX::RelaIplt; | |
| 2355 | 2632 | StringTableSection *InX::ShStrTab; |
| 2356 | 2633 | StringTableSection *InX::StrTab; |
| 2357 | 2634 | SymbolTableBaseSection *InX::SymTab; |
| ... | ... | @@ -2361,20 +2638,15 @@ template GdbIndexSection *elf::createGdbIndex<ELF32BE>(); |
| 2361 | 2638 | template GdbIndexSection *elf::createGdbIndex<ELF64LE>(); |
| 2362 | 2639 | template GdbIndexSection *elf::createGdbIndex<ELF64BE>(); |
| 2363 | 2640 | |
| 2364 | template void PltSection::addEntry<ELF32LE>(SymbolBody &Sym); | |
| 2365 | template void PltSection::addEntry<ELF32BE>(SymbolBody &Sym); | |
| 2366 | template void PltSection::addEntry<ELF64LE>(SymbolBody &Sym); | |
| 2367 | template void PltSection::addEntry<ELF64BE>(SymbolBody &Sym); | |
| 2368 | ||
| 2369 | template InputSection *elf::createCommonSection<ELF32LE>(); | |
| 2370 | template InputSection *elf::createCommonSection<ELF32BE>(); | |
| 2371 | template InputSection *elf::createCommonSection<ELF64LE>(); | |
| 2372 | template InputSection *elf::createCommonSection<ELF64BE>(); | |
| 2641 | template void EhFrameSection::addSection<ELF32LE>(InputSectionBase *); | |
| 2642 | template void EhFrameSection::addSection<ELF32BE>(InputSectionBase *); | |
| 2643 | template void EhFrameSection::addSection<ELF64LE>(InputSectionBase *); | |
| 2644 | template void EhFrameSection::addSection<ELF64BE>(InputSectionBase *); | |
| 2373 | 2645 | |
| 2374 | template MergeInputSection *elf::createCommentSection<ELF32LE>(); | |
| 2375 | template MergeInputSection *elf::createCommentSection<ELF32BE>(); | |
| 2376 | template MergeInputSection *elf::createCommentSection<ELF64LE>(); | |
| 2377 | template MergeInputSection *elf::createCommentSection<ELF64BE>(); | |
| 2646 | template void PltSection::addEntry<ELF32LE>(Symbol &Sym); | |
| 2647 | template void PltSection::addEntry<ELF32BE>(Symbol &Sym); | |
| 2648 | template void PltSection::addEntry<ELF64LE>(Symbol &Sym); | |
| 2649 | template void PltSection::addEntry<ELF64BE>(Symbol &Sym); | |
| 2378 | 2650 | |
| 2379 | 2651 | template class elf::MipsAbiFlagsSection<ELF32LE>; |
| 2380 | 2652 | template class elf::MipsAbiFlagsSection<ELF32BE>; |
| ... | ... | @@ -2401,21 +2673,16 @@ template class elf::RelocationSection<ELF32BE>; |
| 2401 | 2673 | template class elf::RelocationSection<ELF64LE>; |
| 2402 | 2674 | template class elf::RelocationSection<ELF64BE>; |
| 2403 | 2675 | |
| 2676 | template class elf::AndroidPackedRelocationSection<ELF32LE>; | |
| 2677 | template class elf::AndroidPackedRelocationSection<ELF32BE>; | |
| 2678 | template class elf::AndroidPackedRelocationSection<ELF64LE>; | |
| 2679 | template class elf::AndroidPackedRelocationSection<ELF64BE>; | |
| 2680 | ||
| 2404 | 2681 | template class elf::SymbolTableSection<ELF32LE>; |
| 2405 | 2682 | template class elf::SymbolTableSection<ELF32BE>; |
| 2406 | 2683 | template class elf::SymbolTableSection<ELF64LE>; |
| 2407 | 2684 | template class elf::SymbolTableSection<ELF64BE>; |
| 2408 | 2685 | |
| 2409 | template class elf::HashTableSection<ELF32LE>; | |
| 2410 | template class elf::HashTableSection<ELF32BE>; | |
| 2411 | template class elf::HashTableSection<ELF64LE>; | |
| 2412 | template class elf::HashTableSection<ELF64BE>; | |
| 2413 | ||
| 2414 | template class elf::EhFrameHeader<ELF32LE>; | |
| 2415 | template class elf::EhFrameHeader<ELF32BE>; | |
| 2416 | template class elf::EhFrameHeader<ELF64LE>; | |
| 2417 | template class elf::EhFrameHeader<ELF64BE>; | |
| 2418 | ||
| 2419 | 2686 | template class elf::VersionTableSection<ELF32LE>; |
| 2420 | 2687 | template class elf::VersionTableSection<ELF32BE>; |
| 2421 | 2688 | template class elf::VersionTableSection<ELF64LE>; |
| ... | ... | @@ -2430,8 +2697,3 @@ template class elf::VersionDefinitionSection<ELF32LE>; |
| 2430 | 2697 | template class elf::VersionDefinitionSection<ELF32BE>; |
| 2431 | 2698 | template class elf::VersionDefinitionSection<ELF64LE>; |
| 2432 | 2699 | template class elf::VersionDefinitionSection<ELF64BE>; |
| 2433 | ||
| 2434 | template class elf::EhFrameSection<ELF32LE>; | |
| 2435 | template class elf::EhFrameSection<ELF32BE>; | |
| 2436 | template class elf::EhFrameSection<ELF64LE>; | |
| 2437 | template class elf::EhFrameSection<ELF64BE>; |
deps/lld/ELF/SyntheticSections.h+208-150| ... | ... | @@ -26,17 +26,17 @@ |
| 26 | 26 | #include "InputSection.h" |
| 27 | 27 | #include "llvm/ADT/MapVector.h" |
| 28 | 28 | #include "llvm/MC/StringTableBuilder.h" |
| 29 | ||
| 30 | #include <set> | |
| 29 | #include <functional> | |
| 31 | 30 | |
| 32 | 31 | namespace lld { |
| 33 | 32 | namespace elf { |
| 33 | class SharedSymbol; | |
| 34 | 34 | |
| 35 | 35 | class SyntheticSection : public InputSection { |
| 36 | 36 | public: |
| 37 | 37 | SyntheticSection(uint64_t Flags, uint32_t Type, uint32_t Alignment, |
| 38 | 38 | StringRef Name) |
| 39 | : InputSection(Flags, Type, Alignment, {}, Name, | |
| 39 | : InputSection(nullptr, Flags, Type, Alignment, {}, Name, | |
| 40 | 40 | InputSectionBase::Synthetic) { |
| 41 | 41 | this->Live = true; |
| 42 | 42 | } |
| ... | ... | @@ -47,7 +47,7 @@ public: |
| 47 | 47 | virtual void finalizeContents() {} |
| 48 | 48 | // If the section has the SHF_ALLOC flag and the size may be changed if |
| 49 | 49 | // thunks are added, update the section size. |
| 50 | virtual void updateAllocSize() {} | |
| 50 | virtual bool updateAllocSize() { return false; } | |
| 51 | 51 | // If any additional finalization of contents are needed post thunk creation. |
| 52 | 52 | virtual void postThunkContents() {} |
| 53 | 53 | virtual bool empty() const { return false; } |
| ... | ... | @@ -59,21 +59,12 @@ public: |
| 59 | 59 | }; |
| 60 | 60 | |
| 61 | 61 | struct CieRecord { |
| 62 | EhSectionPiece *Piece = nullptr; | |
| 63 | std::vector<EhSectionPiece *> FdePieces; | |
| 62 | EhSectionPiece *Cie = nullptr; | |
| 63 | std::vector<EhSectionPiece *> Fdes; | |
| 64 | 64 | }; |
| 65 | 65 | |
| 66 | 66 | // Section for .eh_frame. |
| 67 | template <class ELFT> class EhFrameSection final : public SyntheticSection { | |
| 68 | typedef typename ELFT::Shdr Elf_Shdr; | |
| 69 | typedef typename ELFT::Rel Elf_Rel; | |
| 70 | typedef typename ELFT::Rela Elf_Rela; | |
| 71 | ||
| 72 | void updateAlignment(uint64_t Val) { | |
| 73 | if (Val > this->Alignment) | |
| 74 | this->Alignment = Val; | |
| 75 | } | |
| 76 | ||
| 67 | class EhFrameSection final : public SyntheticSection { | |
| 77 | 68 | public: |
| 78 | 69 | EhFrameSection(); |
| 79 | 70 | void writeTo(uint8_t *Buf) override; |
| ... | ... | @@ -81,30 +72,36 @@ public: |
| 81 | 72 | bool empty() const override { return Sections.empty(); } |
| 82 | 73 | size_t getSize() const override { return Size; } |
| 83 | 74 | |
| 84 | void addSection(InputSectionBase *S); | |
| 75 | template <class ELFT> void addSection(InputSectionBase *S); | |
| 85 | 76 | |
| 77 | std::vector<EhInputSection *> Sections; | |
| 86 | 78 | size_t NumFdes = 0; |
| 87 | 79 | |
| 88 | std::vector<EhInputSection *> Sections; | |
| 80 | struct FdeData { | |
| 81 | uint32_t Pc; | |
| 82 | uint32_t FdeVA; | |
| 83 | }; | |
| 84 | ||
| 85 | std::vector<FdeData> getFdeData() const; | |
| 89 | 86 | |
| 90 | 87 | private: |
| 91 | 88 | uint64_t Size = 0; |
| 92 | template <class RelTy> | |
| 89 | ||
| 90 | template <class ELFT, class RelTy> | |
| 93 | 91 | void addSectionAux(EhInputSection *S, llvm::ArrayRef<RelTy> Rels); |
| 94 | 92 | |
| 95 | template <class RelTy> | |
| 93 | template <class ELFT, class RelTy> | |
| 96 | 94 | CieRecord *addCie(EhSectionPiece &Piece, ArrayRef<RelTy> Rels); |
| 97 | 95 | |
| 98 | template <class RelTy> | |
| 96 | template <class ELFT, class RelTy> | |
| 99 | 97 | bool isFdeLive(EhSectionPiece &Piece, ArrayRef<RelTy> Rels); |
| 100 | 98 | |
| 101 | uint64_t getFdePc(uint8_t *Buf, size_t Off, uint8_t Enc); | |
| 99 | uint64_t getFdePc(uint8_t *Buf, size_t Off, uint8_t Enc) const; | |
| 102 | 100 | |
| 103 | std::vector<CieRecord *> Cies; | |
| 101 | std::vector<CieRecord *> CieRecords; | |
| 104 | 102 | |
| 105 | 103 | // CIE records are uniquified by their contents and personality functions. |
| 106 | llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord *> | |
| 107 | CieMap; | |
| 104 | llvm::DenseMap<std::pair<ArrayRef<uint8_t>, Symbol *>, CieRecord *> CieMap; | |
| 108 | 105 | }; |
| 109 | 106 | |
| 110 | 107 | class GotSection : public SyntheticSection { |
| ... | ... | @@ -115,11 +112,11 @@ public: |
| 115 | 112 | bool empty() const override; |
| 116 | 113 | void writeTo(uint8_t *Buf) override; |
| 117 | 114 | |
| 118 | void addEntry(SymbolBody &Sym); | |
| 119 | bool addDynTlsEntry(SymbolBody &Sym); | |
| 115 | void addEntry(Symbol &Sym); | |
| 116 | bool addDynTlsEntry(Symbol &Sym); | |
| 120 | 117 | bool addTlsIndex(); |
| 121 | uint64_t getGlobalDynAddr(const SymbolBody &B) const; | |
| 122 | uint64_t getGlobalDynOffset(const SymbolBody &B) const; | |
| 118 | uint64_t getGlobalDynAddr(const Symbol &B) const; | |
| 119 | uint64_t getGlobalDynOffset(const Symbol &B) const; | |
| 123 | 120 | |
| 124 | 121 | uint64_t getTlsIndexVA() { return this->getVA() + TlsIndexOff; } |
| 125 | 122 | uint32_t getTlsIndexOff() const { return TlsIndexOff; } |
| ... | ... | @@ -159,14 +156,13 @@ private: |
| 159 | 156 | // respectively. |
| 160 | 157 | class BssSection final : public SyntheticSection { |
| 161 | 158 | public: |
| 162 | BssSection(StringRef Name); | |
| 159 | BssSection(StringRef Name, uint64_t Size, uint32_t Alignment); | |
| 163 | 160 | void writeTo(uint8_t *) override {} |
| 164 | 161 | bool empty() const override { return getSize() == 0; } |
| 165 | size_t reserveSpace(uint64_t Size, uint32_t Alignment); | |
| 166 | 162 | size_t getSize() const override { return Size; } |
| 167 | 163 | |
| 168 | private: | |
| 169 | uint64_t Size = 0; | |
| 164 | static bool classof(const SectionBase *S) { return S->Bss; } | |
| 165 | uint64_t Size; | |
| 170 | 166 | }; |
| 171 | 167 | |
| 172 | 168 | class MipsGotSection final : public SyntheticSection { |
| ... | ... | @@ -174,21 +170,21 @@ public: |
| 174 | 170 | MipsGotSection(); |
| 175 | 171 | void writeTo(uint8_t *Buf) override; |
| 176 | 172 | size_t getSize() const override { return Size; } |
| 177 | void updateAllocSize() override; | |
| 173 | bool updateAllocSize() override; | |
| 178 | 174 | void finalizeContents() override; |
| 179 | 175 | bool empty() const override; |
| 180 | void addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr); | |
| 181 | bool addDynTlsEntry(SymbolBody &Sym); | |
| 176 | void addEntry(Symbol &Sym, int64_t Addend, RelExpr Expr); | |
| 177 | bool addDynTlsEntry(Symbol &Sym); | |
| 182 | 178 | bool addTlsIndex(); |
| 183 | uint64_t getPageEntryOffset(const SymbolBody &B, int64_t Addend) const; | |
| 184 | uint64_t getBodyEntryOffset(const SymbolBody &B, int64_t Addend) const; | |
| 185 | uint64_t getGlobalDynOffset(const SymbolBody &B) const; | |
| 179 | uint64_t getPageEntryOffset(const Symbol &B, int64_t Addend) const; | |
| 180 | uint64_t getSymEntryOffset(const Symbol &B, int64_t Addend) const; | |
| 181 | uint64_t getGlobalDynOffset(const Symbol &B) const; | |
| 186 | 182 | |
| 187 | 183 | // Returns the symbol which corresponds to the first entry of the global part |
| 188 | 184 | // of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic |
| 189 | 185 | // table properties. |
| 190 | 186 | // Returns nullptr if the global part is empty. |
| 191 | const SymbolBody *getFirstGlobalEntry() const; | |
| 187 | const Symbol *getFirstGlobalEntry() const; | |
| 192 | 188 | |
| 193 | 189 | // Returns the number of entries in the local part of GOT including |
| 194 | 190 | // the number of reserved entries. |
| ... | ... | @@ -248,7 +244,7 @@ private: |
| 248 | 244 | // to the first index of "Page" entries allocated for this section. |
| 249 | 245 | llvm::SmallMapVector<const OutputSection *, size_t, 16> PageIndexMap; |
| 250 | 246 | |
| 251 | typedef std::pair<const SymbolBody *, uint64_t> GotEntry; | |
| 247 | typedef std::pair<const Symbol *, uint64_t> GotEntry; | |
| 252 | 248 | typedef std::vector<GotEntry> GotEntries; |
| 253 | 249 | // Map from Symbol-Addend pair to the GOT index. |
| 254 | 250 | llvm::DenseMap<GotEntry, size_t> EntryIndexMap; |
| ... | ... | @@ -261,7 +257,7 @@ private: |
| 261 | 257 | GotEntries GlobalEntries; |
| 262 | 258 | |
| 263 | 259 | // TLS entries. |
| 264 | std::vector<const SymbolBody *> TlsEntries; | |
| 260 | std::vector<const Symbol *> TlsEntries; | |
| 265 | 261 | |
| 266 | 262 | uint32_t TlsIndexOff = -1; |
| 267 | 263 | uint64_t Size = 0; |
| ... | ... | @@ -270,13 +266,13 @@ private: |
| 270 | 266 | class GotPltSection final : public SyntheticSection { |
| 271 | 267 | public: |
| 272 | 268 | GotPltSection(); |
| 273 | void addEntry(SymbolBody &Sym); | |
| 269 | void addEntry(Symbol &Sym); | |
| 274 | 270 | size_t getSize() const override; |
| 275 | 271 | void writeTo(uint8_t *Buf) override; |
| 276 | 272 | bool empty() const override { return Entries.empty(); } |
| 277 | 273 | |
| 278 | 274 | private: |
| 279 | std::vector<const SymbolBody *> Entries; | |
| 275 | std::vector<const Symbol *> Entries; | |
| 280 | 276 | }; |
| 281 | 277 | |
| 282 | 278 | // The IgotPltSection is a Got associated with the PltSection for GNU Ifunc |
| ... | ... | @@ -286,13 +282,13 @@ private: |
| 286 | 282 | class IgotPltSection final : public SyntheticSection { |
| 287 | 283 | public: |
| 288 | 284 | IgotPltSection(); |
| 289 | void addEntry(SymbolBody &Sym); | |
| 285 | void addEntry(Symbol &Sym); | |
| 290 | 286 | size_t getSize() const override; |
| 291 | 287 | void writeTo(uint8_t *Buf) override; |
| 292 | 288 | bool empty() const override { return Entries.empty(); } |
| 293 | 289 | |
| 294 | 290 | private: |
| 295 | std::vector<const SymbolBody *> Entries; | |
| 291 | std::vector<const Symbol *> Entries; | |
| 296 | 292 | }; |
| 297 | 293 | |
| 298 | 294 | class StringTableSection final : public SyntheticSection { |
| ... | ... | @@ -315,8 +311,7 @@ private: |
| 315 | 311 | class DynamicReloc { |
| 316 | 312 | public: |
| 317 | 313 | DynamicReloc(uint32_t Type, const InputSectionBase *InputSec, |
| 318 | uint64_t OffsetInSec, bool UseSymVA, SymbolBody *Sym, | |
| 319 | int64_t Addend) | |
| 314 | uint64_t OffsetInSec, bool UseSymVA, Symbol *Sym, int64_t Addend) | |
| 320 | 315 | : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec), |
| 321 | 316 | UseSymVA(UseSymVA), Addend(Addend) {} |
| 322 | 317 | |
| ... | ... | @@ -328,7 +323,7 @@ public: |
| 328 | 323 | uint32_t Type; |
| 329 | 324 | |
| 330 | 325 | private: |
| 331 | SymbolBody *Sym; | |
| 326 | Symbol *Sym; | |
| 332 | 327 | const InputSectionBase *InputSec = nullptr; |
| 333 | 328 | uint64_t OffsetInSec; |
| 334 | 329 | bool UseSymVA; |
| ... | ... | @@ -342,30 +337,8 @@ template <class ELFT> class DynamicSection final : public SyntheticSection { |
| 342 | 337 | typedef typename ELFT::Shdr Elf_Shdr; |
| 343 | 338 | typedef typename ELFT::Sym Elf_Sym; |
| 344 | 339 | |
| 345 | // The .dynamic section contains information for the dynamic linker. | |
| 346 | // The section consists of fixed size entries, which consist of | |
| 347 | // type and value fields. Value are one of plain integers, symbol | |
| 348 | // addresses, or section addresses. This struct represents the entry. | |
| 349 | struct Entry { | |
| 350 | int32_t Tag; | |
| 351 | union { | |
| 352 | OutputSection *OutSec; | |
| 353 | InputSection *InSec; | |
| 354 | uint64_t Val; | |
| 355 | const SymbolBody *Sym; | |
| 356 | }; | |
| 357 | enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind; | |
| 358 | Entry(int32_t Tag, OutputSection *OutSec, KindT Kind = SecAddr) | |
| 359 | : Tag(Tag), OutSec(OutSec), Kind(Kind) {} | |
| 360 | Entry(int32_t Tag, InputSection *Sec) | |
| 361 | : Tag(Tag), InSec(Sec), Kind(InSecAddr) {} | |
| 362 | Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {} | |
| 363 | Entry(int32_t Tag, const SymbolBody *Sym) | |
| 364 | : Tag(Tag), Sym(Sym), Kind(SymAddr) {} | |
| 365 | }; | |
| 366 | ||
| 367 | 340 | // finalizeContents() fills this vector with the section contents. |
| 368 | std::vector<Entry> Entries; | |
| 341 | std::vector<std::pair<int32_t, std::function<uint64_t()>>> Entries; | |
| 369 | 342 | |
| 370 | 343 | public: |
| 371 | 344 | DynamicSection(); |
| ... | ... | @@ -374,33 +347,66 @@ public: |
| 374 | 347 | size_t getSize() const override { return Size; } |
| 375 | 348 | |
| 376 | 349 | private: |
| 377 | void addEntries(); | |
| 378 | void add(Entry E) { Entries.push_back(E); } | |
| 350 | void add(int32_t Tag, std::function<uint64_t()> Fn); | |
| 351 | void addInt(int32_t Tag, uint64_t Val); | |
| 352 | void addInSec(int32_t Tag, InputSection *Sec); | |
| 353 | void addOutSec(int32_t Tag, OutputSection *Sec); | |
| 354 | void addSize(int32_t Tag, OutputSection *Sec); | |
| 355 | void addSym(int32_t Tag, Symbol *Sym); | |
| 356 | ||
| 379 | 357 | uint64_t Size = 0; |
| 380 | 358 | }; |
| 381 | 359 | |
| 382 | template <class ELFT> class RelocationSection final : public SyntheticSection { | |
| 360 | class RelocationBaseSection : public SyntheticSection { | |
| 361 | public: | |
| 362 | RelocationBaseSection(StringRef Name, uint32_t Type, int32_t DynamicTag, | |
| 363 | int32_t SizeDynamicTag); | |
| 364 | void addReloc(const DynamicReloc &Reloc); | |
| 365 | bool empty() const override { return Relocs.empty(); } | |
| 366 | size_t getSize() const override { return Relocs.size() * this->Entsize; } | |
| 367 | size_t getRelativeRelocCount() const { return NumRelativeRelocs; } | |
| 368 | void finalizeContents() override; | |
| 369 | int32_t DynamicTag, SizeDynamicTag; | |
| 370 | ||
| 371 | protected: | |
| 372 | std::vector<DynamicReloc> Relocs; | |
| 373 | size_t NumRelativeRelocs = 0; | |
| 374 | }; | |
| 375 | ||
| 376 | template <class ELFT> | |
| 377 | class RelocationSection final : public RelocationBaseSection { | |
| 383 | 378 | typedef typename ELFT::Rel Elf_Rel; |
| 384 | 379 | typedef typename ELFT::Rela Elf_Rela; |
| 385 | 380 | |
| 386 | 381 | public: |
| 387 | 382 | RelocationSection(StringRef Name, bool Sort); |
| 388 | void addReloc(const DynamicReloc &Reloc); | |
| 389 | 383 | unsigned getRelocOffset(); |
| 390 | void finalizeContents() override; | |
| 391 | 384 | void writeTo(uint8_t *Buf) override; |
| 392 | bool empty() const override { return Relocs.empty(); } | |
| 393 | size_t getSize() const override { return Relocs.size() * this->Entsize; } | |
| 394 | size_t getRelativeRelocCount() const { return NumRelativeRelocs; } | |
| 395 | 385 | |
| 396 | 386 | private: |
| 397 | 387 | bool Sort; |
| 398 | size_t NumRelativeRelocs = 0; | |
| 399 | std::vector<DynamicReloc> Relocs; | |
| 388 | }; | |
| 389 | ||
| 390 | template <class ELFT> | |
| 391 | class AndroidPackedRelocationSection final : public RelocationBaseSection { | |
| 392 | typedef typename ELFT::Rel Elf_Rel; | |
| 393 | typedef typename ELFT::Rela Elf_Rela; | |
| 394 | ||
| 395 | public: | |
| 396 | AndroidPackedRelocationSection(StringRef Name); | |
| 397 | ||
| 398 | bool updateAllocSize() override; | |
| 399 | size_t getSize() const override { return RelocData.size(); } | |
| 400 | void writeTo(uint8_t *Buf) override { | |
| 401 | memcpy(Buf, RelocData.data(), RelocData.size()); | |
| 402 | } | |
| 403 | ||
| 404 | private: | |
| 405 | SmallVector<char, 0> RelocData; | |
| 400 | 406 | }; |
| 401 | 407 | |
| 402 | 408 | struct SymbolTableEntry { |
| 403 | SymbolBody *Symbol; | |
| 409 | Symbol *Sym; | |
| 404 | 410 | size_t StrTabOffset; |
| 405 | 411 | }; |
| 406 | 412 | |
| ... | ... | @@ -410,9 +416,9 @@ public: |
| 410 | 416 | void finalizeContents() override; |
| 411 | 417 | void postThunkContents() override; |
| 412 | 418 | size_t getSize() const override { return getNumSymbols() * Entsize; } |
| 413 | void addSymbol(SymbolBody *Body); | |
| 419 | void addSymbol(Symbol *Sym); | |
| 414 | 420 | unsigned getNumSymbols() const { return Symbols.size() + 1; } |
| 415 | size_t getSymbolIndex(SymbolBody *Body); | |
| 421 | size_t getSymbolIndex(Symbol *Sym); | |
| 416 | 422 | ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; } |
| 417 | 423 | |
| 418 | 424 | protected: |
| ... | ... | @@ -420,6 +426,10 @@ protected: |
| 420 | 426 | std::vector<SymbolTableEntry> Symbols; |
| 421 | 427 | |
| 422 | 428 | StringTableSection &StrTabSec; |
| 429 | ||
| 430 | llvm::once_flag OnceFlag; | |
| 431 | llvm::DenseMap<Symbol *, size_t> SymbolIndexMap; | |
| 432 | llvm::DenseMap<OutputSection *, size_t> SectionIndexMap; | |
| 423 | 433 | }; |
| 424 | 434 | |
| 425 | 435 | template <class ELFT> |
| ... | ... | @@ -451,9 +461,10 @@ private: |
| 451 | 461 | void writeHashTable(uint8_t *Buf); |
| 452 | 462 | |
| 453 | 463 | struct Entry { |
| 454 | SymbolBody *Body; | |
| 464 | Symbol *Sym; | |
| 455 | 465 | size_t StrTabOffset; |
| 456 | 466 | uint32_t Hash; |
| 467 | uint32_t BucketIdx; | |
| 457 | 468 | }; |
| 458 | 469 | |
| 459 | 470 | std::vector<Entry> Symbols; |
| ... | ... | @@ -462,7 +473,7 @@ private: |
| 462 | 473 | size_t Size = 0; |
| 463 | 474 | }; |
| 464 | 475 | |
| 465 | template <class ELFT> class HashTableSection final : public SyntheticSection { | |
| 476 | class HashTableSection final : public SyntheticSection { | |
| 466 | 477 | public: |
| 467 | 478 | HashTableSection(); |
| 468 | 479 | void finalizeContents() override; |
| ... | ... | @@ -485,57 +496,81 @@ public: |
| 485 | 496 | bool empty() const override { return Entries.empty(); } |
| 486 | 497 | void addSymbols(); |
| 487 | 498 | |
| 488 | template <class ELFT> void addEntry(SymbolBody &Sym); | |
| 499 | template <class ELFT> void addEntry(Symbol &Sym); | |
| 489 | 500 | |
| 490 | 501 | private: |
| 491 | void writeHeader(uint8_t *Buf){}; | |
| 492 | void addHeaderSymbols(){}; | |
| 493 | 502 | unsigned getPltRelocOff() const; |
| 494 | std::vector<std::pair<const SymbolBody *, unsigned>> Entries; | |
| 503 | std::vector<std::pair<const Symbol *, unsigned>> Entries; | |
| 495 | 504 | // Iplt always has HeaderSize of 0, the Plt HeaderSize is always non-zero |
| 496 | 505 | size_t HeaderSize; |
| 497 | 506 | }; |
| 498 | 507 | |
| 499 | class GdbIndexSection final : public SyntheticSection { | |
| 500 | const unsigned OffsetTypeSize = 4; | |
| 501 | const unsigned CuListOffset = 6 * OffsetTypeSize; | |
| 502 | const unsigned CompilationUnitSize = 16; | |
| 503 | const unsigned AddressEntrySize = 16 + OffsetTypeSize; | |
| 504 | const unsigned SymTabEntrySize = 2 * OffsetTypeSize; | |
| 508 | // GdbIndexChunk is created for each .debug_info section and contains | |
| 509 | // information to create a part of .gdb_index for a given input section. | |
| 510 | struct GdbIndexChunk { | |
| 511 | struct AddressEntry { | |
| 512 | InputSection *Section; | |
| 513 | uint64_t LowAddress; | |
| 514 | uint64_t HighAddress; | |
| 515 | uint32_t CuIndex; | |
| 516 | }; | |
| 517 | ||
| 518 | struct CuEntry { | |
| 519 | uint64_t CuOffset; | |
| 520 | uint64_t CuLength; | |
| 521 | }; | |
| 505 | 522 | |
| 523 | struct NameTypeEntry { | |
| 524 | llvm::CachedHashStringRef Name; | |
| 525 | uint8_t Type; | |
| 526 | }; | |
| 527 | ||
| 528 | InputSection *DebugInfoSec; | |
| 529 | std::vector<AddressEntry> AddressAreas; | |
| 530 | std::vector<CuEntry> CompilationUnits; | |
| 531 | std::vector<NameTypeEntry> NamesAndTypes; | |
| 532 | }; | |
| 533 | ||
| 534 | // The symbol type for the .gdb_index section. | |
| 535 | struct GdbSymbol { | |
| 536 | uint32_t NameHash; | |
| 537 | size_t NameOffset; | |
| 538 | size_t CuVectorIndex; | |
| 539 | }; | |
| 540 | ||
| 541 | class GdbIndexSection final : public SyntheticSection { | |
| 506 | 542 | public: |
| 507 | 543 | GdbIndexSection(std::vector<GdbIndexChunk> &&Chunks); |
| 508 | void finalizeContents() override; | |
| 509 | 544 | void writeTo(uint8_t *Buf) override; |
| 510 | 545 | size_t getSize() const override; |
| 511 | 546 | bool empty() const override; |
| 512 | 547 | |
| 513 | // Symbol table is a hash table for types and names. | |
| 514 | // It is the area of gdb index. | |
| 515 | GdbHashTab SymbolTable; | |
| 548 | private: | |
| 549 | void fixCuIndex(); | |
| 550 | std::vector<std::vector<uint32_t>> createCuVectors(); | |
| 551 | std::vector<GdbSymbol *> createGdbSymtab(); | |
| 552 | ||
| 553 | // A symbol table for this .gdb_index section. | |
| 554 | std::vector<GdbSymbol *> GdbSymtab; | |
| 516 | 555 | |
| 517 | 556 | // CU vector is a part of constant pool area of section. |
| 518 | std::vector<std::set<uint32_t>> CuVectors; | |
| 557 | std::vector<std::vector<uint32_t>> CuVectors; | |
| 519 | 558 | |
| 520 | // String pool is also a part of constant pool, it follows CU vectors. | |
| 521 | llvm::StringTableBuilder StringPool; | |
| 559 | // Symbol table contents. | |
| 560 | llvm::DenseMap<llvm::CachedHashStringRef, GdbSymbol *> Symbols; | |
| 522 | 561 | |
| 523 | 562 | // Each chunk contains information gathered from a debug sections of single |
| 524 | 563 | // object and used to build different areas of gdb index. |
| 525 | 564 | std::vector<GdbIndexChunk> Chunks; |
| 526 | 565 | |
| 527 | private: | |
| 528 | void buildIndex(); | |
| 529 | ||
| 566 | static constexpr uint32_t CuListOffset = 24; | |
| 530 | 567 | uint32_t CuTypesOffset; |
| 531 | uint32_t SymTabOffset; | |
| 568 | uint32_t SymtabOffset; | |
| 532 | 569 | uint32_t ConstantPoolOffset; |
| 533 | 570 | uint32_t StringPoolOffset; |
| 571 | uint32_t StringPoolSize; | |
| 534 | 572 | |
| 535 | size_t CuVectorsSize = 0; | |
| 536 | std::vector<size_t> CuVectorsOffset; | |
| 537 | ||
| 538 | bool Finalized = false; | |
| 573 | std::vector<size_t> CuVectorOffsets; | |
| 539 | 574 | }; |
| 540 | 575 | |
| 541 | 576 | template <class ELFT> GdbIndexSection *createGdbIndex(); |
| ... | ... | @@ -549,21 +584,12 @@ template <class ELFT> GdbIndexSection *createGdbIndex(); |
| 549 | 584 | // Detailed info about internals can be found in Ian Lance Taylor's blog: |
| 550 | 585 | // http://www.airs.com/blog/archives/460 (".eh_frame") |
| 551 | 586 | // http://www.airs.com/blog/archives/462 (".eh_frame_hdr") |
| 552 | template <class ELFT> class EhFrameHeader final : public SyntheticSection { | |
| 587 | class EhFrameHeader final : public SyntheticSection { | |
| 553 | 588 | public: |
| 554 | 589 | EhFrameHeader(); |
| 555 | 590 | void writeTo(uint8_t *Buf) override; |
| 556 | 591 | size_t getSize() const override; |
| 557 | void addFde(uint32_t Pc, uint32_t FdeVA); | |
| 558 | 592 | bool empty() const override; |
| 559 | ||
| 560 | private: | |
| 561 | struct FdeData { | |
| 562 | uint32_t Pc; | |
| 563 | uint32_t FdeVA; | |
| 564 | }; | |
| 565 | ||
| 566 | std::vector<FdeData> Fdes; | |
| 567 | 593 | }; |
| 568 | 594 | |
| 569 | 595 | // For more information about .gnu.version and .gnu.version_r see: |
| ... | ... | @@ -639,22 +665,58 @@ public: |
| 639 | 665 | // with different attributes in a single output sections. To do that |
| 640 | 666 | // we put them into MergeSyntheticSection synthetic input sections which are |
| 641 | 667 | // attached to regular output sections. |
| 642 | class MergeSyntheticSection final : public SyntheticSection { | |
| 668 | class MergeSyntheticSection : public SyntheticSection { | |
| 643 | 669 | public: |
| 644 | MergeSyntheticSection(StringRef Name, uint32_t Type, uint64_t Flags, | |
| 645 | uint32_t Alignment); | |
| 646 | 670 | void addSection(MergeInputSection *MS); |
| 671 | ||
| 672 | protected: | |
| 673 | MergeSyntheticSection(StringRef Name, uint32_t Type, uint64_t Flags, | |
| 674 | uint32_t Alignment) | |
| 675 | : SyntheticSection(Flags, Type, Alignment, Name) {} | |
| 676 | ||
| 677 | std::vector<MergeInputSection *> Sections; | |
| 678 | }; | |
| 679 | ||
| 680 | class MergeTailSection final : public MergeSyntheticSection { | |
| 681 | public: | |
| 682 | MergeTailSection(StringRef Name, uint32_t Type, uint64_t Flags, | |
| 683 | uint32_t Alignment); | |
| 684 | ||
| 685 | size_t getSize() const override; | |
| 647 | 686 | void writeTo(uint8_t *Buf) override; |
| 648 | 687 | void finalizeContents() override; |
| 649 | bool shouldTailMerge() const; | |
| 650 | size_t getSize() const override; | |
| 651 | 688 | |
| 652 | 689 | private: |
| 653 | void finalizeTailMerge(); | |
| 654 | void finalizeNoTailMerge(); | |
| 655 | ||
| 656 | 690 | llvm::StringTableBuilder Builder; |
| 657 | std::vector<MergeInputSection *> Sections; | |
| 691 | }; | |
| 692 | ||
| 693 | class MergeNoTailSection final : public MergeSyntheticSection { | |
| 694 | public: | |
| 695 | MergeNoTailSection(StringRef Name, uint32_t Type, uint64_t Flags, | |
| 696 | uint32_t Alignment) | |
| 697 | : MergeSyntheticSection(Name, Type, Flags, Alignment) {} | |
| 698 | ||
| 699 | size_t getSize() const override { return Size; } | |
| 700 | void writeTo(uint8_t *Buf) override; | |
| 701 | void finalizeContents() override; | |
| 702 | ||
| 703 | private: | |
| 704 | // We use the most significant bits of a hash as a shard ID. | |
| 705 | // The reason why we don't want to use the least significant bits is | |
| 706 | // because DenseMap also uses lower bits to determine a bucket ID. | |
| 707 | // If we use lower bits, it significantly increases the probability of | |
| 708 | // hash collisons. | |
| 709 | size_t getShardId(uint32_t Hash) { | |
| 710 | return Hash >> (32 - llvm::countTrailingZeros(NumShards)); | |
| 711 | } | |
| 712 | ||
| 713 | // Section size | |
| 714 | size_t Size; | |
| 715 | ||
| 716 | // String table contents | |
| 717 | constexpr static size_t NumShards = 32; | |
| 718 | std::vector<llvm::StringTableBuilder> Shards; | |
| 719 | size_t ShardOffsets[NumShards]; | |
| 658 | 720 | }; |
| 659 | 721 | |
| 660 | 722 | // .MIPS.abiflags section. |
| ... | ... | @@ -723,6 +785,9 @@ public: |
| 723 | 785 | ARMExidxSentinelSection(); |
| 724 | 786 | size_t getSize() const override { return 8; } |
| 725 | 787 | void writeTo(uint8_t *Buf) override; |
| 788 | bool empty() const override; | |
| 789 | ||
| 790 | InputSection *Highest = 0; | |
| 726 | 791 | }; |
| 727 | 792 | |
| 728 | 793 | // A container for one or more linker generated thunks. Instances of these |
| ... | ... | @@ -746,13 +811,13 @@ private: |
| 746 | 811 | size_t Size = 0; |
| 747 | 812 | }; |
| 748 | 813 | |
| 749 | template <class ELFT> InputSection *createCommonSection(); | |
| 750 | 814 | InputSection *createInterpSection(); |
| 751 | template <class ELFT> MergeInputSection *createCommentSection(); | |
| 752 | void decompressAndMergeSections(); | |
| 815 | MergeInputSection *createCommentSection(); | |
| 816 | void decompressSections(); | |
| 817 | void mergeSections(); | |
| 753 | 818 | |
| 754 | SymbolBody *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, | |
| 755 | uint64_t Size, InputSectionBase *Section); | |
| 819 | Symbol *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, | |
| 820 | uint64_t Size, InputSectionBase &Section); | |
| 756 | 821 | |
| 757 | 822 | // Linker generated sections which can be used as inputs. |
| 758 | 823 | struct InX { |
| ... | ... | @@ -760,11 +825,13 @@ struct InX { |
| 760 | 825 | static BssSection *Bss; |
| 761 | 826 | static BssSection *BssRelRo; |
| 762 | 827 | static BuildIdSection *BuildId; |
| 763 | static InputSection *Common; | |
| 828 | static EhFrameHeader *EhFrameHdr; | |
| 829 | static EhFrameSection *EhFrame; | |
| 764 | 830 | static SyntheticSection *Dynamic; |
| 765 | 831 | static StringTableSection *DynStrTab; |
| 766 | 832 | static SymbolTableBaseSection *DynSymTab; |
| 767 | 833 | static GnuHashTableSection *GnuHashTab; |
| 834 | static HashTableSection *HashTab; | |
| 768 | 835 | static InputSection *Interp; |
| 769 | 836 | static GdbIndexSection *GdbIndex; |
| 770 | 837 | static GotSection *Got; |
| ... | ... | @@ -774,29 +841,20 @@ struct InX { |
| 774 | 841 | static MipsRldMapSection *MipsRldMap; |
| 775 | 842 | static PltSection *Plt; |
| 776 | 843 | static PltSection *Iplt; |
| 844 | static RelocationBaseSection *RelaDyn; | |
| 845 | static RelocationBaseSection *RelaPlt; | |
| 846 | static RelocationBaseSection *RelaIplt; | |
| 777 | 847 | static StringTableSection *ShStrTab; |
| 778 | 848 | static StringTableSection *StrTab; |
| 779 | 849 | static SymbolTableBaseSection *SymTab; |
| 780 | 850 | }; |
| 781 | 851 | |
| 782 | template <class ELFT> struct In : public InX { | |
| 783 | static EhFrameHeader<ELFT> *EhFrameHdr; | |
| 784 | static EhFrameSection<ELFT> *EhFrame; | |
| 785 | static HashTableSection<ELFT> *HashTab; | |
| 786 | static RelocationSection<ELFT> *RelaDyn; | |
| 787 | static RelocationSection<ELFT> *RelaPlt; | |
| 788 | static RelocationSection<ELFT> *RelaIplt; | |
| 852 | template <class ELFT> struct In { | |
| 789 | 853 | static VersionDefinitionSection<ELFT> *VerDef; |
| 790 | 854 | static VersionTableSection<ELFT> *VerSym; |
| 791 | 855 | static VersionNeedSection<ELFT> *VerNeed; |
| 792 | 856 | }; |
| 793 | 857 | |
| 794 | template <class ELFT> EhFrameHeader<ELFT> *In<ELFT>::EhFrameHdr; | |
| 795 | template <class ELFT> EhFrameSection<ELFT> *In<ELFT>::EhFrame; | |
| 796 | template <class ELFT> HashTableSection<ELFT> *In<ELFT>::HashTab; | |
| 797 | template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaDyn; | |
| 798 | template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaPlt; | |
| 799 | template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaIplt; | |
| 800 | 858 | template <class ELFT> VersionDefinitionSection<ELFT> *In<ELFT>::VerDef; |
| 801 | 859 | template <class ELFT> VersionTableSection<ELFT> *In<ELFT>::VerSym; |
| 802 | 860 | template <class ELFT> VersionNeedSection<ELFT> *In<ELFT>::VerNeed; |
deps/lld/ELF/Target.cpp+21-15| ... | ... | @@ -25,11 +25,11 @@ |
| 25 | 25 | //===----------------------------------------------------------------------===// |
| 26 | 26 | |
| 27 | 27 | #include "Target.h" |
| 28 | #include "Error.h" | |
| 29 | 28 | #include "InputFiles.h" |
| 30 | 29 | #include "OutputSections.h" |
| 31 | 30 | #include "SymbolTable.h" |
| 32 | 31 | #include "Symbols.h" |
| 32 | #include "lld/Common/ErrorHandler.h" | |
| 33 | 33 | #include "llvm/Object/ELF.h" |
| 34 | 34 | |
| 35 | 35 | using namespace llvm; |
| ... | ... | @@ -40,7 +40,7 @@ using namespace lld::elf; |
| 40 | 40 | |
| 41 | 41 | TargetInfo *elf::Target; |
| 42 | 42 | |
| 43 | std::string lld::toString(uint32_t Type) { | |
| 43 | std::string lld::toString(RelType Type) { | |
| 44 | 44 | StringRef S = getELFRelocationTypeName(elf::Config->EMachine, Type); |
| 45 | 45 | if (S == "Unknown") |
| 46 | 46 | return ("Unknown (" + Twine(Type) + ")").str(); |
| ... | ... | @@ -89,7 +89,7 @@ TargetInfo *elf::getTarget() { |
| 89 | 89 | |
| 90 | 90 | template <class ELFT> static std::string getErrorLoc(const uint8_t *Loc) { |
| 91 | 91 | for (InputSectionBase *D : InputSections) { |
| 92 | auto *IS = dyn_cast_or_null<InputSection>(D); | |
| 92 | auto *IS = dyn_cast<InputSection>(D); | |
| 93 | 93 | if (!IS || !IS->getParent()) |
| 94 | 94 | continue; |
| 95 | 95 | |
| ... | ... | @@ -117,27 +117,26 @@ std::string elf::getErrorLocation(const uint8_t *Loc) { |
| 117 | 117 | |
| 118 | 118 | TargetInfo::~TargetInfo() {} |
| 119 | 119 | |
| 120 | int64_t TargetInfo::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const { | |
| 120 | int64_t TargetInfo::getImplicitAddend(const uint8_t *Buf, RelType Type) const { | |
| 121 | 121 | return 0; |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | bool TargetInfo::usesOnlyLowPageBits(uint32_t Type) const { return false; } | |
| 124 | bool TargetInfo::usesOnlyLowPageBits(RelType Type) const { return false; } | |
| 125 | 125 | |
| 126 | bool TargetInfo::needsThunk(RelExpr Expr, uint32_t RelocType, | |
| 127 | const InputFile *File, const SymbolBody &S) const { | |
| 126 | bool TargetInfo::needsThunk(RelExpr Expr, RelType Type, const InputFile *File, | |
| 127 | uint64_t BranchAddr, const Symbol &S) const { | |
| 128 | 128 | return false; |
| 129 | 129 | } |
| 130 | 130 | |
| 131 | bool TargetInfo::inBranchRange(uint32_t RelocType, uint64_t Src, | |
| 132 | uint64_t Dst) const { | |
| 131 | bool TargetInfo::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const { | |
| 133 | 132 | return true; |
| 134 | 133 | } |
| 135 | 134 | |
| 136 | void TargetInfo::writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const { | |
| 135 | void TargetInfo::writeIgotPlt(uint8_t *Buf, const Symbol &S) const { | |
| 137 | 136 | writeGotPlt(Buf, S); |
| 138 | 137 | } |
| 139 | 138 | |
| 140 | RelExpr TargetInfo::adjustRelaxExpr(uint32_t Type, const uint8_t *Data, | |
| 139 | RelExpr TargetInfo::adjustRelaxExpr(RelType Type, const uint8_t *Data, | |
| 141 | 140 | RelExpr Expr) const { |
| 142 | 141 | return Expr; |
| 143 | 142 | } |
| ... | ... | @@ -146,22 +145,29 @@ void TargetInfo::relaxGot(uint8_t *Loc, uint64_t Val) const { |
| 146 | 145 | llvm_unreachable("Should not have claimed to be relaxable"); |
| 147 | 146 | } |
| 148 | 147 | |
| 149 | void TargetInfo::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, | |
| 148 | void TargetInfo::relaxTlsGdToLe(uint8_t *Loc, RelType Type, | |
| 150 | 149 | uint64_t Val) const { |
| 151 | 150 | llvm_unreachable("Should not have claimed to be relaxable"); |
| 152 | 151 | } |
| 153 | 152 | |
| 154 | void TargetInfo::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, | |
| 153 | void TargetInfo::relaxTlsGdToIe(uint8_t *Loc, RelType Type, | |
| 155 | 154 | uint64_t Val) const { |
| 156 | 155 | llvm_unreachable("Should not have claimed to be relaxable"); |
| 157 | 156 | } |
| 158 | 157 | |
| 159 | void TargetInfo::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, | |
| 158 | void TargetInfo::relaxTlsIeToLe(uint8_t *Loc, RelType Type, | |
| 160 | 159 | uint64_t Val) const { |
| 161 | 160 | llvm_unreachable("Should not have claimed to be relaxable"); |
| 162 | 161 | } |
| 163 | 162 | |
| 164 | void TargetInfo::relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, | |
| 163 | void TargetInfo::relaxTlsLdToLe(uint8_t *Loc, RelType Type, | |
| 165 | 164 | uint64_t Val) const { |
| 166 | 165 | llvm_unreachable("Should not have claimed to be relaxable"); |
| 167 | 166 | } |
| 167 | ||
| 168 | uint64_t TargetInfo::getImageBase() { | |
| 169 | // Use -image-base if set. Fall back to the target default if not. | |
| 170 | if (Config->ImageBase) | |
| 171 | return *Config->ImageBase; | |
| 172 | return Config->Pic ? 0 : DefaultImageBase; | |
| 173 | } |
deps/lld/ELF/Target.h+69-46| ... | ... | @@ -10,25 +10,27 @@ |
| 10 | 10 | #ifndef LLD_ELF_TARGET_H |
| 11 | 11 | #define LLD_ELF_TARGET_H |
| 12 | 12 | |
| 13 | #include "Error.h" | |
| 14 | 13 | #include "InputSection.h" |
| 14 | #include "lld/Common/ErrorHandler.h" | |
| 15 | 15 | #include "llvm/Object/ELF.h" |
| 16 | 16 | |
| 17 | 17 | namespace lld { |
| 18 | std::string toString(uint32_t RelType); | |
| 18 | std::string toString(elf::RelType Type); | |
| 19 | 19 | |
| 20 | 20 | namespace elf { |
| 21 | class Defined; | |
| 21 | 22 | class InputFile; |
| 22 | class SymbolBody; | |
| 23 | class Symbol; | |
| 23 | 24 | |
| 24 | 25 | class TargetInfo { |
| 25 | 26 | public: |
| 26 | virtual bool isPicRel(uint32_t Type) const { return true; } | |
| 27 | virtual uint32_t getDynRel(uint32_t Type) const { return Type; } | |
| 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 | 30 | virtual void writeGotPltHeader(uint8_t *Buf) const {} |
| 29 | virtual void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const {}; | |
| 30 | virtual void writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const; | |
| 31 | virtual int64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const; | |
| 31 | virtual void writeGotPlt(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; | |
| 32 | 34 | |
| 33 | 35 | // If lazy binding is supported, the first entry of the PLT has code |
| 34 | 36 | // to call the dynamic linker to resolve PLT entries the first time |
| ... | ... | @@ -38,50 +40,54 @@ public: |
| 38 | 40 | virtual void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, |
| 39 | 41 | uint64_t PltEntryAddr, int32_t Index, |
| 40 | 42 | unsigned RelOff) const {} |
| 41 | virtual void addPltHeaderSymbols(InputSectionBase *IS) const {} | |
| 42 | virtual void addPltSymbols(InputSectionBase *IS, uint64_t Off) const {} | |
| 43 | virtual void addPltHeaderSymbols(InputSection &IS) const {} | |
| 44 | virtual void addPltSymbols(InputSection &IS, uint64_t Off) const {} | |
| 45 | ||
| 43 | 46 | // Returns true if a relocation only uses the low bits of a value such that |
| 44 | 47 | // all those bits are in in the same page. For example, if the relocation |
| 45 | 48 | // only uses the low 12 bits in a system with 4k pages. If this is true, the |
| 46 | 49 | // bits will always have the same value at runtime and we don't have to emit |
| 47 | 50 | // a dynamic relocation. |
| 48 | virtual bool usesOnlyLowPageBits(uint32_t Type) const; | |
| 51 | virtual bool usesOnlyLowPageBits(RelType Type) const; | |
| 49 | 52 | |
| 50 | 53 | // Decide whether a Thunk is needed for the relocation from File |
| 51 | 54 | // targeting S. |
| 52 | virtual bool needsThunk(RelExpr Expr, uint32_t RelocType, | |
| 53 | const InputFile *File, const SymbolBody &S) const; | |
| 55 | virtual bool needsThunk(RelExpr Expr, RelType RelocType, | |
| 56 | const InputFile *File, uint64_t BranchAddr, | |
| 57 | const Symbol &S) const; | |
| 54 | 58 | // Return true if we can reach Dst from Src with Relocation RelocType |
| 55 | virtual bool inBranchRange(uint32_t RelocType, uint64_t Src, | |
| 59 | virtual bool inBranchRange(RelType Type, uint64_t Src, | |
| 56 | 60 | uint64_t Dst) const; |
| 57 | virtual RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, | |
| 61 | virtual RelExpr getRelExpr(RelType Type, const Symbol &S, | |
| 58 | 62 | const uint8_t *Loc) const = 0; |
| 59 | virtual void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const = 0; | |
| 63 | ||
| 64 | virtual void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const = 0; | |
| 65 | ||
| 60 | 66 | virtual ~TargetInfo(); |
| 61 | 67 | |
| 62 | 68 | unsigned TlsGdRelaxSkip = 1; |
| 63 | 69 | unsigned PageSize = 4096; |
| 64 | 70 | unsigned DefaultMaxPageSize = 4096; |
| 65 | 71 | |
| 66 | // On FreeBSD x86_64 the first page cannot be mmaped. | |
| 67 | // On Linux that is controled by vm.mmap_min_addr. At least on some x86_64 | |
| 68 | // installs that is 65536, so the first 15 pages cannot be used. | |
| 69 | // Given that, the smallest value that can be used in here is 0x10000. | |
| 70 | uint64_t DefaultImageBase = 0x10000; | |
| 72 | uint64_t getImageBase(); | |
| 71 | 73 | |
| 72 | 74 | // Offset of _GLOBAL_OFFSET_TABLE_ from base of .got section. Use -1 for |
| 73 | 75 | // end of .got |
| 74 | 76 | uint64_t GotBaseSymOff = 0; |
| 75 | 77 | |
| 76 | uint32_t CopyRel; | |
| 77 | uint32_t GotRel; | |
| 78 | uint32_t PltRel; | |
| 79 | uint32_t RelativeRel; | |
| 80 | uint32_t IRelativeRel; | |
| 81 | uint32_t TlsDescRel; | |
| 82 | uint32_t TlsGotRel; | |
| 83 | uint32_t TlsModuleIndexRel; | |
| 84 | uint32_t TlsOffsetRel; | |
| 78 | // On systems with range extensions we place collections of Thunks at | |
| 79 | // regular spacings that enable the majority of branches reach the Thunks. | |
| 80 | uint32_t ThunkSectionSpacing = 0; | |
| 81 | ||
| 82 | RelType CopyRel; | |
| 83 | RelType GotRel; | |
| 84 | RelType PltRel; | |
| 85 | RelType RelativeRel; | |
| 86 | RelType IRelativeRel; | |
| 87 | RelType TlsDescRel; | |
| 88 | RelType TlsGotRel; | |
| 89 | RelType TlsModuleIndexRel; | |
| 90 | RelType TlsOffsetRel; | |
| 85 | 91 | unsigned GotEntrySize = 0; |
| 86 | 92 | unsigned GotPltEntrySize = 0; |
| 87 | 93 | unsigned PltEntrySize; |
| ... | ... | @@ -100,13 +106,20 @@ public: |
| 100 | 106 | // executable OutputSections. |
| 101 | 107 | uint32_t TrapInstr = 0; |
| 102 | 108 | |
| 103 | virtual RelExpr adjustRelaxExpr(uint32_t Type, const uint8_t *Data, | |
| 109 | virtual RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data, | |
| 104 | 110 | RelExpr Expr) const; |
| 105 | 111 | virtual void relaxGot(uint8_t *Loc, uint64_t Val) const; |
| 106 | virtual void relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const; | |
| 107 | virtual void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const; | |
| 108 | virtual void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const; | |
| 109 | virtual void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const; | |
| 112 | virtual void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const; | |
| 113 | virtual void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const; | |
| 114 | virtual void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const; | |
| 115 | virtual void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const; | |
| 116 | ||
| 117 | protected: | |
| 118 | // On FreeBSD x86_64 the first page cannot be mmaped. | |
| 119 | // On Linux that is controled by vm.mmap_min_addr. At least on some x86_64 | |
| 120 | // installs that is 65536, so the first 15 pages cannot be used. | |
| 121 | // Given that, the smallest value that can be used in here is 0x10000. | |
| 122 | uint64_t DefaultImageBase = 0x10000; | |
| 110 | 123 | }; |
| 111 | 124 | |
| 112 | 125 | TargetInfo *getAArch64TargetInfo(); |
| ... | ... | @@ -129,32 +142,42 @@ uint64_t getAArch64Page(uint64_t Expr); |
| 129 | 142 | extern TargetInfo *Target; |
| 130 | 143 | TargetInfo *getTarget(); |
| 131 | 144 | |
| 145 | template <class ELFT> bool isMipsPIC(const Defined *Sym); | |
| 146 | ||
| 147 | static inline void reportRangeError(uint8_t *Loc, RelType Type, const Twine &V, | |
| 148 | int64_t Min, uint64_t Max) { | |
| 149 | error(getErrorLocation(Loc) + "relocation " + lld::toString(Type) + | |
| 150 | " out of range: " + V + " is not in [" + Twine(Min) + ", " + | |
| 151 | Twine(Max) + "]"); | |
| 152 | } | |
| 153 | ||
| 132 | 154 | template <unsigned N> |
| 133 | static void checkInt(uint8_t *Loc, int64_t V, uint32_t Type) { | |
| 155 | static void checkInt(uint8_t *Loc, int64_t V, RelType Type) { | |
| 134 | 156 | if (!llvm::isInt<N>(V)) |
| 135 | error(getErrorLocation(Loc) + "relocation " + lld::toString(Type) + | |
| 136 | " out of range"); | |
| 157 | reportRangeError(Loc, Type, Twine(V), llvm::minIntN(N), llvm::maxIntN(N)); | |
| 137 | 158 | } |
| 138 | 159 | |
| 139 | 160 | template <unsigned N> |
| 140 | static void checkUInt(uint8_t *Loc, uint64_t V, uint32_t Type) { | |
| 161 | static void checkUInt(uint8_t *Loc, uint64_t V, RelType Type) { | |
| 141 | 162 | if (!llvm::isUInt<N>(V)) |
| 142 | error(getErrorLocation(Loc) + "relocation " + lld::toString(Type) + | |
| 143 | " out of range"); | |
| 163 | reportRangeError(Loc, Type, Twine(V), 0, llvm::maxUIntN(N)); | |
| 144 | 164 | } |
| 145 | 165 | |
| 146 | 166 | template <unsigned N> |
| 147 | static void checkIntUInt(uint8_t *Loc, uint64_t V, uint32_t Type) { | |
| 167 | static void checkIntUInt(uint8_t *Loc, uint64_t V, RelType Type) { | |
| 148 | 168 | if (!llvm::isInt<N>(V) && !llvm::isUInt<N>(V)) |
| 149 | error(getErrorLocation(Loc) + "relocation " + lld::toString(Type) + | |
| 150 | " out of range"); | |
| 169 | // For the error message we should cast V to a signed integer so that error | |
| 170 | // messages show a small negative value rather than an extremely large one | |
| 171 | reportRangeError(Loc, Type, Twine((int64_t)V), llvm::minIntN(N), | |
| 172 | llvm::maxUIntN(N)); | |
| 151 | 173 | } |
| 152 | 174 | |
| 153 | 175 | template <unsigned N> |
| 154 | static void checkAlignment(uint8_t *Loc, uint64_t V, uint32_t Type) { | |
| 176 | static void checkAlignment(uint8_t *Loc, uint64_t V, RelType Type) { | |
| 155 | 177 | if ((V & (N - 1)) != 0) |
| 156 | 178 | error(getErrorLocation(Loc) + "improper alignment for relocation " + |
| 157 | lld::toString(Type)); | |
| 179 | lld::toString(Type) + ": 0x" + llvm::utohexstr(V) + | |
| 180 | " is not aligned to " + Twine(N) + " bytes"); | |
| 158 | 181 | } |
| 159 | 182 | } // namespace elf |
| 160 | 183 | } // namespace lld |
deps/lld/ELF/Threads.h deleted-88| ... | ... | @@ -1,88 +0,0 @@ |
| 1 | //===- Threads.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 | // LLD supports threads to distribute workloads to multiple cores. Using | |
| 11 | // multicore is most effective when more than one core are idle. At the | |
| 12 | // last step of a build, it is often the case that a linker is the only | |
| 13 | // active process on a computer. So, we are naturally interested in using | |
| 14 | // threads wisely to reduce latency to deliver results to users. | |
| 15 | // | |
| 16 | // That said, we don't want to do "too clever" things using threads. | |
| 17 | // Complex multi-threaded algorithms are sometimes extremely hard to | |
| 18 | // reason about and can easily mess up the entire design. | |
| 19 | // | |
| 20 | // Fortunately, when a linker links large programs (when the link time is | |
| 21 | // most critical), it spends most of the time to work on massive number of | |
| 22 | // small pieces of data of the same kind, and there are opportunities for | |
| 23 | // large parallelism there. Here are examples: | |
| 24 | // | |
| 25 | // - We have hundreds of thousands of input sections that need to be | |
| 26 | // copied to a result file at the last step of link. Once we fix a file | |
| 27 | // layout, each section can be copied to its destination and its | |
| 28 | // relocations can be applied independently. | |
| 29 | // | |
| 30 | // - We have tens of millions of small strings when constructing a | |
| 31 | // mergeable string section. | |
| 32 | // | |
| 33 | // For the cases such as the former, we can just use parallel_for_each | |
| 34 | // instead of std::for_each (or a plain for loop). Because tasks are | |
| 35 | // completely independent from each other, we can run them in parallel | |
| 36 | // without any coordination between them. That's very easy to understand | |
| 37 | // and reason about. | |
| 38 | // | |
| 39 | // For the cases such as the latter, we can use parallel algorithms to | |
| 40 | // deal with massive data. We have to write code for a tailored algorithm | |
| 41 | // for each problem, but the complexity of multi-threading is isolated in | |
| 42 | // a single pass and doesn't affect the linker's overall design. | |
| 43 | // | |
| 44 | // The above approach seems to be working fairly well. As an example, when | |
| 45 | // linking Chromium (output size 1.6 GB), using 4 cores reduces latency to | |
| 46 | // 75% compared to single core (from 12.66 seconds to 9.55 seconds) on my | |
| 47 | // Ivy Bridge Xeon 2.8 GHz machine. Using 40 cores reduces it to 63% (from | |
| 48 | // 12.66 seconds to 7.95 seconds). Because of the Amdahl's law, the | |
| 49 | // speedup is not linear, but as you add more cores, it gets faster. | |
| 50 | // | |
| 51 | // On a final note, if you are trying to optimize, keep the axiom "don't | |
| 52 | // guess, measure!" in mind. Some important passes of the linker are not | |
| 53 | // that slow. For example, resolving all symbols is not a very heavy pass, | |
| 54 | // although it would be very hard to parallelize it. You want to first | |
| 55 | // identify a slow pass and then optimize it. | |
| 56 | // | |
| 57 | //===----------------------------------------------------------------------===// | |
| 58 | ||
| 59 | #ifndef LLD_ELF_THREADS_H | |
| 60 | #define LLD_ELF_THREADS_H | |
| 61 | ||
| 62 | #include "Config.h" | |
| 63 | ||
| 64 | #include "llvm/Support/Parallel.h" | |
| 65 | #include <functional> | |
| 66 | ||
| 67 | namespace lld { | |
| 68 | namespace elf { | |
| 69 | ||
| 70 | template <class IterTy, class FuncTy> | |
| 71 | void parallelForEach(IterTy Begin, IterTy End, FuncTy Fn) { | |
| 72 | if (Config->Threads) | |
| 73 | for_each(llvm::parallel::par, Begin, End, Fn); | |
| 74 | else | |
| 75 | for_each(llvm::parallel::seq, Begin, End, Fn); | |
| 76 | } | |
| 77 | ||
| 78 | inline void parallelForEachN(size_t Begin, size_t End, | |
| 79 | std::function<void(size_t)> Fn) { | |
| 80 | if (Config->Threads) | |
| 81 | for_each_n(llvm::parallel::par, Begin, End, Fn); | |
| 82 | else | |
| 83 | for_each_n(llvm::parallel::seq, Begin, End, Fn); | |
| 84 | } | |
| 85 | } // namespace elf | |
| 86 | } // namespace lld | |
| 87 | ||
| 88 | #endif |
deps/lld/ELF/Thunks.cpp+208-47| ... | ... | @@ -23,13 +23,13 @@ |
| 23 | 23 | |
| 24 | 24 | #include "Thunks.h" |
| 25 | 25 | #include "Config.h" |
| 26 | #include "Error.h" | |
| 27 | 26 | #include "InputSection.h" |
| 28 | #include "Memory.h" | |
| 29 | 27 | #include "OutputSections.h" |
| 30 | 28 | #include "Symbols.h" |
| 31 | 29 | #include "SyntheticSections.h" |
| 32 | 30 | #include "Target.h" |
| 31 | #include "lld/Common/ErrorHandler.h" | |
| 32 | #include "lld/Common/Memory.h" | |
| 33 | 33 | #include "llvm/BinaryFormat/ELF.h" |
| 34 | 34 | #include "llvm/Support/Casting.h" |
| 35 | 35 | #include "llvm/Support/Endian.h" |
| ... | ... | @@ -48,52 +48,69 @@ namespace elf { |
| 48 | 48 | |
| 49 | 49 | namespace { |
| 50 | 50 | |
| 51 | // AArch64 long range Thunks | |
| 52 | class AArch64ABSLongThunk final : public Thunk { | |
| 53 | public: | |
| 54 | AArch64ABSLongThunk(Symbol &Dest) : Thunk(Dest) {} | |
| 55 | uint32_t size() const override { return 16; } | |
| 56 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; | |
| 57 | void addSymbols(ThunkSection &IS) override; | |
| 58 | }; | |
| 59 | ||
| 60 | class AArch64ADRPThunk final : public Thunk { | |
| 61 | public: | |
| 62 | AArch64ADRPThunk(Symbol &Dest) : Thunk(Dest) {} | |
| 63 | uint32_t size() const override { return 12; } | |
| 64 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; | |
| 65 | void addSymbols(ThunkSection &IS) override; | |
| 66 | }; | |
| 67 | ||
| 51 | 68 | // Specific ARM Thunk implementations. The naming convention is: |
| 52 | 69 | // Source State, TargetState, Target Requirement, ABS or PI, Range |
| 53 | 70 | class ARMV7ABSLongThunk final : public Thunk { |
| 54 | 71 | public: |
| 55 | ARMV7ABSLongThunk(const SymbolBody &Dest) : Thunk(Dest) {} | |
| 72 | ARMV7ABSLongThunk(Symbol &Dest) : Thunk(Dest) {} | |
| 56 | 73 | |
| 57 | 74 | uint32_t size() const override { return 12; } |
| 58 | 75 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; |
| 59 | 76 | void addSymbols(ThunkSection &IS) override; |
| 60 | bool isCompatibleWith(uint32_t RelocType) const override; | |
| 77 | bool isCompatibleWith(RelType Type) const override; | |
| 61 | 78 | }; |
| 62 | 79 | |
| 63 | 80 | class ARMV7PILongThunk final : public Thunk { |
| 64 | 81 | public: |
| 65 | ARMV7PILongThunk(const SymbolBody &Dest) : Thunk(Dest) {} | |
| 82 | ARMV7PILongThunk(Symbol &Dest) : Thunk(Dest) {} | |
| 66 | 83 | |
| 67 | 84 | uint32_t size() const override { return 16; } |
| 68 | 85 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; |
| 69 | 86 | void addSymbols(ThunkSection &IS) override; |
| 70 | bool isCompatibleWith(uint32_t RelocType) const override; | |
| 87 | bool isCompatibleWith(RelType Type) const override; | |
| 71 | 88 | }; |
| 72 | 89 | |
| 73 | 90 | class ThumbV7ABSLongThunk final : public Thunk { |
| 74 | 91 | public: |
| 75 | ThumbV7ABSLongThunk(const SymbolBody &Dest) : Thunk(Dest) { Alignment = 2; } | |
| 92 | ThumbV7ABSLongThunk(Symbol &Dest) : Thunk(Dest) { Alignment = 2; } | |
| 76 | 93 | |
| 77 | 94 | uint32_t size() const override { return 10; } |
| 78 | 95 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; |
| 79 | 96 | void addSymbols(ThunkSection &IS) override; |
| 80 | bool isCompatibleWith(uint32_t RelocType) const override; | |
| 97 | bool isCompatibleWith(RelType Type) const override; | |
| 81 | 98 | }; |
| 82 | 99 | |
| 83 | 100 | class ThumbV7PILongThunk final : public Thunk { |
| 84 | 101 | public: |
| 85 | ThumbV7PILongThunk(const SymbolBody &Dest) : Thunk(Dest) { Alignment = 2; } | |
| 102 | ThumbV7PILongThunk(Symbol &Dest) : Thunk(Dest) { Alignment = 2; } | |
| 86 | 103 | |
| 87 | 104 | uint32_t size() const override { return 12; } |
| 88 | 105 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; |
| 89 | 106 | void addSymbols(ThunkSection &IS) override; |
| 90 | bool isCompatibleWith(uint32_t RelocType) const override; | |
| 107 | bool isCompatibleWith(RelType Type) const override; | |
| 91 | 108 | }; |
| 92 | 109 | |
| 93 | 110 | // MIPS LA25 thunk |
| 94 | 111 | class MipsThunk final : public Thunk { |
| 95 | 112 | public: |
| 96 | MipsThunk(const SymbolBody &Dest) : Thunk(Dest) {} | |
| 113 | MipsThunk(Symbol &Dest) : Thunk(Dest) {} | |
| 97 | 114 | |
| 98 | 115 | uint32_t size() const override { return 16; } |
| 99 | 116 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; |
| ... | ... | @@ -101,10 +118,86 @@ public: |
| 101 | 118 | InputSection *getTargetInputSection() const override; |
| 102 | 119 | }; |
| 103 | 120 | |
| 121 | // microMIPS R2-R5 LA25 thunk | |
| 122 | class MicroMipsThunk final : public Thunk { | |
| 123 | public: | |
| 124 | MicroMipsThunk(Symbol &Dest) : Thunk(Dest) {} | |
| 125 | ||
| 126 | uint32_t size() const override { return 14; } | |
| 127 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; | |
| 128 | void addSymbols(ThunkSection &IS) override; | |
| 129 | InputSection *getTargetInputSection() const override; | |
| 130 | }; | |
| 131 | ||
| 132 | // microMIPS R6 LA25 thunk | |
| 133 | class MicroMipsR6Thunk final : public Thunk { | |
| 134 | public: | |
| 135 | MicroMipsR6Thunk(Symbol &Dest) : Thunk(Dest) {} | |
| 136 | ||
| 137 | uint32_t size() const override { return 12; } | |
| 138 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; | |
| 139 | void addSymbols(ThunkSection &IS) override; | |
| 140 | InputSection *getTargetInputSection() const override; | |
| 141 | }; | |
| 142 | ||
| 104 | 143 | } // end anonymous namespace |
| 105 | 144 | |
| 145 | // AArch64 long range Thunks | |
| 146 | ||
| 147 | static uint64_t getAArch64ThunkDestVA(const Symbol &S) { | |
| 148 | uint64_t V = S.isInPlt() ? S.getPltVA() : S.getVA(); | |
| 149 | return V; | |
| 150 | } | |
| 151 | ||
| 152 | void AArch64ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | |
| 153 | const uint8_t Data[] = { | |
| 154 | 0x50, 0x00, 0x00, 0x58, // ldr x16, L0 | |
| 155 | 0x00, 0x02, 0x1f, 0xd6, // br x16 | |
| 156 | 0x00, 0x00, 0x00, 0x00, // L0: .xword S | |
| 157 | 0x00, 0x00, 0x00, 0x00, | |
| 158 | }; | |
| 159 | uint64_t S = getAArch64ThunkDestVA(Destination); | |
| 160 | memcpy(Buf, Data, sizeof(Data)); | |
| 161 | Target->relocateOne(Buf + 8, R_AARCH64_ABS64, S); | |
| 162 | } | |
| 163 | ||
| 164 | void AArch64ABSLongThunk::addSymbols(ThunkSection &IS) { | |
| 165 | ThunkSym = addSyntheticLocal( | |
| 166 | Saver.save("__AArch64AbsLongThunk_" + Destination.getName()), STT_FUNC, | |
| 167 | Offset, size(), IS); | |
| 168 | addSyntheticLocal("$x", STT_NOTYPE, Offset, 0, IS); | |
| 169 | addSyntheticLocal("$d", STT_NOTYPE, Offset + 8, 0, IS); | |
| 170 | } | |
| 171 | ||
| 172 | // This Thunk has a maximum range of 4Gb, this is sufficient for all programs | |
| 173 | // using the small code model, including pc-relative ones. At time of writing | |
| 174 | // 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 | |
| 176 | // worrying about the destination being more than 4Gb away. | |
| 177 | void AArch64ADRPThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | |
| 178 | const uint8_t Data[] = { | |
| 179 | 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) | |
| 181 | 0x00, 0x02, 0x1f, 0xd6, // br x16 | |
| 182 | }; | |
| 183 | uint64_t S = getAArch64ThunkDestVA(Destination); | |
| 184 | uint64_t P = ThunkSym->getVA(); | |
| 185 | memcpy(Buf, Data, sizeof(Data)); | |
| 186 | Target->relocateOne(Buf, R_AARCH64_ADR_PREL_PG_HI21, | |
| 187 | getAArch64Page(S) - getAArch64Page(P)); | |
| 188 | Target->relocateOne(Buf + 4, R_AARCH64_ADD_ABS_LO12_NC, S); | |
| 189 | } | |
| 190 | ||
| 191 | void AArch64ADRPThunk::addSymbols(ThunkSection &IS) | |
| 192 | { | |
| 193 | ThunkSym = addSyntheticLocal( | |
| 194 | Saver.save("__AArch64ADRPThunk_" + Destination.getName()), STT_FUNC, | |
| 195 | Offset, size(), IS); | |
| 196 | addSyntheticLocal("$x", STT_NOTYPE, Offset, 0, IS); | |
| 197 | } | |
| 198 | ||
| 106 | 199 | // ARM Target Thunks |
| 107 | static uint64_t getARMThunkDestVA(const SymbolBody &S) { | |
| 200 | static uint64_t getARMThunkDestVA(const Symbol &S) { | |
| 108 | 201 | uint64_t V = S.isInPlt() ? S.getPltVA() : S.getVA(); |
| 109 | 202 | return SignExtend64<32>(V); |
| 110 | 203 | } |
| ... | ... | @@ -124,13 +217,13 @@ void ARMV7ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { |
| 124 | 217 | void ARMV7ABSLongThunk::addSymbols(ThunkSection &IS) { |
| 125 | 218 | ThunkSym = addSyntheticLocal( |
| 126 | 219 | Saver.save("__ARMv7ABSLongThunk_" + Destination.getName()), STT_FUNC, |
| 127 | Offset, size(), &IS); | |
| 128 | addSyntheticLocal("$a", STT_NOTYPE, Offset, 0, &IS); | |
| 220 | Offset, size(), IS); | |
| 221 | addSyntheticLocal("$a", STT_NOTYPE, Offset, 0, IS); | |
| 129 | 222 | } |
| 130 | 223 | |
| 131 | bool ARMV7ABSLongThunk::isCompatibleWith(uint32_t RelocType) const { | |
| 224 | bool ARMV7ABSLongThunk::isCompatibleWith(RelType Type) const { | |
| 132 | 225 | // Thumb branch relocations can't use BLX |
| 133 | return RelocType != R_ARM_THM_JUMP19 && RelocType != R_ARM_THM_JUMP24; | |
| 226 | return Type != R_ARM_THM_JUMP19 && Type != R_ARM_THM_JUMP24; | |
| 134 | 227 | } |
| 135 | 228 | |
| 136 | 229 | void ThumbV7ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { |
| ... | ... | @@ -148,67 +241,67 @@ void ThumbV7ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { |
| 148 | 241 | void ThumbV7ABSLongThunk::addSymbols(ThunkSection &IS) { |
| 149 | 242 | ThunkSym = addSyntheticLocal( |
| 150 | 243 | Saver.save("__Thumbv7ABSLongThunk_" + Destination.getName()), STT_FUNC, |
| 151 | Offset | 0x1, size(), &IS); | |
| 152 | addSyntheticLocal("$t", STT_NOTYPE, Offset, 0, &IS); | |
| 244 | Offset | 0x1, size(), IS); | |
| 245 | addSyntheticLocal("$t", STT_NOTYPE, Offset, 0, IS); | |
| 153 | 246 | } |
| 154 | 247 | |
| 155 | bool ThumbV7ABSLongThunk::isCompatibleWith(uint32_t RelocType) const { | |
| 248 | bool ThumbV7ABSLongThunk::isCompatibleWith(RelType Type) const { | |
| 156 | 249 | // ARM branch relocations can't use BLX |
| 157 | return RelocType != R_ARM_JUMP24 && RelocType != R_ARM_PC24 && | |
| 158 | RelocType != R_ARM_PLT32; | |
| 250 | return Type != R_ARM_JUMP24 && Type != R_ARM_PC24 && Type != R_ARM_PLT32; | |
| 159 | 251 | } |
| 160 | 252 | |
| 161 | 253 | void ARMV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { |
| 162 | 254 | const uint8_t Data[] = { |
| 163 | 0xf0, 0xcf, 0x0f, 0xe3, // P: movw ip,:lower16:S - (P + (L1-P) +8) | |
| 164 | 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S - (P + (L1-P+4) +8) | |
| 255 | 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) | |
| 165 | 257 | 0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc |
| 166 | 258 | 0x1c, 0xff, 0x2f, 0xe1, // bx r12 |
| 167 | 259 | }; |
| 168 | 260 | uint64_t S = getARMThunkDestVA(Destination); |
| 169 | 261 | uint64_t P = ThunkSym->getVA(); |
| 262 | uint64_t Offset = S - P - 16; | |
| 170 | 263 | memcpy(Buf, Data, sizeof(Data)); |
| 171 | Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, S - P - 16); | |
| 172 | Target->relocateOne(Buf + 4, R_ARM_MOVT_PREL, S - P - 12); | |
| 264 | Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, Offset); | |
| 265 | Target->relocateOne(Buf + 4, R_ARM_MOVT_PREL, Offset); | |
| 173 | 266 | } |
| 174 | 267 | |
| 175 | 268 | void ARMV7PILongThunk::addSymbols(ThunkSection &IS) { |
| 176 | 269 | ThunkSym = addSyntheticLocal( |
| 177 | 270 | Saver.save("__ARMV7PILongThunk_" + Destination.getName()), STT_FUNC, |
| 178 | Offset, size(), &IS); | |
| 179 | addSyntheticLocal("$a", STT_NOTYPE, Offset, 0, &IS); | |
| 271 | Offset, size(), IS); | |
| 272 | addSyntheticLocal("$a", STT_NOTYPE, Offset, 0, IS); | |
| 180 | 273 | } |
| 181 | 274 | |
| 182 | bool ARMV7PILongThunk::isCompatibleWith(uint32_t RelocType) const { | |
| 275 | bool ARMV7PILongThunk::isCompatibleWith(RelType Type) const { | |
| 183 | 276 | // Thumb branch relocations can't use BLX |
| 184 | return RelocType != R_ARM_THM_JUMP19 && RelocType != R_ARM_THM_JUMP24; | |
| 277 | return Type != R_ARM_THM_JUMP19 && Type != R_ARM_THM_JUMP24; | |
| 185 | 278 | } |
| 186 | 279 | |
| 187 | 280 | void ThumbV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { |
| 188 | 281 | const uint8_t Data[] = { |
| 189 | 282 | 0x4f, 0xf6, 0xf4, 0x7c, // P: movw ip,:lower16:S - (P + (L1-P) + 4) |
| 190 | 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P+4) + 4) | |
| 283 | 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P) + 4) | |
| 191 | 284 | 0xfc, 0x44, // L1: add r12, pc |
| 192 | 285 | 0x60, 0x47, // bx r12 |
| 193 | 286 | }; |
| 194 | 287 | uint64_t S = getARMThunkDestVA(Destination); |
| 195 | 288 | uint64_t P = ThunkSym->getVA() & ~0x1; |
| 289 | uint64_t Offset = S - P - 12; | |
| 196 | 290 | memcpy(Buf, Data, sizeof(Data)); |
| 197 | Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, S - P - 12); | |
| 198 | Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, S - P - 8); | |
| 291 | Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, Offset); | |
| 292 | Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, Offset); | |
| 199 | 293 | } |
| 200 | 294 | |
| 201 | 295 | void ThumbV7PILongThunk::addSymbols(ThunkSection &IS) { |
| 202 | 296 | ThunkSym = addSyntheticLocal( |
| 203 | 297 | Saver.save("__ThumbV7PILongThunk_" + Destination.getName()), STT_FUNC, |
| 204 | Offset | 0x1, size(), &IS); | |
| 205 | addSyntheticLocal("$t", STT_NOTYPE, Offset, 0, &IS); | |
| 298 | Offset | 0x1, size(), IS); | |
| 299 | addSyntheticLocal("$t", STT_NOTYPE, Offset, 0, IS); | |
| 206 | 300 | } |
| 207 | 301 | |
| 208 | bool ThumbV7PILongThunk::isCompatibleWith(uint32_t RelocType) const { | |
| 302 | bool ThumbV7PILongThunk::isCompatibleWith(RelType Type) const { | |
| 209 | 303 | // ARM branch relocations can't use BLX |
| 210 | return RelocType != R_ARM_JUMP24 && RelocType != R_ARM_PC24 && | |
| 211 | RelocType != R_ARM_PLT32; | |
| 304 | return Type != R_ARM_JUMP24 && Type != R_ARM_PC24 && Type != R_ARM_PLT32; | |
| 212 | 305 | } |
| 213 | 306 | |
| 214 | 307 | // Write MIPS LA25 thunk code to call PIC function from the non-PIC one. |
| ... | ... | @@ -225,20 +318,78 @@ void MipsThunk::writeTo(uint8_t *Buf, ThunkSection &) const { |
| 225 | 318 | void MipsThunk::addSymbols(ThunkSection &IS) { |
| 226 | 319 | ThunkSym = |
| 227 | 320 | addSyntheticLocal(Saver.save("__LA25Thunk_" + Destination.getName()), |
| 228 | STT_FUNC, Offset, size(), &IS); | |
| 321 | STT_FUNC, Offset, size(), IS); | |
| 229 | 322 | } |
| 230 | 323 | |
| 231 | 324 | InputSection *MipsThunk::getTargetInputSection() const { |
| 232 | auto *DR = dyn_cast<DefinedRegular>(&Destination); | |
| 233 | return dyn_cast<InputSection>(DR->Section); | |
| 325 | auto &DR = cast<Defined>(Destination); | |
| 326 | return dyn_cast<InputSection>(DR.Section); | |
| 234 | 327 | } |
| 235 | 328 | |
| 236 | Thunk::Thunk(const SymbolBody &D) : Destination(D), Offset(0) {} | |
| 329 | // Write microMIPS R2-R5 LA25 thunk code | |
| 330 | // to call PIC function from the non-PIC one. | |
| 331 | void MicroMipsThunk::writeTo(uint8_t *Buf, ThunkSection &) const { | |
| 332 | uint64_t S = Destination.getVA() | 1; | |
| 333 | write16(Buf, 0x41b9, Config->Endianness); // lui $25, %hi(func) | |
| 334 | write16(Buf + 4, 0xd400, Config->Endianness); // j func | |
| 335 | write16(Buf + 8, 0x3339, Config->Endianness); // addiu $25, $25, %lo(func) | |
| 336 | write16(Buf + 12, 0x0c00, Config->Endianness); // nop | |
| 337 | Target->relocateOne(Buf, R_MICROMIPS_HI16, S); | |
| 338 | Target->relocateOne(Buf + 4, R_MICROMIPS_26_S1, S); | |
| 339 | Target->relocateOne(Buf + 8, R_MICROMIPS_LO16, S); | |
| 340 | } | |
| 341 | ||
| 342 | void MicroMipsThunk::addSymbols(ThunkSection &IS) { | |
| 343 | ThunkSym = | |
| 344 | addSyntheticLocal(Saver.save("__microLA25Thunk_" + Destination.getName()), | |
| 345 | STT_FUNC, Offset, size(), IS); | |
| 346 | ThunkSym->StOther |= STO_MIPS_MICROMIPS; | |
| 347 | } | |
| 348 | ||
| 349 | InputSection *MicroMipsThunk::getTargetInputSection() const { | |
| 350 | auto &DR = cast<Defined>(Destination); | |
| 351 | return dyn_cast<InputSection>(DR.Section); | |
| 352 | } | |
| 353 | ||
| 354 | // Write microMIPS R6 LA25 thunk code | |
| 355 | // to call PIC function from the non-PIC one. | |
| 356 | void MicroMipsR6Thunk::writeTo(uint8_t *Buf, ThunkSection &) const { | |
| 357 | uint64_t S = Destination.getVA() | 1; | |
| 358 | uint64_t P = ThunkSym->getVA(); | |
| 359 | write16(Buf, 0x1320, Config->Endianness); // lui $25, %hi(func) | |
| 360 | write16(Buf + 4, 0x3339, Config->Endianness); // addiu $25, $25, %lo(func) | |
| 361 | write16(Buf + 8, 0x9400, Config->Endianness); // bc func | |
| 362 | Target->relocateOne(Buf, R_MICROMIPS_HI16, S); | |
| 363 | Target->relocateOne(Buf + 4, R_MICROMIPS_LO16, S); | |
| 364 | Target->relocateOne(Buf + 8, R_MICROMIPS_PC26_S1, S - P - 12); | |
| 365 | } | |
| 366 | ||
| 367 | void MicroMipsR6Thunk::addSymbols(ThunkSection &IS) { | |
| 368 | ThunkSym = | |
| 369 | addSyntheticLocal(Saver.save("__microLA25Thunk_" + Destination.getName()), | |
| 370 | STT_FUNC, Offset, size(), IS); | |
| 371 | ThunkSym->StOther |= STO_MIPS_MICROMIPS; | |
| 372 | } | |
| 373 | ||
| 374 | InputSection *MicroMipsR6Thunk::getTargetInputSection() const { | |
| 375 | auto &DR = cast<Defined>(Destination); | |
| 376 | return dyn_cast<InputSection>(DR.Section); | |
| 377 | } | |
| 378 | ||
| 379 | Thunk::Thunk(Symbol &D) : Destination(D), Offset(0) {} | |
| 237 | 380 | |
| 238 | 381 | Thunk::~Thunk() = default; |
| 239 | 382 | |
| 383 | static Thunk *addThunkAArch64(RelType Type, Symbol &S) { | |
| 384 | if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26) | |
| 385 | fatal("unrecognized relocation type"); | |
| 386 | if (Config->Pic) | |
| 387 | return make<AArch64ADRPThunk>(S); | |
| 388 | return make<AArch64ABSLongThunk>(S); | |
| 389 | } | |
| 390 | ||
| 240 | 391 | // Creates a thunk for Thumb-ARM interworking. |
| 241 | static Thunk *addThunkArm(uint32_t Reloc, SymbolBody &S) { | |
| 392 | static Thunk *addThunkArm(RelType Reloc, Symbol &S) { | |
| 242 | 393 | // ARM relocations need ARM to Thumb interworking Thunks. |
| 243 | 394 | // Thumb relocations need Thumb to ARM relocations. |
| 244 | 395 | // Use position independent Thunks if we require position independent code. |
| ... | ... | @@ -246,11 +397,13 @@ static Thunk *addThunkArm(uint32_t Reloc, SymbolBody &S) { |
| 246 | 397 | case R_ARM_PC24: |
| 247 | 398 | case R_ARM_PLT32: |
| 248 | 399 | case R_ARM_JUMP24: |
| 400 | case R_ARM_CALL: | |
| 249 | 401 | if (Config->Pic) |
| 250 | 402 | return make<ARMV7PILongThunk>(S); |
| 251 | 403 | return make<ARMV7ABSLongThunk>(S); |
| 252 | 404 | case R_ARM_THM_JUMP19: |
| 253 | 405 | case R_ARM_THM_JUMP24: |
| 406 | case R_ARM_THM_CALL: | |
| 254 | 407 | if (Config->Pic) |
| 255 | 408 | return make<ThumbV7PILongThunk>(S); |
| 256 | 409 | return make<ThumbV7ABSLongThunk>(S); |
| ... | ... | @@ -258,13 +411,21 @@ static Thunk *addThunkArm(uint32_t Reloc, SymbolBody &S) { |
| 258 | 411 | fatal("unrecognized relocation type"); |
| 259 | 412 | } |
| 260 | 413 | |
| 261 | static Thunk *addThunkMips(SymbolBody &S) { return make<MipsThunk>(S); } | |
| 414 | static Thunk *addThunkMips(RelType Type, Symbol &S) { | |
| 415 | if ((S.StOther & STO_MIPS_MICROMIPS) && isMipsR6()) | |
| 416 | return make<MicroMipsR6Thunk>(S); | |
| 417 | if (S.StOther & STO_MIPS_MICROMIPS) | |
| 418 | return make<MicroMipsThunk>(S); | |
| 419 | return make<MipsThunk>(S); | |
| 420 | } | |
| 262 | 421 | |
| 263 | Thunk *addThunk(uint32_t RelocType, SymbolBody &S) { | |
| 264 | if (Config->EMachine == EM_ARM) | |
| 265 | return addThunkArm(RelocType, S); | |
| 422 | Thunk *addThunk(RelType Type, Symbol &S) { | |
| 423 | if (Config->EMachine == EM_AARCH64) | |
| 424 | return addThunkAArch64(Type, S); | |
| 425 | else if (Config->EMachine == EM_ARM) | |
| 426 | return addThunkArm(Type, S); | |
| 266 | 427 | else if (Config->EMachine == EM_MIPS) |
| 267 | return addThunkMips(S); | |
| 428 | return addThunkMips(Type, S); | |
| 268 | 429 | llvm_unreachable("add Thunk only supported for ARM and Mips"); |
| 269 | 430 | return nullptr; |
| 270 | 431 | } |
deps/lld/ELF/Thunks.h+9-9| ... | ... | @@ -14,7 +14,7 @@ |
| 14 | 14 | |
| 15 | 15 | namespace lld { |
| 16 | 16 | namespace elf { |
| 17 | class SymbolBody; | |
| 17 | class Symbol; | |
| 18 | 18 | class ThunkSection; |
| 19 | 19 | // Class to describe an instance of a Thunk. |
| 20 | 20 | // A Thunk is a code-sequence inserted by the linker in between a caller and |
| ... | ... | @@ -23,11 +23,11 @@ class ThunkSection; |
| 23 | 23 | // include transferring control from non-pi to pi and changing state on |
| 24 | 24 | // targets like ARM. |
| 25 | 25 | // |
| 26 | // Thunks can be created for DefinedRegular, Shared and Undefined Symbols. | |
| 26 | // Thunks can be created for Defined, Shared and Undefined Symbols. | |
| 27 | 27 | // Thunks are assigned to synthetic ThunkSections |
| 28 | 28 | class Thunk { |
| 29 | 29 | public: |
| 30 | Thunk(const SymbolBody &Destination); | |
| 30 | Thunk(Symbol &Destination); | |
| 31 | 31 | virtual ~Thunk(); |
| 32 | 32 | |
| 33 | 33 | virtual uint32_t size() const { return 0; } |
| ... | ... | @@ -41,21 +41,21 @@ public: |
| 41 | 41 | // a branch and fall through to the first Symbol in the Target. |
| 42 | 42 | virtual InputSection *getTargetInputSection() const { return nullptr; } |
| 43 | 43 | |
| 44 | // To reuse a Thunk the caller as identified by the RelocType must be | |
| 44 | // To reuse a Thunk the caller as identified by the Type must be | |
| 45 | 45 | // compatible with it. |
| 46 | virtual bool isCompatibleWith(uint32_t RelocType) const { return true; } | |
| 46 | virtual bool isCompatibleWith(RelType Type) const { return true; } | |
| 47 | 47 | |
| 48 | 48 | // The alignment requirement for this Thunk, defaults to the size of the |
| 49 | 49 | // typical code section alignment. |
| 50 | const SymbolBody &Destination; | |
| 51 | SymbolBody *ThunkSym; | |
| 52 | uint64_t Offset; | |
| 50 | Symbol &Destination; | |
| 51 | Symbol *ThunkSym; | |
| 52 | uint64_t Offset = 0; | |
| 53 | 53 | uint32_t Alignment = 4; |
| 54 | 54 | }; |
| 55 | 55 | |
| 56 | 56 | // For a Relocation to symbol S create a Thunk to be added to a synthetic |
| 57 | 57 | // ThunkSection. At present there are implementations for ARM and Mips Thunks. |
| 58 | Thunk *addThunk(uint32_t RelocType, SymbolBody &S); | |
| 58 | Thunk *addThunk(RelType Type, Symbol &S); | |
| 59 | 59 | |
| 60 | 60 | } // namespace elf |
| 61 | 61 | } // namespace lld |
deps/lld/ELF/Writer.cpp+910-748| ... | ... | @@ -8,22 +8,22 @@ |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | 10 | #include "Writer.h" |
| 11 | #include "AArch64ErrataFix.h" | |
| 11 | 12 | #include "Config.h" |
| 12 | 13 | #include "Filesystem.h" |
| 13 | 14 | #include "LinkerScript.h" |
| 14 | 15 | #include "MapFile.h" |
| 15 | #include "Memory.h" | |
| 16 | 16 | #include "OutputSections.h" |
| 17 | 17 | #include "Relocations.h" |
| 18 | 18 | #include "Strings.h" |
| 19 | 19 | #include "SymbolTable.h" |
| 20 | #include "Symbols.h" | |
| 20 | 21 | #include "SyntheticSections.h" |
| 21 | 22 | #include "Target.h" |
| 22 | #include "Threads.h" | |
| 23 | #include "lld/Common/Memory.h" | |
| 24 | #include "lld/Common/Threads.h" | |
| 23 | 25 | #include "llvm/ADT/StringMap.h" |
| 24 | 26 | #include "llvm/ADT/StringSwitch.h" |
| 25 | #include "llvm/Support/FileOutputBuffer.h" | |
| 26 | #include "llvm/Support/raw_ostream.h" | |
| 27 | 27 | #include <climits> |
| 28 | 28 | |
| 29 | 29 | using namespace llvm; |
| ... | ... | @@ -39,6 +39,7 @@ namespace { |
| 39 | 39 | // The writer writes a SymbolTable result to a file. |
| 40 | 40 | template <class ELFT> class Writer { |
| 41 | 41 | public: |
| 42 | Writer() : Buffer(errorHandler().OutputBuffer) {} | |
| 42 | 43 | typedef typename ELFT::Shdr Elf_Shdr; |
| 43 | 44 | typedef typename ELFT::Ehdr Elf_Ehdr; |
| 44 | 45 | typedef typename ELFT::Phdr Elf_Phdr; |
| ... | ... | @@ -46,43 +47,37 @@ public: |
| 46 | 47 | void run(); |
| 47 | 48 | |
| 48 | 49 | private: |
| 49 | void clearOutputSections(); | |
| 50 | void createSyntheticSections(); | |
| 51 | 50 | void copyLocalSymbols(); |
| 52 | 51 | void addSectionSymbols(); |
| 53 | void addReservedSymbols(); | |
| 54 | void createSections(); | |
| 55 | 52 | void forEachRelSec(std::function<void(InputSectionBase &)> Fn); |
| 56 | 53 | void sortSections(); |
| 54 | void resolveShfLinkOrder(); | |
| 55 | void sortInputSections(); | |
| 57 | 56 | void finalizeSections(); |
| 58 | void addPredefinedSections(); | |
| 57 | void setReservedSymbolSections(); | |
| 59 | 58 | |
| 60 | std::vector<PhdrEntry> createPhdrs(); | |
| 59 | std::vector<PhdrEntry *> createPhdrs(); | |
| 61 | 60 | void removeEmptyPTLoad(); |
| 62 | void addPtArmExid(std::vector<PhdrEntry> &Phdrs); | |
| 61 | void addPtArmExid(std::vector<PhdrEntry *> &Phdrs); | |
| 63 | 62 | void assignFileOffsets(); |
| 64 | 63 | void assignFileOffsetsBinary(); |
| 65 | 64 | void setPhdrs(); |
| 66 | 65 | void fixSectionAlignments(); |
| 67 | void fixPredefinedSymbols(); | |
| 68 | 66 | void openFile(); |
| 67 | void writeTrapInstr(); | |
| 69 | 68 | void writeHeader(); |
| 70 | 69 | void writeSections(); |
| 71 | 70 | void writeSectionsBinary(); |
| 72 | 71 | void writeBuildId(); |
| 73 | 72 | |
| 74 | std::unique_ptr<FileOutputBuffer> Buffer; | |
| 75 | ||
| 76 | OutputSectionFactory Factory; | |
| 73 | std::unique_ptr<FileOutputBuffer> &Buffer; | |
| 77 | 74 | |
| 78 | 75 | void addRelIpltSymbols(); |
| 79 | 76 | void addStartEndSymbols(); |
| 80 | 77 | void addStartStopSymbols(OutputSection *Sec); |
| 81 | 78 | uint64_t getEntryAddr(); |
| 82 | OutputSection *findSectionInScript(StringRef Name); | |
| 83 | OutputSectionCommand *findSectionCommand(StringRef Name); | |
| 84 | 79 | |
| 85 | std::vector<PhdrEntry> Phdrs; | |
| 80 | std::vector<PhdrEntry *> Phdrs; | |
| 86 | 81 | |
| 87 | 82 | uint64_t FileSize; |
| 88 | 83 | uint64_t SectionHeaderOff; |
| ... | ... | @@ -91,49 +86,60 @@ private: |
| 91 | 86 | }; |
| 92 | 87 | } // anonymous namespace |
| 93 | 88 | |
| 94 | StringRef elf::getOutputSectionName(StringRef Name) { | |
| 89 | StringRef elf::getOutputSectionName(InputSectionBase *S) { | |
| 95 | 90 | // ".zdebug_" is a prefix for ZLIB-compressed sections. |
| 96 | 91 | // Because we decompressed input sections, we want to remove 'z'. |
| 97 | if (Name.startswith(".zdebug_")) | |
| 98 | return Saver.save("." + Name.substr(2)); | |
| 92 | if (S->Name.startswith(".zdebug_")) | |
| 93 | return Saver.save("." + S->Name.substr(2)); | |
| 99 | 94 | |
| 100 | 95 | if (Config->Relocatable) |
| 101 | return Name; | |
| 96 | return S->Name; | |
| 97 | ||
| 98 | // 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 | |
| 100 | // technically required, but not doing it is odd). This code guarantees that. | |
| 101 | if ((S->Type == SHT_REL || S->Type == SHT_RELA) && | |
| 102 | !isa<SyntheticSection>(S)) { | |
| 103 | OutputSection *Out = | |
| 104 | cast<InputSection>(S)->getRelocatedSection()->getOutputSection(); | |
| 105 | if (S->Type == SHT_RELA) | |
| 106 | return Saver.save(".rela" + Out->Name); | |
| 107 | return Saver.save(".rel" + Out->Name); | |
| 108 | } | |
| 102 | 109 | |
| 103 | 110 | for (StringRef V : |
| 104 | 111 | {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.", |
| 105 | 112 | ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.", |
| 106 | 113 | ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."}) { |
| 107 | 114 | StringRef Prefix = V.drop_back(); |
| 108 | if (Name.startswith(V) || Name == Prefix) | |
| 115 | if (S->Name.startswith(V) || S->Name == Prefix) | |
| 109 | 116 | return Prefix; |
| 110 | 117 | } |
| 111 | 118 | |
| 112 | 119 | // CommonSection is identified as "COMMON" in linker scripts. |
| 113 | 120 | // By default, it should go to .bss section. |
| 114 | if (Name == "COMMON") | |
| 121 | if (S->Name == "COMMON") | |
| 115 | 122 | return ".bss"; |
| 116 | 123 | |
| 117 | return Name; | |
| 124 | return S->Name; | |
| 118 | 125 | } |
| 119 | 126 | |
| 120 | template <class ELFT> static bool needsInterpSection() { | |
| 121 | return !Symtab<ELFT>::X->getSharedFiles().empty() && | |
| 122 | !Config->DynamicLinker.empty() && !Script->ignoreInterpSection(); | |
| 127 | static bool needsInterpSection() { | |
| 128 | return !SharedFiles.empty() && !Config->DynamicLinker.empty() && | |
| 129 | Script->needsInterpSection(); | |
| 123 | 130 | } |
| 124 | 131 | |
| 125 | 132 | template <class ELFT> void elf::writeResult() { Writer<ELFT>().run(); } |
| 126 | 133 | |
| 127 | 134 | template <class ELFT> void Writer<ELFT>::removeEmptyPTLoad() { |
| 128 | auto I = std::remove_if(Phdrs.begin(), Phdrs.end(), [&](const PhdrEntry &P) { | |
| 129 | if (P.p_type != PT_LOAD) | |
| 135 | llvm::erase_if(Phdrs, [&](const PhdrEntry *P) { | |
| 136 | if (P->p_type != PT_LOAD) | |
| 130 | 137 | return false; |
| 131 | if (!P.First) | |
| 138 | if (!P->FirstSec) | |
| 132 | 139 | return true; |
| 133 | uint64_t Size = P.Last->Addr + P.Last->Size - P.First->Addr; | |
| 140 | uint64_t Size = P->LastSec->Addr + P->LastSec->Size - P->FirstSec->Addr; | |
| 134 | 141 | return Size == 0; |
| 135 | 142 | }); |
| 136 | Phdrs.erase(I, Phdrs.end()); | |
| 137 | 143 | } |
| 138 | 144 | |
| 139 | 145 | template <class ELFT> static void combineEhFrameSections() { |
| ... | ... | @@ -142,7 +148,7 @@ template <class ELFT> static void combineEhFrameSections() { |
| 142 | 148 | if (!ES || !ES->Live) |
| 143 | 149 | continue; |
| 144 | 150 | |
| 145 | In<ELFT>::EhFrame->addSection(ES); | |
| 151 | InX::EhFrame->addSection<ELFT>(ES); | |
| 146 | 152 | S = nullptr; |
| 147 | 153 | } |
| 148 | 154 | |
| ... | ... | @@ -150,130 +156,87 @@ template <class ELFT> static void combineEhFrameSections() { |
| 150 | 156 | V.erase(std::remove(V.begin(), V.end(), nullptr), V.end()); |
| 151 | 157 | } |
| 152 | 158 | |
| 153 | template <class ELFT> void Writer<ELFT>::clearOutputSections() { | |
| 154 | // Clear the OutputSections to make sure it is not used anymore. Any | |
| 155 | // code from this point on should be using the linker script | |
| 156 | // commands. | |
| 157 | for (OutputSection *Sec : OutputSections) | |
| 158 | Sec->Sections.clear(); | |
| 159 | OutputSections.clear(); | |
| 159 | static Defined *addOptionalRegular(StringRef Name, SectionBase *Sec, | |
| 160 | uint64_t Val, uint8_t StOther = STV_HIDDEN, | |
| 161 | uint8_t Binding = STB_GLOBAL) { | |
| 162 | Symbol *S = Symtab->find(Name); | |
| 163 | if (!S || S->isDefined()) | |
| 164 | return nullptr; | |
| 165 | Symbol *Sym = Symtab->addRegular(Name, StOther, STT_NOTYPE, Val, | |
| 166 | /*Size=*/0, Binding, Sec, | |
| 167 | /*File=*/nullptr); | |
| 168 | return cast<Defined>(Sym); | |
| 160 | 169 | } |
| 161 | 170 | |
| 162 | // The main function of the writer. | |
| 163 | template <class ELFT> void Writer<ELFT>::run() { | |
| 164 | // Create linker-synthesized sections such as .got or .plt. | |
| 165 | // Such sections are of type input section. | |
| 166 | createSyntheticSections(); | |
| 167 | ||
| 168 | if (!Config->Relocatable) | |
| 169 | combineEhFrameSections<ELFT>(); | |
| 170 | ||
| 171 | // We need to create some reserved symbols such as _end. Create them. | |
| 172 | if (!Config->Relocatable) | |
| 173 | addReservedSymbols(); | |
| 174 | ||
| 175 | // Create output sections. | |
| 176 | if (Script->Opt.HasSections) { | |
| 177 | // If linker script contains SECTIONS commands, let it create sections. | |
| 178 | Script->processCommands(Factory); | |
| 179 | ||
| 180 | // Linker scripts may have left some input sections unassigned. | |
| 181 | // Assign such sections using the default rule. | |
| 182 | Script->addOrphanSections(Factory); | |
| 183 | } else { | |
| 184 | // If linker script does not contain SECTIONS commands, create | |
| 185 | // output sections by default rules. We still need to give the | |
| 186 | // linker script a chance to run, because it might contain | |
| 187 | // non-SECTIONS commands such as ASSERT. | |
| 188 | Script->processCommands(Factory); | |
| 189 | createSections(); | |
| 190 | } | |
| 191 | clearOutputSections(); | |
| 192 | ||
| 193 | if (Config->Discard != DiscardPolicy::All) | |
| 194 | copyLocalSymbols(); | |
| 195 | ||
| 196 | if (Config->CopyRelocs) | |
| 197 | addSectionSymbols(); | |
| 198 | ||
| 199 | // Now that we have a complete set of output sections. This function | |
| 200 | // completes section contents. For example, we need to add strings | |
| 201 | // to the string table, and add entries to .got and .plt. | |
| 202 | // finalizeSections does that. | |
| 203 | finalizeSections(); | |
| 204 | if (ErrorCount) | |
| 205 | return; | |
| 206 | ||
| 207 | if (!Script->Opt.HasSections && !Config->Relocatable) | |
| 208 | fixSectionAlignments(); | |
| 209 | ||
| 210 | // If -compressed-debug-sections is specified, we need to compress | |
| 211 | // .debug_* sections. Do it right now because it changes the size of | |
| 212 | // output sections. | |
| 213 | parallelForEach( | |
| 214 | OutputSectionCommands.begin(), OutputSectionCommands.end(), | |
| 215 | [](OutputSectionCommand *Cmd) { Cmd->maybeCompress<ELFT>(); }); | |
| 216 | ||
| 217 | Script->assignAddresses(); | |
| 218 | Script->allocateHeaders(Phdrs); | |
| 219 | ||
| 220 | // Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a | |
| 221 | // 0 sized region. This has to be done late since only after assignAddresses | |
| 222 | // we know the size of the sections. | |
| 223 | removeEmptyPTLoad(); | |
| 224 | ||
| 225 | if (!Config->OFormatBinary) | |
| 226 | assignFileOffsets(); | |
| 227 | else | |
| 228 | assignFileOffsetsBinary(); | |
| 171 | // The linker is expected to define some symbols depending on | |
| 172 | // the linking result. This function defines such symbols. | |
| 173 | void elf::addReservedSymbols() { | |
| 174 | if (Config->EMachine == EM_MIPS) { | |
| 175 | // Define _gp for MIPS. st_value of _gp symbol will be updated by Writer | |
| 176 | // so that it points to an absolute address which by default is relative | |
| 177 | // to GOT. Default offset is 0x7ff0. | |
| 178 | // See "Global Data Symbols" in Chapter 6 in the following document: | |
| 179 | // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf | |
| 180 | ElfSym::MipsGp = Symtab->addAbsolute("_gp", STV_HIDDEN, STB_GLOBAL); | |
| 229 | 181 | |
| 230 | setPhdrs(); | |
| 182 | // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between | |
| 183 | // start of function and 'gp' pointer into GOT. | |
| 184 | if (Symtab->find("_gp_disp")) | |
| 185 | ElfSym::MipsGpDisp = | |
| 186 | Symtab->addAbsolute("_gp_disp", STV_HIDDEN, STB_GLOBAL); | |
| 231 | 187 | |
| 232 | if (Config->Relocatable) { | |
| 233 | for (OutputSectionCommand *Cmd : OutputSectionCommands) | |
| 234 | Cmd->Sec->Addr = 0; | |
| 235 | } else { | |
| 236 | fixPredefinedSymbols(); | |
| 188 | // The __gnu_local_gp is a magic symbol equal to the current value of 'gp' | |
| 189 | // pointer. This symbol is used in the code generated by .cpload pseudo-op | |
| 190 | // in case of using -mno-shared option. | |
| 191 | // https://sourceware.org/ml/binutils/2004-12/msg00094.html | |
| 192 | if (Symtab->find("__gnu_local_gp")) | |
| 193 | ElfSym::MipsLocalGp = | |
| 194 | Symtab->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_GLOBAL); | |
| 237 | 195 | } |
| 238 | 196 | |
| 239 | // It does not make sense try to open the file if we have error already. | |
| 240 | if (ErrorCount) | |
| 241 | return; | |
| 242 | // Write the result down to a file. | |
| 243 | openFile(); | |
| 244 | if (ErrorCount) | |
| 245 | return; | |
| 197 | ElfSym::GlobalOffsetTable = addOptionalRegular( | |
| 198 | "_GLOBAL_OFFSET_TABLE_", Out::ElfHeader, Target->GotBaseSymOff); | |
| 246 | 199 | |
| 247 | if (!Config->OFormatBinary) { | |
| 248 | writeHeader(); | |
| 249 | writeSections(); | |
| 250 | } else { | |
| 251 | writeSectionsBinary(); | |
| 252 | } | |
| 200 | // __ehdr_start is the location of ELF file headers. Note that we define | |
| 201 | // this symbol unconditionally even when using a linker script, which | |
| 202 | // differs from the behavior implemented by GNU linker which only define | |
| 203 | // this symbol if ELF headers are in the memory mapped segment. | |
| 204 | // __executable_start is not documented, but the expectation of at | |
| 205 | // least the android libc is that it points to the elf header too. | |
| 206 | // __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 | |
| 208 | // different in different DSOs, so we chose the start address of the DSO. | |
| 209 | for (const char *Name : | |
| 210 | {"__ehdr_start", "__executable_start", "__dso_handle"}) | |
| 211 | addOptionalRegular(Name, Out::ElfHeader, 0, STV_HIDDEN); | |
| 253 | 212 | |
| 254 | // Backfill .note.gnu.build-id section content. This is done at last | |
| 255 | // because the content is usually a hash value of the entire output file. | |
| 256 | writeBuildId(); | |
| 257 | if (ErrorCount) | |
| 213 | // If linker script do layout we do not need to create any standart symbols. | |
| 214 | if (Script->HasSectionsCommand) | |
| 258 | 215 | return; |
| 259 | 216 | |
| 260 | // Handle -Map option. | |
| 261 | writeMapFile<ELFT>(OutputSectionCommands); | |
| 262 | if (ErrorCount) | |
| 263 | return; | |
| 217 | auto Add = [](StringRef S, int64_t Pos) { | |
| 218 | return addOptionalRegular(S, Out::ElfHeader, Pos, STV_DEFAULT); | |
| 219 | }; | |
| 264 | 220 | |
| 265 | if (auto EC = Buffer->commit()) | |
| 266 | error("failed to write to the output file: " + EC.message()); | |
| 221 | ElfSym::Bss = Add("__bss_start", 0); | |
| 222 | ElfSym::End1 = Add("end", -1); | |
| 223 | ElfSym::End2 = Add("_end", -1); | |
| 224 | ElfSym::Etext1 = Add("etext", -1); | |
| 225 | ElfSym::Etext2 = Add("_etext", -1); | |
| 226 | ElfSym::Edata1 = Add("edata", -1); | |
| 227 | ElfSym::Edata2 = Add("_edata", -1); | |
| 228 | } | |
| 267 | 229 | |
| 268 | // Flush the output streams and exit immediately. A full shutdown | |
| 269 | // is a good test that we are keeping track of all allocated memory, | |
| 270 | // but actually freeing it is a waste of time in a regular linker run. | |
| 271 | if (Config->ExitEarly) | |
| 272 | exitLld(0); | |
| 230 | static OutputSection *findSection(StringRef Name) { | |
| 231 | for (BaseCommand *Base : Script->SectionCommands) | |
| 232 | if (auto *Sec = dyn_cast<OutputSection>(Base)) | |
| 233 | if (Sec->Name == Name) | |
| 234 | return Sec; | |
| 235 | return nullptr; | |
| 273 | 236 | } |
| 274 | 237 | |
| 275 | 238 | // Initialize Out members. |
| 276 | template <class ELFT> void Writer<ELFT>::createSyntheticSections() { | |
| 239 | template <class ELFT> static void createSyntheticSections() { | |
| 277 | 240 | // Initialize all pointers with NULL. This is needed because |
| 278 | 241 | // you can call lld::elf::main more than once as a library. |
| 279 | 242 | memset(&Out::First, 0, sizeof(Out)); |
| ... | ... | @@ -282,16 +245,19 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { |
| 282 | 245 | |
| 283 | 246 | InX::DynStrTab = make<StringTableSection>(".dynstr", true); |
| 284 | 247 | InX::Dynamic = make<DynamicSection<ELFT>>(); |
| 285 | In<ELFT>::RelaDyn = make<RelocationSection<ELFT>>( | |
| 286 | Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc); | |
| 248 | if (Config->AndroidPackDynRelocs) { | |
| 249 | InX::RelaDyn = make<AndroidPackedRelocationSection<ELFT>>( | |
| 250 | Config->IsRela ? ".rela.dyn" : ".rel.dyn"); | |
| 251 | } else { | |
| 252 | InX::RelaDyn = make<RelocationSection<ELFT>>( | |
| 253 | Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc); | |
| 254 | } | |
| 287 | 255 | InX::ShStrTab = make<StringTableSection>(".shstrtab", false); |
| 288 | 256 | |
| 289 | Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC); | |
| 290 | Out::ElfHeader->Size = sizeof(Elf_Ehdr); | |
| 291 | 257 | Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC); |
| 292 | Out::ProgramHeaders->updateAlignment(Config->Wordsize); | |
| 258 | Out::ProgramHeaders->Alignment = Config->Wordsize; | |
| 293 | 259 | |
| 294 | if (needsInterpSection<ELFT>()) { | |
| 260 | if (needsInterpSection()) { | |
| 295 | 261 | InX::Interp = createInterpSection(); |
| 296 | 262 | Add(InX::Interp); |
| 297 | 263 | } else { |
| ... | ... | @@ -308,20 +274,21 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { |
| 308 | 274 | Add(InX::BuildId); |
| 309 | 275 | } |
| 310 | 276 | |
| 311 | InX::Common = createCommonSection<ELFT>(); | |
| 312 | if (InX::Common) | |
| 313 | Add(InX::Common); | |
| 314 | ||
| 315 | InX::Bss = make<BssSection>(".bss"); | |
| 277 | InX::Bss = make<BssSection>(".bss", 0, 1); | |
| 316 | 278 | Add(InX::Bss); |
| 317 | InX::BssRelRo = make<BssSection>(".bss.rel.ro"); | |
| 279 | ||
| 280 | // 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. | |
| 282 | // This makes sure our relro is contiguous. | |
| 283 | bool HasDataRelRo = | |
| 284 | Script->HasSectionsCommand && findSection(".data.rel.ro"); | |
| 285 | InX::BssRelRo = make<BssSection>( | |
| 286 | HasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1); | |
| 318 | 287 | Add(InX::BssRelRo); |
| 319 | 288 | |
| 320 | 289 | // Add MIPS-specific sections. |
| 321 | bool HasDynSymTab = !Symtab<ELFT>::X->getSharedFiles().empty() || | |
| 322 | Config->Pic || Config->ExportDynamic; | |
| 323 | 290 | if (Config->EMachine == EM_MIPS) { |
| 324 | if (!Config->Shared && HasDynSymTab) { | |
| 291 | if (!Config->Shared && Config->HasDynSymTab) { | |
| 325 | 292 | InX::MipsRldMap = make<MipsRldMapSection>(); |
| 326 | 293 | Add(InX::MipsRldMap); |
| 327 | 294 | } |
| ... | ... | @@ -333,7 +300,7 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { |
| 333 | 300 | Add(Sec); |
| 334 | 301 | } |
| 335 | 302 | |
| 336 | if (HasDynSymTab) { | |
| 303 | if (Config->HasDynSymTab) { | |
| 337 | 304 | InX::DynSymTab = make<SymbolTableSection<ELFT>>(*InX::DynStrTab); |
| 338 | 305 | Add(InX::DynSymTab); |
| 339 | 306 | |
| ... | ... | @@ -354,13 +321,13 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { |
| 354 | 321 | } |
| 355 | 322 | |
| 356 | 323 | if (Config->SysvHash) { |
| 357 | In<ELFT>::HashTab = make<HashTableSection<ELFT>>(); | |
| 358 | Add(In<ELFT>::HashTab); | |
| 324 | InX::HashTab = make<HashTableSection>(); | |
| 325 | Add(InX::HashTab); | |
| 359 | 326 | } |
| 360 | 327 | |
| 361 | 328 | Add(InX::Dynamic); |
| 362 | 329 | Add(InX::DynStrTab); |
| 363 | Add(In<ELFT>::RelaDyn); | |
| 330 | Add(InX::RelaDyn); | |
| 364 | 331 | } |
| 365 | 332 | |
| 366 | 333 | // Add .got. MIPS' .got is so different from the other archs, |
| ... | ... | @@ -385,16 +352,22 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { |
| 385 | 352 | |
| 386 | 353 | // We always need to add rel[a].plt to output if it has entries. |
| 387 | 354 | // Even for static linking it can contain R_[*]_IRELATIVE relocations. |
| 388 | In<ELFT>::RelaPlt = make<RelocationSection<ELFT>>( | |
| 355 | InX::RelaPlt = make<RelocationSection<ELFT>>( | |
| 389 | 356 | Config->IsRela ? ".rela.plt" : ".rel.plt", false /*Sort*/); |
| 390 | Add(In<ELFT>::RelaPlt); | |
| 357 | Add(InX::RelaPlt); | |
| 391 | 358 | |
| 392 | 359 | // The RelaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure |
| 393 | // that the IRelative relocations are processed last by the dynamic loader | |
| 394 | In<ELFT>::RelaIplt = make<RelocationSection<ELFT>>( | |
| 395 | (Config->EMachine == EM_ARM) ? ".rel.dyn" : In<ELFT>::RelaPlt->Name, | |
| 360 | // that the IRelative relocations are processed last by the dynamic loader. | |
| 361 | // We cannot place the iplt section in .rel.dyn when Android relocation | |
| 362 | // packing is enabled because that would cause a section type mismatch. | |
| 363 | // However, because the Android dynamic loader reads .rel.plt after .rel.dyn, | |
| 364 | // we can get the desired behaviour by placing the iplt section in .rel.plt. | |
| 365 | InX::RelaIplt = make<RelocationSection<ELFT>>( | |
| 366 | (Config->EMachine == EM_ARM && !Config->AndroidPackDynRelocs) | |
| 367 | ? ".rel.dyn" | |
| 368 | : InX::RelaPlt->Name, | |
| 396 | 369 | false /*Sort*/); |
| 397 | Add(In<ELFT>::RelaIplt); | |
| 370 | Add(InX::RelaIplt); | |
| 398 | 371 | |
| 399 | 372 | InX::Plt = make<PltSection>(Target->PltHeaderSize); |
| 400 | 373 | Add(InX::Plt); |
| ... | ... | @@ -403,11 +376,11 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { |
| 403 | 376 | |
| 404 | 377 | if (!Config->Relocatable) { |
| 405 | 378 | if (Config->EhFrameHdr) { |
| 406 | In<ELFT>::EhFrameHdr = make<EhFrameHeader<ELFT>>(); | |
| 407 | Add(In<ELFT>::EhFrameHdr); | |
| 379 | InX::EhFrameHdr = make<EhFrameHeader>(); | |
| 380 | Add(InX::EhFrameHdr); | |
| 408 | 381 | } |
| 409 | In<ELFT>::EhFrame = make<EhFrameSection<ELFT>>(); | |
| 410 | Add(In<ELFT>::EhFrame); | |
| 382 | InX::EhFrame = make<EhFrameSection>(); | |
| 383 | Add(InX::EhFrame); | |
| 411 | 384 | } |
| 412 | 385 | |
| 413 | 386 | if (InX::SymTab) |
| ... | ... | @@ -415,10 +388,105 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { |
| 415 | 388 | Add(InX::ShStrTab); |
| 416 | 389 | if (InX::StrTab) |
| 417 | 390 | Add(InX::StrTab); |
| 391 | ||
| 392 | if (Config->EMachine == EM_ARM && !Config->Relocatable) | |
| 393 | // Add a sentinel to terminate .ARM.exidx. It helps an unwinder | |
| 394 | // to find the exact address range of the last entry. | |
| 395 | Add(make<ARMExidxSentinelSection>()); | |
| 396 | } | |
| 397 | ||
| 398 | // The main function of the writer. | |
| 399 | template <class ELFT> void Writer<ELFT>::run() { | |
| 400 | // Create linker-synthesized sections such as .got or .plt. | |
| 401 | // Such sections are of type input section. | |
| 402 | createSyntheticSections<ELFT>(); | |
| 403 | ||
| 404 | if (!Config->Relocatable) | |
| 405 | combineEhFrameSections<ELFT>(); | |
| 406 | ||
| 407 | // We want to process linker script commands. When SECTIONS command | |
| 408 | // is given we let it create sections. | |
| 409 | Script->processSectionCommands(); | |
| 410 | ||
| 411 | // Linker scripts controls how input sections are assigned to output sections. | |
| 412 | // Input sections that were not handled by scripts are called "orphans", and | |
| 413 | // they are assigned to output sections by the default rule. Process that. | |
| 414 | Script->addOrphanSections(); | |
| 415 | ||
| 416 | if (Config->Discard != DiscardPolicy::All) | |
| 417 | copyLocalSymbols(); | |
| 418 | ||
| 419 | if (Config->CopyRelocs) | |
| 420 | addSectionSymbols(); | |
| 421 | ||
| 422 | // Now that we have a complete set of output sections. This function | |
| 423 | // completes section contents. For example, we need to add strings | |
| 424 | // to the string table, and add entries to .got and .plt. | |
| 425 | // finalizeSections does that. | |
| 426 | finalizeSections(); | |
| 427 | if (errorCount()) | |
| 428 | return; | |
| 429 | ||
| 430 | Script->assignAddresses(); | |
| 431 | ||
| 432 | // If -compressed-debug-sections is specified, we need to compress | |
| 433 | // .debug_* sections. Do it right now because it changes the size of | |
| 434 | // output sections. | |
| 435 | for (OutputSection *Sec : OutputSections) | |
| 436 | Sec->maybeCompress<ELFT>(); | |
| 437 | ||
| 438 | Script->allocateHeaders(Phdrs); | |
| 439 | ||
| 440 | // Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a | |
| 441 | // 0 sized region. This has to be done late since only after assignAddresses | |
| 442 | // we know the size of the sections. | |
| 443 | removeEmptyPTLoad(); | |
| 444 | ||
| 445 | if (!Config->OFormatBinary) | |
| 446 | assignFileOffsets(); | |
| 447 | else | |
| 448 | assignFileOffsetsBinary(); | |
| 449 | ||
| 450 | setPhdrs(); | |
| 451 | ||
| 452 | if (Config->Relocatable) { | |
| 453 | for (OutputSection *Sec : OutputSections) | |
| 454 | Sec->Addr = 0; | |
| 455 | } | |
| 456 | ||
| 457 | // It does not make sense try to open the file if we have error already. | |
| 458 | if (errorCount()) | |
| 459 | return; | |
| 460 | // Write the result down to a file. | |
| 461 | openFile(); | |
| 462 | if (errorCount()) | |
| 463 | return; | |
| 464 | ||
| 465 | if (!Config->OFormatBinary) { | |
| 466 | writeTrapInstr(); | |
| 467 | writeHeader(); | |
| 468 | writeSections(); | |
| 469 | } else { | |
| 470 | writeSectionsBinary(); | |
| 471 | } | |
| 472 | ||
| 473 | // Backfill .note.gnu.build-id section content. This is done at last | |
| 474 | // because the content is usually a hash value of the entire output file. | |
| 475 | writeBuildId(); | |
| 476 | if (errorCount()) | |
| 477 | return; | |
| 478 | ||
| 479 | // Handle -Map option. | |
| 480 | writeMapFile(); | |
| 481 | if (errorCount()) | |
| 482 | return; | |
| 483 | ||
| 484 | if (auto E = Buffer->commit()) | |
| 485 | error("failed to write to the output file: " + toString(std::move(E))); | |
| 418 | 486 | } |
| 419 | 487 | |
| 420 | 488 | static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName, |
| 421 | const SymbolBody &B) { | |
| 489 | const Symbol &B) { | |
| 422 | 490 | if (B.isFile() || B.isSection()) |
| 423 | 491 | return false; |
| 424 | 492 | |
| ... | ... | @@ -443,27 +511,25 @@ static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName, |
| 443 | 511 | return !Sec || !(Sec->Flags & SHF_MERGE); |
| 444 | 512 | } |
| 445 | 513 | |
| 446 | static bool includeInSymtab(const SymbolBody &B) { | |
| 447 | if (!B.isLocal() && !B.symbol()->IsUsedInRegularObj) | |
| 514 | static bool includeInSymtab(const Symbol &B) { | |
| 515 | if (!B.isLocal() && !B.IsUsedInRegularObj) | |
| 448 | 516 | return false; |
| 449 | 517 | |
| 450 | if (auto *D = dyn_cast<DefinedRegular>(&B)) { | |
| 518 | if (auto *D = dyn_cast<Defined>(&B)) { | |
| 451 | 519 | // Always include absolute symbols. |
| 452 | 520 | SectionBase *Sec = D->Section; |
| 453 | 521 | if (!Sec) |
| 454 | 522 | return true; |
| 455 | if (auto *IS = dyn_cast<InputSectionBase>(Sec)) { | |
| 456 | Sec = IS->Repl; | |
| 457 | IS = cast<InputSectionBase>(Sec); | |
| 458 | // Exclude symbols pointing to garbage-collected sections. | |
| 459 | if (!IS->Live) | |
| 460 | return false; | |
| 461 | } | |
| 523 | Sec = Sec->Repl; | |
| 524 | // Exclude symbols pointing to garbage-collected sections. | |
| 525 | if (isa<InputSectionBase>(Sec) && !Sec->Live) | |
| 526 | return false; | |
| 462 | 527 | if (auto *S = dyn_cast<MergeInputSection>(Sec)) |
| 463 | 528 | if (!S->getSectionPiece(D->Value)->Live) |
| 464 | 529 | return false; |
| 530 | return true; | |
| 465 | 531 | } |
| 466 | return true; | |
| 532 | return B.Used; | |
| 467 | 533 | } |
| 468 | 534 | |
| 469 | 535 | // Local symbols are not in the linker's symbol table. This function scans |
| ... | ... | @@ -471,12 +537,13 @@ static bool includeInSymtab(const SymbolBody &B) { |
| 471 | 537 | template <class ELFT> void Writer<ELFT>::copyLocalSymbols() { |
| 472 | 538 | if (!InX::SymTab) |
| 473 | 539 | return; |
| 474 | for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) { | |
| 475 | for (SymbolBody *B : F->getLocalSymbols()) { | |
| 476 | if (!B->IsLocal) | |
| 540 | for (InputFile *File : ObjectFiles) { | |
| 541 | ObjFile<ELFT> *F = cast<ObjFile<ELFT>>(File); | |
| 542 | for (Symbol *B : F->getLocalSymbols()) { | |
| 543 | if (!B->isLocal()) | |
| 477 | 544 | fatal(toString(F) + |
| 478 | 545 | ": broken object: getLocalSymbols returns a non-local symbol"); |
| 479 | auto *DR = dyn_cast<DefinedRegular>(B); | |
| 546 | auto *DR = dyn_cast<Defined>(B); | |
| 480 | 547 | |
| 481 | 548 | // No reason to keep local undefined symbol in symtab. |
| 482 | 549 | if (!DR) |
| ... | ... | @@ -493,27 +560,36 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() { |
| 493 | 560 | } |
| 494 | 561 | |
| 495 | 562 | template <class ELFT> void Writer<ELFT>::addSectionSymbols() { |
| 496 | // Create one STT_SECTION symbol for each output section we might | |
| 497 | // have a relocation with. | |
| 498 | for (BaseCommand *Base : Script->Opt.Commands) { | |
| 499 | auto *Cmd = dyn_cast<OutputSectionCommand>(Base); | |
| 500 | if (!Cmd) | |
| 563 | // Create a section symbol for each output section so that we can represent | |
| 564 | // relocations that point to the section. If we know that no relocation is | |
| 565 | // referring to a section (that happens if the section is a synthetic one), we | |
| 566 | // don't create a section symbol for that section. | |
| 567 | for (BaseCommand *Base : Script->SectionCommands) { | |
| 568 | auto *Sec = dyn_cast<OutputSection>(Base); | |
| 569 | if (!Sec) | |
| 501 | 570 | continue; |
| 502 | auto I = llvm::find_if(Cmd->Commands, [](BaseCommand *Base) { | |
| 571 | auto I = llvm::find_if(Sec->SectionCommands, [](BaseCommand *Base) { | |
| 503 | 572 | if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) |
| 504 | 573 | return !ISD->Sections.empty(); |
| 505 | 574 | return false; |
| 506 | 575 | }); |
| 507 | if (I == Cmd->Commands.end()) | |
| 576 | if (I == Sec->SectionCommands.end()) | |
| 508 | 577 | continue; |
| 509 | 578 | InputSection *IS = cast<InputSectionDescription>(*I)->Sections[0]; |
| 510 | if (isa<SyntheticSection>(IS) || IS->Type == SHT_REL || | |
| 511 | IS->Type == SHT_RELA) | |
| 579 | ||
| 580 | // Relocations are not using REL[A] section symbols. | |
| 581 | if (IS->Type == SHT_REL || IS->Type == SHT_RELA) | |
| 582 | continue; | |
| 583 | ||
| 584 | // Unlike other synthetic sections, mergeable output sections contain data | |
| 585 | // copied from input sections, and there may be a relocation pointing to its | |
| 586 | // contents if -r or -emit-reloc are given. | |
| 587 | if (isa<SyntheticSection>(IS) && !(IS->Flags & SHF_MERGE)) | |
| 512 | 588 | continue; |
| 513 | 589 | |
| 514 | 590 | auto *Sym = |
| 515 | make<DefinedRegular>("", /*IsLocal=*/true, /*StOther=*/0, STT_SECTION, | |
| 516 | /*Value=*/0, /*Size=*/0, IS, nullptr); | |
| 591 | make<Defined>(IS->File, "", STB_LOCAL, /*StOther=*/0, STT_SECTION, | |
| 592 | /*Value=*/0, /*Size=*/0, IS); | |
| 517 | 593 | InX::SymTab->addSymbol(Sym); |
| 518 | 594 | } |
| 519 | 595 | } |
| ... | ... | @@ -524,7 +600,7 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() { |
| 524 | 600 | // |
| 525 | 601 | // This function returns true if a section needs to be put into a |
| 526 | 602 | // PT_GNU_RELRO segment. |
| 527 | bool elf::isRelroSection(const OutputSection *Sec) { | |
| 603 | static bool isRelroSection(const OutputSection *Sec) { | |
| 528 | 604 | if (!Config->ZRelro) |
| 529 | 605 | return false; |
| 530 | 606 | |
| ... | ... | @@ -575,20 +651,14 @@ bool elf::isRelroSection(const OutputSection *Sec) { |
| 575 | 651 | if (Sec == InX::Dynamic->getParent()) |
| 576 | 652 | return true; |
| 577 | 653 | |
| 578 | // .bss.rel.ro is used for copy relocations for read-only symbols. | |
| 579 | // Since the dynamic linker needs to process copy relocations, the | |
| 580 | // section cannot be read-only, but once initialized, they shouldn't | |
| 581 | // change. | |
| 582 | if (Sec == InX::BssRelRo->getParent()) | |
| 583 | return true; | |
| 584 | ||
| 585 | 654 | // Sections with some special names are put into RELRO. This is a |
| 586 | 655 | // bit unfortunate because section names shouldn't be significant in |
| 587 | 656 | // ELF in spirit. But in reality many linker features depend on |
| 588 | 657 | // magic section names. |
| 589 | 658 | StringRef S = Sec->Name; |
| 590 | return S == ".data.rel.ro" || S == ".ctors" || S == ".dtors" || S == ".jcr" || | |
| 591 | S == ".eh_frame" || S == ".openbsd.randomdata"; | |
| 659 | return S == ".data.rel.ro" || S == ".bss.rel.ro" || S == ".ctors" || | |
| 660 | S == ".dtors" || S == ".jcr" || S == ".eh_frame" || | |
| 661 | S == ".openbsd.randomdata"; | |
| 592 | 662 | } |
| 593 | 663 | |
| 594 | 664 | // We compute a rank for each section. The rank indicates where the |
| ... | ... | @@ -696,8 +766,8 @@ static unsigned getSectionRank(const OutputSection *Sec) { |
| 696 | 766 | if (IsNoBits) |
| 697 | 767 | Rank |= RF_BSS; |
| 698 | 768 | |
| 699 | // // Some architectures have additional ordering restrictions for sections | |
| 700 | // // within the same PT_LOAD. | |
| 769 | // Some architectures have additional ordering restrictions for sections | |
| 770 | // within the same PT_LOAD. | |
| 701 | 771 | if (Config->EMachine == EM_PPC64) { |
| 702 | 772 | // PPC64 has a number of special SHT_PROGBITS+SHF_ALLOC+SHF_WRITE sections |
| 703 | 773 | // that we would like to make sure appear is a specific order to maximize |
| ... | ... | @@ -735,8 +805,8 @@ static unsigned getSectionRank(const OutputSection *Sec) { |
| 735 | 805 | } |
| 736 | 806 | |
| 737 | 807 | static bool compareSections(const BaseCommand *ACmd, const BaseCommand *BCmd) { |
| 738 | const OutputSection *A = cast<OutputSectionCommand>(ACmd)->Sec; | |
| 739 | const OutputSection *B = cast<OutputSectionCommand>(BCmd)->Sec; | |
| 808 | const OutputSection *A = cast<OutputSection>(ACmd); | |
| 809 | const OutputSection *B = cast<OutputSection>(BCmd); | |
| 740 | 810 | if (A->SortRank != B->SortRank) |
| 741 | 811 | return A->SortRank < B->SortRank; |
| 742 | 812 | if (!(A->SortRank & RF_NOT_ADDR_SET)) |
| ... | ... | @@ -746,36 +816,14 @@ static bool compareSections(const BaseCommand *ACmd, const BaseCommand *BCmd) { |
| 746 | 816 | } |
| 747 | 817 | |
| 748 | 818 | void PhdrEntry::add(OutputSection *Sec) { |
| 749 | Last = Sec; | |
| 750 | if (!First) | |
| 751 | First = Sec; | |
| 819 | LastSec = Sec; | |
| 820 | if (!FirstSec) | |
| 821 | FirstSec = Sec; | |
| 752 | 822 | p_align = std::max(p_align, Sec->Alignment); |
| 753 | 823 | if (p_type == PT_LOAD) |
| 754 | Sec->FirstInPtLoad = First; | |
| 755 | } | |
| 756 | ||
| 757 | template <class ELFT> | |
| 758 | static Symbol *addRegular(StringRef Name, SectionBase *Sec, uint64_t Value, | |
| 759 | uint8_t StOther = STV_HIDDEN, | |
| 760 | uint8_t Binding = STB_WEAK) { | |
| 761 | // The linker generated symbols are added as STB_WEAK to allow user defined | |
| 762 | // ones to override them. | |
| 763 | return Symtab<ELFT>::X->addRegular(Name, StOther, STT_NOTYPE, Value, | |
| 764 | /*Size=*/0, Binding, Sec, | |
| 765 | /*File=*/nullptr); | |
| 766 | } | |
| 767 | ||
| 768 | template <class ELFT> | |
| 769 | static DefinedRegular * | |
| 770 | addOptionalRegular(StringRef Name, SectionBase *Sec, uint64_t Val, | |
| 771 | uint8_t StOther = STV_HIDDEN, uint8_t Binding = STB_GLOBAL) { | |
| 772 | SymbolBody *S = Symtab<ELFT>::X->find(Name); | |
| 773 | if (!S) | |
| 774 | return nullptr; | |
| 775 | if (S->isInCurrentDSO()) | |
| 776 | return nullptr; | |
| 777 | return cast<DefinedRegular>( | |
| 778 | addRegular<ELFT>(Name, Sec, Val, StOther, Binding)->body()); | |
| 824 | Sec->PtLoad = this; | |
| 825 | if (Sec->LMAExpr) | |
| 826 | ASectionHasLMA = true; | |
| 779 | 827 | } |
| 780 | 828 | |
| 781 | 829 | // The beginning and the ending of .rel[a].plt section are marked |
| ... | ... | @@ -785,177 +833,115 @@ addOptionalRegular(StringRef Name, SectionBase *Sec, uint64_t Val, |
| 785 | 833 | // need these symbols, since IRELATIVE relocs are resolved through GOT |
| 786 | 834 | // and PLT. For details, see http://www.airs.com/blog/archives/403. |
| 787 | 835 | template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() { |
| 788 | if (InX::DynSymTab) | |
| 836 | if (!Config->Static) | |
| 789 | 837 | return; |
| 790 | 838 | StringRef S = Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start"; |
| 791 | addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, 0, STV_HIDDEN, STB_WEAK); | |
| 839 | addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK); | |
| 792 | 840 | |
| 793 | 841 | S = Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end"; |
| 794 | addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, -1, STV_HIDDEN, STB_WEAK); | |
| 842 | addOptionalRegular(S, InX::RelaIplt, -1, STV_HIDDEN, STB_WEAK); | |
| 795 | 843 | } |
| 796 | 844 | |
| 797 | // The linker is expected to define some symbols depending on | |
| 798 | // the linking result. This function defines such symbols. | |
| 799 | template <class ELFT> void Writer<ELFT>::addReservedSymbols() { | |
| 800 | if (Config->EMachine == EM_MIPS) { | |
| 801 | // Define _gp for MIPS. st_value of _gp symbol will be updated by Writer | |
| 802 | // so that it points to an absolute address which by default is relative | |
| 803 | // to GOT. Default offset is 0x7ff0. | |
| 804 | // See "Global Data Symbols" in Chapter 6 in the following document: | |
| 805 | // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf | |
| 806 | ElfSym::MipsGp = Symtab<ELFT>::X->addAbsolute("_gp", STV_HIDDEN, STB_LOCAL); | |
| 807 | ||
| 808 | // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between | |
| 809 | // start of function and 'gp' pointer into GOT. | |
| 810 | if (Symtab<ELFT>::X->find("_gp_disp")) | |
| 811 | ElfSym::MipsGpDisp = | |
| 812 | Symtab<ELFT>::X->addAbsolute("_gp_disp", STV_HIDDEN, STB_LOCAL); | |
| 845 | template <class ELFT> | |
| 846 | void Writer<ELFT>::forEachRelSec(std::function<void(InputSectionBase &)> Fn) { | |
| 847 | // Scan all relocations. Each relocation goes through a series | |
| 848 | // of tests to determine if it needs special treatment, such as | |
| 849 | // creating GOT, PLT, copy relocations, etc. | |
| 850 | // Note that relocations for non-alloc sections are directly | |
| 851 | // processed by InputSection::relocateNonAlloc. | |
| 852 | for (InputSectionBase *IS : InputSections) | |
| 853 | if (IS->Live && isa<InputSection>(IS) && (IS->Flags & SHF_ALLOC)) | |
| 854 | Fn(*IS); | |
| 855 | for (EhInputSection *ES : InX::EhFrame->Sections) | |
| 856 | Fn(*ES); | |
| 857 | } | |
| 813 | 858 | |
| 814 | // The __gnu_local_gp is a magic symbol equal to the current value of 'gp' | |
| 815 | // pointer. This symbol is used in the code generated by .cpload pseudo-op | |
| 816 | // in case of using -mno-shared option. | |
| 817 | // https://sourceware.org/ml/binutils/2004-12/msg00094.html | |
| 818 | if (Symtab<ELFT>::X->find("__gnu_local_gp")) | |
| 819 | ElfSym::MipsLocalGp = | |
| 820 | Symtab<ELFT>::X->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_LOCAL); | |
| 859 | // This function generates assignments for predefined symbols (e.g. _end or | |
| 860 | // _etext) and inserts them into the commands sequence to be processed at the | |
| 861 | // appropriate time. This ensures that the value is going to be correct by the | |
| 862 | // time any references to these symbols are processed and is equivalent to | |
| 863 | // defining these symbols explicitly in the linker script. | |
| 864 | template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() { | |
| 865 | if (ElfSym::GlobalOffsetTable) { | |
| 866 | // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to | |
| 867 | // be at some offset from the base of the .got section, usually 0 or the end | |
| 868 | // of the .got | |
| 869 | InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot) | |
| 870 | : cast<InputSection>(InX::Got); | |
| 871 | ElfSym::GlobalOffsetTable->Section = GotSection; | |
| 821 | 872 | } |
| 822 | 873 | |
| 823 | // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to | |
| 824 | // be at some offset from the base of the .got section, usually 0 or the end | |
| 825 | // of the .got | |
| 826 | InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot) | |
| 827 | : cast<InputSection>(InX::Got); | |
| 828 | ElfSym::GlobalOffsetTable = addOptionalRegular<ELFT>( | |
| 829 | "_GLOBAL_OFFSET_TABLE_", GotSection, Target->GotBaseSymOff); | |
| 830 | ||
| 831 | // __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For | |
| 832 | // static linking the linker is required to optimize away any references to | |
| 833 | // __tls_get_addr, so it's not defined anywhere. Create a hidden definition | |
| 834 | // to avoid the undefined symbol error. | |
| 835 | if (!InX::DynSymTab) | |
| 836 | Symtab<ELFT>::X->addIgnored("__tls_get_addr"); | |
| 837 | ||
| 838 | // __ehdr_start is the location of ELF file headers. Note that we define | |
| 839 | // this symbol unconditionally even when using a linker script, which | |
| 840 | // differs from the behavior implemented by GNU linker which only define | |
| 841 | // this symbol if ELF headers are in the memory mapped segment. | |
| 842 | // __executable_start is not documented, but the expectation of at | |
| 843 | // least the android libc is that it points to the elf header too. | |
| 844 | // __dso_handle symbol is passed to cxa_finalize as a marker to identify | |
| 845 | // each DSO. The address of the symbol doesn't matter as long as they are | |
| 846 | // different in different DSOs, so we chose the start address of the DSO. | |
| 847 | for (const char *Name : | |
| 848 | {"__ehdr_start", "__executable_start", "__dso_handle"}) | |
| 849 | addOptionalRegular<ELFT>(Name, Out::ElfHeader, 0, STV_HIDDEN); | |
| 850 | ||
| 851 | // If linker script do layout we do not need to create any standart symbols. | |
| 852 | if (Script->Opt.HasSections) | |
| 853 | return; | |
| 854 | ||
| 855 | auto Add = [](StringRef S) { | |
| 856 | return addOptionalRegular<ELFT>(S, Out::ElfHeader, 0, STV_DEFAULT); | |
| 857 | }; | |
| 858 | ||
| 859 | ElfSym::Bss = Add("__bss_start"); | |
| 860 | ElfSym::End1 = Add("end"); | |
| 861 | ElfSym::End2 = Add("_end"); | |
| 862 | ElfSym::Etext1 = Add("etext"); | |
| 863 | ElfSym::Etext2 = Add("_etext"); | |
| 864 | ElfSym::Edata1 = Add("edata"); | |
| 865 | ElfSym::Edata2 = Add("_edata"); | |
| 866 | } | |
| 867 | ||
| 868 | // Sort input sections by section name suffixes for | |
| 869 | // __attribute__((init_priority(N))). | |
| 870 | static void sortInitFini(OutputSectionCommand *Cmd) { | |
| 871 | if (Cmd) | |
| 872 | Cmd->sortInitFini(); | |
| 873 | } | |
| 874 | PhdrEntry *Last = nullptr; | |
| 875 | PhdrEntry *LastRO = nullptr; | |
| 874 | 876 | |
| 875 | // Sort input sections by the special rule for .ctors and .dtors. | |
| 876 | static void sortCtorsDtors(OutputSectionCommand *Cmd) { | |
| 877 | if (Cmd) | |
| 878 | Cmd->sortCtorsDtors(); | |
| 879 | } | |
| 877 | for (PhdrEntry *P : Phdrs) { | |
| 878 | if (P->p_type != PT_LOAD) | |
| 879 | continue; | |
| 880 | Last = P; | |
| 881 | if (!(P->p_flags & PF_W)) | |
| 882 | LastRO = P; | |
| 883 | } | |
| 880 | 884 | |
| 881 | // Sort input sections using the list provided by --symbol-ordering-file. | |
| 882 | template <class ELFT> static void sortBySymbolsOrder() { | |
| 883 | if (Config->SymbolOrderingFile.empty()) | |
| 884 | return; | |
| 885 | if (LastRO) { | |
| 886 | // _etext is the first location after the last read-only loadable segment. | |
| 887 | if (ElfSym::Etext1) | |
| 888 | ElfSym::Etext1->Section = LastRO->LastSec; | |
| 889 | if (ElfSym::Etext2) | |
| 890 | ElfSym::Etext2->Section = LastRO->LastSec; | |
| 891 | } | |
| 885 | 892 | |
| 886 | // Build a map from symbols to their priorities. Symbols that didn't | |
| 887 | // appear in the symbol ordering file have the lowest priority 0. | |
| 888 | // All explicitly mentioned symbols have negative (higher) priorities. | |
| 889 | DenseMap<StringRef, int> SymbolOrder; | |
| 890 | int Priority = -Config->SymbolOrderingFile.size(); | |
| 891 | for (StringRef S : Config->SymbolOrderingFile) | |
| 892 | SymbolOrder.insert({S, Priority++}); | |
| 893 | ||
| 894 | // Build a map from sections to their priorities. | |
| 895 | DenseMap<SectionBase *, int> SectionOrder; | |
| 896 | for (elf::ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles()) { | |
| 897 | for (SymbolBody *Body : File->getSymbols()) { | |
| 898 | auto *D = dyn_cast<DefinedRegular>(Body); | |
| 899 | if (!D || !D->Section) | |
| 900 | continue; | |
| 901 | int &Priority = SectionOrder[D->Section]; | |
| 902 | Priority = std::min(Priority, SymbolOrder.lookup(D->getName())); | |
| 893 | if (Last) { | |
| 894 | // _edata points to the end of the last mapped initialized section. | |
| 895 | OutputSection *Edata = nullptr; | |
| 896 | for (OutputSection *OS : OutputSections) { | |
| 897 | if (OS->Type != SHT_NOBITS) | |
| 898 | Edata = OS; | |
| 899 | if (OS == Last->LastSec) | |
| 900 | break; | |
| 903 | 901 | } |
| 904 | } | |
| 905 | 902 | |
| 906 | // Sort sections by priority. | |
| 907 | for (BaseCommand *Base : Script->Opt.Commands) | |
| 908 | if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) | |
| 909 | Cmd->sort([&](InputSectionBase *S) { return SectionOrder.lookup(S); }); | |
| 910 | } | |
| 903 | if (ElfSym::Edata1) | |
| 904 | ElfSym::Edata1->Section = Edata; | |
| 905 | if (ElfSym::Edata2) | |
| 906 | ElfSym::Edata2->Section = Edata; | |
| 911 | 907 | |
| 912 | template <class ELFT> | |
| 913 | void Writer<ELFT>::forEachRelSec(std::function<void(InputSectionBase &)> Fn) { | |
| 914 | for (InputSectionBase *IS : InputSections) { | |
| 915 | if (!IS->Live) | |
| 916 | continue; | |
| 917 | // Scan all relocations. Each relocation goes through a series | |
| 918 | // of tests to determine if it needs special treatment, such as | |
| 919 | // creating GOT, PLT, copy relocations, etc. | |
| 920 | // Note that relocations for non-alloc sections are directly | |
| 921 | // processed by InputSection::relocateNonAlloc. | |
| 922 | if (!(IS->Flags & SHF_ALLOC)) | |
| 923 | continue; | |
| 924 | if (isa<InputSection>(IS) || isa<EhInputSection>(IS)) | |
| 925 | Fn(*IS); | |
| 908 | // _end is the first location after the uninitialized data region. | |
| 909 | if (ElfSym::End1) | |
| 910 | ElfSym::End1->Section = Last->LastSec; | |
| 911 | if (ElfSym::End2) | |
| 912 | ElfSym::End2->Section = Last->LastSec; | |
| 926 | 913 | } |
| 927 | 914 | |
| 928 | if (!Config->Relocatable) { | |
| 929 | for (EhInputSection *ES : In<ELFT>::EhFrame->Sections) | |
| 930 | Fn(*ES); | |
| 931 | } | |
| 932 | } | |
| 915 | if (ElfSym::Bss) | |
| 916 | ElfSym::Bss->Section = findSection(".bss"); | |
| 933 | 917 | |
| 934 | template <class ELFT> void Writer<ELFT>::createSections() { | |
| 935 | for (InputSectionBase *IS : InputSections) | |
| 936 | if (IS) | |
| 937 | Factory.addInputSec(IS, getOutputSectionName(IS->Name)); | |
| 938 | ||
| 939 | Script->fabricateDefaultCommands(); | |
| 940 | sortBySymbolsOrder<ELFT>(); | |
| 941 | sortInitFini(findSectionCommand(".init_array")); | |
| 942 | sortInitFini(findSectionCommand(".fini_array")); | |
| 943 | sortCtorsDtors(findSectionCommand(".ctors")); | |
| 944 | sortCtorsDtors(findSectionCommand(".dtors")); | |
| 918 | // Setup MIPS _gp_disp/__gnu_local_gp symbols which should | |
| 919 | // be equal to the _gp symbol's value. | |
| 920 | if (ElfSym::MipsGp) { | |
| 921 | // Find GP-relative section with the lowest address | |
| 922 | // and use this address to calculate default _gp value. | |
| 923 | for (OutputSection *OS : OutputSections) { | |
| 924 | if (OS->Flags & SHF_MIPS_GPREL) { | |
| 925 | ElfSym::MipsGp->Section = OS; | |
| 926 | ElfSym::MipsGp->Value = 0x7ff0; | |
| 927 | break; | |
| 928 | } | |
| 929 | } | |
| 930 | } | |
| 945 | 931 | } |
| 946 | 932 | |
| 947 | 933 | // We want to find how similar two ranks are. |
| 948 | 934 | // The more branches in getSectionRank that match, the more similar they are. |
| 949 | 935 | // Since each branch corresponds to a bit flag, we can just use |
| 950 | 936 | // countLeadingZeros. |
| 951 | static int getRankProximity(OutputSection *A, OutputSection *B) { | |
| 937 | static int getRankProximityAux(OutputSection *A, OutputSection *B) { | |
| 952 | 938 | return countLeadingZeros(A->SortRank ^ B->SortRank); |
| 953 | 939 | } |
| 954 | 940 | |
| 955 | 941 | static int getRankProximity(OutputSection *A, BaseCommand *B) { |
| 956 | if (auto *Cmd = dyn_cast<OutputSectionCommand>(B)) | |
| 957 | if (Cmd->Sec) | |
| 958 | return getRankProximity(A, Cmd->Sec); | |
| 942 | if (auto *Sec = dyn_cast<OutputSection>(B)) | |
| 943 | if (Sec->Live) | |
| 944 | return getRankProximityAux(A, Sec); | |
| 959 | 945 | return -1; |
| 960 | 946 | } |
| 961 | 947 | |
| ... | ... | @@ -974,7 +960,7 @@ static int getRankProximity(OutputSection *A, BaseCommand *B) { |
| 974 | 960 | // rw_sec : { *(rw_sec) } |
| 975 | 961 | // would mean that the RW PT_LOAD would become unaligned. |
| 976 | 962 | static bool shouldSkip(BaseCommand *Cmd) { |
| 977 | if (isa<OutputSectionCommand>(Cmd)) | |
| 963 | if (isa<OutputSection>(Cmd)) | |
| 978 | 964 | return false; |
| 979 | 965 | if (auto *Assign = dyn_cast<SymbolAssignment>(Cmd)) |
| 980 | 966 | return Assign->Name != "."; |
| ... | ... | @@ -988,7 +974,7 @@ template <typename ELFT> |
| 988 | 974 | static std::vector<BaseCommand *>::iterator |
| 989 | 975 | findOrphanPos(std::vector<BaseCommand *>::iterator B, |
| 990 | 976 | std::vector<BaseCommand *>::iterator E) { |
| 991 | OutputSection *Sec = cast<OutputSectionCommand>(*E)->Sec; | |
| 977 | OutputSection *Sec = cast<OutputSection>(*E); | |
| 992 | 978 | |
| 993 | 979 | // Find the first element that has as close a rank as possible. |
| 994 | 980 | auto I = std::max_element(B, E, [=](BaseCommand *A, BaseCommand *B) { |
| ... | ... | @@ -1000,44 +986,84 @@ findOrphanPos(std::vector<BaseCommand *>::iterator B, |
| 1000 | 986 | // Consider all existing sections with the same proximity. |
| 1001 | 987 | int Proximity = getRankProximity(Sec, *I); |
| 1002 | 988 | for (; I != E; ++I) { |
| 1003 | auto *Cmd = dyn_cast<OutputSectionCommand>(*I); | |
| 1004 | if (!Cmd || !Cmd->Sec) | |
| 989 | auto *CurSec = dyn_cast<OutputSection>(*I); | |
| 990 | if (!CurSec || !CurSec->Live) | |
| 1005 | 991 | continue; |
| 1006 | if (getRankProximity(Sec, Cmd->Sec) != Proximity || | |
| 1007 | Sec->SortRank < Cmd->Sec->SortRank) | |
| 992 | if (getRankProximity(Sec, CurSec) != Proximity || | |
| 993 | Sec->SortRank < CurSec->SortRank) | |
| 1008 | 994 | break; |
| 1009 | 995 | } |
| 1010 | auto J = std::find_if( | |
| 1011 | llvm::make_reverse_iterator(I), llvm::make_reverse_iterator(B), | |
| 1012 | [](BaseCommand *Cmd) { return isa<OutputSectionCommand>(Cmd); }); | |
| 996 | ||
| 997 | auto IsLiveSection = [](BaseCommand *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), | |
| 1003 | llvm::make_reverse_iterator(B), IsLiveSection); | |
| 1013 | 1004 | I = J.base(); |
| 1005 | ||
| 1006 | // As a special case, if the orphan section is the last section, put | |
| 1007 | // it at the very end, past any other commands. | |
| 1008 | // 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 | |
| 1010 | // alloc sections for example). | |
| 1011 | auto NextSec = std::find_if(I, E, IsLiveSection); | |
| 1012 | if (NextSec == E) | |
| 1013 | return E; | |
| 1014 | ||
| 1014 | 1015 | while (I != E && shouldSkip(*I)) |
| 1015 | 1016 | ++I; |
| 1016 | 1017 | return I; |
| 1017 | 1018 | } |
| 1018 | 1019 | |
| 1020 | // If no layout was provided by linker script, we want to apply default | |
| 1021 | // sorting for special input sections and handle --symbol-ordering-file. | |
| 1022 | template <class ELFT> void Writer<ELFT>::sortInputSections() { | |
| 1023 | assert(!Script->HasSectionsCommand); | |
| 1024 | ||
| 1025 | // Sort input sections by priority using the list provided | |
| 1026 | // by --symbol-ordering-file. | |
| 1027 | DenseMap<SectionBase *, int> Order = buildSectionOrder(); | |
| 1028 | if (!Order.empty()) | |
| 1029 | for (BaseCommand *Base : Script->SectionCommands) | |
| 1030 | if (auto *Sec = dyn_cast<OutputSection>(Base)) | |
| 1031 | if (Sec->Live) | |
| 1032 | Sec->sort([&](InputSectionBase *S) { return Order.lookup(S); }); | |
| 1033 | ||
| 1034 | // Sort input sections by section name suffixes for | |
| 1035 | // __attribute__((init_priority(N))). | |
| 1036 | if (OutputSection *Sec = findSection(".init_array")) | |
| 1037 | Sec->sortInitFini(); | |
| 1038 | if (OutputSection *Sec = findSection(".fini_array")) | |
| 1039 | Sec->sortInitFini(); | |
| 1040 | ||
| 1041 | // Sort input sections by the special rule for .ctors and .dtors. | |
| 1042 | if (OutputSection *Sec = findSection(".ctors")) | |
| 1043 | Sec->sortCtorsDtors(); | |
| 1044 | if (OutputSection *Sec = findSection(".dtors")) | |
| 1045 | Sec->sortCtorsDtors(); | |
| 1046 | } | |
| 1047 | ||
| 1019 | 1048 | template <class ELFT> void Writer<ELFT>::sortSections() { |
| 1020 | if (Script->Opt.HasSections) | |
| 1021 | Script->adjustSectionsBeforeSorting(); | |
| 1049 | Script->adjustSectionsBeforeSorting(); | |
| 1022 | 1050 | |
| 1023 | 1051 | // Don't sort if using -r. It is not necessary and we want to preserve the |
| 1024 | 1052 | // relative order for SHF_LINK_ORDER sections. |
| 1025 | 1053 | if (Config->Relocatable) |
| 1026 | 1054 | return; |
| 1027 | 1055 | |
| 1028 | for (BaseCommand *Base : Script->Opt.Commands) | |
| 1029 | if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) | |
| 1030 | if (OutputSection *Sec = Cmd->Sec) | |
| 1031 | Sec->SortRank = getSectionRank(Sec); | |
| 1032 | ||
| 1033 | if (!Script->Opt.HasSections) { | |
| 1034 | // We know that all the OutputSectionCommands are contiguous in | |
| 1035 | // this case. | |
| 1036 | auto E = Script->Opt.Commands.end(); | |
| 1037 | auto I = Script->Opt.Commands.begin(); | |
| 1038 | auto IsSection = [](BaseCommand *Base) { | |
| 1039 | return isa<OutputSectionCommand>(Base); | |
| 1040 | }; | |
| 1056 | for (BaseCommand *Base : Script->SectionCommands) | |
| 1057 | if (auto *Sec = dyn_cast<OutputSection>(Base)) | |
| 1058 | Sec->SortRank = getSectionRank(Sec); | |
| 1059 | ||
| 1060 | if (!Script->HasSectionsCommand) { | |
| 1061 | sortInputSections(); | |
| 1062 | ||
| 1063 | // 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); }; | |
| 1041 | 1067 | I = std::find_if(I, E, IsSection); |
| 1042 | 1068 | E = std::find_if(llvm::make_reverse_iterator(E), |
| 1043 | 1069 | llvm::make_reverse_iterator(I), IsSection) |
| ... | ... | @@ -1077,7 +1103,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() { |
| 1077 | 1103 | // a PT_LOAD. |
| 1078 | 1104 | // |
| 1079 | 1105 | // There is some ambiguity as to where exactly a new entry should be |
| 1080 | // inserted, because Opt.Commands contains not only output section | |
| 1106 | // inserted, because Commands contains not only output section | |
| 1081 | 1107 | // commands but also other types of commands such as symbol assignment |
| 1082 | 1108 | // expressions. There's no correct answer here due to the lack of the |
| 1083 | 1109 | // formal specification of the linker script. We use heuristics to |
| ... | ... | @@ -1085,11 +1111,11 @@ template <class ELFT> void Writer<ELFT>::sortSections() { |
| 1085 | 1111 | // after another commands. For the details, look at shouldSkip |
| 1086 | 1112 | // function. |
| 1087 | 1113 | |
| 1088 | auto I = Script->Opt.Commands.begin(); | |
| 1089 | auto E = Script->Opt.Commands.end(); | |
| 1114 | auto I = Script->SectionCommands.begin(); | |
| 1115 | auto E = Script->SectionCommands.end(); | |
| 1090 | 1116 | auto NonScriptI = std::find_if(I, E, [](BaseCommand *Base) { |
| 1091 | if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) | |
| 1092 | return Cmd->Sec && Cmd->Sec->SectionIndex == INT_MAX; | |
| 1117 | if (auto *Sec = dyn_cast<OutputSection>(Base)) | |
| 1118 | return Sec->Live && Sec->SectionIndex == INT_MAX; | |
| 1093 | 1119 | return false; |
| 1094 | 1120 | }); |
| 1095 | 1121 | |
| ... | ... | @@ -1109,13 +1135,13 @@ template <class ELFT> void Writer<ELFT>::sortSections() { |
| 1109 | 1135 | |
| 1110 | 1136 | while (NonScriptI != E) { |
| 1111 | 1137 | auto Pos = findOrphanPos<ELFT>(I, NonScriptI); |
| 1112 | OutputSection *Orphan = cast<OutputSectionCommand>(*NonScriptI)->Sec; | |
| 1138 | OutputSection *Orphan = cast<OutputSection>(*NonScriptI); | |
| 1113 | 1139 | |
| 1114 | 1140 | // As an optimization, find all sections with the same sort rank |
| 1115 | 1141 | // and insert them with one rotate. |
| 1116 | 1142 | unsigned Rank = Orphan->SortRank; |
| 1117 | 1143 | auto End = std::find_if(NonScriptI + 1, E, [=](BaseCommand *Cmd) { |
| 1118 | return cast<OutputSectionCommand>(Cmd)->Sec->SortRank != Rank; | |
| 1144 | return cast<OutputSection>(Cmd)->SortRank != Rank; | |
| 1119 | 1145 | }); |
| 1120 | 1146 | std::rotate(Pos, NonScriptI, End); |
| 1121 | 1147 | NonScriptI = End; |
| ... | ... | @@ -1124,6 +1150,139 @@ template <class ELFT> void Writer<ELFT>::sortSections() { |
| 1124 | 1150 | Script->adjustSectionsAfterSorting(); |
| 1125 | 1151 | } |
| 1126 | 1152 | |
| 1153 | static bool compareByFilePosition(InputSection *A, InputSection *B) { | |
| 1154 | // Synthetic, i. e. a sentinel section, should go last. | |
| 1155 | if (A->kind() == InputSectionBase::Synthetic || | |
| 1156 | B->kind() == InputSectionBase::Synthetic) | |
| 1157 | return A->kind() != InputSectionBase::Synthetic; | |
| 1158 | InputSection *LA = A->getLinkOrderDep(); | |
| 1159 | InputSection *LB = B->getLinkOrderDep(); | |
| 1160 | OutputSection *AOut = LA->getParent(); | |
| 1161 | OutputSection *BOut = LB->getParent(); | |
| 1162 | if (AOut != BOut) | |
| 1163 | return AOut->SectionIndex < BOut->SectionIndex; | |
| 1164 | return LA->OutSecOff < LB->OutSecOff; | |
| 1165 | } | |
| 1166 | ||
| 1167 | // This function is used by the --merge-exidx-entries to detect duplicate | |
| 1168 | // .ARM.exidx sections. It is Arm only. | |
| 1169 | // | |
| 1170 | // The .ARM.exidx section is of the form: | |
| 1171 | // | PREL31 offset to function | Unwind instructions for function | | |
| 1172 | // where the unwind instructions are either a small number of unwind | |
| 1173 | // instructions inlined into the table entry, the special CANT_UNWIND value of | |
| 1174 | // 0x1 or a PREL31 offset into a .ARM.extab Section that contains unwind | |
| 1175 | // instructions. | |
| 1176 | // | |
| 1177 | // We return true if all the unwind instructions in the .ARM.exidx entries of | |
| 1178 | // Cur can be merged into the last entry of Prev. | |
| 1179 | static bool isDuplicateArmExidxSec(InputSection *Prev, InputSection *Cur) { | |
| 1180 | ||
| 1181 | // References to .ARM.Extab Sections have bit 31 clear and are not the | |
| 1182 | // special EXIDX_CANTUNWIND bit-pattern. | |
| 1183 | auto IsExtabRef = [](uint32_t Unwind) { | |
| 1184 | return (Unwind & 0x80000000) == 0 && Unwind != 0x1; | |
| 1185 | }; | |
| 1186 | ||
| 1187 | struct ExidxEntry { | |
| 1188 | ulittle32_t Fn; | |
| 1189 | ulittle32_t Unwind; | |
| 1190 | }; | |
| 1191 | ||
| 1192 | // Get the last table Entry from the previous .ARM.exidx section. | |
| 1193 | const ExidxEntry &PrevEntry = *reinterpret_cast<const ExidxEntry *>( | |
| 1194 | Prev->Data.data() + Prev->getSize() - sizeof(ExidxEntry)); | |
| 1195 | if (IsExtabRef(PrevEntry.Unwind)) | |
| 1196 | return false; | |
| 1197 | ||
| 1198 | // We consider the unwind instructions of an .ARM.exidx table entry | |
| 1199 | // a duplicate if the previous unwind instructions if: | |
| 1200 | // - Both are the special EXIDX_CANTUNWIND. | |
| 1201 | // - Both are the same inline unwind instructions. | |
| 1202 | // We do not attempt to follow and check links into .ARM.extab tables as | |
| 1203 | // consecutive identical entries are rare and the effort to check that they | |
| 1204 | // are identical is high. | |
| 1205 | ||
| 1206 | if (isa<SyntheticSection>(Cur)) | |
| 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) | |
| 1215 | return false; | |
| 1216 | // All table entries in this .ARM.exidx Section can be merged into the | |
| 1217 | // previous Section. | |
| 1218 | return true; | |
| 1219 | } | |
| 1220 | ||
| 1221 | template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() { | |
| 1222 | for (OutputSection *Sec : OutputSections) { | |
| 1223 | if (!(Sec->Flags & SHF_LINK_ORDER)) | |
| 1224 | continue; | |
| 1225 | ||
| 1226 | // Link order may be distributed across several InputSectionDescriptions | |
| 1227 | // but sort must consider them all at once. | |
| 1228 | std::vector<InputSection **> ScriptSections; | |
| 1229 | std::vector<InputSection *> Sections; | |
| 1230 | for (BaseCommand *Base : Sec->SectionCommands) { | |
| 1231 | if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) { | |
| 1232 | for (InputSection *&IS : ISD->Sections) { | |
| 1233 | ScriptSections.push_back(&IS); | |
| 1234 | Sections.push_back(IS); | |
| 1235 | } | |
| 1236 | } | |
| 1237 | } | |
| 1238 | std::stable_sort(Sections.begin(), Sections.end(), compareByFilePosition); | |
| 1239 | ||
| 1240 | if (!Config->Relocatable && Config->EMachine == EM_ARM && | |
| 1241 | Sec->Type == SHT_ARM_EXIDX) { | |
| 1242 | ||
| 1243 | if (!Sections.empty() && isa<ARMExidxSentinelSection>(Sections.back())) { | |
| 1244 | assert(Sections.size() >= 2 && | |
| 1245 | "We should create a sentinel section only if there are " | |
| 1246 | "alive regular exidx sections."); | |
| 1247 | // The last executable section is required to fill the sentinel. | |
| 1248 | // 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(); | |
| 1251 | } | |
| 1252 | ||
| 1253 | if (Config->MergeArmExidx) { | |
| 1254 | // The EHABI for the Arm Architecture permits consecutive identical | |
| 1255 | // table entries to be merged. We use a simple implementation that | |
| 1256 | // removes a .ARM.exidx Input Section if it can be merged into the | |
| 1257 | // previous one. This does not require any rewriting of InputSection | |
| 1258 | // contents but misses opportunities for fine grained deduplication | |
| 1259 | // where only a subset of the InputSection contents can be merged. | |
| 1260 | int Cur = 1; | |
| 1261 | int Prev = 0; | |
| 1262 | // The last one is a sentinel entry which should not be removed. | |
| 1263 | int N = Sections.size() - 1; | |
| 1264 | while (Cur < N) { | |
| 1265 | if (isDuplicateArmExidxSec(Sections[Prev], Sections[Cur])) | |
| 1266 | Sections[Cur] = nullptr; | |
| 1267 | else | |
| 1268 | Prev = Cur; | |
| 1269 | ++Cur; | |
| 1270 | } | |
| 1271 | } | |
| 1272 | } | |
| 1273 | ||
| 1274 | for (int I = 0, N = Sections.size(); I < N; ++I) | |
| 1275 | *ScriptSections[I] = Sections[I]; | |
| 1276 | ||
| 1277 | // Remove the Sections we marked as duplicate earlier. | |
| 1278 | for (BaseCommand *Base : Sec->SectionCommands) | |
| 1279 | if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) | |
| 1280 | ISD->Sections.erase( | |
| 1281 | std::remove(ISD->Sections.begin(), ISD->Sections.end(), nullptr), | |
| 1282 | ISD->Sections.end()); | |
| 1283 | } | |
| 1284 | } | |
| 1285 | ||
| 1127 | 1286 | static void applySynthetic(const std::vector<SyntheticSection *> &Sections, |
| 1128 | 1287 | std::function<void(SyntheticSection *)> Fn) { |
| 1129 | 1288 | for (SyntheticSection *SS : Sections) |
| ... | ... | @@ -1131,10 +1290,18 @@ static void applySynthetic(const std::vector<SyntheticSection *> &Sections, |
| 1131 | 1290 | Fn(SS); |
| 1132 | 1291 | } |
| 1133 | 1292 | |
| 1134 | // We need to add input synthetic sections early in createSyntheticSections() | |
| 1135 | // to make them visible from linkescript side. But not all sections are always | |
| 1136 | // required to be in output. For example we don't need dynamic section content | |
| 1137 | // sometimes. This function filters out such unused sections from the output. | |
| 1293 | // In order to allow users to manipulate linker-synthesized sections, | |
| 1294 | // we had to add synthetic sections to the input section list early, | |
| 1295 | // even before we make decisions whether they are needed. This allows | |
| 1296 | // users to write scripts like this: ".mygot : { .got }". | |
| 1297 | // | |
| 1298 | // Doing it has an unintended side effects. If it turns out that we | |
| 1299 | // don't need a .got (for example) at all because there's no | |
| 1300 | // relocation that needs a .got, we don't want to emit .got. | |
| 1301 | // | |
| 1302 | // To deal with the above problem, this function is called after | |
| 1303 | // scanRelocations is called to remove synthetic sections that turn | |
| 1304 | // out to be empty. | |
| 1138 | 1305 | static void removeUnusedSyntheticSections() { |
| 1139 | 1306 | // All input synthetic sections that can be empty are placed after |
| 1140 | 1307 | // all regular ones. We iterate over them all and exit at first |
| ... | ... | @@ -1146,55 +1313,73 @@ static void removeUnusedSyntheticSections() { |
| 1146 | 1313 | OutputSection *OS = SS->getParent(); |
| 1147 | 1314 | if (!SS->empty() || !OS) |
| 1148 | 1315 | continue; |
| 1149 | if ((SS == InX::Got || SS == InX::MipsGot) && ElfSym::GlobalOffsetTable) | |
| 1150 | continue; | |
| 1151 | 1316 | |
| 1152 | OutputSectionCommand *Cmd = Script->getCmd(OS); | |
| 1153 | std::vector<BaseCommand *>::iterator Empty = Cmd->Commands.end(); | |
| 1154 | for (auto I = Cmd->Commands.begin(), E = Cmd->Commands.end(); I != E; ++I) { | |
| 1317 | std::vector<BaseCommand *>::iterator Empty = OS->SectionCommands.end(); | |
| 1318 | for (auto I = OS->SectionCommands.begin(), E = OS->SectionCommands.end(); | |
| 1319 | I != E; ++I) { | |
| 1155 | 1320 | BaseCommand *B = *I; |
| 1156 | 1321 | if (auto *ISD = dyn_cast<InputSectionDescription>(B)) { |
| 1157 | auto P = std::find(ISD->Sections.begin(), ISD->Sections.end(), SS); | |
| 1158 | if (P != ISD->Sections.end()) | |
| 1159 | ISD->Sections.erase(P); | |
| 1322 | llvm::erase_if(ISD->Sections, | |
| 1323 | [=](InputSection *IS) { return IS == SS; }); | |
| 1160 | 1324 | if (ISD->Sections.empty()) |
| 1161 | 1325 | Empty = I; |
| 1162 | 1326 | } |
| 1163 | 1327 | } |
| 1164 | if (Empty != Cmd->Commands.end()) | |
| 1165 | Cmd->Commands.erase(Empty); | |
| 1328 | if (Empty != OS->SectionCommands.end()) | |
| 1329 | OS->SectionCommands.erase(Empty); | |
| 1166 | 1330 | |
| 1167 | 1331 | // If there are no other sections in the output section, remove it from the |
| 1168 | 1332 | // output. |
| 1169 | if (Cmd->Commands.empty()) { | |
| 1170 | // Also remove script commands matching the output section. | |
| 1171 | auto &Cmds = Script->Opt.Commands; | |
| 1172 | auto I = std::remove_if(Cmds.begin(), Cmds.end(), [&](BaseCommand *Cmd) { | |
| 1173 | if (auto *OSCmd = dyn_cast<OutputSectionCommand>(Cmd)) | |
| 1174 | return OSCmd->Sec == OS; | |
| 1175 | return false; | |
| 1176 | }); | |
| 1177 | Cmds.erase(I, Cmds.end()); | |
| 1178 | } | |
| 1333 | if (OS->SectionCommands.empty()) | |
| 1334 | OS->Live = false; | |
| 1179 | 1335 | } |
| 1180 | 1336 | } |
| 1181 | 1337 | |
| 1338 | // Returns true if a symbol can be replaced at load-time by a symbol | |
| 1339 | // with the same name defined in other ELF executable or DSO. | |
| 1340 | static bool computeIsPreemptible(const Symbol &B) { | |
| 1341 | assert(!B.isLocal()); | |
| 1342 | // Only symbols that appear in dynsym can be preempted. | |
| 1343 | if (!B.includeInDynsym()) | |
| 1344 | return false; | |
| 1345 | ||
| 1346 | // Only default visibility symbols can be preempted. | |
| 1347 | if (B.Visibility != STV_DEFAULT) | |
| 1348 | return false; | |
| 1349 | ||
| 1350 | // At this point copy relocations have not been created yet, so any | |
| 1351 | // symbol that is not defined locally is preemptible. | |
| 1352 | if (!B.isDefined()) | |
| 1353 | return true; | |
| 1354 | ||
| 1355 | // If we have a dynamic list it specifies which local symbols are preemptible. | |
| 1356 | if (Config->HasDynamicList) | |
| 1357 | return false; | |
| 1358 | ||
| 1359 | if (!Config->Shared) | |
| 1360 | return false; | |
| 1361 | ||
| 1362 | // -Bsymbolic means that definitions are not preempted. | |
| 1363 | if (Config->Bsymbolic || (Config->BsymbolicFunctions && B.isFunc())) | |
| 1364 | return false; | |
| 1365 | return true; | |
| 1366 | } | |
| 1367 | ||
| 1182 | 1368 | // Create output section objects and add them to OutputSections. |
| 1183 | 1369 | template <class ELFT> void Writer<ELFT>::finalizeSections() { |
| 1184 | Out::DebugInfo = findSectionInScript(".debug_info"); | |
| 1185 | Out::PreinitArray = findSectionInScript(".preinit_array"); | |
| 1186 | Out::InitArray = findSectionInScript(".init_array"); | |
| 1187 | Out::FiniArray = findSectionInScript(".fini_array"); | |
| 1370 | Out::DebugInfo = findSection(".debug_info"); | |
| 1371 | Out::PreinitArray = findSection(".preinit_array"); | |
| 1372 | Out::InitArray = findSection(".init_array"); | |
| 1373 | Out::FiniArray = findSection(".fini_array"); | |
| 1188 | 1374 | |
| 1189 | 1375 | // The linker needs to define SECNAME_start, SECNAME_end and SECNAME_stop |
| 1190 | 1376 | // symbols for sections, so that the runtime can get the start and end |
| 1191 | 1377 | // addresses of each section by section name. Add such symbols. |
| 1192 | 1378 | if (!Config->Relocatable) { |
| 1193 | 1379 | addStartEndSymbols(); |
| 1194 | for (BaseCommand *Base : Script->Opt.Commands) | |
| 1195 | if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) | |
| 1196 | if (Cmd->Sec) | |
| 1197 | addStartStopSymbols(Cmd->Sec); | |
| 1380 | for (BaseCommand *Base : Script->SectionCommands) | |
| 1381 | if (auto *Sec = dyn_cast<OutputSection>(Base)) | |
| 1382 | addStartStopSymbols(Sec); | |
| 1198 | 1383 | } |
| 1199 | 1384 | |
| 1200 | 1385 | // Add _DYNAMIC symbol. Unlike GNU gold, our _DYNAMIC symbol has no type. |
| ... | ... | @@ -1202,7 +1387,9 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { |
| 1202 | 1387 | // Even the author of gold doesn't remember why gold behaves that way. |
| 1203 | 1388 | // https://sourceware.org/ml/binutils/2002-03/msg00360.html |
| 1204 | 1389 | if (InX::DynSymTab) |
| 1205 | addRegular<ELFT>("_DYNAMIC", InX::Dynamic, 0); | |
| 1390 | Symtab->addRegular("_DYNAMIC", STV_HIDDEN, STT_NOTYPE, 0 /*Value*/, | |
| 1391 | /*Size=*/0, STB_WEAK, InX::Dynamic, | |
| 1392 | /*File=*/nullptr); | |
| 1206 | 1393 | |
| 1207 | 1394 | // Define __rel[a]_iplt_{start,end} symbols if needed. |
| 1208 | 1395 | addRelIpltSymbols(); |
| ... | ... | @@ -1210,12 +1397,16 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { |
| 1210 | 1397 | // This responsible for splitting up .eh_frame section into |
| 1211 | 1398 | // pieces. The relocation scan uses those pieces, so this has to be |
| 1212 | 1399 | // earlier. |
| 1213 | applySynthetic({In<ELFT>::EhFrame}, | |
| 1400 | applySynthetic({InX::EhFrame}, | |
| 1214 | 1401 | [](SyntheticSection *SS) { SS->finalizeContents(); }); |
| 1215 | 1402 | |
| 1403 | for (Symbol *S : Symtab->getSymbols()) | |
| 1404 | S->IsPreemptible |= computeIsPreemptible(*S); | |
| 1405 | ||
| 1216 | 1406 | // Scan relocations. This must be done after every symbol is declared so that |
| 1217 | 1407 | // we can correctly decide if a dynamic relocation is needed. |
| 1218 | forEachRelSec(scanRelocations<ELFT>); | |
| 1408 | if (!Config->Relocatable) | |
| 1409 | forEachRelSec(scanRelocations<ELFT>); | |
| 1219 | 1410 | |
| 1220 | 1411 | if (InX::Plt && !InX::Plt->empty()) |
| 1221 | 1412 | InX::Plt->addSymbols(); |
| ... | ... | @@ -1224,42 +1415,40 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { |
| 1224 | 1415 | |
| 1225 | 1416 | // Now that we have defined all possible global symbols including linker- |
| 1226 | 1417 | // synthesized ones. Visit all symbols to give the finishing touches. |
| 1227 | for (Symbol *S : Symtab<ELFT>::X->getSymbols()) { | |
| 1228 | SymbolBody *Body = S->body(); | |
| 1229 | ||
| 1230 | if (!includeInSymtab(*Body)) | |
| 1418 | for (Symbol *Sym : Symtab->getSymbols()) { | |
| 1419 | if (!includeInSymtab(*Sym)) | |
| 1231 | 1420 | continue; |
| 1232 | 1421 | if (InX::SymTab) |
| 1233 | InX::SymTab->addSymbol(Body); | |
| 1422 | InX::SymTab->addSymbol(Sym); | |
| 1234 | 1423 | |
| 1235 | if (InX::DynSymTab && S->includeInDynsym()) { | |
| 1236 | InX::DynSymTab->addSymbol(Body); | |
| 1237 | if (auto *SS = dyn_cast<SharedSymbol>(Body)) | |
| 1238 | if (cast<SharedFile<ELFT>>(SS->File)->isNeeded()) | |
| 1424 | if (InX::DynSymTab && Sym->includeInDynsym()) { | |
| 1425 | InX::DynSymTab->addSymbol(Sym); | |
| 1426 | if (auto *SS = dyn_cast<SharedSymbol>(Sym)) | |
| 1427 | if (cast<SharedFile<ELFT>>(Sym->File)->IsNeeded) | |
| 1239 | 1428 | In<ELFT>::VerNeed->addSymbol(SS); |
| 1240 | 1429 | } |
| 1241 | 1430 | } |
| 1242 | 1431 | |
| 1243 | 1432 | // Do not proceed if there was an undefined symbol. |
| 1244 | if (ErrorCount) | |
| 1433 | if (errorCount()) | |
| 1245 | 1434 | return; |
| 1246 | 1435 | |
| 1247 | addPredefinedSections(); | |
| 1248 | 1436 | removeUnusedSyntheticSections(); |
| 1249 | 1437 | |
| 1250 | 1438 | sortSections(); |
| 1439 | Script->removeEmptyCommands(); | |
| 1251 | 1440 | |
| 1252 | 1441 | // Now that we have the final list, create a list of all the |
| 1253 | // OutputSectionCommands for convenience. | |
| 1254 | for (BaseCommand *Base : Script->Opt.Commands) | |
| 1255 | if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) | |
| 1256 | OutputSectionCommands.push_back(Cmd); | |
| 1442 | // OutputSections for convenience. | |
| 1443 | for (BaseCommand *Base : Script->SectionCommands) | |
| 1444 | if (auto *Sec = dyn_cast<OutputSection>(Base)) | |
| 1445 | OutputSections.push_back(Sec); | |
| 1257 | 1446 | |
| 1258 | 1447 | // Prefer command line supplied address over other constraints. |
| 1259 | for (OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 1260 | auto I = Config->SectionStartMap.find(Cmd->Name); | |
| 1448 | for (OutputSection *Sec : OutputSections) { | |
| 1449 | auto I = Config->SectionStartMap.find(Sec->Name); | |
| 1261 | 1450 | if (I != Config->SectionStartMap.end()) |
| 1262 | Cmd->AddrExpr = [=] { return I->second; }; | |
| 1451 | Sec->AddrExpr = [=] { return I->second; }; | |
| 1263 | 1452 | } |
| 1264 | 1453 | |
| 1265 | 1454 | // This is a bit of a hack. A value of 0 means undef, so we set it |
| ... | ... | @@ -1268,8 +1457,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { |
| 1268 | 1457 | Out::ElfHeader->SectionIndex = 1; |
| 1269 | 1458 | |
| 1270 | 1459 | unsigned I = 1; |
| 1271 | for (OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 1272 | OutputSection *Sec = Cmd->Sec; | |
| 1460 | for (OutputSection *Sec : OutputSections) { | |
| 1273 | 1461 | Sec->SectionIndex = I++; |
| 1274 | 1462 | Sec->ShName = InX::ShStrTab->addString(Sec->Name); |
| 1275 | 1463 | } |
| ... | ... | @@ -1283,66 +1471,64 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { |
| 1283 | 1471 | Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size(); |
| 1284 | 1472 | } |
| 1285 | 1473 | |
| 1474 | // Some symbols are defined in term of program headers. Now that we | |
| 1475 | // have the headers, we can find out which sections they point to. | |
| 1476 | setReservedSymbolSections(); | |
| 1477 | ||
| 1286 | 1478 | // Dynamic section must be the last one in this list and dynamic |
| 1287 | 1479 | // symbol table section (DynSymTab) must be the first one. |
| 1288 | applySynthetic({InX::DynSymTab, InX::Bss, InX::BssRelRo, | |
| 1289 | InX::GnuHashTab, In<ELFT>::HashTab, InX::SymTab, | |
| 1290 | InX::ShStrTab, InX::StrTab, In<ELFT>::VerDef, | |
| 1291 | InX::DynStrTab, InX::GdbIndex, InX::Got, | |
| 1292 | InX::MipsGot, InX::IgotPlt, InX::GotPlt, | |
| 1293 | In<ELFT>::RelaDyn, In<ELFT>::RelaIplt, In<ELFT>::RelaPlt, | |
| 1294 | InX::Plt, InX::Iplt, In<ELFT>::EhFrameHdr, | |
| 1295 | In<ELFT>::VerSym, In<ELFT>::VerNeed, InX::Dynamic}, | |
| 1296 | [](SyntheticSection *SS) { SS->finalizeContents(); }); | |
| 1480 | applySynthetic( | |
| 1481 | {InX::DynSymTab, InX::Bss, InX::BssRelRo, InX::GnuHashTab, | |
| 1482 | InX::HashTab, InX::SymTab, InX::ShStrTab, InX::StrTab, | |
| 1483 | In<ELFT>::VerDef, InX::DynStrTab, InX::Got, InX::MipsGot, | |
| 1484 | InX::IgotPlt, InX::GotPlt, InX::RelaDyn, InX::RelaIplt, | |
| 1485 | InX::RelaPlt, InX::Plt, InX::Iplt, InX::EhFrameHdr, | |
| 1486 | In<ELFT>::VerSym, In<ELFT>::VerNeed, InX::Dynamic}, | |
| 1487 | [](SyntheticSection *SS) { SS->finalizeContents(); }); | |
| 1488 | ||
| 1489 | if (!Script->HasSectionsCommand && !Config->Relocatable) | |
| 1490 | fixSectionAlignments(); | |
| 1491 | ||
| 1492 | // After link order processing .ARM.exidx sections can be deduplicated, which | |
| 1493 | // needs to be resolved before any other address dependent operation. | |
| 1494 | resolveShfLinkOrder(); | |
| 1297 | 1495 | |
| 1298 | // Some architectures use small displacements for jump instructions. | |
| 1299 | // It is linker's responsibility to create thunks containing long | |
| 1300 | // jump instructions if jump targets are too far. Create thunks. | |
| 1301 | if (Target->NeedsThunks) { | |
| 1302 | // FIXME: only ARM Interworking and Mips LA25 Thunks are implemented, | |
| 1303 | // these | |
| 1304 | // do not require address information. To support range extension Thunks | |
| 1305 | // we need to assign addresses so that we can tell if jump instructions | |
| 1306 | // are out of range. This will need to turn into a loop that converges | |
| 1307 | // when no more Thunks are added | |
| 1496 | // Some architectures need to generate content that depends on the address | |
| 1497 | // of InputSections. For example some architectures use small displacements | |
| 1498 | // for jump instructions that is is the linker's responsibility for creating | |
| 1499 | // range extension thunks for. As the generation of the content may also | |
| 1500 | // alter InputSection addresses we must converge to a fixed point. | |
| 1501 | if (Target->NeedsThunks || Config->AndroidPackDynRelocs) { | |
| 1308 | 1502 | ThunkCreator TC; |
| 1309 | Script->assignAddresses(); | |
| 1310 | if (TC.createThunks(OutputSectionCommands)) { | |
| 1311 | applySynthetic({InX::MipsGot}, | |
| 1312 | [](SyntheticSection *SS) { SS->updateAllocSize(); }); | |
| 1313 | if (TC.createThunks(OutputSectionCommands)) | |
| 1314 | fatal("All non-range thunks should be created in first call"); | |
| 1315 | } | |
| 1503 | AArch64Err843419Patcher A64P; | |
| 1504 | bool Changed; | |
| 1505 | do { | |
| 1506 | Script->assignAddresses(); | |
| 1507 | Changed = false; | |
| 1508 | if (Target->NeedsThunks) | |
| 1509 | Changed |= TC.createThunks(OutputSections); | |
| 1510 | if (Config->FixCortexA53Errata843419) { | |
| 1511 | if (Changed) | |
| 1512 | Script->assignAddresses(); | |
| 1513 | Changed |= A64P.createFixes(); | |
| 1514 | } | |
| 1515 | if (InX::MipsGot) | |
| 1516 | InX::MipsGot->updateAllocSize(); | |
| 1517 | Changed |= InX::RelaDyn->updateAllocSize(); | |
| 1518 | } while (Changed); | |
| 1316 | 1519 | } |
| 1317 | 1520 | |
| 1318 | 1521 | // Fill other section headers. The dynamic table is finalized |
| 1319 | 1522 | // at the end because some tags like RELSZ depend on result |
| 1320 | 1523 | // of finalizing other sections. |
| 1321 | for (OutputSectionCommand *Cmd : OutputSectionCommands) | |
| 1322 | Cmd->finalize<ELFT>(); | |
| 1524 | for (OutputSection *Sec : OutputSections) | |
| 1525 | Sec->finalize<ELFT>(); | |
| 1323 | 1526 | |
| 1324 | 1527 | // createThunks may have added local symbols to the static symbol table |
| 1325 | applySynthetic({InX::SymTab, InX::ShStrTab, InX::StrTab}, | |
| 1528 | applySynthetic({InX::SymTab}, | |
| 1326 | 1529 | [](SyntheticSection *SS) { SS->postThunkContents(); }); |
| 1327 | 1530 | } |
| 1328 | 1531 | |
| 1329 | template <class ELFT> void Writer<ELFT>::addPredefinedSections() { | |
| 1330 | // ARM ABI requires .ARM.exidx to be terminated by some piece of data. | |
| 1331 | // We have the terminater synthetic section class. Add that at the end. | |
| 1332 | OutputSectionCommand *Cmd = findSectionCommand(".ARM.exidx"); | |
| 1333 | if (!Cmd || !Cmd->Sec || Config->Relocatable) | |
| 1334 | return; | |
| 1335 | ||
| 1336 | auto *Sentinel = make<ARMExidxSentinelSection>(); | |
| 1337 | Cmd->Sec->addSection(Sentinel); | |
| 1338 | // Add the sentinel to the last of these too. | |
| 1339 | auto ISD = std::find_if(Cmd->Commands.rbegin(), Cmd->Commands.rend(), | |
| 1340 | [](const BaseCommand *Base) { | |
| 1341 | return isa<InputSectionDescription>(Base); | |
| 1342 | }); | |
| 1343 | cast<InputSectionDescription>(*ISD)->Sections.push_back(Sentinel); | |
| 1344 | } | |
| 1345 | ||
| 1346 | 1532 | // The linker is expected to define SECNAME_start and SECNAME_end |
| 1347 | 1533 | // symbols for a few sections. This function defines them. |
| 1348 | 1534 | template <class ELFT> void Writer<ELFT>::addStartEndSymbols() { |
| ... | ... | @@ -1350,13 +1536,13 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() { |
| 1350 | 1536 | // These symbols resolve to the image base if the section does not exist. |
| 1351 | 1537 | // A special value -1 indicates end of the section. |
| 1352 | 1538 | if (OS) { |
| 1353 | addOptionalRegular<ELFT>(Start, OS, 0); | |
| 1354 | addOptionalRegular<ELFT>(End, OS, -1); | |
| 1539 | addOptionalRegular(Start, OS, 0); | |
| 1540 | addOptionalRegular(End, OS, -1); | |
| 1355 | 1541 | } else { |
| 1356 | 1542 | if (Config->Pic) |
| 1357 | 1543 | OS = Out::ElfHeader; |
| 1358 | addOptionalRegular<ELFT>(Start, OS, 0); | |
| 1359 | addOptionalRegular<ELFT>(End, OS, 0); | |
| 1544 | addOptionalRegular(Start, OS, 0); | |
| 1545 | addOptionalRegular(End, OS, 0); | |
| 1360 | 1546 | } |
| 1361 | 1547 | }; |
| 1362 | 1548 | |
| ... | ... | @@ -1364,7 +1550,7 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() { |
| 1364 | 1550 | Define("__init_array_start", "__init_array_end", Out::InitArray); |
| 1365 | 1551 | Define("__fini_array_start", "__fini_array_end", Out::FiniArray); |
| 1366 | 1552 | |
| 1367 | if (OutputSection *Sec = findSectionInScript(".ARM.exidx")) | |
| 1553 | if (OutputSection *Sec = findSection(".ARM.exidx")) | |
| 1368 | 1554 | Define("__exidx_start", "__exidx_end", Sec); |
| 1369 | 1555 | } |
| 1370 | 1556 | |
| ... | ... | @@ -1378,24 +1564,8 @@ void Writer<ELFT>::addStartStopSymbols(OutputSection *Sec) { |
| 1378 | 1564 | StringRef S = Sec->Name; |
| 1379 | 1565 | if (!isValidCIdentifier(S)) |
| 1380 | 1566 | return; |
| 1381 | addOptionalRegular<ELFT>(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT); | |
| 1382 | addOptionalRegular<ELFT>(Saver.save("__stop_" + S), Sec, -1, STV_DEFAULT); | |
| 1383 | } | |
| 1384 | ||
| 1385 | template <class ELFT> | |
| 1386 | OutputSectionCommand *Writer<ELFT>::findSectionCommand(StringRef Name) { | |
| 1387 | for (BaseCommand *Base : Script->Opt.Commands) | |
| 1388 | if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) | |
| 1389 | if (Cmd->Name == Name) | |
| 1390 | return Cmd; | |
| 1391 | return nullptr; | |
| 1392 | } | |
| 1393 | ||
| 1394 | template <class ELFT> | |
| 1395 | OutputSection *Writer<ELFT>::findSectionInScript(StringRef Name) { | |
| 1396 | if (OutputSectionCommand *Cmd = findSectionCommand(Name)) | |
| 1397 | return Cmd->Sec; | |
| 1398 | return nullptr; | |
| 1567 | addOptionalRegular(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT); | |
| 1568 | addOptionalRegular(Saver.save("__stop_" + S), Sec, -1, STV_DEFAULT); | |
| 1399 | 1569 | } |
| 1400 | 1570 | |
| 1401 | 1571 | static bool needsPtLoad(OutputSection *Sec) { |
| ... | ... | @@ -1424,19 +1594,19 @@ static uint64_t computeFlags(uint64_t Flags) { |
| 1424 | 1594 | |
| 1425 | 1595 | // Decide which program headers to create and which sections to include in each |
| 1426 | 1596 | // one. |
| 1427 | template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() { | |
| 1428 | std::vector<PhdrEntry> Ret; | |
| 1597 | template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() { | |
| 1598 | std::vector<PhdrEntry *> Ret; | |
| 1429 | 1599 | auto AddHdr = [&](unsigned Type, unsigned Flags) -> PhdrEntry * { |
| 1430 | Ret.emplace_back(Type, Flags); | |
| 1431 | return &Ret.back(); | |
| 1600 | Ret.push_back(make<PhdrEntry>(Type, Flags)); | |
| 1601 | return Ret.back(); | |
| 1432 | 1602 | }; |
| 1433 | 1603 | |
| 1434 | 1604 | // The first phdr entry is PT_PHDR which describes the program header itself. |
| 1435 | 1605 | AddHdr(PT_PHDR, PF_R)->add(Out::ProgramHeaders); |
| 1436 | 1606 | |
| 1437 | 1607 | // PT_INTERP must be the second entry if exists. |
| 1438 | if (OutputSection *Sec = findSectionInScript(".interp")) | |
| 1439 | AddHdr(PT_INTERP, Sec->getPhdrFlags())->add(Sec); | |
| 1608 | if (OutputSection *Cmd = findSection(".interp")) | |
| 1609 | AddHdr(PT_INTERP, Cmd->getPhdrFlags())->add(Cmd); | |
| 1440 | 1610 | |
| 1441 | 1611 | // Add the first PT_LOAD segment for regular output sections. |
| 1442 | 1612 | uint64_t Flags = computeFlags(PF_R); |
| ... | ... | @@ -1446,8 +1616,7 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() { |
| 1446 | 1616 | Load->add(Out::ElfHeader); |
| 1447 | 1617 | Load->add(Out::ProgramHeaders); |
| 1448 | 1618 | |
| 1449 | for (OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 1450 | OutputSection *Sec = Cmd->Sec; | |
| 1619 | for (OutputSection *Sec : OutputSections) { | |
| 1451 | 1620 | if (!(Sec->Flags & SHF_ALLOC)) |
| 1452 | 1621 | break; |
| 1453 | 1622 | if (!needsPtLoad(Sec)) |
| ... | ... | @@ -1459,7 +1628,9 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() { |
| 1459 | 1628 | // different flags or is loaded at a discontiguous address using AT linker |
| 1460 | 1629 | // script command. |
| 1461 | 1630 | uint64_t NewFlags = computeFlags(Sec->getPhdrFlags()); |
| 1462 | if (Cmd->LMAExpr || Flags != NewFlags) { | |
| 1631 | if ((Sec->LMAExpr && Load->ASectionHasLMA) || | |
| 1632 | Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) { | |
| 1633 | ||
| 1463 | 1634 | Load = AddHdr(PT_LOAD, NewFlags); |
| 1464 | 1635 | Flags = NewFlags; |
| 1465 | 1636 | } |
| ... | ... | @@ -1468,14 +1639,12 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() { |
| 1468 | 1639 | } |
| 1469 | 1640 | |
| 1470 | 1641 | // Add a TLS segment if any. |
| 1471 | PhdrEntry TlsHdr(PT_TLS, PF_R); | |
| 1472 | for (OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 1473 | OutputSection *Sec = Cmd->Sec; | |
| 1642 | PhdrEntry *TlsHdr = make<PhdrEntry>(PT_TLS, PF_R); | |
| 1643 | for (OutputSection *Sec : OutputSections) | |
| 1474 | 1644 | if (Sec->Flags & SHF_TLS) |
| 1475 | TlsHdr.add(Sec); | |
| 1476 | } | |
| 1477 | if (TlsHdr.First) | |
| 1478 | Ret.push_back(std::move(TlsHdr)); | |
| 1645 | TlsHdr->add(Sec); | |
| 1646 | if (TlsHdr->FirstSec) | |
| 1647 | Ret.push_back(TlsHdr); | |
| 1479 | 1648 | |
| 1480 | 1649 | // Add an entry for .dynamic. |
| 1481 | 1650 | if (InX::DynSymTab) |
| ... | ... | @@ -1484,25 +1653,39 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() { |
| 1484 | 1653 | |
| 1485 | 1654 | // PT_GNU_RELRO includes all sections that should be marked as |
| 1486 | 1655 | // read-only by dynamic linker after proccessing relocations. |
| 1487 | PhdrEntry RelRo(PT_GNU_RELRO, PF_R); | |
| 1488 | for (OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 1489 | OutputSection *Sec = Cmd->Sec; | |
| 1490 | if (needsPtLoad(Sec) && isRelroSection(Sec)) | |
| 1491 | RelRo.add(Sec); | |
| 1656 | // Current dynamic loaders only support one PT_GNU_RELRO PHDR, give | |
| 1657 | // an error message if more than one PT_GNU_RELRO PHDR is required. | |
| 1658 | PhdrEntry *RelRo = make<PhdrEntry>(PT_GNU_RELRO, PF_R); | |
| 1659 | bool InRelroPhdr = false; | |
| 1660 | bool IsRelroFinished = false; | |
| 1661 | for (OutputSection *Sec : OutputSections) { | |
| 1662 | if (!needsPtLoad(Sec)) | |
| 1663 | continue; | |
| 1664 | if (isRelroSection(Sec)) { | |
| 1665 | InRelroPhdr = true; | |
| 1666 | if (!IsRelroFinished) | |
| 1667 | RelRo->add(Sec); | |
| 1668 | else | |
| 1669 | error("section: " + Sec->Name + " is not contiguous with other relro" + | |
| 1670 | " sections"); | |
| 1671 | } else if (InRelroPhdr) { | |
| 1672 | InRelroPhdr = false; | |
| 1673 | IsRelroFinished = true; | |
| 1674 | } | |
| 1492 | 1675 | } |
| 1493 | if (RelRo.First) | |
| 1494 | Ret.push_back(std::move(RelRo)); | |
| 1676 | if (RelRo->FirstSec) | |
| 1677 | Ret.push_back(RelRo); | |
| 1495 | 1678 | |
| 1496 | 1679 | // PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr. |
| 1497 | if (!In<ELFT>::EhFrame->empty() && In<ELFT>::EhFrameHdr && | |
| 1498 | In<ELFT>::EhFrame->getParent() && In<ELFT>::EhFrameHdr->getParent()) | |
| 1499 | AddHdr(PT_GNU_EH_FRAME, In<ELFT>::EhFrameHdr->getParent()->getPhdrFlags()) | |
| 1500 | ->add(In<ELFT>::EhFrameHdr->getParent()); | |
| 1680 | if (!InX::EhFrame->empty() && InX::EhFrameHdr && InX::EhFrame->getParent() && | |
| 1681 | InX::EhFrameHdr->getParent()) | |
| 1682 | AddHdr(PT_GNU_EH_FRAME, InX::EhFrameHdr->getParent()->getPhdrFlags()) | |
| 1683 | ->add(InX::EhFrameHdr->getParent()); | |
| 1501 | 1684 | |
| 1502 | 1685 | // PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes |
| 1503 | 1686 | // the dynamic linker fill the segment with random data. |
| 1504 | if (OutputSection *Sec = findSectionInScript(".openbsd.randomdata")) | |
| 1505 | AddHdr(PT_OPENBSD_RANDOMIZE, Sec->getPhdrFlags())->add(Sec); | |
| 1687 | if (OutputSection *Cmd = findSection(".openbsd.randomdata")) | |
| 1688 | AddHdr(PT_OPENBSD_RANDOMIZE, Cmd->getPhdrFlags())->add(Cmd); | |
| 1506 | 1689 | |
| 1507 | 1690 | // PT_GNU_STACK is a special section to tell the loader to make the |
| 1508 | 1691 | // pages for the stack non-executable. If you really want an executable |
| ... | ... | @@ -1524,10 +1707,9 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() { |
| 1524 | 1707 | |
| 1525 | 1708 | // Create one PT_NOTE per a group of contiguous .note sections. |
| 1526 | 1709 | PhdrEntry *Note = nullptr; |
| 1527 | for (OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 1528 | OutputSection *Sec = Cmd->Sec; | |
| 1710 | for (OutputSection *Sec : OutputSections) { | |
| 1529 | 1711 | if (Sec->Type == SHT_NOTE) { |
| 1530 | if (!Note || Cmd->LMAExpr) | |
| 1712 | if (!Note || Sec->LMAExpr) | |
| 1531 | 1713 | Note = AddHdr(PT_NOTE, PF_R); |
| 1532 | 1714 | Note->add(Sec); |
| 1533 | 1715 | } else { |
| ... | ... | @@ -1538,18 +1720,18 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() { |
| 1538 | 1720 | } |
| 1539 | 1721 | |
| 1540 | 1722 | template <class ELFT> |
| 1541 | void Writer<ELFT>::addPtArmExid(std::vector<PhdrEntry> &Phdrs) { | |
| 1723 | void Writer<ELFT>::addPtArmExid(std::vector<PhdrEntry *> &Phdrs) { | |
| 1542 | 1724 | if (Config->EMachine != EM_ARM) |
| 1543 | 1725 | return; |
| 1544 | auto I = llvm::find_if(OutputSectionCommands, [](OutputSectionCommand *Cmd) { | |
| 1545 | return Cmd->Sec->Type == SHT_ARM_EXIDX; | |
| 1726 | auto I = llvm::find_if(OutputSections, [](OutputSection *Cmd) { | |
| 1727 | return Cmd->Type == SHT_ARM_EXIDX; | |
| 1546 | 1728 | }); |
| 1547 | if (I == OutputSectionCommands.end()) | |
| 1729 | if (I == OutputSections.end()) | |
| 1548 | 1730 | return; |
| 1549 | 1731 | |
| 1550 | 1732 | // PT_ARM_EXIDX is the ARM EHABI equivalent of PT_GNU_EH_FRAME |
| 1551 | PhdrEntry ARMExidx(PT_ARM_EXIDX, PF_R); | |
| 1552 | ARMExidx.add((*I)->Sec); | |
| 1733 | PhdrEntry *ARMExidx = make<PhdrEntry>(PT_ARM_EXIDX, PF_R); | |
| 1734 | ARMExidx->add(*I); | |
| 1553 | 1735 | Phdrs.push_back(ARMExidx); |
| 1554 | 1736 | } |
| 1555 | 1737 | |
| ... | ... | @@ -1557,33 +1739,31 @@ void Writer<ELFT>::addPtArmExid(std::vector<PhdrEntry> &Phdrs) { |
| 1557 | 1739 | // first section after PT_GNU_RELRO have to be page aligned so that the dynamic |
| 1558 | 1740 | // linker can set the permissions. |
| 1559 | 1741 | template <class ELFT> void Writer<ELFT>::fixSectionAlignments() { |
| 1560 | auto PageAlign = [](OutputSection *Sec) { | |
| 1561 | OutputSectionCommand *Cmd = Script->getCmd(Sec); | |
| 1742 | auto PageAlign = [](OutputSection *Cmd) { | |
| 1562 | 1743 | if (Cmd && !Cmd->AddrExpr) |
| 1563 | 1744 | Cmd->AddrExpr = [=] { |
| 1564 | 1745 | return alignTo(Script->getDot(), Config->MaxPageSize); |
| 1565 | 1746 | }; |
| 1566 | 1747 | }; |
| 1567 | 1748 | |
| 1568 | for (const PhdrEntry &P : Phdrs) | |
| 1569 | if (P.p_type == PT_LOAD && P.First) | |
| 1570 | PageAlign(P.First); | |
| 1749 | for (const PhdrEntry *P : Phdrs) | |
| 1750 | if (P->p_type == PT_LOAD && P->FirstSec) | |
| 1751 | PageAlign(P->FirstSec); | |
| 1571 | 1752 | |
| 1572 | for (const PhdrEntry &P : Phdrs) { | |
| 1573 | if (P.p_type != PT_GNU_RELRO) | |
| 1753 | for (const PhdrEntry *P : Phdrs) { | |
| 1754 | if (P->p_type != PT_GNU_RELRO) | |
| 1574 | 1755 | continue; |
| 1575 | if (P.First) | |
| 1576 | PageAlign(P.First); | |
| 1756 | if (P->FirstSec) | |
| 1757 | PageAlign(P->FirstSec); | |
| 1577 | 1758 | // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we |
| 1578 | 1759 | // have to align it to a page. |
| 1579 | auto End = OutputSectionCommands.end(); | |
| 1580 | auto I = | |
| 1581 | std::find(OutputSectionCommands.begin(), End, Script->getCmd(P.Last)); | |
| 1760 | auto End = OutputSections.end(); | |
| 1761 | auto I = std::find(OutputSections.begin(), End, P->LastSec); | |
| 1582 | 1762 | if (I == End || (I + 1) == End) |
| 1583 | 1763 | continue; |
| 1584 | OutputSection *Sec = (*(I + 1))->Sec; | |
| 1585 | if (needsPtLoad(Sec)) | |
| 1586 | PageAlign(Sec); | |
| 1764 | OutputSection *Cmd = (*(I + 1)); | |
| 1765 | if (needsPtLoad(Cmd)) | |
| 1766 | PageAlign(Cmd); | |
| 1587 | 1767 | } |
| 1588 | 1768 | } |
| 1589 | 1769 | |
| ... | ... | @@ -1591,40 +1771,45 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() { |
| 1591 | 1771 | // its new file offset. The file offset must be the same with its |
| 1592 | 1772 | // virtual address (modulo the page size) so that the loader can load |
| 1593 | 1773 | // executables without any address adjustment. |
| 1594 | static uint64_t getFileAlignment(uint64_t Off, OutputSection *Sec) { | |
| 1595 | OutputSection *First = Sec->FirstInPtLoad; | |
| 1596 | // If the section is not in a PT_LOAD, we just have to align it. | |
| 1597 | if (!First) | |
| 1598 | return alignTo(Off, Sec->Alignment); | |
| 1599 | ||
| 1774 | static uint64_t getFileAlignment(uint64_t Off, OutputSection *Cmd) { | |
| 1775 | OutputSection *First = Cmd->PtLoad ? Cmd->PtLoad->FirstSec : nullptr; | |
| 1600 | 1776 | // The first section in a PT_LOAD has to have congruent offset and address |
| 1601 | 1777 | // module the page size. |
| 1602 | if (Sec == First) | |
| 1603 | return alignTo(Off, Config->MaxPageSize, Sec->Addr); | |
| 1778 | if (Cmd == First) | |
| 1779 | return alignTo(Off, std::max<uint64_t>(Cmd->Alignment, Config->MaxPageSize), | |
| 1780 | Cmd->Addr); | |
| 1781 | ||
| 1782 | // For SHT_NOBITS we don't want the alignment of the section to impact the | |
| 1783 | // offset of the sections that follow. Since nothing seems to care about the | |
| 1784 | // sh_offset of the SHT_NOBITS section itself, just ignore it. | |
| 1785 | if (Cmd->Type == SHT_NOBITS) | |
| 1786 | return Off; | |
| 1787 | ||
| 1788 | // If the section is not in a PT_LOAD, we just have to align it. | |
| 1789 | if (!Cmd->PtLoad) | |
| 1790 | return alignTo(Off, Cmd->Alignment); | |
| 1604 | 1791 | |
| 1605 | 1792 | // If two sections share the same PT_LOAD the file offset is calculated |
| 1606 | 1793 | // using this formula: Off2 = Off1 + (VA2 - VA1). |
| 1607 | return First->Offset + Sec->Addr - First->Addr; | |
| 1794 | return First->Offset + Cmd->Addr - First->Addr; | |
| 1608 | 1795 | } |
| 1609 | 1796 | |
| 1610 | static uint64_t setOffset(OutputSection *Sec, uint64_t Off) { | |
| 1611 | if (Sec->Type == SHT_NOBITS) { | |
| 1612 | Sec->Offset = Off; | |
| 1797 | static uint64_t setOffset(OutputSection *Cmd, uint64_t Off) { | |
| 1798 | Off = getFileAlignment(Off, Cmd); | |
| 1799 | Cmd->Offset = Off; | |
| 1800 | ||
| 1801 | // For SHT_NOBITS we should not count the size. | |
| 1802 | if (Cmd->Type == SHT_NOBITS) | |
| 1613 | 1803 | return Off; |
| 1614 | } | |
| 1615 | 1804 | |
| 1616 | Off = getFileAlignment(Off, Sec); | |
| 1617 | Sec->Offset = Off; | |
| 1618 | return Off + Sec->Size; | |
| 1805 | return Off + Cmd->Size; | |
| 1619 | 1806 | } |
| 1620 | 1807 | |
| 1621 | 1808 | template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() { |
| 1622 | 1809 | uint64_t Off = 0; |
| 1623 | for (OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 1624 | OutputSection *Sec = Cmd->Sec; | |
| 1810 | for (OutputSection *Sec : OutputSections) | |
| 1625 | 1811 | if (Sec->Flags & SHF_ALLOC) |
| 1626 | 1812 | Off = setOffset(Sec, Off); |
| 1627 | } | |
| 1628 | 1813 | FileSize = alignTo(Off, Config->Wordsize); |
| 1629 | 1814 | } |
| 1630 | 1815 | |
| ... | ... | @@ -1634,46 +1819,58 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() { |
| 1634 | 1819 | Off = setOffset(Out::ElfHeader, Off); |
| 1635 | 1820 | Off = setOffset(Out::ProgramHeaders, Off); |
| 1636 | 1821 | |
| 1637 | for (OutputSectionCommand *Cmd : OutputSectionCommands) | |
| 1638 | Off = setOffset(Cmd->Sec, Off); | |
| 1822 | PhdrEntry *LastRX = nullptr; | |
| 1823 | for (PhdrEntry *P : Phdrs) | |
| 1824 | if (P->p_type == PT_LOAD && (P->p_flags & PF_X)) | |
| 1825 | LastRX = P; | |
| 1826 | ||
| 1827 | for (OutputSection *Sec : OutputSections) { | |
| 1828 | Off = setOffset(Sec, Off); | |
| 1829 | if (Script->HasSectionsCommand) | |
| 1830 | continue; | |
| 1831 | // If this is a last section of the last executable segment and that | |
| 1832 | // segment is the last loadable segment, align the offset of the | |
| 1833 | // following section to avoid loading non-segments parts of the file. | |
| 1834 | if (LastRX && LastRX->LastSec == Sec) | |
| 1835 | Off = alignTo(Off, Target->PageSize); | |
| 1836 | } | |
| 1639 | 1837 | |
| 1640 | 1838 | SectionHeaderOff = alignTo(Off, Config->Wordsize); |
| 1641 | FileSize = | |
| 1642 | SectionHeaderOff + (OutputSectionCommands.size() + 1) * sizeof(Elf_Shdr); | |
| 1839 | FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr); | |
| 1643 | 1840 | } |
| 1644 | 1841 | |
| 1645 | 1842 | // Finalize the program headers. We call this function after we assign |
| 1646 | 1843 | // file offsets and VAs to all sections. |
| 1647 | 1844 | template <class ELFT> void Writer<ELFT>::setPhdrs() { |
| 1648 | for (PhdrEntry &P : Phdrs) { | |
| 1649 | OutputSection *First = P.First; | |
| 1650 | OutputSection *Last = P.Last; | |
| 1845 | for (PhdrEntry *P : Phdrs) { | |
| 1846 | OutputSection *First = P->FirstSec; | |
| 1847 | OutputSection *Last = P->LastSec; | |
| 1651 | 1848 | if (First) { |
| 1652 | P.p_filesz = Last->Offset - First->Offset; | |
| 1849 | P->p_filesz = Last->Offset - First->Offset; | |
| 1653 | 1850 | if (Last->Type != SHT_NOBITS) |
| 1654 | P.p_filesz += Last->Size; | |
| 1655 | P.p_memsz = Last->Addr + Last->Size - First->Addr; | |
| 1656 | P.p_offset = First->Offset; | |
| 1657 | P.p_vaddr = First->Addr; | |
| 1658 | if (!P.HasLMA) | |
| 1659 | P.p_paddr = First->getLMA(); | |
| 1851 | P->p_filesz += Last->Size; | |
| 1852 | P->p_memsz = Last->Addr + Last->Size - First->Addr; | |
| 1853 | P->p_offset = First->Offset; | |
| 1854 | P->p_vaddr = First->Addr; | |
| 1855 | if (!P->HasLMA) | |
| 1856 | P->p_paddr = First->getLMA(); | |
| 1660 | 1857 | } |
| 1661 | if (P.p_type == PT_LOAD) | |
| 1662 | P.p_align = Config->MaxPageSize; | |
| 1663 | else if (P.p_type == PT_GNU_RELRO) { | |
| 1664 | P.p_align = 1; | |
| 1858 | if (P->p_type == PT_LOAD) | |
| 1859 | P->p_align = std::max<uint64_t>(P->p_align, Config->MaxPageSize); | |
| 1860 | else if (P->p_type == PT_GNU_RELRO) { | |
| 1861 | P->p_align = 1; | |
| 1665 | 1862 | // The glibc dynamic loader rounds the size down, so we need to round up |
| 1666 | 1863 | // to protect the last page. This is a no-op on FreeBSD which always |
| 1667 | 1864 | // rounds up. |
| 1668 | P.p_memsz = alignTo(P.p_memsz, Target->PageSize); | |
| 1865 | P->p_memsz = alignTo(P->p_memsz, Target->PageSize); | |
| 1669 | 1866 | } |
| 1670 | 1867 | |
| 1671 | 1868 | // The TLS pointer goes after PT_TLS. At least glibc will align it, |
| 1672 | 1869 | // so round up the size to make sure the offsets are correct. |
| 1673 | if (P.p_type == PT_TLS) { | |
| 1674 | Out::TlsPhdr = &P; | |
| 1675 | if (P.p_memsz) | |
| 1676 | P.p_memsz = alignTo(P.p_memsz, P.p_align); | |
| 1870 | if (P->p_type == PT_TLS) { | |
| 1871 | Out::TlsPhdr = P; | |
| 1872 | if (P->p_memsz) | |
| 1873 | P->p_memsz = alignTo(P->p_memsz, P->p_align); | |
| 1677 | 1874 | } |
| 1678 | 1875 | } |
| 1679 | 1876 | } |
| ... | ... | @@ -1682,27 +1879,29 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() { |
| 1682 | 1879 | // |
| 1683 | 1880 | // 1. the '-e' entry command-line option; |
| 1684 | 1881 | // 2. the ENTRY(symbol) command in a linker control script; |
| 1685 | // 3. the value of the symbol start, if present; | |
| 1686 | // 4. the address of the first byte of the .text section, if present; | |
| 1687 | // 5. the address 0. | |
| 1882 | // 3. the value of the symbol _start, if present; | |
| 1883 | // 4. the number represented by the entry symbol, if it is a number; | |
| 1884 | // 5. the address of the first byte of the .text section, if present; | |
| 1885 | // 6. the address 0. | |
| 1688 | 1886 | template <class ELFT> uint64_t Writer<ELFT>::getEntryAddr() { |
| 1689 | // Case 1, 2 or 3. As a special case, if the symbol is actually | |
| 1690 | // a number, we'll use that number as an address. | |
| 1691 | if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Entry)) | |
| 1887 | // Case 1, 2 or 3 | |
| 1888 | if (Symbol *B = Symtab->find(Config->Entry)) | |
| 1692 | 1889 | return B->getVA(); |
| 1890 | ||
| 1891 | // Case 4 | |
| 1693 | 1892 | uint64_t Addr; |
| 1694 | 1893 | if (to_integer(Config->Entry, Addr)) |
| 1695 | 1894 | return Addr; |
| 1696 | 1895 | |
| 1697 | // Case 4 | |
| 1698 | if (OutputSection *Sec = findSectionInScript(".text")) { | |
| 1896 | // Case 5 | |
| 1897 | if (OutputSection *Sec = findSection(".text")) { | |
| 1699 | 1898 | if (Config->WarnMissingEntry) |
| 1700 | 1899 | warn("cannot find entry symbol " + Config->Entry + "; defaulting to 0x" + |
| 1701 | 1900 | utohexstr(Sec->Addr)); |
| 1702 | 1901 | return Sec->Addr; |
| 1703 | 1902 | } |
| 1704 | 1903 | |
| 1705 | // Case 5 | |
| 1904 | // Case 6 | |
| 1706 | 1905 | if (Config->WarnMissingEntry) |
| 1707 | 1906 | warn("cannot find entry symbol " + Config->Entry + |
| 1708 | 1907 | "; not setting start address"); |
| ... | ... | @@ -1717,64 +1916,6 @@ static uint16_t getELFType() { |
| 1717 | 1916 | return ET_EXEC; |
| 1718 | 1917 | } |
| 1719 | 1918 | |
| 1720 | // This function is called after we have assigned address and size | |
| 1721 | // to each section. This function fixes some predefined | |
| 1722 | // symbol values that depend on section address and size. | |
| 1723 | template <class ELFT> void Writer<ELFT>::fixPredefinedSymbols() { | |
| 1724 | // _etext is the first location after the last read-only loadable segment. | |
| 1725 | // _edata is the first location after the last read-write loadable segment. | |
| 1726 | // _end is the first location after the uninitialized data region. | |
| 1727 | PhdrEntry *Last = nullptr; | |
| 1728 | PhdrEntry *LastRO = nullptr; | |
| 1729 | PhdrEntry *LastRW = nullptr; | |
| 1730 | for (PhdrEntry &P : Phdrs) { | |
| 1731 | if (P.p_type != PT_LOAD) | |
| 1732 | continue; | |
| 1733 | Last = &P; | |
| 1734 | if (P.p_flags & PF_W) | |
| 1735 | LastRW = &P; | |
| 1736 | else | |
| 1737 | LastRO = &P; | |
| 1738 | } | |
| 1739 | ||
| 1740 | auto Set = [](DefinedRegular *S, OutputSection *Sec, uint64_t Value) { | |
| 1741 | if (S) { | |
| 1742 | S->Section = Sec; | |
| 1743 | S->Value = Value; | |
| 1744 | } | |
| 1745 | }; | |
| 1746 | ||
| 1747 | if (Last) { | |
| 1748 | Set(ElfSym::End1, Last->First, Last->p_memsz); | |
| 1749 | Set(ElfSym::End2, Last->First, Last->p_memsz); | |
| 1750 | } | |
| 1751 | if (LastRO) { | |
| 1752 | Set(ElfSym::Etext1, LastRO->First, LastRO->p_filesz); | |
| 1753 | Set(ElfSym::Etext2, LastRO->First, LastRO->p_filesz); | |
| 1754 | } | |
| 1755 | if (LastRW) { | |
| 1756 | Set(ElfSym::Edata1, LastRW->First, LastRW->p_filesz); | |
| 1757 | Set(ElfSym::Edata2, LastRW->First, LastRW->p_filesz); | |
| 1758 | } | |
| 1759 | ||
| 1760 | if (ElfSym::Bss) | |
| 1761 | ElfSym::Bss->Section = findSectionInScript(".bss"); | |
| 1762 | ||
| 1763 | // Setup MIPS _gp_disp/__gnu_local_gp symbols which should | |
| 1764 | // be equal to the _gp symbol's value. | |
| 1765 | if (Config->EMachine == EM_MIPS && !ElfSym::MipsGp->Value) { | |
| 1766 | // Find GP-relative section with the lowest address | |
| 1767 | // and use this address to calculate default _gp value. | |
| 1768 | for (const OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 1769 | OutputSection *OS = Cmd->Sec; | |
| 1770 | if (OS->Flags & SHF_MIPS_GPREL) { | |
| 1771 | ElfSym::MipsGp->Value = OS->Addr + 0x7ff0; | |
| 1772 | break; | |
| 1773 | } | |
| 1774 | } | |
| 1775 | } | |
| 1776 | } | |
| 1777 | ||
| 1778 | 1919 | template <class ELFT> void Writer<ELFT>::writeHeader() { |
| 1779 | 1920 | uint8_t *Buf = Buffer->getBufferStart(); |
| 1780 | 1921 | memcpy(Buf, "\177ELF", 4); |
| ... | ... | @@ -1790,20 +1931,13 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { |
| 1790 | 1931 | EHdr->e_version = EV_CURRENT; |
| 1791 | 1932 | EHdr->e_entry = getEntryAddr(); |
| 1792 | 1933 | EHdr->e_shoff = SectionHeaderOff; |
| 1934 | EHdr->e_flags = Config->EFlags; | |
| 1793 | 1935 | EHdr->e_ehsize = sizeof(Elf_Ehdr); |
| 1794 | 1936 | EHdr->e_phnum = Phdrs.size(); |
| 1795 | 1937 | EHdr->e_shentsize = sizeof(Elf_Shdr); |
| 1796 | EHdr->e_shnum = OutputSectionCommands.size() + 1; | |
| 1938 | EHdr->e_shnum = OutputSections.size() + 1; | |
| 1797 | 1939 | EHdr->e_shstrndx = InX::ShStrTab->getParent()->SectionIndex; |
| 1798 | 1940 | |
| 1799 | if (Config->EMachine == EM_ARM) | |
| 1800 | // We don't currently use any features incompatible with EF_ARM_EABI_VER5, | |
| 1801 | // but we don't have any firm guarantees of conformance. Linux AArch64 | |
| 1802 | // kernels (as of 2016) require an EABI version to be set. | |
| 1803 | EHdr->e_flags = EF_ARM_EABI_VER5; | |
| 1804 | else if (Config->EMachine == EM_MIPS) | |
| 1805 | EHdr->e_flags = getMipsEFlags<ELFT>(); | |
| 1806 | ||
| 1807 | 1941 | if (!Config->Relocatable) { |
| 1808 | 1942 | EHdr->e_phoff = sizeof(Elf_Ehdr); |
| 1809 | 1943 | EHdr->e_phentsize = sizeof(Elf_Phdr); |
| ... | ... | @@ -1811,22 +1945,22 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { |
| 1811 | 1945 | |
| 1812 | 1946 | // Write the program header table. |
| 1813 | 1947 | auto *HBuf = reinterpret_cast<Elf_Phdr *>(Buf + EHdr->e_phoff); |
| 1814 | for (PhdrEntry &P : Phdrs) { | |
| 1815 | HBuf->p_type = P.p_type; | |
| 1816 | HBuf->p_flags = P.p_flags; | |
| 1817 | HBuf->p_offset = P.p_offset; | |
| 1818 | HBuf->p_vaddr = P.p_vaddr; | |
| 1819 | HBuf->p_paddr = P.p_paddr; | |
| 1820 | HBuf->p_filesz = P.p_filesz; | |
| 1821 | HBuf->p_memsz = P.p_memsz; | |
| 1822 | HBuf->p_align = P.p_align; | |
| 1948 | for (PhdrEntry *P : Phdrs) { | |
| 1949 | HBuf->p_type = P->p_type; | |
| 1950 | HBuf->p_flags = P->p_flags; | |
| 1951 | HBuf->p_offset = P->p_offset; | |
| 1952 | HBuf->p_vaddr = P->p_vaddr; | |
| 1953 | HBuf->p_paddr = P->p_paddr; | |
| 1954 | HBuf->p_filesz = P->p_filesz; | |
| 1955 | HBuf->p_memsz = P->p_memsz; | |
| 1956 | HBuf->p_align = P->p_align; | |
| 1823 | 1957 | ++HBuf; |
| 1824 | 1958 | } |
| 1825 | 1959 | |
| 1826 | 1960 | // Write the section header table. Note that the first table entry is null. |
| 1827 | 1961 | auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff); |
| 1828 | for (OutputSectionCommand *Cmd : OutputSectionCommands) | |
| 1829 | Cmd->Sec->writeHeaderTo<ELFT>(++SHdrs); | |
| 1962 | for (OutputSection *Sec : OutputSections) | |
| 1963 | Sec->writeHeaderTo<ELFT>(++SHdrs); | |
| 1830 | 1964 | } |
| 1831 | 1965 | |
| 1832 | 1966 | // Open a result file. |
| ... | ... | @@ -1837,23 +1971,58 @@ template <class ELFT> void Writer<ELFT>::openFile() { |
| 1837 | 1971 | } |
| 1838 | 1972 | |
| 1839 | 1973 | unlinkAsync(Config->OutputFile); |
| 1840 | ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr = | |
| 1841 | FileOutputBuffer::create(Config->OutputFile, FileSize, | |
| 1842 | FileOutputBuffer::F_executable); | |
| 1974 | unsigned Flags = 0; | |
| 1975 | if (!Config->Relocatable) | |
| 1976 | Flags = FileOutputBuffer::F_executable; | |
| 1977 | Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = | |
| 1978 | FileOutputBuffer::create(Config->OutputFile, FileSize, Flags); | |
| 1843 | 1979 | |
| 1844 | if (auto EC = BufferOrErr.getError()) | |
| 1845 | error("failed to open " + Config->OutputFile + ": " + EC.message()); | |
| 1980 | if (!BufferOrErr) | |
| 1981 | error("failed to open " + Config->OutputFile + ": " + | |
| 1982 | llvm::toString(BufferOrErr.takeError())); | |
| 1846 | 1983 | else |
| 1847 | 1984 | Buffer = std::move(*BufferOrErr); |
| 1848 | 1985 | } |
| 1849 | 1986 | |
| 1850 | 1987 | template <class ELFT> void Writer<ELFT>::writeSectionsBinary() { |
| 1851 | 1988 | uint8_t *Buf = Buffer->getBufferStart(); |
| 1852 | for (OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 1853 | OutputSection *Sec = Cmd->Sec; | |
| 1989 | for (OutputSection *Sec : OutputSections) | |
| 1854 | 1990 | if (Sec->Flags & SHF_ALLOC) |
| 1855 | Cmd->writeTo<ELFT>(Buf + Sec->Offset); | |
| 1856 | } | |
| 1991 | Sec->writeTo<ELFT>(Buf + Sec->Offset); | |
| 1992 | } | |
| 1993 | ||
| 1994 | static void fillTrap(uint8_t *I, uint8_t *End) { | |
| 1995 | for (; I + 4 <= End; I += 4) | |
| 1996 | memcpy(I, &Target->TrapInstr, 4); | |
| 1997 | } | |
| 1998 | ||
| 1999 | // Fill the last page of executable segments with trap instructions | |
| 2000 | // instead of leaving them as zero. Even though it is not required by any | |
| 2001 | // standard, it is in general a good thing to do for security reasons. | |
| 2002 | // | |
| 2003 | // We'll leave other pages in segments as-is because the rest will be | |
| 2004 | // overwritten by output sections. | |
| 2005 | template <class ELFT> void Writer<ELFT>::writeTrapInstr() { | |
| 2006 | if (Script->HasSectionsCommand) | |
| 2007 | return; | |
| 2008 | ||
| 2009 | // Fill the last page. | |
| 2010 | uint8_t *Buf = Buffer->getBufferStart(); | |
| 2011 | for (PhdrEntry *P : Phdrs) | |
| 2012 | if (P->p_type == PT_LOAD && (P->p_flags & PF_X)) | |
| 2013 | fillTrap(Buf + alignDown(P->p_offset + P->p_filesz, Target->PageSize), | |
| 2014 | Buf + alignTo(P->p_offset + P->p_filesz, Target->PageSize)); | |
| 2015 | ||
| 2016 | // Round up the file size of the last segment to the page boundary iff it is | |
| 2017 | // an executable segment to ensure that other tools don't accidentally | |
| 2018 | // trim the instruction padding (e.g. when stripping the file). | |
| 2019 | PhdrEntry *Last = nullptr; | |
| 2020 | for (PhdrEntry *P : Phdrs) | |
| 2021 | if (P->p_type == PT_LOAD) | |
| 2022 | Last = P; | |
| 2023 | ||
| 2024 | if (Last && (Last->p_flags & PF_X)) | |
| 2025 | Last->p_memsz = Last->p_filesz = alignTo(Last->p_filesz, Target->PageSize); | |
| 1857 | 2026 | } |
| 1858 | 2027 | |
| 1859 | 2028 | // Write section contents to a mmap'ed file. |
| ... | ... | @@ -1862,39 +2031,32 @@ template <class ELFT> void Writer<ELFT>::writeSections() { |
| 1862 | 2031 | |
| 1863 | 2032 | // PPC64 needs to process relocations in the .opd section |
| 1864 | 2033 | // before processing relocations in code-containing sections. |
| 1865 | if (auto *OpdCmd = findSectionCommand(".opd")) { | |
| 1866 | Out::Opd = OpdCmd->Sec; | |
| 2034 | if (auto *OpdCmd = findSection(".opd")) { | |
| 2035 | Out::Opd = OpdCmd; | |
| 1867 | 2036 | Out::OpdBuf = Buf + Out::Opd->Offset; |
| 1868 | 2037 | OpdCmd->template writeTo<ELFT>(Buf + Out::Opd->Offset); |
| 1869 | 2038 | } |
| 1870 | 2039 | |
| 1871 | OutputSection *EhFrameHdr = | |
| 1872 | (In<ELFT>::EhFrameHdr && !In<ELFT>::EhFrameHdr->empty()) | |
| 1873 | ? In<ELFT>::EhFrameHdr->getParent() | |
| 1874 | : nullptr; | |
| 2040 | OutputSection *EhFrameHdr = nullptr; | |
| 2041 | if (InX::EhFrameHdr && !InX::EhFrameHdr->empty()) | |
| 2042 | EhFrameHdr = InX::EhFrameHdr->getParent(); | |
| 1875 | 2043 | |
| 1876 | 2044 | // In -r or -emit-relocs mode, write the relocation sections first as in |
| 1877 | 2045 | // ELf_Rel targets we might find out that we need to modify the relocated |
| 1878 | 2046 | // section while doing it. |
| 1879 | for (OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 1880 | OutputSection *Sec = Cmd->Sec; | |
| 2047 | for (OutputSection *Sec : OutputSections) | |
| 1881 | 2048 | if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA) |
| 1882 | Cmd->writeTo<ELFT>(Buf + Sec->Offset); | |
| 1883 | } | |
| 2049 | Sec->writeTo<ELFT>(Buf + Sec->Offset); | |
| 1884 | 2050 | |
| 1885 | for (OutputSectionCommand *Cmd : OutputSectionCommands) { | |
| 1886 | OutputSection *Sec = Cmd->Sec; | |
| 2051 | for (OutputSection *Sec : OutputSections) | |
| 1887 | 2052 | if (Sec != Out::Opd && Sec != EhFrameHdr && Sec->Type != SHT_REL && |
| 1888 | 2053 | Sec->Type != SHT_RELA) |
| 1889 | Cmd->writeTo<ELFT>(Buf + Sec->Offset); | |
| 1890 | } | |
| 2054 | Sec->writeTo<ELFT>(Buf + Sec->Offset); | |
| 1891 | 2055 | |
| 1892 | 2056 | // The .eh_frame_hdr depends on .eh_frame section contents, therefore |
| 1893 | 2057 | // it should be written after .eh_frame is written. |
| 1894 | if (EhFrameHdr) { | |
| 1895 | OutputSectionCommand *Cmd = Script->getCmd(EhFrameHdr); | |
| 1896 | Cmd->writeTo<ELFT>(Buf + EhFrameHdr->Offset); | |
| 1897 | } | |
| 2058 | if (EhFrameHdr) | |
| 2059 | EhFrameHdr->writeTo<ELFT>(Buf + EhFrameHdr->Offset); | |
| 1898 | 2060 | } |
| 1899 | 2061 | |
| 1900 | 2062 | template <class ELFT> void Writer<ELFT>::writeBuildId() { |
deps/lld/ELF/Writer.h+16-7| ... | ... | @@ -20,11 +20,10 @@ namespace elf { |
| 20 | 20 | class InputFile; |
| 21 | 21 | class OutputSection; |
| 22 | 22 | class InputSectionBase; |
| 23 | template <class ELFT> class ObjectFile; | |
| 24 | template <class ELFT> class SymbolTable; | |
| 23 | template <class ELFT> class ObjFile; | |
| 24 | class SymbolTable; | |
| 25 | 25 | template <class ELFT> void writeResult(); |
| 26 | 26 | template <class ELFT> void markLive(); |
| 27 | bool isRelroSection(const OutputSection *Sec); | |
| 28 | 27 | |
| 29 | 28 | // This describes a program header entry. |
| 30 | 29 | // Each contains type, access flags and range of output sections that will be |
| ... | ... | @@ -42,19 +41,29 @@ struct PhdrEntry { |
| 42 | 41 | uint32_t p_type = 0; |
| 43 | 42 | uint32_t p_flags = 0; |
| 44 | 43 | |
| 45 | OutputSection *First = nullptr; | |
| 46 | OutputSection *Last = nullptr; | |
| 44 | OutputSection *FirstSec = nullptr; | |
| 45 | OutputSection *LastSec = nullptr; | |
| 47 | 46 | bool HasLMA = false; |
| 47 | ||
| 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; | |
| 48 | 54 | }; |
| 49 | 55 | |
| 50 | llvm::StringRef getOutputSectionName(llvm::StringRef Name); | |
| 56 | void addReservedSymbols(); | |
| 57 | llvm::StringRef getOutputSectionName(InputSectionBase *S); | |
| 51 | 58 | |
| 52 | template <class ELFT> uint32_t getMipsEFlags(); | |
| 59 | template <class ELFT> uint32_t calcMipsEFlags(); | |
| 53 | 60 | |
| 54 | 61 | uint8_t getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag, |
| 55 | 62 | llvm::StringRef FileName); |
| 56 | 63 | |
| 57 | 64 | bool isMipsN32Abi(const InputFile *F); |
| 65 | bool isMicroMips(); | |
| 66 | bool isMipsR6(); | |
| 58 | 67 | } // namespace elf |
| 59 | 68 | } // namespace lld |
| 60 | 69 |
deps/lld/MinGW/CMakeLists.txt created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | set(LLVM_TARGET_DEFINITIONS Options.td) | |
| 2 | tablegen(LLVM Options.inc -gen-opt-parser-defs) | |
| 3 | add_public_tablegen_target(MinGWOptionsTableGen) | |
| 4 | ||
| 5 | if(NOT LLD_BUILT_STANDALONE) | |
| 6 | set(tablegen_deps intrinsics_gen) | |
| 7 | endif() | |
| 8 | ||
| 9 | add_lld_library(lldMinGW | |
| 10 | Driver.cpp | |
| 11 | ||
| 12 | LINK_COMPONENTS | |
| 13 | Option | |
| 14 | Support | |
| 15 | ||
| 16 | LINK_LIBS | |
| 17 | lldCOFF | |
| 18 | lldCommon | |
| 19 | ||
| 20 | DEPENDS | |
| 21 | MinGWOptionsTableGen | |
| 22 | ${tablegen_deps} | |
| 23 | ) |
deps/lld/MinGW/Driver.cpp created+247| ... | ... | @@ -0,0 +1,247 @@ |
| 1 | //===- MinGW/Driver.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 | /// GNU ld style linker driver for COFF currently supporting mingw-w64. | |
| 11 | /// | |
| 12 | //===----------------------------------------------------------------------===// | |
| 13 | ||
| 14 | #include "lld/Common/Driver.h" | |
| 15 | #include "lld/Common/ErrorHandler.h" | |
| 16 | #include "llvm/ADT/ArrayRef.h" | |
| 17 | #include "llvm/ADT/Optional.h" | |
| 18 | #include "llvm/ADT/StringExtras.h" | |
| 19 | #include "llvm/ADT/StringRef.h" | |
| 20 | #include "llvm/Option/Arg.h" | |
| 21 | #include "llvm/Option/ArgList.h" | |
| 22 | #include "llvm/Option/Option.h" | |
| 23 | #include "llvm/Support/CommandLine.h" | |
| 24 | #include "llvm/Support/FileSystem.h" | |
| 25 | #include "llvm/Support/Path.h" | |
| 26 | ||
| 27 | #if !defined(_MSC_VER) && !defined(__MINGW32__) | |
| 28 | #include <unistd.h> | |
| 29 | #endif | |
| 30 | ||
| 31 | using namespace lld; | |
| 32 | using namespace llvm; | |
| 33 | ||
| 34 | // Create OptTable | |
| 35 | enum { | |
| 36 | OPT_INVALID = 0, | |
| 37 | #define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID, | |
| 38 | #include "Options.inc" | |
| 39 | #undef OPTION | |
| 40 | }; | |
| 41 | ||
| 42 | // Create prefix string literals used in Options.td | |
| 43 | #define PREFIX(NAME, VALUE) static const char *const NAME[] = VALUE; | |
| 44 | #include "Options.inc" | |
| 45 | #undef PREFIX | |
| 46 | ||
| 47 | // Create table mapping all options defined in Options.td | |
| 48 | static const opt::OptTable::Info InfoTable[] = { | |
| 49 | #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ | |
| 50 | {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \ | |
| 51 | X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12}, | |
| 52 | #include "Options.inc" | |
| 53 | #undef OPTION | |
| 54 | }; | |
| 55 | ||
| 56 | namespace { | |
| 57 | class MinGWOptTable : public opt::OptTable { | |
| 58 | public: | |
| 59 | MinGWOptTable() : OptTable(InfoTable, false) {} | |
| 60 | opt::InputArgList parse(ArrayRef<const char *> Argv); | |
| 61 | }; | |
| 62 | } // namespace | |
| 63 | ||
| 64 | opt::InputArgList MinGWOptTable::parse(ArrayRef<const char *> Argv) { | |
| 65 | unsigned MissingIndex; | |
| 66 | unsigned MissingCount; | |
| 67 | ||
| 68 | SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size()); | |
| 69 | opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount); | |
| 70 | ||
| 71 | if (MissingCount) | |
| 72 | fatal(StringRef(Args.getArgString(MissingIndex)) + ": missing argument"); | |
| 73 | for (auto *Arg : Args.filtered(OPT_UNKNOWN)) | |
| 74 | fatal("unknown argument: " + Arg->getSpelling()); | |
| 75 | if (!Args.hasArg(OPT_INPUT) && !Args.hasArg(OPT_l)) | |
| 76 | fatal("no input files"); | |
| 77 | return Args; | |
| 78 | } | |
| 79 | ||
| 80 | // Find a file by concatenating given paths. | |
| 81 | static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) { | |
| 82 | SmallString<128> S; | |
| 83 | sys::path::append(S, Path1, Path2); | |
| 84 | if (sys::fs::exists(S)) | |
| 85 | return S.str().str(); | |
| 86 | return None; | |
| 87 | } | |
| 88 | ||
| 89 | // This is for -lfoo. We'll look for libfoo.dll.a or libfoo.a from search paths. | |
| 90 | static std::string | |
| 91 | searchLibrary(StringRef Name, ArrayRef<StringRef> SearchPaths, bool BStatic) { | |
| 92 | if (Name.startswith(":")) { | |
| 93 | for (StringRef Dir : SearchPaths) | |
| 94 | if (Optional<std::string> S = findFile(Dir, Name.substr(1))) | |
| 95 | return *S; | |
| 96 | fatal("unable to find library -l" + Name); | |
| 97 | } | |
| 98 | ||
| 99 | for (StringRef Dir : SearchPaths) { | |
| 100 | if (!BStatic) | |
| 101 | if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".dll.a")) | |
| 102 | return *S; | |
| 103 | if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".a")) | |
| 104 | return *S; | |
| 105 | } | |
| 106 | fatal("unable to find library -l" + Name); | |
| 107 | } | |
| 108 | ||
| 109 | // Convert Unix-ish command line arguments to Windows-ish ones and | |
| 110 | // then call coff::link. | |
| 111 | bool mingw::link(ArrayRef<const char *> ArgsArr, raw_ostream &Diag) { | |
| 112 | MinGWOptTable Parser; | |
| 113 | opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); | |
| 114 | ||
| 115 | std::vector<std::string> LinkArgs; | |
| 116 | auto Add = [&](const Twine &S) { LinkArgs.push_back(S.str()); }; | |
| 117 | ||
| 118 | Add("lld-link"); | |
| 119 | Add("-lldmingw"); | |
| 120 | ||
| 121 | if (auto *A = Args.getLastArg(OPT_entry)) { | |
| 122 | StringRef S = A->getValue(); | |
| 123 | if (Args.getLastArgValue(OPT_m) == "i386pe" && S.startswith("_")) | |
| 124 | Add("-entry:" + S.substr(1)); | |
| 125 | else | |
| 126 | Add("-entry:" + S); | |
| 127 | } | |
| 128 | ||
| 129 | if (auto *A = Args.getLastArg(OPT_subs)) | |
| 130 | Add("-subsystem:" + StringRef(A->getValue())); | |
| 131 | if (auto *A = Args.getLastArg(OPT_out_implib)) | |
| 132 | Add("-implib:" + StringRef(A->getValue())); | |
| 133 | if (auto *A = Args.getLastArg(OPT_stack)) | |
| 134 | Add("-stack:" + StringRef(A->getValue())); | |
| 135 | if (auto *A = Args.getLastArg(OPT_output_def)) | |
| 136 | Add("-output-def:" + StringRef(A->getValue())); | |
| 137 | if (auto *A = Args.getLastArg(OPT_image_base)) | |
| 138 | Add("-base:" + StringRef(A->getValue())); | |
| 139 | ||
| 140 | if (auto *A = Args.getLastArg(OPT_o)) | |
| 141 | Add("-out:" + StringRef(A->getValue())); | |
| 142 | else if (Args.hasArg(OPT_shared)) | |
| 143 | Add("-out:a.dll"); | |
| 144 | else | |
| 145 | Add("-out:a.exe"); | |
| 146 | ||
| 147 | if (Args.hasArg(OPT_shared)) | |
| 148 | Add("-dll"); | |
| 149 | if (Args.hasArg(OPT_verbose)) | |
| 150 | Add("-verbose"); | |
| 151 | if (Args.hasArg(OPT_export_all_symbols)) | |
| 152 | Add("-export-all-symbols"); | |
| 153 | if (!Args.hasArg(OPT_strip_all)) | |
| 154 | Add("-debug:dwarf"); | |
| 155 | if (Args.hasArg(OPT_large_address_aware)) | |
| 156 | Add("-largeaddressaware"); | |
| 157 | ||
| 158 | if (Args.getLastArgValue(OPT_m) != "thumb2pe" && | |
| 159 | Args.getLastArgValue(OPT_m) != "arm64pe" && !Args.hasArg(OPT_dynamicbase)) | |
| 160 | Add("-dynamicbase:no"); | |
| 161 | ||
| 162 | if (Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false)) | |
| 163 | Add("-opt:ref"); | |
| 164 | else | |
| 165 | Add("-opt:noref"); | |
| 166 | ||
| 167 | if (auto *A = Args.getLastArg(OPT_icf)) { | |
| 168 | StringRef S = A->getValue(); | |
| 169 | if (S == "all") | |
| 170 | Add("-opt:icf"); | |
| 171 | else if (S == "safe" || S == "none") | |
| 172 | Add("-opt:noicf"); | |
| 173 | else | |
| 174 | fatal("unknown parameter: --icf=" + S); | |
| 175 | } else { | |
| 176 | Add("-opt:noicf"); | |
| 177 | } | |
| 178 | ||
| 179 | if (auto *A = Args.getLastArg(OPT_m)) { | |
| 180 | StringRef S = A->getValue(); | |
| 181 | if (S == "i386pe") | |
| 182 | Add("-machine:x86"); | |
| 183 | else if (S == "i386pep") | |
| 184 | Add("-machine:x64"); | |
| 185 | else if (S == "thumb2pe") | |
| 186 | Add("-machine:arm"); | |
| 187 | else if (S == "arm64pe") | |
| 188 | Add("-machine:arm64"); | |
| 189 | else | |
| 190 | fatal("unknown parameter: -m" + S); | |
| 191 | } | |
| 192 | ||
| 193 | for (auto *A : Args.filtered(OPT_mllvm)) | |
| 194 | Add("-mllvm:" + StringRef(A->getValue())); | |
| 195 | ||
| 196 | for (auto *A : Args.filtered(OPT_Xlink)) | |
| 197 | Add(A->getValue()); | |
| 198 | ||
| 199 | if (Args.getLastArgValue(OPT_m) == "i386pe") | |
| 200 | Add("-alternatename:__image_base__=___ImageBase"); | |
| 201 | else | |
| 202 | Add("-alternatename:__image_base__=__ImageBase"); | |
| 203 | ||
| 204 | std::vector<StringRef> SearchPaths; | |
| 205 | for (auto *A : Args.filtered(OPT_L)) | |
| 206 | SearchPaths.push_back(A->getValue()); | |
| 207 | ||
| 208 | StringRef Prefix = ""; | |
| 209 | bool Static = false; | |
| 210 | for (auto *A : Args) { | |
| 211 | switch (A->getOption().getUnaliasedOption().getID()) { | |
| 212 | case OPT_INPUT: | |
| 213 | if (StringRef(A->getValue()).endswith_lower(".def")) | |
| 214 | Add("-def:" + StringRef(A->getValue())); | |
| 215 | else | |
| 216 | Add(Prefix + StringRef(A->getValue())); | |
| 217 | break; | |
| 218 | case OPT_l: | |
| 219 | Add(Prefix + searchLibrary(A->getValue(), SearchPaths, Static)); | |
| 220 | break; | |
| 221 | case OPT_whole_archive: | |
| 222 | Prefix = "-wholearchive:"; | |
| 223 | break; | |
| 224 | case OPT_no_whole_archive: | |
| 225 | Prefix = ""; | |
| 226 | break; | |
| 227 | case OPT_Bstatic: | |
| 228 | Static = true; | |
| 229 | break; | |
| 230 | case OPT_Bdynamic: | |
| 231 | Static = false; | |
| 232 | break; | |
| 233 | } | |
| 234 | } | |
| 235 | ||
| 236 | if (Args.hasArg(OPT_verbose) || Args.hasArg(OPT__HASH_HASH_HASH)) | |
| 237 | outs() << llvm::join(LinkArgs, " ") << "\n"; | |
| 238 | ||
| 239 | if (Args.hasArg(OPT__HASH_HASH_HASH)) | |
| 240 | return true; | |
| 241 | ||
| 242 | // Repack vector of strings to vector of const char pointers for coff::link. | |
| 243 | std::vector<const char *> Vec; | |
| 244 | for (const std::string &S : LinkArgs) | |
| 245 | Vec.push_back(S.c_str()); | |
| 246 | return coff::link(Vec, true); | |
| 247 | } |
deps/lld/MinGW/Options.td created+68| ... | ... | @@ -0,0 +1,68 @@ |
| 1 | include "llvm/Option/OptParser.td" | |
| 2 | ||
| 3 | class F<string name>: Flag<["--", "-"], name>; | |
| 4 | class J<string name>: Joined<["--", "-"], name>; | |
| 5 | class S<string name>: Separate<["--", "-"], name>; | |
| 6 | ||
| 7 | def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">, | |
| 8 | HelpText<"Add a directory to the library search path">; | |
| 9 | def dynamicbase: F<"dynamicbase">, HelpText<"Enable ASLR">; | |
| 10 | def entry: S<"entry">, MetaVarName<"<entry>">, | |
| 11 | HelpText<"Name of entry point symbol">; | |
| 12 | def export_all_symbols: F<"export-all-symbols">, | |
| 13 | HelpText<"Export all symbols even if a def file or dllexport attributes are used">; | |
| 14 | def gc_sections: F<"gc-sections">, HelpText<"Remove unused sections">; | |
| 15 | def icf: J<"icf=">, HelpText<"Identical code folding">; | |
| 16 | def image_base: S<"image-base">, HelpText<"Base address of the program">; | |
| 17 | def l: JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">, | |
| 18 | HelpText<"Root name of library to use">; | |
| 19 | def m: JoinedOrSeparate<["-"], "m">, HelpText<"Set target emulation">; | |
| 20 | def no_whole_archive: F<"no-whole-archive">, | |
| 21 | HelpText<"No longer include all object files for following archives">; | |
| 22 | def large_address_aware: Flag<["--"], "large-address-aware">, | |
| 23 | HelpText<"Enable large addresses">; | |
| 24 | def no_gc_sections: F<"no-gc-sections">, HelpText<"Don't remove unused sections">; | |
| 25 | def o: JoinedOrSeparate<["-"], "o">, MetaVarName<"<path>">, | |
| 26 | HelpText<"Path to file to write output">; | |
| 27 | def out_implib: Separate<["--"], "out-implib">, HelpText<"Import library name">; | |
| 28 | def out_implib_eq: Joined<["--"], "out-implib=">, Alias<out_implib>; | |
| 29 | def output_def: S<"output-def">, HelpText<"Output def file">; | |
| 30 | def shared: F<"shared">, HelpText<"Build a shared object">; | |
| 31 | def subs: S<"subsystem">, HelpText<"Specify subsystem">; | |
| 32 | def stack: S<"stack">; | |
| 33 | def strip_all: F<"strip-all">, | |
| 34 | HelpText<"Omit all symbol information from the output binary">; | |
| 35 | def whole_archive: F<"whole-archive">, | |
| 36 | HelpText<"Include all object files for following archives">; | |
| 37 | def verbose: F<"verbose">, HelpText<"Verbose mode">; | |
| 38 | ||
| 39 | // LLD specific options | |
| 40 | def _HASH_HASH_HASH : Flag<["-"], "###">, | |
| 41 | HelpText<"Print (but do not run) the commands to run for this compilation">; | |
| 42 | def mllvm: S<"mllvm">; | |
| 43 | def Xlink : J<"Xlink=">, MetaVarName<"<arg>">, | |
| 44 | HelpText<"Pass <arg> to the COFF linker">; | |
| 45 | ||
| 46 | // Currently stubs to avoid errors | |
| 47 | def Bdynamic: F<"Bdynamic">, HelpText<"Link against shared libraries">; | |
| 48 | def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries">; | |
| 49 | def O: Joined<["-"], "O">, HelpText<"Optimize output file size">; | |
| 50 | def build_id: F<"build-id">; | |
| 51 | def disable_auto_image_base: F<"disable-auto-image-base">; | |
| 52 | def enable_auto_image_base: F<"enable-auto-image-base">; | |
| 53 | def enable_auto_import: F<"enable-auto-import">; | |
| 54 | def full_shutdown: Flag<["--"], "full-shutdown">; | |
| 55 | def high_entropy_va: F<"high-entropy-va">, HelpText<"Enable 64-bit ASLR">; | |
| 56 | def major_image_version: S<"major-image-version">; | |
| 57 | def minor_image_version: S<"minor-image-version">; | |
| 58 | def no_seh: F<"no-seh">; | |
| 59 | def nxcompat: F<"nxcompat">, HelpText<"Enable data execution prevention">; | |
| 60 | def pic_executable: F<"pic-executable">; | |
| 61 | def sysroot: J<"sysroot">, HelpText<"Sysroot">; | |
| 62 | def tsaware: F<"tsaware">, HelpText<"Create Terminal Server aware executable">; | |
| 63 | def v: Flag<["-"], "v">, HelpText<"Display the version number">; | |
| 64 | def version: F<"version">, HelpText<"Display the version number and exit">; | |
| 65 | ||
| 66 | // Alias | |
| 67 | def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>; | |
| 68 | def alias_strip_s: Flag<["-"], "s">, Alias<strip_all>; |
deps/lld/README.md+10-2| ... | ... | @@ -1,6 +1,5 @@ |
| 1 | ||
| 2 | 1 | LLVM Linker (lld) |
| 3 | ============================== | |
| 2 | ================= | |
| 4 | 3 | |
| 5 | 4 | This directory and its subdirectories contain source code for the LLVM Linker, a |
| 6 | 5 | modular cross platform linker which is built as part of the LLVM compiler |
| ... | ... | @@ -9,3 +8,12 @@ infrastructure project. |
| 9 | 8 | lld is open source software. You may freely distribute it under the terms of |
| 10 | 9 | the license agreement found in LICENSE.txt. |
| 11 | 10 | |
| 11 | Benchmarking | |
| 12 | ============ | |
| 13 | ||
| 14 | In order to make sure various developers can evaluate patches over the | |
| 15 | same tests, we create a collection of self contained programs. | |
| 16 | ||
| 17 | It is hosted at https://s3-us-west-2.amazonaws.com/linker-tests/lld-speed-test.tar.xz | |
| 18 | ||
| 19 | The current sha256 is 10eec685463d5a8bbf08d77f4ca96282161d396c65bd97dc99dbde644a31610f. |
deps/lld/cmake/modules/AddLLD.cmake+4-8| ... | ... | @@ -25,11 +25,9 @@ macro(add_lld_library name) |
| 25 | 25 | RUNTIME DESTINATION bin) |
| 26 | 26 | |
| 27 | 27 | if (${ARG_SHARED} AND NOT CMAKE_CONFIGURATION_TYPES) |
| 28 | add_custom_target(install-${name} | |
| 28 | add_llvm_install_targets(install-${name} | |
| 29 | 29 | DEPENDS ${name} |
| 30 | COMMAND "${CMAKE_COMMAND}" | |
| 31 | -DCMAKE_INSTALL_COMPONENT=${name} | |
| 32 | -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") | |
| 30 | COMPONENT ${name}) | |
| 33 | 31 | endif() |
| 34 | 32 | set_property(GLOBAL APPEND PROPERTY LLD_EXPORTS ${name}) |
| 35 | 33 | endif() |
| ... | ... | @@ -60,11 +58,9 @@ macro(add_lld_tool name) |
| 60 | 58 | COMPONENT ${name}) |
| 61 | 59 | |
| 62 | 60 | if(NOT CMAKE_CONFIGURATION_TYPES) |
| 63 | add_custom_target(install-${name} | |
| 61 | add_llvm_install_targets(install-${name} | |
| 64 | 62 | DEPENDS ${name} |
| 65 | COMMAND "${CMAKE_COMMAND}" | |
| 66 | -DCMAKE_INSTALL_COMPONENT=${name} | |
| 67 | -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") | |
| 63 | COMPONENT ${name}) | |
| 68 | 64 | endif() |
| 69 | 65 | set_property(GLOBAL APPEND PROPERTY LLD_EXPORTS ${name}) |
| 70 | 66 | endif() |
deps/lld/docs/Driver.rst+1-1| ... | ... | @@ -65,7 +65,7 @@ Adding an Option to an existing Flavor |
| 65 | 65 | Adding a Flavor |
| 66 | 66 | =============== |
| 67 | 67 | |
| 68 | #. Add an entry for the flavor in :file:`include/lld/Driver/Driver.h` to | |
| 68 | #. Add an entry for the flavor in :file:`include/lld/Common/Driver.h` to | |
| 69 | 69 | :cpp:class:`lld::UniversalDriver::Flavor`. |
| 70 | 70 | |
| 71 | 71 | #. Add an entry in :file:`lib/Driver/UniversalDriver.cpp` to |
deps/lld/docs/NewLLD.rst+67-72| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | The ELF and COFF Linkers | |
| 2 | ======================== | |
| 1 | The ELF, COFF and Wasm Linkers | |
| 2 | ============================== | |
| 3 | 3 | |
| 4 | 4 | The ELF Linker as a Library |
| 5 | 5 | --------------------------- |
| ... | ... | @@ -33,11 +33,12 @@ between speed, simplicity and extensibility. |
| 33 | 33 | |
| 34 | 34 | We implemented the linkers as native linkers for each file format. |
| 35 | 35 | |
| 36 | The two linkers share the same design but do not share code. | |
| 36 | The linkers share the same design but share very little code. | |
| 37 | 37 | Sharing code makes sense if the benefit is worth its cost. |
| 38 | In our case, ELF and COFF are different enough that we thought the layer to | |
| 39 | abstract the differences wouldn't worth its complexity and run-time cost. | |
| 40 | Elimination of the abstract layer has greatly simplified the implementation. | |
| 38 | In our case, the object formats are different enough that we thought the layer | |
| 39 | to abstract the differences wouldn't be worth its complexity and run-time | |
| 40 | cost. Elimination of the abstract layer has greatly simplified the | |
| 41 | implementation. | |
| 41 | 42 | |
| 42 | 43 | * Speed by design |
| 43 | 44 | |
| ... | ... | @@ -57,59 +58,61 @@ between speed, simplicity and extensibility. |
| 57 | 58 | |
| 58 | 59 | * Efficient archive file handling |
| 59 | 60 | |
| 60 | LLD's handling of archive files (the files with ".a" file extension) is different | |
| 61 | from the traditional Unix linkers and similar to Windows linkers. | |
| 62 | We'll describe how the traditional Unix linker handles archive files, | |
| 63 | what the problem is, and how LLD approached the problem. | |
| 61 | LLD's handling of archive files (the files with ".a" file extension) is | |
| 62 | different from the traditional Unix linkers and similar to Windows linkers. | |
| 63 | We'll describe how the traditional Unix linker handles archive files, what the | |
| 64 | problem is, and how LLD approached the problem. | |
| 64 | 65 | |
| 65 | The traditional Unix linker maintains a set of undefined symbols during linking. | |
| 66 | The linker visits each file in the order as they appeared in the command line | |
| 67 | until the set becomes empty. What the linker would do depends on file type. | |
| 66 | The traditional Unix linker maintains a set of undefined symbols during | |
| 67 | linking. The linker visits each file in the order as they appeared in the | |
| 68 | command line until the set becomes empty. What the linker would do depends on | |
| 69 | file type. | |
| 68 | 70 | |
| 69 | - If the linker visits an object file, the linker links object files to the result, | |
| 70 | and undefined symbols in the object file are added to the set. | |
| 71 | - If the linker visits an object file, the linker links object files to the | |
| 72 | result, and undefined symbols in the object file are added to the set. | |
| 71 | 73 | |
| 72 | - If the linker visits an archive file, it checks for the archive file's symbol table | |
| 73 | and extracts all object files that have definitions for any symbols in the set. | |
| 74 | - If the linker visits an archive file, it checks for the archive file's | |
| 75 | symbol table and extracts all object files that have definitions for any | |
| 76 | symbols in the set. | |
| 74 | 77 | |
| 75 | This algorithm sometimes leads to a counter-intuitive behavior. | |
| 76 | If you give archive files before object files, nothing will happen | |
| 77 | because when the linker visits archives, there is no undefined symbols in the set. | |
| 78 | As a result, no files are extracted from the first archive file, | |
| 79 | and the link is done at that point because the set is empty after it visits one file. | |
| 78 | This algorithm sometimes leads to a counter-intuitive behavior. If you give | |
| 79 | archive files before object files, nothing will happen because when the linker | |
| 80 | visits archives, there is no undefined symbols in the set. As a result, no | |
| 81 | files are extracted from the first archive file, and the link is done at that | |
| 82 | point because the set is empty after it visits one file. | |
| 80 | 83 | |
| 81 | 84 | You can fix the problem by reordering the files, |
| 82 | 85 | but that cannot fix the issue of mutually-dependent archive files. |
| 83 | 86 | |
| 84 | Linking mutually-dependent archive files is tricky. | |
| 85 | You may specify the same archive file multiple times to | |
| 86 | let the linker visit it more than once. | |
| 87 | Or, you may use the special command line options, `--start-group` and `--end-group`, | |
| 88 | to let the linker loop over the files between the options until | |
| 87 | Linking mutually-dependent archive files is tricky. You may specify the same | |
| 88 | archive file multiple times to let the linker visit it more than once. Or, | |
| 89 | you may use the special command line options, `--start-group` and | |
| 90 | `--end-group`, to let the linker loop over the files between the options until | |
| 89 | 91 | no new symbols are added to the set. |
| 90 | 92 | |
| 91 | 93 | Visiting the same archive files multiple makes the linker slower. |
| 92 | 94 | |
| 93 | Here is how LLD approaches the problem. Instead of memorizing only undefined symbols, | |
| 94 | we program LLD so that it memorizes all symbols. | |
| 95 | When it sees an undefined symbol that can be resolved by extracting an object file | |
| 96 | from an archive file it previously visited, it immediately extracts the file and link it. | |
| 97 | It is doable because LLD does not forget symbols it have seen in archive files. | |
| 95 | Here is how LLD approaches the problem. Instead of memorizing only undefined | |
| 96 | symbols, we program LLD so that it memorizes all symbols. When it sees an | |
| 97 | undefined symbol that can be resolved by extracting an object file from an | |
| 98 | archive file it previously visited, it immediately extracts the file and link | |
| 99 | it. It is doable because LLD does not forget symbols it have seen in archive | |
| 100 | files. | |
| 98 | 101 | |
| 99 | 102 | We believe that the LLD's way is efficient and easy to justify. |
| 100 | 103 | |
| 101 | The semantics of LLD's archive handling is different from the traditional Unix's. | |
| 102 | You can observe it if you carefully craft archive files to exploit it. | |
| 103 | However, in reality, we don't know any program that cannot link | |
| 104 | with our algorithm so far, so it's not going to cause trouble. | |
| 104 | The semantics of LLD's archive handling is different from the traditional | |
| 105 | Unix's. You can observe it if you carefully craft archive files to exploit | |
| 106 | it. However, in reality, we don't know any program that cannot link with our | |
| 107 | algorithm so far, so it's not going to cause trouble. | |
| 105 | 108 | |
| 106 | 109 | Numbers You Want to Know |
| 107 | 110 | ------------------------ |
| 108 | 111 | |
| 109 | 112 | To give you intuition about what kinds of data the linker is mainly working on, |
| 110 | 113 | I'll give you the list of objects and their numbers LLD has to read and process |
| 111 | in order to link a very large executable. In order to link Chrome with debug info, | |
| 112 | which is roughly 2 GB in output size, LLD reads | |
| 114 | in order to link a very large executable. In order to link Chrome with debug | |
| 115 | info, which is roughly 2 GB in output size, LLD reads | |
| 113 | 116 | |
| 114 | 117 | - 17,000 files, |
| 115 | 118 | - 1,800,000 sections, |
| ... | ... | @@ -136,17 +139,17 @@ when handling files. |
| 136 | 139 | Important Data Structures |
| 137 | 140 | ------------------------- |
| 138 | 141 | |
| 139 | We will describe the key data structures in LLD in this section. | |
| 140 | The linker can be understood as the interactions between them. | |
| 141 | Once you understand their functions, the code of the linker should look obvious to you. | |
| 142 | We will describe the key data structures in LLD in this section. The linker can | |
| 143 | be understood as the interactions between them. Once you understand their | |
| 144 | functions, the code of the linker should look obvious to you. | |
| 142 | 145 | |
| 143 | * SymbolBody | |
| 146 | * Symbol | |
| 144 | 147 | |
| 145 | SymbolBody is a class to represent symbols. | |
| 148 | This class represents a symbol. | |
| 146 | 149 | They are created for symbols in object files or archive files. |
| 147 | 150 | The linker creates linker-defined symbols as well. |
| 148 | 151 | |
| 149 | There are basically three types of SymbolBodies: Defined, Undefined, or Lazy. | |
| 152 | There are basically three types of Symbols: Defined, Undefined, or Lazy. | |
| 150 | 153 | |
| 151 | 154 | - Defined symbols are for all symbols that are considered as "resolved", |
| 152 | 155 | including real defined symbols, COMDAT symbols, common symbols, |
| ... | ... | @@ -156,33 +159,25 @@ Once you understand their functions, the code of the linker should look obvious |
| 156 | 159 | - Lazy symbols represent symbols we found in archive file headers |
| 157 | 160 | which can turn into Defined if we read archieve members. |
| 158 | 161 | |
| 159 | * Symbol | |
| 162 | There's only one Symbol instance for each unique symbol name. This uniqueness | |
| 163 | is guaranteed by the symbol table. As the resolver reads symbols from input | |
| 164 | files, it replaces an existing Symbol with the "best" Symbol for its symbol | |
| 165 | name using the placement new. | |
| 160 | 166 | |
| 161 | A Symbol is a container for a SymbolBody. There's only one Symbol for each | |
| 162 | unique symbol name (this uniqueness is guaranteed by the symbol table). | |
| 163 | Each global symbol has only one SymbolBody at any one time, which is | |
| 164 | the SymbolBody stored within a memory region of the Symbol large enough | |
| 165 | to store any SymbolBody. | |
| 166 | ||
| 167 | As the resolver reads symbols from input files, it replaces the Symbol's | |
| 168 | SymbolBody with the "best" SymbolBody for its symbol name by constructing | |
| 169 | the new SymbolBody in place on top of the existing SymbolBody. For example, | |
| 170 | if the resolver is given a defined symbol, and the SymbolBody with its name | |
| 171 | is undefined, it will construct a Defined SymbolBody over the Undefined | |
| 172 | SymbolBody. | |
| 173 | ||
| 174 | This means that each SymbolBody pointer always points to the best SymbolBody, | |
| 175 | and it is possible to get from a SymbolBody to a Symbol, or vice versa, | |
| 176 | by adding or subtracting a fixed offset. This memory layout helps reduce | |
| 177 | the cache miss rate through high locality and a small number of required | |
| 178 | pointer indirections. | |
| 167 | The above mechanism allows you to use pointers to Symbols as a very cheap way | |
| 168 | to access name resolution results. Assume for example that you have a pointer | |
| 169 | to an undefined symbol before name resolution. If the symbol is resolved to a | |
| 170 | defined symbol by the resolver, the pointer will "automatically" point to the | |
| 171 | defined symbol, because the undefined symbol the pointer pointed to will have | |
| 172 | been replaced by the defined symbol in-place. | |
| 179 | 173 | |
| 180 | 174 | * SymbolTable |
| 181 | 175 | |
| 182 | 176 | SymbolTable is basically a hash table from strings to Symbols |
| 183 | 177 | with logic to resolve symbol conflicts. It resolves conflicts by symbol type. |
| 184 | 178 | |
| 185 | - If we add Defined and Undefined symbols, the symbol table will keep the former. | |
| 179 | - If we add Defined and Undefined symbols, the symbol table will keep the | |
| 180 | former. | |
| 186 | 181 | - If we add Defined and Lazy symbols, it will keep the former. |
| 187 | 182 | - If we add Lazy and Undefined, it will keep the former, |
| 188 | 183 | but it will also trigger the Lazy symbol to load the archive member |
| ... | ... | @@ -221,15 +216,14 @@ There are mainly three actors in this linker. |
| 221 | 216 | InputFile is a superclass of file readers. |
| 222 | 217 | We have a different subclass for each input file type, |
| 223 | 218 | such as regular object file, archive file, etc. |
| 224 | They are responsible for creating and owning SymbolBodies and | |
| 225 | InputSections/Chunks. | |
| 219 | They are responsible for creating and owning Symbols and InputSections/Chunks. | |
| 226 | 220 | |
| 227 | 221 | * Writer |
| 228 | 222 | |
| 229 | The writer is responsible for writing file headers and InputSections/Chunks to a file. | |
| 230 | It creates OutputSections, put all InputSections/Chunks into them, | |
| 231 | assign unique, non-overlapping addresses and file offsets to them, | |
| 232 | and then write them down to a file. | |
| 223 | The writer is responsible for writing file headers and InputSections/Chunks to | |
| 224 | a file. It creates OutputSections, put all InputSections/Chunks into them, | |
| 225 | assign unique, non-overlapping addresses and file offsets to them, and then | |
| 226 | write them down to a file. | |
| 233 | 227 | |
| 234 | 228 | * Driver |
| 235 | 229 | |
| ... | ... | @@ -237,7 +231,8 @@ There are mainly three actors in this linker. |
| 237 | 231 | |
| 238 | 232 | - processes command line options, |
| 239 | 233 | - creates a symbol table, |
| 240 | - creates an InputFile for each input file and puts all symbols within into the symbol table, | |
| 234 | - creates an InputFile for each input file and puts all symbols within into | |
| 235 | the symbol table, | |
| 241 | 236 | - checks if there's no remaining undefined symbols, |
| 242 | 237 | - creates a writer, |
| 243 | 238 | - and passes the symbol table to the writer to write the result to a file. |
| ... | ... | @@ -301,7 +296,7 @@ Glossary |
| 301 | 296 | they are merged by ICF. It is known as an effective technique, |
| 302 | 297 | and it usually reduces C++ program's size by a few percent or more. |
| 303 | 298 | |
| 304 | Note that this is not entirely sound optimization. C/C++ require | |
| 299 | Note that this is not an entirely sound optimization. C/C++ require | |
| 305 | 300 | different functions have different addresses. If a program depends on |
| 306 | 301 | that property, it would fail at runtime. |
| 307 | 302 |
deps/lld/docs/ReleaseNotes.rst+82-155| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | ======================= |
| 2 | lld 5.0.0 Release Notes | |
| 2 | LLD 6.0.0 Release Notes | |
| 3 | 3 | ======================= |
| 4 | 4 | |
| 5 | 5 | .. contents:: |
| ... | ... | @@ -8,16 +8,10 @@ lld 5.0.0 Release Notes |
| 8 | 8 | Introduction |
| 9 | 9 | ============ |
| 10 | 10 | |
| 11 | lld is a linker from the LLVM project. It supports ELF (Unix), COFF (Windows) | |
| 12 | and Mach-O (macOS), and it is generally faster than the GNU bfd or gold linkers | |
| 13 | or the MSVC linker. | |
| 14 | ||
| 15 | lld is designed to be a drop-in replacement for the system linkers, so that | |
| 16 | users don't need to change their build systems other than swapping the linker | |
| 17 | command. | |
| 18 | ||
| 19 | All lld releases may be downloaded from the `LLVM releases web site | |
| 20 | <http://llvm.org/releases/>`_. | |
| 11 | This document contains the release notes for the lld linker, release 6.0.0. | |
| 12 | Here we describe the status of lld, including major improvements | |
| 13 | from the previous release. All lld releases may be downloaded | |
| 14 | from the `LLVM releases web site <http://llvm.org/releases/>`_. | |
| 21 | 15 | |
| 22 | 16 | Non-comprehensive list of changes in this release |
| 23 | 17 | ================================================= |
| ... | ... | @@ -25,148 +19,81 @@ Non-comprehensive list of changes in this release |
| 25 | 19 | ELF Improvements |
| 26 | 20 | ---------------- |
| 27 | 21 | |
| 28 | * First and foremost, a lot of compatibility issues and bugs have been fixed. | |
| 29 | Linker script support has significantly improved. As a result, we believe you | |
| 30 | are very likely to be able to link your programs with lld without experiencing | |
| 31 | any problem now. | |
| 32 | ||
| 33 | * Error message format has changed in order to improve readability. | |
| 34 | Traditionally, linker's error messages are concise and arguably too terse. | |
| 35 | This is an example of lld 4.0.0's error message (they are actually in one line):: | |
| 36 | ||
| 37 | /ssd/clang/bin/ld.lld: error: /ssd/llvm-project/lld/ELF/Writer.cpp:207: | |
| 38 | undefined symbol 'lld::elf::EhFrameSection::addSection()' | |
| 39 | ||
| 40 | It is not easy to read because too much information is packed into a single line | |
| 41 | and the embedded text, particularly a symbol name, is sometimes too long. | |
| 42 | In lld 5.0.0, we use more vertical space to print out error messages in a more | |
| 43 | structured manner like this:: | |
| 44 | ||
| 45 | bin/ld.lld: error: undefined symbol: lld::elf::EhFrameSection::addSection() | |
| 46 | >>> Referenced by Writer.cpp:207 (/ssd/llvm-project/lld/ELF/Writer.cpp:207) | |
| 47 | >>> Writer.cpp.o in archive lib/liblldELF.a | |
| 48 | ||
| 49 | As a bonus, the new error message contains source code location of the error | |
| 50 | if it is available from debug info. | |
| 51 | ||
| 52 | * ``./configure`` scripts generated by GNU autoconf determines whether a linker | |
| 53 | supports modern GNU-compatible features or not by searching for "GNU" in the | |
| 54 | ``--help`` message. To be compatible with the scripts, we decided to add a | |
| 55 | string "(compatible with GNU linkers)" to our ``--help`` message. This is a | |
| 56 | hack, but just like the web browser's User-Agent string (which everyone still | |
| 57 | claim they are "Mozilla/5.0"), we had no choice other than doing this to claim | |
| 58 | that we accept GNU-compatible options. | |
| 59 | ||
| 60 | * The ``-Map`` option is added. The option is to make the linker to print out how | |
| 61 | input files are mapped to the output file. Here is an example:: | |
| 62 | ||
| 63 | Address Size Align Out In Symbol | |
| 64 | 00000000016d84d8 00000000008f8f50 8 .eh_frame | |
| 65 | 00000000016d84d8 00000000008f8f50 8 <internal>:(.eh_frame) | |
| 66 | 0000000001fd2000 00000000034b3bd0 16 .text | |
| 67 | 0000000001fd2000 000000000000002a 1 /usr/lib/x86_64-linux-gnu/crt1.o:(.text) | |
| 68 | 0000000001fd2000 0000000000000000 0 _start | |
| 69 | 0000000001fd202a 0000000000000000 1 /usr/lib/x86_64-linux-gnu/crti.o:(.text) | |
| 70 | 0000000001fd2030 00000000000000bd 16 /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o:(.text) | |
| 71 | 0000000001fd2030 0000000000000000 0 deregister_tm_clones | |
| 72 | 0000000001fd2060 0000000000000000 0 register_tm_clones | |
| 73 | ||
| 74 | This format is not the same as GNU linkers as our linker internal data | |
| 75 | structure is different from them but contains the same amount of information | |
| 76 | and should be more readable than their outputs. | |
| 77 | ||
| 78 | As with other lld features, the ``-Map`` option is designed with speed in mind. | |
| 79 | The option would generate a hundred megabyte text file if you link a large | |
| 80 | program with it. lld can usually do that in a few seconds, and it is generally | |
| 81 | a few times faster than the GNU gold's ``-Map`` option. | |
| 82 | ||
| 83 | * lld's ``--gdb-index`` option used to be slow, but we sped it up so that it is | |
| 84 | at least as fast as the GNU gold. | |
| 85 | ||
| 86 | * Some nonstandard relocations, such as R_X86_64_8 or R_X86_64_16, are supported. | |
| 87 | They are not used for 32/64-bit applications, but some 16-bit bootloaders need | |
| 88 | them. | |
| 89 | ||
| 90 | * Paddings in executable text sections are now filled with trap instructions | |
| 91 | (such as INT3) instead of being left as null bytes. This change improves | |
| 92 | disassembler outputs because it now prints out trap instructions instead of | |
| 93 | trying to decode 0x00 as an instruction. It also makes debugging of some type | |
| 94 | of program easier because when the control reaches a padding, the program | |
| 95 | immediately raises an error. | |
| 96 | ||
| 97 | * The following options are added: ``-M``, ``-Map``, | |
| 98 | ``-compress-debug-sections``, ``-emit-relocs``, | |
| 99 | ``-error-unresolved-symbols``, ``-exclude-libs``, ``-filter``, | |
| 100 | ``-no-dynamic-linker``, ``-no-export-dynamic``, ``-no-fatal-warnings``, | |
| 101 | ``-print-map``, ``-warn-unresolved-symbols``, ``-z nocopyreloc``, | |
| 102 | ``-z notext``, ``-z rodynamic`` | |
| 103 | ||
| 104 | ||
| 105 | Contributors to lld 5.0 | |
| 106 | ======================= | |
| 22 | * A lot of bugs and compatibility issues have been identified and fixed as a | |
| 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 | ||
| 74 | COFF Improvements | |
| 75 | ----------------- | |
| 76 | ||
| 77 | * A GNU ld style frontend for the COFF linker has been added for MinGW. | |
| 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 | ||
| 95 | WebAssembly Improvements | |
| 96 | ------------------------ | |
| 107 | 97 | |
| 108 | We had 63 individuals contribute to lld 5.0. Thank you so much! | |
| 109 | ||
| 110 | - Adrian McCarthy | |
| 111 | - Alberto Magni | |
| 112 | - Alexander Richardson | |
| 113 | - Andre Vieira | |
| 114 | - Andrew Ng | |
| 115 | - Anton Korobeynikov | |
| 116 | - Bob Haarman | |
| 117 | - David Blaikie | |
| 118 | - Davide Italiano | |
| 119 | - David L. Jones | |
| 120 | - Dmitry Mikulin | |
| 121 | - Ed Maste | |
| 122 | - Ed Schouten | |
| 123 | - Eric Beckmann | |
| 124 | - Eric Fiselier | |
| 125 | - Eugene Leviant | |
| 126 | - Evgeniy Stepanov | |
| 127 | - Galina Kistanova | |
| 128 | - George Rimar | |
| 129 | - Hans Wennborg | |
| 130 | - Igor Kudrin | |
| 131 | - Ismail Donmez | |
| 132 | - Jake Ehrlich | |
| 133 | - James Henderson | |
| 134 | - Joel Jones | |
| 135 | - Jon Chesterfield | |
| 136 | - Kamil Rytarowski | |
| 137 | - Kevin Enderby | |
| 138 | - Konstantin Zhuravlyov | |
| 139 | - Kyungwoo Lee | |
| 140 | - Leslie Zhai | |
| 141 | - Mark Kettenis | |
| 142 | - Martell Malone | |
| 143 | - Martin Storsjo | |
| 144 | - Meador Inge | |
| 145 | - Mehdi Amini | |
| 146 | - Michal Gorny | |
| 147 | - NAKAMURA Takumi | |
| 148 | - Paul Robinson | |
| 149 | - Pavel Labath | |
| 150 | - Petar Jovanovic | |
| 151 | - Peter Collingbourne | |
| 152 | - Peter Smith | |
| 153 | - Petr Hosek | |
| 154 | - Rafael Espindola | |
| 155 | - Reid Kleckner | |
| 156 | - Richard Smith | |
| 157 | - Robert Clarke | |
| 158 | - Rui Ueyama | |
| 159 | - Saleem Abdulrasool | |
| 160 | - Sam Clegg | |
| 161 | - Sean Eveson | |
| 162 | - Sean Silva | |
| 163 | - Shankar Easwaran | |
| 164 | - Shoaib Meenai | |
| 165 | - Simon Atanasyan | |
| 166 | - Simon Dardis | |
| 167 | - Simon Tatham | |
| 168 | - Sylvestre Ledru | |
| 169 | - Tom Stellard | |
| 170 | - Vitaly Buka | |
| 171 | - Yuka Takahashi | |
| 172 | - Zachary Turner | |
| 98 | * Initial version of WebAssembly support has landed. You can invoke the | |
| 99 | WebAssembly linker by ``wasm-ld``. |
deps/lld/docs/WebAssembly.rst created+36| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | WebAssembly lld port | |
| 2 | ==================== | |
| 3 | ||
| 4 | Note: The WebAssembly port is still a work in progress and is be lacking | |
| 5 | certain features. | |
| 6 | ||
| 7 | The WebAssembly version of lld takes WebAssembly binaries as inputs and produces | |
| 8 | a WebAssembly binary as its output. For the most part this port tried to mimic | |
| 9 | the behaviour of traditional ELF linkers and specifically the ELF lld port. | |
| 10 | Where possible that command line flags and the semantics should be the same. | |
| 11 | ||
| 12 | ||
| 13 | Object file format | |
| 14 | ------------------ | |
| 15 | ||
| 16 | The format the input object files that lld expects is specified as part of the | |
| 17 | the WebAssembly tool conventions | |
| 18 | https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md. | |
| 19 | ||
| 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 | |
| 22 | currently requires enabling the experimental backed using | |
| 23 | ``-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly``. | |
| 24 | ||
| 25 | ||
| 26 | Missing features | |
| 27 | ---------------- | |
| 28 | ||
| 29 | There are several key features that are not yet implement in the WebAssembly | |
| 30 | ports: | |
| 31 | ||
| 32 | - COMDAT support. This means that support for C++ is still very limited. | |
| 33 | - Function stripping. Currently there is no support for ``--gc-sections`` so | |
| 34 | functions and data from a given object will linked as a unit. | |
| 35 | - Section start/end symbols. The synthetic symbols that mark the start and | |
| 36 | of data regions are not yet created in the output file. |
deps/lld/docs/_templates/indexsidebar.html+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | 1 | <h3>Bugs</h3> |
| 2 | 2 | |
| 3 | 3 | <p>lld bugs should be reported at the |
| 4 | LLVM <a href="http://llvm.org/bugs">Bugzilla</a>.</p> | |
| 4 | LLVM <a href="https://bugs.llvm.org/">Bugzilla</a>.</p> |
deps/lld/docs/conf.py+2-2| ... | ... | @@ -48,9 +48,9 @@ copyright = u'2011-%d, LLVM Project' % date.today().year |
| 48 | 48 | # built documents. |
| 49 | 49 | # |
| 50 | 50 | # The short version. |
| 51 | version = '5' | |
| 51 | version = '6' | |
| 52 | 52 | # The full version, including alpha/beta/rc tags. |
| 53 | release = '5' | |
| 53 | release = '6' | |
| 54 | 54 | |
| 55 | 55 | # The language for content autogenerated by Sphinx. Refer to documentation |
| 56 | 56 | # for a list of supported languages. |
deps/lld/docs/index.rst+27-28| ... | ... | @@ -5,13 +5,14 @@ LLD is a linker from the LLVM project. That is a drop-in replacement |
| 5 | 5 | for system linkers and runs much faster than them. It also provides |
| 6 | 6 | features that are useful for toolchain developers. |
| 7 | 7 | |
| 8 | The linker supports ELF (Unix), PE/COFF (Windows) and Mach-O (macOS) | |
| 9 | in descending order of completeness. Internally, LLD consists of three | |
| 10 | 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 | |
| 12 | the Windows debug info (PDB) support. The Mach-O port is built based | |
| 13 | on a different architecture than the ELF or COFF ports. For the | |
| 14 | details about Mach-O, please read :doc:`AtomLLD`. | |
| 8 | The linker supports ELF (Unix), PE/COFF (Windows), Mach-O (macOS) and | |
| 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 | |
| 11 | this document. The PE/COFF port is almost complete except the lack of the | |
| 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 | |
| 14 | different architecture than the others. For the details about Mach-O, please | |
| 15 | read :doc:`AtomLLD`. | |
| 15 | 16 | |
| 16 | 17 | Features |
| 17 | 18 | -------- |
| ... | ... | @@ -71,30 +72,27 @@ Performance |
| 71 | 72 | ----------- |
| 72 | 73 | |
| 73 | 74 | This is a link time comparison on a 2-socket 20-core 40-thread Xeon |
| 74 | E5-2680 2.80 GHz machine with an SSD drive. | |
| 75 | ||
| 76 | LLD is much faster than the GNU linkers for large programs. That's | |
| 77 | fast for small programs too, but because the link time is short | |
| 78 | anyway, the difference is not very noticeable in that case. | |
| 79 | ||
| 75 | E5-2680 2.80 GHz machine with an SSD drive. We ran gold and lld with | |
| 76 | or without multi-threading support. To disable multi-threading, we | |
| 77 | added ``-no-threads`` to the command lines. | |
| 78 | ||
| 79 | ============ =========== ============ ==================== ================== =============== ============= | |
| 80 | Program Output size GNU ld GNU gold w/o threads GNU gold w/threads lld w/o threads lld w/threads | |
| 81 | ffmpeg dbg 92 MiB 1.72s 1.16s 1.01s 0.60s 0.35s | |
| 82 | mysqld dbg 154 MiB 8.50s 2.96s 2.68s 1.06s 0.68s | |
| 83 | clang dbg 1.67 GiB 104.03s 34.18s 23.49s 14.82s 5.28s | |
| 84 | chromium dbg 1.14 GiB 209.05s [1]_ 64.70s 60.82s 27.60s 16.70s | |
| 85 | ============ =========== ============ ==================== ================== =============== ============= | |
| 86 | ||
| 87 | As you can see, lld is significantly faster than GNU linkers. | |
| 80 | 88 | Note that this is just a benchmark result of our environment. |
| 81 | 89 | Depending on number of available cores, available amount of memory or |
| 82 | 90 | disk latency/throughput, your results may vary. |
| 83 | 91 | |
| 84 | ============ =========== ============ ============= ====== | |
| 85 | Program Output size GNU ld GNU gold [1]_ LLD | |
| 86 | ffmpeg dbg 91 MiB 1.59s 1.15s 0.78s | |
| 87 | mysqld dbg 157 MiB 7.09s 2.49s 1.31s | |
| 88 | clang dbg 1.45 GiB 86.76s 21.93s 8.38s | |
| 89 | chromium dbg 1.52 GiB 142.30s [2]_ 40.86s 12.69s | |
| 90 | ============ =========== ============ ============= ====== | |
| 91 | ||
| 92 | .. [1] With the ``--threads`` option to enable multi-threading support. | |
| 93 | ||
| 94 | .. [2] Since GNU ld doesn't support the ``-icf=all`` option, we | |
| 95 | removed that from the command line for GNU ld. GNU ld would be | |
| 96 | slower than this if it had that option support. For gold and | |
| 97 | LLD, we use ``-icf=all``. | |
| 92 | .. [1] Since GNU ld doesn't support the ``-icf=all`` and | |
| 93 | ``-gdb-index`` options, we removed them from the command line | |
| 94 | for GNU ld. GNU ld would have been slower than this if it had | |
| 95 | these options. | |
| 98 | 96 | |
| 99 | 97 | Build |
| 100 | 98 | ----- |
| ... | ... | @@ -110,7 +108,7 @@ build that tree. You need `cmake` and of course a C++ compiler. |
| 110 | 108 | |
| 111 | 109 | .. code-block:: console |
| 112 | 110 | |
| 113 | $ git clone https://github.com/llvm-project/llvm-project/ | |
| 111 | $ git clone https://github.com/llvm-project/llvm-project-20170507 llvm-project | |
| 114 | 112 | $ mkdir build |
| 115 | 113 | $ cd build |
| 116 | 114 | $ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=lld -DCMAKE_INSTALL_PREFIX=/usr/local ../llvm-project/llvm |
| ... | ... | @@ -175,5 +173,6 @@ document soon. |
| 175 | 173 | |
| 176 | 174 | NewLLD |
| 177 | 175 | AtomLLD |
| 176 | WebAssembly | |
| 178 | 177 | windows_support |
| 179 | 178 | ReleaseNotes |
deps/lld/docs/sphinx_intro.rst+8-28| ... | ... | @@ -57,41 +57,21 @@ to install it using: |
| 57 | 57 | Building the documentation |
| 58 | 58 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 59 | 59 | |
| 60 | In order to build the documentation, all you should need to do is change to the | |
| 61 | ``docs`` directory and invoke make as follows:: | |
| 62 | ||
| 63 | $ cd path/to/project/docs | |
| 64 | $ make html | |
| 65 | ||
| 66 | Note that on Windows there is a ``make.bat`` command in the docs directory which | |
| 67 | supplies the same interface as the ``Makefile``. | |
| 68 | ||
| 69 | That command will invoke ``sphinx-build`` with the appropriate options for the | |
| 70 | project, and generate the HTML documentation in a ``_build`` subdirectory. You | |
| 71 | can browse it starting from the index page by visiting | |
| 72 | ``_build/html/index.html``. | |
| 73 | ||
| 74 | Sphinx supports a wide variety of generation formats (including LaTeX, man | |
| 75 | pages, and plain text). The ``Makefile`` includes a number of convenience | |
| 76 | targets for invoking ``sphinx-build`` appropriately, the common ones are: | |
| 77 | ||
| 78 | make html | |
| 79 | Generate the HTML output. | |
| 80 | ||
| 81 | make latexpdf | |
| 82 | Generate LaTeX documentation and convert to a PDF. | |
| 83 | ||
| 84 | make man | |
| 85 | Generate man pages. | |
| 60 | In order to build the documentation need to add ``-DLLVM_ENABLE_SPHINX=ON`` to | |
| 61 | your ``cmake`` command. Once you do this you can build the docs using | |
| 62 | ``docs-lld-html`` build (``ninja`` or ``make``) target. | |
| 86 | 63 | |
| 64 | That build target will invoke ``sphinx-build`` with the appropriate options for | |
| 65 | the project, and generate the HTML documentation in a ``tools/lld/docs/html`` | |
| 66 | subdirectory. | |
| 87 | 67 | |
| 88 | 68 | .. _writing_documentation: |
| 89 | 69 | |
| 90 | 70 | Writing documentation |
| 91 | 71 | ~~~~~~~~~~~~~~~~~~~~~ |
| 92 | 72 | |
| 93 | The documentation itself is written in the reStructuredText (ReST) format, and Sphinx | |
| 94 | defines additional tags to support features like cross-referencing. | |
| 73 | The documentation itself is written in the reStructuredText (ReST) format, and | |
| 74 | Sphinx defines additional tags to support features like cross-referencing. | |
| 95 | 75 | |
| 96 | 76 | The ReST format itself is organized around documents mostly being readable |
| 97 | 77 | plaintext documents. You should generally be able to write new documentation |
deps/lld/include/lld/Common/Args.h created+35| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | //===- Args.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_ARGS_H | |
| 11 | #define LLD_ARGS_H | |
| 12 | ||
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | #include "llvm/Support/MemoryBuffer.h" | |
| 15 | #include <vector> | |
| 16 | ||
| 17 | namespace llvm { | |
| 18 | namespace opt { | |
| 19 | class InputArgList; | |
| 20 | } | |
| 21 | } // namespace llvm | |
| 22 | ||
| 23 | namespace lld { | |
| 24 | namespace args { | |
| 25 | int getInteger(llvm::opt::InputArgList &Args, unsigned Key, int Default); | |
| 26 | std::vector<StringRef> getStrings(llvm::opt::InputArgList &Args, int Id); | |
| 27 | ||
| 28 | uint64_t getZOptionValue(llvm::opt::InputArgList &Args, int Id, StringRef Key, | |
| 29 | uint64_t Default); | |
| 30 | ||
| 31 | std::vector<StringRef> getLines(MemoryBufferRef MB); | |
| 32 | } // namespace args | |
| 33 | } // namespace lld | |
| 34 | ||
| 35 | #endif |
deps/lld/include/lld/Common/Driver.h created+43| ... | ... | @@ -0,0 +1,43 @@ |
| 1 | //===- lld/Common/Driver.h - Linker Driver Emulator -----------------------===// | |
| 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_DRIVER_H | |
| 11 | #define LLD_COMMON_DRIVER_H | |
| 12 | ||
| 13 | #include "llvm/ADT/ArrayRef.h" | |
| 14 | #include "llvm/Support/raw_ostream.h" | |
| 15 | ||
| 16 | namespace lld { | |
| 17 | namespace coff { | |
| 18 | bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly, | |
| 19 | llvm::raw_ostream &Diag = llvm::errs()); | |
| 20 | } | |
| 21 | ||
| 22 | namespace mingw { | |
| 23 | bool link(llvm::ArrayRef<const char *> Args, | |
| 24 | llvm::raw_ostream &Diag = llvm::errs()); | |
| 25 | } | |
| 26 | ||
| 27 | namespace elf { | |
| 28 | bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly, | |
| 29 | llvm::raw_ostream &Diag = llvm::errs()); | |
| 30 | } | |
| 31 | ||
| 32 | namespace mach_o { | |
| 33 | bool link(llvm::ArrayRef<const char *> Args, | |
| 34 | llvm::raw_ostream &Diag = llvm::errs()); | |
| 35 | } | |
| 36 | ||
| 37 | namespace wasm { | |
| 38 | bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly, | |
| 39 | llvm::raw_ostream &Diag = llvm::errs()); | |
| 40 | } | |
| 41 | } | |
| 42 | ||
| 43 | #endif |
deps/lld/include/lld/Common/ErrorHandler.h created+112| ... | ... | @@ -0,0 +1,112 @@ |
| 1 | //===- ErrorHandler.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 | // In LLD, we have three levels of errors: fatal, error or warn. | |
| 11 | // | |
| 12 | // Fatal makes the program exit immediately with an error message. | |
| 13 | // You shouldn't use it except for reporting a corrupted input file. | |
| 14 | // | |
| 15 | // Error prints out an error message and increment a global variable | |
| 16 | // ErrorCount to record the fact that we met an error condition. It does | |
| 17 | // not exit, so it is safe for a lld-as-a-library use case. It is generally | |
| 18 | // useful because it can report more than one error in a single run. | |
| 19 | // | |
| 20 | // Warn doesn't do anything but printing out a given message. | |
| 21 | // | |
| 22 | // It is not recommended to use llvm::outs() or llvm::errs() directly | |
| 23 | // in LLD because they are not thread-safe. The functions declared in | |
| 24 | // this file are mutually excluded, so you want to use them instead. | |
| 25 | // | |
| 26 | //===----------------------------------------------------------------------===// | |
| 27 | ||
| 28 | #ifndef LLD_COMMON_ERRORHANDLER_H | |
| 29 | #define LLD_COMMON_ERRORHANDLER_H | |
| 30 | ||
| 31 | #include "lld/Common/LLVM.h" | |
| 32 | ||
| 33 | #include "llvm/ADT/STLExtras.h" | |
| 34 | #include "llvm/Support/Error.h" | |
| 35 | #include "llvm/Support/FileOutputBuffer.h" | |
| 36 | ||
| 37 | namespace lld { | |
| 38 | ||
| 39 | class ErrorHandler { | |
| 40 | public: | |
| 41 | uint64_t ErrorCount = 0; | |
| 42 | uint64_t ErrorLimit = 20; | |
| 43 | StringRef ErrorLimitExceededMsg = "too many errors emitted, stopping now"; | |
| 44 | StringRef LogName = "lld"; | |
| 45 | llvm::raw_ostream *ErrorOS = &llvm::errs(); | |
| 46 | bool ColorDiagnostics = llvm::errs().has_colors(); | |
| 47 | bool ExitEarly = true; | |
| 48 | bool FatalWarnings = false; | |
| 49 | bool Verbose = false; | |
| 50 | ||
| 51 | void error(const Twine &Msg); | |
| 52 | LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg); | |
| 53 | void log(const Twine &Msg); | |
| 54 | void message(const Twine &Msg); | |
| 55 | void warn(const Twine &Msg); | |
| 56 | ||
| 57 | std::unique_ptr<llvm::FileOutputBuffer> OutputBuffer; | |
| 58 | ||
| 59 | private: | |
| 60 | void print(StringRef S, raw_ostream::Colors C); | |
| 61 | }; | |
| 62 | ||
| 63 | /// Returns the default error handler. | |
| 64 | ErrorHandler &errorHandler(); | |
| 65 | ||
| 66 | inline void error(const Twine &Msg) { errorHandler().error(Msg); } | |
| 67 | inline LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg) { | |
| 68 | errorHandler().fatal(Msg); | |
| 69 | } | |
| 70 | inline void log(const Twine &Msg) { errorHandler().log(Msg); } | |
| 71 | inline void message(const Twine &Msg) { errorHandler().message(Msg); } | |
| 72 | inline void warn(const Twine &Msg) { errorHandler().warn(Msg); } | |
| 73 | inline uint64_t errorCount() { return errorHandler().ErrorCount; } | |
| 74 | ||
| 75 | LLVM_ATTRIBUTE_NORETURN void exitLld(int Val); | |
| 76 | ||
| 77 | // check functions are convenient functions to strip errors | |
| 78 | // from error-or-value objects. | |
| 79 | template <class T> T check(ErrorOr<T> E) { | |
| 80 | if (auto EC = E.getError()) | |
| 81 | fatal(EC.message()); | |
| 82 | return std::move(*E); | |
| 83 | } | |
| 84 | ||
| 85 | template <class T> T check(Expected<T> E) { | |
| 86 | if (!E) | |
| 87 | fatal(llvm::toString(E.takeError())); | |
| 88 | return std::move(*E); | |
| 89 | } | |
| 90 | ||
| 91 | template <class T> | |
| 92 | T check2(ErrorOr<T> E, llvm::function_ref<std::string()> Prefix) { | |
| 93 | if (auto EC = E.getError()) | |
| 94 | fatal(Prefix() + ": " + EC.message()); | |
| 95 | return std::move(*E); | |
| 96 | } | |
| 97 | ||
| 98 | template <class T> | |
| 99 | T check2(Expected<T> E, llvm::function_ref<std::string()> Prefix) { | |
| 100 | if (!E) | |
| 101 | fatal(Prefix() + ": " + toString(E.takeError())); | |
| 102 | return std::move(*E); | |
| 103 | } | |
| 104 | ||
| 105 | inline std::string toString(const Twine &S) { return S.str(); } | |
| 106 | ||
| 107 | // To evaluate the second argument lazily, we use C macro. | |
| 108 | #define CHECK(E, S) check2(E, [&] { return toString(S); }) | |
| 109 | ||
| 110 | } // namespace lld | |
| 111 | ||
| 112 | #endif |
deps/lld/include/lld/Common/LLVM.h created+83| ... | ... | @@ -0,0 +1,83 @@ |
| 1 | //===--- LLVM.h - Import various common LLVM datatypes ----------*- C++ -*-===// | |
| 2 | // | |
| 3 | // The LLVM Compiler Infrastructure | |
| 4 | // | |
| 5 | // This file is distributed under the University of Illinois Open Source | |
| 6 | // License. See LICENSE.TXT for details. | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | // | |
| 10 | // This file forward declares and imports various common LLVM datatypes that | |
| 11 | // lld wants to use unqualified. | |
| 12 | // | |
| 13 | //===----------------------------------------------------------------------===// | |
| 14 | ||
| 15 | #ifndef LLD_COMMON_LLVM_H | |
| 16 | #define LLD_COMMON_LLVM_H | |
| 17 | ||
| 18 | // This should be the only #include, force #includes of all the others on | |
| 19 | // clients. | |
| 20 | #include "llvm/ADT/Hashing.h" | |
| 21 | #include "llvm/Support/Casting.h" | |
| 22 | #include <utility> | |
| 23 | ||
| 24 | namespace llvm { | |
| 25 | // ADT's. | |
| 26 | class Error; | |
| 27 | class StringRef; | |
| 28 | class Twine; | |
| 29 | class MemoryBuffer; | |
| 30 | class MemoryBufferRef; | |
| 31 | template<typename T> class ArrayRef; | |
| 32 | template<unsigned InternalLen> class SmallString; | |
| 33 | template<typename T, unsigned N> class SmallVector; | |
| 34 | template<typename T> class SmallVectorImpl; | |
| 35 | ||
| 36 | template<typename T> | |
| 37 | struct SaveAndRestore; | |
| 38 | ||
| 39 | template<typename T> | |
| 40 | class ErrorOr; | |
| 41 | ||
| 42 | template<typename T> | |
| 43 | class Expected; | |
| 44 | ||
| 45 | class raw_ostream; | |
| 46 | // TODO: DenseMap, ... | |
| 47 | } | |
| 48 | ||
| 49 | namespace lld { | |
| 50 | // Casting operators. | |
| 51 | using llvm::isa; | |
| 52 | using llvm::cast; | |
| 53 | using llvm::dyn_cast; | |
| 54 | using llvm::dyn_cast_or_null; | |
| 55 | using llvm::cast_or_null; | |
| 56 | ||
| 57 | // ADT's. | |
| 58 | using llvm::Error; | |
| 59 | using llvm::StringRef; | |
| 60 | using llvm::Twine; | |
| 61 | using llvm::MemoryBuffer; | |
| 62 | using llvm::MemoryBufferRef; | |
| 63 | using llvm::ArrayRef; | |
| 64 | using llvm::SmallString; | |
| 65 | using llvm::SmallVector; | |
| 66 | using llvm::SmallVectorImpl; | |
| 67 | using llvm::SaveAndRestore; | |
| 68 | using llvm::ErrorOr; | |
| 69 | using llvm::Expected; | |
| 70 | ||
| 71 | using llvm::raw_ostream; | |
| 72 | } // end namespace lld. | |
| 73 | ||
| 74 | namespace std { | |
| 75 | template <> struct hash<llvm::StringRef> { | |
| 76 | public: | |
| 77 | size_t operator()(const llvm::StringRef &s) const { | |
| 78 | return llvm::hash_value(s); | |
| 79 | } | |
| 80 | }; | |
| 81 | } | |
| 82 | ||
| 83 | #endif |
deps/lld/include/lld/Common/Memory.h created+60| ... | ... | @@ -0,0 +1,60 @@ |
| 1 | //===- Memory.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 defines arena allocators. | |
| 11 | // | |
| 12 | // Almost all large objects, such as files, sections or symbols, are | |
| 13 | // used for the entire lifetime of the linker once they are created. | |
| 14 | // This usage characteristic makes arena allocator an attractive choice | |
| 15 | // where the entire linker is one arena. With an arena, newly created | |
| 16 | // objects belong to the arena and freed all at once when everything is done. | |
| 17 | // Arena allocators are efficient and easy to understand. | |
| 18 | // Most objects are allocated using the arena allocators defined by this file. | |
| 19 | // | |
| 20 | //===----------------------------------------------------------------------===// | |
| 21 | ||
| 22 | #ifndef LLD_COMMON_MEMORY_H | |
| 23 | #define LLD_COMMON_MEMORY_H | |
| 24 | ||
| 25 | #include "llvm/Support/Allocator.h" | |
| 26 | #include "llvm/Support/StringSaver.h" | |
| 27 | #include <vector> | |
| 28 | ||
| 29 | namespace lld { | |
| 30 | ||
| 31 | // Use this arena if your object doesn't have a destructor. | |
| 32 | extern llvm::BumpPtrAllocator BAlloc; | |
| 33 | extern llvm::StringSaver Saver; | |
| 34 | ||
| 35 | void freeArena(); | |
| 36 | ||
| 37 | // These two classes are hack to keep track of all | |
| 38 | // SpecificBumpPtrAllocator instances. | |
| 39 | struct SpecificAllocBase { | |
| 40 | SpecificAllocBase() { Instances.push_back(this); } | |
| 41 | virtual ~SpecificAllocBase() = default; | |
| 42 | virtual void reset() = 0; | |
| 43 | static std::vector<SpecificAllocBase *> Instances; | |
| 44 | }; | |
| 45 | ||
| 46 | template <class T> struct SpecificAlloc : public SpecificAllocBase { | |
| 47 | void reset() override { Alloc.DestroyAll(); } | |
| 48 | llvm::SpecificBumpPtrAllocator<T> Alloc; | |
| 49 | }; | |
| 50 | ||
| 51 | // Use this arena if your object has a destructor. | |
| 52 | // Your destructor will be invoked from freeArena(). | |
| 53 | template <typename T, typename... U> T *make(U &&... Args) { | |
| 54 | static SpecificAlloc<T> Alloc; | |
| 55 | return new (Alloc.Alloc.Allocate()) T(std::forward<U>(Args)...); | |
| 56 | } | |
| 57 | ||
| 58 | } // namespace lld | |
| 59 | ||
| 60 | #endif |
deps/lld/include/lld/Common/Reproduce.h created+39| ... | ... | @@ -0,0 +1,39 @@ |
| 1 | //===- Reproduce.h - Utilities for creating reproducers ---------*- 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_REPRODUCE_H | |
| 11 | #define LLD_COMMON_REPRODUCE_H | |
| 12 | ||
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | #include "llvm/ADT/StringRef.h" | |
| 15 | #include "llvm/Support/Error.h" | |
| 16 | ||
| 17 | namespace llvm { | |
| 18 | namespace opt { class Arg; } | |
| 19 | } | |
| 20 | ||
| 21 | namespace lld { | |
| 22 | ||
| 23 | // Makes a given pathname an absolute path first, and then remove | |
| 24 | // beginning /. For example, "../foo.o" is converted to "home/john/foo.o", | |
| 25 | // assuming that the current directory is "/home/john/bar". | |
| 26 | std::string relativeToRoot(StringRef Path); | |
| 27 | ||
| 28 | // Quote a given string if it contains a space character. | |
| 29 | std::string quote(StringRef S); | |
| 30 | ||
| 31 | // Rewrite the given path if a file exists with that pathname, otherwise | |
| 32 | // returns the original path. | |
| 33 | std::string rewritePath(StringRef S); | |
| 34 | ||
| 35 | // Returns the string form of the given argument. | |
| 36 | std::string toString(const llvm::opt::Arg &Arg); | |
| 37 | } | |
| 38 | ||
| 39 | #endif |
deps/lld/include/lld/Common/Strings.h created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 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_STRINGS_H | |
| 11 | #define LLD_STRINGS_H | |
| 12 | ||
| 13 | #include "llvm/ADT/Optional.h" | |
| 14 | #include "llvm/ADT/StringRef.h" | |
| 15 | #include <string> | |
| 16 | ||
| 17 | namespace lld { | |
| 18 | // Returns a demangled C++ symbol name. If Name is not a mangled | |
| 19 | // name, it returns Optional::None. | |
| 20 | llvm::Optional<std::string> demangleItanium(llvm::StringRef Name); | |
| 21 | } | |
| 22 | ||
| 23 | #endif |
deps/lld/include/lld/Common/TargetOptionsCommandFlags.h created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | //===-- TargetOptionsCommandFlags.h ----------------------------*- C++ -*-===// | |
| 2 | // | |
| 3 | // The LLVM Compiler Infrastructure | |
| 4 | // | |
| 5 | // This file is distributed under the University of Illinois Open Source | |
| 6 | // License. See LICENSE.TXT for details. | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | // | |
| 10 | // Helper to create TargetOptions from command line flags. | |
| 11 | // | |
| 12 | //===----------------------------------------------------------------------===// | |
| 13 | ||
| 14 | #include "llvm/ADT/Optional.h" | |
| 15 | #include "llvm/Support/CodeGen.h" | |
| 16 | #include "llvm/Target/TargetOptions.h" | |
| 17 | ||
| 18 | namespace lld { | |
| 19 | llvm::TargetOptions InitTargetOptionsFromCodeGenFlags(); | |
| 20 | llvm::Optional<llvm::CodeModel::Model> GetCodeModelFromCMModel(); | |
| 21 | } |
deps/lld/include/lld/Common/Threads.h created+86| ... | ... | @@ -0,0 +1,86 @@ |
| 1 | //===- Threads.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 | // LLD supports threads to distribute workloads to multiple cores. Using | |
| 11 | // multicore is most effective when more than one core are idle. At the | |
| 12 | // last step of a build, it is often the case that a linker is the only | |
| 13 | // active process on a computer. So, we are naturally interested in using | |
| 14 | // threads wisely to reduce latency to deliver results to users. | |
| 15 | // | |
| 16 | // That said, we don't want to do "too clever" things using threads. | |
| 17 | // Complex multi-threaded algorithms are sometimes extremely hard to | |
| 18 | // reason about and can easily mess up the entire design. | |
| 19 | // | |
| 20 | // Fortunately, when a linker links large programs (when the link time is | |
| 21 | // most critical), it spends most of the time to work on massive number of | |
| 22 | // small pieces of data of the same kind, and there are opportunities for | |
| 23 | // large parallelism there. Here are examples: | |
| 24 | // | |
| 25 | // - We have hundreds of thousands of input sections that need to be | |
| 26 | // copied to a result file at the last step of link. Once we fix a file | |
| 27 | // layout, each section can be copied to its destination and its | |
| 28 | // relocations can be applied independently. | |
| 29 | // | |
| 30 | // - We have tens of millions of small strings when constructing a | |
| 31 | // mergeable string section. | |
| 32 | // | |
| 33 | // For the cases such as the former, we can just use parallelForEach | |
| 34 | // instead of std::for_each (or a plain for loop). Because tasks are | |
| 35 | // completely independent from each other, we can run them in parallel | |
| 36 | // without any coordination between them. That's very easy to understand | |
| 37 | // and reason about. | |
| 38 | // | |
| 39 | // For the cases such as the latter, we can use parallel algorithms to | |
| 40 | // deal with massive data. We have to write code for a tailored algorithm | |
| 41 | // for each problem, but the complexity of multi-threading is isolated in | |
| 42 | // a single pass and doesn't affect the linker's overall design. | |
| 43 | // | |
| 44 | // The above approach seems to be working fairly well. As an example, when | |
| 45 | // linking Chromium (output size 1.6 GB), using 4 cores reduces latency to | |
| 46 | // 75% compared to single core (from 12.66 seconds to 9.55 seconds) on my | |
| 47 | // Ivy Bridge Xeon 2.8 GHz machine. Using 40 cores reduces it to 63% (from | |
| 48 | // 12.66 seconds to 7.95 seconds). Because of the Amdahl's law, the | |
| 49 | // speedup is not linear, but as you add more cores, it gets faster. | |
| 50 | // | |
| 51 | // On a final note, if you are trying to optimize, keep the axiom "don't | |
| 52 | // guess, measure!" in mind. Some important passes of the linker are not | |
| 53 | // that slow. For example, resolving all symbols is not a very heavy pass, | |
| 54 | // although it would be very hard to parallelize it. You want to first | |
| 55 | // identify a slow pass and then optimize it. | |
| 56 | // | |
| 57 | //===----------------------------------------------------------------------===// | |
| 58 | ||
| 59 | #ifndef LLD_COMMON_THREADS_H | |
| 60 | #define LLD_COMMON_THREADS_H | |
| 61 | ||
| 62 | #include "llvm/Support/Parallel.h" | |
| 63 | #include <functional> | |
| 64 | ||
| 65 | namespace lld { | |
| 66 | ||
| 67 | extern bool ThreadsEnabled; | |
| 68 | ||
| 69 | template <typename R, class FuncTy> void parallelForEach(R &&Range, FuncTy Fn) { | |
| 70 | if (ThreadsEnabled) | |
| 71 | for_each(llvm::parallel::par, std::begin(Range), std::end(Range), Fn); | |
| 72 | else | |
| 73 | for_each(llvm::parallel::seq, std::begin(Range), std::end(Range), Fn); | |
| 74 | } | |
| 75 | ||
| 76 | inline void parallelForEachN(size_t Begin, size_t End, | |
| 77 | std::function<void(size_t)> Fn) { | |
| 78 | if (ThreadsEnabled) | |
| 79 | for_each_n(llvm::parallel::par, Begin, End, Fn); | |
| 80 | else | |
| 81 | for_each_n(llvm::parallel::seq, Begin, End, Fn); | |
| 82 | } | |
| 83 | ||
| 84 | } // namespace lld | |
| 85 | ||
| 86 | #endif |
deps/lld/include/lld/Common/Version.h created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | //===- lld/Common/Version.h - LLD Version Number ----------------*- C++ -*-===// | |
| 2 | // | |
| 3 | // The LLVM Compiler Infrastructure | |
| 4 | // | |
| 5 | // This file is distributed under the University of Illinois Open Source | |
| 6 | // License. See LICENSE.TXT for details. | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | // | |
| 10 | // Defines a version-related utility function. | |
| 11 | // | |
| 12 | //===----------------------------------------------------------------------===// | |
| 13 | ||
| 14 | #ifndef LLD_VERSION_H | |
| 15 | #define LLD_VERSION_H | |
| 16 | ||
| 17 | #include "lld/Common/Version.inc" | |
| 18 | #include "llvm/ADT/StringRef.h" | |
| 19 | ||
| 20 | namespace lld { | |
| 21 | /// \brief Retrieves a string representing the complete lld version. | |
| 22 | std::string getLLDVersion(); | |
| 23 | } | |
| 24 | ||
| 25 | #endif // LLD_VERSION_H |
deps/lld/include/lld/Common/Version.inc.in created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | #define LLD_VERSION @LLD_VERSION@ | |
| 2 | #define LLD_VERSION_STRING "@LLD_VERSION@" | |
| 3 | #define LLD_VERSION_MAJOR @LLD_VERSION_MAJOR@ | |
| 4 | #define LLD_VERSION_MINOR @LLD_VERSION_MINOR@ | |
| 5 | #define LLD_REVISION_STRING "@LLD_REVISION@" | |
| 6 | #define LLD_REPOSITORY_STRING "@LLD_REPOSITORY@" |
deps/lld/include/lld/Config/Version.h deleted-25| ... | ... | @@ -1,25 +0,0 @@ |
| 1 | //===- lld/Config/Version.h - LLD Version Number ----------------*- C++ -*-===// | |
| 2 | // | |
| 3 | // The LLVM Compiler Infrastructure | |
| 4 | // | |
| 5 | // This file is distributed under the University of Illinois Open Source | |
| 6 | // License. See LICENSE.TXT for details. | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | // | |
| 10 | // Defines a version-related utility function. | |
| 11 | // | |
| 12 | //===----------------------------------------------------------------------===// | |
| 13 | ||
| 14 | #ifndef LLD_VERSION_H | |
| 15 | #define LLD_VERSION_H | |
| 16 | ||
| 17 | #include "lld/Config/Version.inc" | |
| 18 | #include "llvm/ADT/StringRef.h" | |
| 19 | ||
| 20 | namespace lld { | |
| 21 | /// \brief Retrieves a string representing the complete lld version. | |
| 22 | std::string getLLDVersion(); | |
| 23 | } | |
| 24 | ||
| 25 | #endif // LLD_VERSION_H |
deps/lld/include/lld/Config/Version.inc.in deleted-6| ... | ... | @@ -1,6 +0,0 @@ |
| 1 | #define LLD_VERSION @LLD_VERSION@ | |
| 2 | #define LLD_VERSION_STRING "@LLD_VERSION@" | |
| 3 | #define LLD_VERSION_MAJOR @LLD_VERSION_MAJOR@ | |
| 4 | #define LLD_VERSION_MINOR @LLD_VERSION_MINOR@ | |
| 5 | #define LLD_REVISION_STRING "@LLD_REVISION@" | |
| 6 | #define LLD_REPOSITORY_STRING "@LLD_REPOSITORY@" |
deps/lld/include/lld/Core/Atom.h+1-1| ... | ... | @@ -10,7 +10,7 @@ |
| 10 | 10 | #ifndef LLD_CORE_ATOM_H |
| 11 | 11 | #define LLD_CORE_ATOM_H |
| 12 | 12 | |
| 13 | #include "lld/Core/LLVM.h" | |
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | 14 | #include "llvm/ADT/StringRef.h" |
| 15 | 15 | |
| 16 | 16 | namespace lld { |
deps/lld/include/lld/Core/DefinedAtom.h+1-1| ... | ... | @@ -10,9 +10,9 @@ |
| 10 | 10 | #ifndef LLD_CORE_DEFINED_ATOM_H |
| 11 | 11 | #define LLD_CORE_DEFINED_ATOM_H |
| 12 | 12 | |
| 13 | #include "lld/Common/LLVM.h" | |
| 13 | 14 | #include "lld/Core/Atom.h" |
| 14 | 15 | #include "lld/Core/Reference.h" |
| 15 | #include "lld/Core/LLVM.h" | |
| 16 | 16 | #include "llvm/Support/ErrorHandling.h" |
| 17 | 17 | |
| 18 | 18 | namespace lld { |
deps/lld/include/lld/Core/Error.h+1-1| ... | ... | @@ -14,7 +14,7 @@ |
| 14 | 14 | #ifndef LLD_CORE_ERROR_H |
| 15 | 15 | #define LLD_CORE_ERROR_H |
| 16 | 16 | |
| 17 | #include "lld/Core/LLVM.h" | |
| 17 | #include "lld/Common/LLVM.h" | |
| 18 | 18 | #include "llvm/ADT/Twine.h" |
| 19 | 19 | #include "llvm/Support/Error.h" |
| 20 | 20 | #include <system_error> |
deps/lld/include/lld/Core/LLVM.h deleted-83| ... | ... | @@ -1,83 +0,0 @@ |
| 1 | //===--- LLVM.h - Import various common LLVM datatypes ----------*- C++ -*-===// | |
| 2 | // | |
| 3 | // The LLVM Compiler Infrastructure | |
| 4 | // | |
| 5 | // This file is distributed under the University of Illinois Open Source | |
| 6 | // License. See LICENSE.TXT for details. | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | // | |
| 10 | // This file forward declares and imports various common LLVM datatypes that | |
| 11 | // lld wants to use unqualified. | |
| 12 | // | |
| 13 | //===----------------------------------------------------------------------===// | |
| 14 | ||
| 15 | #ifndef LLD_CORE_LLVM_H | |
| 16 | #define LLD_CORE_LLVM_H | |
| 17 | ||
| 18 | // This should be the only #include, force #includes of all the others on | |
| 19 | // clients. | |
| 20 | #include "llvm/ADT/Hashing.h" | |
| 21 | #include "llvm/Support/Casting.h" | |
| 22 | #include <utility> | |
| 23 | ||
| 24 | namespace llvm { | |
| 25 | // ADT's. | |
| 26 | class Error; | |
| 27 | class StringRef; | |
| 28 | class Twine; | |
| 29 | class MemoryBuffer; | |
| 30 | class MemoryBufferRef; | |
| 31 | template<typename T> class ArrayRef; | |
| 32 | template<unsigned InternalLen> class SmallString; | |
| 33 | template<typename T, unsigned N> class SmallVector; | |
| 34 | template<typename T> class SmallVectorImpl; | |
| 35 | ||
| 36 | template<typename T> | |
| 37 | struct SaveAndRestore; | |
| 38 | ||
| 39 | template<typename T> | |
| 40 | class ErrorOr; | |
| 41 | ||
| 42 | template<typename T> | |
| 43 | class Expected; | |
| 44 | ||
| 45 | class raw_ostream; | |
| 46 | // TODO: DenseMap, ... | |
| 47 | } | |
| 48 | ||
| 49 | namespace lld { | |
| 50 | // Casting operators. | |
| 51 | using llvm::isa; | |
| 52 | using llvm::cast; | |
| 53 | using llvm::dyn_cast; | |
| 54 | using llvm::dyn_cast_or_null; | |
| 55 | using llvm::cast_or_null; | |
| 56 | ||
| 57 | // ADT's. | |
| 58 | using llvm::Error; | |
| 59 | using llvm::StringRef; | |
| 60 | using llvm::Twine; | |
| 61 | using llvm::MemoryBuffer; | |
| 62 | using llvm::MemoryBufferRef; | |
| 63 | using llvm::ArrayRef; | |
| 64 | using llvm::SmallString; | |
| 65 | using llvm::SmallVector; | |
| 66 | using llvm::SmallVectorImpl; | |
| 67 | using llvm::SaveAndRestore; | |
| 68 | using llvm::ErrorOr; | |
| 69 | using llvm::Expected; | |
| 70 | ||
| 71 | using llvm::raw_ostream; | |
| 72 | } // end namespace lld. | |
| 73 | ||
| 74 | namespace std { | |
| 75 | template <> struct hash<llvm::StringRef> { | |
| 76 | public: | |
| 77 | size_t operator()(const llvm::StringRef &s) const { | |
| 78 | return llvm::hash_value(s); | |
| 79 | } | |
| 80 | }; | |
| 81 | } | |
| 82 | ||
| 83 | #endif |
deps/lld/include/lld/Core/LinkingContext.h+2-2| ... | ... | @@ -62,7 +62,7 @@ public: |
| 62 | 62 | /// of DefinedAtoms that should be marked live (along with all Atoms they |
| 63 | 63 | /// reference). Only Atoms with scope scopeLinkageUnit or scopeGlobal can |
| 64 | 64 | /// be kept live using this method. |
| 65 | const std::vector<StringRef> &deadStripRoots() const { | |
| 65 | ArrayRef<StringRef> deadStripRoots() const { | |
| 66 | 66 | return _deadStripRoots; |
| 67 | 67 | } |
| 68 | 68 | |
| ... | ... | @@ -106,7 +106,7 @@ public: |
| 106 | 106 | /// options which are used to configure LLVM's command line settings. |
| 107 | 107 | /// For instance the -debug-only XXX option can be used to dynamically |
| 108 | 108 | /// trace different parts of LLVM and lld. |
| 109 | const std::vector<const char *> &llvmOptions() const { return _llvmOptions; } | |
| 109 | ArrayRef<const char *> llvmOptions() const { return _llvmOptions; } | |
| 110 | 110 | |
| 111 | 111 | /// \name Methods used by Drivers to configure TargetInfo |
| 112 | 112 | /// @{ |
deps/lld/include/lld/Core/PassManager.h+1-1| ... | ... | @@ -10,7 +10,7 @@ |
| 10 | 10 | #ifndef LLD_CORE_PASS_MANAGER_H |
| 11 | 11 | #define LLD_CORE_PASS_MANAGER_H |
| 12 | 12 | |
| 13 | #include "lld/Core/LLVM.h" | |
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | 14 | #include "lld/Core/Pass.h" |
| 15 | 15 | #include "llvm/Support/Error.h" |
| 16 | 16 | #include <memory> |
deps/lld/include/lld/Core/Reader.h+1-1| ... | ... | @@ -10,7 +10,7 @@ |
| 10 | 10 | #ifndef LLD_CORE_READER_H |
| 11 | 11 | #define LLD_CORE_READER_H |
| 12 | 12 | |
| 13 | #include "lld/Core/LLVM.h" | |
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | 14 | #include "lld/Core/Reference.h" |
| 15 | 15 | #include "llvm/ADT/StringRef.h" |
| 16 | 16 | #include "llvm/BinaryFormat/Magic.h" |
deps/lld/include/lld/Core/Reproduce.h deleted-39| ... | ... | @@ -1,39 +0,0 @@ |
| 1 | //===- Reproduce.h - Utilities for creating reproducers ---------*- 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_CORE_REPRODUCE_H | |
| 11 | #define LLD_CORE_REPRODUCE_H | |
| 12 | ||
| 13 | #include "lld/Core/LLVM.h" | |
| 14 | #include "llvm/ADT/StringRef.h" | |
| 15 | #include "llvm/Support/Error.h" | |
| 16 | ||
| 17 | namespace llvm { | |
| 18 | namespace opt { class Arg; } | |
| 19 | } | |
| 20 | ||
| 21 | namespace lld { | |
| 22 | ||
| 23 | // Makes a given pathname an absolute path first, and then remove | |
| 24 | // beginning /. For example, "../foo.o" is converted to "home/john/foo.o", | |
| 25 | // assuming that the current directory is "/home/john/bar". | |
| 26 | std::string relativeToRoot(StringRef Path); | |
| 27 | ||
| 28 | // Quote a given string if it contains a space character. | |
| 29 | std::string quote(StringRef S); | |
| 30 | ||
| 31 | // Rewrite the given path if a file exists with that pathname, otherwise | |
| 32 | // returns the original path. | |
| 33 | std::string rewritePath(StringRef S); | |
| 34 | ||
| 35 | // Returns the string form of the given argument. | |
| 36 | std::string toString(llvm::opt::Arg *Arg); | |
| 37 | } | |
| 38 | ||
| 39 | #endif |
deps/lld/include/lld/Core/SymbolTable.h+1-1| ... | ... | @@ -10,7 +10,7 @@ |
| 10 | 10 | #ifndef LLD_CORE_SYMBOL_TABLE_H |
| 11 | 11 | #define LLD_CORE_SYMBOL_TABLE_H |
| 12 | 12 | |
| 13 | #include "lld/Core/LLVM.h" | |
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | 14 | #include "llvm/ADT/DenseSet.h" |
| 15 | 15 | #include "llvm/ADT/StringExtras.h" |
| 16 | 16 | #include <cstring> |
deps/lld/include/lld/Core/TargetOptionsCommandFlags.h deleted-20| ... | ... | @@ -1,20 +0,0 @@ |
| 1 | //===-- TargetOptionsCommandFlags.h ----------------------------*- C++ -*-===// | |
| 2 | // | |
| 3 | // The LLVM Compiler Infrastructure | |
| 4 | // | |
| 5 | // This file is distributed under the University of Illinois Open Source | |
| 6 | // License. See LICENSE.TXT for details. | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | // | |
| 10 | // Helper to create TargetOptions from command line flags. | |
| 11 | // | |
| 12 | //===----------------------------------------------------------------------===// | |
| 13 | ||
| 14 | #include "llvm/Support/CodeGen.h" | |
| 15 | #include "llvm/Target/TargetOptions.h" | |
| 16 | ||
| 17 | namespace lld { | |
| 18 | llvm::TargetOptions InitTargetOptionsFromCodeGenFlags(); | |
| 19 | llvm::CodeModel::Model GetCodeModelFromCMModel(); | |
| 20 | } |
deps/lld/include/lld/Core/Writer.h+1-1| ... | ... | @@ -10,7 +10,7 @@ |
| 10 | 10 | #ifndef LLD_CORE_WRITER_H |
| 11 | 11 | #define LLD_CORE_WRITER_H |
| 12 | 12 | |
| 13 | #include "lld/Core/LLVM.h" | |
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | 14 | #include "llvm/Support/Error.h" |
| 15 | 15 | #include <memory> |
| 16 | 16 | #include <vector> |
deps/lld/include/lld/Driver/Driver.h deleted-33| ... | ... | @@ -1,33 +0,0 @@ |
| 1 | //===- lld/Driver/Driver.h - Linker Driver Emulator -----------------------===// | |
| 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_DRIVER_DRIVER_H | |
| 11 | #define LLD_DRIVER_DRIVER_H | |
| 12 | ||
| 13 | #include "llvm/ADT/ArrayRef.h" | |
| 14 | #include "llvm/Support/raw_ostream.h" | |
| 15 | ||
| 16 | namespace lld { | |
| 17 | namespace coff { | |
| 18 | bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly, | |
| 19 | llvm::raw_ostream &Diag = llvm::errs()); | |
| 20 | } | |
| 21 | ||
| 22 | namespace elf { | |
| 23 | bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly, | |
| 24 | llvm::raw_ostream &Diag = llvm::errs()); | |
| 25 | } | |
| 26 | ||
| 27 | namespace mach_o { | |
| 28 | bool link(llvm::ArrayRef<const char *> Args, | |
| 29 | llvm::raw_ostream &Diag = llvm::errs()); | |
| 30 | } | |
| 31 | } | |
| 32 | ||
| 33 | #endif |
deps/lld/include/lld/ReaderWriter/YamlContext.h+2-1| ... | ... | @@ -10,7 +10,7 @@ |
| 10 | 10 | #ifndef LLD_READER_WRITER_YAML_CONTEXT_H |
| 11 | 11 | #define LLD_READER_WRITER_YAML_CONTEXT_H |
| 12 | 12 | |
| 13 | #include "lld/Core/LLVM.h" | |
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | 14 | #include <functional> |
| 15 | 15 | #include <memory> |
| 16 | 16 | #include <vector> |
| ... | ... | @@ -18,6 +18,7 @@ |
| 18 | 18 | namespace lld { |
| 19 | 19 | class File; |
| 20 | 20 | class LinkingContext; |
| 21 | class Registry; | |
| 21 | 22 | namespace mach_o { |
| 22 | 23 | namespace normalized { |
| 23 | 24 | struct NormalizedFile; |
deps/lld/lib/CMakeLists.txt-1| ... | ... | @@ -1,4 +1,3 @@ |
| 1 | add_subdirectory(Config) | |
| 2 | 1 | add_subdirectory(Core) |
| 3 | 2 | add_subdirectory(Driver) |
| 4 | 3 | add_subdirectory(ReaderWriter) |
deps/lld/lib/Config/CMakeLists.txt deleted-9| ... | ... | @@ -1,9 +0,0 @@ |
| 1 | add_lld_library(lldConfig | |
| 2 | Version.cpp | |
| 3 | ||
| 4 | ADDITIONAL_HEADER_DIRS | |
| 5 | ${LLD_INCLUDE_DIR}/lld/Config | |
| 6 | ||
| 7 | LINK_COMPONENTS | |
| 8 | Support | |
| 9 | ) |
deps/lld/lib/Config/Version.cpp deleted-43| ... | ... | @@ -1,43 +0,0 @@ |
| 1 | //===- lib/Config/Version.cpp - LLD Version Number ---------------*- C++-=====// | |
| 2 | // | |
| 3 | // The LLVM Compiler Infrastructure | |
| 4 | // | |
| 5 | // This file is distributed under the University of Illinois Open Source | |
| 6 | // License. See LICENSE.TXT for details. | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | // | |
| 10 | // This file defines several version-related utility functions for LLD. | |
| 11 | // | |
| 12 | //===----------------------------------------------------------------------===// | |
| 13 | ||
| 14 | #include "lld/Config/Version.h" | |
| 15 | ||
| 16 | using namespace llvm; | |
| 17 | ||
| 18 | // Returns an SVN repository path, which is usually "trunk". | |
| 19 | static std::string getRepositoryPath() { | |
| 20 | StringRef S = LLD_REPOSITORY_STRING; | |
| 21 | size_t Pos = S.find("lld/"); | |
| 22 | if (Pos != StringRef::npos) | |
| 23 | return S.substr(Pos + 4); | |
| 24 | return S; | |
| 25 | } | |
| 26 | ||
| 27 | // Returns an SVN repository name, e.g., " (trunk 284614)" | |
| 28 | // or an empty string if no repository info is available. | |
| 29 | static std::string getRepository() { | |
| 30 | std::string Repo = getRepositoryPath(); | |
| 31 | std::string Rev = LLD_REVISION_STRING; | |
| 32 | ||
| 33 | if (Repo.empty() && Rev.empty()) | |
| 34 | return ""; | |
| 35 | if (!Repo.empty() && !Rev.empty()) | |
| 36 | return " (" + Repo + " " + Rev + ")"; | |
| 37 | return " (" + Repo + Rev + ")"; | |
| 38 | } | |
| 39 | ||
| 40 | // Returns a version string, e.g., "LLD 4.0 (lld/trunk 284614)". | |
| 41 | std::string lld::getLLDVersion() { | |
| 42 | return "LLD " + std::string(LLD_VERSION_STRING) + getRepository(); | |
| 43 | } |
deps/lld/lib/Core/CMakeLists.txt-2| ... | ... | @@ -8,10 +8,8 @@ add_lld_library(lldCore |
| 8 | 8 | File.cpp |
| 9 | 9 | LinkingContext.cpp |
| 10 | 10 | Reader.cpp |
| 11 | Reproduce.cpp | |
| 12 | 11 | Resolver.cpp |
| 13 | 12 | SymbolTable.cpp |
| 14 | TargetOptionsCommandFlags.cpp | |
| 15 | 13 | Writer.cpp |
| 16 | 14 | |
| 17 | 15 | ADDITIONAL_HEADER_DIRS |
deps/lld/lib/Core/Reproduce.cpp deleted-66| ... | ... | @@ -1,66 +0,0 @@ |
| 1 | //===- Reproduce.cpp - Utilities for creating reproducers -----------------===// | |
| 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/Core/Reproduce.h" | |
| 11 | #include "llvm/Option/Arg.h" | |
| 12 | #include "llvm/Support/Error.h" | |
| 13 | #include "llvm/Support/FileSystem.h" | |
| 14 | #include "llvm/Support/Path.h" | |
| 15 | ||
| 16 | using namespace lld; | |
| 17 | using namespace llvm; | |
| 18 | using namespace llvm::sys; | |
| 19 | ||
| 20 | // Makes a given pathname an absolute path first, and then remove | |
| 21 | // beginning /. For example, "../foo.o" is converted to "home/john/foo.o", | |
| 22 | // assuming that the current directory is "/home/john/bar". | |
| 23 | // Returned string is a forward slash separated path even on Windows to avoid | |
| 24 | // a mess with backslash-as-escape and backslash-as-path-separator. | |
| 25 | std::string lld::relativeToRoot(StringRef Path) { | |
| 26 | SmallString<128> Abs = Path; | |
| 27 | if (fs::make_absolute(Abs)) | |
| 28 | return Path; | |
| 29 | path::remove_dots(Abs, /*remove_dot_dot=*/true); | |
| 30 | ||
| 31 | // This is Windows specific. root_name() returns a drive letter | |
| 32 | // (e.g. "c:") or a UNC name (//net). We want to keep it as part | |
| 33 | // of the result. | |
| 34 | SmallString<128> Res; | |
| 35 | StringRef Root = path::root_name(Abs); | |
| 36 | if (Root.endswith(":")) | |
| 37 | Res = Root.drop_back(); | |
| 38 | else if (Root.startswith("//")) | |
| 39 | Res = Root.substr(2); | |
| 40 | ||
| 41 | path::append(Res, path::relative_path(Abs)); | |
| 42 | return path::convert_to_slash(Res); | |
| 43 | } | |
| 44 | ||
| 45 | // Quote a given string if it contains a space character. | |
| 46 | std::string lld::quote(StringRef S) { | |
| 47 | if (S.find(' ') == StringRef::npos) | |
| 48 | return S; | |
| 49 | return ("\"" + S + "\"").str(); | |
| 50 | } | |
| 51 | ||
| 52 | std::string lld::rewritePath(StringRef S) { | |
| 53 | if (fs::exists(S)) | |
| 54 | return relativeToRoot(S); | |
| 55 | return S; | |
| 56 | } | |
| 57 | ||
| 58 | std::string lld::toString(opt::Arg *Arg) { | |
| 59 | std::string K = Arg->getSpelling(); | |
| 60 | if (Arg->getNumValues() == 0) | |
| 61 | return K; | |
| 62 | std::string V = quote(Arg->getValue()); | |
| 63 | if (Arg->getOption().getRenderStyle() == opt::Option::RenderJoinedStyle) | |
| 64 | return K + V; | |
| 65 | return K + " " + V; | |
| 66 | } |
deps/lld/lib/Core/Resolver.cpp+3-3| ... | ... | @@ -7,13 +7,13 @@ |
| 7 | 7 | // |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | #include "lld/Core/Atom.h" | |
| 10 | #include "lld/Core/Resolver.h" | |
| 11 | #include "lld/Common/LLVM.h" | |
| 11 | 12 | #include "lld/Core/ArchiveLibraryFile.h" |
| 13 | #include "lld/Core/Atom.h" | |
| 12 | 14 | #include "lld/Core/File.h" |
| 13 | 15 | #include "lld/Core/Instrumentation.h" |
| 14 | #include "lld/Core/LLVM.h" | |
| 15 | 16 | #include "lld/Core/LinkingContext.h" |
| 16 | #include "lld/Core/Resolver.h" | |
| 17 | 17 | #include "lld/Core/SharedLibraryFile.h" |
| 18 | 18 | #include "lld/Core/SymbolTable.h" |
| 19 | 19 | #include "lld/Core/UndefinedAtom.h" |
deps/lld/lib/Core/SymbolTable.cpp+1-1| ... | ... | @@ -8,11 +8,11 @@ |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | 10 | #include "lld/Core/SymbolTable.h" |
| 11 | #include "lld/Common/LLVM.h" | |
| 11 | 12 | #include "lld/Core/AbsoluteAtom.h" |
| 12 | 13 | #include "lld/Core/Atom.h" |
| 13 | 14 | #include "lld/Core/DefinedAtom.h" |
| 14 | 15 | #include "lld/Core/File.h" |
| 15 | #include "lld/Core/LLVM.h" | |
| 16 | 16 | #include "lld/Core/LinkingContext.h" |
| 17 | 17 | #include "lld/Core/Resolver.h" |
| 18 | 18 | #include "lld/Core/SharedLibraryAtom.h" |
deps/lld/lib/Core/TargetOptionsCommandFlags.cpp deleted-32| ... | ... | @@ -1,32 +0,0 @@ |
| 1 | //===-- TargetOptionsCommandFlags.cpp ---------------------------*- 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 exists as a place for global variables defined in LLVM's | |
| 11 | // CodeGen/CommandFlags.h. By putting the resulting object file in | |
| 12 | // an archive and linking with it, the definitions will automatically be | |
| 13 | // included when needed and skipped when already present. | |
| 14 | // | |
| 15 | //===----------------------------------------------------------------------===// | |
| 16 | ||
| 17 | #include "lld/Core/TargetOptionsCommandFlags.h" | |
| 18 | ||
| 19 | #include "llvm/CodeGen/CommandFlags.h" | |
| 20 | #include "llvm/Target/TargetOptions.h" | |
| 21 | ||
| 22 | // Define an externally visible version of | |
| 23 | // InitTargetOptionsFromCodeGenFlags, so that its functionality can be | |
| 24 | // used without having to include llvm/CodeGen/CommandFlags.h, which | |
| 25 | // would lead to multiple definitions of the command line flags. | |
| 26 | llvm::TargetOptions lld::InitTargetOptionsFromCodeGenFlags() { | |
| 27 | return ::InitTargetOptionsFromCodeGenFlags(); | |
| 28 | } | |
| 29 | ||
| 30 | llvm::CodeModel::Model lld::GetCodeModelFromCMModel() { | |
| 31 | return CMModel; | |
| 32 | } |
deps/lld/lib/Driver/CMakeLists.txt+1-3| ... | ... | @@ -9,14 +9,12 @@ add_lld_library(lldDriver |
| 9 | 9 | ${LLD_INCLUDE_DIR}/lld/Driver |
| 10 | 10 | |
| 11 | 11 | LINK_COMPONENTS |
| 12 | Object | |
| 13 | 12 | Option |
| 14 | 13 | Support |
| 15 | 14 | |
| 16 | 15 | LINK_LIBS |
| 17 | lldConfig | |
| 18 | lldMachO | |
| 19 | 16 | lldCore |
| 17 | lldMachO | |
| 20 | 18 | lldReaderWriter |
| 21 | 19 | lldYAML |
| 22 | 20 | ) |
deps/lld/lib/Driver/DarwinLdDriver.cpp+3-3| ... | ... | @@ -13,11 +13,11 @@ |
| 13 | 13 | /// |
| 14 | 14 | //===----------------------------------------------------------------------===// |
| 15 | 15 | |
| 16 | #include "lld/Common/LLVM.h" | |
| 16 | 17 | #include "lld/Core/ArchiveLibraryFile.h" |
| 17 | 18 | #include "lld/Core/Error.h" |
| 18 | 19 | #include "lld/Core/File.h" |
| 19 | 20 | #include "lld/Core/Instrumentation.h" |
| 20 | #include "lld/Core/LLVM.h" | |
| 21 | 21 | #include "lld/Core/LinkingContext.h" |
| 22 | 22 | #include "lld/Core/Node.h" |
| 23 | 23 | #include "lld/Core/PassManager.h" |
| ... | ... | @@ -74,7 +74,7 @@ enum { |
| 74 | 74 | #undef PREFIX |
| 75 | 75 | |
| 76 | 76 | // Create table mapping all options defined in DarwinLdOptions.td |
| 77 | static const llvm::opt::OptTable::Info infoTable[] = { | |
| 77 | static const llvm::opt::OptTable::Info InfoTable[] = { | |
| 78 | 78 | #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ |
| 79 | 79 | HELPTEXT, METAVAR, VALUES) \ |
| 80 | 80 | {PREFIX, NAME, HELPTEXT, \ |
| ... | ... | @@ -88,7 +88,7 @@ static const llvm::opt::OptTable::Info infoTable[] = { |
| 88 | 88 | // Create OptTable class for parsing actual command line arguments |
| 89 | 89 | class DarwinLdOptTable : public llvm::opt::OptTable { |
| 90 | 90 | public: |
| 91 | DarwinLdOptTable() : OptTable(infoTable) {} | |
| 91 | DarwinLdOptTable() : OptTable(InfoTable) {} | |
| 92 | 92 | }; |
| 93 | 93 | |
| 94 | 94 | static std::vector<std::unique_ptr<File>> |
deps/lld/lib/ReaderWriter/CMakeLists.txt-1| ... | ... | @@ -17,5 +17,4 @@ add_lld_library(lldReaderWriter |
| 17 | 17 | |
| 18 | 18 | LINK_LIBS |
| 19 | 19 | lldCore |
| 20 | lldYAML | |
| 21 | 20 | ) |
deps/lld/lib/ReaderWriter/FileArchive.cpp+1-1| ... | ... | @@ -7,9 +7,9 @@ |
| 7 | 7 | // |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | #include "lld/Common/LLVM.h" | |
| 10 | 11 | #include "lld/Core/ArchiveLibraryFile.h" |
| 11 | 12 | #include "lld/Core/File.h" |
| 12 | #include "lld/Core/LLVM.h" | |
| 13 | 13 | #include "lld/Core/Reader.h" |
| 14 | 14 | #include "llvm/ADT/STLExtras.h" |
| 15 | 15 | #include "llvm/ADT/StringRef.h" |
deps/lld/lib/ReaderWriter/MachO/ArchHandler.h+1-1| ... | ... | @@ -13,7 +13,7 @@ |
| 13 | 13 | #include "Atoms.h" |
| 14 | 14 | #include "File.h" |
| 15 | 15 | #include "MachONormalizedFile.h" |
| 16 | #include "lld/Core/LLVM.h" | |
| 16 | #include "lld/Common/LLVM.h" | |
| 17 | 17 | #include "lld/Core/Error.h" |
| 18 | 18 | #include "lld/Core/Reference.h" |
| 19 | 19 | #include "lld/Core/Simple.h" |
deps/lld/lib/ReaderWriter/MachO/CMakeLists.txt+1-1| ... | ... | @@ -21,9 +21,9 @@ add_lld_library(lldMachO |
| 21 | 21 | |
| 22 | 22 | LINK_COMPONENTS |
| 23 | 23 | DebugInfoDWARF |
| 24 | Demangle | |
| 24 | 25 | Object |
| 25 | 26 | Support |
| 26 | Demangle | |
| 27 | 27 | |
| 28 | 28 | LINK_LIBS |
| 29 | 29 | lldCore |
deps/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp+1-1| ... | ... | @@ -17,9 +17,9 @@ |
| 17 | 17 | #include "File.h" |
| 18 | 18 | #include "MachONormalizedFileBinaryUtils.h" |
| 19 | 19 | #include "MachOPasses.h" |
| 20 | #include "lld/Common/LLVM.h" | |
| 20 | 21 | #include "lld/Core/DefinedAtom.h" |
| 21 | 22 | #include "lld/Core/File.h" |
| 22 | #include "lld/Core/LLVM.h" | |
| 23 | 23 | #include "lld/Core/Reference.h" |
| 24 | 24 | #include "lld/Core/Simple.h" |
| 25 | 25 | #include "llvm/ADT/DenseMap.h" |
deps/lld/lib/ReaderWriter/MachO/FlatNamespaceFile.h+2| ... | ... | @@ -10,7 +10,9 @@ |
| 10 | 10 | #ifndef LLD_READER_WRITER_MACHO_FLAT_NAMESPACE_FILE_H |
| 11 | 11 | #define LLD_READER_WRITER_MACHO_FLAT_NAMESPACE_FILE_H |
| 12 | 12 | |
| 13 | #include "Atoms.h" | |
| 13 | 14 | #include "lld/Core/SharedLibraryFile.h" |
| 15 | #include "lld/ReaderWriter/MachOLinkingContext.h" | |
| 14 | 16 | #include "llvm/Support/Debug.h" |
| 15 | 17 | |
| 16 | 18 | namespace lld { |
deps/lld/lib/ReaderWriter/MachO/GOTPass.cpp+1-1| ... | ... | @@ -35,9 +35,9 @@ |
| 35 | 35 | #include "ArchHandler.h" |
| 36 | 36 | #include "File.h" |
| 37 | 37 | #include "MachOPasses.h" |
| 38 | #include "lld/Common/LLVM.h" | |
| 38 | 39 | #include "lld/Core/DefinedAtom.h" |
| 39 | 40 | #include "lld/Core/File.h" |
| 40 | #include "lld/Core/LLVM.h" | |
| 41 | 41 | #include "lld/Core/Reference.h" |
| 42 | 42 | #include "lld/Core/Simple.h" |
| 43 | 43 | #include "llvm/ADT/DenseMap.h" |
deps/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp+1-1| ... | ... | @@ -14,11 +14,11 @@ |
| 14 | 14 | #include "MachONormalizedFile.h" |
| 15 | 15 | #include "MachOPasses.h" |
| 16 | 16 | #include "SectCreateFile.h" |
| 17 | #include "lld/Common/Driver.h" | |
| 17 | 18 | #include "lld/Core/ArchiveLibraryFile.h" |
| 18 | 19 | #include "lld/Core/PassManager.h" |
| 19 | 20 | #include "lld/Core/Reader.h" |
| 20 | 21 | #include "lld/Core/Writer.h" |
| 21 | #include "lld/Driver/Driver.h" | |
| 22 | 22 | #include "llvm/ADT/STLExtras.h" |
| 23 | 23 | #include "llvm/ADT/StringExtras.h" |
| 24 | 24 | #include "llvm/ADT/Triple.h" |
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h+1-10| ... | ... | @@ -43,8 +43,8 @@ |
| 43 | 43 | #define LLD_READER_WRITER_MACHO_NORMALIZE_FILE_H |
| 44 | 44 | |
| 45 | 45 | #include "DebugInfo.h" |
| 46 | #include "lld/Common/LLVM.h" | |
| 46 | 47 | #include "lld/Core/Error.h" |
| 47 | #include "lld/Core/LLVM.h" | |
| 48 | 48 | #include "lld/ReaderWriter/MachOLinkingContext.h" |
| 49 | 49 | #include "llvm/ADT/SmallString.h" |
| 50 | 50 | #include "llvm/ADT/StringRef.h" |
| ... | ... | @@ -124,15 +124,6 @@ struct Section { |
| 124 | 124 | ArrayRef<uint8_t> content; |
| 125 | 125 | Relocations relocations; |
| 126 | 126 | IndirectSymbols indirectSymbols; |
| 127 | ||
| 128 | #ifndef NDEBUG | |
| 129 | raw_ostream& operator<<(raw_ostream &OS) const { | |
| 130 | dump(OS); | |
| 131 | return OS; | |
| 132 | } | |
| 133 | ||
| 134 | void dump(raw_ostream &OS = llvm::dbgs()) const; | |
| 135 | #endif | |
| 136 | 127 | }; |
| 137 | 128 | |
| 138 | 129 |
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp+5-2| ... | ... | @@ -24,8 +24,8 @@ |
| 24 | 24 | #include "ArchHandler.h" |
| 25 | 25 | #include "MachONormalizedFile.h" |
| 26 | 26 | #include "MachONormalizedFileBinaryUtils.h" |
| 27 | #include "lld/Common/LLVM.h" | |
| 27 | 28 | #include "lld/Core/Error.h" |
| 28 | #include "lld/Core/LLVM.h" | |
| 29 | 29 | #include "lld/Core/SharedLibraryFile.h" |
| 30 | 30 | #include "llvm/ADT/STLExtras.h" |
| 31 | 31 | #include "llvm/ADT/SmallString.h" |
| ... | ... | @@ -511,7 +511,8 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, |
| 511 | 511 | const uint8_t *trieStart = reinterpret_cast<const uint8_t *>( |
| 512 | 512 | start + read32(&dyldInfo->export_off, isBig)); |
| 513 | 513 | ArrayRef<uint8_t> trie(trieStart, read32(&dyldInfo->export_size, isBig)); |
| 514 | for (const ExportEntry &trieExport : MachOObjectFile::exports(trie)) { | |
| 514 | Error Err = Error::success(); | |
| 515 | for (const ExportEntry &trieExport : MachOObjectFile::exports(Err, trie)) { | |
| 515 | 516 | Export normExport; |
| 516 | 517 | normExport.name = trieExport.name().copy(f->ownedAllocations); |
| 517 | 518 | normExport.offset = trieExport.address(); |
| ... | ... | @@ -522,6 +523,8 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, |
| 522 | 523 | normExport.otherName = trieExport.otherName().copy(f->ownedAllocations); |
| 523 | 524 | f->exportInfo.push_back(normExport); |
| 524 | 525 | } |
| 526 | if (Err) | |
| 527 | return std::move(Err); | |
| 525 | 528 | } |
| 526 | 529 | } |
| 527 | 530 |
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h+1-1| ... | ... | @@ -11,8 +11,8 @@ |
| 11 | 11 | #define LLD_READER_WRITER_MACHO_NORMALIZED_FILE_BINARY_UTILS_H |
| 12 | 12 | |
| 13 | 13 | #include "MachONormalizedFile.h" |
| 14 | #include "lld/Common/LLVM.h" | |
| 14 | 15 | #include "lld/Core/Error.h" |
| 15 | #include "lld/Core/LLVM.h" | |
| 16 | 16 | #include "llvm/ADT/StringRef.h" |
| 17 | 17 | #include "llvm/BinaryFormat/MachO.h" |
| 18 | 18 | #include "llvm/Support/Casting.h" |
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp+6-5| ... | ... | @@ -23,8 +23,8 @@ |
| 23 | 23 | |
| 24 | 24 | #include "MachONormalizedFile.h" |
| 25 | 25 | #include "MachONormalizedFileBinaryUtils.h" |
| 26 | #include "lld/Common/LLVM.h" | |
| 26 | 27 | #include "lld/Core/Error.h" |
| 27 | #include "lld/Core/LLVM.h" | |
| 28 | 28 | #include "llvm/ADT/SmallString.h" |
| 29 | 29 | #include "llvm/ADT/SmallVector.h" |
| 30 | 30 | #include "llvm/ADT/StringRef.h" |
| ... | ... | @@ -1523,10 +1523,10 @@ llvm::Error MachOFileLayout::writeBinary(StringRef path) { |
| 1523 | 1523 | unsigned flags = 0; |
| 1524 | 1524 | if (_file.fileType != llvm::MachO::MH_OBJECT) |
| 1525 | 1525 | flags = llvm::FileOutputBuffer::F_executable; |
| 1526 | ErrorOr<std::unique_ptr<llvm::FileOutputBuffer>> fobOrErr = | |
| 1526 | Expected<std::unique_ptr<llvm::FileOutputBuffer>> fobOrErr = | |
| 1527 | 1527 | llvm::FileOutputBuffer::create(path, size(), flags); |
| 1528 | if (std::error_code ec = fobOrErr.getError()) | |
| 1529 | return llvm::errorCodeToError(ec); | |
| 1528 | if (Error E = fobOrErr.takeError()) | |
| 1529 | return E; | |
| 1530 | 1530 | std::unique_ptr<llvm::FileOutputBuffer> &fob = *fobOrErr; |
| 1531 | 1531 | // Write content. |
| 1532 | 1532 | _buffer = fob->getBufferStart(); |
| ... | ... | @@ -1535,7 +1535,8 @@ llvm::Error MachOFileLayout::writeBinary(StringRef path) { |
| 1535 | 1535 | return ec; |
| 1536 | 1536 | writeSectionContent(); |
| 1537 | 1537 | writeLinkEditContent(); |
| 1538 | fob->commit(); | |
| 1538 | if (Error E = fob->commit()) | |
| 1539 | return E; | |
| 1539 | 1540 | |
| 1540 | 1541 | return llvm::Error::success(); |
| 1541 | 1542 | } |
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp+1-1| ... | ... | @@ -24,8 +24,8 @@ |
| 24 | 24 | #include "DebugInfo.h" |
| 25 | 25 | #include "MachONormalizedFile.h" |
| 26 | 26 | #include "MachONormalizedFileBinaryUtils.h" |
| 27 | #include "lld/Common/LLVM.h" | |
| 27 | 28 | #include "lld/Core/Error.h" |
| 28 | #include "lld/Core/LLVM.h" | |
| 29 | 29 | #include "llvm/ADT/StringRef.h" |
| 30 | 30 | #include "llvm/ADT/StringSwitch.h" |
| 31 | 31 | #include "llvm/BinaryFormat/MachO.h" |
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp+1-1| ... | ... | @@ -25,8 +25,8 @@ |
| 25 | 25 | #include "File.h" |
| 26 | 26 | #include "MachONormalizedFile.h" |
| 27 | 27 | #include "MachONormalizedFileBinaryUtils.h" |
| 28 | #include "lld/Common/LLVM.h" | |
| 28 | 29 | #include "lld/Core/Error.h" |
| 29 | #include "lld/Core/LLVM.h" | |
| 30 | 30 | #include "llvm/BinaryFormat/Dwarf.h" |
| 31 | 31 | #include "llvm/BinaryFormat/MachO.h" |
| 32 | 32 | #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" |
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp+4-4| ... | ... | @@ -16,8 +16,8 @@ |
| 16 | 16 | /// +------------+ +------+ |
| 17 | 17 | |
| 18 | 18 | #include "MachONormalizedFile.h" |
| 19 | #include "lld/Common/LLVM.h" | |
| 19 | 20 | #include "lld/Core/Error.h" |
| 20 | #include "lld/Core/LLVM.h" | |
| 21 | 21 | #include "lld/ReaderWriter/YamlContext.h" |
| 22 | 22 | #include "llvm/ADT/SmallString.h" |
| 23 | 23 | #include "llvm/ADT/StringRef.h" |
| ... | ... | @@ -257,7 +257,7 @@ template <> struct ScalarTraits<SectionAlignment> { |
| 257 | 257 | return StringRef(); // returning empty string means success |
| 258 | 258 | } |
| 259 | 259 | |
| 260 | static bool mustQuote(StringRef) { return false; } | |
| 260 | static QuotingType mustQuote(StringRef) { return QuotingType::None; } | |
| 261 | 261 | }; |
| 262 | 262 | |
| 263 | 263 | template <> |
| ... | ... | @@ -522,7 +522,7 @@ struct ScalarTraits<VMProtect> { |
| 522 | 522 | // Return the empty string on success, |
| 523 | 523 | return StringRef(); |
| 524 | 524 | } |
| 525 | static bool mustQuote(StringRef) { return false; } | |
| 525 | static QuotingType mustQuote(StringRef) { return QuotingType::None; } | |
| 526 | 526 | }; |
| 527 | 527 | |
| 528 | 528 | |
| ... | ... | @@ -706,7 +706,7 @@ struct ScalarTraits<PackedVersion> { |
| 706 | 706 | // Return the empty string on success, |
| 707 | 707 | return StringRef(); |
| 708 | 708 | } |
| 709 | static bool mustQuote(StringRef) { return false; } | |
| 709 | static QuotingType mustQuote(StringRef) { return QuotingType::None; } | |
| 710 | 710 | }; |
| 711 | 711 | |
| 712 | 712 | template <> |
deps/lld/lib/ReaderWriter/MachO/ObjCPass.cpp+1-1| ... | ... | @@ -13,9 +13,9 @@ |
| 13 | 13 | #include "File.h" |
| 14 | 14 | #include "MachONormalizedFileBinaryUtils.h" |
| 15 | 15 | #include "MachOPasses.h" |
| 16 | #include "lld/Common/LLVM.h" | |
| 16 | 17 | #include "lld/Core/DefinedAtom.h" |
| 17 | 18 | #include "lld/Core/File.h" |
| 18 | #include "lld/Core/LLVM.h" | |
| 19 | 19 | #include "lld/Core/Reference.h" |
| 20 | 20 | #include "lld/Core/Simple.h" |
| 21 | 21 | #include "lld/ReaderWriter/MachOLinkingContext.h" |
deps/lld/lib/ReaderWriter/MachO/ShimPass.cpp+1-1| ... | ... | @@ -26,9 +26,9 @@ |
| 26 | 26 | #include "ArchHandler.h" |
| 27 | 27 | #include "File.h" |
| 28 | 28 | #include "MachOPasses.h" |
| 29 | #include "lld/Common/LLVM.h" | |
| 29 | 30 | #include "lld/Core/DefinedAtom.h" |
| 30 | 31 | #include "lld/Core/File.h" |
| 31 | #include "lld/Core/LLVM.h" | |
| 32 | 32 | #include "lld/Core/Reference.h" |
| 33 | 33 | #include "lld/Core/Simple.h" |
| 34 | 34 | #include "lld/ReaderWriter/MachOLinkingContext.h" |
deps/lld/lib/ReaderWriter/MachO/StubsPass.cpp+1-1| ... | ... | @@ -17,9 +17,9 @@ |
| 17 | 17 | #include "ArchHandler.h" |
| 18 | 18 | #include "File.h" |
| 19 | 19 | #include "MachOPasses.h" |
| 20 | #include "lld/Common/LLVM.h" | |
| 20 | 21 | #include "lld/Core/DefinedAtom.h" |
| 21 | 22 | #include "lld/Core/File.h" |
| 22 | #include "lld/Core/LLVM.h" | |
| 23 | 23 | #include "lld/Core/Reference.h" |
| 24 | 24 | #include "lld/Core/Simple.h" |
| 25 | 25 | #include "lld/ReaderWriter/MachOLinkingContext.h" |
deps/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp+3-3| ... | ... | @@ -280,7 +280,7 @@ template <> struct ScalarTraits<RefKind> { |
| 280 | 280 | return StringRef("unknown reference kind"); |
| 281 | 281 | } |
| 282 | 282 | |
| 283 | static bool mustQuote(StringRef) { return false; } | |
| 283 | static QuotingType mustQuote(StringRef) { return QuotingType::None; } | |
| 284 | 284 | }; |
| 285 | 285 | |
| 286 | 286 | template <> struct ScalarEnumerationTraits<lld::File::Kind> { |
| ... | ... | @@ -495,7 +495,7 @@ template <> struct ScalarTraits<lld::DefinedAtom::Alignment> { |
| 495 | 495 | return StringRef(); // returning empty string means success |
| 496 | 496 | } |
| 497 | 497 | |
| 498 | static bool mustQuote(StringRef) { return false; } | |
| 498 | static QuotingType mustQuote(StringRef) { return QuotingType::None; } | |
| 499 | 499 | }; |
| 500 | 500 | |
| 501 | 501 | template <> struct ScalarEnumerationTraits<FileKinds> { |
| ... | ... | @@ -552,7 +552,7 @@ template <> struct ScalarTraits<ImplicitHex8> { |
| 552 | 552 | return StringRef(); // returning empty string means success |
| 553 | 553 | } |
| 554 | 554 | |
| 555 | static bool mustQuote(StringRef) { return false; } | |
| 555 | static QuotingType mustQuote(StringRef) { return QuotingType::None; } | |
| 556 | 556 | }; |
| 557 | 557 | |
| 558 | 558 | // YAML conversion for std::vector<const lld::File*> |
deps/lld/test/CMakeLists.txt+10-5| ... | ... | @@ -17,18 +17,23 @@ llvm_canonicalize_cmake_booleans( |
| 17 | 17 | HAVE_LIBZ) |
| 18 | 18 | |
| 19 | 19 | configure_lit_site_cfg( |
| 20 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in | |
| 21 | ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg) | |
| 20 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in | |
| 21 | ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py | |
| 22 | MAIN_CONFIG | |
| 23 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py | |
| 24 | ) | |
| 22 | 25 | configure_lit_site_cfg( |
| 23 | ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in | |
| 24 | ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg | |
| 26 | ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in | |
| 27 | ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py | |
| 28 | MAIN_CONFIG | |
| 29 | ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py | |
| 25 | 30 | ) |
| 26 | 31 | |
| 27 | 32 | set(LLD_TEST_DEPS lld) |
| 28 | 33 | if (NOT LLD_BUILT_STANDALONE) |
| 29 | 34 | list(APPEND LLD_TEST_DEPS |
| 30 | 35 | FileCheck count not llvm-ar llvm-as llvm-dis llvm-dwarfdump llvm-nm |
| 31 | llc llvm-config llvm-objdump llvm-readobj yaml2obj obj2yaml | |
| 36 | llc llvm-config llvm-objdump llvm-readelf llvm-readobj yaml2obj obj2yaml | |
| 32 | 37 | llvm-mc llvm-lib llvm-pdbutil opt |
| 33 | 38 | ) |
| 34 | 39 | endif() |
deps/lld/test/COFF/Inputs/alpha.ll created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | define void @_DllMainCRTStartup() { | |
| 2 | entry: | |
| 3 | ret void | |
| 4 | } | |
| 5 | ||
| 6 | define dllexport void @f() local_unnamed_addr { | |
| 7 | entry: | |
| 8 | ret void | |
| 9 | } |
deps/lld/test/COFF/Inputs/beta.ll created+7| ... | ... | @@ -0,0 +1,7 @@ |
| 1 | declare dllimport void @f() local_unnamed_addr | |
| 2 | ||
| 3 | define void @g() local_unnamed_addr { | |
| 4 | entry: | |
| 5 | tail call void @f() | |
| 6 | ret void | |
| 7 | } |
deps/lld/test/COFF/Inputs/except_handler3.lib created| Binary files /dev/null and b/deps/lld/test/COFF/Inputs/except_handler3.lib differ |
deps/lld/test/COFF/Inputs/far-arm-thumb-abs20.s created+2| ... | ... | @@ -0,0 +1,2 @@ |
| 1 | .global too_far20 | |
| 2 | too_far20 = 0x501004 |
deps/lld/test/COFF/Inputs/gamma.ll created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | ||
| 2 | declare void @f() local_unnamed_addr | |
| 3 | ||
| 4 | define void @__imp_f() local_unnamed_addr { | |
| 5 | entry: | |
| 6 | ret void | |
| 7 | } | |
| 8 | ||
| 9 | define void @mainCRTStartup() local_unnamed_addr { | |
| 10 | entry: | |
| 11 | tail call void @f() | |
| 12 | ret void | |
| 13 | } | |
| 14 |
deps/lld/test/COFF/Inputs/library2-arm64.lib created| Binary files /dev/null and b/deps/lld/test/COFF/Inputs/library2-arm64.lib differ |
deps/lld/test/COFF/Inputs/library2.def created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | LIBRARY library2 | |
| 2 | EXPORTS | |
| 3 | function2 |
deps/lld/test/COFF/Inputs/locally-imported-def.s created+4| ... | ... | @@ -0,0 +1,4 @@ |
| 1 | .text | |
| 2 | .globl f | |
| 3 | f: | |
| 4 | 	ret |
deps/lld/test/COFF/Inputs/locally-imported-imp.s created+2| ... | ... | @@ -0,0 +1,2 @@ |
| 1 | .text | |
| 2 | 	call	__imp_f |
deps/lld/test/COFF/Inputs/lto-cache.ll created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" | |
| 2 | target triple = "x86_64-pc-windows-msvc" | |
| 3 | ||
| 4 | define i32 @main() { | |
| 5 | entry: | |
| 6 | call void (...) @globalfunc() | |
| 7 | ret i32 0 | |
| 8 | } | |
| 9 | ||
| 10 | declare void @globalfunc(...) |
deps/lld/test/COFF/Inputs/pdb-globals.yaml created+593| ... | ... | @@ -0,0 +1,593 @@ |
| 1 | # // YAML Generated from the following source code: | |
| 2 | # // Compile with clang-cl /Z7 /GS- /c t.obj pdb-globals.cpp | |
| 3 | # | |
| 4 | # void *__purecall = 0; | |
| 5 | # | |
| 6 | # struct HelloPoint { | |
| 7 | # int X = 3; | |
| 8 | # int Y = 4; | |
| 9 | # int Z = 5; | |
| 10 | # }; | |
| 11 | # | |
| 12 | # // S_LPROCREF | |
| 13 | # static int LocalFunc() { return 42; } | |
| 14 | # | |
| 15 | # // S_PROCREF | |
| 16 | # int GlobalFunc() { return 43; } | |
| 17 | # | |
| 18 | # // S_LDATA32 | |
| 19 | # const int ConstantVar = 17; | |
| 20 | # | |
| 21 | # // S_GDATA32 | |
| 22 | # const int *GlobalVar = &ConstantVar; | |
| 23 | # | |
| 24 | # // S_CONSTANT | |
| 25 | # constexpr int ConstexprVar = 18; | |
| 26 | # | |
| 27 | # // S_UDT | |
| 28 | # typedef HelloPoint HelloPointTypedef; | |
| 29 | # | |
| 30 | # int main(int argc, char **argv) { | |
| 31 | # HelloPointTypedef P; | |
| 32 | # int N = P.X + P.Y + P.Z; | |
| 33 | # N += LocalFunc() + GlobalFunc(); | |
| 34 | # N += *GlobalVar; | |
| 35 | # N += ConstexprVar; | |
| 36 | # } | |
| 37 | ||
| 38 | ||
| 39 | --- !COFF | |
| 40 | header: | |
| 41 | Machine: IMAGE_FILE_MACHINE_I386 | |
| 42 | Characteristics: [ ] | |
| 43 | sections: | |
| 44 | - Name: .text | |
| 45 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 46 | Alignment: 16 | |
| 47 | SectionData: 5589E5B82B0000005DC3660F1F4400005589E583EC208B450C8B4D088D55F4894DEC89D18945E8E8000000008B4DF4034DF8034DFC894DF08945E4E8000000008945E0E80000000031C98B55E001C20355F08955F0A1000000008B000345F08945F08B45F083C0128945F089C883C4205DC366666666662E0F1F8400000000005589E5B82A0000005DC3 | |
| 48 | Relocations: | |
| 49 | - VirtualAddress: 40 | |
| 50 | SymbolName: '??0HelloPoint@@QAE@XZ' | |
| 51 | Type: IMAGE_REL_I386_REL32 | |
| 52 | - VirtualAddress: 60 | |
| 53 | SymbolName: '?LocalFunc@@YAHXZ' | |
| 54 | Type: IMAGE_REL_I386_REL32 | |
| 55 | - VirtualAddress: 68 | |
| 56 | SymbolName: '?GlobalFunc@@YAHXZ' | |
| 57 | Type: IMAGE_REL_I386_REL32 | |
| 58 | - VirtualAddress: 86 | |
| 59 | SymbolName: '?GlobalVar@@3PBHB' | |
| 60 | Type: IMAGE_REL_I386_DIR32 | |
| 61 | - Name: .data | |
| 62 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | |
| 63 | Alignment: 4 | |
| 64 | SectionData: '00000000' | |
| 65 | Relocations: | |
| 66 | - VirtualAddress: 0 | |
| 67 | SymbolName: _ConstantVar | |
| 68 | Type: IMAGE_REL_I386_DIR32 | |
| 69 | - Name: .bss | |
| 70 | Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | |
| 71 | Alignment: 4 | |
| 72 | SectionData: '' | |
| 73 | - Name: .text | |
| 74 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 75 | Alignment: 16 | |
| 76 | SectionData: 5589E550894DFC8B4DFCC70103000000C7410404000000C741080500000089C883C4045DC3 | |
| 77 | - Name: .rdata | |
| 78 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | |
| 79 | Alignment: 4 | |
| 80 | SectionData: '11000000' | |
| 81 | - Name: .drectve | |
| 82 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | |
| 83 | Alignment: 1 | |
| 84 | SectionData: 202F44454641554C544C49423A6C6962636D742E6C6962202F44454641554C544C49423A6F6C646E616D65732E6C6962 | |
| 85 | - Name: '.debug$S' | |
| 86 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 87 | Alignment: 4 | |
| 88 | SectionData: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F100000036000000300047110000000000000000000000000A00000000000000000000000210000000000000000000476C6F62616C46756E630002004F110000F20000002000000000000000000000000A0000000000000001000000140000000000000010000000F1000000B60000002A00471100000000000000000000000062000000000000000000000006100000000000000000006D61696E000D003E1174000000010061726763001200451116000000080000001F000000000053000D003E11031000000100617267760012004511160000000C0000001F000000000053000A003E1107100000000050001200451116000000F4FFFFFF1F000000000053000A003E117400000000004E001200451116000000F0FFFFFF1F0000000000530002004F110000F200000050000000000000000000000062000000000000000700000044000000000000001E0000000F0000001F0000001C000000200000002800000021000000450000002200000052000000230000005B00000024000000F1000000350000002F0046110000000000000000000000000A00000000000000000000000F100000000000000000004C6F63616C46756E630002004F11000000F20000002000000000000000000000000A000000000000000100000014000000000000000D000000F10000004B00000017000D11030400000000000000005F5F7075726563616C6C0016000D1111100000000000000000476C6F62616C5661720018000C1110100000000000000000436F6E7374616E745661720000F10000002D000000180008110710000048656C6C6F506F696E745479706564656600110008110910000048656C6C6F506F696E7400000000F4000000080000000100000000000000F30000003800000000643A5C7372635C6C6C766D2D6D6F6E6F5C6C6C645C746573745C636F66665C696E707574735C7064622D676C6F62616C732E6370700000 | |
| 89 | Subsections: | |
| 90 | - !Symbols | |
| 91 | Records: | |
| 92 | - Kind: S_COMPILE3 | |
| 93 | Compile3Sym: | |
| 94 | Flags: [ ] | |
| 95 | Machine: Pentium3 | |
| 96 | FrontendMajor: 6 | |
| 97 | FrontendMinor: 0 | |
| 98 | FrontendBuild: 0 | |
| 99 | FrontendQFE: 0 | |
| 100 | BackendMajor: 6000 | |
| 101 | BackendMinor: 0 | |
| 102 | BackendBuild: 0 | |
| 103 | BackendQFE: 0 | |
| 104 | Version: 'clang version 6.0.0 ' | |
| 105 | - Kind: S_GPROC32_ID | |
| 106 | ProcSym: | |
| 107 | CodeSize: 10 | |
| 108 | DbgStart: 0 | |
| 109 | DbgEnd: 0 | |
| 110 | FunctionType: 4098 | |
| 111 | Flags: [ ] | |
| 112 | DisplayName: GlobalFunc | |
| 113 | - Kind: S_PROC_ID_END | |
| 114 | ScopeEndSym: | |
| 115 | - Kind: S_GPROC32_ID | |
| 116 | ProcSym: | |
| 117 | CodeSize: 98 | |
| 118 | DbgStart: 0 | |
| 119 | DbgEnd: 0 | |
| 120 | FunctionType: 4102 | |
| 121 | Flags: [ ] | |
| 122 | DisplayName: main | |
| 123 | - Kind: S_LOCAL | |
| 124 | LocalSym: | |
| 125 | Type: 116 | |
| 126 | Flags: [ IsParameter ] | |
| 127 | VarName: argc | |
| 128 | - Kind: S_DEFRANGE_REGISTER_REL | |
| 129 | DefRangeRegisterRelSym: | |
| 130 | - Kind: S_LOCAL | |
| 131 | LocalSym: | |
| 132 | Type: 4099 | |
| 133 | Flags: [ IsParameter ] | |
| 134 | VarName: argv | |
| 135 | - Kind: S_DEFRANGE_REGISTER_REL | |
| 136 | DefRangeRegisterRelSym: | |
| 137 | - Kind: S_LOCAL | |
| 138 | LocalSym: | |
| 139 | Type: 4103 | |
| 140 | Flags: [ ] | |
| 141 | VarName: P | |
| 142 | - Kind: S_DEFRANGE_REGISTER_REL | |
| 143 | DefRangeRegisterRelSym: | |
| 144 | - Kind: S_LOCAL | |
| 145 | LocalSym: | |
| 146 | Type: 116 | |
| 147 | Flags: [ ] | |
| 148 | VarName: N | |
| 149 | - Kind: S_DEFRANGE_REGISTER_REL | |
| 150 | DefRangeRegisterRelSym: | |
| 151 | - Kind: S_PROC_ID_END | |
| 152 | ScopeEndSym: | |
| 153 | - Kind: S_LPROC32_ID | |
| 154 | ProcSym: | |
| 155 | CodeSize: 10 | |
| 156 | DbgStart: 0 | |
| 157 | DbgEnd: 0 | |
| 158 | FunctionType: 4111 | |
| 159 | Flags: [ ] | |
| 160 | DisplayName: LocalFunc | |
| 161 | - Kind: S_PROC_ID_END | |
| 162 | ScopeEndSym: | |
| 163 | - Kind: S_GDATA32 | |
| 164 | DataSym: | |
| 165 | Type: 1027 | |
| 166 | DisplayName: __purecall | |
| 167 | - Kind: S_GDATA32 | |
| 168 | DataSym: | |
| 169 | Type: 4113 | |
| 170 | DisplayName: GlobalVar | |
| 171 | - Kind: S_LDATA32 | |
| 172 | DataSym: | |
| 173 | Type: 4112 | |
| 174 | DisplayName: ConstantVar | |
| 175 | - Kind: S_UDT | |
| 176 | UDTSym: | |
| 177 | Type: 4103 | |
| 178 | UDTName: HelloPointTypedef | |
| 179 | - Kind: S_UDT | |
| 180 | UDTSym: | |
| 181 | Type: 4105 | |
| 182 | UDTName: HelloPoint | |
| 183 | - !FileChecksums | |
| 184 | Checksums: | |
| 185 | - FileName: 'd:\src\llvm-mono\lld\test\coff\inputs\pdb-globals.cpp' | |
| 186 | Kind: None | |
| 187 | Checksum: '' | |
| 188 | - !StringTable | |
| 189 | Strings: | |
| 190 | - 'd:\src\llvm-mono\lld\test\coff\inputs\pdb-globals.cpp' | |
| 191 | - '' | |
| 192 | Relocations: | |
| 193 | - VirtualAddress: 100 | |
| 194 | SymbolName: '?GlobalFunc@@YAHXZ' | |
| 195 | Type: IMAGE_REL_I386_SECREL | |
| 196 | - VirtualAddress: 104 | |
| 197 | SymbolName: '?GlobalFunc@@YAHXZ' | |
| 198 | Type: IMAGE_REL_I386_SECTION | |
| 199 | - VirtualAddress: 132 | |
| 200 | SymbolName: '?GlobalFunc@@YAHXZ' | |
| 201 | Type: IMAGE_REL_I386_SECREL | |
| 202 | - VirtualAddress: 136 | |
| 203 | SymbolName: '?GlobalFunc@@YAHXZ' | |
| 204 | Type: IMAGE_REL_I386_SECTION | |
| 205 | - VirtualAddress: 204 | |
| 206 | SymbolName: _main | |
| 207 | Type: IMAGE_REL_I386_SECREL | |
| 208 | - VirtualAddress: 208 | |
| 209 | SymbolName: _main | |
| 210 | Type: IMAGE_REL_I386_SECTION | |
| 211 | - VirtualAddress: 243 | |
| 212 | SymbolName: .text | |
| 213 | Type: IMAGE_REL_I386_SECREL | |
| 214 | - VirtualAddress: 247 | |
| 215 | SymbolName: .text | |
| 216 | Type: IMAGE_REL_I386_SECTION | |
| 217 | - VirtualAddress: 278 | |
| 218 | SymbolName: .text | |
| 219 | Type: IMAGE_REL_I386_SECREL | |
| 220 | - VirtualAddress: 282 | |
| 221 | SymbolName: .text | |
| 222 | Type: IMAGE_REL_I386_SECTION | |
| 223 | - VirtualAddress: 310 | |
| 224 | SymbolName: .text | |
| 225 | Type: IMAGE_REL_I386_SECREL | |
| 226 | - VirtualAddress: 314 | |
| 227 | SymbolName: .text | |
| 228 | Type: IMAGE_REL_I386_SECTION | |
| 229 | - VirtualAddress: 342 | |
| 230 | SymbolName: .text | |
| 231 | Type: IMAGE_REL_I386_SECREL | |
| 232 | - VirtualAddress: 346 | |
| 233 | SymbolName: .text | |
| 234 | Type: IMAGE_REL_I386_SECTION | |
| 235 | - VirtualAddress: 364 | |
| 236 | SymbolName: _main | |
| 237 | Type: IMAGE_REL_I386_SECREL | |
| 238 | - VirtualAddress: 368 | |
| 239 | SymbolName: _main | |
| 240 | Type: IMAGE_REL_I386_SECTION | |
| 241 | - VirtualAddress: 484 | |
| 242 | SymbolName: '?LocalFunc@@YAHXZ' | |
| 243 | Type: IMAGE_REL_I386_SECREL | |
| 244 | - VirtualAddress: 488 | |
| 245 | SymbolName: '?LocalFunc@@YAHXZ' | |
| 246 | Type: IMAGE_REL_I386_SECTION | |
| 247 | - VirtualAddress: 516 | |
| 248 | SymbolName: '?LocalFunc@@YAHXZ' | |
| 249 | Type: IMAGE_REL_I386_SECREL | |
| 250 | - VirtualAddress: 520 | |
| 251 | SymbolName: '?LocalFunc@@YAHXZ' | |
| 252 | Type: IMAGE_REL_I386_SECTION | |
| 253 | - VirtualAddress: 564 | |
| 254 | SymbolName: '?__purecall@@3PAXA' | |
| 255 | Type: IMAGE_REL_I386_SECREL | |
| 256 | - VirtualAddress: 568 | |
| 257 | SymbolName: '?__purecall@@3PAXA' | |
| 258 | Type: IMAGE_REL_I386_SECTION | |
| 259 | - VirtualAddress: 589 | |
| 260 | SymbolName: '?GlobalVar@@3PBHB' | |
| 261 | Type: IMAGE_REL_I386_SECREL | |
| 262 | - VirtualAddress: 593 | |
| 263 | SymbolName: '?GlobalVar@@3PBHB' | |
| 264 | Type: IMAGE_REL_I386_SECTION | |
| 265 | - VirtualAddress: 613 | |
| 266 | SymbolName: _ConstantVar | |
| 267 | Type: IMAGE_REL_I386_SECREL | |
| 268 | - VirtualAddress: 617 | |
| 269 | SymbolName: _ConstantVar | |
| 270 | Type: IMAGE_REL_I386_SECTION | |
| 271 | - Name: '.debug$T' | |
| 272 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 273 | Alignment: 4 | |
| 274 | SectionData: 0400000006000112000000000E000810740000000000000000100000160001160000000001100000476C6F62616C46756E6300F10A000210700400000A8000000E0001120200000074000000031000000E0008107400000000000200041000001200011600000000051000006D61696E00F3F2F13200051500008002000000000000000000000000000048656C6C6F506F696E74002E3F415548656C6C6F506F696E74404000F2F1260003120D15030074000000000058000D15030074000000040059000D1503007400000008005A0032000515030000020810000000000000000000000C0048656C6C6F506F696E74002E3F415548656C6C6F506F696E74404000F2F13E00051600000000643A5C7372635C6C6C766D2D6D6F6E6F5C6C6C645C746573745C636F66665C696E707574735C7064622D676C6F62616C732E63707000F2F10E000616091000000A100000060000000A000210071000000A8000001A00091003000000071000000C1000000B000000001000000000000016000216071000000D10000048656C6C6F506F696E7400F11600011600000000011000004C6F63616C46756E6300F2F10A000110740000000100F2F10A000210101000000A800000 | |
| 275 | Types: | |
| 276 | - Kind: LF_ARGLIST | |
| 277 | ArgList: | |
| 278 | ArgIndices: [ ] | |
| 279 | - Kind: LF_PROCEDURE | |
| 280 | Procedure: | |
| 281 | ReturnType: 116 | |
| 282 | CallConv: NearC | |
| 283 | Options: [ None ] | |
| 284 | ParameterCount: 0 | |
| 285 | ArgumentList: 4096 | |
| 286 | - Kind: LF_FUNC_ID | |
| 287 | FuncId: | |
| 288 | ParentScope: 0 | |
| 289 | FunctionType: 4097 | |
| 290 | Name: GlobalFunc | |
| 291 | - Kind: LF_POINTER | |
| 292 | Pointer: | |
| 293 | ReferentType: 1136 | |
| 294 | Attrs: 32778 | |
| 295 | - Kind: LF_ARGLIST | |
| 296 | ArgList: | |
| 297 | ArgIndices: [ 116, 4099 ] | |
| 298 | - Kind: LF_PROCEDURE | |
| 299 | Procedure: | |
| 300 | ReturnType: 116 | |
| 301 | CallConv: NearC | |
| 302 | Options: [ None ] | |
| 303 | ParameterCount: 2 | |
| 304 | ArgumentList: 4100 | |
| 305 | - Kind: LF_FUNC_ID | |
| 306 | FuncId: | |
| 307 | ParentScope: 0 | |
| 308 | FunctionType: 4101 | |
| 309 | Name: main | |
| 310 | - Kind: LF_STRUCTURE | |
| 311 | Class: | |
| 312 | MemberCount: 0 | |
| 313 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 314 | FieldList: 0 | |
| 315 | Name: HelloPoint | |
| 316 | UniqueName: '.?AUHelloPoint@@' | |
| 317 | DerivationList: 0 | |
| 318 | VTableShape: 0 | |
| 319 | Size: 0 | |
| 320 | - Kind: LF_FIELDLIST | |
| 321 | FieldList: | |
| 322 | - Kind: LF_MEMBER | |
| 323 | DataMember: | |
| 324 | Attrs: 3 | |
| 325 | Type: 116 | |
| 326 | FieldOffset: 0 | |
| 327 | Name: X | |
| 328 | - Kind: LF_MEMBER | |
| 329 | DataMember: | |
| 330 | Attrs: 3 | |
| 331 | Type: 116 | |
| 332 | FieldOffset: 4 | |
| 333 | Name: Y | |
| 334 | - Kind: LF_MEMBER | |
| 335 | DataMember: | |
| 336 | Attrs: 3 | |
| 337 | Type: 116 | |
| 338 | FieldOffset: 8 | |
| 339 | Name: Z | |
| 340 | - Kind: LF_STRUCTURE | |
| 341 | Class: | |
| 342 | MemberCount: 3 | |
| 343 | Options: [ None, HasUniqueName ] | |
| 344 | FieldList: 4104 | |
| 345 | Name: HelloPoint | |
| 346 | UniqueName: '.?AUHelloPoint@@' | |
| 347 | DerivationList: 0 | |
| 348 | VTableShape: 0 | |
| 349 | Size: 12 | |
| 350 | - Kind: LF_STRING_ID | |
| 351 | StringId: | |
| 352 | Id: 0 | |
| 353 | String: 'd:\src\llvm-mono\lld\test\coff\inputs\pdb-globals.cpp' | |
| 354 | - Kind: LF_UDT_SRC_LINE | |
| 355 | UdtSourceLine: | |
| 356 | UDT: 4105 | |
| 357 | SourceFile: 4106 | |
| 358 | LineNumber: 6 | |
| 359 | - Kind: LF_POINTER | |
| 360 | Pointer: | |
| 361 | ReferentType: 4103 | |
| 362 | Attrs: 32778 | |
| 363 | - Kind: LF_MFUNCTION | |
| 364 | MemberFunction: | |
| 365 | ReturnType: 3 | |
| 366 | ClassType: 4103 | |
| 367 | ThisType: 4108 | |
| 368 | CallConv: ThisCall | |
| 369 | Options: [ None ] | |
| 370 | ParameterCount: 0 | |
| 371 | ArgumentList: 4096 | |
| 372 | ThisPointerAdjustment: 0 | |
| 373 | - Kind: LF_MFUNC_ID | |
| 374 | MemberFuncId: | |
| 375 | ClassType: 4103 | |
| 376 | FunctionType: 4109 | |
| 377 | Name: HelloPoint | |
| 378 | - Kind: LF_FUNC_ID | |
| 379 | FuncId: | |
| 380 | ParentScope: 0 | |
| 381 | FunctionType: 4097 | |
| 382 | Name: LocalFunc | |
| 383 | - Kind: LF_MODIFIER | |
| 384 | Modifier: | |
| 385 | ModifiedType: 116 | |
| 386 | Modifiers: [ None, Const ] | |
| 387 | - Kind: LF_POINTER | |
| 388 | Pointer: | |
| 389 | ReferentType: 4112 | |
| 390 | Attrs: 32778 | |
| 391 | - Name: '.debug$S' | |
| 392 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 393 | Alignment: 4 | |
| 394 | SectionData: 04000000F1000000650000003C0047110000000000000000000000002500000000000000000000000E1000000000000000000048656C6C6F506F696E743A3A48656C6C6F506F696E74000D003E110C100000010074686973001200451116000000FCFFFFFF0A00000000001B0002004F11000000F20000004000000000000000000000002500000000000000050000003400000000000000060000000A00000007000000100000000800000017000000090000001E00000006000000 | |
| 395 | Subsections: | |
| 396 | - !Symbols | |
| 397 | Records: | |
| 398 | - Kind: S_GPROC32_ID | |
| 399 | ProcSym: | |
| 400 | CodeSize: 37 | |
| 401 | DbgStart: 0 | |
| 402 | DbgEnd: 0 | |
| 403 | FunctionType: 4110 | |
| 404 | Flags: [ ] | |
| 405 | DisplayName: 'HelloPoint::HelloPoint' | |
| 406 | - Kind: S_LOCAL | |
| 407 | LocalSym: | |
| 408 | Type: 4108 | |
| 409 | Flags: [ IsParameter ] | |
| 410 | VarName: this | |
| 411 | - Kind: S_DEFRANGE_REGISTER_REL | |
| 412 | DefRangeRegisterRelSym: | |
| 413 | - Kind: S_PROC_ID_END | |
| 414 | ScopeEndSym: | |
| 415 | Relocations: | |
| 416 | - VirtualAddress: 44 | |
| 417 | SymbolName: '??0HelloPoint@@QAE@XZ' | |
| 418 | Type: IMAGE_REL_I386_SECREL | |
| 419 | - VirtualAddress: 48 | |
| 420 | SymbolName: '??0HelloPoint@@QAE@XZ' | |
| 421 | Type: IMAGE_REL_I386_SECTION | |
| 422 | - VirtualAddress: 101 | |
| 423 | SymbolName: .text | |
| 424 | Type: IMAGE_REL_I386_SECREL | |
| 425 | - VirtualAddress: 105 | |
| 426 | SymbolName: .text | |
| 427 | Type: IMAGE_REL_I386_SECTION | |
| 428 | - VirtualAddress: 124 | |
| 429 | SymbolName: '??0HelloPoint@@QAE@XZ' | |
| 430 | Type: IMAGE_REL_I386_SECREL | |
| 431 | - VirtualAddress: 128 | |
| 432 | SymbolName: '??0HelloPoint@@QAE@XZ' | |
| 433 | Type: IMAGE_REL_I386_SECTION | |
| 434 | symbols: | |
| 435 | - Name: .text | |
| 436 | Value: 0 | |
| 437 | SectionNumber: 1 | |
| 438 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 439 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 440 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 441 | SectionDefinition: | |
| 442 | Length: 138 | |
| 443 | NumberOfRelocations: 4 | |
| 444 | NumberOfLinenumbers: 0 | |
| 445 | CheckSum: 3215092891 | |
| 446 | Number: 1 | |
| 447 | - Name: .data | |
| 448 | Value: 0 | |
| 449 | SectionNumber: 2 | |
| 450 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 451 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 452 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 453 | SectionDefinition: | |
| 454 | Length: 4 | |
| 455 | NumberOfRelocations: 1 | |
| 456 | NumberOfLinenumbers: 0 | |
| 457 | CheckSum: 0 | |
| 458 | Number: 2 | |
| 459 | - Name: .bss | |
| 460 | Value: 0 | |
| 461 | SectionNumber: 3 | |
| 462 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 463 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 464 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 465 | SectionDefinition: | |
| 466 | Length: 4 | |
| 467 | NumberOfRelocations: 0 | |
| 468 | NumberOfLinenumbers: 0 | |
| 469 | CheckSum: 0 | |
| 470 | Number: 3 | |
| 471 | - Name: .text | |
| 472 | Value: 0 | |
| 473 | SectionNumber: 4 | |
| 474 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 475 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 476 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 477 | SectionDefinition: | |
| 478 | Length: 37 | |
| 479 | NumberOfRelocations: 0 | |
| 480 | NumberOfLinenumbers: 0 | |
| 481 | CheckSum: 77530982 | |
| 482 | Number: 4 | |
| 483 | Selection: IMAGE_COMDAT_SELECT_ANY | |
| 484 | - Name: '??0HelloPoint@@QAE@XZ' | |
| 485 | Value: 0 | |
| 486 | SectionNumber: 4 | |
| 487 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 488 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 489 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 490 | - Name: .rdata | |
| 491 | Value: 0 | |
| 492 | SectionNumber: 5 | |
| 493 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 494 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 495 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 496 | SectionDefinition: | |
| 497 | Length: 4 | |
| 498 | NumberOfRelocations: 0 | |
| 499 | NumberOfLinenumbers: 0 | |
| 500 | CheckSum: 3903140090 | |
| 501 | Number: 5 | |
| 502 | - Name: .drectve | |
| 503 | Value: 0 | |
| 504 | SectionNumber: 6 | |
| 505 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 506 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 507 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 508 | SectionDefinition: | |
| 509 | Length: 48 | |
| 510 | NumberOfRelocations: 0 | |
| 511 | NumberOfLinenumbers: 0 | |
| 512 | CheckSum: 149686238 | |
| 513 | Number: 6 | |
| 514 | - Name: '.debug$S' | |
| 515 | Value: 0 | |
| 516 | SectionNumber: 7 | |
| 517 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 518 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 519 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 520 | SectionDefinition: | |
| 521 | Length: 768 | |
| 522 | NumberOfRelocations: 26 | |
| 523 | NumberOfLinenumbers: 0 | |
| 524 | CheckSum: 2940884584 | |
| 525 | Number: 7 | |
| 526 | - Name: '.debug$S' | |
| 527 | Value: 0 | |
| 528 | SectionNumber: 9 | |
| 529 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 530 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 531 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 532 | SectionDefinition: | |
| 533 | Length: 188 | |
| 534 | NumberOfRelocations: 6 | |
| 535 | NumberOfLinenumbers: 0 | |
| 536 | CheckSum: 1246640575 | |
| 537 | Number: 4 | |
| 538 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | |
| 539 | - Name: '.debug$T' | |
| 540 | Value: 0 | |
| 541 | SectionNumber: 8 | |
| 542 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 543 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 544 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 545 | SectionDefinition: | |
| 546 | Length: 452 | |
| 547 | NumberOfRelocations: 0 | |
| 548 | NumberOfLinenumbers: 0 | |
| 549 | CheckSum: 2561906059 | |
| 550 | Number: 8 | |
| 551 | - Name: '@feat.00' | |
| 552 | Value: 1 | |
| 553 | SectionNumber: -1 | |
| 554 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 555 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 556 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 557 | - Name: '?GlobalFunc@@YAHXZ' | |
| 558 | Value: 0 | |
| 559 | SectionNumber: 1 | |
| 560 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 561 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 562 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 563 | - Name: _main | |
| 564 | Value: 16 | |
| 565 | SectionNumber: 1 | |
| 566 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 567 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 568 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 569 | - Name: '?LocalFunc@@YAHXZ' | |
| 570 | Value: 128 | |
| 571 | SectionNumber: 1 | |
| 572 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 573 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 574 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 575 | - Name: '?GlobalVar@@3PBHB' | |
| 576 | Value: 0 | |
| 577 | SectionNumber: 2 | |
| 578 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 579 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 580 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 581 | - Name: '?__purecall@@3PAXA' | |
| 582 | Value: 0 | |
| 583 | SectionNumber: 3 | |
| 584 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 585 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 586 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 587 | - Name: _ConstantVar | |
| 588 | Value: 0 | |
| 589 | SectionNumber: 5 | |
| 590 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 591 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 592 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 593 | ... |
deps/lld/test/COFF/Inputs/pdb-hashes-1.yaml created+540| ... | ... | @@ -0,0 +1,540 @@ |
| 1 | --- !COFF | |
| 2 | header: | |
| 3 | Machine: IMAGE_FILE_MACHINE_I386 | |
| 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: 5589E55683EC188B450C8B4D088D55F4C745F8000000008B7508894DF089D18934248945ECE80000000083EC048D4DF4890C248945E8E80000000083C4185E5DC3 | |
| 10 | Relocations: | |
| 11 | - VirtualAddress: 38 | |
| 12 | SymbolName: '??0Foo@NS@@QAE@H@Z' | |
| 13 | Type: IMAGE_REL_I386_REL32 | |
| 14 | - VirtualAddress: 55 | |
| 15 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' | |
| 16 | Type: IMAGE_REL_I386_REL32 | |
| 17 | - Name: .data | |
| 18 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | |
| 19 | Alignment: 4 | |
| 20 | SectionData: '' | |
| 21 | - Name: .bss | |
| 22 | Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | |
| 23 | Alignment: 4 | |
| 24 | SectionData: '' | |
| 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: 5589E583EC088B4508894DFC8B4DFC8B550889118945F889C883C4085DC20400 | |
| 29 | - Name: .drectve | |
| 30 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | |
| 31 | Alignment: 1 | |
| 32 | SectionData: 202F44454641554C544C49423A6C6962636D742E6C6962202F44454641554C544C49423A6F6C646E616D65732E6C6962 | |
| 33 | - Name: '.debug$S' | |
| 34 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 35 | Alignment: 4 | |
| 36 | SectionData: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F50000008400000000000000000000004100000000000000080000000000000052000000070000000400000001000000400000000000000008000000000000007F0000000600040000000000030000003E000000000000000800000000000000BD0000000400040000000000040000003D000000000000000800000000000000FA0000000300080000000000F1000000960000002A00471100000000000000000000000041000000000000000000000003100000000000000000006D61696E000D003E1174000000010061726763001200451116000000080000001700000000002A000D003E11001000000100617267760012004511160000000C0000001700000000002A000A003E1109100000000066001200451116000000F4FFFFFF1700000000002A0002004F110000F200000030000000000000000000000041000000000000000300000024000000000000000300000017000000040000003000000005000000F1000000100000000E000811091000004E533A3A466F6F00F40000003000000001000000100165C9E387F88362A8EB2B49539DD5A65500002B00000010019303CF100D518DAF59C31DA01FEF4AFC0000F30000004801000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A312E63707000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D2024657369202454302038202D205E203D2000 | |
| 37 | Subsections: | |
| 38 | - !Symbols | |
| 39 | Records: | |
| 40 | - Kind: S_COMPILE3 | |
| 41 | Compile3Sym: | |
| 42 | Flags: [ ] | |
| 43 | Machine: Pentium3 | |
| 44 | FrontendMajor: 6 | |
| 45 | FrontendMinor: 0 | |
| 46 | FrontendBuild: 0 | |
| 47 | FrontendQFE: 0 | |
| 48 | BackendMajor: 6000 | |
| 49 | BackendMinor: 0 | |
| 50 | BackendBuild: 0 | |
| 51 | BackendQFE: 0 | |
| 52 | Version: 'clang version 6.0.0 ' | |
| 53 | - !FrameData | |
| 54 | Frames: | |
| 55 | - CodeSize: 65 | |
| 56 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' | |
| 57 | LocalSize: 0 | |
| 58 | MaxStackSize: 0 | |
| 59 | ParamsSize: 8 | |
| 60 | PrologSize: 7 | |
| 61 | RvaStart: 0 | |
| 62 | SavedRegsSize: 0 | |
| 63 | - CodeSize: 64 | |
| 64 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | |
| 65 | LocalSize: 0 | |
| 66 | MaxStackSize: 0 | |
| 67 | ParamsSize: 8 | |
| 68 | PrologSize: 6 | |
| 69 | RvaStart: 1 | |
| 70 | SavedRegsSize: 4 | |
| 71 | - CodeSize: 62 | |
| 72 | FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | |
| 73 | LocalSize: 0 | |
| 74 | MaxStackSize: 0 | |
| 75 | ParamsSize: 8 | |
| 76 | PrologSize: 4 | |
| 77 | RvaStart: 3 | |
| 78 | SavedRegsSize: 4 | |
| 79 | - CodeSize: 61 | |
| 80 | FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $esi $T0 8 - ^ = ' | |
| 81 | LocalSize: 0 | |
| 82 | MaxStackSize: 0 | |
| 83 | ParamsSize: 8 | |
| 84 | PrologSize: 3 | |
| 85 | RvaStart: 4 | |
| 86 | SavedRegsSize: 8 | |
| 87 | - !Symbols | |
| 88 | Records: | |
| 89 | - Kind: S_GPROC32_ID | |
| 90 | ProcSym: | |
| 91 | CodeSize: 65 | |
| 92 | DbgStart: 0 | |
| 93 | DbgEnd: 0 | |
| 94 | FunctionType: 4099 | |
| 95 | Flags: [ ] | |
| 96 | DisplayName: main | |
| 97 | - Kind: S_LOCAL | |
| 98 | LocalSym: | |
| 99 | Type: 116 | |
| 100 | Flags: [ IsParameter ] | |
| 101 | VarName: argc | |
| 102 | - Kind: S_DEFRANGE_REGISTER_REL | |
| 103 | DefRangeRegisterRelSym: | |
| 104 | - Kind: S_LOCAL | |
| 105 | LocalSym: | |
| 106 | Type: 4096 | |
| 107 | Flags: [ IsParameter ] | |
| 108 | VarName: argv | |
| 109 | - Kind: S_DEFRANGE_REGISTER_REL | |
| 110 | DefRangeRegisterRelSym: | |
| 111 | - Kind: S_LOCAL | |
| 112 | LocalSym: | |
| 113 | Type: 4105 | |
| 114 | Flags: [ ] | |
| 115 | VarName: f | |
| 116 | - Kind: S_DEFRANGE_REGISTER_REL | |
| 117 | DefRangeRegisterRelSym: | |
| 118 | - Kind: S_PROC_ID_END | |
| 119 | ScopeEndSym: | |
| 120 | - !Lines | |
| 121 | CodeSize: 65 | |
| 122 | Flags: [ ] | |
| 123 | RelocOffset: 0 | |
| 124 | RelocSegment: 0 | |
| 125 | Blocks: | |
| 126 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp' | |
| 127 | Lines: | |
| 128 | - Offset: 0 | |
| 129 | LineStart: 3 | |
| 130 | IsStatement: false | |
| 131 | EndDelta: 0 | |
| 132 | - Offset: 23 | |
| 133 | LineStart: 4 | |
| 134 | IsStatement: false | |
| 135 | EndDelta: 0 | |
| 136 | - Offset: 48 | |
| 137 | LineStart: 5 | |
| 138 | IsStatement: false | |
| 139 | EndDelta: 0 | |
| 140 | Columns: | |
| 141 | - !Symbols | |
| 142 | Records: | |
| 143 | - Kind: S_UDT | |
| 144 | UDTSym: | |
| 145 | Type: 4105 | |
| 146 | UDTName: 'NS::Foo' | |
| 147 | - !FileChecksums | |
| 148 | Checksums: | |
| 149 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp' | |
| 150 | Kind: MD5 | |
| 151 | Checksum: 65C9E387F88362A8EB2B49539DD5A655 | |
| 152 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' | |
| 153 | Kind: MD5 | |
| 154 | Checksum: 9303CF100D518DAF59C31DA01FEF4AFC | |
| 155 | - !StringTable | |
| 156 | Strings: | |
| 157 | - 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp' | |
| 158 | - 'D:\src\llvmbuild\clang\Debug\x86\obj.h' | |
| 159 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' | |
| 160 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | |
| 161 | - '$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 - ^ = ' | |
| 163 | Relocations: | |
| 164 | - VirtualAddress: 68 | |
| 165 | SymbolName: _main | |
| 166 | Type: IMAGE_REL_I386_DIR32NB | |
| 167 | - VirtualAddress: 240 | |
| 168 | SymbolName: _main | |
| 169 | Type: IMAGE_REL_I386_SECREL | |
| 170 | - VirtualAddress: 244 | |
| 171 | SymbolName: _main | |
| 172 | Type: IMAGE_REL_I386_SECTION | |
| 173 | - VirtualAddress: 279 | |
| 174 | SymbolName: .text | |
| 175 | Type: IMAGE_REL_I386_SECREL | |
| 176 | - VirtualAddress: 283 | |
| 177 | SymbolName: .text | |
| 178 | Type: IMAGE_REL_I386_SECTION | |
| 179 | - VirtualAddress: 314 | |
| 180 | SymbolName: .text | |
| 181 | Type: IMAGE_REL_I386_SECREL | |
| 182 | - VirtualAddress: 318 | |
| 183 | SymbolName: .text | |
| 184 | Type: IMAGE_REL_I386_SECTION | |
| 185 | - VirtualAddress: 346 | |
| 186 | SymbolName: .text | |
| 187 | Type: IMAGE_REL_I386_SECREL | |
| 188 | - VirtualAddress: 350 | |
| 189 | SymbolName: .text | |
| 190 | Type: IMAGE_REL_I386_SECTION | |
| 191 | - VirtualAddress: 368 | |
| 192 | SymbolName: _main | |
| 193 | Type: IMAGE_REL_I386_SECREL | |
| 194 | - VirtualAddress: 372 | |
| 195 | SymbolName: _main | |
| 196 | Type: IMAGE_REL_I386_SECTION | |
| 197 | - Name: '.debug$T' | |
| 198 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 199 | Alignment: 4 | |
| 200 | SectionData: 040000000A000210700400000A8000000E0001120200000074000000001000000E0008107400000000000200011000001200011600000000021000006D61696E00F3F2F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000210041000000A8000000A00011201000000740000001A0009100300000004100000051000000B00010006100000000000001A0003120D15030074000000000058001115030007100000466F6F002A0005150200000208100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E000616091000000A100000020000000E0002160410000007100000466F6F00 | |
| 201 | Types: | |
| 202 | - Kind: LF_POINTER | |
| 203 | Pointer: | |
| 204 | ReferentType: 1136 | |
| 205 | Attrs: 32778 | |
| 206 | - Kind: LF_ARGLIST | |
| 207 | ArgList: | |
| 208 | ArgIndices: [ 116, 4096 ] | |
| 209 | - Kind: LF_PROCEDURE | |
| 210 | Procedure: | |
| 211 | ReturnType: 116 | |
| 212 | CallConv: NearC | |
| 213 | Options: [ None ] | |
| 214 | ParameterCount: 2 | |
| 215 | ArgumentList: 4097 | |
| 216 | - Kind: LF_FUNC_ID | |
| 217 | FuncId: | |
| 218 | ParentScope: 0 | |
| 219 | FunctionType: 4098 | |
| 220 | Name: main | |
| 221 | - Kind: LF_STRUCTURE | |
| 222 | Class: | |
| 223 | MemberCount: 0 | |
| 224 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 225 | FieldList: 0 | |
| 226 | Name: 'NS::Foo' | |
| 227 | UniqueName: '.?AUFoo@NS@@' | |
| 228 | DerivationList: 0 | |
| 229 | VTableShape: 0 | |
| 230 | Size: 0 | |
| 231 | - Kind: LF_POINTER | |
| 232 | Pointer: | |
| 233 | ReferentType: 4100 | |
| 234 | Attrs: 32778 | |
| 235 | - Kind: LF_ARGLIST | |
| 236 | ArgList: | |
| 237 | ArgIndices: [ 116 ] | |
| 238 | - Kind: LF_MFUNCTION | |
| 239 | MemberFunction: | |
| 240 | ReturnType: 3 | |
| 241 | ClassType: 4100 | |
| 242 | ThisType: 4101 | |
| 243 | CallConv: ThisCall | |
| 244 | Options: [ None ] | |
| 245 | ParameterCount: 1 | |
| 246 | ArgumentList: 4102 | |
| 247 | ThisPointerAdjustment: 0 | |
| 248 | - Kind: LF_FIELDLIST | |
| 249 | FieldList: | |
| 250 | - Kind: LF_MEMBER | |
| 251 | DataMember: | |
| 252 | Attrs: 3 | |
| 253 | Type: 116 | |
| 254 | FieldOffset: 0 | |
| 255 | Name: X | |
| 256 | - Kind: LF_ONEMETHOD | |
| 257 | OneMethod: | |
| 258 | Type: 4103 | |
| 259 | Attrs: 3 | |
| 260 | VFTableOffset: -1 | |
| 261 | Name: Foo | |
| 262 | - Kind: LF_STRUCTURE | |
| 263 | Class: | |
| 264 | MemberCount: 2 | |
| 265 | Options: [ None, HasUniqueName ] | |
| 266 | FieldList: 4104 | |
| 267 | Name: 'NS::Foo' | |
| 268 | UniqueName: '.?AUFoo@NS@@' | |
| 269 | DerivationList: 0 | |
| 270 | VTableShape: 0 | |
| 271 | Size: 4 | |
| 272 | - Kind: LF_STRING_ID | |
| 273 | StringId: | |
| 274 | Id: 0 | |
| 275 | String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' | |
| 276 | - Kind: LF_UDT_SRC_LINE | |
| 277 | UdtSourceLine: | |
| 278 | UDT: 4105 | |
| 279 | SourceFile: 4106 | |
| 280 | LineNumber: 2 | |
| 281 | - Kind: LF_MFUNC_ID | |
| 282 | MemberFuncId: | |
| 283 | ClassType: 4100 | |
| 284 | FunctionType: 4103 | |
| 285 | Name: Foo | |
| 286 | - Name: '.debug$H' | |
| 287 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 288 | Alignment: 4 | |
| 289 | SectionData: C5C93301000000009E56666824DC4B12E25261D4E09E6E9DA0F4EE31FDEC3D2D96287486127C66070B248ED52E421F55074AE5CC2D68AF9F0A3BEF23993968F7FD82CA84BF0439C1A64C9070C6A6ADB0A34D21DAD0FFC3E99E616EF06A14EA74A2420F9062A1FB04917E5975E3A50EABE5E8FE3945468547C19DC681D0BFB3B797DD91CA4D7F1953C314442D5549419E78044E38A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0C0A9021B711ACC4F67008974EBF441031BDD653F6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA0AF6C1846743F43D846BB19517E12E8873BBA90CC41DD1BEAC89CBA8897AC1BA46762E2557A82D894CEAE81AEF8680D723D403D9A4481F0E28683A98 | |
| 290 | GlobalHashes: | |
| 291 | Version: 0 | |
| 292 | HashAlgorithm: 0 | |
| 293 | HashValues: | |
| 294 | - 9E56666824DC4B12E25261D4E09E6E9DA0F4EE31 | |
| 295 | - FDEC3D2D96287486127C66070B248ED52E421F55 | |
| 296 | - 074AE5CC2D68AF9F0A3BEF23993968F7FD82CA84 | |
| 297 | - BF0439C1A64C9070C6A6ADB0A34D21DAD0FFC3E9 | |
| 298 | - 9E616EF06A14EA74A2420F9062A1FB04917E5975 | |
| 299 | - E3A50EABE5E8FE3945468547C19DC681D0BFB3B7 | |
| 300 | - 97DD91CA4D7F1953C314442D5549419E78044E38 | |
| 301 | - A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0 | |
| 302 | - C0A9021B711ACC4F67008974EBF441031BDD653F | |
| 303 | - 6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA | |
| 304 | - 0AF6C1846743F43D846BB19517E12E8873BBA90C | |
| 305 | - C41DD1BEAC89CBA8897AC1BA46762E2557A82D89 | |
| 306 | - 4CEAE81AEF8680D723D403D9A4481F0E28683A98 | |
| 307 | - Name: '.debug$S' | |
| 308 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 309 | Alignment: 4 | |
| 310 | SectionData: 04000000F500000064000000000000000000000020000000000000000400000000000000520000000600000004000000010000001F0000000000000004000000000000007F0000000500040000000000030000001D000000000000000400000000000000BD0000000300040000000000F10000007B000000320047110000000000000000000000002000000000000000000000000C100000000000000000004E533A3A466F6F3A3A466F6F000D003E1105100000010074686973001200451116000000FCFFFFFF0F000000000011000A003E1174000000010078001200451116000000080000000F0000000000110002004F1100F2000000200000000000000000000000200000001800000001000000140000000000000003000000 | |
| 311 | Subsections: | |
| 312 | - !FrameData | |
| 313 | Frames: | |
| 314 | - CodeSize: 32 | |
| 315 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' | |
| 316 | LocalSize: 0 | |
| 317 | MaxStackSize: 0 | |
| 318 | ParamsSize: 4 | |
| 319 | PrologSize: 6 | |
| 320 | RvaStart: 0 | |
| 321 | SavedRegsSize: 0 | |
| 322 | - CodeSize: 31 | |
| 323 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | |
| 324 | LocalSize: 0 | |
| 325 | MaxStackSize: 0 | |
| 326 | ParamsSize: 4 | |
| 327 | PrologSize: 5 | |
| 328 | RvaStart: 1 | |
| 329 | SavedRegsSize: 4 | |
| 330 | - CodeSize: 29 | |
| 331 | FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | |
| 332 | LocalSize: 0 | |
| 333 | MaxStackSize: 0 | |
| 334 | ParamsSize: 4 | |
| 335 | PrologSize: 3 | |
| 336 | RvaStart: 3 | |
| 337 | SavedRegsSize: 4 | |
| 338 | - !Symbols | |
| 339 | Records: | |
| 340 | - Kind: S_GPROC32_ID | |
| 341 | ProcSym: | |
| 342 | CodeSize: 32 | |
| 343 | DbgStart: 0 | |
| 344 | DbgEnd: 0 | |
| 345 | FunctionType: 4108 | |
| 346 | Flags: [ ] | |
| 347 | DisplayName: 'NS::Foo::Foo' | |
| 348 | - Kind: S_LOCAL | |
| 349 | LocalSym: | |
| 350 | Type: 4101 | |
| 351 | Flags: [ IsParameter ] | |
| 352 | VarName: this | |
| 353 | - Kind: S_DEFRANGE_REGISTER_REL | |
| 354 | DefRangeRegisterRelSym: | |
| 355 | - Kind: S_LOCAL | |
| 356 | LocalSym: | |
| 357 | Type: 116 | |
| 358 | Flags: [ IsParameter ] | |
| 359 | VarName: x | |
| 360 | - Kind: S_DEFRANGE_REGISTER_REL | |
| 361 | DefRangeRegisterRelSym: | |
| 362 | - Kind: S_PROC_ID_END | |
| 363 | ScopeEndSym: | |
| 364 | - !Lines | |
| 365 | CodeSize: 32 | |
| 366 | Flags: [ ] | |
| 367 | RelocOffset: 0 | |
| 368 | RelocSegment: 0 | |
| 369 | Blocks: | |
| 370 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' | |
| 371 | Lines: | |
| 372 | - Offset: 0 | |
| 373 | LineStart: 3 | |
| 374 | IsStatement: false | |
| 375 | EndDelta: 0 | |
| 376 | Columns: | |
| 377 | Relocations: | |
| 378 | - VirtualAddress: 12 | |
| 379 | SymbolName: '??0Foo@NS@@QAE@H@Z' | |
| 380 | Type: IMAGE_REL_I386_DIR32NB | |
| 381 | - VirtualAddress: 152 | |
| 382 | SymbolName: '??0Foo@NS@@QAE@H@Z' | |
| 383 | Type: IMAGE_REL_I386_SECREL | |
| 384 | - VirtualAddress: 156 | |
| 385 | SymbolName: '??0Foo@NS@@QAE@H@Z' | |
| 386 | Type: IMAGE_REL_I386_SECTION | |
| 387 | - VirtualAddress: 199 | |
| 388 | SymbolName: .text | |
| 389 | Type: IMAGE_REL_I386_SECREL | |
| 390 | - VirtualAddress: 203 | |
| 391 | SymbolName: .text | |
| 392 | Type: IMAGE_REL_I386_SECTION | |
| 393 | - VirtualAddress: 231 | |
| 394 | SymbolName: .text | |
| 395 | Type: IMAGE_REL_I386_SECREL | |
| 396 | - VirtualAddress: 235 | |
| 397 | SymbolName: .text | |
| 398 | Type: IMAGE_REL_I386_SECTION | |
| 399 | - VirtualAddress: 252 | |
| 400 | SymbolName: '??0Foo@NS@@QAE@H@Z' | |
| 401 | Type: IMAGE_REL_I386_SECREL | |
| 402 | - VirtualAddress: 256 | |
| 403 | SymbolName: '??0Foo@NS@@QAE@H@Z' | |
| 404 | Type: IMAGE_REL_I386_SECTION | |
| 405 | symbols: | |
| 406 | - Name: .text | |
| 407 | Value: 0 | |
| 408 | SectionNumber: 1 | |
| 409 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 410 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 411 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 412 | SectionDefinition: | |
| 413 | Length: 65 | |
| 414 | NumberOfRelocations: 2 | |
| 415 | NumberOfLinenumbers: 0 | |
| 416 | CheckSum: 4176946275 | |
| 417 | Number: 1 | |
| 418 | - Name: .data | |
| 419 | Value: 0 | |
| 420 | SectionNumber: 2 | |
| 421 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 422 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 423 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 424 | SectionDefinition: | |
| 425 | Length: 0 | |
| 426 | NumberOfRelocations: 0 | |
| 427 | NumberOfLinenumbers: 0 | |
| 428 | CheckSum: 0 | |
| 429 | Number: 2 | |
| 430 | - Name: .bss | |
| 431 | Value: 0 | |
| 432 | SectionNumber: 3 | |
| 433 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 434 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 435 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 436 | SectionDefinition: | |
| 437 | Length: 0 | |
| 438 | NumberOfRelocations: 0 | |
| 439 | NumberOfLinenumbers: 0 | |
| 440 | CheckSum: 0 | |
| 441 | Number: 3 | |
| 442 | - Name: .text | |
| 443 | Value: 0 | |
| 444 | SectionNumber: 4 | |
| 445 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 446 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 447 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 448 | SectionDefinition: | |
| 449 | Length: 32 | |
| 450 | NumberOfRelocations: 0 | |
| 451 | NumberOfLinenumbers: 0 | |
| 452 | CheckSum: 1438182552 | |
| 453 | Number: 4 | |
| 454 | Selection: IMAGE_COMDAT_SELECT_ANY | |
| 455 | - Name: '??0Foo@NS@@QAE@H@Z' | |
| 456 | Value: 0 | |
| 457 | SectionNumber: 4 | |
| 458 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 459 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 460 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 461 | - Name: .drectve | |
| 462 | Value: 0 | |
| 463 | SectionNumber: 5 | |
| 464 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 465 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 466 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 467 | SectionDefinition: | |
| 468 | Length: 48 | |
| 469 | NumberOfRelocations: 0 | |
| 470 | NumberOfLinenumbers: 0 | |
| 471 | CheckSum: 149686238 | |
| 472 | Number: 5 | |
| 473 | - Name: '.debug$S' | |
| 474 | Value: 0 | |
| 475 | SectionNumber: 6 | |
| 476 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 477 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 478 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 479 | SectionDefinition: | |
| 480 | Length: 832 | |
| 481 | NumberOfRelocations: 11 | |
| 482 | NumberOfLinenumbers: 0 | |
| 483 | CheckSum: 4106171226 | |
| 484 | Number: 6 | |
| 485 | - Name: '.debug$S' | |
| 486 | Value: 0 | |
| 487 | SectionNumber: 9 | |
| 488 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 489 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 490 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 491 | SectionDefinition: | |
| 492 | Length: 284 | |
| 493 | NumberOfRelocations: 9 | |
| 494 | NumberOfLinenumbers: 0 | |
| 495 | CheckSum: 1378739251 | |
| 496 | Number: 4 | |
| 497 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | |
| 498 | - Name: '.debug$T' | |
| 499 | Value: 0 | |
| 500 | SectionNumber: 7 | |
| 501 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 502 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 503 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 504 | SectionDefinition: | |
| 505 | Length: 316 | |
| 506 | NumberOfRelocations: 0 | |
| 507 | NumberOfLinenumbers: 0 | |
| 508 | CheckSum: 3343977630 | |
| 509 | Number: 7 | |
| 510 | - Name: '.debug$H' | |
| 511 | Value: 0 | |
| 512 | SectionNumber: 8 | |
| 513 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 514 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 515 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 516 | SectionDefinition: | |
| 517 | Length: 268 | |
| 518 | NumberOfRelocations: 0 | |
| 519 | NumberOfLinenumbers: 0 | |
| 520 | CheckSum: 3965031229 | |
| 521 | Number: 8 | |
| 522 | - Name: '@feat.00' | |
| 523 | Value: 1 | |
| 524 | SectionNumber: -1 | |
| 525 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 526 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 527 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 528 | - Name: _main | |
| 529 | Value: 0 | |
| 530 | SectionNumber: 1 | |
| 531 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 532 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 533 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 534 | - Name: '?func@NS@@YAHABUFoo@1@@Z' | |
| 535 | Value: 0 | |
| 536 | SectionNumber: 0 | |
| 537 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 538 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 539 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 540 | ... |
deps/lld/test/COFF/Inputs/pdb-hashes-2-missing.yaml created+321| ... | ... | @@ -0,0 +1,321 @@ |
| 1 | --- !COFF | |
| 2 | header: | |
| 3 | Machine: IMAGE_FILE_MACHINE_I386 | |
| 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: 5589E5508B45088B4D088B09C1E1018945FC89C883C4045DC3 | |
| 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: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F5000000640000000000000000000000190000000000000004000000000000002B000000040000000400000001000000180000000000000004000000000000005800000003000400000000000300000016000000000000000400000000000000960000000100040000000000F1000000540000002E0047110000000000000000000000001900000000000000000000000D100000000000000000004E533A3A66756E63000A003E110310000001006600120045111600000008000000070000000000120002004F11F20000002800000000000000000000001900000000000000020000001C00000000000000030000000700000004000000F1000000100000000E0008110A1000004E533A3A466F6F00F40000001800000001000000100159DFAC75D18675AED1AD169FE316317E0000F3000000D400000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A322E63707000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200000 | |
| 26 | Subsections: | |
| 27 | - !Symbols | |
| 28 | Records: | |
| 29 | - Kind: S_COMPILE3 | |
| 30 | Compile3Sym: | |
| 31 | Flags: [ ] | |
| 32 | Machine: Pentium3 | |
| 33 | FrontendMajor: 6 | |
| 34 | FrontendMinor: 0 | |
| 35 | FrontendBuild: 0 | |
| 36 | FrontendQFE: 0 | |
| 37 | BackendMajor: 6000 | |
| 38 | BackendMinor: 0 | |
| 39 | BackendBuild: 0 | |
| 40 | BackendQFE: 0 | |
| 41 | Version: 'clang version 6.0.0 ' | |
| 42 | - !FrameData | |
| 43 | Frames: | |
| 44 | - CodeSize: 25 | |
| 45 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' | |
| 46 | LocalSize: 0 | |
| 47 | MaxStackSize: 0 | |
| 48 | ParamsSize: 4 | |
| 49 | PrologSize: 4 | |
| 50 | RvaStart: 0 | |
| 51 | SavedRegsSize: 0 | |
| 52 | - CodeSize: 24 | |
| 53 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | |
| 54 | LocalSize: 0 | |
| 55 | MaxStackSize: 0 | |
| 56 | ParamsSize: 4 | |
| 57 | PrologSize: 3 | |
| 58 | RvaStart: 1 | |
| 59 | SavedRegsSize: 4 | |
| 60 | - CodeSize: 22 | |
| 61 | FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | |
| 62 | LocalSize: 0 | |
| 63 | MaxStackSize: 0 | |
| 64 | ParamsSize: 4 | |
| 65 | PrologSize: 1 | |
| 66 | RvaStart: 3 | |
| 67 | SavedRegsSize: 4 | |
| 68 | - !Symbols | |
| 69 | Records: | |
| 70 | - Kind: S_GPROC32_ID | |
| 71 | ProcSym: | |
| 72 | CodeSize: 25 | |
| 73 | DbgStart: 0 | |
| 74 | DbgEnd: 0 | |
| 75 | FunctionType: 4109 | |
| 76 | Flags: [ ] | |
| 77 | DisplayName: 'NS::func' | |
| 78 | - Kind: S_LOCAL | |
| 79 | LocalSym: | |
| 80 | Type: 4099 | |
| 81 | Flags: [ IsParameter ] | |
| 82 | VarName: f | |
| 83 | - Kind: S_DEFRANGE_REGISTER_REL | |
| 84 | DefRangeRegisterRelSym: | |
| 85 | - Kind: S_PROC_ID_END | |
| 86 | ScopeEndSym: | |
| 87 | - !Lines | |
| 88 | CodeSize: 25 | |
| 89 | Flags: [ ] | |
| 90 | RelocOffset: 0 | |
| 91 | RelocSegment: 0 | |
| 92 | Blocks: | |
| 93 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' | |
| 94 | Lines: | |
| 95 | - Offset: 0 | |
| 96 | LineStart: 3 | |
| 97 | IsStatement: false | |
| 98 | EndDelta: 0 | |
| 99 | - Offset: 7 | |
| 100 | LineStart: 4 | |
| 101 | IsStatement: false | |
| 102 | EndDelta: 0 | |
| 103 | Columns: | |
| 104 | - !Symbols | |
| 105 | Records: | |
| 106 | - Kind: S_UDT | |
| 107 | UDTSym: | |
| 108 | Type: 4106 | |
| 109 | UDTName: 'NS::Foo' | |
| 110 | - !FileChecksums | |
| 111 | Checksums: | |
| 112 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' | |
| 113 | Kind: MD5 | |
| 114 | Checksum: 59DFAC75D18675AED1AD169FE316317E | |
| 115 | - !StringTable | |
| 116 | Strings: | |
| 117 | - 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' | |
| 118 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' | |
| 119 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | |
| 120 | - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | |
| 121 | - '' | |
| 122 | Relocations: | |
| 123 | - VirtualAddress: 68 | |
| 124 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' | |
| 125 | Type: IMAGE_REL_I386_DIR32NB | |
| 126 | - VirtualAddress: 208 | |
| 127 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' | |
| 128 | Type: IMAGE_REL_I386_SECREL | |
| 129 | - VirtualAddress: 212 | |
| 130 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' | |
| 131 | Type: IMAGE_REL_I386_SECTION | |
| 132 | - VirtualAddress: 248 | |
| 133 | SymbolName: .text | |
| 134 | Type: IMAGE_REL_I386_SECREL | |
| 135 | - VirtualAddress: 252 | |
| 136 | SymbolName: .text | |
| 137 | Type: IMAGE_REL_I386_SECTION | |
| 138 | - VirtualAddress: 268 | |
| 139 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' | |
| 140 | Type: IMAGE_REL_I386_SECREL | |
| 141 | - VirtualAddress: 272 | |
| 142 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' | |
| 143 | Type: IMAGE_REL_I386_SECTION | |
| 144 | - Name: '.debug$T' | |
| 145 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 146 | Alignment: 4 | |
| 147 | SectionData: 040000000A000516000000004E5300F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000110011000000100F2F10A000210021000002A8000000A00011201000000031000000E0008107400000000000100041000000A000210011000000A8000000A00011201000000740000001A0009100300000001100000061000000B00010007100000000000001A0003120D15030074000000000058001115030008100000466F6F002A0005150200000209100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E0006160A1000000B1000000200000012000116001000000510000066756E6300F3F2F1 | |
| 148 | Types: | |
| 149 | - Kind: LF_STRING_ID | |
| 150 | StringId: | |
| 151 | Id: 0 | |
| 152 | String: NS | |
| 153 | - Kind: LF_STRUCTURE | |
| 154 | Class: | |
| 155 | MemberCount: 0 | |
| 156 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 157 | FieldList: 0 | |
| 158 | Name: 'NS::Foo' | |
| 159 | UniqueName: '.?AUFoo@NS@@' | |
| 160 | DerivationList: 0 | |
| 161 | VTableShape: 0 | |
| 162 | Size: 0 | |
| 163 | - Kind: LF_MODIFIER | |
| 164 | Modifier: | |
| 165 | ModifiedType: 4097 | |
| 166 | Modifiers: [ None, Const ] | |
| 167 | - Kind: LF_POINTER | |
| 168 | Pointer: | |
| 169 | ReferentType: 4098 | |
| 170 | Attrs: 32810 | |
| 171 | - Kind: LF_ARGLIST | |
| 172 | ArgList: | |
| 173 | ArgIndices: [ 4099 ] | |
| 174 | - Kind: LF_PROCEDURE | |
| 175 | Procedure: | |
| 176 | ReturnType: 116 | |
| 177 | CallConv: NearC | |
| 178 | Options: [ None ] | |
| 179 | ParameterCount: 1 | |
| 180 | ArgumentList: 4100 | |
| 181 | - Kind: LF_POINTER | |
| 182 | Pointer: | |
| 183 | ReferentType: 4097 | |
| 184 | Attrs: 32778 | |
| 185 | - Kind: LF_ARGLIST | |
| 186 | ArgList: | |
| 187 | ArgIndices: [ 116 ] | |
| 188 | - Kind: LF_MFUNCTION | |
| 189 | MemberFunction: | |
| 190 | ReturnType: 3 | |
| 191 | ClassType: 4097 | |
| 192 | ThisType: 4102 | |
| 193 | CallConv: ThisCall | |
| 194 | Options: [ None ] | |
| 195 | ParameterCount: 1 | |
| 196 | ArgumentList: 4103 | |
| 197 | ThisPointerAdjustment: 0 | |
| 198 | - Kind: LF_FIELDLIST | |
| 199 | FieldList: | |
| 200 | - Kind: LF_MEMBER | |
| 201 | DataMember: | |
| 202 | Attrs: 3 | |
| 203 | Type: 116 | |
| 204 | FieldOffset: 0 | |
| 205 | Name: X | |
| 206 | - Kind: LF_ONEMETHOD | |
| 207 | OneMethod: | |
| 208 | Type: 4104 | |
| 209 | Attrs: 3 | |
| 210 | VFTableOffset: -1 | |
| 211 | Name: Foo | |
| 212 | - Kind: LF_STRUCTURE | |
| 213 | Class: | |
| 214 | MemberCount: 2 | |
| 215 | Options: [ None, HasUniqueName ] | |
| 216 | FieldList: 4105 | |
| 217 | Name: 'NS::Foo' | |
| 218 | UniqueName: '.?AUFoo@NS@@' | |
| 219 | DerivationList: 0 | |
| 220 | VTableShape: 0 | |
| 221 | Size: 4 | |
| 222 | - Kind: LF_STRING_ID | |
| 223 | StringId: | |
| 224 | Id: 0 | |
| 225 | String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' | |
| 226 | - Kind: LF_UDT_SRC_LINE | |
| 227 | UdtSourceLine: | |
| 228 | UDT: 4106 | |
| 229 | SourceFile: 4107 | |
| 230 | LineNumber: 2 | |
| 231 | - Kind: LF_FUNC_ID | |
| 232 | FuncId: | |
| 233 | ParentScope: 4096 | |
| 234 | FunctionType: 4101 | |
| 235 | Name: func | |
| 236 | symbols: | |
| 237 | - Name: .text | |
| 238 | Value: 0 | |
| 239 | SectionNumber: 1 | |
| 240 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 241 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 242 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 243 | SectionDefinition: | |
| 244 | Length: 25 | |
| 245 | NumberOfRelocations: 0 | |
| 246 | NumberOfLinenumbers: 0 | |
| 247 | CheckSum: 1820185021 | |
| 248 | Number: 1 | |
| 249 | - Name: .data | |
| 250 | Value: 0 | |
| 251 | SectionNumber: 2 | |
| 252 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 253 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 254 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 255 | SectionDefinition: | |
| 256 | Length: 0 | |
| 257 | NumberOfRelocations: 0 | |
| 258 | NumberOfLinenumbers: 0 | |
| 259 | CheckSum: 0 | |
| 260 | Number: 2 | |
| 261 | - Name: .bss | |
| 262 | Value: 0 | |
| 263 | SectionNumber: 3 | |
| 264 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 265 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 266 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 267 | SectionDefinition: | |
| 268 | Length: 0 | |
| 269 | NumberOfRelocations: 0 | |
| 270 | NumberOfLinenumbers: 0 | |
| 271 | CheckSum: 0 | |
| 272 | Number: 3 | |
| 273 | - Name: .drectve | |
| 274 | Value: 0 | |
| 275 | SectionNumber: 4 | |
| 276 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 277 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 278 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 279 | SectionDefinition: | |
| 280 | Length: 48 | |
| 281 | NumberOfRelocations: 0 | |
| 282 | NumberOfLinenumbers: 0 | |
| 283 | CheckSum: 149686238 | |
| 284 | Number: 4 | |
| 285 | - Name: '.debug$S' | |
| 286 | Value: 0 | |
| 287 | SectionNumber: 5 | |
| 288 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 289 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 290 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 291 | SectionDefinition: | |
| 292 | Length: 584 | |
| 293 | NumberOfRelocations: 7 | |
| 294 | NumberOfLinenumbers: 0 | |
| 295 | CheckSum: 2847177244 | |
| 296 | Number: 5 | |
| 297 | - Name: '.debug$T' | |
| 298 | Value: 0 | |
| 299 | SectionNumber: 6 | |
| 300 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 301 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 302 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 303 | SectionDefinition: | |
| 304 | Length: 320 | |
| 305 | NumberOfRelocations: 0 | |
| 306 | NumberOfLinenumbers: 0 | |
| 307 | CheckSum: 2684556216 | |
| 308 | Number: 6 | |
| 309 | - Name: '@feat.00' | |
| 310 | Value: 1 | |
| 311 | SectionNumber: -1 | |
| 312 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 313 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 314 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 315 | - Name: '?func@NS@@YAHABUFoo@1@@Z' | |
| 316 | Value: 0 | |
| 317 | SectionNumber: 1 | |
| 318 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 319 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 320 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 321 | ... |
deps/lld/test/COFF/Inputs/pdb-hashes-2.yaml created+355| ... | ... | @@ -0,0 +1,355 @@ |
| 1 | --- !COFF | |
| 2 | header: | |
| 3 | Machine: IMAGE_FILE_MACHINE_I386 | |
| 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: 5589E5508B45088B4D088B09C1E1018945FC89C883C4045DC3 | |
| 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: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F5000000640000000000000000000000190000000000000004000000000000002B000000040000000400000001000000180000000000000004000000000000005800000003000400000000000300000016000000000000000400000000000000960000000100040000000000F1000000540000002E0047110000000000000000000000001900000000000000000000000D100000000000000000004E533A3A66756E63000A003E110310000001006600120045111600000008000000070000000000120002004F11F20000002800000000000000000000001900000000000000020000001C00000000000000030000000700000004000000F1000000100000000E0008110A1000004E533A3A466F6F00F40000001800000001000000100159DFAC75D18675AED1AD169FE316317E0000F3000000D400000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A322E63707000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200000 | |
| 26 | Subsections: | |
| 27 | - !Symbols | |
| 28 | Records: | |
| 29 | - Kind: S_COMPILE3 | |
| 30 | Compile3Sym: | |
| 31 | Flags: [ ] | |
| 32 | Machine: Pentium3 | |
| 33 | FrontendMajor: 6 | |
| 34 | FrontendMinor: 0 | |
| 35 | FrontendBuild: 0 | |
| 36 | FrontendQFE: 0 | |
| 37 | BackendMajor: 6000 | |
| 38 | BackendMinor: 0 | |
| 39 | BackendBuild: 0 | |
| 40 | BackendQFE: 0 | |
| 41 | Version: 'clang version 6.0.0 ' | |
| 42 | - !FrameData | |
| 43 | Frames: | |
| 44 | - CodeSize: 25 | |
| 45 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' | |
| 46 | LocalSize: 0 | |
| 47 | MaxStackSize: 0 | |
| 48 | ParamsSize: 4 | |
| 49 | PrologSize: 4 | |
| 50 | RvaStart: 0 | |
| 51 | SavedRegsSize: 0 | |
| 52 | - CodeSize: 24 | |
| 53 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | |
| 54 | LocalSize: 0 | |
| 55 | MaxStackSize: 0 | |
| 56 | ParamsSize: 4 | |
| 57 | PrologSize: 3 | |
| 58 | RvaStart: 1 | |
| 59 | SavedRegsSize: 4 | |
| 60 | - CodeSize: 22 | |
| 61 | FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | |
| 62 | LocalSize: 0 | |
| 63 | MaxStackSize: 0 | |
| 64 | ParamsSize: 4 | |
| 65 | PrologSize: 1 | |
| 66 | RvaStart: 3 | |
| 67 | SavedRegsSize: 4 | |
| 68 | - !Symbols | |
| 69 | Records: | |
| 70 | - Kind: S_GPROC32_ID | |
| 71 | ProcSym: | |
| 72 | CodeSize: 25 | |
| 73 | DbgStart: 0 | |
| 74 | DbgEnd: 0 | |
| 75 | FunctionType: 4109 | |
| 76 | Flags: [ ] | |
| 77 | DisplayName: 'NS::func' | |
| 78 | - Kind: S_LOCAL | |
| 79 | LocalSym: | |
| 80 | Type: 4099 | |
| 81 | Flags: [ IsParameter ] | |
| 82 | VarName: f | |
| 83 | - Kind: S_DEFRANGE_REGISTER_REL | |
| 84 | DefRangeRegisterRelSym: | |
| 85 | - Kind: S_PROC_ID_END | |
| 86 | ScopeEndSym: | |
| 87 | - !Lines | |
| 88 | CodeSize: 25 | |
| 89 | Flags: [ ] | |
| 90 | RelocOffset: 0 | |
| 91 | RelocSegment: 0 | |
| 92 | Blocks: | |
| 93 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' | |
| 94 | Lines: | |
| 95 | - Offset: 0 | |
| 96 | LineStart: 3 | |
| 97 | IsStatement: false | |
| 98 | EndDelta: 0 | |
| 99 | - Offset: 7 | |
| 100 | LineStart: 4 | |
| 101 | IsStatement: false | |
| 102 | EndDelta: 0 | |
| 103 | Columns: | |
| 104 | - !Symbols | |
| 105 | Records: | |
| 106 | - Kind: S_UDT | |
| 107 | UDTSym: | |
| 108 | Type: 4106 | |
| 109 | UDTName: 'NS::Foo' | |
| 110 | - !FileChecksums | |
| 111 | Checksums: | |
| 112 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' | |
| 113 | Kind: MD5 | |
| 114 | Checksum: 59DFAC75D18675AED1AD169FE316317E | |
| 115 | - !StringTable | |
| 116 | Strings: | |
| 117 | - 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' | |
| 118 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' | |
| 119 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | |
| 120 | - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | |
| 121 | - '' | |
| 122 | Relocations: | |
| 123 | - VirtualAddress: 68 | |
| 124 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' | |
| 125 | Type: IMAGE_REL_I386_DIR32NB | |
| 126 | - VirtualAddress: 208 | |
| 127 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' | |
| 128 | Type: IMAGE_REL_I386_SECREL | |
| 129 | - VirtualAddress: 212 | |
| 130 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' | |
| 131 | Type: IMAGE_REL_I386_SECTION | |
| 132 | - VirtualAddress: 248 | |
| 133 | SymbolName: .text | |
| 134 | Type: IMAGE_REL_I386_SECREL | |
| 135 | - VirtualAddress: 252 | |
| 136 | SymbolName: .text | |
| 137 | Type: IMAGE_REL_I386_SECTION | |
| 138 | - VirtualAddress: 268 | |
| 139 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' | |
| 140 | Type: IMAGE_REL_I386_SECREL | |
| 141 | - VirtualAddress: 272 | |
| 142 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' | |
| 143 | Type: IMAGE_REL_I386_SECTION | |
| 144 | - Name: '.debug$T' | |
| 145 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 146 | Alignment: 4 | |
| 147 | SectionData: 040000000A000516000000004E5300F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000110011000000100F2F10A000210021000002A8000000A00011201000000031000000E0008107400000000000100041000000A000210011000000A8000000A00011201000000740000001A0009100300000001100000061000000B00010007100000000000001A0003120D15030074000000000058001115030008100000466F6F002A0005150200000209100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E0006160A1000000B1000000200000012000116001000000510000066756E6300F3F2F1 | |
| 148 | Types: | |
| 149 | - Kind: LF_STRING_ID | |
| 150 | StringId: | |
| 151 | Id: 0 | |
| 152 | String: NS | |
| 153 | - Kind: LF_STRUCTURE | |
| 154 | Class: | |
| 155 | MemberCount: 0 | |
| 156 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 157 | FieldList: 0 | |
| 158 | Name: 'NS::Foo' | |
| 159 | UniqueName: '.?AUFoo@NS@@' | |
| 160 | DerivationList: 0 | |
| 161 | VTableShape: 0 | |
| 162 | Size: 0 | |
| 163 | - Kind: LF_MODIFIER | |
| 164 | Modifier: | |
| 165 | ModifiedType: 4097 | |
| 166 | Modifiers: [ None, Const ] | |
| 167 | - Kind: LF_POINTER | |
| 168 | Pointer: | |
| 169 | ReferentType: 4098 | |
| 170 | Attrs: 32810 | |
| 171 | - Kind: LF_ARGLIST | |
| 172 | ArgList: | |
| 173 | ArgIndices: [ 4099 ] | |
| 174 | - Kind: LF_PROCEDURE | |
| 175 | Procedure: | |
| 176 | ReturnType: 116 | |
| 177 | CallConv: NearC | |
| 178 | Options: [ None ] | |
| 179 | ParameterCount: 1 | |
| 180 | ArgumentList: 4100 | |
| 181 | - Kind: LF_POINTER | |
| 182 | Pointer: | |
| 183 | ReferentType: 4097 | |
| 184 | Attrs: 32778 | |
| 185 | - Kind: LF_ARGLIST | |
| 186 | ArgList: | |
| 187 | ArgIndices: [ 116 ] | |
| 188 | - Kind: LF_MFUNCTION | |
| 189 | MemberFunction: | |
| 190 | ReturnType: 3 | |
| 191 | ClassType: 4097 | |
| 192 | ThisType: 4102 | |
| 193 | CallConv: ThisCall | |
| 194 | Options: [ None ] | |
| 195 | ParameterCount: 1 | |
| 196 | ArgumentList: 4103 | |
| 197 | ThisPointerAdjustment: 0 | |
| 198 | - Kind: LF_FIELDLIST | |
| 199 | FieldList: | |
| 200 | - Kind: LF_MEMBER | |
| 201 | DataMember: | |
| 202 | Attrs: 3 | |
| 203 | Type: 116 | |
| 204 | FieldOffset: 0 | |
| 205 | Name: X | |
| 206 | - Kind: LF_ONEMETHOD | |
| 207 | OneMethod: | |
| 208 | Type: 4104 | |
| 209 | Attrs: 3 | |
| 210 | VFTableOffset: -1 | |
| 211 | Name: Foo | |
| 212 | - Kind: LF_STRUCTURE | |
| 213 | Class: | |
| 214 | MemberCount: 2 | |
| 215 | Options: [ None, HasUniqueName ] | |
| 216 | FieldList: 4105 | |
| 217 | Name: 'NS::Foo' | |
| 218 | UniqueName: '.?AUFoo@NS@@' | |
| 219 | DerivationList: 0 | |
| 220 | VTableShape: 0 | |
| 221 | Size: 4 | |
| 222 | - Kind: LF_STRING_ID | |
| 223 | StringId: | |
| 224 | Id: 0 | |
| 225 | String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' | |
| 226 | - Kind: LF_UDT_SRC_LINE | |
| 227 | UdtSourceLine: | |
| 228 | UDT: 4106 | |
| 229 | SourceFile: 4107 | |
| 230 | LineNumber: 2 | |
| 231 | - Kind: LF_FUNC_ID | |
| 232 | FuncId: | |
| 233 | ParentScope: 4096 | |
| 234 | FunctionType: 4101 | |
| 235 | Name: func | |
| 236 | - Name: '.debug$H' | |
| 237 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 238 | Alignment: 4 | |
| 239 | SectionData: C5C9330100000000EC145CD76AEFE74E78880D531132B3BB8FFACEF79E616EF06A14EA74A2420F9062A1FB04917E59759949E334BA18509ED692F3C65CE242D8450EBC78B81B63AF8316DC324562EB9F0D4A0D708E8A25C263DB05943C19B84A36719E1E414DDA3EDBDF005322238D70F9058EEDC5C50EF11BC849618B51FD89E3A50EABE5E8FE3945468547C19DC681D0BFB3B797DD91CA4D7F1953C314442D5549419E78044E38A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0C0A9021B711ACC4F67008974EBF441031BDD653F6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA0AF6C1846743F43D846BB19517E12E8873BBA90CC41DD1BEAC89CBA8897AC1BA46762E2557A82D89DCBC783AF285D9DBB672F67A81E36906B2038B57 | |
| 240 | GlobalHashes: | |
| 241 | Version: 0 | |
| 242 | HashAlgorithm: 0 | |
| 243 | HashValues: | |
| 244 | - EC145CD76AEFE74E78880D531132B3BB8FFACEF7 | |
| 245 | - 9E616EF06A14EA74A2420F9062A1FB04917E5975 | |
| 246 | - 9949E334BA18509ED692F3C65CE242D8450EBC78 | |
| 247 | - B81B63AF8316DC324562EB9F0D4A0D708E8A25C2 | |
| 248 | - 63DB05943C19B84A36719E1E414DDA3EDBDF0053 | |
| 249 | - 22238D70F9058EEDC5C50EF11BC849618B51FD89 | |
| 250 | - E3A50EABE5E8FE3945468547C19DC681D0BFB3B7 | |
| 251 | - 97DD91CA4D7F1953C314442D5549419E78044E38 | |
| 252 | - A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0 | |
| 253 | - C0A9021B711ACC4F67008974EBF441031BDD653F | |
| 254 | - 6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA | |
| 255 | - 0AF6C1846743F43D846BB19517E12E8873BBA90C | |
| 256 | - C41DD1BEAC89CBA8897AC1BA46762E2557A82D89 | |
| 257 | - DCBC783AF285D9DBB672F67A81E36906B2038B57 | |
| 258 | symbols: | |
| 259 | - Name: .text | |
| 260 | Value: 0 | |
| 261 | SectionNumber: 1 | |
| 262 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 263 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 264 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 265 | SectionDefinition: | |
| 266 | Length: 25 | |
| 267 | NumberOfRelocations: 0 | |
| 268 | NumberOfLinenumbers: 0 | |
| 269 | CheckSum: 1820185021 | |
| 270 | Number: 1 | |
| 271 | - Name: .data | |
| 272 | Value: 0 | |
| 273 | SectionNumber: 2 | |
| 274 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 275 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 276 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 277 | SectionDefinition: | |
| 278 | Length: 0 | |
| 279 | NumberOfRelocations: 0 | |
| 280 | NumberOfLinenumbers: 0 | |
| 281 | CheckSum: 0 | |
| 282 | Number: 2 | |
| 283 | - Name: .bss | |
| 284 | Value: 0 | |
| 285 | SectionNumber: 3 | |
| 286 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 287 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 288 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 289 | SectionDefinition: | |
| 290 | Length: 0 | |
| 291 | NumberOfRelocations: 0 | |
| 292 | NumberOfLinenumbers: 0 | |
| 293 | CheckSum: 0 | |
| 294 | Number: 3 | |
| 295 | - Name: .drectve | |
| 296 | Value: 0 | |
| 297 | SectionNumber: 4 | |
| 298 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 299 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 300 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 301 | SectionDefinition: | |
| 302 | Length: 48 | |
| 303 | NumberOfRelocations: 0 | |
| 304 | NumberOfLinenumbers: 0 | |
| 305 | CheckSum: 149686238 | |
| 306 | Number: 4 | |
| 307 | - Name: '.debug$S' | |
| 308 | Value: 0 | |
| 309 | SectionNumber: 5 | |
| 310 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 311 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 312 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 313 | SectionDefinition: | |
| 314 | Length: 584 | |
| 315 | NumberOfRelocations: 7 | |
| 316 | NumberOfLinenumbers: 0 | |
| 317 | CheckSum: 2847177244 | |
| 318 | Number: 5 | |
| 319 | - Name: '.debug$T' | |
| 320 | Value: 0 | |
| 321 | SectionNumber: 6 | |
| 322 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 323 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 324 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 325 | SectionDefinition: | |
| 326 | Length: 320 | |
| 327 | NumberOfRelocations: 0 | |
| 328 | NumberOfLinenumbers: 0 | |
| 329 | CheckSum: 2684556216 | |
| 330 | Number: 6 | |
| 331 | - Name: '.debug$H' | |
| 332 | Value: 0 | |
| 333 | SectionNumber: 7 | |
| 334 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 335 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 336 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 337 | SectionDefinition: | |
| 338 | Length: 288 | |
| 339 | NumberOfRelocations: 0 | |
| 340 | NumberOfLinenumbers: 0 | |
| 341 | CheckSum: 2348181452 | |
| 342 | Number: 7 | |
| 343 | - Name: '@feat.00' | |
| 344 | Value: 1 | |
| 345 | SectionNumber: -1 | |
| 346 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 347 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 348 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 349 | - Name: '?func@NS@@YAHABUFoo@1@@Z' | |
| 350 | Value: 0 | |
| 351 | SectionNumber: 1 | |
| 352 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 353 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 354 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 355 | ... |
deps/lld/test/COFF/Inputs/pdb-scopes-a.yaml+58-58| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | 1 | --- !COFF |
| 2 | header: | |
| 2 | header: | |
| 3 | 3 | Machine: IMAGE_FILE_MACHINE_AMD64 |
| 4 | 4 | Characteristics: [ ] |
| 5 | sections: | |
| 5 | sections: | |
| 6 | 6 | - Name: .drectve |
| 7 | 7 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] |
| 8 | 8 | Alignment: 1 |
| ... | ... | @@ -10,15 +10,15 @@ sections: |
| 10 | 10 | - Name: '.debug$S' |
| 11 | 11 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 12 | 12 | Alignment: 1 |
| 13 | Subsections: | |
| 13 | Subsections: | |
| 14 | 14 | - !Symbols |
| 15 | Records: | |
| 15 | Records: | |
| 16 | 16 | - Kind: S_OBJNAME |
| 17 | ObjNameSym: | |
| 17 | ObjNameSym: | |
| 18 | 18 | Signature: 0 |
| 19 | 19 | ObjectName: 'C:\src\llvm-project\build\a.obj' |
| 20 | 20 | - Kind: S_COMPILE3 |
| 21 | Compile3Sym: | |
| 21 | Compile3Sym: | |
| 22 | 22 | Flags: [ SecurityChecks, HotPatch ] |
| 23 | 23 | Machine: X64 |
| 24 | 24 | FrontendMajor: 19 |
| ... | ... | @@ -31,9 +31,9 @@ sections: |
| 31 | 31 | BackendQFE: 1 |
| 32 | 32 | Version: 'Microsoft (R) Optimizing Compiler' |
| 33 | 33 | - !Symbols |
| 34 | Records: | |
| 34 | Records: | |
| 35 | 35 | - Kind: S_GPROC32_ID |
| 36 | ProcSym: | |
| 36 | ProcSym: | |
| 37 | 37 | CodeSize: 5 |
| 38 | 38 | DbgStart: 4 |
| 39 | 39 | DbgEnd: 4 |
| ... | ... | @@ -41,7 +41,7 @@ sections: |
| 41 | 41 | Flags: [ ] |
| 42 | 42 | DisplayName: g |
| 43 | 43 | - Kind: S_FRAMEPROC |
| 44 | FrameProcSym: | |
| 44 | FrameProcSym: | |
| 45 | 45 | TotalFrameBytes: 0 |
| 46 | 46 | PaddingFrameBytes: 0 |
| 47 | 47 | OffsetToPadding: 0 |
| ... | ... | @@ -50,30 +50,30 @@ sections: |
| 50 | 50 | SectionIdOfExceptionHandler: 0 |
| 51 | 51 | Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] |
| 52 | 52 | - Kind: S_REGREL32 |
| 53 | RegRelativeSym: | |
| 53 | RegRelativeSym: | |
| 54 | 54 | Offset: 8 |
| 55 | 55 | Type: 116 |
| 56 | 56 | Register: RSP |
| 57 | 57 | VarName: x |
| 58 | 58 | - Kind: S_PROC_ID_END |
| 59 | ScopeEndSym: | |
| 59 | ScopeEndSym: | |
| 60 | 60 | - !Lines |
| 61 | 61 | CodeSize: 5 |
| 62 | 62 | Flags: [ ] |
| 63 | 63 | RelocOffset: 0 |
| 64 | 64 | RelocSegment: 0 |
| 65 | Blocks: | |
| 65 | Blocks: | |
| 66 | 66 | - FileName: 'c:\src\llvm-project\build\a.c' |
| 67 | Lines: | |
| 67 | Lines: | |
| 68 | 68 | - Offset: 0 |
| 69 | 69 | LineStart: 1 |
| 70 | 70 | IsStatement: true |
| 71 | 71 | EndDelta: 0 |
| 72 | Columns: | |
| 72 | Columns: | |
| 73 | 73 | - !Symbols |
| 74 | Records: | |
| 74 | Records: | |
| 75 | 75 | - Kind: S_GPROC32_ID |
| 76 | ProcSym: | |
| 76 | ProcSym: | |
| 77 | 77 | CodeSize: 58 |
| 78 | 78 | DbgStart: 8 |
| 79 | 79 | DbgEnd: 53 |
| ... | ... | @@ -81,7 +81,7 @@ sections: |
| 81 | 81 | Flags: [ ] |
| 82 | 82 | DisplayName: main |
| 83 | 83 | - Kind: S_FRAMEPROC |
| 84 | FrameProcSym: | |
| 84 | FrameProcSym: | |
| 85 | 85 | TotalFrameBytes: 56 |
| 86 | 86 | PaddingFrameBytes: 0 |
| 87 | 87 | OffsetToPadding: 0 |
| ... | ... | @@ -90,47 +90,47 @@ sections: |
| 90 | 90 | SectionIdOfExceptionHandler: 0 |
| 91 | 91 | Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] |
| 92 | 92 | - Kind: S_REGREL32 |
| 93 | RegRelativeSym: | |
| 93 | RegRelativeSym: | |
| 94 | 94 | Offset: 64 |
| 95 | 95 | Type: 116 |
| 96 | 96 | Register: RSP |
| 97 | 97 | VarName: argc |
| 98 | 98 | - Kind: S_BLOCK32 |
| 99 | BlockSym: | |
| 99 | BlockSym: | |
| 100 | 100 | CodeSize: 17 |
| 101 | 101 | Offset: 15 |
| 102 | 102 | BlockName: '' |
| 103 | 103 | - Kind: S_REGREL32 |
| 104 | RegRelativeSym: | |
| 104 | RegRelativeSym: | |
| 105 | 105 | Offset: 32 |
| 106 | 106 | Type: 116 |
| 107 | 107 | Register: RSP |
| 108 | 108 | VarName: x |
| 109 | 109 | - Kind: S_END |
| 110 | ScopeEndSym: | |
| 110 | ScopeEndSym: | |
| 111 | 111 | - Kind: S_BLOCK32 |
| 112 | BlockSym: | |
| 112 | BlockSym: | |
| 113 | 113 | CodeSize: 17 |
| 114 | 114 | Offset: 34 |
| 115 | 115 | BlockName: '' |
| 116 | 116 | - Kind: S_REGREL32 |
| 117 | RegRelativeSym: | |
| 117 | RegRelativeSym: | |
| 118 | 118 | Offset: 36 |
| 119 | 119 | Type: 116 |
| 120 | 120 | Register: RSP |
| 121 | 121 | VarName: y |
| 122 | 122 | - Kind: S_END |
| 123 | ScopeEndSym: | |
| 123 | ScopeEndSym: | |
| 124 | 124 | - Kind: S_PROC_ID_END |
| 125 | ScopeEndSym: | |
| 125 | ScopeEndSym: | |
| 126 | 126 | - !Lines |
| 127 | 127 | CodeSize: 58 |
| 128 | 128 | Flags: [ ] |
| 129 | 129 | RelocOffset: 0 |
| 130 | 130 | RelocSegment: 0 |
| 131 | Blocks: | |
| 131 | Blocks: | |
| 132 | 132 | - FileName: 'c:\src\llvm-project\build\a.c' |
| 133 | Lines: | |
| 133 | Lines: | |
| 134 | 134 | - Offset: 0 |
| 135 | 135 | LineStart: 3 |
| 136 | 136 | IsStatement: true |
| ... | ... | @@ -163,21 +163,21 @@ sections: |
| 163 | 163 | LineStart: 11 |
| 164 | 164 | IsStatement: true |
| 165 | 165 | EndDelta: 0 |
| 166 | Columns: | |
| 166 | Columns: | |
| 167 | 167 | - !FileChecksums |
| 168 | Checksums: | |
| 168 | Checksums: | |
| 169 | 169 | - FileName: 'c:\src\llvm-project\build\a.c' |
| 170 | 170 | Kind: MD5 |
| 171 | 171 | Checksum: 7FA72225C3F5630316383BD8BCC3EF72 |
| 172 | 172 | - !StringTable |
| 173 | Strings: | |
| 173 | Strings: | |
| 174 | 174 | - 'c:\src\llvm-project\build\a.c' |
| 175 | 175 | - !Symbols |
| 176 | Records: | |
| 176 | Records: | |
| 177 | 177 | - Kind: S_BUILDINFO |
| 178 | BuildInfoSym: | |
| 178 | BuildInfoSym: | |
| 179 | 179 | BuildId: 4110 |
| 180 | Relocations: | |
| 180 | Relocations: | |
| 181 | 181 | - VirtualAddress: 152 |
| 182 | 182 | SymbolName: g |
| 183 | 183 | Type: IMAGE_REL_AMD64_SECREL |
| ... | ... | @@ -217,78 +217,78 @@ sections: |
| 217 | 217 | - Name: '.debug$T' |
| 218 | 218 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 219 | 219 | Alignment: 1 |
| 220 | Types: | |
| 220 | Types: | |
| 221 | 221 | - Kind: LF_ARGLIST |
| 222 | ArgList: | |
| 222 | ArgList: | |
| 223 | 223 | ArgIndices: [ 116 ] |
| 224 | 224 | - Kind: LF_PROCEDURE |
| 225 | Procedure: | |
| 225 | Procedure: | |
| 226 | 226 | ReturnType: 3 |
| 227 | 227 | CallConv: NearC |
| 228 | 228 | Options: [ None ] |
| 229 | 229 | ParameterCount: 1 |
| 230 | 230 | ArgumentList: 4096 |
| 231 | 231 | - Kind: LF_POINTER |
| 232 | Pointer: | |
| 232 | Pointer: | |
| 233 | 233 | ReferentType: 4097 |
| 234 | 234 | Attrs: 65548 |
| 235 | 235 | - Kind: LF_FUNC_ID |
| 236 | FuncId: | |
| 236 | FuncId: | |
| 237 | 237 | ParentScope: 0 |
| 238 | 238 | FunctionType: 4097 |
| 239 | 239 | Name: g |
| 240 | 240 | - Kind: LF_PROCEDURE |
| 241 | Procedure: | |
| 241 | Procedure: | |
| 242 | 242 | ReturnType: 116 |
| 243 | 243 | CallConv: NearC |
| 244 | 244 | Options: [ None ] |
| 245 | 245 | ParameterCount: 1 |
| 246 | 246 | ArgumentList: 4096 |
| 247 | 247 | - Kind: LF_FUNC_ID |
| 248 | FuncId: | |
| 248 | FuncId: | |
| 249 | 249 | ParentScope: 0 |
| 250 | 250 | FunctionType: 4100 |
| 251 | 251 | Name: main |
| 252 | 252 | - Kind: LF_FUNC_ID |
| 253 | FuncId: | |
| 253 | FuncId: | |
| 254 | 254 | ParentScope: 0 |
| 255 | 255 | FunctionType: 4097 |
| 256 | 256 | Name: f |
| 257 | 257 | - Kind: LF_STRING_ID |
| 258 | StringId: | |
| 258 | StringId: | |
| 259 | 259 | Id: 0 |
| 260 | 260 | String: 'C:\src\llvm-project\build' |
| 261 | 261 | - Kind: LF_STRING_ID |
| 262 | StringId: | |
| 262 | StringId: | |
| 263 | 263 | Id: 0 |
| 264 | 264 | String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe' |
| 265 | 265 | - Kind: LF_STRING_ID |
| 266 | StringId: | |
| 266 | StringId: | |
| 267 | 267 | Id: 0 |
| 268 | 268 | String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um' |
| 269 | 269 | - Kind: LF_SUBSTR_LIST |
| 270 | StringList: | |
| 270 | StringList: | |
| 271 | 271 | StringIndices: [ 4105 ] |
| 272 | 272 | - Kind: LF_STRING_ID |
| 273 | StringId: | |
| 273 | StringId: | |
| 274 | 274 | Id: 4106 |
| 275 | 275 | String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X' |
| 276 | 276 | - Kind: LF_STRING_ID |
| 277 | StringId: | |
| 277 | StringId: | |
| 278 | 278 | Id: 0 |
| 279 | 279 | String: a.c |
| 280 | 280 | - Kind: LF_STRING_ID |
| 281 | StringId: | |
| 281 | StringId: | |
| 282 | 282 | Id: 0 |
| 283 | 283 | String: 'C:\src\llvm-project\build\vc140.pdb' |
| 284 | 284 | - Kind: LF_BUILDINFO |
| 285 | BuildInfo: | |
| 285 | BuildInfo: | |
| 286 | 286 | ArgIndices: [ 4103, 4104, 4108, 4109, 4107 ] |
| 287 | 287 | - Name: '.text$mn' |
| 288 | 288 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 289 | 289 | Alignment: 16 |
| 290 | 290 | SectionData: 894C2408C3CCCCCCCCCCCCCCCCCCCCCC894C24084883EC38837C2440007413C74424202A0000008B4C2420E800000000EB11C74424240D0000008B4C2424E80000000033C04883C438C3 |
| 291 | Relocations: | |
| 291 | Relocations: | |
| 292 | 292 | - VirtualAddress: 44 |
| 293 | 293 | SymbolName: f |
| 294 | 294 | Type: IMAGE_REL_AMD64_REL32 |
| ... | ... | @@ -303,7 +303,7 @@ sections: |
| 303 | 303 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] |
| 304 | 304 | Alignment: 4 |
| 305 | 305 | SectionData: 000000003A00000000000000 |
| 306 | Relocations: | |
| 306 | Relocations: | |
| 307 | 307 | - VirtualAddress: 0 |
| 308 | 308 | SymbolName: '$LN5' |
| 309 | 309 | Type: IMAGE_REL_AMD64_ADDR32NB |
| ... | ... | @@ -313,14 +313,14 @@ sections: |
| 313 | 313 | - VirtualAddress: 8 |
| 314 | 314 | SymbolName: '$unwind$main' |
| 315 | 315 | Type: IMAGE_REL_AMD64_ADDR32NB |
| 316 | symbols: | |
| 316 | symbols: | |
| 317 | 317 | - Name: .drectve |
| 318 | 318 | Value: 0 |
| 319 | 319 | SectionNumber: 1 |
| 320 | 320 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 321 | 321 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 322 | 322 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 323 | SectionDefinition: | |
| 323 | SectionDefinition: | |
| 324 | 324 | Length: 47 |
| 325 | 325 | NumberOfRelocations: 0 |
| 326 | 326 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -332,7 +332,7 @@ symbols: |
| 332 | 332 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 333 | 333 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 334 | 334 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 335 | SectionDefinition: | |
| 335 | SectionDefinition: | |
| 336 | 336 | Length: 628 |
| 337 | 337 | NumberOfRelocations: 12 |
| 338 | 338 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -344,7 +344,7 @@ symbols: |
| 344 | 344 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 345 | 345 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 346 | 346 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 347 | SectionDefinition: | |
| 347 | SectionDefinition: | |
| 348 | 348 | Length: 624 |
| 349 | 349 | NumberOfRelocations: 0 |
| 350 | 350 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -356,7 +356,7 @@ symbols: |
| 356 | 356 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 357 | 357 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 358 | 358 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 359 | SectionDefinition: | |
| 359 | SectionDefinition: | |
| 360 | 360 | Length: 74 |
| 361 | 361 | NumberOfRelocations: 2 |
| 362 | 362 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -392,7 +392,7 @@ symbols: |
| 392 | 392 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 393 | 393 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 394 | 394 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 395 | SectionDefinition: | |
| 395 | SectionDefinition: | |
| 396 | 396 | Length: 8 |
| 397 | 397 | NumberOfRelocations: 0 |
| 398 | 398 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -410,7 +410,7 @@ symbols: |
| 410 | 410 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 411 | 411 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 412 | 412 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 413 | SectionDefinition: | |
| 413 | SectionDefinition: | |
| 414 | 414 | Length: 12 |
| 415 | 415 | NumberOfRelocations: 3 |
| 416 | 416 | NumberOfLinenumbers: 0 |
deps/lld/test/COFF/Inputs/pdb-scopes-b.yaml+50-50| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | 1 | --- !COFF |
| 2 | header: | |
| 2 | header: | |
| 3 | 3 | Machine: IMAGE_FILE_MACHINE_AMD64 |
| 4 | 4 | Characteristics: [ ] |
| 5 | sections: | |
| 5 | sections: | |
| 6 | 6 | - Name: .drectve |
| 7 | 7 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] |
| 8 | 8 | Alignment: 1 |
| ... | ... | @@ -10,15 +10,15 @@ sections: |
| 10 | 10 | - Name: '.debug$S' |
| 11 | 11 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 12 | 12 | Alignment: 1 |
| 13 | Subsections: | |
| 13 | Subsections: | |
| 14 | 14 | - !Symbols |
| 15 | Records: | |
| 15 | Records: | |
| 16 | 16 | - Kind: S_OBJNAME |
| 17 | ObjNameSym: | |
| 17 | ObjNameSym: | |
| 18 | 18 | Signature: 0 |
| 19 | 19 | ObjectName: 'C:\src\llvm-project\build\b.obj' |
| 20 | 20 | - Kind: S_COMPILE3 |
| 21 | Compile3Sym: | |
| 21 | Compile3Sym: | |
| 22 | 22 | Flags: [ SecurityChecks, HotPatch ] |
| 23 | 23 | Machine: X64 |
| 24 | 24 | FrontendMajor: 19 |
| ... | ... | @@ -31,9 +31,9 @@ sections: |
| 31 | 31 | BackendQFE: 1 |
| 32 | 32 | Version: 'Microsoft (R) Optimizing Compiler' |
| 33 | 33 | - !Symbols |
| 34 | Records: | |
| 34 | Records: | |
| 35 | 35 | - Kind: S_GPROC32_ID |
| 36 | ProcSym: | |
| 36 | ProcSym: | |
| 37 | 37 | CodeSize: 62 |
| 38 | 38 | DbgStart: 8 |
| 39 | 39 | DbgEnd: 57 |
| ... | ... | @@ -41,7 +41,7 @@ sections: |
| 41 | 41 | Flags: [ ] |
| 42 | 42 | DisplayName: f |
| 43 | 43 | - Kind: S_FRAMEPROC |
| 44 | FrameProcSym: | |
| 44 | FrameProcSym: | |
| 45 | 45 | TotalFrameBytes: 56 |
| 46 | 46 | PaddingFrameBytes: 0 |
| 47 | 47 | OffsetToPadding: 0 |
| ... | ... | @@ -50,47 +50,47 @@ sections: |
| 50 | 50 | SectionIdOfExceptionHandler: 0 |
| 51 | 51 | Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] |
| 52 | 52 | - Kind: S_REGREL32 |
| 53 | RegRelativeSym: | |
| 53 | RegRelativeSym: | |
| 54 | 54 | Offset: 64 |
| 55 | 55 | Type: 116 |
| 56 | 56 | Register: RSP |
| 57 | 57 | VarName: x |
| 58 | 58 | - Kind: S_BLOCK32 |
| 59 | BlockSym: | |
| 59 | BlockSym: | |
| 60 | 60 | CodeSize: 20 |
| 61 | 61 | Offset: 15 |
| 62 | 62 | BlockName: '' |
| 63 | 63 | - Kind: S_REGREL32 |
| 64 | RegRelativeSym: | |
| 64 | RegRelativeSym: | |
| 65 | 65 | Offset: 32 |
| 66 | 66 | Type: 116 |
| 67 | 67 | Register: RSP |
| 68 | 68 | VarName: y |
| 69 | 69 | - Kind: S_END |
| 70 | ScopeEndSym: | |
| 70 | ScopeEndSym: | |
| 71 | 71 | - Kind: S_BLOCK32 |
| 72 | BlockSym: | |
| 72 | BlockSym: | |
| 73 | 73 | CodeSize: 20 |
| 74 | 74 | Offset: 37 |
| 75 | 75 | BlockName: '' |
| 76 | 76 | - Kind: S_REGREL32 |
| 77 | RegRelativeSym: | |
| 77 | RegRelativeSym: | |
| 78 | 78 | Offset: 36 |
| 79 | 79 | Type: 116 |
| 80 | 80 | Register: RSP |
| 81 | 81 | VarName: w |
| 82 | 82 | - Kind: S_END |
| 83 | ScopeEndSym: | |
| 83 | ScopeEndSym: | |
| 84 | 84 | - Kind: S_PROC_ID_END |
| 85 | ScopeEndSym: | |
| 85 | ScopeEndSym: | |
| 86 | 86 | - !Lines |
| 87 | 87 | CodeSize: 62 |
| 88 | 88 | Flags: [ ] |
| 89 | 89 | RelocOffset: 0 |
| 90 | 90 | RelocSegment: 0 |
| 91 | Blocks: | |
| 91 | Blocks: | |
| 92 | 92 | - FileName: 'c:\src\llvm-project\build\b.c' |
| 93 | Lines: | |
| 93 | Lines: | |
| 94 | 94 | - Offset: 0 |
| 95 | 95 | LineStart: 2 |
| 96 | 96 | IsStatement: true |
| ... | ... | @@ -123,21 +123,21 @@ sections: |
| 123 | 123 | LineStart: 10 |
| 124 | 124 | IsStatement: true |
| 125 | 125 | EndDelta: 0 |
| 126 | Columns: | |
| 126 | Columns: | |
| 127 | 127 | - !FileChecksums |
| 128 | Checksums: | |
| 128 | Checksums: | |
| 129 | 129 | - FileName: 'c:\src\llvm-project\build\b.c' |
| 130 | 130 | Kind: MD5 |
| 131 | 131 | Checksum: 8E8C92DB46478902EBEAEBFCFF15A6E0 |
| 132 | 132 | - !StringTable |
| 133 | Strings: | |
| 133 | Strings: | |
| 134 | 134 | - 'c:\src\llvm-project\build\b.c' |
| 135 | 135 | - !Symbols |
| 136 | Records: | |
| 136 | Records: | |
| 137 | 137 | - Kind: S_BUILDINFO |
| 138 | BuildInfoSym: | |
| 138 | BuildInfoSym: | |
| 139 | 139 | BuildId: 4110 |
| 140 | Relocations: | |
| 140 | Relocations: | |
| 141 | 141 | - VirtualAddress: 152 |
| 142 | 142 | SymbolName: f |
| 143 | 143 | Type: IMAGE_REL_AMD64_SECREL |
| ... | ... | @@ -165,76 +165,76 @@ sections: |
| 165 | 165 | - Name: '.debug$T' |
| 166 | 166 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 167 | 167 | Alignment: 1 |
| 168 | Types: | |
| 168 | Types: | |
| 169 | 169 | - Kind: LF_ARGLIST |
| 170 | ArgList: | |
| 170 | ArgList: | |
| 171 | 171 | ArgIndices: [ 0 ] |
| 172 | 172 | - Kind: LF_PROCEDURE |
| 173 | Procedure: | |
| 173 | Procedure: | |
| 174 | 174 | ReturnType: 3 |
| 175 | 175 | CallConv: NearC |
| 176 | 176 | Options: [ None ] |
| 177 | 177 | ParameterCount: 0 |
| 178 | 178 | ArgumentList: 4096 |
| 179 | 179 | - Kind: LF_POINTER |
| 180 | Pointer: | |
| 180 | Pointer: | |
| 181 | 181 | ReferentType: 4097 |
| 182 | 182 | Attrs: 65548 |
| 183 | 183 | - Kind: LF_ARGLIST |
| 184 | ArgList: | |
| 184 | ArgList: | |
| 185 | 185 | ArgIndices: [ 116 ] |
| 186 | 186 | - Kind: LF_PROCEDURE |
| 187 | Procedure: | |
| 187 | Procedure: | |
| 188 | 188 | ReturnType: 3 |
| 189 | 189 | CallConv: NearC |
| 190 | 190 | Options: [ None ] |
| 191 | 191 | ParameterCount: 1 |
| 192 | 192 | ArgumentList: 4099 |
| 193 | 193 | - Kind: LF_FUNC_ID |
| 194 | FuncId: | |
| 194 | FuncId: | |
| 195 | 195 | ParentScope: 0 |
| 196 | 196 | FunctionType: 4100 |
| 197 | 197 | Name: f |
| 198 | 198 | - Kind: LF_FUNC_ID |
| 199 | FuncId: | |
| 199 | FuncId: | |
| 200 | 200 | ParentScope: 0 |
| 201 | 201 | FunctionType: 4097 |
| 202 | 202 | Name: g |
| 203 | 203 | - Kind: LF_STRING_ID |
| 204 | StringId: | |
| 204 | StringId: | |
| 205 | 205 | Id: 0 |
| 206 | 206 | String: 'C:\src\llvm-project\build' |
| 207 | 207 | - Kind: LF_STRING_ID |
| 208 | StringId: | |
| 208 | StringId: | |
| 209 | 209 | Id: 0 |
| 210 | 210 | String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe' |
| 211 | 211 | - Kind: LF_STRING_ID |
| 212 | StringId: | |
| 212 | StringId: | |
| 213 | 213 | Id: 0 |
| 214 | 214 | String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um' |
| 215 | 215 | - Kind: LF_SUBSTR_LIST |
| 216 | StringList: | |
| 216 | StringList: | |
| 217 | 217 | StringIndices: [ 4105 ] |
| 218 | 218 | - Kind: LF_STRING_ID |
| 219 | StringId: | |
| 219 | StringId: | |
| 220 | 220 | Id: 4106 |
| 221 | 221 | String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X' |
| 222 | 222 | - Kind: LF_STRING_ID |
| 223 | StringId: | |
| 223 | StringId: | |
| 224 | 224 | Id: 0 |
| 225 | 225 | String: b.c |
| 226 | 226 | - Kind: LF_STRING_ID |
| 227 | StringId: | |
| 227 | StringId: | |
| 228 | 228 | Id: 0 |
| 229 | 229 | String: 'C:\src\llvm-project\build\vc140.pdb' |
| 230 | 230 | - Kind: LF_BUILDINFO |
| 231 | BuildInfo: | |
| 231 | BuildInfo: | |
| 232 | 232 | ArgIndices: [ 4103, 4104, 4108, 4109, 4107 ] |
| 233 | 233 | - Name: '.text$mn' |
| 234 | 234 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 235 | 235 | Alignment: 16 |
| 236 | 236 | SectionData: 894C24084883EC38837C24400074168B44244083C003894424208B4C2420E800000000EB148B44244083C004894424248B4C2424E8000000004883C438C3 |
| 237 | Relocations: | |
| 237 | Relocations: | |
| 238 | 238 | - VirtualAddress: 31 |
| 239 | 239 | SymbolName: g |
| 240 | 240 | Type: IMAGE_REL_AMD64_REL32 |
| ... | ... | @@ -249,7 +249,7 @@ sections: |
| 249 | 249 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] |
| 250 | 250 | Alignment: 4 |
| 251 | 251 | SectionData: '000000003E00000000000000' |
| 252 | Relocations: | |
| 252 | Relocations: | |
| 253 | 253 | - VirtualAddress: 0 |
| 254 | 254 | SymbolName: '$LN5' |
| 255 | 255 | Type: IMAGE_REL_AMD64_ADDR32NB |
| ... | ... | @@ -259,14 +259,14 @@ sections: |
| 259 | 259 | - VirtualAddress: 8 |
| 260 | 260 | SymbolName: '$unwind$f' |
| 261 | 261 | Type: IMAGE_REL_AMD64_ADDR32NB |
| 262 | symbols: | |
| 262 | symbols: | |
| 263 | 263 | - Name: .drectve |
| 264 | 264 | Value: 0 |
| 265 | 265 | SectionNumber: 1 |
| 266 | 266 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 267 | 267 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 268 | 268 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 269 | SectionDefinition: | |
| 269 | SectionDefinition: | |
| 270 | 270 | Length: 47 |
| 271 | 271 | NumberOfRelocations: 0 |
| 272 | 272 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -278,7 +278,7 @@ symbols: |
| 278 | 278 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 279 | 279 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 280 | 280 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 281 | SectionDefinition: | |
| 281 | SectionDefinition: | |
| 282 | 282 | Length: 484 |
| 283 | 283 | NumberOfRelocations: 8 |
| 284 | 284 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -290,7 +290,7 @@ symbols: |
| 290 | 290 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 291 | 291 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 292 | 292 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 293 | SectionDefinition: | |
| 293 | SectionDefinition: | |
| 294 | 294 | Length: 616 |
| 295 | 295 | NumberOfRelocations: 0 |
| 296 | 296 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -302,7 +302,7 @@ symbols: |
| 302 | 302 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 303 | 303 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 304 | 304 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 305 | SectionDefinition: | |
| 305 | SectionDefinition: | |
| 306 | 306 | Length: 62 |
| 307 | 307 | NumberOfRelocations: 2 |
| 308 | 308 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -332,7 +332,7 @@ symbols: |
| 332 | 332 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 333 | 333 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 334 | 334 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 335 | SectionDefinition: | |
| 335 | SectionDefinition: | |
| 336 | 336 | Length: 8 |
| 337 | 337 | NumberOfRelocations: 0 |
| 338 | 338 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -350,7 +350,7 @@ symbols: |
| 350 | 350 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 351 | 351 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 352 | 352 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 353 | SectionDefinition: | |
| 353 | SectionDefinition: | |
| 354 | 354 | Length: 12 |
| 355 | 355 | NumberOfRelocations: 3 |
| 356 | 356 | NumberOfLinenumbers: 0 |
deps/lld/test/COFF/Inputs/pdb_comdat_bar.yaml+58-58| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | 1 | --- !COFF |
| 2 | header: | |
| 2 | header: | |
| 3 | 3 | Machine: IMAGE_FILE_MACHINE_AMD64 |
| 4 | 4 | Characteristics: [ ] |
| 5 | sections: | |
| 5 | sections: | |
| 6 | 6 | - Name: .drectve |
| 7 | 7 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] |
| 8 | 8 | Alignment: 1 |
| ... | ... | @@ -10,15 +10,15 @@ sections: |
| 10 | 10 | - Name: '.debug$S' |
| 11 | 11 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 12 | 12 | Alignment: 1 |
| 13 | Subsections: | |
| 13 | Subsections: | |
| 14 | 14 | - !Symbols |
| 15 | Records: | |
| 15 | Records: | |
| 16 | 16 | - Kind: S_OBJNAME |
| 17 | ObjNameSym: | |
| 17 | ObjNameSym: | |
| 18 | 18 | Signature: 0 |
| 19 | 19 | ObjectName: 'C:\src\llvm-project\build\pdb_comdat_bar.obj' |
| 20 | 20 | - Kind: S_COMPILE3 |
| 21 | Compile3Sym: | |
| 21 | Compile3Sym: | |
| 22 | 22 | Flags: [ SecurityChecks, HotPatch ] |
| 23 | 23 | Machine: X64 |
| 24 | 24 | FrontendMajor: 19 |
| ... | ... | @@ -31,9 +31,9 @@ sections: |
| 31 | 31 | BackendQFE: 1 |
| 32 | 32 | Version: 'Microsoft (R) Optimizing Compiler' |
| 33 | 33 | - !Symbols |
| 34 | Records: | |
| 34 | Records: | |
| 35 | 35 | - Kind: S_GPROC32_ID |
| 36 | ProcSym: | |
| 36 | ProcSym: | |
| 37 | 37 | PtrParent: 0 |
| 38 | 38 | PtrEnd: 0 |
| 39 | 39 | PtrNext: 0 |
| ... | ... | @@ -45,7 +45,7 @@ sections: |
| 45 | 45 | Flags: [ ] |
| 46 | 46 | DisplayName: bar |
| 47 | 47 | - Kind: S_FRAMEPROC |
| 48 | FrameProcSym: | |
| 48 | FrameProcSym: | |
| 49 | 49 | TotalFrameBytes: 40 |
| 50 | 50 | PaddingFrameBytes: 0 |
| 51 | 51 | OffsetToPadding: 0 |
| ... | ... | @@ -54,15 +54,15 @@ sections: |
| 54 | 54 | SectionIdOfExceptionHandler: 0 |
| 55 | 55 | Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] |
| 56 | 56 | - Kind: S_PROC_ID_END |
| 57 | ScopeEndSym: | |
| 57 | ScopeEndSym: | |
| 58 | 58 | - !Lines |
| 59 | 59 | CodeSize: 14 |
| 60 | 60 | Flags: [ ] |
| 61 | 61 | RelocOffset: 0 |
| 62 | 62 | RelocSegment: 0 |
| 63 | Blocks: | |
| 63 | Blocks: | |
| 64 | 64 | - FileName: 'c:\src\llvm-project\build\pdb_comdat_bar.c' |
| 65 | Lines: | |
| 65 | Lines: | |
| 66 | 66 | - Offset: 0 |
| 67 | 67 | LineStart: 3 |
| 68 | 68 | IsStatement: true |
| ... | ... | @@ -75,15 +75,15 @@ sections: |
| 75 | 75 | LineStart: 5 |
| 76 | 76 | IsStatement: true |
| 77 | 77 | EndDelta: 0 |
| 78 | Columns: | |
| 78 | Columns: | |
| 79 | 79 | - !Symbols |
| 80 | Records: | |
| 80 | Records: | |
| 81 | 81 | - Kind: S_GDATA32 |
| 82 | DataSym: | |
| 82 | DataSym: | |
| 83 | 83 | Type: 116 |
| 84 | 84 | DisplayName: global |
| 85 | 85 | - !FileChecksums |
| 86 | Checksums: | |
| 86 | Checksums: | |
| 87 | 87 | - FileName: 'c:\src\llvm-project\build\pdb_comdat_bar.c' |
| 88 | 88 | Kind: MD5 |
| 89 | 89 | Checksum: 365279DB4FCBEDD721BBFC3B14A953C2 |
| ... | ... | @@ -91,15 +91,15 @@ sections: |
| 91 | 91 | Kind: MD5 |
| 92 | 92 | Checksum: D74D834EFAC3AE2B45E606A8320B1D5C |
| 93 | 93 | - !StringTable |
| 94 | Strings: | |
| 94 | Strings: | |
| 95 | 95 | - 'c:\src\llvm-project\build\pdb_comdat_bar.c' |
| 96 | 96 | - 'c:\src\llvm-project\build\foo.h' |
| 97 | 97 | - !Symbols |
| 98 | Records: | |
| 98 | Records: | |
| 99 | 99 | - Kind: S_BUILDINFO |
| 100 | BuildInfoSym: | |
| 100 | BuildInfoSym: | |
| 101 | 101 | BuildId: 4110 |
| 102 | Relocations: | |
| 102 | Relocations: | |
| 103 | 103 | - VirtualAddress: 168 |
| 104 | 104 | SymbolName: bar |
| 105 | 105 | Type: IMAGE_REL_AMD64_SECREL |
| ... | ... | @@ -121,70 +121,70 @@ sections: |
| 121 | 121 | - Name: '.debug$T' |
| 122 | 122 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 123 | 123 | Alignment: 1 |
| 124 | Types: | |
| 124 | Types: | |
| 125 | 125 | - Kind: LF_ARGLIST |
| 126 | ArgList: | |
| 126 | ArgList: | |
| 127 | 127 | ArgIndices: [ 0 ] |
| 128 | 128 | - Kind: LF_PROCEDURE |
| 129 | Procedure: | |
| 129 | Procedure: | |
| 130 | 130 | ReturnType: 3 |
| 131 | 131 | CallConv: NearC |
| 132 | 132 | Options: [ None ] |
| 133 | 133 | ParameterCount: 0 |
| 134 | 134 | ArgumentList: 4096 |
| 135 | 135 | - Kind: LF_POINTER |
| 136 | Pointer: | |
| 136 | Pointer: | |
| 137 | 137 | ReferentType: 4097 |
| 138 | 138 | Attrs: 65548 |
| 139 | 139 | - Kind: LF_FUNC_ID |
| 140 | FuncId: | |
| 140 | FuncId: | |
| 141 | 141 | ParentScope: 0 |
| 142 | 142 | FunctionType: 4097 |
| 143 | 143 | Name: foo |
| 144 | 144 | - Kind: LF_ARGLIST |
| 145 | ArgList: | |
| 145 | ArgList: | |
| 146 | 146 | ArgIndices: [ ] |
| 147 | 147 | - Kind: LF_PROCEDURE |
| 148 | Procedure: | |
| 148 | Procedure: | |
| 149 | 149 | ReturnType: 3 |
| 150 | 150 | CallConv: NearC |
| 151 | 151 | Options: [ None ] |
| 152 | 152 | ParameterCount: 0 |
| 153 | 153 | ArgumentList: 4100 |
| 154 | 154 | - Kind: LF_FUNC_ID |
| 155 | FuncId: | |
| 155 | FuncId: | |
| 156 | 156 | ParentScope: 0 |
| 157 | 157 | FunctionType: 4101 |
| 158 | 158 | Name: bar |
| 159 | 159 | - Kind: LF_STRING_ID |
| 160 | StringId: | |
| 160 | StringId: | |
| 161 | 161 | Id: 0 |
| 162 | 162 | String: 'C:\src\llvm-project\build' |
| 163 | 163 | - Kind: LF_STRING_ID |
| 164 | StringId: | |
| 164 | StringId: | |
| 165 | 165 | Id: 0 |
| 166 | 166 | String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe' |
| 167 | 167 | - Kind: LF_STRING_ID |
| 168 | StringId: | |
| 168 | StringId: | |
| 169 | 169 | Id: 0 |
| 170 | 170 | String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um' |
| 171 | 171 | - Kind: LF_SUBSTR_LIST |
| 172 | StringList: | |
| 172 | StringList: | |
| 173 | 173 | StringIndices: [ 4105 ] |
| 174 | 174 | - Kind: LF_STRING_ID |
| 175 | StringId: | |
| 175 | StringId: | |
| 176 | 176 | Id: 4106 |
| 177 | 177 | String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X' |
| 178 | 178 | - Kind: LF_STRING_ID |
| 179 | StringId: | |
| 179 | StringId: | |
| 180 | 180 | Id: 0 |
| 181 | 181 | String: pdb_comdat_bar.c |
| 182 | 182 | - Kind: LF_STRING_ID |
| 183 | StringId: | |
| 183 | StringId: | |
| 184 | 184 | Id: 0 |
| 185 | 185 | String: 'C:\src\llvm-project\build\vc140.pdb' |
| 186 | 186 | - Kind: LF_BUILDINFO |
| 187 | BuildInfo: | |
| 187 | BuildInfo: | |
| 188 | 188 | ArgIndices: [ 4103, 4104, 4108, 4109, 4107 ] |
| 189 | 189 | - Name: .bss |
| 190 | 190 | Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] |
| ... | ... | @@ -194,7 +194,7 @@ sections: |
| 194 | 194 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 195 | 195 | Alignment: 16 |
| 196 | 196 | SectionData: 4883EC28E8000000004883C428C3 |
| 197 | Relocations: | |
| 197 | Relocations: | |
| 198 | 198 | - VirtualAddress: 5 |
| 199 | 199 | SymbolName: foo |
| 200 | 200 | Type: IMAGE_REL_AMD64_REL32 |
| ... | ... | @@ -202,7 +202,7 @@ sections: |
| 202 | 202 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 203 | 203 | Alignment: 16 |
| 204 | 204 | SectionData: 8B0500000000FFC0890500000000C3 |
| 205 | Relocations: | |
| 205 | Relocations: | |
| 206 | 206 | - VirtualAddress: 2 |
| 207 | 207 | SymbolName: global |
| 208 | 208 | Type: IMAGE_REL_AMD64_REL32 |
| ... | ... | @@ -212,11 +212,11 @@ sections: |
| 212 | 212 | - Name: '.debug$S' |
| 213 | 213 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 214 | 214 | Alignment: 1 |
| 215 | Subsections: | |
| 215 | Subsections: | |
| 216 | 216 | - !Symbols |
| 217 | Records: | |
| 217 | Records: | |
| 218 | 218 | - Kind: S_GPROC32_ID |
| 219 | ProcSym: | |
| 219 | ProcSym: | |
| 220 | 220 | PtrParent: 0 |
| 221 | 221 | PtrEnd: 0 |
| 222 | 222 | PtrNext: 0 |
| ... | ... | @@ -228,7 +228,7 @@ sections: |
| 228 | 228 | Flags: [ ] |
| 229 | 229 | DisplayName: foo |
| 230 | 230 | - Kind: S_FRAMEPROC |
| 231 | FrameProcSym: | |
| 231 | FrameProcSym: | |
| 232 | 232 | TotalFrameBytes: 0 |
| 233 | 233 | PaddingFrameBytes: 0 |
| 234 | 234 | OffsetToPadding: 0 |
| ... | ... | @@ -237,15 +237,15 @@ sections: |
| 237 | 237 | SectionIdOfExceptionHandler: 0 |
| 238 | 238 | Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ] |
| 239 | 239 | - Kind: S_PROC_ID_END |
| 240 | ScopeEndSym: | |
| 240 | ScopeEndSym: | |
| 241 | 241 | - !Lines |
| 242 | 242 | CodeSize: 15 |
| 243 | 243 | Flags: [ ] |
| 244 | 244 | RelocOffset: 0 |
| 245 | 245 | RelocSegment: 0 |
| 246 | Blocks: | |
| 246 | Blocks: | |
| 247 | 247 | - FileName: 'c:\src\llvm-project\build\foo.h' |
| 248 | Lines: | |
| 248 | Lines: | |
| 249 | 249 | - Offset: 0 |
| 250 | 250 | LineStart: 2 |
| 251 | 251 | IsStatement: true |
| ... | ... | @@ -258,8 +258,8 @@ sections: |
| 258 | 258 | LineStart: 4 |
| 259 | 259 | IsStatement: true |
| 260 | 260 | EndDelta: 0 |
| 261 | Columns: | |
| 262 | Relocations: | |
| 261 | Columns: | |
| 262 | Relocations: | |
| 263 | 263 | - VirtualAddress: 44 |
| 264 | 264 | SymbolName: foo |
| 265 | 265 | Type: IMAGE_REL_AMD64_SECREL |
| ... | ... | @@ -280,7 +280,7 @@ sections: |
| 280 | 280 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] |
| 281 | 281 | Alignment: 4 |
| 282 | 282 | SectionData: '000000000E00000000000000' |
| 283 | Relocations: | |
| 283 | Relocations: | |
| 284 | 284 | - VirtualAddress: 0 |
| 285 | 285 | SymbolName: '$LN3' |
| 286 | 286 | Type: IMAGE_REL_AMD64_ADDR32NB |
| ... | ... | @@ -290,14 +290,14 @@ sections: |
| 290 | 290 | - VirtualAddress: 8 |
| 291 | 291 | SymbolName: '$unwind$bar' |
| 292 | 292 | Type: IMAGE_REL_AMD64_ADDR32NB |
| 293 | symbols: | |
| 293 | symbols: | |
| 294 | 294 | - Name: .drectve |
| 295 | 295 | Value: 0 |
| 296 | 296 | SectionNumber: 1 |
| 297 | 297 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 298 | 298 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 299 | 299 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 300 | SectionDefinition: | |
| 300 | SectionDefinition: | |
| 301 | 301 | Length: 47 |
| 302 | 302 | NumberOfRelocations: 0 |
| 303 | 303 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -309,7 +309,7 @@ symbols: |
| 309 | 309 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 310 | 310 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 311 | 311 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 312 | SectionDefinition: | |
| 312 | SectionDefinition: | |
| 313 | 313 | Length: 460 |
| 314 | 314 | NumberOfRelocations: 6 |
| 315 | 315 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -321,7 +321,7 @@ symbols: |
| 321 | 321 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 322 | 322 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 323 | 323 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 324 | SectionDefinition: | |
| 324 | SectionDefinition: | |
| 325 | 325 | Length: 628 |
| 326 | 326 | NumberOfRelocations: 0 |
| 327 | 327 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -333,7 +333,7 @@ symbols: |
| 333 | 333 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 334 | 334 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 335 | 335 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 336 | SectionDefinition: | |
| 336 | SectionDefinition: | |
| 337 | 337 | Length: 4 |
| 338 | 338 | NumberOfRelocations: 0 |
| 339 | 339 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -351,7 +351,7 @@ symbols: |
| 351 | 351 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 352 | 352 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 353 | 353 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 354 | SectionDefinition: | |
| 354 | SectionDefinition: | |
| 355 | 355 | Length: 14 |
| 356 | 356 | NumberOfRelocations: 1 |
| 357 | 357 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -363,7 +363,7 @@ symbols: |
| 363 | 363 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 364 | 364 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 365 | 365 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 366 | SectionDefinition: | |
| 366 | SectionDefinition: | |
| 367 | 367 | Length: 15 |
| 368 | 368 | NumberOfRelocations: 2 |
| 369 | 369 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -376,7 +376,7 @@ symbols: |
| 376 | 376 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 377 | 377 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 378 | 378 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 379 | SectionDefinition: | |
| 379 | SectionDefinition: | |
| 380 | 380 | Length: 148 |
| 381 | 381 | NumberOfRelocations: 4 |
| 382 | 382 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -407,7 +407,7 @@ symbols: |
| 407 | 407 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 408 | 408 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 409 | 409 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 410 | SectionDefinition: | |
| 410 | SectionDefinition: | |
| 411 | 411 | Length: 8 |
| 412 | 412 | NumberOfRelocations: 0 |
| 413 | 413 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -425,7 +425,7 @@ symbols: |
| 425 | 425 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 426 | 426 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 427 | 427 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 428 | SectionDefinition: | |
| 428 | SectionDefinition: | |
| 429 | 429 | Length: 12 |
| 430 | 430 | NumberOfRelocations: 3 |
| 431 | 431 | NumberOfLinenumbers: 0 |
deps/lld/test/COFF/Inputs/pdb_comdat_main.yaml+58-58| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | 1 | --- !COFF |
| 2 | header: | |
| 2 | header: | |
| 3 | 3 | Machine: IMAGE_FILE_MACHINE_AMD64 |
| 4 | 4 | Characteristics: [ ] |
| 5 | sections: | |
| 5 | sections: | |
| 6 | 6 | - Name: .drectve |
| 7 | 7 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] |
| 8 | 8 | Alignment: 1 |
| ... | ... | @@ -10,15 +10,15 @@ sections: |
| 10 | 10 | - Name: '.debug$S' |
| 11 | 11 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 12 | 12 | Alignment: 1 |
| 13 | Subsections: | |
| 13 | Subsections: | |
| 14 | 14 | - !Symbols |
| 15 | Records: | |
| 15 | Records: | |
| 16 | 16 | - Kind: S_OBJNAME |
| 17 | ObjNameSym: | |
| 17 | ObjNameSym: | |
| 18 | 18 | Signature: 0 |
| 19 | 19 | ObjectName: 'C:\src\llvm-project\build\pdb_comdat_main.obj' |
| 20 | 20 | - Kind: S_COMPILE3 |
| 21 | Compile3Sym: | |
| 21 | Compile3Sym: | |
| 22 | 22 | Flags: [ SecurityChecks, HotPatch ] |
| 23 | 23 | Machine: X64 |
| 24 | 24 | FrontendMajor: 19 |
| ... | ... | @@ -31,9 +31,9 @@ sections: |
| 31 | 31 | BackendQFE: 1 |
| 32 | 32 | Version: 'Microsoft (R) Optimizing Compiler' |
| 33 | 33 | - !Symbols |
| 34 | Records: | |
| 34 | Records: | |
| 35 | 35 | - Kind: S_GPROC32_ID |
| 36 | ProcSym: | |
| 36 | ProcSym: | |
| 37 | 37 | PtrParent: 0 |
| 38 | 38 | PtrEnd: 0 |
| 39 | 39 | PtrNext: 0 |
| ... | ... | @@ -45,7 +45,7 @@ sections: |
| 45 | 45 | Flags: [ ] |
| 46 | 46 | DisplayName: main |
| 47 | 47 | - Kind: S_FRAMEPROC |
| 48 | FrameProcSym: | |
| 48 | FrameProcSym: | |
| 49 | 49 | TotalFrameBytes: 40 |
| 50 | 50 | PaddingFrameBytes: 0 |
| 51 | 51 | OffsetToPadding: 0 |
| ... | ... | @@ -54,15 +54,15 @@ sections: |
| 54 | 54 | SectionIdOfExceptionHandler: 0 |
| 55 | 55 | Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] |
| 56 | 56 | - Kind: S_PROC_ID_END |
| 57 | ScopeEndSym: | |
| 57 | ScopeEndSym: | |
| 58 | 58 | - !Lines |
| 59 | 59 | CodeSize: 24 |
| 60 | 60 | Flags: [ ] |
| 61 | 61 | RelocOffset: 0 |
| 62 | 62 | RelocSegment: 0 |
| 63 | Blocks: | |
| 63 | Blocks: | |
| 64 | 64 | - FileName: 'c:\src\llvm-project\build\pdb_comdat_main.c' |
| 65 | Lines: | |
| 65 | Lines: | |
| 66 | 66 | - Offset: 0 |
| 67 | 67 | LineStart: 2 |
| 68 | 68 | IsStatement: true |
| ... | ... | @@ -83,15 +83,15 @@ sections: |
| 83 | 83 | LineStart: 6 |
| 84 | 84 | IsStatement: true |
| 85 | 85 | EndDelta: 0 |
| 86 | Columns: | |
| 86 | Columns: | |
| 87 | 87 | - !Symbols |
| 88 | Records: | |
| 88 | Records: | |
| 89 | 89 | - Kind: S_GDATA32 |
| 90 | DataSym: | |
| 90 | DataSym: | |
| 91 | 91 | Type: 116 |
| 92 | 92 | DisplayName: global |
| 93 | 93 | - !FileChecksums |
| 94 | Checksums: | |
| 94 | Checksums: | |
| 95 | 95 | - FileName: 'c:\src\llvm-project\build\pdb_comdat_main.c' |
| 96 | 96 | Kind: MD5 |
| 97 | 97 | Checksum: F969E51BBE373436D81492EB61387F36 |
| ... | ... | @@ -99,15 +99,15 @@ sections: |
| 99 | 99 | Kind: MD5 |
| 100 | 100 | Checksum: D74D834EFAC3AE2B45E606A8320B1D5C |
| 101 | 101 | - !StringTable |
| 102 | Strings: | |
| 102 | Strings: | |
| 103 | 103 | - 'c:\src\llvm-project\build\pdb_comdat_main.c' |
| 104 | 104 | - 'c:\src\llvm-project\build\foo.h' |
| 105 | 105 | - !Symbols |
| 106 | Records: | |
| 106 | Records: | |
| 107 | 107 | - Kind: S_BUILDINFO |
| 108 | BuildInfoSym: | |
| 108 | BuildInfoSym: | |
| 109 | 109 | BuildId: 4111 |
| 110 | Relocations: | |
| 110 | Relocations: | |
| 111 | 111 | - VirtualAddress: 168 |
| 112 | 112 | SymbolName: main |
| 113 | 113 | Type: IMAGE_REL_AMD64_SECREL |
| ... | ... | @@ -129,81 +129,81 @@ sections: |
| 129 | 129 | - Name: '.debug$T' |
| 130 | 130 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 131 | 131 | Alignment: 1 |
| 132 | Types: | |
| 132 | Types: | |
| 133 | 133 | - Kind: LF_ARGLIST |
| 134 | ArgList: | |
| 134 | ArgList: | |
| 135 | 135 | ArgIndices: [ 0 ] |
| 136 | 136 | - Kind: LF_PROCEDURE |
| 137 | Procedure: | |
| 137 | Procedure: | |
| 138 | 138 | ReturnType: 3 |
| 139 | 139 | CallConv: NearC |
| 140 | 140 | Options: [ None ] |
| 141 | 141 | ParameterCount: 0 |
| 142 | 142 | ArgumentList: 4096 |
| 143 | 143 | - Kind: LF_POINTER |
| 144 | Pointer: | |
| 144 | Pointer: | |
| 145 | 145 | ReferentType: 4097 |
| 146 | 146 | Attrs: 65548 |
| 147 | 147 | - Kind: LF_FUNC_ID |
| 148 | FuncId: | |
| 148 | FuncId: | |
| 149 | 149 | ParentScope: 0 |
| 150 | 150 | FunctionType: 4097 |
| 151 | 151 | Name: foo |
| 152 | 152 | - Kind: LF_ARGLIST |
| 153 | ArgList: | |
| 153 | ArgList: | |
| 154 | 154 | ArgIndices: [ ] |
| 155 | 155 | - Kind: LF_PROCEDURE |
| 156 | Procedure: | |
| 156 | Procedure: | |
| 157 | 157 | ReturnType: 116 |
| 158 | 158 | CallConv: NearC |
| 159 | 159 | Options: [ None ] |
| 160 | 160 | ParameterCount: 0 |
| 161 | 161 | ArgumentList: 4100 |
| 162 | 162 | - Kind: LF_FUNC_ID |
| 163 | FuncId: | |
| 163 | FuncId: | |
| 164 | 164 | ParentScope: 0 |
| 165 | 165 | FunctionType: 4101 |
| 166 | 166 | Name: main |
| 167 | 167 | - Kind: LF_FUNC_ID |
| 168 | FuncId: | |
| 168 | FuncId: | |
| 169 | 169 | ParentScope: 0 |
| 170 | 170 | FunctionType: 4097 |
| 171 | 171 | Name: bar |
| 172 | 172 | - Kind: LF_STRING_ID |
| 173 | StringId: | |
| 173 | StringId: | |
| 174 | 174 | Id: 0 |
| 175 | 175 | String: 'C:\src\llvm-project\build' |
| 176 | 176 | - Kind: LF_STRING_ID |
| 177 | StringId: | |
| 177 | StringId: | |
| 178 | 178 | Id: 0 |
| 179 | 179 | String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe' |
| 180 | 180 | - Kind: LF_STRING_ID |
| 181 | StringId: | |
| 181 | StringId: | |
| 182 | 182 | Id: 0 |
| 183 | 183 | String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um' |
| 184 | 184 | - Kind: LF_SUBSTR_LIST |
| 185 | StringList: | |
| 185 | StringList: | |
| 186 | 186 | StringIndices: [ 4106 ] |
| 187 | 187 | - Kind: LF_STRING_ID |
| 188 | StringId: | |
| 188 | StringId: | |
| 189 | 189 | Id: 4107 |
| 190 | 190 | String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X' |
| 191 | 191 | - Kind: LF_STRING_ID |
| 192 | StringId: | |
| 192 | StringId: | |
| 193 | 193 | Id: 0 |
| 194 | 194 | String: pdb_comdat_main.c |
| 195 | 195 | - Kind: LF_STRING_ID |
| 196 | StringId: | |
| 196 | StringId: | |
| 197 | 197 | Id: 0 |
| 198 | 198 | String: 'C:\src\llvm-project\build\vc140.pdb' |
| 199 | 199 | - Kind: LF_BUILDINFO |
| 200 | BuildInfo: | |
| 200 | BuildInfo: | |
| 201 | 201 | ArgIndices: [ 4104, 4105, 4109, 4110, 4108 ] |
| 202 | 202 | - Name: '.text$mn' |
| 203 | 203 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 204 | 204 | Alignment: 16 |
| 205 | 205 | SectionData: 4883EC28E800000000E800000000B82A0000004883C428C3 |
| 206 | Relocations: | |
| 206 | Relocations: | |
| 207 | 207 | - VirtualAddress: 5 |
| 208 | 208 | SymbolName: foo |
| 209 | 209 | Type: IMAGE_REL_AMD64_REL32 |
| ... | ... | @@ -214,7 +214,7 @@ sections: |
| 214 | 214 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 215 | 215 | Alignment: 16 |
| 216 | 216 | SectionData: 8B0500000000FFC0890500000000C3 |
| 217 | Relocations: | |
| 217 | Relocations: | |
| 218 | 218 | - VirtualAddress: 2 |
| 219 | 219 | SymbolName: global |
| 220 | 220 | Type: IMAGE_REL_AMD64_REL32 |
| ... | ... | @@ -224,11 +224,11 @@ sections: |
| 224 | 224 | - Name: '.debug$S' |
| 225 | 225 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 226 | 226 | Alignment: 1 |
| 227 | Subsections: | |
| 227 | Subsections: | |
| 228 | 228 | - !Symbols |
| 229 | Records: | |
| 229 | Records: | |
| 230 | 230 | - Kind: S_GPROC32_ID |
| 231 | ProcSym: | |
| 231 | ProcSym: | |
| 232 | 232 | PtrParent: 0 |
| 233 | 233 | PtrEnd: 0 |
| 234 | 234 | PtrNext: 0 |
| ... | ... | @@ -240,7 +240,7 @@ sections: |
| 240 | 240 | Flags: [ ] |
| 241 | 241 | DisplayName: foo |
| 242 | 242 | - Kind: S_FRAMEPROC |
| 243 | FrameProcSym: | |
| 243 | FrameProcSym: | |
| 244 | 244 | TotalFrameBytes: 0 |
| 245 | 245 | PaddingFrameBytes: 0 |
| 246 | 246 | OffsetToPadding: 0 |
| ... | ... | @@ -249,15 +249,15 @@ sections: |
| 249 | 249 | SectionIdOfExceptionHandler: 0 |
| 250 | 250 | Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ] |
| 251 | 251 | - Kind: S_PROC_ID_END |
| 252 | ScopeEndSym: | |
| 252 | ScopeEndSym: | |
| 253 | 253 | - !Lines |
| 254 | 254 | CodeSize: 15 |
| 255 | 255 | Flags: [ ] |
| 256 | 256 | RelocOffset: 0 |
| 257 | 257 | RelocSegment: 0 |
| 258 | Blocks: | |
| 258 | Blocks: | |
| 259 | 259 | - FileName: 'c:\src\llvm-project\build\foo.h' |
| 260 | Lines: | |
| 260 | Lines: | |
| 261 | 261 | - Offset: 0 |
| 262 | 262 | LineStart: 2 |
| 263 | 263 | IsStatement: true |
| ... | ... | @@ -270,8 +270,8 @@ sections: |
| 270 | 270 | LineStart: 4 |
| 271 | 271 | IsStatement: true |
| 272 | 272 | EndDelta: 0 |
| 273 | Columns: | |
| 274 | Relocations: | |
| 273 | Columns: | |
| 274 | Relocations: | |
| 275 | 275 | - VirtualAddress: 44 |
| 276 | 276 | SymbolName: foo |
| 277 | 277 | Type: IMAGE_REL_AMD64_SECREL |
| ... | ... | @@ -292,7 +292,7 @@ sections: |
| 292 | 292 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] |
| 293 | 293 | Alignment: 4 |
| 294 | 294 | SectionData: '000000001800000000000000' |
| 295 | Relocations: | |
| 295 | Relocations: | |
| 296 | 296 | - VirtualAddress: 0 |
| 297 | 297 | SymbolName: '$LN3' |
| 298 | 298 | Type: IMAGE_REL_AMD64_ADDR32NB |
| ... | ... | @@ -302,14 +302,14 @@ sections: |
| 302 | 302 | - VirtualAddress: 8 |
| 303 | 303 | SymbolName: '$unwind$main' |
| 304 | 304 | Type: IMAGE_REL_AMD64_ADDR32NB |
| 305 | symbols: | |
| 305 | symbols: | |
| 306 | 306 | - Name: .drectve |
| 307 | 307 | Value: 0 |
| 308 | 308 | SectionNumber: 1 |
| 309 | 309 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 310 | 310 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 311 | 311 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 312 | SectionDefinition: | |
| 312 | SectionDefinition: | |
| 313 | 313 | Length: 47 |
| 314 | 314 | NumberOfRelocations: 0 |
| 315 | 315 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -321,7 +321,7 @@ symbols: |
| 321 | 321 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 322 | 322 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 323 | 323 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 324 | SectionDefinition: | |
| 324 | SectionDefinition: | |
| 325 | 325 | Length: 480 |
| 326 | 326 | NumberOfRelocations: 6 |
| 327 | 327 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -333,7 +333,7 @@ symbols: |
| 333 | 333 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 334 | 334 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 335 | 335 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 336 | SectionDefinition: | |
| 336 | SectionDefinition: | |
| 337 | 337 | Length: 648 |
| 338 | 338 | NumberOfRelocations: 0 |
| 339 | 339 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -345,7 +345,7 @@ symbols: |
| 345 | 345 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 346 | 346 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 347 | 347 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 348 | SectionDefinition: | |
| 348 | SectionDefinition: | |
| 349 | 349 | Length: 24 |
| 350 | 350 | NumberOfRelocations: 2 |
| 351 | 351 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -357,7 +357,7 @@ symbols: |
| 357 | 357 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 358 | 358 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 359 | 359 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 360 | SectionDefinition: | |
| 360 | SectionDefinition: | |
| 361 | 361 | Length: 15 |
| 362 | 362 | NumberOfRelocations: 2 |
| 363 | 363 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -370,7 +370,7 @@ symbols: |
| 370 | 370 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 371 | 371 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 372 | 372 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 373 | SectionDefinition: | |
| 373 | SectionDefinition: | |
| 374 | 374 | Length: 148 |
| 375 | 375 | NumberOfRelocations: 4 |
| 376 | 376 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -407,7 +407,7 @@ symbols: |
| 407 | 407 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 408 | 408 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 409 | 409 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 410 | SectionDefinition: | |
| 410 | SectionDefinition: | |
| 411 | 411 | Length: 8 |
| 412 | 412 | NumberOfRelocations: 0 |
| 413 | 413 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -425,7 +425,7 @@ symbols: |
| 425 | 425 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 426 | 426 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 427 | 427 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 428 | SectionDefinition: | |
| 428 | SectionDefinition: | |
| 429 | 429 | Length: 12 |
| 430 | 430 | NumberOfRelocations: 3 |
| 431 | 431 | NumberOfLinenumbers: 0 |
deps/lld/test/COFF/Inputs/pdb_lines_1.yaml+59-59| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | 1 | --- !COFF |
| 2 | header: | |
| 2 | header: | |
| 3 | 3 | Machine: IMAGE_FILE_MACHINE_AMD64 |
| 4 | 4 | Characteristics: [ ] |
| 5 | sections: | |
| 5 | sections: | |
| 6 | 6 | - Name: .drectve |
| 7 | 7 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] |
| 8 | 8 | Alignment: 1 |
| ... | ... | @@ -10,15 +10,15 @@ sections: |
| 10 | 10 | - Name: '.debug$S' |
| 11 | 11 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 12 | 12 | Alignment: 1 |
| 13 | Subsections: | |
| 13 | Subsections: | |
| 14 | 14 | - !Symbols |
| 15 | Records: | |
| 15 | Records: | |
| 16 | 16 | - Kind: S_OBJNAME |
| 17 | ObjNameSym: | |
| 17 | ObjNameSym: | |
| 18 | 18 | Signature: 0 |
| 19 | 19 | ObjectName: 'C:\src\llvm-project\build\pdb_lines_1.obj' |
| 20 | 20 | - Kind: S_COMPILE3 |
| 21 | Compile3Sym: | |
| 21 | Compile3Sym: | |
| 22 | 22 | Flags: [ SecurityChecks, HotPatch ] |
| 23 | 23 | Machine: X64 |
| 24 | 24 | FrontendMajor: 19 |
| ... | ... | @@ -31,9 +31,9 @@ sections: |
| 31 | 31 | BackendQFE: 1 |
| 32 | 32 | Version: 'Microsoft (R) Optimizing Compiler' |
| 33 | 33 | - !Symbols |
| 34 | Records: | |
| 34 | Records: | |
| 35 | 35 | - Kind: S_GPROC32_ID |
| 36 | ProcSym: | |
| 36 | ProcSym: | |
| 37 | 37 | PtrParent: 0 |
| 38 | 38 | PtrEnd: 0 |
| 39 | 39 | PtrNext: 0 |
| ... | ... | @@ -45,7 +45,7 @@ sections: |
| 45 | 45 | Flags: [ ] |
| 46 | 46 | DisplayName: main |
| 47 | 47 | - Kind: S_FRAMEPROC |
| 48 | FrameProcSym: | |
| 48 | FrameProcSym: | |
| 49 | 49 | TotalFrameBytes: 40 |
| 50 | 50 | PaddingFrameBytes: 0 |
| 51 | 51 | OffsetToPadding: 0 |
| ... | ... | @@ -54,15 +54,15 @@ sections: |
| 54 | 54 | SectionIdOfExceptionHandler: 0 |
| 55 | 55 | Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] |
| 56 | 56 | - Kind: S_PROC_ID_END |
| 57 | ScopeEndSym: | |
| 57 | ScopeEndSym: | |
| 58 | 58 | - !Lines |
| 59 | 59 | CodeSize: 19 |
| 60 | 60 | Flags: [ ] |
| 61 | 61 | RelocOffset: 0 |
| 62 | 62 | RelocSegment: 0 |
| 63 | Blocks: | |
| 63 | Blocks: | |
| 64 | 64 | - FileName: 'c:\src\llvm-project\build\pdb_lines_1.c' |
| 65 | Lines: | |
| 65 | Lines: | |
| 66 | 66 | - Offset: 0 |
| 67 | 67 | LineStart: 2 |
| 68 | 68 | IsStatement: true |
| ... | ... | @@ -79,9 +79,9 @@ sections: |
| 79 | 79 | LineStart: 5 |
| 80 | 80 | IsStatement: true |
| 81 | 81 | EndDelta: 0 |
| 82 | Columns: | |
| 82 | Columns: | |
| 83 | 83 | - !FileChecksums |
| 84 | Checksums: | |
| 84 | Checksums: | |
| 85 | 85 | - FileName: 'c:\src\llvm-project\build\pdb_lines_1.c' |
| 86 | 86 | Kind: MD5 |
| 87 | 87 | Checksum: 4EB19DCD86C3BA2238A255C718572E7B |
| ... | ... | @@ -89,15 +89,15 @@ sections: |
| 89 | 89 | Kind: MD5 |
| 90 | 90 | Checksum: 061EB73ABB642532857A4F1D9CBAC323 |
| 91 | 91 | - !StringTable |
| 92 | Strings: | |
| 92 | Strings: | |
| 93 | 93 | - 'c:\src\llvm-project\build\pdb_lines_1.c' |
| 94 | 94 | - 'c:\src\llvm-project\build\foo.h' |
| 95 | 95 | - !Symbols |
| 96 | Records: | |
| 96 | Records: | |
| 97 | 97 | - Kind: S_BUILDINFO |
| 98 | BuildInfoSym: | |
| 98 | BuildInfoSym: | |
| 99 | 99 | BuildId: 4111 |
| 100 | Relocations: | |
| 100 | Relocations: | |
| 101 | 101 | - VirtualAddress: 164 |
| 102 | 102 | SymbolName: main |
| 103 | 103 | Type: IMAGE_REL_AMD64_SECREL |
| ... | ... | @@ -113,81 +113,81 @@ sections: |
| 113 | 113 | - Name: '.debug$T' |
| 114 | 114 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 115 | 115 | Alignment: 1 |
| 116 | Types: | |
| 116 | Types: | |
| 117 | 117 | - Kind: LF_ARGLIST |
| 118 | ArgList: | |
| 118 | ArgList: | |
| 119 | 119 | ArgIndices: [ ] |
| 120 | 120 | - Kind: LF_PROCEDURE |
| 121 | Procedure: | |
| 121 | Procedure: | |
| 122 | 122 | ReturnType: 3 |
| 123 | 123 | CallConv: NearC |
| 124 | 124 | Options: [ None ] |
| 125 | 125 | ParameterCount: 0 |
| 126 | 126 | ArgumentList: 4096 |
| 127 | 127 | - Kind: LF_POINTER |
| 128 | Pointer: | |
| 128 | Pointer: | |
| 129 | 129 | ReferentType: 4097 |
| 130 | 130 | Attrs: 65548 |
| 131 | 131 | - Kind: LF_FUNC_ID |
| 132 | FuncId: | |
| 132 | FuncId: | |
| 133 | 133 | ParentScope: 0 |
| 134 | 134 | FunctionType: 4097 |
| 135 | 135 | Name: foo |
| 136 | 136 | - Kind: LF_ARGLIST |
| 137 | ArgList: | |
| 137 | ArgList: | |
| 138 | 138 | ArgIndices: [ 0 ] |
| 139 | 139 | - Kind: LF_PROCEDURE |
| 140 | Procedure: | |
| 140 | Procedure: | |
| 141 | 141 | ReturnType: 116 |
| 142 | 142 | CallConv: NearC |
| 143 | 143 | Options: [ None ] |
| 144 | 144 | ParameterCount: 0 |
| 145 | 145 | ArgumentList: 4100 |
| 146 | 146 | - Kind: LF_FUNC_ID |
| 147 | FuncId: | |
| 147 | FuncId: | |
| 148 | 148 | ParentScope: 0 |
| 149 | 149 | FunctionType: 4101 |
| 150 | 150 | Name: main |
| 151 | 151 | - Kind: LF_FUNC_ID |
| 152 | FuncId: | |
| 152 | FuncId: | |
| 153 | 153 | ParentScope: 0 |
| 154 | 154 | FunctionType: 4097 |
| 155 | 155 | Name: bar |
| 156 | 156 | - Kind: LF_STRING_ID |
| 157 | StringId: | |
| 157 | StringId: | |
| 158 | 158 | Id: 0 |
| 159 | 159 | String: 'C:\src\llvm-project\build' |
| 160 | 160 | - Kind: LF_STRING_ID |
| 161 | StringId: | |
| 161 | StringId: | |
| 162 | 162 | Id: 0 |
| 163 | 163 | String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe' |
| 164 | 164 | - Kind: LF_STRING_ID |
| 165 | StringId: | |
| 165 | StringId: | |
| 166 | 166 | Id: 0 |
| 167 | 167 | String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um' |
| 168 | 168 | - Kind: LF_SUBSTR_LIST |
| 169 | StringList: | |
| 169 | StringList: | |
| 170 | 170 | StringIndices: [ 4106 ] |
| 171 | 171 | - Kind: LF_STRING_ID |
| 172 | StringId: | |
| 172 | StringId: | |
| 173 | 173 | Id: 4107 |
| 174 | 174 | String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X' |
| 175 | 175 | - Kind: LF_STRING_ID |
| 176 | StringId: | |
| 176 | StringId: | |
| 177 | 177 | Id: 0 |
| 178 | 178 | String: pdb_lines_1.c |
| 179 | 179 | - Kind: LF_STRING_ID |
| 180 | StringId: | |
| 180 | StringId: | |
| 181 | 181 | Id: 0 |
| 182 | 182 | String: 'C:\src\llvm-project\build\vc140.pdb' |
| 183 | 183 | - Kind: LF_BUILDINFO |
| 184 | BuildInfo: | |
| 184 | BuildInfo: | |
| 185 | 185 | ArgIndices: [ 4104, 4105, 4109, 4110, 4108 ] |
| 186 | 186 | - Name: '.text$mn' |
| 187 | 187 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 188 | 188 | Alignment: 16 |
| 189 | 189 | SectionData: 4883EC28E800000000B82A0000004883C428C3 |
| 190 | Relocations: | |
| 190 | Relocations: | |
| 191 | 191 | - VirtualAddress: 5 |
| 192 | 192 | SymbolName: foo |
| 193 | 193 | Type: IMAGE_REL_AMD64_REL32 |
| ... | ... | @@ -195,18 +195,18 @@ sections: |
| 195 | 195 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 196 | 196 | Alignment: 16 |
| 197 | 197 | SectionData: 4883EC28E8000000004883C428C3 |
| 198 | Relocations: | |
| 198 | Relocations: | |
| 199 | 199 | - VirtualAddress: 5 |
| 200 | 200 | SymbolName: bar |
| 201 | 201 | Type: IMAGE_REL_AMD64_REL32 |
| 202 | 202 | - Name: '.debug$S' |
| 203 | 203 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 204 | 204 | Alignment: 1 |
| 205 | Subsections: | |
| 205 | Subsections: | |
| 206 | 206 | - !Symbols |
| 207 | Records: | |
| 207 | Records: | |
| 208 | 208 | - Kind: S_GPROC32_ID |
| 209 | ProcSym: | |
| 209 | ProcSym: | |
| 210 | 210 | PtrParent: 0 |
| 211 | 211 | PtrEnd: 0 |
| 212 | 212 | PtrNext: 0 |
| ... | ... | @@ -218,7 +218,7 @@ sections: |
| 218 | 218 | Flags: [ ] |
| 219 | 219 | DisplayName: foo |
| 220 | 220 | - Kind: S_FRAMEPROC |
| 221 | FrameProcSym: | |
| 221 | FrameProcSym: | |
| 222 | 222 | TotalFrameBytes: 40 |
| 223 | 223 | PaddingFrameBytes: 0 |
| 224 | 224 | OffsetToPadding: 0 |
| ... | ... | @@ -227,15 +227,15 @@ sections: |
| 227 | 227 | SectionIdOfExceptionHandler: 0 |
| 228 | 228 | Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ] |
| 229 | 229 | - Kind: S_PROC_ID_END |
| 230 | ScopeEndSym: | |
| 230 | ScopeEndSym: | |
| 231 | 231 | - !Lines |
| 232 | 232 | CodeSize: 14 |
| 233 | 233 | Flags: [ ] |
| 234 | 234 | RelocOffset: 0 |
| 235 | 235 | RelocSegment: 0 |
| 236 | Blocks: | |
| 236 | Blocks: | |
| 237 | 237 | - FileName: 'c:\src\llvm-project\build\foo.h' |
| 238 | Lines: | |
| 238 | Lines: | |
| 239 | 239 | - Offset: 0 |
| 240 | 240 | LineStart: 2 |
| 241 | 241 | IsStatement: true |
| ... | ... | @@ -248,8 +248,8 @@ sections: |
| 248 | 248 | LineStart: 4 |
| 249 | 249 | IsStatement: true |
| 250 | 250 | EndDelta: 0 |
| 251 | Columns: | |
| 252 | Relocations: | |
| 251 | Columns: | |
| 252 | Relocations: | |
| 253 | 253 | - VirtualAddress: 44 |
| 254 | 254 | SymbolName: foo |
| 255 | 255 | Type: IMAGE_REL_AMD64_SECREL |
| ... | ... | @@ -270,7 +270,7 @@ sections: |
| 270 | 270 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] |
| 271 | 271 | Alignment: 4 |
| 272 | 272 | SectionData: '000000000E00000000000000' |
| 273 | Relocations: | |
| 273 | Relocations: | |
| 274 | 274 | - VirtualAddress: 0 |
| 275 | 275 | SymbolName: '$LN3' |
| 276 | 276 | Type: IMAGE_REL_AMD64_ADDR32NB |
| ... | ... | @@ -288,7 +288,7 @@ sections: |
| 288 | 288 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] |
| 289 | 289 | Alignment: 4 |
| 290 | 290 | SectionData: '000000001300000000000000' |
| 291 | Relocations: | |
| 291 | Relocations: | |
| 292 | 292 | - VirtualAddress: 0 |
| 293 | 293 | SymbolName: '$LN3' |
| 294 | 294 | Type: IMAGE_REL_AMD64_ADDR32NB |
| ... | ... | @@ -298,14 +298,14 @@ sections: |
| 298 | 298 | - VirtualAddress: 8 |
| 299 | 299 | SymbolName: '$unwind$main' |
| 300 | 300 | Type: IMAGE_REL_AMD64_ADDR32NB |
| 301 | symbols: | |
| 301 | symbols: | |
| 302 | 302 | - Name: .drectve |
| 303 | 303 | Value: 0 |
| 304 | 304 | SectionNumber: 1 |
| 305 | 305 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 306 | 306 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 307 | 307 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 308 | SectionDefinition: | |
| 308 | SectionDefinition: | |
| 309 | 309 | Length: 47 |
| 310 | 310 | NumberOfRelocations: 0 |
| 311 | 311 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -317,7 +317,7 @@ symbols: |
| 317 | 317 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 318 | 318 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 319 | 319 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 320 | SectionDefinition: | |
| 320 | SectionDefinition: | |
| 321 | 321 | Length: 432 |
| 322 | 322 | NumberOfRelocations: 4 |
| 323 | 323 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -329,7 +329,7 @@ symbols: |
| 329 | 329 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 330 | 330 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 331 | 331 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 332 | SectionDefinition: | |
| 332 | SectionDefinition: | |
| 333 | 333 | Length: 644 |
| 334 | 334 | NumberOfRelocations: 0 |
| 335 | 335 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -341,7 +341,7 @@ symbols: |
| 341 | 341 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 342 | 342 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 343 | 343 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 344 | SectionDefinition: | |
| 344 | SectionDefinition: | |
| 345 | 345 | Length: 19 |
| 346 | 346 | NumberOfRelocations: 1 |
| 347 | 347 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -353,7 +353,7 @@ symbols: |
| 353 | 353 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 354 | 354 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 355 | 355 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 356 | SectionDefinition: | |
| 356 | SectionDefinition: | |
| 357 | 357 | Length: 14 |
| 358 | 358 | NumberOfRelocations: 1 |
| 359 | 359 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -366,7 +366,7 @@ symbols: |
| 366 | 366 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 367 | 367 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 368 | 368 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 369 | SectionDefinition: | |
| 369 | SectionDefinition: | |
| 370 | 370 | Length: 148 |
| 371 | 371 | NumberOfRelocations: 4 |
| 372 | 372 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -409,7 +409,7 @@ symbols: |
| 409 | 409 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 410 | 410 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 411 | 411 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 412 | SectionDefinition: | |
| 412 | SectionDefinition: | |
| 413 | 413 | Length: 8 |
| 414 | 414 | NumberOfRelocations: 0 |
| 415 | 415 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -428,7 +428,7 @@ symbols: |
| 428 | 428 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 429 | 429 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 430 | 430 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 431 | SectionDefinition: | |
| 431 | SectionDefinition: | |
| 432 | 432 | Length: 12 |
| 433 | 433 | NumberOfRelocations: 3 |
| 434 | 434 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -447,7 +447,7 @@ symbols: |
| 447 | 447 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 448 | 448 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 449 | 449 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 450 | SectionDefinition: | |
| 450 | SectionDefinition: | |
| 451 | 451 | Length: 8 |
| 452 | 452 | NumberOfRelocations: 0 |
| 453 | 453 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -465,7 +465,7 @@ symbols: |
| 465 | 465 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 466 | 466 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 467 | 467 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 468 | SectionDefinition: | |
| 468 | SectionDefinition: | |
| 469 | 469 | Length: 12 |
| 470 | 470 | NumberOfRelocations: 3 |
| 471 | 471 | NumberOfLinenumbers: 0 |
deps/lld/test/COFF/Inputs/pdb_lines_2.yaml+35-35| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | 1 | --- !COFF |
| 2 | header: | |
| 2 | header: | |
| 3 | 3 | Machine: IMAGE_FILE_MACHINE_AMD64 |
| 4 | 4 | Characteristics: [ ] |
| 5 | sections: | |
| 5 | sections: | |
| 6 | 6 | - Name: .drectve |
| 7 | 7 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] |
| 8 | 8 | Alignment: 1 |
| ... | ... | @@ -10,15 +10,15 @@ sections: |
| 10 | 10 | - Name: '.debug$S' |
| 11 | 11 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 12 | 12 | Alignment: 1 |
| 13 | Subsections: | |
| 13 | Subsections: | |
| 14 | 14 | - !Symbols |
| 15 | Records: | |
| 15 | Records: | |
| 16 | 16 | - Kind: S_OBJNAME |
| 17 | ObjNameSym: | |
| 17 | ObjNameSym: | |
| 18 | 18 | Signature: 0 |
| 19 | 19 | ObjectName: 'C:\src\llvm-project\build\pdb_lines_2.obj' |
| 20 | 20 | - Kind: S_COMPILE3 |
| 21 | Compile3Sym: | |
| 21 | Compile3Sym: | |
| 22 | 22 | Flags: [ SecurityChecks, HotPatch ] |
| 23 | 23 | Machine: X64 |
| 24 | 24 | FrontendMajor: 19 |
| ... | ... | @@ -31,9 +31,9 @@ sections: |
| 31 | 31 | BackendQFE: 1 |
| 32 | 32 | Version: 'Microsoft (R) Optimizing Compiler' |
| 33 | 33 | - !Symbols |
| 34 | Records: | |
| 34 | Records: | |
| 35 | 35 | - Kind: S_GPROC32_ID |
| 36 | ProcSym: | |
| 36 | ProcSym: | |
| 37 | 37 | PtrParent: 0 |
| 38 | 38 | PtrEnd: 0 |
| 39 | 39 | PtrNext: 0 |
| ... | ... | @@ -45,7 +45,7 @@ sections: |
| 45 | 45 | Flags: [ ] |
| 46 | 46 | DisplayName: bar |
| 47 | 47 | - Kind: S_FRAMEPROC |
| 48 | FrameProcSym: | |
| 48 | FrameProcSym: | |
| 49 | 49 | TotalFrameBytes: 0 |
| 50 | 50 | PaddingFrameBytes: 0 |
| 51 | 51 | OffsetToPadding: 0 |
| ... | ... | @@ -54,15 +54,15 @@ sections: |
| 54 | 54 | SectionIdOfExceptionHandler: 0 |
| 55 | 55 | Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] |
| 56 | 56 | - Kind: S_PROC_ID_END |
| 57 | ScopeEndSym: | |
| 57 | ScopeEndSym: | |
| 58 | 58 | - !Lines |
| 59 | 59 | CodeSize: 1 |
| 60 | 60 | Flags: [ ] |
| 61 | 61 | RelocOffset: 0 |
| 62 | 62 | RelocSegment: 0 |
| 63 | Blocks: | |
| 63 | Blocks: | |
| 64 | 64 | - FileName: 'c:\src\llvm-project\build\pdb_lines_2.c' |
| 65 | Lines: | |
| 65 | Lines: | |
| 66 | 66 | - Offset: 0 |
| 67 | 67 | LineStart: 1 |
| 68 | 68 | IsStatement: true |
| ... | ... | @@ -71,21 +71,21 @@ sections: |
| 71 | 71 | LineStart: 2 |
| 72 | 72 | IsStatement: true |
| 73 | 73 | EndDelta: 0 |
| 74 | Columns: | |
| 74 | Columns: | |
| 75 | 75 | - !FileChecksums |
| 76 | Checksums: | |
| 76 | Checksums: | |
| 77 | 77 | - FileName: 'c:\src\llvm-project\build\pdb_lines_2.c' |
| 78 | 78 | Kind: MD5 |
| 79 | 79 | Checksum: DF91CB3A2B8D917486574BB50CAC4CC7 |
| 80 | 80 | - !StringTable |
| 81 | Strings: | |
| 81 | Strings: | |
| 82 | 82 | - 'c:\src\llvm-project\build\pdb_lines_2.c' |
| 83 | 83 | - !Symbols |
| 84 | Records: | |
| 84 | Records: | |
| 85 | 85 | - Kind: S_BUILDINFO |
| 86 | BuildInfoSym: | |
| 86 | BuildInfoSym: | |
| 87 | 87 | BuildId: 4106 |
| 88 | Relocations: | |
| 88 | Relocations: | |
| 89 | 89 | - VirtualAddress: 164 |
| 90 | 90 | SymbolName: bar |
| 91 | 91 | Type: IMAGE_REL_AMD64_SECREL |
| ... | ... | @@ -101,64 +101,64 @@ sections: |
| 101 | 101 | - Name: '.debug$T' |
| 102 | 102 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 103 | 103 | Alignment: 1 |
| 104 | Types: | |
| 104 | Types: | |
| 105 | 105 | - Kind: LF_ARGLIST |
| 106 | ArgList: | |
| 106 | ArgList: | |
| 107 | 107 | ArgIndices: [ ] |
| 108 | 108 | - Kind: LF_PROCEDURE |
| 109 | Procedure: | |
| 109 | Procedure: | |
| 110 | 110 | ReturnType: 3 |
| 111 | 111 | CallConv: NearC |
| 112 | 112 | Options: [ None ] |
| 113 | 113 | ParameterCount: 0 |
| 114 | 114 | ArgumentList: 4096 |
| 115 | 115 | - Kind: LF_FUNC_ID |
| 116 | FuncId: | |
| 116 | FuncId: | |
| 117 | 117 | ParentScope: 0 |
| 118 | 118 | FunctionType: 4097 |
| 119 | 119 | Name: bar |
| 120 | 120 | - Kind: LF_STRING_ID |
| 121 | StringId: | |
| 121 | StringId: | |
| 122 | 122 | Id: 0 |
| 123 | 123 | String: 'C:\src\llvm-project\build' |
| 124 | 124 | - Kind: LF_STRING_ID |
| 125 | StringId: | |
| 125 | StringId: | |
| 126 | 126 | Id: 0 |
| 127 | 127 | String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe' |
| 128 | 128 | - Kind: LF_STRING_ID |
| 129 | StringId: | |
| 129 | StringId: | |
| 130 | 130 | Id: 0 |
| 131 | 131 | String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um' |
| 132 | 132 | - Kind: LF_SUBSTR_LIST |
| 133 | StringList: | |
| 133 | StringList: | |
| 134 | 134 | StringIndices: [ 4101 ] |
| 135 | 135 | - Kind: LF_STRING_ID |
| 136 | StringId: | |
| 136 | StringId: | |
| 137 | 137 | Id: 4102 |
| 138 | 138 | String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X' |
| 139 | 139 | - Kind: LF_STRING_ID |
| 140 | StringId: | |
| 140 | StringId: | |
| 141 | 141 | Id: 0 |
| 142 | 142 | String: pdb_lines_2.c |
| 143 | 143 | - Kind: LF_STRING_ID |
| 144 | StringId: | |
| 144 | StringId: | |
| 145 | 145 | Id: 0 |
| 146 | 146 | String: 'C:\src\llvm-project\build\vc140.pdb' |
| 147 | 147 | - Kind: LF_BUILDINFO |
| 148 | BuildInfo: | |
| 148 | BuildInfo: | |
| 149 | 149 | ArgIndices: [ 4099, 4100, 4104, 4105, 4103 ] |
| 150 | 150 | - Name: '.text$mn' |
| 151 | 151 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 152 | 152 | Alignment: 16 |
| 153 | 153 | SectionData: C3 |
| 154 | symbols: | |
| 154 | symbols: | |
| 155 | 155 | - Name: .drectve |
| 156 | 156 | Value: 0 |
| 157 | 157 | SectionNumber: 1 |
| 158 | 158 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 159 | 159 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 160 | 160 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 161 | SectionDefinition: | |
| 161 | SectionDefinition: | |
| 162 | 162 | Length: 47 |
| 163 | 163 | NumberOfRelocations: 0 |
| 164 | 164 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -170,7 +170,7 @@ symbols: |
| 170 | 170 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 171 | 171 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 172 | 172 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 173 | SectionDefinition: | |
| 173 | SectionDefinition: | |
| 174 | 174 | Length: 360 |
| 175 | 175 | NumberOfRelocations: 4 |
| 176 | 176 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -182,7 +182,7 @@ symbols: |
| 182 | 182 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 183 | 183 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 184 | 184 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 185 | SectionDefinition: | |
| 185 | SectionDefinition: | |
| 186 | 186 | Length: 568 |
| 187 | 187 | NumberOfRelocations: 0 |
| 188 | 188 | NumberOfLinenumbers: 0 |
| ... | ... | @@ -194,7 +194,7 @@ symbols: |
| 194 | 194 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 195 | 195 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 196 | 196 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 197 | SectionDefinition: | |
| 197 | SectionDefinition: | |
| 198 | 198 | Length: 1 |
| 199 | 199 | NumberOfRelocations: 0 |
| 200 | 200 | NumberOfLinenumbers: 0 |
deps/lld/test/COFF/arm-thumb-branch20-error.s created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | // REQUIRES: arm | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %s -o %t.obj | |
| 3 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %S/Inputs/far-arm-thumb-abs20.s -o %t.far.obj | |
| 4 | // RUN: not lld-link -entry:_start -subsystem:console %t.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s | |
| 5 | .syntax unified | |
| 6 | .globl _start | |
| 7 | _start: | |
| 8 | bne too_far20 | |
| 9 | ||
| 10 | // CHECK: relocation out of range |
deps/lld/test/COFF/arm64-dynamicbase.s created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | // REQUIRES: aarch64 | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-windows %s -o %t.obj | |
| 3 | // RUN: not lld-link -entry:_start -subsystem:console %t.obj -out:%t.exe -dynamicbase:no 2>&1 | FileCheck %s | |
| 4 | .globl _start | |
| 5 | _start: | |
| 6 | ret | |
| 7 | ||
| 8 | # CHECK: dynamicbase:no is not compatible with arm64 |
deps/lld/test/COFF/arm64-import2.test created+85| ... | ... | @@ -0,0 +1,85 @@ |
| 1 | # REQUIRES: aarch64 | |
| 2 | ||
| 3 | # RUN: yaml2obj < %s > %t.obj | |
| 4 | # RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE | |
| 5 | # RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t.obj %p/Inputs/library-arm64.lib %p/Inputs/library2-arm64.lib | |
| 6 | # RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER | |
| 7 | # RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s -check-prefix IMPORTS | |
| 8 | ||
| 9 | # BEFORE: Disassembly of section .text: | |
| 10 | # BEFORE: 0: 00 00 00 94 bl #0 | |
| 11 | # BEFORE: 4: 00 00 00 94 bl #0 | |
| 12 | # BEFORE: 8: c0 03 5f d6 ret | |
| 13 | ||
| 14 | # AFTER: Disassembly of section .text: | |
| 15 | # AFTER: 140001000: 03 00 00 94 bl #12 | |
| 16 | # AFTER: 140001004: 05 00 00 94 bl #20 | |
| 17 | # AFTER: 140001008: c0 03 5f d6 ret | |
| 18 | # AFTER: 14000100c: 10 00 00 b0 adrp x16, #4096 | |
| 19 | # AFTER: 140001010: 10 32 40 f9 ldr x16, [x16, #96] | |
| 20 | # AFTER: 140001014: 00 02 1f d6 br x16 | |
| 21 | # AFTER: 140001018: 10 00 00 b0 adrp x16, #4096 | |
| 22 | # AFTER: 14000101c: 10 3a 40 f9 ldr x16, [x16, #112] | |
| 23 | # AFTER: 140001020: 00 02 1f d6 br x16 | |
| 24 | ||
| 25 | # IMPORTS: Import { | |
| 26 | # IMPORTS: Name: library.dll | |
| 27 | # IMPORTS: ImportLookupTableRVA: 0x2040 | |
| 28 | # IMPORTS: ImportAddressTableRVA: 0x2060 | |
| 29 | # IMPORTS: Symbol: function (2) | |
| 30 | # IMPORTS: } | |
| 31 | # IMPORTS: Import { | |
| 32 | # IMPORTS: Name: library2.dll | |
| 33 | # IMPORTS: ImportLookupTableRVA: 0x2050 | |
| 34 | # IMPORTS: ImportAddressTableRVA: 0x2070 | |
| 35 | # IMPORTS: Symbol: function2 (0) | |
| 36 | # IMPORTS: } | |
| 37 | ||
| 38 | --- !COFF | |
| 39 | header: | |
| 40 | Machine: IMAGE_FILE_MACHINE_ARM64 | |
| 41 | Characteristics: [ ] | |
| 42 | sections: | |
| 43 | - Name: .text | |
| 44 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 45 | Alignment: 4 | |
| 46 | SectionData: 0000009400000094C0035FD6 | |
| 47 | Relocations: | |
| 48 | - VirtualAddress: 0 | |
| 49 | SymbolName: function | |
| 50 | Type: IMAGE_REL_ARM64_BRANCH26 | |
| 51 | - VirtualAddress: 4 | |
| 52 | SymbolName: function2 | |
| 53 | Type: IMAGE_REL_ARM64_BRANCH26 | |
| 54 | symbols: | |
| 55 | - Name: .text | |
| 56 | Value: 0 | |
| 57 | SectionNumber: 1 | |
| 58 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 59 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 60 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 61 | SectionDefinition: | |
| 62 | Length: 12 | |
| 63 | NumberOfRelocations: 2 | |
| 64 | NumberOfLinenumbers: 0 | |
| 65 | CheckSum: 1438860354 | |
| 66 | Number: 1 | |
| 67 | - Name: main | |
| 68 | Value: 0 | |
| 69 | SectionNumber: 1 | |
| 70 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 71 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 72 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 73 | - Name: function | |
| 74 | Value: 0 | |
| 75 | SectionNumber: 0 | |
| 76 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 77 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 78 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 79 | - Name: function2 | |
| 80 | Value: 0 | |
| 81 | SectionNumber: 0 | |
| 82 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 83 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 84 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 85 | ... |
deps/lld/test/COFF/arm64-relocs-imports.test+130-23| ... | ... | @@ -14,29 +14,67 @@ |
| 14 | 14 | # BEFORE: 14: 00 01 40 79 ldrh w0, [x8] |
| 15 | 15 | # BEFORE: 18: 00 01 40 b9 ldr w0, [x8] |
| 16 | 16 | # BEFORE: 1c: 00 01 40 f9 ldr x0, [x8] |
| 17 | # BEFORE: 20: e0 03 1f 2a mov w0, wzr | |
| 18 | # BEFORE: 24: fe 07 41 f8 ldr x30, [sp], #16 | |
| 19 | # BEFORE: 28: c0 03 5f d6 ret | |
| 20 | # BEFORE: 2c: 08 00 00 00 <unknown> | |
| 21 | # BEFORE: 30: 00 00 00 00 <unknown> | |
| 17 | # BEFORE: 20: 00 01 00 39 strb w0, [x8] | |
| 18 | # BEFORE: 24: 00 01 00 79 strh w0, [x8] | |
| 19 | # BEFORE: 28: 00 01 00 b9 str w0, [x8] | |
| 20 | # BEFORE: 2c: 00 01 00 f9 str x0, [x8] | |
| 21 | # BEFORE: 30: 00 01 40 3d ldr b0, [x8] | |
| 22 | # BEFORE: 34: 00 01 40 7d ldr h0, [x8] | |
| 23 | # BEFORE: 38: 00 01 40 bd ldr s0, [x8] | |
| 24 | # BEFORE: 3c: 00 01 40 fd ldr d0, [x8] | |
| 25 | # BEFORE: 40: 00 01 c0 3d ldr q0, [x8] | |
| 26 | # BEFORE: 44: 00 01 00 3d str b0, [x8] | |
| 27 | # BEFORE: 48: 00 01 00 7d str h0, [x8] | |
| 28 | # BEFORE: 4c: 00 01 00 bd str s0, [x8] | |
| 29 | # BEFORE: 50: 00 01 00 fd str d0, [x8] | |
| 30 | # BEFORE: 54: 00 01 80 3d str q0, [x8] | |
| 31 | # BEFORE: 58: 00 05 40 f9 ldr x0, [x8, #8] | |
| 32 | # BEFORE: 5c: 20 1a 01 b0 adrp x0, #36982784 | |
| 33 | # BEFORE: 60: 00 fc 4f f9 ldr x0, [x0, #8184] | |
| 34 | # BEFORE: 64: e0 03 1f 2a mov w0, wzr | |
| 35 | # BEFORE: 68: fe 07 41 f8 ldr x30, [sp], #16 | |
| 36 | # BEFORE: 6c: c0 03 5f d6 ret | |
| 37 | # BEFORE: 70: 08 00 00 00 <unknown> | |
| 38 | # BEFORE: 74: 00 00 00 00 <unknown> | |
| 39 | # BEFORE: 78: 01 00 00 00 <unknown> | |
| 40 | # BEFORE: 7c: 01 00 00 00 <unknown> | |
| 22 | 41 | |
| 23 | 42 | # AFTER: Disassembly of section .text: |
| 24 | 43 | # AFTER: 140002000: fe 0f 1f f8 str x30, [sp, #-16]! |
| 25 | 44 | # AFTER: 140002004: e0 ff ff f0 adrp x0, #-4096 |
| 26 | 45 | # AFTER: 140002008: 00 18 00 91 add x0, x0, #6 |
| 27 | # AFTER: 14000200c: 0a 00 00 94 bl #40 | |
| 46 | # AFTER: 14000200c: 1d 00 00 94 bl #116 | |
| 28 | 47 | # AFTER: 140002010: 00 21 40 39 ldrb w0, [x8, #8] |
| 29 | 48 | # AFTER: 140002014: 00 11 40 79 ldrh w0, [x8, #8] |
| 30 | 49 | # AFTER: 140002018: 00 09 40 b9 ldr w0, [x8, #8] |
| 31 | 50 | # AFTER: 14000201c: 00 05 40 f9 ldr x0, [x8, #8] |
| 32 | # AFTER: 140002020: e0 03 1f 2a mov w0, wzr | |
| 33 | # AFTER: 140002024: fe 07 41 f8 ldr x30, [sp], #16 | |
| 34 | # AFTER: 140002028: c0 03 5f d6 ret | |
| 35 | # AFTER: 14000202c: 10 10 00 40 <unknown> | |
| 36 | # AFTER: 140002030: 01 00 00 00 <unknown> | |
| 37 | # AFTER: 140002034: 10 00 00 b0 adrp x16, #4096 | |
| 38 | # AFTER: 140002038: 10 1e 40 f9 ldr x16, [x16, #56] | |
| 39 | # AFTER: 14000203c: 00 02 1f d6 br x16 | |
| 51 | # AFTER: 140002020: 00 21 00 39 strb w0, [x8, #8] | |
| 52 | # AFTER: 140002024: 00 11 00 79 strh w0, [x8, #8] | |
| 53 | # AFTER: 140002028: 00 09 00 b9 str w0, [x8, #8] | |
| 54 | # AFTER: 14000202c: 00 05 00 f9 str x0, [x8, #8] | |
| 55 | # AFTER: 140002030: 00 41 40 3d ldr b0, [x8, #16] | |
| 56 | # AFTER: 140002034: 00 21 40 7d ldr h0, [x8, #16] | |
| 57 | # AFTER: 140002038: 00 11 40 bd ldr s0, [x8, #16] | |
| 58 | # AFTER: 14000203c: 00 09 40 fd ldr d0, [x8, #16] | |
| 59 | # AFTER: 140002040: 00 05 c0 3d ldr q0, [x8, #16] | |
| 60 | # AFTER: 140002044: 00 41 00 3d str b0, [x8, #16] | |
| 61 | # AFTER: 140002048: 00 21 00 7d str h0, [x8, #16] | |
| 62 | # AFTER: 14000204c: 00 11 00 bd str s0, [x8, #16] | |
| 63 | # AFTER: 140002050: 00 09 00 fd str d0, [x8, #16] | |
| 64 | # AFTER: 140002054: 00 05 80 3d str q0, [x8, #16] | |
| 65 | # AFTER: 140002058: 00 09 40 f9 ldr x0, [x8, #16] | |
| 66 | # AFTER: 14000205c: 00 00 00 b0 adrp x0, #4096 | |
| 67 | # AFTER: 140002060: 00 fc 47 f9 ldr x0, [x0, #4088] | |
| 68 | # AFTER: 140002064: e0 03 1f 2a mov w0, wzr | |
| 69 | # AFTER: 140002068: fe 07 41 f8 ldr x30, [sp], #16 | |
| 70 | # AFTER: 14000206c: c0 03 5f d6 ret | |
| 71 | # AFTER: 140002070: 10 10 00 40 <unknown> | |
| 72 | # AFTER: 140002074: 01 00 00 00 <unknown> | |
| 73 | # AFTER: 140002078: 09 10 00 00 <unknown> | |
| 74 | # AFTER: 14000207c: 09 00 00 00 <unknown> | |
| 75 | # AFTER: 140002080: 10 00 00 b0 adrp x16, #4096 | |
| 76 | # AFTER: 140002084: 10 1e 40 f9 ldr x16, [x16, #56] | |
| 77 | # AFTER: 140002088: 00 02 1f d6 br x16 | |
| 40 | 78 | |
| 41 | 79 | --- !COFF |
| 42 | 80 | header: |
| ... | ... | @@ -46,32 +84,89 @@ sections: |
| 46 | 84 | - Name: .text |
| 47 | 85 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 48 | 86 | Alignment: 4 |
| 49 | SectionData: FE0F1FF80000009000080091000000940001403900014079000140B9000140F9E0031F2AFE0741F8C0035FD60800000000000000 | |
| 87 | SectionData: FE0F1FF80000009000080091000000940001403900014079000140B9000140F90001003900010079000100B9000100F90001403D0001407D000140BD000140FD0001C03D0001003D0001007D000100BD000100FD0001803D000540F9201A01B000FC4FF9E0031F2AFE0741F8C0035FD608000000000000000100000001000000 | |
| 50 | 88 | Relocations: |
| 51 | 89 | - VirtualAddress: 4 |
| 52 | 90 | SymbolName: .Lstr |
| 53 | Type: 4 | |
| 91 | Type: IMAGE_REL_ARM64_PAGEBASE_REL21 | |
| 54 | 92 | - VirtualAddress: 8 |
| 55 | 93 | SymbolName: .Lstr |
| 56 | Type: 6 | |
| 94 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12A | |
| 57 | 95 | - VirtualAddress: 12 |
| 58 | 96 | SymbolName: function |
| 59 | Type: 3 | |
| 97 | Type: IMAGE_REL_ARM64_BRANCH26 | |
| 60 | 98 | - VirtualAddress: 16 |
| 61 | 99 | SymbolName: .Lglobal |
| 62 | Type: 7 | |
| 100 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 63 | 101 | - VirtualAddress: 20 |
| 64 | 102 | SymbolName: .Lglobal |
| 65 | Type: 7 | |
| 103 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 66 | 104 | - VirtualAddress: 24 |
| 67 | 105 | SymbolName: .Lglobal |
| 68 | Type: 7 | |
| 106 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 69 | 107 | - VirtualAddress: 28 |
| 70 | 108 | SymbolName: .Lglobal |
| 71 | Type: 7 | |
| 109 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 110 | - VirtualAddress: 32 | |
| 111 | SymbolName: .Lglobal | |
| 112 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 113 | - VirtualAddress: 36 | |
| 114 | SymbolName: .Lglobal | |
| 115 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 116 | - VirtualAddress: 40 | |
| 117 | SymbolName: .Lglobal | |
| 118 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 72 | 119 | - VirtualAddress: 44 |
| 73 | 120 | SymbolName: .Lglobal |
| 74 | Type: 14 | |
| 121 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 122 | - VirtualAddress: 48 | |
| 123 | SymbolName: .Lglobal16 | |
| 124 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 125 | - VirtualAddress: 52 | |
| 126 | SymbolName: .Lglobal16 | |
| 127 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 128 | - VirtualAddress: 56 | |
| 129 | SymbolName: .Lglobal16 | |
| 130 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 131 | - VirtualAddress: 60 | |
| 132 | SymbolName: .Lglobal16 | |
| 133 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 134 | - VirtualAddress: 64 | |
| 135 | SymbolName: .Lglobal16 | |
| 136 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 137 | - VirtualAddress: 68 | |
| 138 | SymbolName: .Lglobal16 | |
| 139 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 140 | - VirtualAddress: 72 | |
| 141 | SymbolName: .Lglobal16 | |
| 142 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 143 | - VirtualAddress: 76 | |
| 144 | SymbolName: .Lglobal16 | |
| 145 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 146 | - VirtualAddress: 80 | |
| 147 | SymbolName: .Lglobal16 | |
| 148 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 149 | - VirtualAddress: 84 | |
| 150 | SymbolName: .Lglobal16 | |
| 151 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 152 | - VirtualAddress: 88 | |
| 153 | SymbolName: .Lglobal | |
| 154 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 155 | - VirtualAddress: 92 | |
| 156 | SymbolName: .Lglobal16 | |
| 157 | Type: IMAGE_REL_ARM64_PAGEBASE_REL21 | |
| 158 | - VirtualAddress: 96 | |
| 159 | SymbolName: .Lglobal0 | |
| 160 | Type: IMAGE_REL_ARM64_PAGEOFFSET_12L | |
| 161 | - VirtualAddress: 112 | |
| 162 | SymbolName: .Lglobal | |
| 163 | Type: IMAGE_REL_ARM64_ADDR64 | |
| 164 | - VirtualAddress: 120 | |
| 165 | SymbolName: .Lglobal | |
| 166 | Type: IMAGE_REL_ARM64_ADDR32NB | |
| 167 | - VirtualAddress: 124 | |
| 168 | SymbolName: .Lglobal | |
| 169 | Type: IMAGE_REL_ARM64_SECREL | |
| 75 | 170 | - Name: .data |
| 76 | 171 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] |
| 77 | 172 | Alignment: 4 |
| ... | ... | @@ -127,6 +222,18 @@ symbols: |
| 127 | 222 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 128 | 223 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 129 | 224 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 225 | - Name: .Lglobal16 | |
| 226 | Value: 16 | |
| 227 | SectionNumber: 4 | |
| 228 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 229 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 230 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 231 | - Name: .Lglobal0 | |
| 232 | Value: 0 | |
| 233 | SectionNumber: 4 | |
| 234 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 235 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 236 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 130 | 237 | - Name: function |
| 131 | 238 | Value: 0 |
| 132 | 239 | SectionNumber: 0 |
deps/lld/test/COFF/armnt-blx23t.test+1-1| ... | ... | @@ -37,7 +37,7 @@ sections: |
| 37 | 37 | Relocations: |
| 38 | 38 | - VirtualAddress: 12 |
| 39 | 39 | SymbolName: identity |
| 40 | Type: 21 | |
| 40 | Type: IMAGE_REL_ARM_BLX23T | |
| 41 | 41 | symbols: |
| 42 | 42 | - Name: .text |
| 43 | 43 | Value: 0 |
deps/lld/test/COFF/armnt-branch24t.test+1-1| ... | ... | @@ -30,7 +30,7 @@ sections: |
| 30 | 30 | Relocations: |
| 31 | 31 | - VirtualAddress: 6 |
| 32 | 32 | SymbolName: identity |
| 33 | Type: 20 | |
| 33 | Type: IMAGE_REL_ARM_BRANCH24T | |
| 34 | 34 | symbols: |
| 35 | 35 | - Name: .text |
| 36 | 36 | Value: 0 |
deps/lld/test/COFF/armnt-dynamicbase.test created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | # RUN: yaml2obj < %p/Inputs/armnt-executable.obj.yaml > %t.obj | |
| 2 | # RUN: not lld-link /out:%t.exe /entry:mainCRTStartup /subsystem:console %t.obj /dynamicbase:no 2>&1 | FileCheck %s | |
| 3 | # CHECK: dynamicbase:no is not compatible with arm |
deps/lld/test/COFF/armnt-imports.test+1-1| ... | ... | @@ -22,7 +22,7 @@ sections: |
| 22 | 22 | Relocations: |
| 23 | 23 | - VirtualAddress: 0 |
| 24 | 24 | SymbolName: __imp_function |
| 25 | Type: 17 | |
| 25 | Type: IMAGE_REL_ARM_MOV32T | |
| 26 | 26 | symbols: |
| 27 | 27 | - Name: .text |
| 28 | 28 | Value: 0 |
deps/lld/test/COFF/armnt-mov32t-exec.test+1-1| ... | ... | @@ -31,7 +31,7 @@ sections: |
| 31 | 31 | Relocations: |
| 32 | 32 | - VirtualAddress: 4 |
| 33 | 33 | SymbolName: function |
| 34 | Type: 17 | |
| 34 | Type: IMAGE_REL_ARM_MOV32T | |
| 35 | 35 | symbols: |
| 36 | 36 | - Name: .text |
| 37 | 37 | Value: 0 |
deps/lld/test/COFF/armnt-movt32t.test+1-1| ... | ... | @@ -27,7 +27,7 @@ sections: |
| 27 | 27 | Relocations: |
| 28 | 28 | - VirtualAddress: 0 |
| 29 | 29 | SymbolName: buffer |
| 30 | Type: 17 | |
| 30 | Type: IMAGE_REL_ARM_MOV32T | |
| 31 | 31 | - Name: .rdata |
| 32 | 32 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] |
| 33 | 33 | Alignment: 1 |
deps/lld/test/COFF/common-alignment.test created+78| ... | ... | @@ -0,0 +1,78 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: yaml2obj %s > %t.obj | |
| 3 | # RUN: lld-link /out:%t.exe /entry:main %t.obj %t.obj | |
| 4 | # RUN: llvm-objdump -d %t.exe | FileCheck %s | |
| 5 | ||
| 6 | # Operands of B8 (MOV EAX) are common symbols | |
| 7 | # CHECK: 3000: b8 00 10 00 40 | |
| 8 | # CHECK: 3005: b8 10 10 00 40 | |
| 9 | ||
| 10 | --- !COFF | |
| 11 | header: | |
| 12 | Machine: IMAGE_FILE_MACHINE_AMD64 | |
| 13 | Characteristics: [] | |
| 14 | sections: | |
| 15 | - Name: .text | |
| 16 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 17 | Alignment: 4 | |
| 18 | SectionData: b800000000b800000000 | |
| 19 | Relocations: | |
| 20 | - VirtualAddress: 1 | |
| 21 | SymbolName: bssdata4 | |
| 22 | Type: IMAGE_REL_AMD64_ADDR32 | |
| 23 | - VirtualAddress: 6 | |
| 24 | SymbolName: bssdata4_align16 | |
| 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 | |
| 31 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | |
| 32 | Alignment: 1 | |
| 33 | SectionData: 202d616c69676e636f6d6d3a62737364617461345f616c69676e31362c340a # -aligncomm:bssdata4_align16,4 | |
| 34 | ||
| 35 | symbols: | |
| 36 | - Name: .text | |
| 37 | Value: 0 | |
| 38 | SectionNumber: 1 | |
| 39 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 40 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 41 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 42 | SectionDefinition: | |
| 43 | Length: 0 | |
| 44 | NumberOfRelocations: 5 | |
| 45 | NumberOfLinenumbers: 0 | |
| 46 | CheckSum: 0 | |
| 47 | 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 | |
| 61 | Value: 0 | |
| 62 | SectionNumber: 1 | |
| 63 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 64 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 65 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 66 | - Name: bssdata4 | |
| 67 | Value: 4 | |
| 68 | SectionNumber: 0 | |
| 69 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 70 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 71 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 72 | - Name: bssdata4_align16 | |
| 73 | Value: 4 | |
| 74 | SectionNumber: 0 | |
| 75 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 76 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 77 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 78 | ... |
deps/lld/test/COFF/ctors_dtors_priority.s created+30| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -triple=x86_64-windows-gnu -filetype=obj -o %t.obj %s | |
| 3 | # RUN: lld-link -entry:main %t.obj -out:%t.exe | |
| 4 | # RUN: llvm-objdump -s %t.exe | FileCheck %s | |
| 5 | ||
| 6 | .globl main | |
| 7 | main: | |
| 8 | nop | |
| 9 | ||
| 10 | .section .ctors.00005, "w" | |
| 11 | .quad 2 | |
| 12 | .section .ctors, "w" | |
| 13 | .quad 1 | |
| 14 | .section .ctors.00100, "w" | |
| 15 | .quad 3 | |
| 16 | ||
| 17 | .section .dtors, "w" | |
| 18 | .quad 1 | |
| 19 | .section .dtors.00100, "w" | |
| 20 | .quad 3 | |
| 21 | .section .dtors.00005, "w" | |
| 22 | .quad 2 | |
| 23 | ||
| 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 | |
| 30 | # CHECK-NEXT: 140002010 03000000 00000000 |
deps/lld/test/COFF/debug-dwarf.test created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | # Check that /debug creates %t.pdb. | |
| 2 | # RUN: rm -f %t.pdb | |
| 3 | # RUN: lld-link /debug /entry:main /out:%t.exe %p/Inputs/ret42.obj | |
| 4 | # RUN: ls %t.pdb | |
| 5 | ||
| 6 | # Check that /debug:dwarf does not create %t.pdb. | |
| 7 | # RUN: rm -f %t.pdb | |
| 8 | # RUN: lld-link /debug:dwarf /entry:main /out:%t.exe %p/Inputs/ret42.obj | |
| 9 | # RUN: not ls %t.pdb | |
| 10 | ||
| 11 | # Check that /debug:dwarf /debug creates %t.pdb. | |
| 12 | # RUN: rm -f %t.pdb | |
| 13 | # RUN: lld-link /debug:dwarf /debug /entry:main /out:%t.exe %p/Inputs/ret42.obj | |
| 14 | # RUN: ls %t.pdb | |
| 15 | ||
| 16 | # Check that /debug:dwarf /pdb:%t.pdb does not create %t.pdb. | |
| 17 | # RUN: rm -f %t.pdb | |
| 18 | # RUN: lld-link /debug:dwarf /pdb:%t.pdb /entry:main /out:%t.exe %p/Inputs/ret42.obj | |
| 19 | # RUN: not ls %t.pdb |
deps/lld/test/COFF/def-export-stdcall.s+73-5| ... | ... | @@ -1,21 +1,89 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=i686-windows-msvc %s -o %t.obj |
| 3 | # RUN: echo -e "LIBRARY foo\nEXPORTS\n stdcall" > %t.def | |
| 3 | # RUN: echo -e "LIBRARY foo\nEXPORTS\n stdcall\n fastcall\n vectorcall\n _underscored" > %t.def | |
| 4 | 4 | # RUN: lld-link -entry:dllmain -dll -def:%t.def %t.obj -out:%t.dll -implib:%t.lib |
| 5 | # RUN: llvm-readobj %t.lib | FileCheck %s | |
| 6 | # CHECK: Name type: undecorate | |
| 7 | # CHECK: __imp__stdcall@8 | |
| 8 | # CHECK: _stdcall@8 | |
| 5 | # RUN: llvm-readobj %t.lib | FileCheck -check-prefix UNDECORATED-IMPLIB %s | |
| 6 | # RUN: llvm-readobj -coff-exports %t.dll | FileCheck -check-prefix UNDECORATED-EXPORTS %s | |
| 7 | ||
| 8 | # UNDECORATED-IMPLIB: Name type: noprefix | |
| 9 | # UNDECORATED-IMPLIB-NEXT: __imp___underscored | |
| 10 | # UNDECORATED-IMPLIB-NEXT: __underscored | |
| 11 | # UNDECORATED-IMPLIB: Name type: undecorate | |
| 12 | # UNDECORATED-IMPLIB-NEXT: __imp_@fastcall@8 | |
| 13 | # UNDECORATED-IMPLIB-NEXT: fastcall@8 | |
| 14 | # UNDECORATED-IMPLIB: Name type: undecorate | |
| 15 | # UNDECORATED-IMPLIB-NEXT: __imp__stdcall@8 | |
| 16 | # UNDECORATED-IMPLIB-NEXT: _stdcall@8 | |
| 17 | # UNDECORATED-IMPLIB: Name type: undecorate | |
| 18 | # UNDECORATED-IMPLIB-NEXT: __imp_vectorcall@@8 | |
| 19 | # UNDECORATED-IMPLIB-NEXT: vectorcall@@8 | |
| 20 | ||
| 21 | # UNDECORATED-EXPORTS: Name: _underscored | |
| 22 | # UNDECORATED-EXPORTS: Name: fastcall | |
| 23 | # UNDECORATED-EXPORTS: Name: stdcall | |
| 24 | # UNDECORATED-EXPORTS: Name: vectorcall | |
| 25 | ||
| 26 | ||
| 27 | # RUN: echo -e "LIBRARY foo\nEXPORTS\n _stdcall@8\n @fastcall@8\n vectorcall@@8" > %t.def | |
| 28 | # RUN: lld-link -entry:dllmain -dll -def:%t.def %t.obj -out:%t.dll -implib:%t.lib | |
| 29 | # RUN: llvm-readobj %t.lib | FileCheck -check-prefix DECORATED-IMPLIB %s | |
| 30 | # RUN: llvm-readobj -coff-exports %t.dll | FileCheck -check-prefix DECORATED-EXPORTS %s | |
| 31 | ||
| 32 | # DECORATED-IMPLIB: Name type: name | |
| 33 | # DECORATED-IMPLIB-NEXT: __imp_@fastcall@8 | |
| 34 | # DECORATED-IMPLIB-NEXT: @fastcall@8 | |
| 35 | # TODO: To match link.exe, this one should also be Name type: name. | |
| 36 | # DECORATED-IMPLIB: Name type: noprefix | |
| 37 | # DECORATED-IMPLIB-NEXT: __imp__stdcall@8 | |
| 38 | # DECORATED-IMPLIB-NEXT: _stdcall@8 | |
| 39 | # DECORATED-IMPLIB: Name type: name | |
| 40 | # DECORATED-IMPLIB-NEXT: __imp_vectorcall@@8 | |
| 41 | # DECORATED-IMPLIB-NEXT: vectorcall@@8 | |
| 42 | ||
| 43 | # DECORATED-EXPORTS: Name: @fastcall@8 | |
| 44 | # TODO: To match link.exe, this one should actually be _stdcall@8 | |
| 45 | # DECORATED-EXPORTS: Name: stdcall@8 | |
| 46 | # DECORATED-EXPORTS: Name: vectorcall@@8 | |
| 47 | ||
| 48 | ||
| 49 | # RUN: echo -e "LIBRARY foo\nEXPORTS\n stdcall@8\n @fastcall@8" > %t.def | |
| 50 | # 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 | |
| 52 | # RUN: llvm-readobj -coff-exports %t.dll | FileCheck -check-prefix DECORATED-MINGW-EXPORTS %s | |
| 53 | ||
| 54 | # DECORATED-MINGW-IMPLIB: Name type: name | |
| 55 | # DECORATED-MINGW-IMPLIB-NEXT: __imp_@fastcall@8 | |
| 56 | # DECORATED-MINGW-IMPLIB-NEXT: fastcall@8 | |
| 57 | # DECORATED-MINGW-IMPLIB: Name type: noprefix | |
| 58 | # DECORATED-MINGW-IMPLIB-NEXT: __imp__stdcall@8 | |
| 59 | # DECORATED-MINGW-IMPLIB-NEXT: _stdcall@8 | |
| 60 | ||
| 61 | # DECORATED-MINGW-EXPORTS: Name: @fastcall@8 | |
| 62 | # DECORATED-MINGW-EXPORTS: Name: stdcall@8 | |
| 63 | ||
| 9 | 64 | |
| 10 | 65 | .def _stdcall@8; |
| 11 | 66 | .scl 2; |
| 12 | 67 | .type 32; |
| 13 | 68 | .endef |
| 14 | 69 | .globl _stdcall@8 |
| 70 | .globl @fastcall@8 | |
| 71 | .globl vectorcall@@8 | |
| 72 | .globl __underscored | |
| 15 | 73 | _stdcall@8: |
| 16 | 74 | movl 8(%esp), %eax |
| 17 | 75 | addl 4(%esp), %eax |
| 18 | 76 | retl $8 |
| 77 | @fastcall@8: | |
| 78 | movl 8(%esp), %eax | |
| 79 | addl 4(%esp), %eax | |
| 80 | retl $8 | |
| 81 | vectorcall@@8: | |
| 82 | movl 8(%esp), %eax | |
| 83 | addl 4(%esp), %eax | |
| 84 | retl $8 | |
| 85 | __underscored: | |
| 86 | ret | |
| 19 | 87 | |
| 20 | 88 | .def _dllmain; |
| 21 | 89 | .scl 2; |
deps/lld/test/COFF/delayimports-armnt.yaml created+106| ... | ... | @@ -0,0 +1,106 @@ |
| 1 | # REQUIRES: arm | |
| 2 | # RUN: yaml2obj < %s > %t.obj | |
| 3 | # RUN: lld-link %t.obj %p/Inputs/library.lib /subsystem:console \ | |
| 4 | # RUN: /entry:mainCRTStartup /alternatename:__delayLoadHelper2=mainCRTStartup \ | |
| 5 | # RUN: /delayload:library.dll /out:%t.exe | |
| 6 | # RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s | |
| 7 | # RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s | |
| 8 | # RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s | |
| 9 | ||
| 10 | # IMPORT: Format: COFF-ARM | |
| 11 | # IMPORT-NEXT: Arch: thumb | |
| 12 | # IMPORT-NEXT: AddressSize: 32bit | |
| 13 | # IMPORT-NEXT: DelayImport { | |
| 14 | # IMPORT-NEXT: Name: library.dll | |
| 15 | # IMPORT-NEXT: Attributes: 0x1 | |
| 16 | # IMPORT-NEXT: ModuleHandle: 0x3000 | |
| 17 | # IMPORT-NEXT: ImportAddressTable: 0x3008 | |
| 18 | # IMPORT-NEXT: ImportNameTable: 0x2040 | |
| 19 | # IMPORT-NEXT: BoundDelayImportTable: 0x0 | |
| 20 | # IMPORT-NEXT: UnloadDelayImportTable: 0x0 | |
| 21 | # IMPORT-NEXT: Import { | |
| 22 | # IMPORT-NEXT: Symbol: function (0) | |
| 23 | # IMPORT-NEXT: Address: 0x401019 | |
| 24 | # IMPORT-NEXT: } | |
| 25 | # IMPORT-NEXT: } | |
| 26 | # | |
| 27 | # BASEREL: BaseReloc [ | |
| 28 | # BASEREL-NEXT: Entry { | |
| 29 | # BASEREL-NEXT: Type: ARM_MOV32(T) | |
| 30 | # BASEREL-NEXT: Address: 0x1000 | |
| 31 | # BASEREL-NEXT: } | |
| 32 | # BASEREL-NEXT: Entry { | |
| 33 | # BASEREL-NEXT: Type: ARM_MOV32(T) | |
| 34 | # BASEREL-NEXT: Address: 0x100C | |
| 35 | # BASEREL-NEXT: } | |
| 36 | # BASEREL-NEXT: Entry { | |
| 37 | # BASEREL-NEXT: Type: ARM_MOV32(T) | |
| 38 | # BASEREL-NEXT: Address: 0x1018 | |
| 39 | # BASEREL-NEXT: } | |
| 40 | # BASEREL-NEXT: Entry { | |
| 41 | # BASEREL-NEXT: Type: ARM_MOV32(T) | |
| 42 | # BASEREL-NEXT: Address: 0x102E | |
| 43 | # BASEREL-NEXT: } | |
| 44 | # BASEREL-NEXT: Entry { | |
| 45 | # BASEREL-NEXT: Type: HIGHLOW | |
| 46 | # BASEREL-NEXT: Address: 0x3008 | |
| 47 | # BASEREL-NEXT: } | |
| 48 | # BASEREL-NEXT: Entry { | |
| 49 | # BASEREL-NEXT: Type: ABSOLUTE | |
| 50 | # BASEREL-NEXT: Address: 0x3000 | |
| 51 | # BASEREL-NEXT: } | |
| 52 | # BASEREL-NEXT: ] | |
| 53 | # | |
| 54 | # DISASM: 401018: 43 f2 08 0c movw r12, #12296 | |
| 55 | # DISASM-NEXT: 40101c: c0 f2 40 0c movt r12, #64 | |
| 56 | # DISASM-NEXT: 401020: 2d e9 0f 48 push.w {r0, r1, r2, r3, r11, lr} | |
| 57 | # DISASM-NEXT: 401024: 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} | |
| 59 | # DISASM-NEXT: 40102c: 61 46 mov r1, r12 | |
| 60 | # DISASM-NEXT: 40102e: 42 f2 00 00 movw r0, #8192 | |
| 61 | # DISASM-NEXT: 401032: c0 f2 40 00 movt r0, #64 | |
| 62 | # DISASM-NEXT: 401036: ff f7 e3 ff bl #-58 | |
| 63 | # DISASM-NEXT: 40103a: 84 46 mov r12, r0 | |
| 64 | # DISASM-NEXT: 40103c: 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} | |
| 66 | # DISASM-NEXT: 401044: 60 47 bx r12 | |
| 67 | ||
| 68 | --- !COFF | |
| 69 | header: | |
| 70 | Machine: IMAGE_FILE_MACHINE_ARMNT | |
| 71 | Characteristics: [ ] | |
| 72 | sections: | |
| 73 | - Name: .text | |
| 74 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 75 | Alignment: 4 | |
| 76 | SectionData: 40F20000C0F2000000680047 | |
| 77 | Relocations: | |
| 78 | - VirtualAddress: 0 | |
| 79 | SymbolName: __imp_function | |
| 80 | Type: IMAGE_REL_ARM_MOV32T | |
| 81 | symbols: | |
| 82 | - Name: .text | |
| 83 | Value: 0 | |
| 84 | SectionNumber: 1 | |
| 85 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 86 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 87 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 88 | SectionDefinition: | |
| 89 | Length: 12 | |
| 90 | NumberOfRelocations: 1 | |
| 91 | NumberOfLinenumbers: 0 | |
| 92 | CheckSum: 0 | |
| 93 | Number: 1 | |
| 94 | - Name: mainCRTStartup | |
| 95 | Value: 0 | |
| 96 | SectionNumber: 1 | |
| 97 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 98 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 99 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 100 | - Name: __imp_function | |
| 101 | Value: 0 | |
| 102 | SectionNumber: 0 | |
| 103 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 104 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 105 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 106 | ... |
deps/lld/test/COFF/delayimports32.test+2-2| ... | ... | @@ -73,7 +73,7 @@ BASEREL-NEXT: ] |
| 73 | 73 | |
| 74 | 74 | DISASM: 202b: 68 20 10 40 00 pushl $4198432 |
| 75 | 75 | DISASM-NEXT: 2030: 68 00 40 40 00 pushl $4210688 |
| 76 | DISASM-NEXT: 2035: e8 c6 ff ff ff calll -58 <_main@0> | |
| 76 | DISASM-NEXT: 2035: e8 c6 ff ff ff calll -58 <.text> | |
| 77 | 77 | DISASM-NEXT: 203a: 5a popl %edx |
| 78 | 78 | DISASM-NEXT: 203b: 59 popl %ecx |
| 79 | 79 | DISASM-NEXT: 203c: ff e0 jmpl *%eax |
| ... | ... | @@ -81,7 +81,7 @@ DISASM-NEXT: 203e: 51 pushl %ecx |
| 81 | 81 | DISASM-NEXT: 203f: 52 pushl %edx |
| 82 | 82 | DISASM-NEXT: 2040: 68 24 10 40 00 pushl $4198436 |
| 83 | 83 | DISASM-NEXT: 2045: 68 00 40 40 00 pushl $4210688 |
| 84 | DISASM-NEXT: 204a: e8 b1 ff ff ff calll -79 <_main@0> | |
| 84 | DISASM-NEXT: 204a: e8 b1 ff ff ff calll -79 <.text> | |
| 85 | 85 | DISASM-NEXT: 204f: 5a popl %edx |
| 86 | 86 | DISASM-NEXT: 2050: 59 popl %ecx |
| 87 | 87 | DISASM-NEXT: 2051: ff e0 jmpl *%eax |
deps/lld/test/COFF/dllexport-mingw.s created+24| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | # REQEUIRES: x86 | |
| 2 | ||
| 3 | # RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj | |
| 4 | ||
| 5 | # RUN: lld-link -lldmingw -dll -out:%t.dll -entry:main %t.obj -implib:%t.lib | |
| 6 | # RUN: llvm-readobj %t.lib | FileCheck %s | |
| 7 | ||
| 8 | # CHECK: Symbol: __imp___underscoredFunc | |
| 9 | # CHECK: Symbol: __underscoredFunc | |
| 10 | # CHECK: Symbol: __imp__func | |
| 11 | # CHECK: Symbol: _func | |
| 12 | ||
| 13 | .global _main | |
| 14 | .global _func | |
| 15 | .global __underscoredFunc | |
| 16 | .text | |
| 17 | _main: | |
| 18 | ret | |
| 19 | _func: | |
| 20 | ret | |
| 21 | __underscoredFunc: | |
| 22 | ret | |
| 23 | .section .drectve | |
| 24 | .ascii "-export:func -export:_underscoredFunc" |
deps/lld/test/COFF/driver.test+3| ... | ... | @@ -1,3 +1,6 @@ |
| 1 | 1 | # RUN: not lld-link nosuchfile.obj >& %t.log |
| 2 | 2 | # RUN: FileCheck -check-prefix=MISSING %s < %t.log |
| 3 | 3 | MISSING: nosuchfile.obj: {{[Nn]}}o such file or directory |
| 4 | ||
| 5 | # RUN: lld-link --version | FileCheck -check-prefix=VERSION %s | |
| 6 | VERSION: {{LLD [0-9]+\.[0-9]+}} |
deps/lld/test/COFF/duplicate.test created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 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 beta.obj %S/Inputs/beta.ll | |
| 3 | RUN: lld-link /out:alpha.dll /dll alpha.obj /implib:alpha.lib | |
| 4 | RUN: not lld-link /out:beta.dll /dll alpha.obj beta.obj alpha.lib 2>&1 | FileCheck %s -check-prefix CHECK-ALPHA | |
| 5 | ||
| 6 | CHECK-ALPHA: error: duplicate symbol: f in {{.*}}alpha.obj and in alpha.dll | |
| 7 | ||
| 8 | RUN: llc -mtriple x86_64-windows-msvc -filetype obj -o gamma.obj %S/Inputs/gamma.ll | |
| 9 | RUN: not lld-link /out:gamma.exe /subsystem:console /entry:mainCRTStartup gamma.obj alpha.lib 2>&1 | FileCheck %s -check-prefix CHECK-GAMMA | |
| 10 | ||
| 11 | CHECK-GAMMA: error: duplicate symbol: __imp_f in {{.*}}gamma.obj and in alpha.dll | |
| 12 |
deps/lld/test/COFF/entry-drectve.test created+24| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | # RUN: yaml2obj < %s > %t.obj | |
| 2 | # RUN: lld-link /subsystem:console /out:%t.exe %t.obj | |
| 3 | ||
| 4 | --- !COFF | |
| 5 | header: | |
| 6 | Machine: IMAGE_FILE_MACHINE_I386 | |
| 7 | Characteristics: [] | |
| 8 | sections: | |
| 9 | - Name: .text | |
| 10 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 11 | Alignment: 4 | |
| 12 | SectionData: B800000000506800000000680000000050E80000000050E800000000 | |
| 13 | - Name: .drectve | |
| 14 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | |
| 15 | Alignment: 1 | |
| 16 | SectionData: 2f656e7472793a437573746f6d456e74727900 # /entry:CustomEntry | |
| 17 | symbols: | |
| 18 | - Name: _CustomEntry | |
| 19 | Value: 0 | |
| 20 | SectionNumber: 1 | |
| 21 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 22 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 23 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 24 | ... |
deps/lld/test/COFF/entry-inference.test+4-4| ... | ... | @@ -14,10 +14,10 @@ |
| 14 | 14 | # RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1 |
| 15 | 15 | # RUN: FileCheck -check-prefix=WWINMAIN %s < %t.log |
| 16 | 16 | |
| 17 | # MAIN: <root>: undefined symbol: mainCRTStartup | |
| 18 | # WMAIN: <root>: undefined symbol: wmainCRTStartup | |
| 19 | # WINMAIN: <root>: undefined symbol: WinMainCRTStartup | |
| 20 | # WWINMAIN: <root>: undefined symbol: wWinMainCRTStartup | |
| 17 | # MAIN: error: <root>: undefined symbol: mainCRTStartup | |
| 18 | # WMAIN: error: <root>: undefined symbol: wmainCRTStartup | |
| 19 | # WINMAIN: error: <root>: undefined symbol: WinMainCRTStartup | |
| 20 | # WWINMAIN: error: <root>: undefined symbol: wWinMainCRTStartup | |
| 21 | 21 | |
| 22 | 22 | --- !COFF |
| 23 | 23 | header: |
deps/lld/test/COFF/export-all.s created+86| ... | ... | @@ -0,0 +1,86 @@ |
| 1 | # REQEUIRES: x86 | |
| 2 | ||
| 3 | # RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj | |
| 4 | ||
| 5 | # RUN: lld-link -lldmingw -dll -out:%t.dll -entry:DllMainCRTStartup@12 %t.obj -implib:%t.lib | |
| 6 | # RUN: llvm-readobj -coff-exports %t.dll | FileCheck %s | |
| 7 | # RUN: llvm-readobj %t.lib | FileCheck -check-prefix=IMPLIB %s | |
| 8 | ||
| 9 | # CHECK-NOT: Name: DllMainCRTStartup | |
| 10 | # CHECK-NOT: Name: _imp__unexported | |
| 11 | # CHECK: Name: dataSym | |
| 12 | # CHECK: Name: foobar | |
| 13 | # CHECK-NOT: Name: unexported | |
| 14 | ||
| 15 | # IMPLIB: Symbol: __imp__dataSym | |
| 16 | # IMPLIB-NOT: Symbol: _dataSym | |
| 17 | # IMPLIB: Symbol: __imp__foobar | |
| 18 | # IMPLIB: Symbol: _foobar | |
| 19 | ||
| 20 | .global _foobar | |
| 21 | .global _DllMainCRTStartup@12 | |
| 22 | .global _dataSym | |
| 23 | .global _unexported | |
| 24 | .global __imp__unexported | |
| 25 | .text | |
| 26 | _DllMainCRTStartup@12: | |
| 27 | ret | |
| 28 | _foobar: | |
| 29 | ret | |
| 30 | _unexported: | |
| 31 | ret | |
| 32 | .data | |
| 33 | _dataSym: | |
| 34 | .int 4 | |
| 35 | __imp__unexported: | |
| 36 | .int _unexported | |
| 37 | ||
| 38 | # Test specifying -export-all-symbols, on an object file that contains | |
| 39 | # dllexport directive for some of the symbols. | |
| 40 | ||
| 41 | # RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj | |
| 42 | # | |
| 43 | # RUN: lld-link -out:%t.dll -dll %t.obj -lldmingw -export-all-symbols -output-def:%t.def | |
| 44 | # RUN: llvm-readobj -coff-exports %t.dll | FileCheck -check-prefix=CHECK2 %s | |
| 45 | # RUN: cat %t.def | FileCheck -check-prefix=CHECK2-DEF %s | |
| 46 | ||
| 47 | # Note, this will actually export _DllMainCRTStartup as well, since | |
| 48 | # it uses the standard spelling in this object file, not the MinGW one. | |
| 49 | ||
| 50 | # CHECK2: Name: exportfn1 | |
| 51 | # CHECK2: Name: exportfn2 | |
| 52 | # CHECK2: Name: exportfn3 | |
| 53 | ||
| 54 | # CHECK2-DEF: EXPORTS | |
| 55 | # CHECK2-DEF: exportfn1 @3 | |
| 56 | # CHECK2-DEF: exportfn2 @4 | |
| 57 | # CHECK2-DEF: exportfn3 @5 | |
| 58 | ||
| 59 | # Test ignoring certain object files and libs. | |
| 60 | ||
| 61 | # RUN: echo -e ".global foobar\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\nfoobar:\ncall mingwfunc\ncall crtfunc\nret\n" > %t.main.s | |
| 62 | # RUN: llvm-mc -triple=x86_64-windows-gnu %t.main.s -filetype=obj -o %t.main.obj | |
| 63 | # RUN: mkdir -p %T/libs | |
| 64 | # RUN: echo -e ".global mingwfunc\n.text\nmingwfunc:\nret\n" > %T/libs/mingwfunc.s | |
| 65 | # RUN: llvm-mc -triple=x86_64-windows-gnu %T/libs/mingwfunc.s -filetype=obj -o %T/libs/mingwfunc.o | |
| 66 | # RUN: llvm-ar rcs %T/libs/libmingwex.a %T/libs/mingwfunc.o | |
| 67 | # RUN: echo -e ".global crtfunc\n.text\ncrtfunc:\nret\n" > %T/libs/crtfunc.s | |
| 68 | # RUN: llvm-mc -triple=x86_64-windows-gnu %T/libs/crtfunc.s -filetype=obj -o %T/libs/crt2.o | |
| 69 | # RUN: lld-link -out:%t.dll -dll -entry:DllMainCRTStartup %t.main.obj -lldmingw %T/libs/crt2.o %T/libs/libmingwex.a -output-def:%t.def | |
| 70 | # RUN: echo "EOF" >> %t.def | |
| 71 | # RUN: cat %t.def | FileCheck -check-prefix=CHECK-EXCLUDE %s | |
| 72 | ||
| 73 | # CHECK-EXCLUDE: EXPORTS | |
| 74 | # CHECK-EXCLUDE-NEXT: foobar @1 | |
| 75 | # CHECK-EXCLUDE-NEXT: EOF | |
| 76 | ||
| 77 | # Test that we handle import libraries together with -opt:noref. | |
| 78 | ||
| 79 | # RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj | |
| 80 | # RUN: lld-link -lldmingw -dll -out:%t.dll -entry:main@0 %t.obj -implib:%t.lib -opt:noref %p/Inputs/std32.lib -output-def:%t.def | |
| 81 | # RUN: echo "EOF" >> %t.def | |
| 82 | # RUN: cat %t.def | FileCheck -check-prefix=CHECK-IMPLIB %s | |
| 83 | ||
| 84 | # CHECK-IMPLIB: EXPORTS | |
| 85 | # CHECK-IMPLIB-NEXT: main@0 @1 | |
| 86 | # CHECK-IMPLIB-NEXT: EOF |
deps/lld/test/COFF/export-arm64.yaml created+70| ... | ... | @@ -0,0 +1,70 @@ |
| 1 | # REQUIRES: aarch64 | |
| 2 | ||
| 3 | # RUN: yaml2obj < %s > %t.obj | |
| 4 | # RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 /implib:%t.lib | |
| 5 | # RUN: llvm-objdump -p %t.dll | FileCheck %s | |
| 6 | # RUN: llvm-objdump -r %t.lib | FileCheck %s -check-prefix=RELOCS | |
| 7 | ||
| 8 | # CHECK: Export Table: | |
| 9 | # CHECK: DLL name: export-arm64.yaml.tmp.dll | |
| 10 | # CHECK: Ordinal RVA Name | |
| 11 | # CHECK-NEXT: 0 0 | |
| 12 | # CHECK-NEXT: 1 0x1008 exportfn1 | |
| 13 | # CHECK-NEXT: 2 0x1010 exportfn2 | |
| 14 | # CHECK-NEXT: 3 0x1018 exportfn3 | |
| 15 | ||
| 16 | # RELOCS: IMAGE_REL_ARM64_ADDR32NB .idata$6 | |
| 17 | # RELOCS: IMAGE_REL_ARM64_ADDR32NB .idata$4 | |
| 18 | # RELOCS: IMAGE_REL_ARM64_ADDR32NB .idata$5 | |
| 19 | ||
| 20 | --- !COFF | |
| 21 | header: | |
| 22 | Machine: IMAGE_FILE_MACHINE_ARM64 | |
| 23 | Characteristics: [] | |
| 24 | sections: | |
| 25 | - Name: .text | |
| 26 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 27 | Alignment: 4 | |
| 28 | SectionData: e0031f2ac0035fd6e0031f2ac0035fd6e0031f2ac0035fd6e0031f2ac0035fd6 | |
| 29 | - Name: .drectve | |
| 30 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | |
| 31 | Alignment: 1 | |
| 32 | SectionData: 2f6578706f72743a6578706f7274666e3300 # /export:exportfn3 | |
| 33 | symbols: | |
| 34 | - Name: .text | |
| 35 | Value: 0 | |
| 36 | SectionNumber: 1 | |
| 37 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 38 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 39 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 40 | SectionDefinition: | |
| 41 | Length: 32 | |
| 42 | NumberOfRelocations: 0 | |
| 43 | NumberOfLinenumbers: 0 | |
| 44 | CheckSum: 0 | |
| 45 | Number: 1 | |
| 46 | - Name: _DllMainCRTStartup | |
| 47 | Value: 0 | |
| 48 | SectionNumber: 1 | |
| 49 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 50 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 51 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 52 | - Name: exportfn1 | |
| 53 | Value: 8 | |
| 54 | SectionNumber: 1 | |
| 55 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 56 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 57 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 58 | - Name: exportfn2 | |
| 59 | Value: 16 | |
| 60 | SectionNumber: 1 | |
| 61 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 62 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 63 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 64 | - Name: exportfn3 | |
| 65 | Value: 24 | |
| 66 | SectionNumber: 1 | |
| 67 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 68 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 69 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 70 | ... |
deps/lld/test/COFF/export-armnt.yaml created+95| ... | ... | @@ -0,0 +1,95 @@ |
| 1 | # REQUIRES: arm | |
| 2 | ||
| 3 | # RUN: yaml2obj < %s > %t.obj | |
| 4 | # | |
| 5 | # RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 /export:exportdata,data | |
| 6 | # RUN: llvm-objdump -p %t.dll | FileCheck %s | |
| 7 | ||
| 8 | # CHECK: Export Table: | |
| 9 | # CHECK: DLL name: export-armnt.yaml.tmp.dll | |
| 10 | # CHECK: Ordinal RVA Name | |
| 11 | # CHECK-NEXT: 0 0 | |
| 12 | # CHECK-NEXT: 1 0x1000 exportdata | |
| 13 | # CHECK-NEXT: 2 0x2005 exportfn1 | |
| 14 | # CHECK-NEXT: 3 0x2009 exportfn2 | |
| 15 | # CHECK-NEXT: 4 0x2009 exportfn3 | |
| 16 | ||
| 17 | --- !COFF | |
| 18 | header: | |
| 19 | Machine: IMAGE_FILE_MACHINE_ARMNT | |
| 20 | Characteristics: [] | |
| 21 | sections: | |
| 22 | - Name: .text | |
| 23 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 24 | Alignment: 4 | |
| 25 | SectionData: 704700bf704700bf704700bf | |
| 26 | - Name: .data | |
| 27 | Characteristics: [ IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | |
| 28 | Alignment: 4 | |
| 29 | SectionData: 00000000 | |
| 30 | - Name: .drectve | |
| 31 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | |
| 32 | Alignment: 1 | |
| 33 | SectionData: 2f6578706f72743a6578706f7274666e3300 # /export:exportfn3 | |
| 34 | symbols: | |
| 35 | - Name: .text | |
| 36 | Value: 0 | |
| 37 | SectionNumber: 1 | |
| 38 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 39 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 40 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 41 | SectionDefinition: | |
| 42 | Length: 12 | |
| 43 | NumberOfRelocations: 0 | |
| 44 | NumberOfLinenumbers: 0 | |
| 45 | CheckSum: 0 | |
| 46 | Number: 0 | |
| 47 | - Name: .data | |
| 48 | Value: 0 | |
| 49 | SectionNumber: 2 | |
| 50 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 51 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 52 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 53 | SectionDefinition: | |
| 54 | Length: 4 | |
| 55 | NumberOfRelocations: 0 | |
| 56 | NumberOfLinenumbers: 0 | |
| 57 | CheckSum: 0 | |
| 58 | Number: 0 | |
| 59 | - Name: _DllMainCRTStartup | |
| 60 | Value: 0 | |
| 61 | SectionNumber: 1 | |
| 62 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 63 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 64 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 65 | - Name: exportfn1 | |
| 66 | Value: 4 | |
| 67 | SectionNumber: 1 | |
| 68 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 69 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 70 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 71 | - Name: exportfn2 | |
| 72 | Value: 8 | |
| 73 | SectionNumber: 1 | |
| 74 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 75 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 76 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 77 | - Name: exportfn3 | |
| 78 | Value: 8 | |
| 79 | SectionNumber: 1 | |
| 80 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 81 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 82 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 83 | - Name: exportdata | |
| 84 | Value: 0 | |
| 85 | SectionNumber: 2 | |
| 86 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 87 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 88 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 89 | - Name: '?mangled@@YAHXZ' | |
| 90 | Value: 8 | |
| 91 | SectionNumber: 1 | |
| 92 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 93 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 94 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 95 | ... |
deps/lld/test/COFF/export32.test+5| ... | ... | @@ -57,6 +57,11 @@ |
| 57 | 57 | # RUN: lld-link /out:%t.dll /dll %t.obj /def:%t.def |
| 58 | 58 | # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK5 %s |
| 59 | 59 | |
| 60 | # RUN: echo "EXPORTS exportfn1 @ 3" > %t.def | |
| 61 | # RUN: echo "fn2=exportfn2 @ 2" >> %t.def | |
| 62 | # RUN: lld-link /out:%t.dll /dll %t.obj /def:%t.def | |
| 63 | # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK5 %s | |
| 64 | ||
| 60 | 65 | # CHECK5: Export Table: |
| 61 | 66 | # CHECK5: DLL name: export32.test.tmp.dll |
| 62 | 67 | # CHECK5: Ordinal RVA Name |
deps/lld/test/COFF/filename-casing.s created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %T/MixedCase.obj %s | |
| 4 | # RUN: not lld-link /entry:main %T/MixedCase.obj 2>&1 | FileCheck -check-prefix=OBJECT %s | |
| 5 | ||
| 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 | |
| 8 | ||
| 9 | # OBJECT: MixedCase.obj: undefined symbol: f | |
| 10 | # ARCHIVE: MixedCase.lib(MixedCase.obj): undefined symbol: f | |
| 11 | ||
| 12 | .globl main | |
| 13 | main: | |
| 14 | 	callq	f |
deps/lld/test/COFF/force.test+4-3| ... | ... | @@ -1,10 +1,11 @@ |
| 1 | 1 | # RUN: yaml2obj < %s > %t.obj |
| 2 | 2 | # RUN: not lld-link /out:%t.exe /entry:main %t.obj >& %t.log |
| 3 | # RUN: FileCheck %s < %t.log | |
| 3 | # RUN: FileCheck -check-prefix=ERROR %s < %t.log | |
| 4 | 4 | # RUN: lld-link /out:%t.exe /entry:main %t.obj /force >& %t.log |
| 5 | # RUN: FileCheck %s < %t.log | |
| 5 | # RUN: FileCheck -check-prefix=WARN %s < %t.log | |
| 6 | 6 | |
| 7 | # CHECK: .obj: undefined symbol: foo | |
| 7 | # ERROR: error: {{.*}}.obj: undefined symbol: foo | |
| 8 | # WARN: warning: {{.*}}.obj: undefined symbol: foo | |
| 8 | 9 | |
| 9 | 10 | --- !COFF |
| 10 | 11 | header: |
deps/lld/test/COFF/guardcf.test+6| ... | ... | @@ -71,4 +71,10 @@ symbols: |
| 71 | 71 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 72 | 72 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 73 | 73 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL |
| 74 | - Name: __enclave_config | |
| 75 | Value: 0 | |
| 76 | SectionNumber: 0 | |
| 77 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 78 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 79 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 74 | 80 | ... |
deps/lld/test/COFF/hello32.test+3-3| ... | ... | @@ -39,13 +39,13 @@ HEADER-NEXT: MajorImageVersion: 0 |
| 39 | 39 | HEADER-NEXT: MinorImageVersion: 0 |
| 40 | 40 | HEADER-NEXT: MajorSubsystemVersion: 6 |
| 41 | 41 | HEADER-NEXT: MinorSubsystemVersion: 0 |
| 42 | HEADER-NEXT: SizeOfImage: 16896 | |
| 42 | HEADER-NEXT: SizeOfImage: 20480 | |
| 43 | 43 | HEADER-NEXT: SizeOfHeaders: 512 |
| 44 | 44 | HEADER-NEXT: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3) |
| 45 | HEADER-NEXT: Characteristics [ (0x9940) | |
| 45 | HEADER-NEXT: Characteristics [ (0x9540) | |
| 46 | 46 | HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_APPCONTAINER (0x1000) |
| 47 | 47 | HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE (0x40) |
| 48 | HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_NO_BIND (0x800) | |
| 48 | HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_NO_SEH (0x400) | |
| 49 | 49 | HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT (0x100) |
| 50 | 50 | HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE (0x8000) |
| 51 | 51 | HEADER-NEXT: ] |
deps/lld/test/COFF/icf-associative.test+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | # RUN: yaml2obj < %s > %t.obj |
| 2 | # RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \ | |
| 2 | # RUN: lld-link /opt:icf /entry:foo /out:%t.exe /subsystem:console /include:bar \ | |
| 3 | 3 | # RUN: /debug /verbose %t.obj > %t.log 2>&1 |
| 4 | 4 | # RUN: FileCheck %s < %t.log |
| 5 | 5 |
deps/lld/test/COFF/icf-executable.s created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | # 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 | ||
| 4 | # CHECK: Selected internal | |
| 5 | # CHECK: Removed f2 | |
| 6 | ||
| 7 | .section .text,"xr",one_only,internal | |
| 8 | internal: | |
| 9 | .globl main | |
| 10 | main: | |
| 11 | call f2 | |
| 12 | ret | |
| 13 | ||
| 14 | .section .text,"xr",one_only,f2 | |
| 15 | .globl f2 | |
| 16 | f2: | |
| 17 | call main | |
| 18 | ret |
deps/lld/test/COFF/icf-simple.test+26-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | # RUN: yaml2obj < %s > %t.obj |
| 2 | # RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \ | |
| 2 | # RUN: lld-link /opt:icf /entry:foo /out:%t.exe /subsystem:console /include:bar \ | |
| 3 | 3 | # RUN: /verbose %t.obj > %t.log 2>&1 |
| 4 | 4 | # RUN: FileCheck -check-prefix=ICF %s < %t.log |
| 5 | 5 | |
| ... | ... | @@ -13,6 +13,31 @@ |
| 13 | 13 | # RUN: /verbose /opt:noref,noicf %t.obj > %t.log 2>&1 |
| 14 | 14 | # RUN: FileCheck -check-prefix=NOICF %s < %t.log |
| 15 | 15 | |
| 16 | # ICF is on by default (no /opt: flags). | |
| 17 | # RUN: lld-link /entry:foo /out:%t.exe /subsystem:console \ | |
| 18 | # RUN: /include:bar /verbose %t.obj > %t.log 2>&1 | |
| 19 | # RUN: FileCheck -check-prefix=ICF %s < %t.log | |
| 20 | ||
| 21 | # /debug disables ICF. | |
| 22 | # RUN: lld-link /debug /entry:foo /out:%t.exe /subsystem:console \ | |
| 23 | # RUN: /include:bar /verbose %t.obj > %t.log 2>&1 | |
| 24 | # RUN: FileCheck -check-prefix=NOICF %s < %t.log | |
| 25 | ||
| 26 | # /opt:noref disables ICF. | |
| 27 | # RUN: lld-link /opt:noref /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 | ||
| 31 | # /debug /opt:ref enables ICF. | |
| 32 | # RUN: lld-link /debug /opt:ref /entry:foo /out:%t.exe /subsystem:console \ | |
| 33 | # RUN: /include:bar /verbose %t.obj > %t.log 2>&1 | |
| 34 | # RUN: FileCheck -check-prefix=ICF %s < %t.log | |
| 35 | ||
| 36 | # /debug /opt:noicf,ref disables ICF. | |
| 37 | # RUN: lld-link /debug /opt:noicf,ref /entry:foo /out:%t.exe /subsystem:console \ | |
| 38 | # RUN: /include:bar /verbose %t.obj > %t.log 2>&1 | |
| 39 | # RUN: FileCheck -check-prefix=NOICF %s < %t.log | |
| 40 | ||
| 16 | 41 | # NOICF-NOT: Removed foo |
| 17 | 42 | # NOICF-NOT: Removed bar |
| 18 | 43 |
deps/lld/test/COFF/icf-xdata.s created+86| ... | ... | @@ -0,0 +1,86 @@ |
| 1 | # RUN: llvm-mc %s -triple x86_64-windows-msvc -filetype=obj -o %t.obj | |
| 2 | # RUN: lld-link %t.obj -dll -noentry -out:%t.dll | |
| 3 | # RUN: llvm-readobj -sections %t.dll | FileCheck %s | |
| 4 | ||
| 5 | # There shouldn't be much xdata, because all three .pdata entries (12 bytes | |
| 6 | # each) should use the same .xdata unwind info. | |
| 7 | # CHECK: Name: .pdata | |
| 8 | # CHECK-NEXT: VirtualSize: 0x24 | |
| 9 | # CHECK: Name: .xdata | |
| 10 | # CHECK-NEXT: VirtualSize: 0x8 | |
| 11 | ||
| 12 | 	.text | |
| 13 | callee: | |
| 14 | 	ret | |
| 15 | ||
| 16 | 	.def	 xdata1; | |
| 17 | 	.scl	2; | |
| 18 | 	.type	32; | |
| 19 | 	.endef | |
| 20 | 	.section	.text,"xr",one_only,xdata1 | |
| 21 | 	.globl	xdata1 # -- Begin function xdata1 | |
| 22 | 	.p2align	4, 0x90 | |
| 23 | xdata1: # @xdata1 | |
| 24 | .seh_proc xdata1 | |
| 25 | # BB#0: # %entry | |
| 26 | 	subq	$40, %rsp | |
| 27 | 	.seh_stackalloc 40 | |
| 28 | 	.seh_endprologue | |
| 29 | 	callq	callee | |
| 30 | 	nop | |
| 31 | 	addq	$40, %rsp | |
| 32 | 	jmp	callee # TAILCALL | |
| 33 | 	.seh_handlerdata | |
| 34 | 	.section	.text,"xr",one_only,xdata1 | |
| 35 | 	.seh_endproc | |
| 36 | # -- End function | |
| 37 | 	.def	 xdata2; | |
| 38 | 	.scl	2; | |
| 39 | 	.type	32; | |
| 40 | 	.endef | |
| 41 | 	.section	.text,"xr",one_only,xdata2 | |
| 42 | 	.globl	xdata2 # -- Begin function xdata2 | |
| 43 | 	.p2align	4, 0x90 | |
| 44 | xdata2: # @xdata2 | |
| 45 | .seh_proc xdata2 | |
| 46 | # BB#0: # %entry | |
| 47 | 	subq	$40, %rsp | |
| 48 | 	.seh_stackalloc 40 | |
| 49 | 	.seh_endprologue | |
| 50 | 	callq	callee | |
| 51 | 	callq	callee | |
| 52 | 	nop | |
| 53 | 	addq	$40, %rsp | |
| 54 | 	jmp	callee # TAILCALL | |
| 55 | 	.seh_handlerdata | |
| 56 | 	.section	.text,"xr",one_only,xdata2 | |
| 57 | 	.seh_endproc | |
| 58 | # -- End function | |
| 59 | 	.def	 xdata3; | |
| 60 | 	.scl	2; | |
| 61 | 	.type	32; | |
| 62 | 	.endef | |
| 63 | 	.section	.text,"xr",one_only,xdata3 | |
| 64 | 	.globl	xdata3 # -- Begin function xdata3 | |
| 65 | 	.p2align	4, 0x90 | |
| 66 | xdata3: # @xdata3 | |
| 67 | .seh_proc xdata3 | |
| 68 | # BB#0: # %entry | |
| 69 | 	subq	$40, %rsp | |
| 70 | 	.seh_stackalloc 40 | |
| 71 | 	.seh_endprologue | |
| 72 | 	callq	callee | |
| 73 | 	callq	callee | |
| 74 | 	callq	callee | |
| 75 | 	nop | |
| 76 | 	addq	$40, %rsp | |
| 77 | 	jmp	callee # TAILCALL | |
| 78 | 	.seh_handlerdata | |
| 79 | 	.section	.text,"xr",one_only,xdata3 | |
| 80 | 	.seh_endproc | |
| 81 | # -- End function | |
| 82 | 	.section	.drectve,"yn" | |
| 83 | 	.ascii	" -export:xdata1" | |
| 84 | 	.ascii	" -export:xdata2" | |
| 85 | 	.ascii	" -export:xdata3" | |
| 86 |
deps/lld/test/COFF/ignore4217.yaml created+72| ... | ... | @@ -0,0 +1,72 @@ |
| 1 | # Tests that /ignore:4217 suppresses "locally defined symbol imported" warnings. | |
| 2 | # RUN: yaml2obj < %s > %t.obj | |
| 3 | ||
| 4 | # RUN: lld-link -entry:main -out:%t.exe %t.obj 2>&1 \ | |
| 5 | # RUN: | FileCheck -check-prefix=WARNINGS %s | |
| 6 | # RUN: lld-link -ignore:4217 -entry:main -out:%t.exe %t.obj 2>&1 \ | |
| 7 | # RUN: | FileCheck -allow-empty -check-prefix=SUPPRESSED %s | |
| 8 | ||
| 9 | # WARNINGS: locally defined symbol imported | |
| 10 | # SUPPRESSED-NOT: locally defined symbol imported | |
| 11 | ||
| 12 | --- !COFF | |
| 13 | header: | |
| 14 | Machine: IMAGE_FILE_MACHINE_AMD64 | |
| 15 | Characteristics: [ ] | |
| 16 | sections: | |
| 17 | - Name: .text | |
| 18 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 19 | Alignment: 16 | |
| 20 | SectionData: B82A000000C3662E0F1F8400000000004883EC28C744242400000000E800000000904883C428C3 | |
| 21 | Relocations: | |
| 22 | - VirtualAddress: 29 | |
| 23 | SymbolName: __imp_foo | |
| 24 | Type: IMAGE_REL_AMD64_REL32 | |
| 25 | - Name: .data | |
| 26 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | |
| 27 | Alignment: 4 | |
| 28 | SectionData: '' | |
| 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: 39 | |
| 38 | NumberOfRelocations: 1 | |
| 39 | NumberOfLinenumbers: 0 | |
| 40 | CheckSum: 3087210877 | |
| 41 | Number: 1 | |
| 42 | - Name: .data | |
| 43 | Value: 0 | |
| 44 | SectionNumber: 2 | |
| 45 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 46 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 47 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 48 | SectionDefinition: | |
| 49 | Length: 0 | |
| 50 | NumberOfRelocations: 0 | |
| 51 | NumberOfLinenumbers: 0 | |
| 52 | CheckSum: 0 | |
| 53 | Number: 2 | |
| 54 | - Name: foo | |
| 55 | Value: 0 | |
| 56 | SectionNumber: 1 | |
| 57 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 58 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 59 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 60 | - Name: main | |
| 61 | Value: 16 | |
| 62 | SectionNumber: 1 | |
| 63 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 64 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 65 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 66 | - Name: __imp_foo | |
| 67 | Value: 0 | |
| 68 | SectionNumber: 0 | |
| 69 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 70 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 71 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 72 | ... |
deps/lld/test/COFF/include.test+13| ... | ... | @@ -62,6 +62,19 @@ symbols: |
| 62 | 62 | CheckSum: 0 |
| 63 | 63 | Number: 0 |
| 64 | 64 | Selection: IMAGE_COMDAT_SELECT_ANY |
| 65 | - Name: '.text$mn' | |
| 66 | Value: 0 | |
| 67 | SectionNumber: 3 | |
| 68 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 69 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 70 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 71 | SectionDefinition: | |
| 72 | Length: 6 | |
| 73 | NumberOfRelocations: 0 | |
| 74 | NumberOfLinenumbers: 0 | |
| 75 | CheckSum: 0 | |
| 76 | Number: 0 | |
| 77 | Selection: IMAGE_COMDAT_SELECT_ANY | |
| 65 | 78 | - Name: main |
| 66 | 79 | Value: 0 |
| 67 | 80 | SectionNumber: 1 |
deps/lld/test/COFF/libpath.test+10-2| ... | ... | @@ -5,14 +5,22 @@ |
| 5 | 5 | |
| 6 | 6 | # RUN: env LIB=%t/a lld-link /out:%t.exe /entry:main /verbose \ |
| 7 | 7 | # RUN: std64.lib /subsystem:console %p/Inputs/hello64.obj \ |
| 8 | # RUN: /libpath:%t/b /libpath:%t/c > %t.log | |
| 8 | # RUN: /libpath:%t/b /libpath:%t/c 2> %t.log | |
| 9 | 9 | # RUN: FileCheck -check-prefix=CHECK1 %s < %t.log |
| 10 | 10 | |
| 11 | 11 | CHECK1: b{{[/\\]}}std64.lib |
| 12 | 12 | |
| 13 | 13 | # RUN: lld-link /out:%t.exe /entry:main /verbose \ |
| 14 | 14 | # RUN: std64.lib /subsystem:console %p/Inputs/hello64.obj \ |
| 15 | # RUN: /libpath:%t/a /libpath:%t/b /libpath:%t/c > %t.log | |
| 15 | # RUN: /libpath:%t/a /libpath:%t/b /libpath:%t/c 2> %t.log | |
| 16 | 16 | # RUN: FileCheck -check-prefix=CHECK2 %s < %t.log |
| 17 | 17 | |
| 18 | 18 | CHECK2: a{{[/\\]}}std64.lib |
| 19 | ||
| 20 | # RUN: lld-link /out:%t.exe /entry:main /verbose \ | |
| 21 | # RUN: %t/a/std64.lib /subsystem:console %p/Inputs/hello64.obj \ | |
| 22 | # RUN: /libpath:%t/b /verbose > %t.log 2>&1 | |
| 23 | # RUN: FileCheck -check-prefix=CHECK3 %s < %t.log | |
| 24 | ||
| 25 | CHECK3: Reading {{.*}}a/std64.lib | |
| 26 | CHECK3-NOT: Reading {{.*}}b/std64.lib |
deps/lld/test/COFF/linkrepro-manifest.test created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | REQUIRES: x86, gnutar, manifest_tool | |
| 2 | ||
| 3 | RUN: rm -rf %t && mkdir %t && cd %t | |
| 4 | RUN: lld-link -entry:__ImageBase -nodefaultlib -linkrepro:%t -manifest:embed %p/Inputs/std32.lib -subsystem:console | |
| 5 | RUN: tar tf repro.tar | FileCheck --check-prefix=LIST %s | |
| 6 | RUN: tar xOf repro.tar repro/response.txt | FileCheck %s | |
| 7 | ||
| 8 | LIST: manifest.res | |
| 9 | ||
| 10 | CHECK-NOT: -manifest: | |
| 11 | CHECK: .manifest.res | |
| 12 | CHECK-NOT: -manifest: |
deps/lld/test/COFF/linkrepro-pdb.test created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | REQUIRES: x86, gnutar | |
| 2 | ||
| 3 | RUN: rm -rf %t && mkdir -p %t && cd %t | |
| 4 | RUN: yaml2obj %S/Inputs/pdb-type-server-simple-a.yaml -o a.obj | |
| 5 | RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o b.obj | |
| 6 | RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb | |
| 7 | RUN: lld-link a.obj b.obj -entry:main -debug -out:t.exe -pdb:t.pdb -nodefaultlib -linkrepro:. | |
| 8 | RUN: tar xOf repro.tar repro/%:t/ts.pdb > repro-ts.pdb | |
| 9 | RUN: diff ts.pdb repro-ts.pdb |
deps/lld/test/COFF/linkrepro-res.test created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | # REQUIRES: x86, shell | |
| 2 | ||
| 3 | # RUN: rm -rf %t.dir | |
| 4 | # RUN: mkdir -p %t.dir/build | |
| 5 | # RUN: cd %t.dir/build | |
| 6 | # RUN: lld-link %p/Inputs/resource.res /subsystem:console /machine:x64 \ | |
| 7 | # RUN: /entry:__ImageBase /linkrepro:. /out:%t.exe | |
| 8 | # RUN: tar xf repro.tar | |
| 9 | # RUN: diff %p/Inputs/resource.res repro/%:p/Inputs/resource.res | |
| 10 | # RUN: FileCheck %s --check-prefix=RSP < repro/response.txt | |
| 11 | ||
| 12 | # RSP: resource.res |
deps/lld/test/COFF/loadcfg.test+2-19| ... | ... | @@ -14,10 +14,6 @@ sections: |
| 14 | 14 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 15 | 15 | Alignment: 4 |
| 16 | 16 | SectionData: B82A000000C3 |
| 17 | - Name: .text | |
| 18 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 19 | Alignment: 4 | |
| 20 | SectionData: B82A000000C3 | |
| 21 | 17 | - Name: .rdata |
| 22 | 18 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] |
| 23 | 19 | Alignment: 16 |
| ... | ... | @@ -35,19 +31,6 @@ symbols: |
| 35 | 31 | NumberOfLinenumbers: 0 |
| 36 | 32 | CheckSum: 0 |
| 37 | 33 | Number: 0 |
| 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: 6 | |
| 46 | NumberOfRelocations: 0 | |
| 47 | NumberOfLinenumbers: 0 | |
| 48 | CheckSum: 0 | |
| 49 | Number: 0 | |
| 50 | Selection: IMAGE_COMDAT_SELECT_ANY | |
| 51 | 34 | - Name: main |
| 52 | 35 | Value: 0 |
| 53 | 36 | SectionNumber: 1 |
| ... | ... | @@ -56,7 +39,7 @@ symbols: |
| 56 | 39 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL |
| 57 | 40 | - Name: .rdata |
| 58 | 41 | Value: 0 |
| 59 | SectionNumber: 3 | |
| 42 | SectionNumber: 2 | |
| 60 | 43 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 61 | 44 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 62 | 45 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| ... | ... | @@ -68,7 +51,7 @@ symbols: |
| 68 | 51 | Number: 3 |
| 69 | 52 | - Name: _load_config_used |
| 70 | 53 | Value: 0 |
| 71 | SectionNumber: 3 | |
| 54 | SectionNumber: 2 | |
| 72 | 55 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 73 | 56 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 74 | 57 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL |
deps/lld/test/COFF/locally-imported-arm64.test created+61| ... | ... | @@ -0,0 +1,61 @@ |
| 1 | # RUN: yaml2obj < %s > %t.obj | |
| 2 | # RUN: lld-link /out:%t.exe /entry:main %t.obj | |
| 3 | # RUN: llvm-objdump -s %t.exe | FileCheck %s | |
| 4 | # RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s | |
| 5 | ||
| 6 | # CHECK: Contents of section .text: | |
| 7 | # CHECK-NEXT: 1000 00200000 | |
| 8 | # CHECK: Contents of section .rdata: | |
| 9 | # CHECK-NEXT: 2000 04100040 01000000 | |
| 10 | ||
| 11 | # BASEREL: BaseReloc [ | |
| 12 | # BASEREL-NEXT: Entry { | |
| 13 | # BASEREL-NEXT: Type: DIR64 | |
| 14 | # BASEREL-NEXT: Address: 0x2000 | |
| 15 | # BASEREL-NEXT: } | |
| 16 | # BASEREL-NEXT: Entry { | |
| 17 | # BASEREL-NEXT: Type: ABSOLUTE | |
| 18 | # BASEREL-NEXT: Address: 0x2000 | |
| 19 | # BASEREL-NEXT: } | |
| 20 | # BASEREL-NEXT: ] | |
| 21 | ||
| 22 | --- !COFF | |
| 23 | header: | |
| 24 | Machine: IMAGE_FILE_MACHINE_ARM64 | |
| 25 | Characteristics: [] | |
| 26 | sections: | |
| 27 | - Name: .text | |
| 28 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 29 | Alignment: 4 | |
| 30 | SectionData: 00000000 | |
| 31 | Relocations: | |
| 32 | - VirtualAddress: 0 | |
| 33 | SymbolName: __imp_main | |
| 34 | Type: IMAGE_REL_ARM64_ADDR32NB | |
| 35 | symbols: | |
| 36 | - Name: .text | |
| 37 | Value: 0 | |
| 38 | SectionNumber: 1 | |
| 39 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 40 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 41 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 42 | SectionDefinition: | |
| 43 | Length: 4 | |
| 44 | NumberOfRelocations: 1 | |
| 45 | NumberOfLinenumbers: 0 | |
| 46 | CheckSum: 0 | |
| 47 | Number: 0 | |
| 48 | Selection: IMAGE_COMDAT_SELECT_ANY | |
| 49 | - Name: main | |
| 50 | Value: 4 | |
| 51 | SectionNumber: 1 | |
| 52 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 53 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 54 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 55 | - Name: __imp_main | |
| 56 | Value: 0 | |
| 57 | SectionNumber: 0 | |
| 58 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 59 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 60 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 61 | ... |
deps/lld/test/COFF/locally-imported-warn-multiple.s created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %T/locally-imported-def.obj %S/Inputs/locally-imported-def.s | |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %T/locally-imported-imp1.obj %S/Inputs/locally-imported-imp.s | |
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %T/locally-imported-imp2.obj %S/Inputs/locally-imported-imp.s | |
| 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %t.obj %s | |
| 7 | # RUN: lld-link /entry:main %T/locally-imported-def.obj %T/locally-imported-imp1.obj %T/locally-imported-imp2.obj %t.obj 2>&1 | FileCheck %s | |
| 8 | ||
| 9 | # CHECK: warning: [[TESTDIR:.+]]locally-imported-imp1.obj: locally defined symbol imported: f (defined in [[TESTDIR]]locally-imported-def.obj) | |
| 10 | # CHECK-NEXT: warning: [[TESTDIR:.+]]locally-imported-imp2.obj: locally defined symbol imported: f (defined in [[TESTDIR]]locally-imported-def.obj) | |
| 11 | ||
| 12 | .globl main | |
| 13 | main: | |
| 14 | 	ret |
deps/lld/test/COFF/locally-imported.test+3-1| ... | ... | @@ -1,8 +1,10 @@ |
| 1 | 1 | # RUN: yaml2obj < %s > %t.obj |
| 2 | # RUN: lld-link /out:%t.exe /entry:main %t.obj | |
| 2 | # RUN: lld-link /out:%t.exe /entry:main %t.obj 2>&1 | FileCheck -check-prefix=WARN %s | |
| 3 | 3 | # RUN: llvm-objdump -s %t.exe | FileCheck %s |
| 4 | 4 | # RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s |
| 5 | 5 | |
| 6 | # WARN: warning: [[INPUT:.+]]: locally defined symbol imported: main (defined in [[INPUT]]) | |
| 7 | ||
| 6 | 8 | # CHECK: Contents of section .text: |
| 7 | 9 | # CHECK-NEXT: 1000 00200000 |
| 8 | 10 | # CHECK: Contents of section .rdata: |
deps/lld/test/COFF/long-section-name.test+21-2| ... | ... | @@ -1,7 +1,10 @@ |
| 1 | 1 | # RUN: yaml2obj < %s > %t.obj |
| 2 | # RUN: lld-link /debug /out:%t.exe /entry:main %t.obj | |
| 2 | # RUN: lld-link /out:%t.exe /entry:main %t.obj | |
| 3 | 3 | # RUN: llvm-readobj -sections %t.exe | FileCheck %s |
| 4 | # RUN: lld-link /debug /out:%t2.exe /entry:main %t.obj | |
| 5 | # RUN: llvm-readobj -sections %t2.exe | FileCheck %s | |
| 4 | 6 | |
| 7 | # CHECK: Name: .eh_fram ( | |
| 5 | 8 | # CHECK: Name: .data_long_section_name |
| 6 | 9 | # CHECK: Name: .text_long_section_name |
| 7 | 10 | |
| ... | ... | @@ -11,10 +14,14 @@ header: |
| 11 | 14 | Characteristics: [ ] |
| 12 | 15 | sections: |
| 13 | 16 | - Name: .text_long_section_name |
| 14 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 17 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_DISCARDABLE ] | |
| 15 | 18 | Alignment: 4 |
| 16 | 19 | SectionData: B82A000000C3 |
| 17 | 20 | - Name: .data_long_section_name |
| 21 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE, IMAGE_SCN_MEM_DISCARDABLE ] | |
| 22 | Alignment: 4 | |
| 23 | SectionData: "00" | |
| 24 | - Name: .eh_frame | |
| 18 | 25 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] |
| 19 | 26 | Alignment: 4 |
| 20 | 27 | SectionData: "00" |
| ... | ... | @@ -49,6 +56,18 @@ symbols: |
| 49 | 56 | NumberOfLinenumbers: 0 |
| 50 | 57 | CheckSum: 0 |
| 51 | 58 | Number: 0 |
| 59 | - Name: .eh_frame | |
| 60 | Value: 0 | |
| 61 | SectionNumber: 3 | |
| 62 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 63 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 64 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 65 | SectionDefinition: | |
| 66 | Length: 0 | |
| 67 | NumberOfRelocations: 0 | |
| 68 | NumberOfLinenumbers: 0 | |
| 69 | CheckSum: 0 | |
| 70 | Number: 0 | |
| 52 | 71 | - Name: main |
| 53 | 72 | Value: 0 |
| 54 | 73 | SectionNumber: 1 |
deps/lld/test/COFF/lto-cache.ll created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | ; REQUIRES: x86 | |
| 2 | ||
| 3 | ; RUN: opt -module-hash -module-summary %s -o %t.o | |
| 4 | ; RUN: opt -module-hash -module-summary %p/Inputs/lto-cache.ll -o %t2.o | |
| 5 | ||
| 6 | ; RUN: rm -Rf %t.cache && mkdir %t.cache | |
| 7 | ; Create two files that would be removed by cache pruning due to age. | |
| 8 | ; We should only remove files matching the pattern "llvmcache-*". | |
| 9 | ; RUN: touch -t 197001011200 %t.cache/llvmcache-foo %t.cache/foo | |
| 10 | ; RUN: lld-link /lldltocache:%t.cache /lldltocachepolicy:prune_after=1h /out:%t3 /entry:main %t2.o %t.o | |
| 11 | ||
| 12 | ; Two cached objects, plus a timestamp file and "foo", minus the file we removed. | |
| 13 | ; RUN: ls %t.cache | count 4 | |
| 14 | ||
| 15 | target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" | |
| 16 | target triple = "x86_64-pc-windows-msvc" | |
| 17 | ||
| 18 | define void @globalfunc() #0 { | |
| 19 | entry: | |
| 20 | ret void | |
| 21 | } |
deps/lld/test/COFF/lto-opt-level.ll+6-6| ... | ... | @@ -1,10 +1,10 @@ |
| 1 | 1 | ; RUN: llvm-as -o %t.obj %s |
| 2 | ; RUN: lld-link /out:%t0.exe /entry:main /subsystem:console /opt:lldlto=0 /debug %t.obj | |
| 3 | ; RUN: llvm-nm %t0.exe | FileCheck --check-prefix=CHECK-O0 %s | |
| 4 | ; RUN: lld-link /out:%t2.exe /entry:main /subsystem:console /opt:lldlto=2 /debug %t.obj | |
| 5 | ; RUN: llvm-nm %t2.exe | FileCheck --check-prefix=CHECK-O2 %s | |
| 6 | ; RUN: lld-link /out:%t2a.exe /entry:main /subsystem:console /debug %t.obj | |
| 7 | ; RUN: llvm-nm %t2a.exe | FileCheck --check-prefix=CHECK-O2 %s | |
| 2 | ; 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: lld-link /out:%t2.exe /entry:main /subsystem:console /opt:lldlto=2 /lldmap:%t2.map %t.obj | |
| 5 | ; RUN: FileCheck --check-prefix=CHECK-O2 %s < %t2.map | |
| 6 | ; RUN: lld-link /out:%t2a.exe /entry:main /subsystem:console /lldmap:%t2a.map %t.obj | |
| 7 | ; RUN: FileCheck --check-prefix=CHECK-O2 %s < %t2a.map | |
| 8 | 8 | |
| 9 | 9 | target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" |
| 10 | 10 | target triple = "x86_64-pc-windows-msvc" |
deps/lld/test/COFF/lto-reloc-model.ll created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | ; RUN: llvm-as -o %t %s | |
| 2 | ; RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t | |
| 3 | ; RUN: llvm-objdump -d %t.exe | FileCheck %s | |
| 4 | ||
| 5 | target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" | |
| 6 | target triple = "i686-pc-windows-msvc" | |
| 7 | ||
| 8 | @foo = thread_local global i8 0 | |
| 9 | ||
| 10 | module asm "__tls_index = 1" | |
| 11 | module asm "__tls_array = 2" | |
| 12 | ||
| 13 | define i8* @main() { | |
| 14 | ; CHECK: movl 1, %eax | |
| 15 | ; CHECK: movl %fs:2, %ecx | |
| 16 | ; CHECK: movl (%ecx,%eax,4), %eax | |
| 17 | ; CHECK: leal (%eax), %eax | |
| 18 | ret i8* @foo | |
| 19 | } |
deps/lld/test/COFF/lto.ll+15-1| ... | ... | @@ -82,7 +82,21 @@ |
| 82 | 82 | ; TEXT-10: Disassembly of section .text: |
| 83 | 83 | ; TEXT-10-NEXT: .text: |
| 84 | 84 | ; TEXT-10-NEXT: retq |
| 85 | ; TEXT-10-NEXT: nopw %cs:(%rax,%rax) | |
| 85 | ; TEXT-10-NEXT: nop | |
| 86 | ; TEXT-10-NEXT: nop | |
| 87 | ; TEXT-10-NEXT: nop | |
| 88 | ; TEXT-10-NEXT: nop | |
| 89 | ; TEXT-10-NEXT: nop | |
| 90 | ; TEXT-10-NEXT: nop | |
| 91 | ; TEXT-10-NEXT: nop | |
| 92 | ; TEXT-10-NEXT: nop | |
| 93 | ; TEXT-10-NEXT: nop | |
| 94 | ; TEXT-10-NEXT: nop | |
| 95 | ; TEXT-10-NEXT: nop | |
| 96 | ; TEXT-10-NEXT: nop | |
| 97 | ; TEXT-10-NEXT: nop | |
| 98 | ; TEXT-10-NEXT: nop | |
| 99 | ; TEXT-10-NEXT: nop | |
| 86 | 100 | ; TEXT-10-NEXT: retq |
| 87 | 101 | ; TEXT-10-NEXT: int3 |
| 88 | 102 | ; TEXT-10-NEXT: int3 |
deps/lld/test/COFF/manifest.test+15-1| ... | ... | @@ -57,10 +57,24 @@ DEPENDENCY: </dependentAssembly> |
| 57 | 57 | DEPENDENCY: </dependency> |
| 58 | 58 | DEPENDENCY: </assembly> |
| 59 | 59 | |
| 60 | # RUN: lld-link /manifest /out:%t.exe /entry:main /manifestuac:no %t.obj | |
| 60 | # RUN: lld-link /manifest /out:%t.exe /entry:main /manifestuac:no \ | |
| 61 | # RUN: /manifestdependency:"foo='bar'" %t.obj | |
| 61 | 62 | # RUN: FileCheck -check-prefix=NOUAC %s < %t.exe.manifest |
| 62 | 63 | |
| 63 | 64 | NOUAC: <?xml version="1.0" standalone="yes"?> |
| 64 | 65 | NOUAC: <assembly xmlns="urn:schemas-microsoft-com:asm.v1" |
| 65 | 66 | NOUAC: manifestVersion="1.0"> |
| 67 | NOUAC: <dependency> | |
| 68 | NOUAC: <dependentAssembly> | |
| 69 | NOUAC: <assemblyIdentity foo='bar' /> | |
| 70 | NOUAC: </dependentAssembly> | |
| 71 | NOUAC: </dependency> | |
| 66 | 72 | NOUAC: </assembly> |
| 73 | ||
| 74 | # RUN: lld-link /manifest /out:%t.exe /entry:main /manifestuac:no %t.obj | |
| 75 | # RUN: FileCheck -check-prefix=NOUACNODEP %s < %t.exe.manifest | |
| 76 | ||
| 77 | NOUACNODEP: <?xml version="1.0" standalone="yes"?> | |
| 78 | NOUACNODEP: <assembly xmlns="urn:schemas-microsoft-com:asm.v1" | |
| 79 | NOUACNODEP: manifestVersion="1.0"> | |
| 80 | NOUACNODEP: </assembly> |
deps/lld/test/COFF/manifestinput-error.test created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | # UNSUPPORTED: manifest_tool | |
| 2 | # UNSUPPORTED: libxml2 | |
| 3 | ||
| 4 | # RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj | |
| 5 | # RUN: not lld-link /out:%t.exe /entry:main \ | |
| 6 | # RUN: /manifest:embed \ | |
| 7 | # RUN: /manifestuac:"level='requireAdministrator'" \ | |
| 8 | # RUN: /manifestinput:%p/Inputs/manifestinput.test %t.obj 2>&1 | FileCheck %s | |
| 9 | ||
| 10 | # CHECK: error: unable to find mt.exe in PATH: No such file or directory |
deps/lld/test/COFF/manifestinput-nowarning.test created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | # UNSUPPORTED: libxml2 | |
| 2 | # REQUIRES: manifest_tool | |
| 3 | ||
| 4 | # RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj | |
| 5 | # RUN: lld-link /out:%t.exe /entry:main \ | |
| 6 | # RUN: /manifest:embed \ | |
| 7 | # RUN: /manifestuac:"level='requireAdministrator'" \ | |
| 8 | # RUN: /manifestinput:%p/Inputs/manifestinput.test %t.obj | \ | |
| 9 | # RUN:	 FileCheck -allow-empty %s | |
| 10 | ||
| 11 | # CHECK-NOT: warning: error with internal manifest tool: no libxml2 |
deps/lld/test/COFF/manifestinput.test+2-2| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | # REQUIRES: win_mt | |
| 1 | # REQUIRES: manifest_tool | |
| 2 | 2 | |
| 3 | 3 | # RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj |
| 4 | 4 | # RUN: lld-link /out:%t.exe /entry:main \ |
| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | TEST_EMBED: ResourceTableRVA: 0x1000 |
| 12 | 12 | TEST_EMBED-NEXT: ResourceTableSize: 0x298 |
| 13 | 13 | TEST_EMBED-DAG: Resources [ |
| 14 | TEST_EMBED-NEXT: Total Number of Resources: 1 | |
| 14 | TEST_EMBED-NEXT: Total Number of Resources: 1 | |
| 15 | 15 | TEST_EMBED-DAG: Number of String Entries: 0 |
| 16 | 16 | TEST_EMBED-NEXT: Number of ID Entries: 1 |
| 17 | 17 | TEST_EMBED-NEXT: Type: kRT_MANIFEST (ID 24) [ |
deps/lld/test/COFF/msvclto-archive.ll+3-3| ... | ... | @@ -9,14 +9,14 @@ |
| 9 | 9 | ; RUN: mkdir -p %t.dir |
| 10 | 10 | ; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t.dir/bitcode.obj %p/Inputs/msvclto.s |
| 11 | 11 | ; RUN: lld-link %t-main1.a %t.dir/bitcode.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \ |
| 12 | ; RUN: /entry:main /verbose > %t.log || true | |
| 12 | ; RUN: /entry:main /verbose 2> %t.log || true | |
| 13 | 13 | ; RUN: FileCheck -check-prefix=BC %s < %t.log |
| 14 | 14 | ; BC-NOT: Creating a temporary archive for |
| 15 | 15 | |
| 16 | 16 | ; RUN: rm -f %t-main2.a |
| 17 | 17 | ; RUN: llvm-ar cru %t-main2.a %t.dir/bitcode.obj |
| 18 | 18 | ; RUN: lld-link %t.obj %t-main2.a /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \ |
| 19 | ; RUN: /entry:main /verbose > %t.log || true | |
| 19 | ; RUN: /entry:main /verbose 2> %t.log || true | |
| 20 | 20 | ; RUN: FileCheck -check-prefix=OBJ %s < %t.log |
| 21 | 21 | ; OBJ-NOT: Creating a temporary archive |
| 22 | 22 | |
| ... | ... | @@ -25,7 +25,7 @@ |
| 25 | 25 | ; RUN: rm -f %t-main3.a |
| 26 | 26 | ; RUN: llvm-ar cruT %t-main3.a %t.dir/bitcode.obj |
| 27 | 27 | ; RUN: lld-link %t.obj %t-main3.a /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \ |
| 28 | ; RUN: /entry:main /verbose > %t.log || true | |
| 28 | ; RUN: /entry:main /verbose 2> %t.log || true | |
| 29 | 29 | ; RUN: FileCheck -check-prefix=THIN %s < %t.log |
| 30 | 30 | ; THIN: Creating a temporary archive |
| 31 | 31 |
deps/lld/test/COFF/msvclto-order.ll+1-1| ... | ... | @@ -5,7 +5,7 @@ |
| 5 | 5 | ; RUN: llc -filetype=obj %S/Inputs/msvclto-order-b.ll -o %T/msvclto-order-b.obj |
| 6 | 6 | ; RUN: llvm-ar crs %T/msvclto-order-b.lib %T/msvclto-order-b.obj |
| 7 | 7 | ; RUN: lld-link /verbose /msvclto /out:%t.exe /entry:main %t.obj \ |
| 8 | ; RUN: %T/msvclto-order-a.lib %T/msvclto-order-b.lib > %t.log || true | |
| 8 | ; RUN: %T/msvclto-order-a.lib %T/msvclto-order-b.lib 2> %t.log || true | |
| 9 | 9 | ; RUN: FileCheck %s < %t.log |
| 10 | 10 | |
| 11 | 11 | ; CHECK: : link.exe |
deps/lld/test/COFF/msvclto.ll+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | ; RUN: mkdir -p %t.dir |
| 4 | 4 | ; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t.dir/bitcode.obj %p/Inputs/msvclto.s |
| 5 | 5 | ; RUN: lld-link %t.obj %t.dir/bitcode.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \ |
| 6 | ; RUN: /entry:main /verbose > %t.log || true | |
| 6 | ; RUN: /entry:main /verbose 2> %t.log || true | |
| 7 | 7 | ; RUN: FileCheck %s < %t.log |
| 8 | 8 | |
| 9 | 9 | ; CHECK: /opt:icf /entry:main |
deps/lld/test/COFF/nodefaultlib.test+3-3| ... | ... | @@ -19,9 +19,9 @@ |
| 19 | 19 | # RUN: /nodefaultlib:std64.lib >& %t.log || true |
| 20 | 20 | # RUN: FileCheck -check-prefix=CHECK3 %s < %t.log |
| 21 | 21 | |
| 22 | CHECK1: hello64.obj: {{[Nn]}}o such file or directory | |
| 23 | CHECK2: hello64: {{[Nn]}}o such file or directory | |
| 24 | CHECK3: hello64.obj: undefined symbol: MessageBoxA | |
| 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 | |
| 24 | CHECK3: error: {{.*}}hello64.obj: undefined symbol: MessageBoxA | |
| 25 | 25 | |
| 26 | 26 | # RUN: lld-link /libpath:%T /out:%t.exe /entry:main \ |
| 27 | 27 | # RUN: /subsystem:console hello64.obj /defaultlib:std64.lib |
deps/lld/test/COFF/nopdb.test deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | # Check that /debug creates %t.pdb. | |
| 2 | # RUN: rm -f %t.pdb | |
| 3 | # RUN: lld-link /debug /entry:main /out:%t.exe %p/Inputs/ret42.obj | |
| 4 | # RUN: ls %t.pdb | |
| 5 | ||
| 6 | # Check that /debug /nopdb does not create %t.pdb. | |
| 7 | # RUN: rm -f %t.pdb | |
| 8 | # RUN: lld-link /debug /nopdb /entry:main /out:%t.exe %p/Inputs/ret42.obj | |
| 9 | # RUN: not ls %t.pdb | |
| 10 | ||
| 11 | # Check that /debug /nopdb /pdb:%t.pdb does not create %t.pdb. | |
| 12 | # RUN: rm -f %t.pdb | |
| 13 | # RUN: lld-link /debug /nopdb /pdb:%t.pdb /entry:main /out:%t.exe %p/Inputs/ret42.obj | |
| 14 | # RUN: not ls %t.pdb |
deps/lld/test/COFF/options.test+7-1| ... | ... | @@ -2,7 +2,13 @@ |
| 2 | 2 | |
| 3 | 3 | # RUN: lld-link /out:%t.exe /entry:main %t.obj |
| 4 | 4 | # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=BIND %s |
| 5 | BIND: IMAGE_DLL_CHARACTERISTICS_NO_BIND | |
| 5 | # RUN: lld-link /allowbind /out:%t.exe /entry:main %t.obj | |
| 6 | # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=BIND %s | |
| 7 | BIND-NOT: IMAGE_DLL_CHARACTERISTICS_NO_BIND | |
| 8 | ||
| 9 | # RUN: lld-link /allowbind:no /out:%t.exe /entry:main %t.obj | |
| 10 | # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOBIND %s | |
| 11 | NOBIND: IMAGE_DLL_CHARACTERISTICS_NO_BIND | |
| 6 | 12 | |
| 7 | 13 | # RUN: lld-link /out:%t.exe /entry:main %t.obj |
| 8 | 14 | # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ISO %s |
deps/lld/test/COFF/pdata-arm64.yaml created+87| ... | ... | @@ -0,0 +1,87 @@ |
| 1 | # RUN: yaml2obj < %s > %t.obj | |
| 2 | # | |
| 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 | |
| 5 | ||
| 6 | # PDATA: 00200000 2500a100 24200000 31002201 | |
| 7 | ||
| 8 | --- !COFF | |
| 9 | header: | |
| 10 | Machine: IMAGE_FILE_MACHINE_ARM64 | |
| 11 | Characteristics: [ ] | |
| 12 | sections: | |
| 13 | - Name: .text | |
| 14 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 15 | Alignment: 4 | |
| 16 | SectionData: ff4300d1f37b00a9f303012a00000094e003132a00000094f37b40a9ff430091c0035fd6f353bea9fe0b00f9f303012af403022a00000094e003132a00000094e003142a00000094fe0b40f9f353c2a8c0035fd6c0035fd6 | |
| 17 | Relocations: | |
| 18 | - VirtualAddress: 12 | |
| 19 | SymbolName: func3 | |
| 20 | Type: IMAGE_REL_ARM64_BRANCH26 | |
| 21 | - VirtualAddress: 20 | |
| 22 | SymbolName: func3 | |
| 23 | Type: IMAGE_REL_ARM64_BRANCH26 | |
| 24 | - VirtualAddress: 52 | |
| 25 | SymbolName: func3 | |
| 26 | Type: IMAGE_REL_ARM64_BRANCH26 | |
| 27 | - VirtualAddress: 60 | |
| 28 | SymbolName: func3 | |
| 29 | Type: IMAGE_REL_ARM64_BRANCH26 | |
| 30 | - VirtualAddress: 68 | |
| 31 | SymbolName: func3 | |
| 32 | Type: IMAGE_REL_ARM64_BRANCH26 | |
| 33 | - Name: .pdata | |
| 34 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | |
| 35 | Alignment: 4 | |
| 36 | SectionData: 0000000031002201000000002500a100 | |
| 37 | Relocations: | |
| 38 | - VirtualAddress: 0 | |
| 39 | SymbolName: func2 | |
| 40 | Type: IMAGE_REL_ARM64_ADDR32NB | |
| 41 | - VirtualAddress: 8 | |
| 42 | SymbolName: func1 | |
| 43 | Type: IMAGE_REL_ARM64_ADDR32NB | |
| 44 | symbols: | |
| 45 | - Name: .text | |
| 46 | Value: 0 | |
| 47 | SectionNumber: 1 | |
| 48 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 49 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 50 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 51 | SectionDefinition: | |
| 52 | Length: 57 | |
| 53 | NumberOfRelocations: 0 | |
| 54 | NumberOfLinenumbers: 0 | |
| 55 | CheckSum: 0 | |
| 56 | Number: 1 | |
| 57 | - Name: .pdata | |
| 58 | Value: 0 | |
| 59 | SectionNumber: 2 | |
| 60 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 61 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 62 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 63 | SectionDefinition: | |
| 64 | Length: 16 | |
| 65 | NumberOfRelocations: 2 | |
| 66 | NumberOfLinenumbers: 0 | |
| 67 | CheckSum: 0 | |
| 68 | Number: 2 | |
| 69 | - Name: func1 | |
| 70 | Value: 0 | |
| 71 | SectionNumber: 1 | |
| 72 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 73 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 74 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 75 | - Name: func2 | |
| 76 | Value: 36 | |
| 77 | SectionNumber: 1 | |
| 78 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 79 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 80 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 81 | - Name: func3 | |
| 82 | Value: 84 | |
| 83 | SectionNumber: 1 | |
| 84 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 85 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 86 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 87 | ... |
deps/lld/test/COFF/pdb-comdat.test+28-15| ... | ... | @@ -25,8 +25,8 @@ pdb_comdat_main.obj should be included in the PDB. |
| 25 | 25 | RUN: rm -rf %t && mkdir -p %t && cd %t |
| 26 | 26 | RUN: yaml2obj %S/Inputs/pdb_comdat_main.yaml -o pdb_comdat_main.obj |
| 27 | 27 | RUN: yaml2obj %S/Inputs/pdb_comdat_bar.yaml -o pdb_comdat_bar.obj |
| 28 | RUN: lld-link pdb_comdat_main.obj pdb_comdat_bar.obj -out:t.exe -debug -pdb:t.pdb -nodefaultlib -entry:main | |
| 29 | RUN: llvm-pdbutil dump -l -symbols t.pdb | FileCheck %s | |
| 28 | RUN: lld-link pdb_comdat_main.obj pdb_comdat_bar.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main | |
| 29 | RUN: llvm-pdbutil dump -l -symbols -globals %t.pdb | FileCheck %s | |
| 30 | 30 | |
| 31 | 31 | CHECK: Lines |
| 32 | 32 | CHECK: ============================================================ |
| ... | ... | @@ -38,6 +38,20 @@ CHECK: c:\src\llvm-project\build\pdb_comdat_bar.c (MD5: 365279DB4FCBEDD721 |
| 38 | 38 | CHECK-NOT: c:\src\llvm-project\build\foo.h |
| 39 | 39 | CHECK-LABEL: Mod 0002 | `* Linker *`: |
| 40 | 40 | |
| 41 | CHECK-LABEL: Global Symbols | |
| 42 | CHECK-NEXT: ============================================================ | |
| 43 | CHECK-NEXT: Records | |
| 44 | CHECK-NEXT: 84 | S_PROCREF [size = 20] `main` | |
| 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` | |
| 49 | CHECK-NEXT: module = 2, sum name = 0, offset = 120 | |
| 50 | CHECK-NEXT: 104 | S_GDATA32 [size = 24] `global` | |
| 51 | CHECK-NEXT: type = 0x0074 (int), addr = 0000:0000 | |
| 52 | CHECK-NEXT: 168 | S_GDATA32 [size = 24] `global` | |
| 53 | CHECK-NEXT: type = 0x0074 (int), addr = 0000:0000 | |
| 54 | ||
| 41 | 55 | CHECK: Symbols |
| 42 | 56 | CHECK: ============================================================ |
| 43 | 57 | CHECK-LABEL: Mod 0000 | `{{.*}}pdb_comdat_main.obj`: |
| ... | ... | @@ -46,7 +60,7 @@ CHECK: 60 | S_COMPILE3 [size = 60] |
| 46 | 60 | CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c |
| 47 | 61 | CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 |
| 48 | 62 | CHECK: flags = security checks | hot patchable |
| 49 | CHECK: 120 | S_GPROC32_ID [size = 44] `main` | |
| 63 | CHECK: 120 | S_GPROC32 [size = 44] `main` | |
| 50 | 64 | CHECK: parent = 0, end = 196, addr = 0002:0000, code size = 24 |
| 51 | 65 | CHECK: debug start = 4, debug end = 19, flags = none |
| 52 | 66 | CHECK: 164 | S_FRAMEPROC [size = 32] |
| ... | ... | @@ -54,24 +68,22 @@ CHECK: size = 40, padding size = 0, offset to padding = 0 |
| 54 | 68 | CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 |
| 55 | 69 | CHECK: flags = has async eh | opt speed |
| 56 | 70 | CHECK: 196 | S_END [size = 4] |
| 57 | CHECK: 200 | S_GDATA32 [size = 24] `global` | |
| 58 | CHECK: type = 0x0074 (int), addr = 0000:0000 | |
| 59 | CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `0x100A` | |
| 60 | CHECK: 232 | S_GPROC32_ID [size = 44] `foo` | |
| 61 | CHECK: parent = 0, end = 308, addr = 0002:0032, code size = 15 | |
| 71 | CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `0x100A` | |
| 72 | CHECK: 208 | S_GPROC32 [size = 44] `foo` | |
| 73 | CHECK: parent = 0, end = 284, addr = 0002:0032, code size = 15 | |
| 62 | 74 | CHECK: debug start = 0, debug end = 14, flags = none |
| 63 | CHECK: 276 | S_FRAMEPROC [size = 32] | |
| 75 | CHECK: 252 | S_FRAMEPROC [size = 32] | |
| 64 | 76 | CHECK: size = 0, padding size = 0, offset to padding = 0 |
| 65 | 77 | CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 |
| 66 | 78 | CHECK: flags = marked inline | has async eh | opt speed |
| 67 | CHECK: 308 | S_END [size = 4] | |
| 79 | CHECK: 284 | S_END [size = 4] | |
| 68 | 80 | CHECK-LABEL: Mod 0001 | `{{.*}}pdb_comdat_bar.obj`: |
| 69 | 81 | CHECK: 4 | S_OBJNAME [size = 56] sig=0, `C:\src\llvm-project\build\pdb_comdat_bar.obj` |
| 70 | 82 | CHECK: 60 | S_COMPILE3 [size = 60] |
| 71 | 83 | CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c |
| 72 | 84 | CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 |
| 73 | 85 | CHECK: flags = security checks | hot patchable |
| 74 | CHECK: 120 | S_GPROC32_ID [size = 44] `bar` | |
| 86 | CHECK: 120 | S_GPROC32 [size = 44] `bar` | |
| 75 | 87 | CHECK: parent = 0, end = 196, addr = 0002:0048, code size = 14 |
| 76 | 88 | CHECK: debug start = 4, debug end = 9, flags = none |
| 77 | 89 | CHECK: 164 | S_FRAMEPROC [size = 32] |
| ... | ... | @@ -79,10 +91,8 @@ CHECK: size = 40, padding size = 0, offset to padding = 0 |
| 79 | 91 | CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 |
| 80 | 92 | CHECK: flags = has async eh | opt speed |
| 81 | 93 | CHECK: 196 | S_END [size = 4] |
| 82 | CHECK: 200 | S_GDATA32 [size = 24] `global` | |
| 83 | CHECK: type = 0x0074 (int), addr = 0000:0000 | |
| 84 | CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `0x100D` | |
| 85 | CHECK-NOT: S_GPROC32_ID {{.*}} `foo` | |
| 94 | CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `0x100D` | |
| 95 | CHECK-NOT: S_GPROC32 {{.*}} `foo` | |
| 86 | 96 | CHECK-LABEL: Mod 0002 | `* Linker *`: |
| 87 | 97 | |
| 88 | 98 | Reorder the object files and verify that the other table is selected. |
| ... | ... | @@ -97,3 +107,6 @@ REORDER-LABEL: Mod 0001 | `{{.*}}pdb_comdat_main.obj`: |
| 97 | 107 | REORDER: c:\src\llvm-project\build\pdb_comdat_main.c |
| 98 | 108 | REORDER-NOT: c:\src\llvm-project\build\foo.h |
| 99 | 109 | REORDER-LABEL: Mod 0002 | `* Linker *`: |
| 110 | ||
| 111 | Make sure that we don't crash on non-prevailing debug sections if -debug is not enabled. | |
| 112 | RUN: lld-link pdb_comdat_main.obj pdb_comdat_bar.obj -out:%t.exe -nodefaultlib -entry:main |
deps/lld/test/COFF/pdb-diff.test+10-7| ... | ... | @@ -4,8 +4,11 @@ as the "baseline" for us to measure against. Then we link the same object |
| 4 | 4 | file with LLD and compare the two PDBs. Since the baseline object file and |
| 5 | 5 | PDB are already checked in, we just run LLD on the object file. |
| 6 | 6 | |
| 7 | RUN: lld-link /debug /pdb:%T/pdb-diff-lld.pdb /nodefaultlib /entry:main %S/Inputs/pdb-diff.obj | |
| 8 | RUN: llvm-pdbutil diff -result -values=false -left-bin-root=%S -right-bin-root=D:/src/llvm-mono/lld/test/COFF/ %T/pdb-diff-lld.pdb %S/Inputs/pdb-diff-cl.pdb | FileCheck %s | |
| 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 | |
| 9 | 12 | |
| 10 | 13 | CHECK: ---------------------- |
| 11 | 14 | CHECK-NEXT: | MSF Super Block | |
| ... | ... | @@ -25,7 +28,7 @@ CHECK-NEXT: | Stream Directory | |
| 25 | 28 | CHECK-NEXT: |------------------------------+---| |
| 26 | 29 | CHECK-NEXT: | File | | |
| 27 | 30 | CHECK-NEXT: |------------------------------+---| |
| 28 | CHECK-NEXT: | Stream Count | D | | |
| 31 | CHECK-NEXT: | Stream Count | I | | |
| 29 | 32 | CHECK-NEXT: |------------------------------+---| |
| 30 | 33 | CHECK-NEXT: | Old MSF Directory | I | |
| 31 | 34 | CHECK-NEXT: |------------------------------+---| |
| ... | ... | @@ -55,9 +58,9 @@ CHECK-NEXT: | IPI Hash | {{[EI]}} | |
| 55 | 58 | CHECK-NEXT: |------------------------------+---| |
| 56 | 59 | CHECK-NEXT: | Public Symbol Hash | {{[EI]}} | |
| 57 | 60 | CHECK-NEXT: |------------------------------+---| |
| 58 | CHECK-NEXT: | Public Symbol Records | {{[EI]}} | | |
| 61 | CHECK-NEXT: | Global Symbol Hash | {{[EI]}} | | |
| 59 | 62 | CHECK-NEXT: |------------------------------+---| |
| 60 | CHECK-NEXT: | Global Symbol Hash | D | | |
| 63 | CHECK-NEXT: | Symbol Records | {{[EI]}} | | |
| 61 | 64 | CHECK-NEXT: |------------------------------+---| |
| 62 | 65 | CHECK-NEXT: ------------------------------------ |
| 63 | 66 | CHECK-NEXT: | String Table | |
| ... | ... | @@ -152,7 +155,7 @@ CHECK-NEXT: | DBG (NewFPO) | {{[EI]}} | |
| 152 | 155 | CHECK-NEXT: |----------------------------------------+---| |
| 153 | 156 | CHECK-NEXT: | DBG (SectionHdrOrig) | I | |
| 154 | 157 | CHECK-NEXT: |----------------------------------------+---| |
| 155 | CHECK-NEXT: | Globals Stream | D | | |
| 158 | CHECK-NEXT: | Globals Stream | {{[EI]}} | | |
| 156 | 159 | CHECK-NEXT: |----------------------------------------+---| |
| 157 | 160 | CHECK-NEXT: | Publics Stream | {{[EI]}} | |
| 158 | 161 | CHECK-NEXT: |----------------------------------------+---| |
| ... | ... | @@ -186,7 +189,7 @@ CHECK-NEXT: | - Pdb File Path Index | I | |
| 186 | 189 | CHECK-NEXT: |----------------------------------------+---| |
| 187 | 190 | CHECK-NEXT: | - Source File Name Index | I | |
| 188 | 191 | CHECK-NEXT: |----------------------------------------+---| |
| 189 | CHECK-NEXT: | - Symbol Byte Size | D | | |
| 192 | CHECK-NEXT: | - Symbol Byte Size | | |
| 190 | 193 | CHECK-NEXT: |----------------------------------------+---| |
| 191 | 194 | CHECK-NEXT: | Module "* Linker *" | |
| 192 | 195 | CHECK-NEXT: |----------------------------------------+---| |
deps/lld/test/COFF/pdb-global-gc.yaml+13-9| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | 1 | # RUN: yaml2obj %s -o %t.obj |
| 2 | 2 | # RUN: llvm-mc %S/Inputs/pdb-global-gc.s -triple x86_64-windows-msvc -filetype=obj -o %t2.obj |
| 3 | 3 | # RUN: lld-link %t.obj %t2.obj -debug -entry:main \ |
| 4 | # RUN: -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb -verbose | |
| 5 | # RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s | |
| 4 | # RUN: -nodefaultlib -opt:ref -out:%t.exe -pdb:%t.pdb -verbose | |
| 5 | # RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s | |
| 6 | 6 | |
| 7 | 7 | # This tests the case where an __imp_ chunk is discarded by linker GC. The debug |
| 8 | 8 | # info may refer to the __imp_ symbol still. |
| ... | ... | @@ -12,13 +12,17 @@ |
| 12 | 12 | # int discarded() { return __wc_mb_cur; } |
| 13 | 13 | # int main() { return g2; } |
| 14 | 14 | |
| 15 | # CHECK: Symbols | |
| 16 | # CHECK: ============================================================ | |
| 17 | # CHECK: Mod 0000 | `{{.*}}pdb-global-gc.yaml.tmp.obj`: | |
| 18 | # CHECK: 4 | S_GDATA32 [size = 28] `__wc_mb_cur` | |
| 19 | # CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000 | |
| 20 | # CHECK: Mod 0001 | `{{.*}}pdb-global-gc.yaml.tmp2.obj`: | |
| 21 | # CHECK: Mod 0002 | `* Linker *`: | |
| 15 | # CHECK: Global Symbols | |
| 16 | # CHECK-NEXT: ============================================================ | |
| 17 | # CHECK-NEXT: Records | |
| 18 | # CHECK-NEXT: 20 | S_GDATA32 [size = 28] `__wc_mb_cur` | |
| 19 | # CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000 | |
| 20 | ||
| 21 | # CHECK: Symbols | |
| 22 | # CHECK: ============================================================ | |
| 23 | # CHECK-NEXT: Mod 0000 | `{{.*}}pdb-global-gc.yaml.tmp.obj`: | |
| 24 | # CHECK-NEXT: Mod 0001 | `{{.*}}pdb-global-gc.yaml.tmp2.obj`: | |
| 25 | # CHECK-NEXT: Mod 0002 | `* Linker *`: | |
| 22 | 26 | |
| 23 | 27 | --- !COFF |
| 24 | 28 | header: |
deps/lld/test/COFF/pdb-global-hashes.test created+93| ... | ... | @@ -0,0 +1,93 @@ |
| 1 | RUN: yaml2obj %p/Inputs/pdb-hashes-1.yaml > %t.1.obj | |
| 2 | RUN: yaml2obj %p/Inputs/pdb-hashes-2.yaml > %t.2.obj | |
| 3 | RUN: yaml2obj %p/Inputs/pdb-hashes-2-missing.yaml > %t.2.missing.obj | |
| 4 | RUN: lld-link /debug %t.1.obj %t.2.obj /entry:main /nodefaultlib /PDB:%t.nohash.pdb | |
| 5 | RUN: lld-link /debug:ghash %t.1.obj %t.2.obj /entry:main /nodefaultlib /PDB:%t.hash.pdb | |
| 6 | RUN: lld-link /debug:ghash %t.1.obj %t.2.missing.obj /entry:main /nodefaultlib /PDB:%t.mixed.pdb | |
| 7 | RUN: llvm-pdbutil dump -types -ids %t.nohash.pdb | FileCheck %s | |
| 8 | RUN: llvm-pdbutil dump -types -ids %t.hash.pdb | FileCheck %s | |
| 9 | RUN: llvm-pdbutil dump -types -ids %t.mixed.pdb | FileCheck %s | |
| 10 | ||
| 11 | ; These object files were generated via the following inputs and commands: | |
| 12 | ; ---------------------------------------------- | |
| 13 | ; // obj.h | |
| 14 | ; namespace NS { | |
| 15 | ; struct Foo { | |
| 16 | ; explicit Foo(int x) : X(x) {} | |
| 17 | ; int X; | |
| 18 | ; }; | |
| 19 | ; | |
| 20 | ; int func(const Foo &f); | |
| 21 | ; } | |
| 22 | ; ---------------------------------------------- | |
| 23 | ; // obj1.cpp | |
| 24 | ; #include "obj.h" | |
| 25 | ; | |
| 26 | ; int main(int argc, char **argv) { | |
| 27 | ; NS::Foo f(argc); | |
| 28 | ; return NS::func(f); | |
| 29 | ; } | |
| 30 | ; ---------------------------------------------- | |
| 31 | ; // obj2.cpp | |
| 32 | ; #include "obj.h" | |
| 33 | ; | |
| 34 | ; int NS::func(const Foo &f) { | |
| 35 | ; return 2 * f.X; | |
| 36 | ; } | |
| 37 | ; ---------------------------------------------- | |
| 38 | ; $ clang-cl /Z7 /GS- obj1.cpp /c /o obj1.obj | |
| 39 | ; $ clang-cl /Z7 /GS- obj2.cpp /c /o obj2.obj | |
| 40 | ||
| 41 | CHECK: Types (TPI Stream) | |
| 42 | CHECK-NEXT: ============================================================ | |
| 43 | CHECK-NEXT: Showing 13 records | |
| 44 | CHECK-NEXT: 0x1000 | LF_POINTER [size = 12] | |
| 45 | CHECK-NEXT: referent = 0x0470 (char*), mode = pointer, opts = None, kind = ptr32 | |
| 46 | CHECK-NEXT: 0x1001 | LF_ARGLIST [size = 16] | |
| 47 | CHECK-NEXT: 0x0074 (int): `int` | |
| 48 | CHECK-NEXT: 0x1000: `char**` | |
| 49 | CHECK-NEXT: 0x1002 | LF_PROCEDURE [size = 16] | |
| 50 | CHECK-NEXT: return type = 0x0074 (int), # args = 2, param list = 0x1001 | |
| 51 | CHECK-NEXT: calling conv = cdecl, options = None | |
| 52 | CHECK-NEXT: 0x1003 | LF_STRUCTURE [size = 44] `NS::Foo` | |
| 53 | CHECK-NEXT: unique name: `.?AUFoo@NS@@` | |
| 54 | CHECK-NEXT: vtable: <no type>, base list: <no type>, field list: <no type> | |
| 55 | CHECK-NEXT: options: forward ref | has unique name | |
| 56 | CHECK-NEXT: 0x1004 | LF_POINTER [size = 12] | |
| 57 | CHECK-NEXT: referent = 0x1003, mode = pointer, opts = None, kind = ptr32 | |
| 58 | CHECK-NEXT: 0x1005 | LF_ARGLIST [size = 12] | |
| 59 | CHECK-NEXT: 0x0074 (int): `int` | |
| 60 | CHECK-NEXT: 0x1006 | LF_MFUNCTION [size = 28] | |
| 61 | CHECK-NEXT: return type = 0x0003 (void), # args = 1, param list = 0x1005 | |
| 62 | CHECK-NEXT: class type = 0x1003, this type = 0x1004, this adjust = 0 | |
| 63 | CHECK-NEXT: calling conv = thiscall, options = None | |
| 64 | CHECK-NEXT: 0x1007 | LF_FIELDLIST [size = 28] | |
| 65 | CHECK-NEXT: - LF_MEMBER [name = `X`, Type = 0x0074 (int), offset = 0, attrs = public] | |
| 66 | CHECK-NEXT: - LF_ONEMETHOD [name = `Foo`] | |
| 67 | CHECK-NEXT: type = 0x1006, vftable offset = -1, attrs = public | |
| 68 | CHECK-NEXT: 0x1008 | LF_STRUCTURE [size = 44] `NS::Foo` | |
| 69 | CHECK-NEXT: unique name: `.?AUFoo@NS@@` | |
| 70 | CHECK-NEXT: vtable: <no type>, base list: <no type>, field list: 0x1007 | |
| 71 | CHECK-NEXT: options: has unique name | |
| 72 | CHECK-NEXT: 0x1009 | LF_MODIFIER [size = 12] | |
| 73 | CHECK-NEXT: referent = 0x1003, modifiers = const | |
| 74 | CHECK-NEXT: 0x100A | LF_POINTER [size = 12] | |
| 75 | CHECK-NEXT: referent = 0x1009, mode = ref, opts = None, kind = ptr32 | |
| 76 | CHECK-NEXT: 0x100B | LF_ARGLIST [size = 12] | |
| 77 | CHECK-NEXT: 0x100A: `const NS::Foo&` | |
| 78 | CHECK-NEXT: 0x100C | LF_PROCEDURE [size = 16] | |
| 79 | CHECK-NEXT: return type = 0x0074 (int), # args = 1, param list = 0x100B | |
| 80 | CHECK-NEXT: calling conv = cdecl, options = None | |
| 81 | CHECK: Types (IPI Stream) | |
| 82 | CHECK-NEXT: ============================================================ | |
| 83 | CHECK-NEXT: Showing 6 records | |
| 84 | CHECK-NEXT: 0x1000 | LF_FUNC_ID [size = 20] | |
| 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 | |
| 87 | CHECK-NEXT: 0x1002 | LF_UDT_SRC_LINE [size = 16] | |
| 88 | CHECK-NEXT: udt = 0x1008, file = 4097, line = 2 | |
| 89 | CHECK-NEXT: 0x1003 | LF_MFUNC_ID [size = 16] | |
| 90 | CHECK-NEXT: name = Foo, type = 0x1006, class type = 0x1003 | |
| 91 | CHECK-NEXT: 0x1004 | LF_STRING_ID [size = 12] ID: <no type>, String: NS | |
| 92 | CHECK-NEXT: 0x1005 | LF_FUNC_ID [size = 20] | |
| 93 | CHECK-NEXT: name = func, type = 0x100C, parent scope = 0x1004 |
deps/lld/test/COFF/pdb-globals.test created+42| ... | ... | @@ -0,0 +1,42 @@ |
| 1 | RUN: yaml2obj %S/Inputs/pdb-globals.yaml > %t.obj | |
| 2 | RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe /pdb:%t.pdb %t.obj | |
| 3 | RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s | |
| 4 | ||
| 5 | # Test that we correctly distribute symbols between the globals and module | |
| 6 | # symbol streams. Specifically: | |
| 7 | # * S_UDT, S_GDATA32, and S_CONSTANT end up in the globals stream, and are | |
| 8 | # omitted from the module stream. | |
| 9 | # * S_GPROC32 and S_LPROC32 end up in the symbols stream, but S_PROCREF and | |
| 10 | # S_LPROCREF are added to the globals stream that refer to the module | |
| 11 | # stream. | |
| 12 | # * S_LDATA32 is copied byte for byte into both streams. | |
| 13 | ||
| 14 | ||
| 15 | CHECK-LABEL: Global Symbols | |
| 16 | CHECK-NEXT: ============================================================ | |
| 17 | CHECK-NEXT: Records | |
| 18 | CHECK-NEXT: 160 | S_PROCREF [size = 28] `GlobalFunc` | |
| 19 | CHECK-NEXT: module = 1, sum name = 0, offset = 52 | |
| 20 | CHECK-NEXT: 188 | S_PROCREF [size = 20] `main` | |
| 21 | 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` | |
| 27 | CHECK-NEXT: type = 0x0403 (void*), addr = 0000:0000 | |
| 28 | CHECK-NEXT: 260 | S_GDATA32 [size = 24] `GlobalVar` | |
| 29 | CHECK-NEXT: type = 0x100B (const int*), addr = 0001:0000 | |
| 30 | CHECK-NEXT: 284 | S_LDATA32 [size = 28] `ConstantVar` | |
| 31 | CHECK-NEXT: type = 0x100A (const int), addr = 0002:0000 | |
| 32 | ||
| 33 | CHECK-LABEL: Symbols | |
| 34 | CHECK-NEXT: ============================================================ | |
| 35 | CHECK-NEXT: Mod 0000 | |
| 36 | CHECK-NOT: | S_GDATA32 | |
| 37 | CHECK-NOT: | S_UDT | |
| 38 | CHECK: 52 | S_GPROC32 [size = 52] `GlobalFunc` | |
| 39 | CHECK: 108 | S_GPROC32 [size = 44] `main` | |
| 40 | CHECK: 292 | S_LPROC32 [size = 52] `LocalFunc` | |
| 41 | CHECK: 348 | S_LDATA32 [size = 28] `ConstantVar` | |
| 42 | CHECK: 376 | S_GPROC32 [size = 64] `HelloPoint::HelloPoint` |
deps/lld/test/COFF/pdb-heapsite.yaml created+1561| ... | ... | @@ -0,0 +1,1561 @@ |
| 1 | # RUN: yaml2obj %s -o %t.obj | |
| 2 | # RUN: lld-link %t.obj -dll -debug -noentry -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb | |
| 3 | # RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s | |
| 4 | ||
| 5 | # This object generated from this C++ source: | |
| 6 | # // t.cpp | |
| 7 | # void *operator new(size_t) { return nullptr; } | |
| 8 | # struct Foo { int x; }; | |
| 9 | # extern "C" __declspec(dllexport) Foo *f() { return new Foo; } | |
| 10 | ||
| 11 | # Compile as: | |
| 12 | # $ cl -c -Z7 t.cpp | |
| 13 | ||
| 14 | # CHECK: S_HEAPALLOCSITE [size = 16] | |
| 15 | # CHECK-NEXT: type = 0x1000 (Foo), addr = {{.*}} call size = 5 | |
| 16 | ||
| 17 | --- !COFF | |
| 18 | header: | |
| 19 | Machine: IMAGE_FILE_MACHINE_AMD64 | |
| 20 | Characteristics: [ ] | |
| 21 | sections: | |
| 22 | - Name: .drectve | |
| 23 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | |
| 24 | Alignment: 1 | |
| 25 | SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D455322202F4558504F52543A6620 | |
| 26 | - Name: '.debug$S' | |
| 27 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 28 | Alignment: 1 | |
| 29 | Subsections: | |
| 30 | - !Symbols | |
| 31 | Records: | |
| 32 | - Kind: S_OBJNAME | |
| 33 | ObjNameSym: | |
| 34 | Signature: 0 | |
| 35 | ObjectName: 'C:\src\llvm-project\build\t.obj' | |
| 36 | - Kind: S_COMPILE3 | |
| 37 | Compile3Sym: | |
| 38 | Flags: [ SecurityChecks, HotPatch ] | |
| 39 | Machine: X64 | |
| 40 | FrontendMajor: 19 | |
| 41 | FrontendMinor: 11 | |
| 42 | FrontendBuild: 25508 | |
| 43 | FrontendQFE: 2 | |
| 44 | BackendMajor: 19 | |
| 45 | BackendMinor: 11 | |
| 46 | BackendBuild: 25508 | |
| 47 | BackendQFE: 2 | |
| 48 | Version: 'Microsoft (R) Optimizing Compiler' | |
| 49 | - !Symbols | |
| 50 | Records: | |
| 51 | - Kind: S_GPROC32_ID | |
| 52 | ProcSym: | |
| 53 | CodeSize: 8 | |
| 54 | DbgStart: 5 | |
| 55 | DbgEnd: 7 | |
| 56 | FunctionType: 4104 | |
| 57 | Flags: [ ] | |
| 58 | DisplayName: operator new | |
| 59 | - Kind: S_FRAMEPROC | |
| 60 | FrameProcSym: | |
| 61 | TotalFrameBytes: 0 | |
| 62 | PaddingFrameBytes: 0 | |
| 63 | OffsetToPadding: 0 | |
| 64 | BytesOfCalleeSavedRegisters: 0 | |
| 65 | OffsetOfExceptionHandler: 0 | |
| 66 | SectionIdOfExceptionHandler: 0 | |
| 67 | Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] | |
| 68 | - Kind: S_REGREL32 | |
| 69 | RegRelativeSym: | |
| 70 | Offset: 8 | |
| 71 | Type: 35 | |
| 72 | Register: RSP | |
| 73 | VarName: __formal | |
| 74 | - Kind: S_PROC_ID_END | |
| 75 | ScopeEndSym: | |
| 76 | - !Lines | |
| 77 | CodeSize: 8 | |
| 78 | Flags: [ ] | |
| 79 | RelocOffset: 0 | |
| 80 | RelocSegment: 0 | |
| 81 | Blocks: | |
| 82 | - FileName: 'c:\src\llvm-project\build\t.cpp' | |
| 83 | Lines: | |
| 84 | - Offset: 0 | |
| 85 | LineStart: 1 | |
| 86 | IsStatement: true | |
| 87 | EndDelta: 0 | |
| 88 | Columns: | |
| 89 | - !Symbols | |
| 90 | Records: | |
| 91 | - Kind: S_GPROC32_ID | |
| 92 | ProcSym: | |
| 93 | CodeSize: 29 | |
| 94 | DbgStart: 4 | |
| 95 | DbgEnd: 24 | |
| 96 | FunctionType: 4107 | |
| 97 | Flags: [ ] | |
| 98 | DisplayName: f | |
| 99 | - Kind: S_FRAMEPROC | |
| 100 | FrameProcSym: | |
| 101 | TotalFrameBytes: 56 | |
| 102 | PaddingFrameBytes: 0 | |
| 103 | OffsetToPadding: 0 | |
| 104 | BytesOfCalleeSavedRegisters: 0 | |
| 105 | OffsetOfExceptionHandler: 0 | |
| 106 | SectionIdOfExceptionHandler: 0 | |
| 107 | Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] | |
| 108 | - Kind: S_HEAPALLOCSITE | |
| 109 | HeapAllocationSiteSym: | |
| 110 | Offset: 9 | |
| 111 | CallInstructionSize: 5 | |
| 112 | Type: 4096 | |
| 113 | - Kind: S_PROC_ID_END | |
| 114 | ScopeEndSym: | |
| 115 | - !Lines | |
| 116 | CodeSize: 29 | |
| 117 | Flags: [ ] | |
| 118 | RelocOffset: 0 | |
| 119 | RelocSegment: 0 | |
| 120 | Blocks: | |
| 121 | - FileName: 'c:\src\llvm-project\build\t.cpp' | |
| 122 | Lines: | |
| 123 | - Offset: 0 | |
| 124 | LineStart: 3 | |
| 125 | IsStatement: true | |
| 126 | EndDelta: 0 | |
| 127 | Columns: | |
| 128 | - !Symbols | |
| 129 | Records: | |
| 130 | - Kind: S_UDT | |
| 131 | UDTSym: | |
| 132 | Type: 4098 | |
| 133 | UDTName: Foo | |
| 134 | - Kind: S_UDT | |
| 135 | UDTSym: | |
| 136 | Type: 4196 | |
| 137 | UDTName: '__vc_attributes::event_sourceAttribute' | |
| 138 | - Kind: S_UDT | |
| 139 | UDTSym: | |
| 140 | Type: 4188 | |
| 141 | UDTName: '__vc_attributes::event_sourceAttribute::optimize_e' | |
| 142 | - Kind: S_UDT | |
| 143 | UDTSym: | |
| 144 | Type: 4185 | |
| 145 | UDTName: '__vc_attributes::event_sourceAttribute::type_e' | |
| 146 | - Kind: S_UDT | |
| 147 | UDTSym: | |
| 148 | Type: 4181 | |
| 149 | UDTName: '__vc_attributes::helper_attributes::v1_alttypeAttribute' | |
| 150 | - Kind: S_UDT | |
| 151 | UDTSym: | |
| 152 | Type: 4175 | |
| 153 | UDTName: '__vc_attributes::helper_attributes::v1_alttypeAttribute::type_e' | |
| 154 | - Kind: S_UDT | |
| 155 | UDTSym: | |
| 156 | Type: 4171 | |
| 157 | UDTName: '__vc_attributes::helper_attributes::usageAttribute' | |
| 158 | - Kind: S_UDT | |
| 159 | UDTSym: | |
| 160 | Type: 4165 | |
| 161 | UDTName: '__vc_attributes::helper_attributes::usageAttribute::usage_e' | |
| 162 | - Kind: S_UDT | |
| 163 | UDTSym: | |
| 164 | Type: 4161 | |
| 165 | UDTName: '__vc_attributes::threadingAttribute' | |
| 166 | - Kind: S_UDT | |
| 167 | UDTSym: | |
| 168 | Type: 4153 | |
| 169 | UDTName: '__vc_attributes::threadingAttribute::threading_e' | |
| 170 | - Kind: S_UDT | |
| 171 | UDTSym: | |
| 172 | Type: 4149 | |
| 173 | UDTName: '__vc_attributes::aggregatableAttribute' | |
| 174 | - Kind: S_UDT | |
| 175 | UDTSym: | |
| 176 | Type: 4141 | |
| 177 | UDTName: '__vc_attributes::aggregatableAttribute::type_e' | |
| 178 | - Kind: S_UDT | |
| 179 | UDTSym: | |
| 180 | Type: 4137 | |
| 181 | UDTName: '__vc_attributes::event_receiverAttribute' | |
| 182 | - Kind: S_UDT | |
| 183 | UDTSym: | |
| 184 | Type: 4127 | |
| 185 | UDTName: '__vc_attributes::event_receiverAttribute::type_e' | |
| 186 | - Kind: S_UDT | |
| 187 | UDTSym: | |
| 188 | Type: 4123 | |
| 189 | UDTName: '__vc_attributes::moduleAttribute' | |
| 190 | - Kind: S_UDT | |
| 191 | UDTSym: | |
| 192 | Type: 4110 | |
| 193 | UDTName: '__vc_attributes::moduleAttribute::type_e' | |
| 194 | - Kind: S_UDT | |
| 195 | UDTSym: | |
| 196 | Type: 35 | |
| 197 | UDTName: size_t | |
| 198 | - !FileChecksums | |
| 199 | Checksums: | |
| 200 | - FileName: 'c:\src\llvm-project\build\t.cpp' | |
| 201 | Kind: MD5 | |
| 202 | Checksum: 3C4D132707FA572FA0869E4E4DAA7F85 | |
| 203 | - !StringTable | |
| 204 | Strings: | |
| 205 | - 'c:\src\llvm-project\build\t.cpp' | |
| 206 | - !Symbols | |
| 207 | Records: | |
| 208 | - Kind: S_BUILDINFO | |
| 209 | BuildInfoSym: | |
| 210 | BuildId: 4205 | |
| 211 | Relocations: | |
| 212 | - VirtualAddress: 152 | |
| 213 | SymbolName: '??2@YAPEAX_K@Z' | |
| 214 | Type: IMAGE_REL_AMD64_SECREL | |
| 215 | - VirtualAddress: 156 | |
| 216 | SymbolName: '??2@YAPEAX_K@Z' | |
| 217 | Type: IMAGE_REL_AMD64_SECTION | |
| 218 | - VirtualAddress: 240 | |
| 219 | SymbolName: '??2@YAPEAX_K@Z' | |
| 220 | Type: IMAGE_REL_AMD64_SECREL | |
| 221 | - VirtualAddress: 244 | |
| 222 | SymbolName: '??2@YAPEAX_K@Z' | |
| 223 | Type: IMAGE_REL_AMD64_SECTION | |
| 224 | - VirtualAddress: 312 | |
| 225 | SymbolName: f | |
| 226 | Type: IMAGE_REL_AMD64_SECREL | |
| 227 | - VirtualAddress: 316 | |
| 228 | SymbolName: f | |
| 229 | Type: IMAGE_REL_AMD64_SECTION | |
| 230 | - VirtualAddress: 355 | |
| 231 | SymbolName: f | |
| 232 | Type: IMAGE_REL_AMD64_SECREL | |
| 233 | - VirtualAddress: 359 | |
| 234 | SymbolName: f | |
| 235 | Type: IMAGE_REL_AMD64_SECTION | |
| 236 | - VirtualAddress: 380 | |
| 237 | SymbolName: f | |
| 238 | Type: IMAGE_REL_AMD64_SECREL | |
| 239 | - VirtualAddress: 384 | |
| 240 | SymbolName: f | |
| 241 | Type: IMAGE_REL_AMD64_SECTION | |
| 242 | - Name: '.debug$T' | |
| 243 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 244 | Alignment: 1 | |
| 245 | Types: | |
| 246 | - Kind: LF_STRUCTURE | |
| 247 | Class: | |
| 248 | MemberCount: 0 | |
| 249 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 250 | FieldList: 0 | |
| 251 | Name: Foo | |
| 252 | UniqueName: '.?AUFoo@@' | |
| 253 | DerivationList: 0 | |
| 254 | VTableShape: 0 | |
| 255 | Size: 0 | |
| 256 | - Kind: LF_FIELDLIST | |
| 257 | FieldList: | |
| 258 | - Kind: LF_MEMBER | |
| 259 | DataMember: | |
| 260 | Attrs: 3 | |
| 261 | Type: 116 | |
| 262 | FieldOffset: 0 | |
| 263 | Name: x | |
| 264 | - Kind: LF_STRUCTURE | |
| 265 | Class: | |
| 266 | MemberCount: 1 | |
| 267 | Options: [ None, HasUniqueName ] | |
| 268 | FieldList: 4097 | |
| 269 | Name: Foo | |
| 270 | UniqueName: '.?AUFoo@@' | |
| 271 | DerivationList: 0 | |
| 272 | VTableShape: 0 | |
| 273 | Size: 4 | |
| 274 | - Kind: LF_STRING_ID | |
| 275 | StringId: | |
| 276 | Id: 0 | |
| 277 | String: 'c:\src\llvm-project\build\t.cpp' | |
| 278 | - Kind: LF_UDT_SRC_LINE | |
| 279 | UdtSourceLine: | |
| 280 | UDT: 4098 | |
| 281 | SourceFile: 4099 | |
| 282 | LineNumber: 2 | |
| 283 | - Kind: LF_POINTER | |
| 284 | Pointer: | |
| 285 | ReferentType: 4096 | |
| 286 | Attrs: 65548 | |
| 287 | - Kind: LF_ARGLIST | |
| 288 | ArgList: | |
| 289 | ArgIndices: [ 35 ] | |
| 290 | - Kind: LF_PROCEDURE | |
| 291 | Procedure: | |
| 292 | ReturnType: 1539 | |
| 293 | CallConv: NearC | |
| 294 | Options: [ None ] | |
| 295 | ParameterCount: 1 | |
| 296 | ArgumentList: 4102 | |
| 297 | - Kind: LF_FUNC_ID | |
| 298 | FuncId: | |
| 299 | ParentScope: 0 | |
| 300 | FunctionType: 4103 | |
| 301 | Name: operator new | |
| 302 | - Kind: LF_ARGLIST | |
| 303 | ArgList: | |
| 304 | ArgIndices: [ ] | |
| 305 | - Kind: LF_PROCEDURE | |
| 306 | Procedure: | |
| 307 | ReturnType: 4101 | |
| 308 | CallConv: NearC | |
| 309 | Options: [ None ] | |
| 310 | ParameterCount: 0 | |
| 311 | ArgumentList: 4105 | |
| 312 | - Kind: LF_FUNC_ID | |
| 313 | FuncId: | |
| 314 | ParentScope: 0 | |
| 315 | FunctionType: 4106 | |
| 316 | Name: f | |
| 317 | - Kind: LF_STRUCTURE | |
| 318 | Class: | |
| 319 | MemberCount: 0 | |
| 320 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 321 | FieldList: 0 | |
| 322 | Name: '__vc_attributes::moduleAttribute' | |
| 323 | UniqueName: '.?AUmoduleAttribute@__vc_attributes@@' | |
| 324 | DerivationList: 0 | |
| 325 | VTableShape: 0 | |
| 326 | Size: 0 | |
| 327 | - Kind: LF_FIELDLIST | |
| 328 | FieldList: | |
| 329 | - Kind: LF_ENUMERATE | |
| 330 | Enumerator: | |
| 331 | Attrs: 3 | |
| 332 | Value: 1 | |
| 333 | Name: dll | |
| 334 | - Kind: LF_ENUMERATE | |
| 335 | Enumerator: | |
| 336 | Attrs: 3 | |
| 337 | Value: 2 | |
| 338 | Name: exe | |
| 339 | - Kind: LF_ENUMERATE | |
| 340 | Enumerator: | |
| 341 | Attrs: 3 | |
| 342 | Value: 3 | |
| 343 | Name: service | |
| 344 | - Kind: LF_ENUMERATE | |
| 345 | Enumerator: | |
| 346 | Attrs: 3 | |
| 347 | Value: 4 | |
| 348 | Name: unspecified | |
| 349 | - Kind: LF_ENUMERATE | |
| 350 | Enumerator: | |
| 351 | Attrs: 3 | |
| 352 | Value: 2 | |
| 353 | Name: EXE | |
| 354 | - Kind: LF_ENUMERATE | |
| 355 | Enumerator: | |
| 356 | Attrs: 3 | |
| 357 | Value: 3 | |
| 358 | Name: SERVICE | |
| 359 | - Kind: LF_ENUM | |
| 360 | Enum: | |
| 361 | NumEnumerators: 6 | |
| 362 | Options: [ None, Nested, HasUniqueName ] | |
| 363 | FieldList: 4109 | |
| 364 | Name: '__vc_attributes::moduleAttribute::type_e' | |
| 365 | UniqueName: '.?AW4type_e@moduleAttribute@__vc_attributes@@' | |
| 366 | UnderlyingType: 116 | |
| 367 | - Kind: LF_STRING_ID | |
| 368 | StringId: | |
| 369 | Id: 0 | |
| 370 | String: 'c:\src\llvm-project\build\predefined c++ attributes (compiler internal)' | |
| 371 | - Kind: LF_UDT_SRC_LINE | |
| 372 | UdtSourceLine: | |
| 373 | UDT: 4110 | |
| 374 | SourceFile: 4111 | |
| 375 | LineNumber: 482 | |
| 376 | - Kind: LF_MODIFIER | |
| 377 | Modifier: | |
| 378 | ModifiedType: 112 | |
| 379 | Modifiers: [ None, Const ] | |
| 380 | - Kind: LF_POINTER | |
| 381 | Pointer: | |
| 382 | ReferentType: 4113 | |
| 383 | Attrs: 65548 | |
| 384 | - Kind: LF_ARGLIST | |
| 385 | ArgList: | |
| 386 | ArgIndices: [ 4110, 4114, 4114, 4114, 116, 48, 4114, 116, | |
| 387 | 4114, 4114, 116, 48, 48, 4114, 4114 ] | |
| 388 | - Kind: LF_POINTER | |
| 389 | Pointer: | |
| 390 | ReferentType: 4108 | |
| 391 | Attrs: 66572 | |
| 392 | - Kind: LF_MFUNCTION | |
| 393 | MemberFunction: | |
| 394 | ReturnType: 3 | |
| 395 | ClassType: 4108 | |
| 396 | ThisType: 4116 | |
| 397 | CallConv: NearC | |
| 398 | Options: [ None, Constructor ] | |
| 399 | ParameterCount: 15 | |
| 400 | ArgumentList: 4115 | |
| 401 | ThisPointerAdjustment: 0 | |
| 402 | - Kind: LF_ARGLIST | |
| 403 | ArgList: | |
| 404 | ArgIndices: [ 4110 ] | |
| 405 | - Kind: LF_MFUNCTION | |
| 406 | MemberFunction: | |
| 407 | ReturnType: 3 | |
| 408 | ClassType: 4108 | |
| 409 | ThisType: 4116 | |
| 410 | CallConv: NearC | |
| 411 | Options: [ None, Constructor ] | |
| 412 | ParameterCount: 1 | |
| 413 | ArgumentList: 4118 | |
| 414 | ThisPointerAdjustment: 0 | |
| 415 | - Kind: LF_MFUNCTION | |
| 416 | MemberFunction: | |
| 417 | ReturnType: 3 | |
| 418 | ClassType: 4108 | |
| 419 | ThisType: 4116 | |
| 420 | CallConv: NearC | |
| 421 | Options: [ None, Constructor ] | |
| 422 | ParameterCount: 0 | |
| 423 | ArgumentList: 4105 | |
| 424 | ThisPointerAdjustment: 0 | |
| 425 | - Kind: LF_METHODLIST | |
| 426 | MethodOverloadList: | |
| 427 | Methods: | |
| 428 | - Type: 4117 | |
| 429 | Attrs: 3 | |
| 430 | VFTableOffset: -1 | |
| 431 | Name: '' | |
| 432 | - Type: 4119 | |
| 433 | Attrs: 3 | |
| 434 | VFTableOffset: -1 | |
| 435 | Name: '' | |
| 436 | - Type: 4120 | |
| 437 | Attrs: 3 | |
| 438 | VFTableOffset: -1 | |
| 439 | Name: '' | |
| 440 | - Kind: LF_FIELDLIST | |
| 441 | FieldList: | |
| 442 | - Kind: LF_NESTTYPE | |
| 443 | NestedType: | |
| 444 | Type: 4110 | |
| 445 | Name: type_e | |
| 446 | - Kind: LF_METHOD | |
| 447 | OverloadedMethod: | |
| 448 | NumOverloads: 3 | |
| 449 | MethodList: 4121 | |
| 450 | Name: moduleAttribute | |
| 451 | - Kind: LF_MEMBER | |
| 452 | DataMember: | |
| 453 | Attrs: 3 | |
| 454 | Type: 4110 | |
| 455 | FieldOffset: 0 | |
| 456 | Name: type | |
| 457 | - Kind: LF_MEMBER | |
| 458 | DataMember: | |
| 459 | Attrs: 3 | |
| 460 | Type: 4114 | |
| 461 | FieldOffset: 8 | |
| 462 | Name: name | |
| 463 | - Kind: LF_MEMBER | |
| 464 | DataMember: | |
| 465 | Attrs: 3 | |
| 466 | Type: 4114 | |
| 467 | FieldOffset: 16 | |
| 468 | Name: version | |
| 469 | - Kind: LF_MEMBER | |
| 470 | DataMember: | |
| 471 | Attrs: 3 | |
| 472 | Type: 4114 | |
| 473 | FieldOffset: 24 | |
| 474 | Name: uuid | |
| 475 | - Kind: LF_MEMBER | |
| 476 | DataMember: | |
| 477 | Attrs: 3 | |
| 478 | Type: 116 | |
| 479 | FieldOffset: 32 | |
| 480 | Name: lcid | |
| 481 | - Kind: LF_MEMBER | |
| 482 | DataMember: | |
| 483 | Attrs: 3 | |
| 484 | Type: 48 | |
| 485 | FieldOffset: 36 | |
| 486 | Name: control | |
| 487 | - Kind: LF_MEMBER | |
| 488 | DataMember: | |
| 489 | Attrs: 3 | |
| 490 | Type: 4114 | |
| 491 | FieldOffset: 40 | |
| 492 | Name: helpstring | |
| 493 | - Kind: LF_MEMBER | |
| 494 | DataMember: | |
| 495 | Attrs: 3 | |
| 496 | Type: 116 | |
| 497 | FieldOffset: 48 | |
| 498 | Name: helpstringcontext | |
| 499 | - Kind: LF_MEMBER | |
| 500 | DataMember: | |
| 501 | Attrs: 3 | |
| 502 | Type: 4114 | |
| 503 | FieldOffset: 56 | |
| 504 | Name: helpstringdll | |
| 505 | - Kind: LF_MEMBER | |
| 506 | DataMember: | |
| 507 | Attrs: 3 | |
| 508 | Type: 4114 | |
| 509 | FieldOffset: 64 | |
| 510 | Name: helpfile | |
| 511 | - Kind: LF_MEMBER | |
| 512 | DataMember: | |
| 513 | Attrs: 3 | |
| 514 | Type: 116 | |
| 515 | FieldOffset: 72 | |
| 516 | Name: helpcontext | |
| 517 | - Kind: LF_MEMBER | |
| 518 | DataMember: | |
| 519 | Attrs: 3 | |
| 520 | Type: 48 | |
| 521 | FieldOffset: 76 | |
| 522 | Name: hidden | |
| 523 | - Kind: LF_MEMBER | |
| 524 | DataMember: | |
| 525 | Attrs: 3 | |
| 526 | Type: 48 | |
| 527 | FieldOffset: 77 | |
| 528 | Name: restricted | |
| 529 | - Kind: LF_MEMBER | |
| 530 | DataMember: | |
| 531 | Attrs: 3 | |
| 532 | Type: 4114 | |
| 533 | FieldOffset: 80 | |
| 534 | Name: custom | |
| 535 | - Kind: LF_MEMBER | |
| 536 | DataMember: | |
| 537 | Attrs: 3 | |
| 538 | Type: 4114 | |
| 539 | FieldOffset: 88 | |
| 540 | Name: resource_name | |
| 541 | - Kind: LF_STRUCTURE | |
| 542 | Class: | |
| 543 | MemberCount: 19 | |
| 544 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | |
| 545 | FieldList: 4122 | |
| 546 | Name: '__vc_attributes::moduleAttribute' | |
| 547 | UniqueName: '.?AUmoduleAttribute@__vc_attributes@@' | |
| 548 | DerivationList: 0 | |
| 549 | VTableShape: 0 | |
| 550 | Size: 96 | |
| 551 | - Kind: LF_UDT_SRC_LINE | |
| 552 | UdtSourceLine: | |
| 553 | UDT: 4123 | |
| 554 | SourceFile: 4111 | |
| 555 | LineNumber: 481 | |
| 556 | - Kind: LF_STRUCTURE | |
| 557 | Class: | |
| 558 | MemberCount: 0 | |
| 559 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 560 | FieldList: 0 | |
| 561 | Name: '__vc_attributes::event_receiverAttribute' | |
| 562 | UniqueName: '.?AUevent_receiverAttribute@__vc_attributes@@' | |
| 563 | DerivationList: 0 | |
| 564 | VTableShape: 0 | |
| 565 | Size: 0 | |
| 566 | - Kind: LF_FIELDLIST | |
| 567 | FieldList: | |
| 568 | - Kind: LF_ENUMERATE | |
| 569 | Enumerator: | |
| 570 | Attrs: 3 | |
| 571 | Value: 0 | |
| 572 | Name: native | |
| 573 | - Kind: LF_ENUMERATE | |
| 574 | Enumerator: | |
| 575 | Attrs: 3 | |
| 576 | Value: 1 | |
| 577 | Name: com | |
| 578 | - Kind: LF_ENUMERATE | |
| 579 | Enumerator: | |
| 580 | Attrs: 3 | |
| 581 | Value: 2 | |
| 582 | Name: managed | |
| 583 | - Kind: LF_ENUM | |
| 584 | Enum: | |
| 585 | NumEnumerators: 3 | |
| 586 | Options: [ None, Nested, HasUniqueName ] | |
| 587 | FieldList: 4126 | |
| 588 | Name: '__vc_attributes::event_receiverAttribute::type_e' | |
| 589 | UniqueName: '.?AW4type_e@event_receiverAttribute@__vc_attributes@@' | |
| 590 | UnderlyingType: 116 | |
| 591 | - Kind: LF_UDT_SRC_LINE | |
| 592 | UdtSourceLine: | |
| 593 | UDT: 4127 | |
| 594 | SourceFile: 4111 | |
| 595 | LineNumber: 136 | |
| 596 | - Kind: LF_ARGLIST | |
| 597 | ArgList: | |
| 598 | ArgIndices: [ 4127, 48 ] | |
| 599 | - Kind: LF_POINTER | |
| 600 | Pointer: | |
| 601 | ReferentType: 4125 | |
| 602 | Attrs: 66572 | |
| 603 | - Kind: LF_MFUNCTION | |
| 604 | MemberFunction: | |
| 605 | ReturnType: 3 | |
| 606 | ClassType: 4125 | |
| 607 | ThisType: 4130 | |
| 608 | CallConv: NearC | |
| 609 | Options: [ None, Constructor ] | |
| 610 | ParameterCount: 2 | |
| 611 | ArgumentList: 4129 | |
| 612 | ThisPointerAdjustment: 0 | |
| 613 | - Kind: LF_ARGLIST | |
| 614 | ArgList: | |
| 615 | ArgIndices: [ 4127 ] | |
| 616 | - Kind: LF_MFUNCTION | |
| 617 | MemberFunction: | |
| 618 | ReturnType: 3 | |
| 619 | ClassType: 4125 | |
| 620 | ThisType: 4130 | |
| 621 | CallConv: NearC | |
| 622 | Options: [ None, Constructor ] | |
| 623 | ParameterCount: 1 | |
| 624 | ArgumentList: 4132 | |
| 625 | ThisPointerAdjustment: 0 | |
| 626 | - Kind: LF_MFUNCTION | |
| 627 | MemberFunction: | |
| 628 | ReturnType: 3 | |
| 629 | ClassType: 4125 | |
| 630 | ThisType: 4130 | |
| 631 | CallConv: NearC | |
| 632 | Options: [ None, Constructor ] | |
| 633 | ParameterCount: 0 | |
| 634 | ArgumentList: 4105 | |
| 635 | ThisPointerAdjustment: 0 | |
| 636 | - Kind: LF_METHODLIST | |
| 637 | MethodOverloadList: | |
| 638 | Methods: | |
| 639 | - Type: 4131 | |
| 640 | Attrs: 3 | |
| 641 | VFTableOffset: -1 | |
| 642 | Name: '' | |
| 643 | - Type: 4133 | |
| 644 | Attrs: 3 | |
| 645 | VFTableOffset: -1 | |
| 646 | Name: '' | |
| 647 | - Type: 4134 | |
| 648 | Attrs: 3 | |
| 649 | VFTableOffset: -1 | |
| 650 | Name: '' | |
| 651 | - Kind: LF_FIELDLIST | |
| 652 | FieldList: | |
| 653 | - Kind: LF_NESTTYPE | |
| 654 | NestedType: | |
| 655 | Type: 4127 | |
| 656 | Name: type_e | |
| 657 | - Kind: LF_METHOD | |
| 658 | OverloadedMethod: | |
| 659 | NumOverloads: 3 | |
| 660 | MethodList: 4135 | |
| 661 | Name: event_receiverAttribute | |
| 662 | - Kind: LF_MEMBER | |
| 663 | DataMember: | |
| 664 | Attrs: 3 | |
| 665 | Type: 4127 | |
| 666 | FieldOffset: 0 | |
| 667 | Name: type | |
| 668 | - Kind: LF_MEMBER | |
| 669 | DataMember: | |
| 670 | Attrs: 3 | |
| 671 | Type: 48 | |
| 672 | FieldOffset: 4 | |
| 673 | Name: layout_dependent | |
| 674 | - Kind: LF_STRUCTURE | |
| 675 | Class: | |
| 676 | MemberCount: 6 | |
| 677 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | |
| 678 | FieldList: 4136 | |
| 679 | Name: '__vc_attributes::event_receiverAttribute' | |
| 680 | UniqueName: '.?AUevent_receiverAttribute@__vc_attributes@@' | |
| 681 | DerivationList: 0 | |
| 682 | VTableShape: 0 | |
| 683 | Size: 8 | |
| 684 | - Kind: LF_UDT_SRC_LINE | |
| 685 | UdtSourceLine: | |
| 686 | UDT: 4137 | |
| 687 | SourceFile: 4111 | |
| 688 | LineNumber: 135 | |
| 689 | - Kind: LF_STRUCTURE | |
| 690 | Class: | |
| 691 | MemberCount: 0 | |
| 692 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 693 | FieldList: 0 | |
| 694 | Name: '__vc_attributes::aggregatableAttribute' | |
| 695 | UniqueName: '.?AUaggregatableAttribute@__vc_attributes@@' | |
| 696 | DerivationList: 0 | |
| 697 | VTableShape: 0 | |
| 698 | Size: 0 | |
| 699 | - Kind: LF_FIELDLIST | |
| 700 | FieldList: | |
| 701 | - Kind: LF_ENUMERATE | |
| 702 | Enumerator: | |
| 703 | Attrs: 3 | |
| 704 | Value: 0 | |
| 705 | Name: never | |
| 706 | - Kind: LF_ENUMERATE | |
| 707 | Enumerator: | |
| 708 | Attrs: 3 | |
| 709 | Value: 1 | |
| 710 | Name: allowed | |
| 711 | - Kind: LF_ENUMERATE | |
| 712 | Enumerator: | |
| 713 | Attrs: 3 | |
| 714 | Value: 2 | |
| 715 | Name: always | |
| 716 | - Kind: LF_ENUM | |
| 717 | Enum: | |
| 718 | NumEnumerators: 3 | |
| 719 | Options: [ None, Nested, HasUniqueName ] | |
| 720 | FieldList: 4140 | |
| 721 | Name: '__vc_attributes::aggregatableAttribute::type_e' | |
| 722 | UniqueName: '.?AW4type_e@aggregatableAttribute@__vc_attributes@@' | |
| 723 | UnderlyingType: 116 | |
| 724 | - Kind: LF_UDT_SRC_LINE | |
| 725 | UdtSourceLine: | |
| 726 | UDT: 4141 | |
| 727 | SourceFile: 4111 | |
| 728 | LineNumber: 545 | |
| 729 | - Kind: LF_ARGLIST | |
| 730 | ArgList: | |
| 731 | ArgIndices: [ 4141 ] | |
| 732 | - Kind: LF_POINTER | |
| 733 | Pointer: | |
| 734 | ReferentType: 4139 | |
| 735 | Attrs: 66572 | |
| 736 | - Kind: LF_MFUNCTION | |
| 737 | MemberFunction: | |
| 738 | ReturnType: 3 | |
| 739 | ClassType: 4139 | |
| 740 | ThisType: 4144 | |
| 741 | CallConv: NearC | |
| 742 | Options: [ None, Constructor ] | |
| 743 | ParameterCount: 1 | |
| 744 | ArgumentList: 4143 | |
| 745 | ThisPointerAdjustment: 0 | |
| 746 | - Kind: LF_MFUNCTION | |
| 747 | MemberFunction: | |
| 748 | ReturnType: 3 | |
| 749 | ClassType: 4139 | |
| 750 | ThisType: 4144 | |
| 751 | CallConv: NearC | |
| 752 | Options: [ None, Constructor ] | |
| 753 | ParameterCount: 0 | |
| 754 | ArgumentList: 4105 | |
| 755 | ThisPointerAdjustment: 0 | |
| 756 | - Kind: LF_METHODLIST | |
| 757 | MethodOverloadList: | |
| 758 | Methods: | |
| 759 | - Type: 4145 | |
| 760 | Attrs: 3 | |
| 761 | VFTableOffset: -1 | |
| 762 | Name: '' | |
| 763 | - Type: 4146 | |
| 764 | Attrs: 3 | |
| 765 | VFTableOffset: -1 | |
| 766 | Name: '' | |
| 767 | - Kind: LF_FIELDLIST | |
| 768 | FieldList: | |
| 769 | - Kind: LF_NESTTYPE | |
| 770 | NestedType: | |
| 771 | Type: 4141 | |
| 772 | Name: type_e | |
| 773 | - Kind: LF_METHOD | |
| 774 | OverloadedMethod: | |
| 775 | NumOverloads: 2 | |
| 776 | MethodList: 4147 | |
| 777 | Name: aggregatableAttribute | |
| 778 | - Kind: LF_MEMBER | |
| 779 | DataMember: | |
| 780 | Attrs: 3 | |
| 781 | Type: 4141 | |
| 782 | FieldOffset: 0 | |
| 783 | Name: type | |
| 784 | - Kind: LF_STRUCTURE | |
| 785 | Class: | |
| 786 | MemberCount: 4 | |
| 787 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | |
| 788 | FieldList: 4148 | |
| 789 | Name: '__vc_attributes::aggregatableAttribute' | |
| 790 | UniqueName: '.?AUaggregatableAttribute@__vc_attributes@@' | |
| 791 | DerivationList: 0 | |
| 792 | VTableShape: 0 | |
| 793 | Size: 4 | |
| 794 | - Kind: LF_UDT_SRC_LINE | |
| 795 | UdtSourceLine: | |
| 796 | UDT: 4149 | |
| 797 | SourceFile: 4111 | |
| 798 | LineNumber: 544 | |
| 799 | - Kind: LF_STRUCTURE | |
| 800 | Class: | |
| 801 | MemberCount: 0 | |
| 802 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 803 | FieldList: 0 | |
| 804 | Name: '__vc_attributes::threadingAttribute' | |
| 805 | UniqueName: '.?AUthreadingAttribute@__vc_attributes@@' | |
| 806 | DerivationList: 0 | |
| 807 | VTableShape: 0 | |
| 808 | Size: 0 | |
| 809 | - Kind: LF_FIELDLIST | |
| 810 | FieldList: | |
| 811 | - Kind: LF_ENUMERATE | |
| 812 | Enumerator: | |
| 813 | Attrs: 3 | |
| 814 | Value: 1 | |
| 815 | Name: apartment | |
| 816 | - Kind: LF_ENUMERATE | |
| 817 | Enumerator: | |
| 818 | Attrs: 3 | |
| 819 | Value: 2 | |
| 820 | Name: single | |
| 821 | - Kind: LF_ENUMERATE | |
| 822 | Enumerator: | |
| 823 | Attrs: 3 | |
| 824 | Value: 3 | |
| 825 | Name: free | |
| 826 | - Kind: LF_ENUMERATE | |
| 827 | Enumerator: | |
| 828 | Attrs: 3 | |
| 829 | Value: 4 | |
| 830 | Name: neutral | |
| 831 | - Kind: LF_ENUMERATE | |
| 832 | Enumerator: | |
| 833 | Attrs: 3 | |
| 834 | Value: 5 | |
| 835 | Name: both | |
| 836 | - Kind: LF_ENUM | |
| 837 | Enum: | |
| 838 | NumEnumerators: 5 | |
| 839 | Options: [ None, Nested, HasUniqueName ] | |
| 840 | FieldList: 4152 | |
| 841 | Name: '__vc_attributes::threadingAttribute::threading_e' | |
| 842 | UniqueName: '.?AW4threading_e@threadingAttribute@__vc_attributes@@' | |
| 843 | UnderlyingType: 116 | |
| 844 | - Kind: LF_UDT_SRC_LINE | |
| 845 | UdtSourceLine: | |
| 846 | UDT: 4153 | |
| 847 | SourceFile: 4111 | |
| 848 | LineNumber: 423 | |
| 849 | - Kind: LF_ARGLIST | |
| 850 | ArgList: | |
| 851 | ArgIndices: [ 4153 ] | |
| 852 | - Kind: LF_POINTER | |
| 853 | Pointer: | |
| 854 | ReferentType: 4151 | |
| 855 | Attrs: 66572 | |
| 856 | - Kind: LF_MFUNCTION | |
| 857 | MemberFunction: | |
| 858 | ReturnType: 3 | |
| 859 | ClassType: 4151 | |
| 860 | ThisType: 4156 | |
| 861 | CallConv: NearC | |
| 862 | Options: [ None, Constructor ] | |
| 863 | ParameterCount: 1 | |
| 864 | ArgumentList: 4155 | |
| 865 | ThisPointerAdjustment: 0 | |
| 866 | - Kind: LF_MFUNCTION | |
| 867 | MemberFunction: | |
| 868 | ReturnType: 3 | |
| 869 | ClassType: 4151 | |
| 870 | ThisType: 4156 | |
| 871 | CallConv: NearC | |
| 872 | Options: [ None, Constructor ] | |
| 873 | ParameterCount: 0 | |
| 874 | ArgumentList: 4105 | |
| 875 | ThisPointerAdjustment: 0 | |
| 876 | - Kind: LF_METHODLIST | |
| 877 | MethodOverloadList: | |
| 878 | Methods: | |
| 879 | - Type: 4157 | |
| 880 | Attrs: 3 | |
| 881 | VFTableOffset: -1 | |
| 882 | Name: '' | |
| 883 | - Type: 4158 | |
| 884 | Attrs: 3 | |
| 885 | VFTableOffset: -1 | |
| 886 | Name: '' | |
| 887 | - Kind: LF_FIELDLIST | |
| 888 | FieldList: | |
| 889 | - Kind: LF_NESTTYPE | |
| 890 | NestedType: | |
| 891 | Type: 4153 | |
| 892 | Name: threading_e | |
| 893 | - Kind: LF_METHOD | |
| 894 | OverloadedMethod: | |
| 895 | NumOverloads: 2 | |
| 896 | MethodList: 4159 | |
| 897 | Name: threadingAttribute | |
| 898 | - Kind: LF_MEMBER | |
| 899 | DataMember: | |
| 900 | Attrs: 3 | |
| 901 | Type: 4153 | |
| 902 | FieldOffset: 0 | |
| 903 | Name: value | |
| 904 | - Kind: LF_STRUCTURE | |
| 905 | Class: | |
| 906 | MemberCount: 4 | |
| 907 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | |
| 908 | FieldList: 4160 | |
| 909 | Name: '__vc_attributes::threadingAttribute' | |
| 910 | UniqueName: '.?AUthreadingAttribute@__vc_attributes@@' | |
| 911 | DerivationList: 0 | |
| 912 | VTableShape: 0 | |
| 913 | Size: 4 | |
| 914 | - Kind: LF_UDT_SRC_LINE | |
| 915 | UdtSourceLine: | |
| 916 | UDT: 4161 | |
| 917 | SourceFile: 4111 | |
| 918 | LineNumber: 422 | |
| 919 | - Kind: LF_STRUCTURE | |
| 920 | Class: | |
| 921 | MemberCount: 0 | |
| 922 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 923 | FieldList: 0 | |
| 924 | Name: '__vc_attributes::helper_attributes::usageAttribute' | |
| 925 | UniqueName: '.?AUusageAttribute@helper_attributes@__vc_attributes@@' | |
| 926 | DerivationList: 0 | |
| 927 | VTableShape: 0 | |
| 928 | Size: 0 | |
| 929 | - Kind: LF_FIELDLIST | |
| 930 | FieldList: | |
| 931 | - Kind: LF_ENUMERATE | |
| 932 | Enumerator: | |
| 933 | Attrs: 3 | |
| 934 | Value: 0 | |
| 935 | Name: eAnyUsage | |
| 936 | - Kind: LF_ENUMERATE | |
| 937 | Enumerator: | |
| 938 | Attrs: 3 | |
| 939 | Value: 1 | |
| 940 | Name: eCoClassUsage | |
| 941 | - Kind: LF_ENUMERATE | |
| 942 | Enumerator: | |
| 943 | Attrs: 3 | |
| 944 | Value: 2 | |
| 945 | Name: eCOMInterfaceUsage | |
| 946 | - Kind: LF_ENUMERATE | |
| 947 | Enumerator: | |
| 948 | Attrs: 3 | |
| 949 | Value: 6 | |
| 950 | Name: eInterfaceUsage | |
| 951 | - Kind: LF_ENUMERATE | |
| 952 | Enumerator: | |
| 953 | Attrs: 3 | |
| 954 | Value: 8 | |
| 955 | Name: eMemberUsage | |
| 956 | - Kind: LF_ENUMERATE | |
| 957 | Enumerator: | |
| 958 | Attrs: 3 | |
| 959 | Value: 16 | |
| 960 | Name: eMethodUsage | |
| 961 | - Kind: LF_ENUMERATE | |
| 962 | Enumerator: | |
| 963 | Attrs: 3 | |
| 964 | Value: 32 | |
| 965 | Name: eInterfaceMethodUsage | |
| 966 | - Kind: LF_ENUMERATE | |
| 967 | Enumerator: | |
| 968 | Attrs: 3 | |
| 969 | Value: 64 | |
| 970 | Name: eInterfaceMemberUsage | |
| 971 | - Kind: LF_ENUMERATE | |
| 972 | Enumerator: | |
| 973 | Attrs: 3 | |
| 974 | Value: 128 | |
| 975 | Name: eCoClassMemberUsage | |
| 976 | - Kind: LF_ENUMERATE | |
| 977 | Enumerator: | |
| 978 | Attrs: 3 | |
| 979 | Value: 256 | |
| 980 | Name: eCoClassMethodUsage | |
| 981 | - Kind: LF_ENUMERATE | |
| 982 | Enumerator: | |
| 983 | Attrs: 3 | |
| 984 | Value: 768 | |
| 985 | Name: eGlobalMethodUsage | |
| 986 | - Kind: LF_ENUMERATE | |
| 987 | Enumerator: | |
| 988 | Attrs: 3 | |
| 989 | Value: 1024 | |
| 990 | Name: eGlobalDataUsage | |
| 991 | - Kind: LF_ENUMERATE | |
| 992 | Enumerator: | |
| 993 | Attrs: 3 | |
| 994 | Value: 2048 | |
| 995 | Name: eClassUsage | |
| 996 | - Kind: LF_ENUMERATE | |
| 997 | Enumerator: | |
| 998 | Attrs: 3 | |
| 999 | Value: 4096 | |
| 1000 | Name: eInterfaceParameterUsage | |
| 1001 | - Kind: LF_ENUMERATE | |
| 1002 | Enumerator: | |
| 1003 | Attrs: 3 | |
| 1004 | Value: 12288 | |
| 1005 | Name: eMethodParameterUsage | |
| 1006 | - Kind: LF_ENUMERATE | |
| 1007 | Enumerator: | |
| 1008 | Attrs: 3 | |
| 1009 | Value: 16384 | |
| 1010 | Name: eIDLModuleUsage | |
| 1011 | - Kind: LF_ENUMERATE | |
| 1012 | Enumerator: | |
| 1013 | Attrs: 3 | |
| 1014 | Value: 32768 | |
| 1015 | Name: eAnonymousUsage | |
| 1016 | - Kind: LF_ENUMERATE | |
| 1017 | Enumerator: | |
| 1018 | Attrs: 3 | |
| 1019 | Value: 65536 | |
| 1020 | Name: eTypedefUsage | |
| 1021 | - Kind: LF_ENUMERATE | |
| 1022 | Enumerator: | |
| 1023 | Attrs: 3 | |
| 1024 | Value: 131072 | |
| 1025 | Name: eUnionUsage | |
| 1026 | - Kind: LF_ENUMERATE | |
| 1027 | Enumerator: | |
| 1028 | Attrs: 3 | |
| 1029 | Value: 262144 | |
| 1030 | Name: eEnumUsage | |
| 1031 | - Kind: LF_ENUMERATE | |
| 1032 | Enumerator: | |
| 1033 | Attrs: 3 | |
| 1034 | Value: 524288 | |
| 1035 | Name: eDefineTagUsage | |
| 1036 | - Kind: LF_ENUMERATE | |
| 1037 | Enumerator: | |
| 1038 | Attrs: 3 | |
| 1039 | Value: 1048576 | |
| 1040 | Name: eStructUsage | |
| 1041 | - Kind: LF_ENUMERATE | |
| 1042 | Enumerator: | |
| 1043 | Attrs: 3 | |
| 1044 | Value: 2097152 | |
| 1045 | Name: eLocalUsage | |
| 1046 | - Kind: LF_ENUMERATE | |
| 1047 | Enumerator: | |
| 1048 | Attrs: 3 | |
| 1049 | Value: 4194304 | |
| 1050 | Name: ePropertyUsage | |
| 1051 | - Kind: LF_ENUMERATE | |
| 1052 | Enumerator: | |
| 1053 | Attrs: 3 | |
| 1054 | Value: 8388608 | |
| 1055 | Name: eEventUsage | |
| 1056 | - Kind: LF_ENUMERATE | |
| 1057 | Enumerator: | |
| 1058 | Attrs: 3 | |
| 1059 | Value: 16777216 | |
| 1060 | Name: eTemplateUsage | |
| 1061 | - Kind: LF_ENUMERATE | |
| 1062 | Enumerator: | |
| 1063 | Attrs: 3 | |
| 1064 | Value: 16777216 | |
| 1065 | Name: eModuleUsage | |
| 1066 | - Kind: LF_ENUMERATE | |
| 1067 | Enumerator: | |
| 1068 | Attrs: 3 | |
| 1069 | Value: 33554432 | |
| 1070 | Name: eIllegalUsage | |
| 1071 | - Kind: LF_ENUMERATE | |
| 1072 | Enumerator: | |
| 1073 | Attrs: 3 | |
| 1074 | Value: 67108864 | |
| 1075 | Name: eAsynchronousUsage | |
| 1076 | - Kind: LF_ENUMERATE | |
| 1077 | Enumerator: | |
| 1078 | Attrs: 3 | |
| 1079 | Value: 4161535 | |
| 1080 | Name: eAnyIDLUsage | |
| 1081 | - Kind: LF_ENUM | |
| 1082 | Enum: | |
| 1083 | NumEnumerators: 30 | |
| 1084 | Options: [ None, Nested, HasUniqueName ] | |
| 1085 | FieldList: 4164 | |
| 1086 | Name: '__vc_attributes::helper_attributes::usageAttribute::usage_e' | |
| 1087 | UniqueName: '.?AW4usage_e@usageAttribute@helper_attributes@__vc_attributes@@' | |
| 1088 | UnderlyingType: 116 | |
| 1089 | - Kind: LF_UDT_SRC_LINE | |
| 1090 | UdtSourceLine: | |
| 1091 | UDT: 4165 | |
| 1092 | SourceFile: 4111 | |
| 1093 | LineNumber: 51 | |
| 1094 | - Kind: LF_ARGLIST | |
| 1095 | ArgList: | |
| 1096 | ArgIndices: [ 117 ] | |
| 1097 | - Kind: LF_POINTER | |
| 1098 | Pointer: | |
| 1099 | ReferentType: 4163 | |
| 1100 | Attrs: 66572 | |
| 1101 | - Kind: LF_MFUNCTION | |
| 1102 | MemberFunction: | |
| 1103 | ReturnType: 3 | |
| 1104 | ClassType: 4163 | |
| 1105 | ThisType: 4168 | |
| 1106 | CallConv: NearC | |
| 1107 | Options: [ None, Constructor ] | |
| 1108 | ParameterCount: 1 | |
| 1109 | ArgumentList: 4167 | |
| 1110 | ThisPointerAdjustment: 0 | |
| 1111 | - Kind: LF_FIELDLIST | |
| 1112 | FieldList: | |
| 1113 | - Kind: LF_NESTTYPE | |
| 1114 | NestedType: | |
| 1115 | Type: 4165 | |
| 1116 | Name: usage_e | |
| 1117 | - Kind: LF_ONEMETHOD | |
| 1118 | OneMethod: | |
| 1119 | Type: 4169 | |
| 1120 | Attrs: 3 | |
| 1121 | VFTableOffset: -1 | |
| 1122 | Name: usageAttribute | |
| 1123 | - Kind: LF_MEMBER | |
| 1124 | DataMember: | |
| 1125 | Attrs: 3 | |
| 1126 | Type: 117 | |
| 1127 | FieldOffset: 0 | |
| 1128 | Name: value | |
| 1129 | - Kind: LF_STRUCTURE | |
| 1130 | Class: | |
| 1131 | MemberCount: 3 | |
| 1132 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | |
| 1133 | FieldList: 4170 | |
| 1134 | Name: '__vc_attributes::helper_attributes::usageAttribute' | |
| 1135 | UniqueName: '.?AUusageAttribute@helper_attributes@__vc_attributes@@' | |
| 1136 | DerivationList: 0 | |
| 1137 | VTableShape: 0 | |
| 1138 | Size: 4 | |
| 1139 | - Kind: LF_UDT_SRC_LINE | |
| 1140 | UdtSourceLine: | |
| 1141 | UDT: 4171 | |
| 1142 | SourceFile: 4111 | |
| 1143 | LineNumber: 49 | |
| 1144 | - Kind: LF_STRUCTURE | |
| 1145 | Class: | |
| 1146 | MemberCount: 0 | |
| 1147 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 1148 | FieldList: 0 | |
| 1149 | Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute' | |
| 1150 | UniqueName: '.?AUv1_alttypeAttribute@helper_attributes@__vc_attributes@@' | |
| 1151 | DerivationList: 0 | |
| 1152 | VTableShape: 0 | |
| 1153 | Size: 0 | |
| 1154 | - Kind: LF_FIELDLIST | |
| 1155 | FieldList: | |
| 1156 | - Kind: LF_ENUMERATE | |
| 1157 | Enumerator: | |
| 1158 | Attrs: 3 | |
| 1159 | Value: 0 | |
| 1160 | Name: eBoolean | |
| 1161 | - Kind: LF_ENUMERATE | |
| 1162 | Enumerator: | |
| 1163 | Attrs: 3 | |
| 1164 | Value: 1 | |
| 1165 | Name: eInteger | |
| 1166 | - Kind: LF_ENUMERATE | |
| 1167 | Enumerator: | |
| 1168 | Attrs: 3 | |
| 1169 | Value: 2 | |
| 1170 | Name: eFloat | |
| 1171 | - Kind: LF_ENUMERATE | |
| 1172 | Enumerator: | |
| 1173 | Attrs: 3 | |
| 1174 | Value: 3 | |
| 1175 | Name: eDouble | |
| 1176 | - Kind: LF_ENUM | |
| 1177 | Enum: | |
| 1178 | NumEnumerators: 4 | |
| 1179 | Options: [ None, Nested, HasUniqueName ] | |
| 1180 | FieldList: 4174 | |
| 1181 | Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute::type_e' | |
| 1182 | UniqueName: '.?AW4type_e@v1_alttypeAttribute@helper_attributes@__vc_attributes@@' | |
| 1183 | UnderlyingType: 116 | |
| 1184 | - Kind: LF_UDT_SRC_LINE | |
| 1185 | UdtSourceLine: | |
| 1186 | UDT: 4175 | |
| 1187 | SourceFile: 4111 | |
| 1188 | LineNumber: 38 | |
| 1189 | - Kind: LF_ARGLIST | |
| 1190 | ArgList: | |
| 1191 | ArgIndices: [ 4175 ] | |
| 1192 | - Kind: LF_POINTER | |
| 1193 | Pointer: | |
| 1194 | ReferentType: 4173 | |
| 1195 | Attrs: 66572 | |
| 1196 | - Kind: LF_MFUNCTION | |
| 1197 | MemberFunction: | |
| 1198 | ReturnType: 3 | |
| 1199 | ClassType: 4173 | |
| 1200 | ThisType: 4178 | |
| 1201 | CallConv: NearC | |
| 1202 | Options: [ None, Constructor ] | |
| 1203 | ParameterCount: 1 | |
| 1204 | ArgumentList: 4177 | |
| 1205 | ThisPointerAdjustment: 0 | |
| 1206 | - Kind: LF_FIELDLIST | |
| 1207 | FieldList: | |
| 1208 | - Kind: LF_NESTTYPE | |
| 1209 | NestedType: | |
| 1210 | Type: 4175 | |
| 1211 | Name: type_e | |
| 1212 | - Kind: LF_ONEMETHOD | |
| 1213 | OneMethod: | |
| 1214 | Type: 4179 | |
| 1215 | Attrs: 3 | |
| 1216 | VFTableOffset: -1 | |
| 1217 | Name: v1_alttypeAttribute | |
| 1218 | - Kind: LF_MEMBER | |
| 1219 | DataMember: | |
| 1220 | Attrs: 3 | |
| 1221 | Type: 4175 | |
| 1222 | FieldOffset: 0 | |
| 1223 | Name: type | |
| 1224 | - Kind: LF_STRUCTURE | |
| 1225 | Class: | |
| 1226 | MemberCount: 3 | |
| 1227 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | |
| 1228 | FieldList: 4180 | |
| 1229 | Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute' | |
| 1230 | UniqueName: '.?AUv1_alttypeAttribute@helper_attributes@__vc_attributes@@' | |
| 1231 | DerivationList: 0 | |
| 1232 | VTableShape: 0 | |
| 1233 | Size: 4 | |
| 1234 | - Kind: LF_UDT_SRC_LINE | |
| 1235 | UdtSourceLine: | |
| 1236 | UDT: 4181 | |
| 1237 | SourceFile: 4111 | |
| 1238 | LineNumber: 37 | |
| 1239 | - Kind: LF_STRUCTURE | |
| 1240 | Class: | |
| 1241 | MemberCount: 0 | |
| 1242 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 1243 | FieldList: 0 | |
| 1244 | Name: '__vc_attributes::event_sourceAttribute' | |
| 1245 | UniqueName: '.?AUevent_sourceAttribute@__vc_attributes@@' | |
| 1246 | DerivationList: 0 | |
| 1247 | VTableShape: 0 | |
| 1248 | Size: 0 | |
| 1249 | - Kind: LF_FIELDLIST | |
| 1250 | FieldList: | |
| 1251 | - Kind: LF_ENUMERATE | |
| 1252 | Enumerator: | |
| 1253 | Attrs: 3 | |
| 1254 | Value: 0 | |
| 1255 | Name: native | |
| 1256 | - Kind: LF_ENUMERATE | |
| 1257 | Enumerator: | |
| 1258 | Attrs: 3 | |
| 1259 | Value: 1 | |
| 1260 | Name: com | |
| 1261 | - Kind: LF_ENUMERATE | |
| 1262 | Enumerator: | |
| 1263 | Attrs: 3 | |
| 1264 | Value: 2 | |
| 1265 | Name: managed | |
| 1266 | - Kind: LF_ENUM | |
| 1267 | Enum: | |
| 1268 | NumEnumerators: 3 | |
| 1269 | Options: [ None, Nested, HasUniqueName ] | |
| 1270 | FieldList: 4184 | |
| 1271 | Name: '__vc_attributes::event_sourceAttribute::type_e' | |
| 1272 | UniqueName: '.?AW4type_e@event_sourceAttribute@__vc_attributes@@' | |
| 1273 | UnderlyingType: 116 | |
| 1274 | - Kind: LF_UDT_SRC_LINE | |
| 1275 | UdtSourceLine: | |
| 1276 | UDT: 4185 | |
| 1277 | SourceFile: 4111 | |
| 1278 | LineNumber: 1142 | |
| 1279 | - Kind: LF_FIELDLIST | |
| 1280 | FieldList: | |
| 1281 | - Kind: LF_ENUMERATE | |
| 1282 | Enumerator: | |
| 1283 | Attrs: 3 | |
| 1284 | Value: 0 | |
| 1285 | Name: speed | |
| 1286 | - Kind: LF_ENUMERATE | |
| 1287 | Enumerator: | |
| 1288 | Attrs: 3 | |
| 1289 | Value: 1 | |
| 1290 | Name: size | |
| 1291 | - Kind: LF_ENUM | |
| 1292 | Enum: | |
| 1293 | NumEnumerators: 2 | |
| 1294 | Options: [ None, Nested, HasUniqueName ] | |
| 1295 | FieldList: 4187 | |
| 1296 | Name: '__vc_attributes::event_sourceAttribute::optimize_e' | |
| 1297 | UniqueName: '.?AW4optimize_e@event_sourceAttribute@__vc_attributes@@' | |
| 1298 | UnderlyingType: 116 | |
| 1299 | - Kind: LF_UDT_SRC_LINE | |
| 1300 | UdtSourceLine: | |
| 1301 | UDT: 4188 | |
| 1302 | SourceFile: 4111 | |
| 1303 | LineNumber: 1145 | |
| 1304 | - Kind: LF_ARGLIST | |
| 1305 | ArgList: | |
| 1306 | ArgIndices: [ 4185 ] | |
| 1307 | - Kind: LF_POINTER | |
| 1308 | Pointer: | |
| 1309 | ReferentType: 4183 | |
| 1310 | Attrs: 66572 | |
| 1311 | - Kind: LF_MFUNCTION | |
| 1312 | MemberFunction: | |
| 1313 | ReturnType: 3 | |
| 1314 | ClassType: 4183 | |
| 1315 | ThisType: 4191 | |
| 1316 | CallConv: NearC | |
| 1317 | Options: [ None, Constructor ] | |
| 1318 | ParameterCount: 1 | |
| 1319 | ArgumentList: 4190 | |
| 1320 | ThisPointerAdjustment: 0 | |
| 1321 | - Kind: LF_MFUNCTION | |
| 1322 | MemberFunction: | |
| 1323 | ReturnType: 3 | |
| 1324 | ClassType: 4183 | |
| 1325 | ThisType: 4191 | |
| 1326 | CallConv: NearC | |
| 1327 | Options: [ None, Constructor ] | |
| 1328 | ParameterCount: 0 | |
| 1329 | ArgumentList: 4105 | |
| 1330 | ThisPointerAdjustment: 0 | |
| 1331 | - Kind: LF_METHODLIST | |
| 1332 | MethodOverloadList: | |
| 1333 | Methods: | |
| 1334 | - Type: 4192 | |
| 1335 | Attrs: 3 | |
| 1336 | VFTableOffset: -1 | |
| 1337 | Name: '' | |
| 1338 | - Type: 4193 | |
| 1339 | Attrs: 3 | |
| 1340 | VFTableOffset: -1 | |
| 1341 | Name: '' | |
| 1342 | - Kind: LF_FIELDLIST | |
| 1343 | FieldList: | |
| 1344 | - Kind: LF_NESTTYPE | |
| 1345 | NestedType: | |
| 1346 | Type: 4185 | |
| 1347 | Name: type_e | |
| 1348 | - Kind: LF_NESTTYPE | |
| 1349 | NestedType: | |
| 1350 | Type: 4188 | |
| 1351 | Name: optimize_e | |
| 1352 | - Kind: LF_METHOD | |
| 1353 | OverloadedMethod: | |
| 1354 | NumOverloads: 2 | |
| 1355 | MethodList: 4194 | |
| 1356 | Name: event_sourceAttribute | |
| 1357 | - Kind: LF_MEMBER | |
| 1358 | DataMember: | |
| 1359 | Attrs: 3 | |
| 1360 | Type: 4185 | |
| 1361 | FieldOffset: 0 | |
| 1362 | Name: type | |
| 1363 | - Kind: LF_MEMBER | |
| 1364 | DataMember: | |
| 1365 | Attrs: 3 | |
| 1366 | Type: 4188 | |
| 1367 | FieldOffset: 4 | |
| 1368 | Name: optimize | |
| 1369 | - Kind: LF_MEMBER | |
| 1370 | DataMember: | |
| 1371 | Attrs: 3 | |
| 1372 | Type: 48 | |
| 1373 | FieldOffset: 8 | |
| 1374 | Name: decorate | |
| 1375 | - Kind: LF_STRUCTURE | |
| 1376 | Class: | |
| 1377 | MemberCount: 7 | |
| 1378 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | |
| 1379 | FieldList: 4195 | |
| 1380 | Name: '__vc_attributes::event_sourceAttribute' | |
| 1381 | UniqueName: '.?AUevent_sourceAttribute@__vc_attributes@@' | |
| 1382 | DerivationList: 0 | |
| 1383 | VTableShape: 0 | |
| 1384 | Size: 12 | |
| 1385 | - Kind: LF_UDT_SRC_LINE | |
| 1386 | UdtSourceLine: | |
| 1387 | UDT: 4196 | |
| 1388 | SourceFile: 4111 | |
| 1389 | LineNumber: 1141 | |
| 1390 | - Kind: LF_STRING_ID | |
| 1391 | StringId: | |
| 1392 | Id: 0 | |
| 1393 | String: 'C:\src\llvm-project\build' | |
| 1394 | - Kind: LF_STRING_ID | |
| 1395 | StringId: | |
| 1396 | Id: 0 | |
| 1397 | String: 'C:\PROGRA~2\MICROS~1\2017\PROFES~1\VC\Tools\MSVC\14.11.25503\bin\HostX64\x64\cl.exe' | |
| 1398 | - Kind: LF_STRING_ID | |
| 1399 | StringId: | |
| 1400 | Id: 0 | |
| 1401 | String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1\2017\PROFES~1\VC\Tools\MSVC\14.11.25503\ATLMFC\include -IC:\PROGRA~2\MICROS~1\2017\PROFES~1\VC\Tools\MSVC\14.11.25503\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.16299.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.16299.0\' | |
| 1402 | - Kind: LF_SUBSTR_LIST | |
| 1403 | StringList: | |
| 1404 | StringIndices: [ 4200 ] | |
| 1405 | - Kind: LF_STRING_ID | |
| 1406 | StringId: | |
| 1407 | Id: 4201 | |
| 1408 | String: 'shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.16299.0\um -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.16299.0\winrt -TP -X' | |
| 1409 | - Kind: LF_STRING_ID | |
| 1410 | StringId: | |
| 1411 | Id: 0 | |
| 1412 | String: t.cpp | |
| 1413 | - Kind: LF_STRING_ID | |
| 1414 | StringId: | |
| 1415 | Id: 0 | |
| 1416 | String: 'C:\src\llvm-project\build\vc140.pdb' | |
| 1417 | - Kind: LF_BUILDINFO | |
| 1418 | BuildInfo: | |
| 1419 | ArgIndices: [ 4198, 4199, 4203, 4204, 4202 ] | |
| 1420 | - Name: '.text$mn' | |
| 1421 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 1422 | Alignment: 16 | |
| 1423 | SectionData: 48894C240833C0C3CCCCCCCCCCCCCCCC4883EC38B904000000E8000000004889442420488B4424204883C438C3 | |
| 1424 | Relocations: | |
| 1425 | - VirtualAddress: 26 | |
| 1426 | SymbolName: '??2@YAPEAX_K@Z' | |
| 1427 | Type: IMAGE_REL_AMD64_REL32 | |
| 1428 | - Name: .xdata | |
| 1429 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | |
| 1430 | Alignment: 4 | |
| 1431 | SectionData: '0104010004620000' | |
| 1432 | - Name: .pdata | |
| 1433 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | |
| 1434 | Alignment: 4 | |
| 1435 | SectionData: 000000001D00000000000000 | |
| 1436 | Relocations: | |
| 1437 | - VirtualAddress: 0 | |
| 1438 | SymbolName: '$LN3' | |
| 1439 | Type: IMAGE_REL_AMD64_ADDR32NB | |
| 1440 | - VirtualAddress: 4 | |
| 1441 | SymbolName: '$LN3' | |
| 1442 | Type: IMAGE_REL_AMD64_ADDR32NB | |
| 1443 | - VirtualAddress: 8 | |
| 1444 | SymbolName: '$unwind$f' | |
| 1445 | Type: IMAGE_REL_AMD64_ADDR32NB | |
| 1446 | symbols: | |
| 1447 | - Name: '@comp.id' | |
| 1448 | Value: 17130404 | |
| 1449 | SectionNumber: -1 | |
| 1450 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 1451 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 1452 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 1453 | - Name: '@feat.00' | |
| 1454 | Value: 2147484048 | |
| 1455 | SectionNumber: -1 | |
| 1456 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 1457 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 1458 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 1459 | - Name: .drectve | |
| 1460 | Value: 0 | |
| 1461 | SectionNumber: 1 | |
| 1462 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 1463 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 1464 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 1465 | SectionDefinition: | |
| 1466 | Length: 57 | |
| 1467 | NumberOfRelocations: 0 | |
| 1468 | NumberOfLinenumbers: 0 | |
| 1469 | CheckSum: 1455566745 | |
| 1470 | Number: 0 | |
| 1471 | - Name: '.debug$S' | |
| 1472 | Value: 0 | |
| 1473 | SectionNumber: 2 | |
| 1474 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 1475 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 1476 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 1477 | SectionDefinition: | |
| 1478 | Length: 1364 | |
| 1479 | NumberOfRelocations: 10 | |
| 1480 | NumberOfLinenumbers: 0 | |
| 1481 | CheckSum: 0 | |
| 1482 | Number: 0 | |
| 1483 | - Name: '.debug$T' | |
| 1484 | Value: 0 | |
| 1485 | SectionNumber: 3 | |
| 1486 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 1487 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 1488 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 1489 | SectionDefinition: | |
| 1490 | Length: 6560 | |
| 1491 | NumberOfRelocations: 0 | |
| 1492 | NumberOfLinenumbers: 0 | |
| 1493 | CheckSum: 0 | |
| 1494 | Number: 0 | |
| 1495 | - Name: '.text$mn' | |
| 1496 | Value: 0 | |
| 1497 | SectionNumber: 4 | |
| 1498 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 1499 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 1500 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 1501 | SectionDefinition: | |
| 1502 | Length: 45 | |
| 1503 | NumberOfRelocations: 1 | |
| 1504 | NumberOfLinenumbers: 0 | |
| 1505 | CheckSum: 1509507051 | |
| 1506 | Number: 0 | |
| 1507 | - Name: '??2@YAPEAX_K@Z' | |
| 1508 | Value: 0 | |
| 1509 | SectionNumber: 4 | |
| 1510 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 1511 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 1512 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 1513 | - Name: f | |
| 1514 | Value: 16 | |
| 1515 | SectionNumber: 4 | |
| 1516 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 1517 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 1518 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 1519 | - Name: '$LN3' | |
| 1520 | Value: 16 | |
| 1521 | SectionNumber: 4 | |
| 1522 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 1523 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 1524 | StorageClass: IMAGE_SYM_CLASS_LABEL | |
| 1525 | - Name: .xdata | |
| 1526 | Value: 0 | |
| 1527 | SectionNumber: 5 | |
| 1528 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 1529 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 1530 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 1531 | SectionDefinition: | |
| 1532 | Length: 8 | |
| 1533 | NumberOfRelocations: 0 | |
| 1534 | NumberOfLinenumbers: 0 | |
| 1535 | CheckSum: 931692337 | |
| 1536 | Number: 0 | |
| 1537 | - Name: '$unwind$f' | |
| 1538 | Value: 0 | |
| 1539 | SectionNumber: 5 | |
| 1540 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 1541 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 1542 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 1543 | - Name: .pdata | |
| 1544 | Value: 0 | |
| 1545 | SectionNumber: 6 | |
| 1546 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 1547 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 1548 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 1549 | SectionDefinition: | |
| 1550 | Length: 12 | |
| 1551 | NumberOfRelocations: 3 | |
| 1552 | NumberOfLinenumbers: 0 | |
| 1553 | CheckSum: 3887998202 | |
| 1554 | Number: 0 | |
| 1555 | - Name: '$pdata$f' | |
| 1556 | Value: 0 | |
| 1557 | SectionNumber: 6 | |
| 1558 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 1559 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 1560 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 1561 | ... |
deps/lld/test/COFF/pdb-import-gc.yaml+12-8| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # RUN: yaml2obj %s -o %t.obj |
| 2 | 2 | # RUN: lld-link %t.obj %S/Inputs/pdb-import-gc.lib -debug -entry:main \ |
| 3 | # RUN: -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb | |
| 4 | # RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s | |
| 3 | # RUN: -nodefaultlib -opt:ref -out:%t.exe -pdb:%t.pdb | |
| 4 | # RUN: llvm-pdbutil dump -globals -symbols %t.pdb | FileCheck %s | |
| 5 | 5 | |
| 6 | 6 | # This tests the case where an __imp_ chunk is discarded by linker GC. The debug |
| 7 | 7 | # info may refer to the __imp_ symbol still. |
| ... | ... | @@ -11,12 +11,16 @@ |
| 11 | 11 | # int discarded() { return __wc_mb_cur; } |
| 12 | 12 | # int main() { return g2; } |
| 13 | 13 | |
| 14 | # CHECK: Symbols | |
| 15 | # CHECK: ============================================================ | |
| 16 | # CHECK: Mod 0000 | `{{.*}}pdb-import-gc.yaml.tmp.obj`: | |
| 17 | # CHECK: 4 | S_GDATA32 [size = 32] `__imp___wc_mb_cur` | |
| 18 | # CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000 | |
| 19 | # CHECK: Mod 0001 | `* Linker *`: | |
| 14 | # CHECK: Global Symbols | |
| 15 | # CHECK-NEXT: ============================================================ | |
| 16 | # CHECK-NEXT: Records | |
| 17 | # CHECK-NEXT: 20 | S_GDATA32 [size = 32] `__imp___wc_mb_cur` | |
| 18 | # CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000 | |
| 19 | ||
| 20 | # CHECK: Symbols | |
| 21 | # CHECK-NEXT: ============================================================ | |
| 22 | # CHECK-NEXT: Mod 0000 | `{{.*}}pdb-import-gc.yaml.tmp.obj`: | |
| 23 | # CHECK-NEXT: Mod 0001 | `* Linker *`: | |
| 20 | 24 | |
| 21 | 25 | --- !COFF |
| 22 | 26 | header: |
deps/lld/test/COFF/pdb-invalid-func-type.yaml+1-1| ... | ... | @@ -7,7 +7,7 @@ |
| 7 | 7 | # RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s |
| 8 | 8 | |
| 9 | 9 | # CHECK: Mod 0000 | `{{.*}}pdb-invalid-func-type.yaml.tmp.obj`: |
| 10 | # CHECK: 4 | S_GPROC32_ID [size = 44] `main` | |
| 10 | # CHECK: 4 | S_GPROC32 [size = 44] `main` | |
| 11 | 11 | # CHECK: parent = 0, end = 80, addr = 0001:0000, code size = 3 |
| 12 | 12 | # CHECK: 48 | S_FRAMEPROC [size = 32] |
| 13 | 13 | # CHECK: 80 | S_END [size = 4] |
deps/lld/test/COFF/pdb-lib.s+3-3| ... | ... | @@ -11,15 +11,15 @@ |
| 11 | 11 | |
| 12 | 12 | # CHECK: Modules |
| 13 | 13 | # CHECK-NEXT: ============================================================ |
| 14 | # CHECK-NEXT: Mod 0000 | Name: `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`: | |
| 14 | # CHECK-NEXT: Mod 0000 | `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`: | |
| 15 | 15 | # CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`: |
| 16 | 16 | # CHECK-NEXT: debug stream: 9, # files: 0, has ec info: false |
| 17 | 17 | # CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 `` |
| 18 | # CHECK-NEXT: Mod 0001 | Name: `bar.obj`: | |
| 18 | # CHECK-NEXT: Mod 0001 | `bar.obj`: | |
| 19 | 19 | # CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]bar.lib}}`: |
| 20 | 20 | # CHECK-NEXT: debug stream: 10, # files: 0, has ec info: false |
| 21 | 21 | # CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 `` |
| 22 | # CHECK-NEXT: Mod 0002 | Name: `* Linker *`: | |
| 22 | # CHECK-NEXT: Mod 0002 | `* Linker *`: | |
| 23 | 23 | # CHECK-NEXT: Obj: ``: |
| 24 | 24 | # CHECK-NEXT: debug stream: 11, # files: 0, has ec info: false |
| 25 | 25 | # CHECK-NEXT: pdb file ni: 1 `{{.*foo.pdb}}`, src file ni: 0 `` |
deps/lld/test/COFF/pdb-linker-module.test+22-16| ... | ... | @@ -1,18 +1,24 @@ |
| 1 | 1 | RUN: lld-link /debug /pdb:%t.pdb /nodefaultlib /entry:main %S/Inputs/pdb-diff.obj |
| 2 | RUN: llvm-pdbutil dump -modules -symbols %t.pdb | FileCheck %s | |
| 2 | 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 | |
| 3 | 4 | |
| 4 | CHECK: Mod 0001 | `* Linker *`: | |
| 5 | CHECK-NEXT: 4 | S_OBJNAME [size = 20] sig=0, `* Linker *` | |
| 6 | CHECK-NEXT: 24 | S_COMPILE3 [size = 40] | |
| 7 | CHECK-NEXT: machine = intel 80386, Ver = LLVM Linker, language = link | |
| 8 | CHECK-NEXT: frontend = 0.0.0.0, backend = 0.0.0.0 | |
| 9 | CHECK-NEXT: flags = none | |
| 10 | CHECK-NEXT: 64 | S_ENVBLOCK | |
| 11 | CHECK-NEXT: - cwd | |
| 12 | CHECK-NEXT: - | |
| 13 | CHECK-NEXT: - exe | |
| 14 | CHECK-NEXT: - {{.*}}lld-link | |
| 15 | CHECK-NEXT: - pdb | |
| 16 | CHECK-NEXT: - {{.*}}pdb-linker-module{{.*}}pdb | |
| 17 | CHECK-NEXT: - cmd | |
| 18 | CHECK-NEXT: - /debug /pdb:{{.*}}pdb-linker-module{{.*}}pdb /nodefaultlib /entry:main {{.*}}pdb-diff.obj | |
| 5 | MODS: Mod 0001 | `* Linker *` | |
| 6 | MODS-NEXT: Obj: ``: | |
| 7 | MODS-NEXT: debug stream: 10, # files: 0, has ec info: false | |
| 8 | MODS-NEXT: pdb file ni: 1 `{{.*}}pdb-linker-module.test.tmp.pdb`, src file ni: 0 `` | |
| 9 | ||
| 10 | SYMS: Mod 0001 | `* Linker *` | |
| 11 | SYMS-NEXT: 4 | S_OBJNAME [size = 20] sig=0, `* Linker *` | |
| 12 | SYMS-NEXT: 24 | S_COMPILE3 [size = 40] | |
| 13 | SYMS-NEXT: machine = intel 80386, Ver = LLVM Linker, language = link | |
| 14 | SYMS-NEXT: frontend = 0.0.0.0, backend = 14.10.25019.0 | |
| 15 | SYMS-NEXT: flags = none | |
| 16 | SYMS-NEXT: 64 | S_ENVBLOCK | |
| 17 | SYMS-NEXT: - cwd | |
| 18 | SYMS-NEXT: - | |
| 19 | SYMS-NEXT: - exe | |
| 20 | SYMS-NEXT: - {{.*}}lld-link | |
| 21 | SYMS-NEXT: - pdb | |
| 22 | SYMS-NEXT: - {{.*}}pdb-linker-module{{.*}}pdb | |
| 23 | SYMS-NEXT: - cmd | |
| 24 | SYMS-NEXT: - /debug /pdb:{{.*}}pdb-linker-module{{.*}}pdb /nodefaultlib /entry:main {{.*}}pdb-diff.obj |
deps/lld/test/COFF/pdb-none.test+2-1| ... | ... | @@ -1,12 +1,13 @@ |
| 1 | 1 | # RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj |
| 2 | 2 | # RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj |
| 3 | # RUN: rm -f %t.pdb %t.dll | |
| 3 | 4 | # RUN: lld-link /debug /debugtype:pdata /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \ |
| 4 | 5 | # RUN: %t1.obj %t2.obj |
| 5 | 6 | |
| 6 | 7 | # RUN: llvm-pdbutil pdb2yaml -pdb-stream %t.pdb | FileCheck %s |
| 7 | 8 | |
| 8 | 9 | # CHECK: PdbStream: |
| 9 | # CHECK-NEXT: Age: 0 | |
| 10 | # CHECK-NEXT: Age: 1 | |
| 10 | 11 | # CHECK-NEXT: Guid: |
| 11 | 12 | # CHECK-NEXT: Signature: |
| 12 | 13 | # CHECK-NEXT: Features: [ VC140 ] |
deps/lld/test/COFF/pdb-options.test+1-1| ... | ... | @@ -18,4 +18,4 @@ |
| 18 | 18 | # RUN: lld-link /DEBUG /entry:main /nodefaultlib %t1.obj %t2.obj |
| 19 | 19 | # RUN: ls %t1.pdb |
| 20 | 20 | # RUN: rm %t* |
| 21 | # RUN: cd %T/.. | |
| 21 | # RUN: cd %T/.. |
deps/lld/test/COFF/pdb-procid-remapping.test created+29| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | # RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj | |
| 2 | # RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj | |
| 3 | # RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \ | |
| 4 | # RUN: %t1.obj %t2.obj | |
| 5 | ||
| 6 | # RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s | |
| 7 | ||
| 8 | CHECK: Symbols | |
| 9 | CHECK-NEXT: ============================================================ | |
| 10 | CHECK-LABEL: Mod 0000 | | |
| 11 | CHECK: 92 | S_GPROC32 [size = 44] `main` | |
| 12 | CHECK-NEXT: parent = 0, end = 168, addr = 0002:0000, code size = 14 | |
| 13 | CHECK-NEXT: type = `0x1004 (int (<no type>))`, debug start = 4, debug end = 9, flags = none | |
| 14 | CHECK-NEXT: 136 | S_FRAMEPROC [size = 32] | |
| 15 | CHECK-NEXT: size = 40, padding size = 0, offset to padding = 0 | |
| 16 | CHECK-NEXT: bytes of callee saved registers = 0, exception handler addr = 0000:0000 | |
| 17 | CHECK-NEXT: flags = has async eh | opt speed | |
| 18 | CHECK-NEXT: 168 | S_END [size = 4] | |
| 19 | CHECK-LABEL: Mod 0001 | | |
| 20 | CHECK: 92 | S_GPROC32 [size = 44] `foo` | |
| 21 | CHECK-NEXT: parent = 0, end = 168, addr = 0002:0016, code size = 6 | |
| 22 | CHECK-NEXT: type = `0x1001 (int ())`, debug start = 0, debug end = 5, flags = none | |
| 23 | CHECK-NEXT: 136 | S_FRAMEPROC [size = 32] | |
| 24 | CHECK-NEXT: size = 0, padding size = 0, offset to padding = 0 | |
| 25 | CHECK-NEXT: bytes of callee saved registers = 0, exception handler addr = 0000:0000 | |
| 26 | CHECK-NEXT: flags = has async eh | opt speed | |
| 27 | CHECK-NEXT: 168 | S_END [size = 4] | |
| 28 | CHECK-LABEL: Mod 0002 | | |
| 29 | CHECK: 4 | S_OBJNAME [size = 20] sig=0, `* Linker *` |
deps/lld/test/COFF/pdb-publics-import.test created+42| ... | ... | @@ -0,0 +1,42 @@ |
| 1 | Make a DLL that exports a few functions, then make a DLL with PDBs that imports | |
| 2 | them. Check that the __imp_ pointer and the generated thunks appear in the | |
| 3 | publics stream. | |
| 4 | ||
| 5 | RUN: yaml2obj < %p/Inputs/export.yaml > %t1.obj | |
| 6 | RUN: lld-link /out:%t1.dll /dll %t1.obj /implib:%t1.lib \ | |
| 7 | RUN: /export:exportfn1 /export:exportfn2 | |
| 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 | |
| 10 | RUN: llvm-pdbutil dump %t2.pdb -publics -section-contribs | FileCheck %s | |
| 11 | ||
| 12 | CHECK: Public Symbols | |
| 13 | CHECK-NEXT: ============================================================ | |
| 14 | CHECK-NEXT: Records | |
| 15 | CHECK-NEXT: 112 | S_PUB32 [size = 20] `main` | |
| 16 | CHECK-NEXT: flags = function, addr = 0001:0000 | |
| 17 | CHECK-NEXT: 64 | S_PUB32 [size = 24] `exportfn1` | |
| 18 | CHECK-NEXT: flags = function, addr = 0001:0016 | |
| 19 | CHECK-NEXT: 88 | S_PUB32 [size = 24] `exportfn2` | |
| 20 | CHECK-NEXT: flags = function, addr = 0001:0032 | |
| 21 | CHECK-NEXT: 32 | S_PUB32 [size = 32] `__imp_exportfn2` | |
| 22 | CHECK-NEXT: flags = none, addr = 0003:0072 | |
| 23 | CHECK-NEXT: 0 | S_PUB32 [size = 32] `__imp_exportfn1` | |
| 24 | CHECK-NEXT: flags = none, addr = 0003:0064 | |
| 25 | ||
| 26 | CHECK: Section Contributions | |
| 27 | CHECK-NEXT: ============================================================ | |
| 28 | main | |
| 29 | CHECK-NEXT: SC[.text] | mod = 0, 0001:0000, size = 8, data crc = 0, reloc crc = 0 | |
| 30 | CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_EXECUTE | | |
| 31 | CHECK-NEXT: IMAGE_SCN_MEM_READ | |
| 32 | exportfn1 thunk | |
| 33 | CHECK-NEXT: SC[.text] | mod = 1, 0001:0016, size = 6, data crc = 0, reloc crc = 0 | |
| 34 | CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | |
| 35 | exportfn2 thunk | |
| 36 | CHECK-NEXT: SC[.text] | mod = 1, 0001:0032, size = 6, data crc = 0, reloc crc = 0 | |
| 37 | CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | |
| 38 | .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: 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: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
deps/lld/test/COFF/pdb-safeseh.yaml+6-5| ... | ... | @@ -1,16 +1,17 @@ |
| 1 | 1 | # RUN: yaml2obj %s -o %t.obj |
| 2 | 2 | # RUN: lld-link -debug -entry:main -out:%t.exe -pdb:%t.pdb %t.obj |
| 3 | # RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s | |
| 3 | # RUN: llvm-pdbutil dump -globals %t.pdb | FileCheck %s | |
| 4 | 4 | |
| 5 | 5 | # There is an S_GDATA32 symbol record with .secrel32 and .secidx relocations in |
| 6 | 6 | # it in this debug info. This is similar to the relocations in the loadcfg.obj |
| 7 | 7 | # file in the MSVC CRT. We need to make sure that our relocation logic matches |
| 8 | 8 | # MSVC's for these absolute, linker-provided symbols. |
| 9 | 9 | |
| 10 | # CHECK: Mod 0000 | | |
| 11 | # CHECK-NEXT: 4 | S_GDATA32 [size = 40] `___safe_se_handler_table` | |
| 12 | # CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000 | |
| 13 | # CHECK-NEXT: Mod 0001 | `* Linker *`: | |
| 10 | # CHECK: Global Symbols | |
| 11 | # CHECK-NEXT: ============================================================ | |
| 12 | # CHECK-NEXT: Records | |
| 13 | # CHECK-NEXT: 20 | S_GDATA32 [size = 40] `___safe_se_handler_table` | |
| 14 | # CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000 | |
| 14 | 15 | |
| 15 | 16 | --- !COFF |
| 16 | 17 | header: |
deps/lld/test/COFF/pdb-same-name.test created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | # RUN: rm -rf %t1 %t2 | |
| 2 | # RUN: mkdir %t1 %t2 | |
| 3 | # RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1/foo.obj | |
| 4 | # RUN: llvm-ar cru %t1/foo.lib %t1/foo.obj | |
| 5 | # RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2/foo.obj | |
| 6 | # RUN: llvm-ar cru %t2/foo.lib %t2/foo.obj | |
| 7 | ||
| 8 | # RUN: rm -f %t.dll %t.pdb | |
| 9 | # RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \ | |
| 10 | # RUN: %t1/foo.lib %t2/foo.lib | |
| 11 | ||
| 12 | # RUN: llvm-pdbutil dump -modules %t.pdb | FileCheck -check-prefix RAW %s | |
| 13 | ||
| 14 | RAW: Modules | |
| 15 | RAW-NEXT: ============================================================ | |
| 16 | RAW-NEXT: Mod 0000 | `foo.obj`: | |
| 17 | RAW-NEXT: Obj: `{{.*}}1\foo.lib`: | |
| 18 | RAW-NEXT: debug stream: 9, # files: 1, has ec info: false | |
| 19 | RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` | |
| 20 | RAW-NEXT: Mod 0001 | `foo.obj`: | |
| 21 | RAW-NEXT: Obj: `{{.*}}2\foo.lib`: | |
| 22 | RAW-NEXT: debug stream: 10, # files: 1, has ec info: false | |
| 23 | RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` |
deps/lld/test/COFF/pdb-scopes.test+3-3| ... | ... | @@ -34,12 +34,12 @@ RUN: lld-link %t-a.obj %t-b.obj -debug -entry:main -nodefaultlib -out:%t.exe -pd |
| 34 | 34 | RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s |
| 35 | 35 | |
| 36 | 36 | CHECK-LABEL: Mod 0000 | `{{.*}}pdb-scopes.test.tmp-a.obj`: |
| 37 | CHECK: 104 | S_GPROC32_ID [size = 44] `g` | |
| 37 | CHECK: 104 | S_GPROC32 [size = 44] `g` | |
| 38 | 38 | CHECK: parent = 0, end = 196, addr = 0002:0000, code size = 5 |
| 39 | 39 | CHECK: debug start = 4, debug end = 4, flags = none |
| 40 | 40 | CHECK: 180 | S_REGREL32 [size = 16] `x` |
| 41 | 41 | CHECK: 196 | S_END [size = 4] |
| 42 | CHECK: 200 | S_GPROC32_ID [size = 44] `main` | |
| 42 | CHECK: 200 | S_GPROC32 [size = 44] `main` | |
| 43 | 43 | CHECK: parent = 0, end = 384, addr = 0002:0016, code size = 58 |
| 44 | 44 | CHECK: debug start = 8, debug end = 53, flags = none |
| 45 | 45 | CHECK: 276 | S_REGREL32 [size = 20] `argc` |
| ... | ... | @@ -56,7 +56,7 @@ CHECK: 380 | S_END [size = 4] |
| 56 | 56 | CHECK: 384 | S_END [size = 4] |
| 57 | 57 | |
| 58 | 58 | CHECK-LABEL: Mod 0001 | `{{.*}}pdb-scopes.test.tmp-b.obj`: |
| 59 | CHECK: 104 | S_GPROC32_ID [size = 44] `f` | |
| 59 | CHECK: 104 | S_GPROC32 [size = 44] `f` | |
| 60 | 60 | CHECK: parent = 0, end = 284, addr = 0002:0080, code size = 62 |
| 61 | 61 | CHECK: debug start = 8, debug end = 57, flags = none |
| 62 | 62 | CHECK: 180 | S_REGREL32 [size = 16] `x` |
deps/lld/test/COFF/pdb-secrel-absolute.yaml+6-5| ... | ... | @@ -1,16 +1,17 @@ |
| 1 | 1 | # RUN: yaml2obj %s -o %t.obj |
| 2 | 2 | # RUN: lld-link -debug -entry:main -out:%t.exe -pdb:%t.pdb %t.obj |
| 3 | # RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s | |
| 3 | # RUN: llvm-pdbutil dump -globals %t.pdb | FileCheck %s | |
| 4 | 4 | |
| 5 | 5 | # There is an S_GDATA32 symbol record with .secrel32 and .secidx relocations in |
| 6 | 6 | # it in this debug info. This is similar to the relocations in the loadcfg.obj |
| 7 | 7 | # file in the MSVC CRT. We need to make sure that our relocation logic matches |
| 8 | 8 | # MSVC's for these absolute, linker-provided symbols. |
| 9 | 9 | |
| 10 | # CHECK: Mod 0000 | | |
| 11 | # CHECK-NEXT: 4 | S_GDATA32 [size = 36] `__guard_fids_table` | |
| 12 | # CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000 | |
| 13 | # CHECK-NEXT: Mod 0001 | `* Linker *`: | |
| 10 | # CHECK: Global Symbols | |
| 11 | # CHECK-NEXT: ============================================================ | |
| 12 | # CHECK-NEXT: Records | |
| 13 | # CHECK-NEXT: 20 | S_GDATA32 [size = 36] `__guard_fids_table` | |
| 14 | # CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000 | |
| 14 | 15 | |
| 15 | 16 | --- !COFF |
| 16 | 17 | header: |
deps/lld/test/COFF/pdb-source-lines.test+18-17| ... | ... | @@ -19,10 +19,11 @@ $ cl -c -Z7 pdb_lines*.c |
| 19 | 19 | |
| 20 | 20 | RUN: yaml2obj %S/Inputs/pdb_lines_1.yaml -o %t.pdb_lines_1.obj |
| 21 | 21 | RUN: yaml2obj %S/Inputs/pdb_lines_2.yaml -o %t.pdb_lines_2.obj |
| 22 | RUN: rm -f %t.exe %t.pdb | |
| 22 | 23 | RUN: lld-link -debug -entry:main -nodefaultlib -out:%t.exe -pdb:%t.pdb %t.pdb_lines_1.obj %t.pdb_lines_2.obj |
| 23 | 24 | RUN: llvm-pdbutil pdb2yaml -modules -module-files -subsections=lines,fc %t.pdb | FileCheck %s |
| 24 | 25 | |
| 25 | CHECK-LABEL: DbiStream: | |
| 26 | CHECK-LABEL: DbiStream: | |
| 26 | 27 | CHECK-NEXT: VerHeader: V70 |
| 27 | 28 | CHECK-NEXT: Age: 1 |
| 28 | 29 | CHECK-NEXT: BuildNumber: 0 |
| ... | ... | @@ -30,22 +31,22 @@ CHECK-NEXT: PdbDllVersion: 0 |
| 30 | 31 | CHECK-NEXT: PdbDllRbld: 0 |
| 31 | 32 | CHECK-NEXT: Flags: 0 |
| 32 | 33 | CHECK-NEXT: MachineType: x86 |
| 33 | CHECK-NEXT: Modules: | |
| 34 | CHECK-NEXT: Modules: | |
| 34 | 35 | |
| 35 | 36 | CHECK-LABEL: - Module: {{.*}}pdb_lines_1.obj |
| 36 | 37 | CHECK-NEXT: ObjFile: {{.*}}pdb_lines_1.obj |
| 37 | CHECK-NEXT: SourceFiles: | |
| 38 | CHECK-NEXT: SourceFiles: | |
| 38 | 39 | CHECK-NEXT: - '{{.*}}pdb_lines_1.c' |
| 39 | 40 | CHECK-NEXT: - '{{.*}}foo.h' |
| 40 | CHECK-NEXT: Subsections: | |
| 41 | CHECK-NEXT: Subsections: | |
| 41 | 42 | CHECK-NEXT: - !Lines |
| 42 | 43 | CHECK-NEXT: CodeSize: 19 |
| 43 | 44 | CHECK-NEXT: Flags: [ ] |
| 44 | 45 | CHECK-NEXT: RelocOffset: 0 |
| 45 | 46 | CHECK-NEXT: RelocSegment: 2 |
| 46 | CHECK-NEXT: Blocks: | |
| 47 | CHECK-NEXT: Blocks: | |
| 47 | 48 | CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c' |
| 48 | CHECK-NEXT: Lines: | |
| 49 | CHECK-NEXT: Lines: | |
| 49 | 50 | CHECK-NEXT: - Offset: 0 |
| 50 | 51 | CHECK-NEXT: LineStart: 2 |
| 51 | 52 | CHECK-NEXT: IsStatement: true |
| ... | ... | @@ -62,9 +63,9 @@ CHECK-NEXT: - Offset: 14 |
| 62 | 63 | CHECK-NEXT: LineStart: 5 |
| 63 | 64 | CHECK-NEXT: IsStatement: true |
| 64 | 65 | CHECK-NEXT: EndDelta: 0 |
| 65 | CHECK-NEXT: Columns: | |
| 66 | CHECK-NEXT: Columns: | |
| 66 | 67 | CHECK-NEXT: - !FileChecksums |
| 67 | CHECK-NEXT: Checksums: | |
| 68 | CHECK-NEXT: Checksums: | |
| 68 | 69 | CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c' |
| 69 | 70 | CHECK-NEXT: Kind: MD5 |
| 70 | 71 | CHECK-NEXT: Checksum: 4EB19DCD86C3BA2238A255C718572E7B |
| ... | ... | @@ -76,9 +77,9 @@ CHECK-NEXT: CodeSize: 14 |
| 76 | 77 | CHECK-NEXT: Flags: [ ] |
| 77 | 78 | CHECK-NEXT: RelocOffset: 32 |
| 78 | 79 | CHECK-NEXT: RelocSegment: 2 |
| 79 | CHECK-NEXT: Blocks: | |
| 80 | CHECK-NEXT: Blocks: | |
| 80 | 81 | CHECK-NEXT: - FileName: '{{.*}}foo.h' |
| 81 | CHECK-NEXT: Lines: | |
| 82 | CHECK-NEXT: Lines: | |
| 82 | 83 | CHECK-NEXT: - Offset: 0 |
| 83 | 84 | CHECK-NEXT: LineStart: 2 |
| 84 | 85 | CHECK-NEXT: IsStatement: true |
| ... | ... | @@ -91,21 +92,21 @@ CHECK-NEXT: - Offset: 9 |
| 91 | 92 | CHECK-NEXT: LineStart: 4 |
| 92 | 93 | CHECK-NEXT: IsStatement: true |
| 93 | 94 | CHECK-NEXT: EndDelta: 0 |
| 94 | CHECK-NEXT: Columns: | |
| 95 | CHECK-NEXT: Columns: | |
| 95 | 96 | |
| 96 | 97 | CHECK-LABEL: - Module: {{.*}}pdb_lines_2.obj |
| 97 | 98 | CHECK-NEXT: ObjFile: {{.*}}pdb_lines_2.obj |
| 98 | CHECK-NEXT: SourceFiles: | |
| 99 | CHECK-NEXT: SourceFiles: | |
| 99 | 100 | CHECK-NEXT: - '{{.*}}pdb_lines_2.c' |
| 100 | CHECK-NEXT: Subsections: | |
| 101 | CHECK-NEXT: Subsections: | |
| 101 | 102 | CHECK-NEXT: - !Lines |
| 102 | 103 | CHECK-NEXT: CodeSize: 1 |
| 103 | 104 | CHECK-NEXT: Flags: [ ] |
| 104 | 105 | CHECK-NEXT: RelocOffset: 48 |
| 105 | 106 | CHECK-NEXT: RelocSegment: 2 |
| 106 | CHECK-NEXT: Blocks: | |
| 107 | CHECK-NEXT: Blocks: | |
| 107 | 108 | CHECK-NEXT: - FileName: '{{.*}}pdb_lines_2.c' |
| 108 | CHECK-NEXT: Lines: | |
| 109 | CHECK-NEXT: Lines: | |
| 109 | 110 | CHECK-NEXT: - Offset: 0 |
| 110 | 111 | CHECK-NEXT: LineStart: 1 |
| 111 | 112 | CHECK-NEXT: IsStatement: true |
| ... | ... | @@ -114,9 +115,9 @@ CHECK-NEXT: - Offset: 0 |
| 114 | 115 | CHECK-NEXT: LineStart: 2 |
| 115 | 116 | CHECK-NEXT: IsStatement: true |
| 116 | 117 | CHECK-NEXT: EndDelta: 0 |
| 117 | CHECK-NEXT: Columns: | |
| 118 | CHECK-NEXT: Columns: | |
| 118 | 119 | CHECK-NEXT: - !FileChecksums |
| 119 | CHECK-NEXT: Checksums: | |
| 120 | CHECK-NEXT: Checksums: | |
| 120 | 121 | CHECK-NEXT: - FileName: '{{.*}}pdb_lines_2.c' |
| 121 | 122 | CHECK-NEXT: Kind: MD5 |
| 122 | 123 | CHECK-NEXT: Checksum: DF91CB3A2B8D917486574BB50CAC4CC7 |
deps/lld/test/COFF/pdb-symbol-types.yaml+11-9| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | # RUN: yaml2obj %s -o %t.obj |
| 2 | 2 | # RUN: lld-link %t.obj -nodefaultlib -entry:main -debug -out:%t.exe -pdb:%t.pdb |
| 3 | # RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s | |
| 3 | # RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s | |
| 4 | 4 | |
| 5 | 5 | # To regenerate the object file: |
| 6 | 6 | # $ cat symbol-types.c |
| ... | ... | @@ -13,6 +13,14 @@ |
| 13 | 13 | # Note that the type of 'global' goes from 0x1005 in the object file to 0x1004 |
| 14 | 14 | # in the PDB because the LF_FUNC_ID is moved to the id stream. |
| 15 | 15 | |
| 16 | # CHECK-LABEL: Global Symbols | |
| 17 | # CHECK-NEXT: ============================================================ | |
| 18 | # CHECK-NEXT: Records | |
| 19 | # CHECK-NEXT: 48 | S_PROCREF [size = 20] `main` | |
| 20 | # CHECK-NEXT: module = 1, sum name = 0, offset = 116 | |
| 21 | # CHECK-NEXT: 68 | S_GDATA32 [size = 28] `global_foo` | |
| 22 | # CHECK-NEXT: type = 0x1004 (Foo), addr = 0001:0000 | |
| 23 | ||
| 16 | 24 | # CHECK: Symbols |
| 17 | 25 | # CHECK: ============================================================ |
| 18 | 26 | # CHECK-LABEL: Mod 0000 | `{{.*}}pdb-symbol-types.yaml.tmp.obj`: |
| ... | ... | @@ -21,7 +29,7 @@ |
| 21 | 29 | # CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c |
| 22 | 30 | # CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 |
| 23 | 31 | # CHECK: flags = security checks | hot patchable |
| 24 | # CHECK: 116 | S_GPROC32_ID [size = 44] `main` | |
| 32 | # CHECK: 116 | S_GPROC32 [size = 44] `main` | |
| 25 | 33 | # CHECK: parent = 0, end = 192, addr = 0002:0000, code size = 7 |
| 26 | 34 | # CHECK: debug start = 0, debug end = 6, flags = none |
| 27 | 35 | # CHECK: 160 | S_FRAMEPROC [size = 32] |
| ... | ... | @@ -29,13 +37,7 @@ |
| 29 | 37 | # CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 |
| 30 | 38 | # CHECK: flags = has async eh | opt speed |
| 31 | 39 | # CHECK: 192 | S_END [size = 4] |
| 32 | # CHECK: 196 | S_GDATA32 [size = 28] `global_foo` | |
| 33 | # CHECK: type = 0x1004 (Foo), addr = 0001:0000 | |
| 34 | # CHECK: 224 | S_UDT [size = 16] `UDT_Foo` | |
| 35 | # CHECK: original type = 0x1004 | |
| 36 | # CHECK: 240 | S_UDT [size = 12] `Foo` | |
| 37 | # CHECK: original type = 0x1004 | |
| 38 | # CHECK: 252 | S_BUILDINFO [size = 8] BuildId = `0x100A` | |
| 40 | # CHECK: 196 | S_BUILDINFO [size = 8] BuildId = `0x100A` | |
| 39 | 41 | # CHECK-LABEL: Mod 0001 | `* Linker *`: |
| 40 | 42 | |
| 41 | 43 | --- !COFF |
deps/lld/test/COFF/pdb-thunk.yaml created+2747| ... | ... | @@ -0,0 +1,2747 @@ |
| 1 | # RUN: yaml2obj %s -o %t.obj | |
| 2 | # RUN: lld-link %t.obj -dll -debug -noentry -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb | |
| 3 | # RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s | |
| 4 | ||
| 5 | # We used to skip vtable thunk symbol records, leading to symbol scope stack | |
| 6 | # imbalances (PR35014). Test that they survive the object file into the PDB. | |
| 7 | ||
| 8 | # This object generated from this C++ source: | |
| 9 | # // t.cpp | |
| 10 | # struct A { | |
| 11 | # virtual int f(); | |
| 12 | # }; | |
| 13 | # struct B { | |
| 14 | # virtual int f(); | |
| 15 | # }; | |
| 16 | # struct C : A, B { | |
| 17 | # __declspec(dllexport) C(); | |
| 18 | # int f() override; | |
| 19 | # int c; | |
| 20 | # }; | |
| 21 | # int A::f() { return 0; } | |
| 22 | # int B::f() { return 0; } | |
| 23 | # int C::f() { return c; } | |
| 24 | # C::C() : c(42) {} | |
| 25 | ||
| 26 | # Compile as: | |
| 27 | # $ cl -GR- -Z7 -c t.cpp | |
| 28 | ||
| 29 | # CHECK: S_THUNK32 | |
| 30 | # CHECK: S_END | |
| 31 | ||
| 32 | --- !COFF | |
| 33 | header: | |
| 34 | Machine: IMAGE_FILE_MACHINE_AMD64 | |
| 35 | Characteristics: [ ] | |
| 36 | sections: | |
| 37 | - Name: .drectve | |
| 38 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | |
| 39 | Alignment: 1 | |
| 40 | SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D455322202F4558504F52543A3F3F304340405145414140585A20 | |
| 41 | - Name: '.debug$S' | |
| 42 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 43 | Alignment: 1 | |
| 44 | Subsections: | |
| 45 | - !Symbols | |
| 46 | Records: | |
| 47 | - Kind: S_OBJNAME | |
| 48 | ObjNameSym: | |
| 49 | Signature: 0 | |
| 50 | ObjectName: 'C:\src\llvm-project\build\t.obj' | |
| 51 | - Kind: S_COMPILE3 | |
| 52 | Compile3Sym: | |
| 53 | Flags: [ SecurityChecks, HotPatch ] | |
| 54 | Machine: X64 | |
| 55 | FrontendMajor: 19 | |
| 56 | FrontendMinor: 11 | |
| 57 | FrontendBuild: 25508 | |
| 58 | FrontendQFE: 2 | |
| 59 | BackendMajor: 19 | |
| 60 | BackendMinor: 11 | |
| 61 | BackendBuild: 25508 | |
| 62 | BackendQFE: 2 | |
| 63 | Version: 'Microsoft (R) Optimizing Compiler' | |
| 64 | - !Symbols | |
| 65 | Records: | |
| 66 | - Kind: S_GPROC32_ID | |
| 67 | ProcSym: | |
| 68 | CodeSize: 8 | |
| 69 | DbgStart: 5 | |
| 70 | DbgEnd: 7 | |
| 71 | FunctionType: 4172 | |
| 72 | Flags: [ ] | |
| 73 | DisplayName: 'A::f' | |
| 74 | - Kind: S_FRAMEPROC | |
| 75 | FrameProcSym: | |
| 76 | TotalFrameBytes: 0 | |
| 77 | PaddingFrameBytes: 0 | |
| 78 | OffsetToPadding: 0 | |
| 79 | BytesOfCalleeSavedRegisters: 0 | |
| 80 | OffsetOfExceptionHandler: 0 | |
| 81 | SectionIdOfExceptionHandler: 0 | |
| 82 | Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] | |
| 83 | - Kind: S_REGREL32 | |
| 84 | RegRelativeSym: | |
| 85 | Offset: 8 | |
| 86 | Type: 4097 | |
| 87 | Register: RSP | |
| 88 | VarName: this | |
| 89 | - Kind: S_PROC_ID_END | |
| 90 | ScopeEndSym: | |
| 91 | - !Lines | |
| 92 | CodeSize: 8 | |
| 93 | Flags: [ ] | |
| 94 | RelocOffset: 0 | |
| 95 | RelocSegment: 0 | |
| 96 | Blocks: | |
| 97 | - FileName: 'c:\src\llvm-project\build\t.cpp' | |
| 98 | Lines: | |
| 99 | - Offset: 0 | |
| 100 | LineStart: 12 | |
| 101 | IsStatement: true | |
| 102 | EndDelta: 0 | |
| 103 | Columns: | |
| 104 | - !Symbols | |
| 105 | Records: | |
| 106 | - Kind: S_GPROC32_ID | |
| 107 | ProcSym: | |
| 108 | CodeSize: 8 | |
| 109 | DbgStart: 5 | |
| 110 | DbgEnd: 7 | |
| 111 | FunctionType: 4173 | |
| 112 | Flags: [ ] | |
| 113 | DisplayName: 'B::f' | |
| 114 | - Kind: S_FRAMEPROC | |
| 115 | FrameProcSym: | |
| 116 | TotalFrameBytes: 0 | |
| 117 | PaddingFrameBytes: 0 | |
| 118 | OffsetToPadding: 0 | |
| 119 | BytesOfCalleeSavedRegisters: 0 | |
| 120 | OffsetOfExceptionHandler: 0 | |
| 121 | SectionIdOfExceptionHandler: 0 | |
| 122 | Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] | |
| 123 | - Kind: S_REGREL32 | |
| 124 | RegRelativeSym: | |
| 125 | Offset: 8 | |
| 126 | Type: 4121 | |
| 127 | Register: RSP | |
| 128 | VarName: this | |
| 129 | - Kind: S_PROC_ID_END | |
| 130 | ScopeEndSym: | |
| 131 | - !Lines | |
| 132 | CodeSize: 8 | |
| 133 | Flags: [ ] | |
| 134 | RelocOffset: 0 | |
| 135 | RelocSegment: 0 | |
| 136 | Blocks: | |
| 137 | - FileName: 'c:\src\llvm-project\build\t.cpp' | |
| 138 | Lines: | |
| 139 | - Offset: 0 | |
| 140 | LineStart: 13 | |
| 141 | IsStatement: true | |
| 142 | EndDelta: 0 | |
| 143 | Columns: | |
| 144 | - !Symbols | |
| 145 | Records: | |
| 146 | - Kind: S_GPROC32_ID | |
| 147 | ProcSym: | |
| 148 | CodeSize: 89 | |
| 149 | DbgStart: 9 | |
| 150 | DbgEnd: 84 | |
| 151 | FunctionType: 4175 | |
| 152 | Flags: [ ] | |
| 153 | DisplayName: 'C::C' | |
| 154 | - Kind: S_FRAMEPROC | |
| 155 | FrameProcSym: | |
| 156 | TotalFrameBytes: 40 | |
| 157 | PaddingFrameBytes: 0 | |
| 158 | OffsetToPadding: 0 | |
| 159 | BytesOfCalleeSavedRegisters: 0 | |
| 160 | OffsetOfExceptionHandler: 0 | |
| 161 | SectionIdOfExceptionHandler: 0 | |
| 162 | Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] | |
| 163 | - Kind: S_REGREL32 | |
| 164 | RegRelativeSym: | |
| 165 | Offset: 48 | |
| 166 | Type: 4143 | |
| 167 | Register: RSP | |
| 168 | VarName: this | |
| 169 | - Kind: S_PROC_ID_END | |
| 170 | ScopeEndSym: | |
| 171 | - !Lines | |
| 172 | CodeSize: 89 | |
| 173 | Flags: [ ] | |
| 174 | RelocOffset: 0 | |
| 175 | RelocSegment: 0 | |
| 176 | Blocks: | |
| 177 | - FileName: 'c:\src\llvm-project\build\t.cpp' | |
| 178 | Lines: | |
| 179 | - Offset: 0 | |
| 180 | LineStart: 15 | |
| 181 | IsStatement: true | |
| 182 | EndDelta: 0 | |
| 183 | - Offset: 67 | |
| 184 | LineStart: 15 | |
| 185 | IsStatement: true | |
| 186 | EndDelta: 0 | |
| 187 | Columns: | |
| 188 | - !Symbols | |
| 189 | Records: | |
| 190 | - Kind: S_GPROC32_ID | |
| 191 | ProcSym: | |
| 192 | CodeSize: 14 | |
| 193 | DbgStart: 5 | |
| 194 | DbgEnd: 13 | |
| 195 | FunctionType: 4174 | |
| 196 | Flags: [ ] | |
| 197 | DisplayName: 'C::f' | |
| 198 | - Kind: S_FRAMEPROC | |
| 199 | FrameProcSym: | |
| 200 | TotalFrameBytes: 0 | |
| 201 | PaddingFrameBytes: 0 | |
| 202 | OffsetToPadding: 0 | |
| 203 | BytesOfCalleeSavedRegisters: 0 | |
| 204 | OffsetOfExceptionHandler: 0 | |
| 205 | SectionIdOfExceptionHandler: 0 | |
| 206 | Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] | |
| 207 | - Kind: S_REGREL32 | |
| 208 | RegRelativeSym: | |
| 209 | Offset: 8 | |
| 210 | Type: 4143 | |
| 211 | Register: RSP | |
| 212 | VarName: this | |
| 213 | - Kind: S_PROC_ID_END | |
| 214 | ScopeEndSym: | |
| 215 | - !Lines | |
| 216 | CodeSize: 14 | |
| 217 | Flags: [ ] | |
| 218 | RelocOffset: 0 | |
| 219 | RelocSegment: 0 | |
| 220 | Blocks: | |
| 221 | - FileName: 'c:\src\llvm-project\build\t.cpp' | |
| 222 | Lines: | |
| 223 | - Offset: 0 | |
| 224 | LineStart: 14 | |
| 225 | IsStatement: true | |
| 226 | EndDelta: 0 | |
| 227 | Columns: | |
| 228 | - !Symbols | |
| 229 | Records: | |
| 230 | - Kind: S_UDT | |
| 231 | UDTSym: | |
| 232 | Type: 4117 | |
| 233 | UDTName: A | |
| 234 | - Kind: S_UDT | |
| 235 | UDTSym: | |
| 236 | Type: 4268 | |
| 237 | UDTName: '__vc_attributes::event_sourceAttribute' | |
| 238 | - Kind: S_UDT | |
| 239 | UDTSym: | |
| 240 | Type: 4260 | |
| 241 | UDTName: '__vc_attributes::event_sourceAttribute::optimize_e' | |
| 242 | - Kind: S_UDT | |
| 243 | UDTSym: | |
| 244 | Type: 4257 | |
| 245 | UDTName: '__vc_attributes::event_sourceAttribute::type_e' | |
| 246 | - Kind: S_UDT | |
| 247 | UDTSym: | |
| 248 | Type: 4253 | |
| 249 | UDTName: '__vc_attributes::helper_attributes::v1_alttypeAttribute' | |
| 250 | - Kind: S_UDT | |
| 251 | UDTSym: | |
| 252 | Type: 4247 | |
| 253 | UDTName: '__vc_attributes::helper_attributes::v1_alttypeAttribute::type_e' | |
| 254 | - Kind: S_UDT | |
| 255 | UDTSym: | |
| 256 | Type: 4243 | |
| 257 | UDTName: '__vc_attributes::helper_attributes::usageAttribute' | |
| 258 | - Kind: S_UDT | |
| 259 | UDTSym: | |
| 260 | Type: 4237 | |
| 261 | UDTName: '__vc_attributes::helper_attributes::usageAttribute::usage_e' | |
| 262 | - Kind: S_UDT | |
| 263 | UDTSym: | |
| 264 | Type: 4233 | |
| 265 | UDTName: '__vc_attributes::threadingAttribute' | |
| 266 | - Kind: S_UDT | |
| 267 | UDTSym: | |
| 268 | Type: 4225 | |
| 269 | UDTName: '__vc_attributes::threadingAttribute::threading_e' | |
| 270 | - Kind: S_UDT | |
| 271 | UDTSym: | |
| 272 | Type: 4221 | |
| 273 | UDTName: '__vc_attributes::aggregatableAttribute' | |
| 274 | - Kind: S_UDT | |
| 275 | UDTSym: | |
| 276 | Type: 4213 | |
| 277 | UDTName: '__vc_attributes::aggregatableAttribute::type_e' | |
| 278 | - Kind: S_UDT | |
| 279 | UDTSym: | |
| 280 | Type: 4209 | |
| 281 | UDTName: '__vc_attributes::event_receiverAttribute' | |
| 282 | - Kind: S_UDT | |
| 283 | UDTSym: | |
| 284 | Type: 4199 | |
| 285 | UDTName: '__vc_attributes::event_receiverAttribute::type_e' | |
| 286 | - Kind: S_UDT | |
| 287 | UDTSym: | |
| 288 | Type: 4195 | |
| 289 | UDTName: '__vc_attributes::moduleAttribute' | |
| 290 | - Kind: S_UDT | |
| 291 | UDTSym: | |
| 292 | Type: 4182 | |
| 293 | UDTName: '__vc_attributes::moduleAttribute::type_e' | |
| 294 | - Kind: S_UDT | |
| 295 | UDTSym: | |
| 296 | Type: 4160 | |
| 297 | UDTName: C | |
| 298 | - Kind: S_UDT | |
| 299 | UDTSym: | |
| 300 | Type: 4140 | |
| 301 | UDTName: B | |
| 302 | - !FileChecksums | |
| 303 | Checksums: | |
| 304 | - FileName: 'c:\src\llvm-project\build\t.cpp' | |
| 305 | Kind: MD5 | |
| 306 | Checksum: 1E487A6B7D4DB0A502F8E5945CCB70D1 | |
| 307 | - !StringTable | |
| 308 | Strings: | |
| 309 | - 'c:\src\llvm-project\build\t.cpp' | |
| 310 | - !Symbols | |
| 311 | Records: | |
| 312 | - Kind: S_BUILDINFO | |
| 313 | BuildInfoSym: | |
| 314 | BuildId: 4281 | |
| 315 | Relocations: | |
| 316 | - VirtualAddress: 152 | |
| 317 | SymbolName: '?f@A@@UEAAHXZ' | |
| 318 | Type: IMAGE_REL_AMD64_SECREL | |
| 319 | - VirtualAddress: 156 | |
| 320 | SymbolName: '?f@A@@UEAAHXZ' | |
| 321 | Type: IMAGE_REL_AMD64_SECTION | |
| 322 | - VirtualAddress: 228 | |
| 323 | SymbolName: '?f@A@@UEAAHXZ' | |
| 324 | Type: IMAGE_REL_AMD64_SECREL | |
| 325 | - VirtualAddress: 232 | |
| 326 | SymbolName: '?f@A@@UEAAHXZ' | |
| 327 | Type: IMAGE_REL_AMD64_SECTION | |
| 328 | - VirtualAddress: 300 | |
| 329 | SymbolName: '?f@B@@UEAAHXZ' | |
| 330 | Type: IMAGE_REL_AMD64_SECREL | |
| 331 | - VirtualAddress: 304 | |
| 332 | SymbolName: '?f@B@@UEAAHXZ' | |
| 333 | Type: IMAGE_REL_AMD64_SECTION | |
| 334 | - VirtualAddress: 376 | |
| 335 | SymbolName: '?f@B@@UEAAHXZ' | |
| 336 | Type: IMAGE_REL_AMD64_SECREL | |
| 337 | - VirtualAddress: 380 | |
| 338 | SymbolName: '?f@B@@UEAAHXZ' | |
| 339 | Type: IMAGE_REL_AMD64_SECTION | |
| 340 | - VirtualAddress: 448 | |
| 341 | SymbolName: '??0C@@QEAA@XZ' | |
| 342 | Type: IMAGE_REL_AMD64_SECREL | |
| 343 | - VirtualAddress: 452 | |
| 344 | SymbolName: '??0C@@QEAA@XZ' | |
| 345 | Type: IMAGE_REL_AMD64_SECTION | |
| 346 | - VirtualAddress: 524 | |
| 347 | SymbolName: '??0C@@QEAA@XZ' | |
| 348 | Type: IMAGE_REL_AMD64_SECREL | |
| 349 | - VirtualAddress: 528 | |
| 350 | SymbolName: '??0C@@QEAA@XZ' | |
| 351 | Type: IMAGE_REL_AMD64_SECTION | |
| 352 | - VirtualAddress: 604 | |
| 353 | SymbolName: '?f@C@@UEAAHXZ' | |
| 354 | Type: IMAGE_REL_AMD64_SECREL | |
| 355 | - VirtualAddress: 608 | |
| 356 | SymbolName: '?f@C@@UEAAHXZ' | |
| 357 | Type: IMAGE_REL_AMD64_SECTION | |
| 358 | - VirtualAddress: 680 | |
| 359 | SymbolName: '?f@C@@UEAAHXZ' | |
| 360 | Type: IMAGE_REL_AMD64_SECREL | |
| 361 | - VirtualAddress: 684 | |
| 362 | SymbolName: '?f@C@@UEAAHXZ' | |
| 363 | Type: IMAGE_REL_AMD64_SECTION | |
| 364 | - Name: '.debug$T' | |
| 365 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 366 | Alignment: 1 | |
| 367 | Types: | |
| 368 | - Kind: LF_STRUCTURE | |
| 369 | Class: | |
| 370 | MemberCount: 0 | |
| 371 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 372 | FieldList: 0 | |
| 373 | Name: A | |
| 374 | UniqueName: '.?AUA@@' | |
| 375 | DerivationList: 0 | |
| 376 | VTableShape: 0 | |
| 377 | Size: 0 | |
| 378 | - Kind: LF_POINTER | |
| 379 | Pointer: | |
| 380 | ReferentType: 4096 | |
| 381 | Attrs: 66572 | |
| 382 | - Kind: LF_VTSHAPE | |
| 383 | VFTableShape: | |
| 384 | Slots: | |
| 385 | - Near16 | |
| 386 | - Kind: LF_POINTER | |
| 387 | Pointer: | |
| 388 | ReferentType: 4098 | |
| 389 | Attrs: 65548 | |
| 390 | - Kind: LF_ARGLIST | |
| 391 | ArgList: | |
| 392 | ArgIndices: [ ] | |
| 393 | - Kind: LF_MFUNCTION | |
| 394 | MemberFunction: | |
| 395 | ReturnType: 116 | |
| 396 | ClassType: 4096 | |
| 397 | ThisType: 4097 | |
| 398 | CallConv: NearC | |
| 399 | Options: [ None ] | |
| 400 | ParameterCount: 0 | |
| 401 | ArgumentList: 4100 | |
| 402 | ThisPointerAdjustment: 0 | |
| 403 | - Kind: LF_POINTER | |
| 404 | Pointer: | |
| 405 | ReferentType: 4096 | |
| 406 | Attrs: 65676 | |
| 407 | - Kind: LF_ARGLIST | |
| 408 | ArgList: | |
| 409 | ArgIndices: [ 4102 ] | |
| 410 | - Kind: LF_MFUNCTION | |
| 411 | MemberFunction: | |
| 412 | ReturnType: 3 | |
| 413 | ClassType: 4096 | |
| 414 | ThisType: 4097 | |
| 415 | CallConv: NearC | |
| 416 | Options: [ None, Constructor ] | |
| 417 | ParameterCount: 1 | |
| 418 | ArgumentList: 4103 | |
| 419 | ThisPointerAdjustment: 0 | |
| 420 | - Kind: LF_MODIFIER | |
| 421 | Modifier: | |
| 422 | ModifiedType: 4096 | |
| 423 | Modifiers: [ None, Const ] | |
| 424 | - Kind: LF_POINTER | |
| 425 | Pointer: | |
| 426 | ReferentType: 4105 | |
| 427 | Attrs: 65580 | |
| 428 | - Kind: LF_ARGLIST | |
| 429 | ArgList: | |
| 430 | ArgIndices: [ 4106 ] | |
| 431 | - Kind: LF_MFUNCTION | |
| 432 | MemberFunction: | |
| 433 | ReturnType: 3 | |
| 434 | ClassType: 4096 | |
| 435 | ThisType: 4097 | |
| 436 | CallConv: NearC | |
| 437 | Options: [ None, Constructor ] | |
| 438 | ParameterCount: 1 | |
| 439 | ArgumentList: 4107 | |
| 440 | ThisPointerAdjustment: 0 | |
| 441 | - Kind: LF_MFUNCTION | |
| 442 | MemberFunction: | |
| 443 | ReturnType: 3 | |
| 444 | ClassType: 4096 | |
| 445 | ThisType: 4097 | |
| 446 | CallConv: NearC | |
| 447 | Options: [ None, Constructor ] | |
| 448 | ParameterCount: 0 | |
| 449 | ArgumentList: 4100 | |
| 450 | ThisPointerAdjustment: 0 | |
| 451 | - Kind: LF_METHODLIST | |
| 452 | MethodOverloadList: | |
| 453 | Methods: | |
| 454 | - Type: 4104 | |
| 455 | Attrs: 259 | |
| 456 | VFTableOffset: -1 | |
| 457 | Name: '' | |
| 458 | - Type: 4108 | |
| 459 | Attrs: 259 | |
| 460 | VFTableOffset: -1 | |
| 461 | Name: '' | |
| 462 | - Type: 4109 | |
| 463 | Attrs: 259 | |
| 464 | VFTableOffset: -1 | |
| 465 | Name: '' | |
| 466 | - Kind: LF_POINTER | |
| 467 | Pointer: | |
| 468 | ReferentType: 4096 | |
| 469 | Attrs: 65580 | |
| 470 | - Kind: LF_MFUNCTION | |
| 471 | MemberFunction: | |
| 472 | ReturnType: 4111 | |
| 473 | ClassType: 4096 | |
| 474 | ThisType: 4097 | |
| 475 | CallConv: NearC | |
| 476 | Options: [ None ] | |
| 477 | ParameterCount: 1 | |
| 478 | ArgumentList: 4103 | |
| 479 | ThisPointerAdjustment: 0 | |
| 480 | - Kind: LF_MFUNCTION | |
| 481 | MemberFunction: | |
| 482 | ReturnType: 4111 | |
| 483 | ClassType: 4096 | |
| 484 | ThisType: 4097 | |
| 485 | CallConv: NearC | |
| 486 | Options: [ None ] | |
| 487 | ParameterCount: 1 | |
| 488 | ArgumentList: 4107 | |
| 489 | ThisPointerAdjustment: 0 | |
| 490 | - Kind: LF_METHODLIST | |
| 491 | MethodOverloadList: | |
| 492 | Methods: | |
| 493 | - Type: 4112 | |
| 494 | Attrs: 259 | |
| 495 | VFTableOffset: -1 | |
| 496 | Name: '' | |
| 497 | - Type: 4113 | |
| 498 | Attrs: 259 | |
| 499 | VFTableOffset: -1 | |
| 500 | Name: '' | |
| 501 | - Kind: LF_FIELDLIST | |
| 502 | FieldList: | |
| 503 | - Kind: LF_VFUNCTAB | |
| 504 | VFPtr: | |
| 505 | Type: 4099 | |
| 506 | - Kind: LF_ONEMETHOD | |
| 507 | OneMethod: | |
| 508 | Type: 4101 | |
| 509 | Attrs: 19 | |
| 510 | VFTableOffset: 0 | |
| 511 | Name: f | |
| 512 | - Kind: LF_METHOD | |
| 513 | OverloadedMethod: | |
| 514 | NumOverloads: 3 | |
| 515 | MethodList: 4110 | |
| 516 | Name: A | |
| 517 | - Kind: LF_METHOD | |
| 518 | OverloadedMethod: | |
| 519 | NumOverloads: 2 | |
| 520 | MethodList: 4114 | |
| 521 | Name: 'operator=' | |
| 522 | - Kind: LF_VTSHAPE | |
| 523 | VFTableShape: | |
| 524 | Slots: | |
| 525 | - Near16 | |
| 526 | - Kind: LF_STRUCTURE | |
| 527 | Class: | |
| 528 | MemberCount: 7 | |
| 529 | Options: [ None, HasConstructorOrDestructor, HasOverloadedOperator, HasOverloadedAssignmentOperator, HasUniqueName ] | |
| 530 | FieldList: 4115 | |
| 531 | Name: A | |
| 532 | UniqueName: '.?AUA@@' | |
| 533 | DerivationList: 0 | |
| 534 | VTableShape: 4116 | |
| 535 | Size: 8 | |
| 536 | - Kind: LF_STRING_ID | |
| 537 | StringId: | |
| 538 | Id: 0 | |
| 539 | String: 'c:\src\llvm-project\build\t.cpp' | |
| 540 | - Kind: LF_UDT_SRC_LINE | |
| 541 | UdtSourceLine: | |
| 542 | UDT: 4117 | |
| 543 | SourceFile: 4118 | |
| 544 | LineNumber: 1 | |
| 545 | - Kind: LF_STRUCTURE | |
| 546 | Class: | |
| 547 | MemberCount: 0 | |
| 548 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 549 | FieldList: 0 | |
| 550 | Name: B | |
| 551 | UniqueName: '.?AUB@@' | |
| 552 | DerivationList: 0 | |
| 553 | VTableShape: 0 | |
| 554 | Size: 0 | |
| 555 | - Kind: LF_POINTER | |
| 556 | Pointer: | |
| 557 | ReferentType: 4120 | |
| 558 | Attrs: 66572 | |
| 559 | - Kind: LF_VTSHAPE | |
| 560 | VFTableShape: | |
| 561 | Slots: | |
| 562 | - Near16 | |
| 563 | - Kind: LF_POINTER | |
| 564 | Pointer: | |
| 565 | ReferentType: 4122 | |
| 566 | Attrs: 65548 | |
| 567 | - Kind: LF_MFUNCTION | |
| 568 | MemberFunction: | |
| 569 | ReturnType: 116 | |
| 570 | ClassType: 4120 | |
| 571 | ThisType: 4121 | |
| 572 | CallConv: NearC | |
| 573 | Options: [ None ] | |
| 574 | ParameterCount: 0 | |
| 575 | ArgumentList: 4100 | |
| 576 | ThisPointerAdjustment: 0 | |
| 577 | - Kind: LF_POINTER | |
| 578 | Pointer: | |
| 579 | ReferentType: 4120 | |
| 580 | Attrs: 65676 | |
| 581 | - Kind: LF_ARGLIST | |
| 582 | ArgList: | |
| 583 | ArgIndices: [ 4125 ] | |
| 584 | - Kind: LF_MFUNCTION | |
| 585 | MemberFunction: | |
| 586 | ReturnType: 3 | |
| 587 | ClassType: 4120 | |
| 588 | ThisType: 4121 | |
| 589 | CallConv: NearC | |
| 590 | Options: [ None, Constructor ] | |
| 591 | ParameterCount: 1 | |
| 592 | ArgumentList: 4126 | |
| 593 | ThisPointerAdjustment: 0 | |
| 594 | - Kind: LF_MODIFIER | |
| 595 | Modifier: | |
| 596 | ModifiedType: 4120 | |
| 597 | Modifiers: [ None, Const ] | |
| 598 | - Kind: LF_POINTER | |
| 599 | Pointer: | |
| 600 | ReferentType: 4128 | |
| 601 | Attrs: 65580 | |
| 602 | - Kind: LF_ARGLIST | |
| 603 | ArgList: | |
| 604 | ArgIndices: [ 4129 ] | |
| 605 | - Kind: LF_MFUNCTION | |
| 606 | MemberFunction: | |
| 607 | ReturnType: 3 | |
| 608 | ClassType: 4120 | |
| 609 | ThisType: 4121 | |
| 610 | CallConv: NearC | |
| 611 | Options: [ None, Constructor ] | |
| 612 | ParameterCount: 1 | |
| 613 | ArgumentList: 4130 | |
| 614 | ThisPointerAdjustment: 0 | |
| 615 | - Kind: LF_MFUNCTION | |
| 616 | MemberFunction: | |
| 617 | ReturnType: 3 | |
| 618 | ClassType: 4120 | |
| 619 | ThisType: 4121 | |
| 620 | CallConv: NearC | |
| 621 | Options: [ None, Constructor ] | |
| 622 | ParameterCount: 0 | |
| 623 | ArgumentList: 4100 | |
| 624 | ThisPointerAdjustment: 0 | |
| 625 | - Kind: LF_METHODLIST | |
| 626 | MethodOverloadList: | |
| 627 | Methods: | |
| 628 | - Type: 4127 | |
| 629 | Attrs: 259 | |
| 630 | VFTableOffset: -1 | |
| 631 | Name: '' | |
| 632 | - Type: 4131 | |
| 633 | Attrs: 259 | |
| 634 | VFTableOffset: -1 | |
| 635 | Name: '' | |
| 636 | - Type: 4132 | |
| 637 | Attrs: 259 | |
| 638 | VFTableOffset: -1 | |
| 639 | Name: '' | |
| 640 | - Kind: LF_POINTER | |
| 641 | Pointer: | |
| 642 | ReferentType: 4120 | |
| 643 | Attrs: 65580 | |
| 644 | - Kind: LF_MFUNCTION | |
| 645 | MemberFunction: | |
| 646 | ReturnType: 4134 | |
| 647 | ClassType: 4120 | |
| 648 | ThisType: 4121 | |
| 649 | CallConv: NearC | |
| 650 | Options: [ None ] | |
| 651 | ParameterCount: 1 | |
| 652 | ArgumentList: 4126 | |
| 653 | ThisPointerAdjustment: 0 | |
| 654 | - Kind: LF_MFUNCTION | |
| 655 | MemberFunction: | |
| 656 | ReturnType: 4134 | |
| 657 | ClassType: 4120 | |
| 658 | ThisType: 4121 | |
| 659 | CallConv: NearC | |
| 660 | Options: [ None ] | |
| 661 | ParameterCount: 1 | |
| 662 | ArgumentList: 4130 | |
| 663 | ThisPointerAdjustment: 0 | |
| 664 | - Kind: LF_METHODLIST | |
| 665 | MethodOverloadList: | |
| 666 | Methods: | |
| 667 | - Type: 4135 | |
| 668 | Attrs: 259 | |
| 669 | VFTableOffset: -1 | |
| 670 | Name: '' | |
| 671 | - Type: 4136 | |
| 672 | Attrs: 259 | |
| 673 | VFTableOffset: -1 | |
| 674 | Name: '' | |
| 675 | - Kind: LF_FIELDLIST | |
| 676 | FieldList: | |
| 677 | - Kind: LF_VFUNCTAB | |
| 678 | VFPtr: | |
| 679 | Type: 4123 | |
| 680 | - Kind: LF_ONEMETHOD | |
| 681 | OneMethod: | |
| 682 | Type: 4124 | |
| 683 | Attrs: 19 | |
| 684 | VFTableOffset: 0 | |
| 685 | Name: f | |
| 686 | - Kind: LF_METHOD | |
| 687 | OverloadedMethod: | |
| 688 | NumOverloads: 3 | |
| 689 | MethodList: 4133 | |
| 690 | Name: B | |
| 691 | - Kind: LF_METHOD | |
| 692 | OverloadedMethod: | |
| 693 | NumOverloads: 2 | |
| 694 | MethodList: 4137 | |
| 695 | Name: 'operator=' | |
| 696 | - Kind: LF_VTSHAPE | |
| 697 | VFTableShape: | |
| 698 | Slots: | |
| 699 | - Near16 | |
| 700 | - Kind: LF_STRUCTURE | |
| 701 | Class: | |
| 702 | MemberCount: 7 | |
| 703 | Options: [ None, HasConstructorOrDestructor, HasOverloadedOperator, HasOverloadedAssignmentOperator, HasUniqueName ] | |
| 704 | FieldList: 4138 | |
| 705 | Name: B | |
| 706 | UniqueName: '.?AUB@@' | |
| 707 | DerivationList: 0 | |
| 708 | VTableShape: 4139 | |
| 709 | Size: 8 | |
| 710 | - Kind: LF_UDT_SRC_LINE | |
| 711 | UdtSourceLine: | |
| 712 | UDT: 4140 | |
| 713 | SourceFile: 4118 | |
| 714 | LineNumber: 4 | |
| 715 | - Kind: LF_STRUCTURE | |
| 716 | Class: | |
| 717 | MemberCount: 0 | |
| 718 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 719 | FieldList: 0 | |
| 720 | Name: C | |
| 721 | UniqueName: '.?AUC@@' | |
| 722 | DerivationList: 0 | |
| 723 | VTableShape: 0 | |
| 724 | Size: 0 | |
| 725 | - Kind: LF_POINTER | |
| 726 | Pointer: | |
| 727 | ReferentType: 4142 | |
| 728 | Attrs: 66572 | |
| 729 | - Kind: LF_POINTER | |
| 730 | Pointer: | |
| 731 | ReferentType: 4142 | |
| 732 | Attrs: 65676 | |
| 733 | - Kind: LF_ARGLIST | |
| 734 | ArgList: | |
| 735 | ArgIndices: [ 4144 ] | |
| 736 | - Kind: LF_MFUNCTION | |
| 737 | MemberFunction: | |
| 738 | ReturnType: 3 | |
| 739 | ClassType: 4142 | |
| 740 | ThisType: 4143 | |
| 741 | CallConv: NearC | |
| 742 | Options: [ None, Constructor ] | |
| 743 | ParameterCount: 1 | |
| 744 | ArgumentList: 4145 | |
| 745 | ThisPointerAdjustment: 0 | |
| 746 | - Kind: LF_MODIFIER | |
| 747 | Modifier: | |
| 748 | ModifiedType: 4142 | |
| 749 | Modifiers: [ None, Const ] | |
| 750 | - Kind: LF_POINTER | |
| 751 | Pointer: | |
| 752 | ReferentType: 4147 | |
| 753 | Attrs: 65580 | |
| 754 | - Kind: LF_ARGLIST | |
| 755 | ArgList: | |
| 756 | ArgIndices: [ 4148 ] | |
| 757 | - Kind: LF_MFUNCTION | |
| 758 | MemberFunction: | |
| 759 | ReturnType: 3 | |
| 760 | ClassType: 4142 | |
| 761 | ThisType: 4143 | |
| 762 | CallConv: NearC | |
| 763 | Options: [ None, Constructor ] | |
| 764 | ParameterCount: 1 | |
| 765 | ArgumentList: 4149 | |
| 766 | ThisPointerAdjustment: 0 | |
| 767 | - Kind: LF_MFUNCTION | |
| 768 | MemberFunction: | |
| 769 | ReturnType: 3 | |
| 770 | ClassType: 4142 | |
| 771 | ThisType: 4143 | |
| 772 | CallConv: NearC | |
| 773 | Options: [ None, Constructor ] | |
| 774 | ParameterCount: 0 | |
| 775 | ArgumentList: 4100 | |
| 776 | ThisPointerAdjustment: 0 | |
| 777 | - Kind: LF_METHODLIST | |
| 778 | MethodOverloadList: | |
| 779 | Methods: | |
| 780 | - Type: 4146 | |
| 781 | Attrs: 259 | |
| 782 | VFTableOffset: -1 | |
| 783 | Name: '' | |
| 784 | - Type: 4150 | |
| 785 | Attrs: 259 | |
| 786 | VFTableOffset: -1 | |
| 787 | Name: '' | |
| 788 | - Type: 4151 | |
| 789 | Attrs: 3 | |
| 790 | VFTableOffset: -1 | |
| 791 | Name: '' | |
| 792 | - Kind: LF_MFUNCTION | |
| 793 | MemberFunction: | |
| 794 | ReturnType: 116 | |
| 795 | ClassType: 4142 | |
| 796 | ThisType: 4143 | |
| 797 | CallConv: NearC | |
| 798 | Options: [ None ] | |
| 799 | ParameterCount: 0 | |
| 800 | ArgumentList: 4100 | |
| 801 | ThisPointerAdjustment: 0 | |
| 802 | - Kind: LF_POINTER | |
| 803 | Pointer: | |
| 804 | ReferentType: 4142 | |
| 805 | Attrs: 65580 | |
| 806 | - Kind: LF_MFUNCTION | |
| 807 | MemberFunction: | |
| 808 | ReturnType: 4154 | |
| 809 | ClassType: 4142 | |
| 810 | ThisType: 4143 | |
| 811 | CallConv: NearC | |
| 812 | Options: [ None ] | |
| 813 | ParameterCount: 1 | |
| 814 | ArgumentList: 4145 | |
| 815 | ThisPointerAdjustment: 0 | |
| 816 | - Kind: LF_MFUNCTION | |
| 817 | MemberFunction: | |
| 818 | ReturnType: 4154 | |
| 819 | ClassType: 4142 | |
| 820 | ThisType: 4143 | |
| 821 | CallConv: NearC | |
| 822 | Options: [ None ] | |
| 823 | ParameterCount: 1 | |
| 824 | ArgumentList: 4149 | |
| 825 | ThisPointerAdjustment: 0 | |
| 826 | - Kind: LF_METHODLIST | |
| 827 | MethodOverloadList: | |
| 828 | Methods: | |
| 829 | - Type: 4155 | |
| 830 | Attrs: 259 | |
| 831 | VFTableOffset: -1 | |
| 832 | Name: '' | |
| 833 | - Type: 4156 | |
| 834 | Attrs: 259 | |
| 835 | VFTableOffset: -1 | |
| 836 | Name: '' | |
| 837 | - Kind: LF_FIELDLIST | |
| 838 | FieldList: | |
| 839 | - Kind: LF_BCLASS | |
| 840 | BaseClass: | |
| 841 | Attrs: 3 | |
| 842 | Type: 4096 | |
| 843 | Offset: 0 | |
| 844 | - Kind: LF_BCLASS | |
| 845 | BaseClass: | |
| 846 | Attrs: 3 | |
| 847 | Type: 4120 | |
| 848 | Offset: 8 | |
| 849 | - Kind: LF_METHOD | |
| 850 | OverloadedMethod: | |
| 851 | NumOverloads: 3 | |
| 852 | MethodList: 4152 | |
| 853 | Name: C | |
| 854 | - Kind: LF_ONEMETHOD | |
| 855 | OneMethod: | |
| 856 | Type: 4153 | |
| 857 | Attrs: 7 | |
| 858 | VFTableOffset: -1 | |
| 859 | Name: f | |
| 860 | - Kind: LF_MEMBER | |
| 861 | DataMember: | |
| 862 | Attrs: 3 | |
| 863 | Type: 116 | |
| 864 | FieldOffset: 16 | |
| 865 | Name: c | |
| 866 | - Kind: LF_METHOD | |
| 867 | OverloadedMethod: | |
| 868 | NumOverloads: 2 | |
| 869 | MethodList: 4157 | |
| 870 | Name: 'operator=' | |
| 871 | - Kind: LF_VTSHAPE | |
| 872 | VFTableShape: | |
| 873 | Slots: | |
| 874 | - Near16 | |
| 875 | - Kind: LF_STRUCTURE | |
| 876 | Class: | |
| 877 | MemberCount: 9 | |
| 878 | Options: [ None, HasConstructorOrDestructor, HasOverloadedOperator, HasOverloadedAssignmentOperator, HasUniqueName ] | |
| 879 | FieldList: 4158 | |
| 880 | Name: C | |
| 881 | UniqueName: '.?AUC@@' | |
| 882 | DerivationList: 0 | |
| 883 | VTableShape: 4159 | |
| 884 | Size: 24 | |
| 885 | - Kind: LF_UDT_SRC_LINE | |
| 886 | UdtSourceLine: | |
| 887 | UDT: 4160 | |
| 888 | SourceFile: 4118 | |
| 889 | LineNumber: 7 | |
| 890 | - Kind: LF_POINTER | |
| 891 | Pointer: | |
| 892 | ReferentType: 4142 | |
| 893 | Attrs: 65548 | |
| 894 | - Kind: LF_MFUNCTION | |
| 895 | MemberFunction: | |
| 896 | ReturnType: 3 | |
| 897 | ClassType: 4142 | |
| 898 | ThisType: 4143 | |
| 899 | CallConv: NearC | |
| 900 | Options: [ None ] | |
| 901 | ParameterCount: 0 | |
| 902 | ArgumentList: 4100 | |
| 903 | ThisPointerAdjustment: 0 | |
| 904 | - Kind: LF_POINTER | |
| 905 | Pointer: | |
| 906 | ReferentType: 4096 | |
| 907 | Attrs: 65548 | |
| 908 | - Kind: LF_MFUNCTION | |
| 909 | MemberFunction: | |
| 910 | ReturnType: 3 | |
| 911 | ClassType: 4096 | |
| 912 | ThisType: 4097 | |
| 913 | CallConv: NearC | |
| 914 | Options: [ None ] | |
| 915 | ParameterCount: 0 | |
| 916 | ArgumentList: 4100 | |
| 917 | ThisPointerAdjustment: 0 | |
| 918 | - Kind: LF_POINTER | |
| 919 | Pointer: | |
| 920 | ReferentType: 4120 | |
| 921 | Attrs: 65548 | |
| 922 | - Kind: LF_MFUNCTION | |
| 923 | MemberFunction: | |
| 924 | ReturnType: 3 | |
| 925 | ClassType: 4120 | |
| 926 | ThisType: 4121 | |
| 927 | CallConv: NearC | |
| 928 | Options: [ None ] | |
| 929 | ParameterCount: 0 | |
| 930 | ArgumentList: 4100 | |
| 931 | ThisPointerAdjustment: 0 | |
| 932 | - Kind: LF_PROCEDURE | |
| 933 | Procedure: | |
| 934 | ReturnType: 3 | |
| 935 | CallConv: NearC | |
| 936 | Options: [ None ] | |
| 937 | ParameterCount: 0 | |
| 938 | ArgumentList: 4100 | |
| 939 | - Kind: LF_POINTER | |
| 940 | Pointer: | |
| 941 | ReferentType: 4168 | |
| 942 | Attrs: 66572 | |
| 943 | - Kind: LF_POINTER | |
| 944 | Pointer: | |
| 945 | ReferentType: 4169 | |
| 946 | Attrs: 65548 | |
| 947 | - Kind: LF_POINTER | |
| 948 | Pointer: | |
| 949 | ReferentType: 4170 | |
| 950 | Attrs: 65548 | |
| 951 | - Kind: LF_MFUNC_ID | |
| 952 | MemberFuncId: | |
| 953 | ClassType: 4096 | |
| 954 | FunctionType: 4101 | |
| 955 | Name: f | |
| 956 | - Kind: LF_MFUNC_ID | |
| 957 | MemberFuncId: | |
| 958 | ClassType: 4120 | |
| 959 | FunctionType: 4124 | |
| 960 | Name: f | |
| 961 | - Kind: LF_MFUNC_ID | |
| 962 | MemberFuncId: | |
| 963 | ClassType: 4142 | |
| 964 | FunctionType: 4153 | |
| 965 | Name: f | |
| 966 | - Kind: LF_MFUNC_ID | |
| 967 | MemberFuncId: | |
| 968 | ClassType: 4142 | |
| 969 | FunctionType: 4151 | |
| 970 | Name: '{ctor}' | |
| 971 | - Kind: LF_MFUNC_ID | |
| 972 | MemberFuncId: | |
| 973 | ClassType: 4096 | |
| 974 | FunctionType: 4109 | |
| 975 | Name: '{ctor}' | |
| 976 | - Kind: LF_MFUNC_ID | |
| 977 | MemberFuncId: | |
| 978 | ClassType: 4120 | |
| 979 | FunctionType: 4132 | |
| 980 | Name: '{ctor}' | |
| 981 | - Kind: LF_MFUNC_ID | |
| 982 | MemberFuncId: | |
| 983 | ClassType: 4142 | |
| 984 | FunctionType: 4153 | |
| 985 | Name: f | |
| 986 | - Kind: LF_ARRAY | |
| 987 | Array: | |
| 988 | ElementType: 4169 | |
| 989 | IndexType: 35 | |
| 990 | Size: 8 | |
| 991 | Name: '' | |
| 992 | - Kind: LF_STRUCTURE | |
| 993 | Class: | |
| 994 | MemberCount: 0 | |
| 995 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 996 | FieldList: 0 | |
| 997 | Name: '__vc_attributes::moduleAttribute' | |
| 998 | UniqueName: '.?AUmoduleAttribute@__vc_attributes@@' | |
| 999 | DerivationList: 0 | |
| 1000 | VTableShape: 0 | |
| 1001 | Size: 0 | |
| 1002 | - Kind: LF_FIELDLIST | |
| 1003 | FieldList: | |
| 1004 | - Kind: LF_ENUMERATE | |
| 1005 | Enumerator: | |
| 1006 | Attrs: 3 | |
| 1007 | Value: 1 | |
| 1008 | Name: dll | |
| 1009 | - Kind: LF_ENUMERATE | |
| 1010 | Enumerator: | |
| 1011 | Attrs: 3 | |
| 1012 | Value: 2 | |
| 1013 | Name: exe | |
| 1014 | - Kind: LF_ENUMERATE | |
| 1015 | Enumerator: | |
| 1016 | Attrs: 3 | |
| 1017 | Value: 3 | |
| 1018 | Name: service | |
| 1019 | - Kind: LF_ENUMERATE | |
| 1020 | Enumerator: | |
| 1021 | Attrs: 3 | |
| 1022 | Value: 4 | |
| 1023 | Name: unspecified | |
| 1024 | - Kind: LF_ENUMERATE | |
| 1025 | Enumerator: | |
| 1026 | Attrs: 3 | |
| 1027 | Value: 2 | |
| 1028 | Name: EXE | |
| 1029 | - Kind: LF_ENUMERATE | |
| 1030 | Enumerator: | |
| 1031 | Attrs: 3 | |
| 1032 | Value: 3 | |
| 1033 | Name: SERVICE | |
| 1034 | - Kind: LF_ENUM | |
| 1035 | Enum: | |
| 1036 | NumEnumerators: 6 | |
| 1037 | Options: [ None, Nested, HasUniqueName ] | |
| 1038 | FieldList: 4181 | |
| 1039 | Name: '__vc_attributes::moduleAttribute::type_e' | |
| 1040 | UniqueName: '.?AW4type_e@moduleAttribute@__vc_attributes@@' | |
| 1041 | UnderlyingType: 116 | |
| 1042 | - Kind: LF_STRING_ID | |
| 1043 | StringId: | |
| 1044 | Id: 0 | |
| 1045 | String: 'c:\src\llvm-project\build\predefined c++ attributes (compiler internal)' | |
| 1046 | - Kind: LF_UDT_SRC_LINE | |
| 1047 | UdtSourceLine: | |
| 1048 | UDT: 4182 | |
| 1049 | SourceFile: 4183 | |
| 1050 | LineNumber: 482 | |
| 1051 | - Kind: LF_MODIFIER | |
| 1052 | Modifier: | |
| 1053 | ModifiedType: 112 | |
| 1054 | Modifiers: [ None, Const ] | |
| 1055 | - Kind: LF_POINTER | |
| 1056 | Pointer: | |
| 1057 | ReferentType: 4185 | |
| 1058 | Attrs: 65548 | |
| 1059 | - Kind: LF_ARGLIST | |
| 1060 | ArgList: | |
| 1061 | ArgIndices: [ 4182, 4186, 4186, 4186, 116, 48, 4186, 116, | |
| 1062 | 4186, 4186, 116, 48, 48, 4186, 4186 ] | |
| 1063 | - Kind: LF_POINTER | |
| 1064 | Pointer: | |
| 1065 | ReferentType: 4180 | |
| 1066 | Attrs: 66572 | |
| 1067 | - Kind: LF_MFUNCTION | |
| 1068 | MemberFunction: | |
| 1069 | ReturnType: 3 | |
| 1070 | ClassType: 4180 | |
| 1071 | ThisType: 4188 | |
| 1072 | CallConv: NearC | |
| 1073 | Options: [ None, Constructor ] | |
| 1074 | ParameterCount: 15 | |
| 1075 | ArgumentList: 4187 | |
| 1076 | ThisPointerAdjustment: 0 | |
| 1077 | - Kind: LF_ARGLIST | |
| 1078 | ArgList: | |
| 1079 | ArgIndices: [ 4182 ] | |
| 1080 | - Kind: LF_MFUNCTION | |
| 1081 | MemberFunction: | |
| 1082 | ReturnType: 3 | |
| 1083 | ClassType: 4180 | |
| 1084 | ThisType: 4188 | |
| 1085 | CallConv: NearC | |
| 1086 | Options: [ None, Constructor ] | |
| 1087 | ParameterCount: 1 | |
| 1088 | ArgumentList: 4190 | |
| 1089 | ThisPointerAdjustment: 0 | |
| 1090 | - Kind: LF_MFUNCTION | |
| 1091 | MemberFunction: | |
| 1092 | ReturnType: 3 | |
| 1093 | ClassType: 4180 | |
| 1094 | ThisType: 4188 | |
| 1095 | CallConv: NearC | |
| 1096 | Options: [ None, Constructor ] | |
| 1097 | ParameterCount: 0 | |
| 1098 | ArgumentList: 4100 | |
| 1099 | ThisPointerAdjustment: 0 | |
| 1100 | - Kind: LF_METHODLIST | |
| 1101 | MethodOverloadList: | |
| 1102 | Methods: | |
| 1103 | - Type: 4189 | |
| 1104 | Attrs: 3 | |
| 1105 | VFTableOffset: -1 | |
| 1106 | Name: '' | |
| 1107 | - Type: 4191 | |
| 1108 | Attrs: 3 | |
| 1109 | VFTableOffset: -1 | |
| 1110 | Name: '' | |
| 1111 | - Type: 4192 | |
| 1112 | Attrs: 3 | |
| 1113 | VFTableOffset: -1 | |
| 1114 | Name: '' | |
| 1115 | - Kind: LF_FIELDLIST | |
| 1116 | FieldList: | |
| 1117 | - Kind: LF_NESTTYPE | |
| 1118 | NestedType: | |
| 1119 | Type: 4182 | |
| 1120 | Name: type_e | |
| 1121 | - Kind: LF_METHOD | |
| 1122 | OverloadedMethod: | |
| 1123 | NumOverloads: 3 | |
| 1124 | MethodList: 4193 | |
| 1125 | Name: moduleAttribute | |
| 1126 | - Kind: LF_MEMBER | |
| 1127 | DataMember: | |
| 1128 | Attrs: 3 | |
| 1129 | Type: 4182 | |
| 1130 | FieldOffset: 0 | |
| 1131 | Name: type | |
| 1132 | - Kind: LF_MEMBER | |
| 1133 | DataMember: | |
| 1134 | Attrs: 3 | |
| 1135 | Type: 4186 | |
| 1136 | FieldOffset: 8 | |
| 1137 | Name: name | |
| 1138 | - Kind: LF_MEMBER | |
| 1139 | DataMember: | |
| 1140 | Attrs: 3 | |
| 1141 | Type: 4186 | |
| 1142 | FieldOffset: 16 | |
| 1143 | Name: version | |
| 1144 | - Kind: LF_MEMBER | |
| 1145 | DataMember: | |
| 1146 | Attrs: 3 | |
| 1147 | Type: 4186 | |
| 1148 | FieldOffset: 24 | |
| 1149 | Name: uuid | |
| 1150 | - Kind: LF_MEMBER | |
| 1151 | DataMember: | |
| 1152 | Attrs: 3 | |
| 1153 | Type: 116 | |
| 1154 | FieldOffset: 32 | |
| 1155 | Name: lcid | |
| 1156 | - Kind: LF_MEMBER | |
| 1157 | DataMember: | |
| 1158 | Attrs: 3 | |
| 1159 | Type: 48 | |
| 1160 | FieldOffset: 36 | |
| 1161 | Name: control | |
| 1162 | - Kind: LF_MEMBER | |
| 1163 | DataMember: | |
| 1164 | Attrs: 3 | |
| 1165 | Type: 4186 | |
| 1166 | FieldOffset: 40 | |
| 1167 | Name: helpstring | |
| 1168 | - Kind: LF_MEMBER | |
| 1169 | DataMember: | |
| 1170 | Attrs: 3 | |
| 1171 | Type: 116 | |
| 1172 | FieldOffset: 48 | |
| 1173 | Name: helpstringcontext | |
| 1174 | - Kind: LF_MEMBER | |
| 1175 | DataMember: | |
| 1176 | Attrs: 3 | |
| 1177 | Type: 4186 | |
| 1178 | FieldOffset: 56 | |
| 1179 | Name: helpstringdll | |
| 1180 | - Kind: LF_MEMBER | |
| 1181 | DataMember: | |
| 1182 | Attrs: 3 | |
| 1183 | Type: 4186 | |
| 1184 | FieldOffset: 64 | |
| 1185 | Name: helpfile | |
| 1186 | - Kind: LF_MEMBER | |
| 1187 | DataMember: | |
| 1188 | Attrs: 3 | |
| 1189 | Type: 116 | |
| 1190 | FieldOffset: 72 | |
| 1191 | Name: helpcontext | |
| 1192 | - Kind: LF_MEMBER | |
| 1193 | DataMember: | |
| 1194 | Attrs: 3 | |
| 1195 | Type: 48 | |
| 1196 | FieldOffset: 76 | |
| 1197 | Name: hidden | |
| 1198 | - Kind: LF_MEMBER | |
| 1199 | DataMember: | |
| 1200 | Attrs: 3 | |
| 1201 | Type: 48 | |
| 1202 | FieldOffset: 77 | |
| 1203 | Name: restricted | |
| 1204 | - Kind: LF_MEMBER | |
| 1205 | DataMember: | |
| 1206 | Attrs: 3 | |
| 1207 | Type: 4186 | |
| 1208 | FieldOffset: 80 | |
| 1209 | Name: custom | |
| 1210 | - Kind: LF_MEMBER | |
| 1211 | DataMember: | |
| 1212 | Attrs: 3 | |
| 1213 | Type: 4186 | |
| 1214 | FieldOffset: 88 | |
| 1215 | Name: resource_name | |
| 1216 | - Kind: LF_STRUCTURE | |
| 1217 | Class: | |
| 1218 | MemberCount: 19 | |
| 1219 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | |
| 1220 | FieldList: 4194 | |
| 1221 | Name: '__vc_attributes::moduleAttribute' | |
| 1222 | UniqueName: '.?AUmoduleAttribute@__vc_attributes@@' | |
| 1223 | DerivationList: 0 | |
| 1224 | VTableShape: 0 | |
| 1225 | Size: 96 | |
| 1226 | - Kind: LF_UDT_SRC_LINE | |
| 1227 | UdtSourceLine: | |
| 1228 | UDT: 4195 | |
| 1229 | SourceFile: 4183 | |
| 1230 | LineNumber: 481 | |
| 1231 | - Kind: LF_STRUCTURE | |
| 1232 | Class: | |
| 1233 | MemberCount: 0 | |
| 1234 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 1235 | FieldList: 0 | |
| 1236 | Name: '__vc_attributes::event_receiverAttribute' | |
| 1237 | UniqueName: '.?AUevent_receiverAttribute@__vc_attributes@@' | |
| 1238 | DerivationList: 0 | |
| 1239 | VTableShape: 0 | |
| 1240 | Size: 0 | |
| 1241 | - Kind: LF_FIELDLIST | |
| 1242 | FieldList: | |
| 1243 | - Kind: LF_ENUMERATE | |
| 1244 | Enumerator: | |
| 1245 | Attrs: 3 | |
| 1246 | Value: 0 | |
| 1247 | Name: native | |
| 1248 | - Kind: LF_ENUMERATE | |
| 1249 | Enumerator: | |
| 1250 | Attrs: 3 | |
| 1251 | Value: 1 | |
| 1252 | Name: com | |
| 1253 | - Kind: LF_ENUMERATE | |
| 1254 | Enumerator: | |
| 1255 | Attrs: 3 | |
| 1256 | Value: 2 | |
| 1257 | Name: managed | |
| 1258 | - Kind: LF_ENUM | |
| 1259 | Enum: | |
| 1260 | NumEnumerators: 3 | |
| 1261 | Options: [ None, Nested, HasUniqueName ] | |
| 1262 | FieldList: 4198 | |
| 1263 | Name: '__vc_attributes::event_receiverAttribute::type_e' | |
| 1264 | UniqueName: '.?AW4type_e@event_receiverAttribute@__vc_attributes@@' | |
| 1265 | UnderlyingType: 116 | |
| 1266 | - Kind: LF_UDT_SRC_LINE | |
| 1267 | UdtSourceLine: | |
| 1268 | UDT: 4199 | |
| 1269 | SourceFile: 4183 | |
| 1270 | LineNumber: 136 | |
| 1271 | - Kind: LF_ARGLIST | |
| 1272 | ArgList: | |
| 1273 | ArgIndices: [ 4199, 48 ] | |
| 1274 | - Kind: LF_POINTER | |
| 1275 | Pointer: | |
| 1276 | ReferentType: 4197 | |
| 1277 | Attrs: 66572 | |
| 1278 | - Kind: LF_MFUNCTION | |
| 1279 | MemberFunction: | |
| 1280 | ReturnType: 3 | |
| 1281 | ClassType: 4197 | |
| 1282 | ThisType: 4202 | |
| 1283 | CallConv: NearC | |
| 1284 | Options: [ None, Constructor ] | |
| 1285 | ParameterCount: 2 | |
| 1286 | ArgumentList: 4201 | |
| 1287 | ThisPointerAdjustment: 0 | |
| 1288 | - Kind: LF_ARGLIST | |
| 1289 | ArgList: | |
| 1290 | ArgIndices: [ 4199 ] | |
| 1291 | - Kind: LF_MFUNCTION | |
| 1292 | MemberFunction: | |
| 1293 | ReturnType: 3 | |
| 1294 | ClassType: 4197 | |
| 1295 | ThisType: 4202 | |
| 1296 | CallConv: NearC | |
| 1297 | Options: [ None, Constructor ] | |
| 1298 | ParameterCount: 1 | |
| 1299 | ArgumentList: 4204 | |
| 1300 | ThisPointerAdjustment: 0 | |
| 1301 | - Kind: LF_MFUNCTION | |
| 1302 | MemberFunction: | |
| 1303 | ReturnType: 3 | |
| 1304 | ClassType: 4197 | |
| 1305 | ThisType: 4202 | |
| 1306 | CallConv: NearC | |
| 1307 | Options: [ None, Constructor ] | |
| 1308 | ParameterCount: 0 | |
| 1309 | ArgumentList: 4100 | |
| 1310 | ThisPointerAdjustment: 0 | |
| 1311 | - Kind: LF_METHODLIST | |
| 1312 | MethodOverloadList: | |
| 1313 | Methods: | |
| 1314 | - Type: 4203 | |
| 1315 | Attrs: 3 | |
| 1316 | VFTableOffset: -1 | |
| 1317 | Name: '' | |
| 1318 | - Type: 4205 | |
| 1319 | Attrs: 3 | |
| 1320 | VFTableOffset: -1 | |
| 1321 | Name: '' | |
| 1322 | - Type: 4206 | |
| 1323 | Attrs: 3 | |
| 1324 | VFTableOffset: -1 | |
| 1325 | Name: '' | |
| 1326 | - Kind: LF_FIELDLIST | |
| 1327 | FieldList: | |
| 1328 | - Kind: LF_NESTTYPE | |
| 1329 | NestedType: | |
| 1330 | Type: 4199 | |
| 1331 | Name: type_e | |
| 1332 | - Kind: LF_METHOD | |
| 1333 | OverloadedMethod: | |
| 1334 | NumOverloads: 3 | |
| 1335 | MethodList: 4207 | |
| 1336 | Name: event_receiverAttribute | |
| 1337 | - Kind: LF_MEMBER | |
| 1338 | DataMember: | |
| 1339 | Attrs: 3 | |
| 1340 | Type: 4199 | |
| 1341 | FieldOffset: 0 | |
| 1342 | Name: type | |
| 1343 | - Kind: LF_MEMBER | |
| 1344 | DataMember: | |
| 1345 | Attrs: 3 | |
| 1346 | Type: 48 | |
| 1347 | FieldOffset: 4 | |
| 1348 | Name: layout_dependent | |
| 1349 | - Kind: LF_STRUCTURE | |
| 1350 | Class: | |
| 1351 | MemberCount: 6 | |
| 1352 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | |
| 1353 | FieldList: 4208 | |
| 1354 | Name: '__vc_attributes::event_receiverAttribute' | |
| 1355 | UniqueName: '.?AUevent_receiverAttribute@__vc_attributes@@' | |
| 1356 | DerivationList: 0 | |
| 1357 | VTableShape: 0 | |
| 1358 | Size: 8 | |
| 1359 | - Kind: LF_UDT_SRC_LINE | |
| 1360 | UdtSourceLine: | |
| 1361 | UDT: 4209 | |
| 1362 | SourceFile: 4183 | |
| 1363 | LineNumber: 135 | |
| 1364 | - Kind: LF_STRUCTURE | |
| 1365 | Class: | |
| 1366 | MemberCount: 0 | |
| 1367 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 1368 | FieldList: 0 | |
| 1369 | Name: '__vc_attributes::aggregatableAttribute' | |
| 1370 | UniqueName: '.?AUaggregatableAttribute@__vc_attributes@@' | |
| 1371 | DerivationList: 0 | |
| 1372 | VTableShape: 0 | |
| 1373 | Size: 0 | |
| 1374 | - Kind: LF_FIELDLIST | |
| 1375 | FieldList: | |
| 1376 | - Kind: LF_ENUMERATE | |
| 1377 | Enumerator: | |
| 1378 | Attrs: 3 | |
| 1379 | Value: 0 | |
| 1380 | Name: never | |
| 1381 | - Kind: LF_ENUMERATE | |
| 1382 | Enumerator: | |
| 1383 | Attrs: 3 | |
| 1384 | Value: 1 | |
| 1385 | Name: allowed | |
| 1386 | - Kind: LF_ENUMERATE | |
| 1387 | Enumerator: | |
| 1388 | Attrs: 3 | |
| 1389 | Value: 2 | |
| 1390 | Name: always | |
| 1391 | - Kind: LF_ENUM | |
| 1392 | Enum: | |
| 1393 | NumEnumerators: 3 | |
| 1394 | Options: [ None, Nested, HasUniqueName ] | |
| 1395 | FieldList: 4212 | |
| 1396 | Name: '__vc_attributes::aggregatableAttribute::type_e' | |
| 1397 | UniqueName: '.?AW4type_e@aggregatableAttribute@__vc_attributes@@' | |
| 1398 | UnderlyingType: 116 | |
| 1399 | - Kind: LF_UDT_SRC_LINE | |
| 1400 | UdtSourceLine: | |
| 1401 | UDT: 4213 | |
| 1402 | SourceFile: 4183 | |
| 1403 | LineNumber: 545 | |
| 1404 | - Kind: LF_ARGLIST | |
| 1405 | ArgList: | |
| 1406 | ArgIndices: [ 4213 ] | |
| 1407 | - Kind: LF_POINTER | |
| 1408 | Pointer: | |
| 1409 | ReferentType: 4211 | |
| 1410 | Attrs: 66572 | |
| 1411 | - Kind: LF_MFUNCTION | |
| 1412 | MemberFunction: | |
| 1413 | ReturnType: 3 | |
| 1414 | ClassType: 4211 | |
| 1415 | ThisType: 4216 | |
| 1416 | CallConv: NearC | |
| 1417 | Options: [ None, Constructor ] | |
| 1418 | ParameterCount: 1 | |
| 1419 | ArgumentList: 4215 | |
| 1420 | ThisPointerAdjustment: 0 | |
| 1421 | - Kind: LF_MFUNCTION | |
| 1422 | MemberFunction: | |
| 1423 | ReturnType: 3 | |
| 1424 | ClassType: 4211 | |
| 1425 | ThisType: 4216 | |
| 1426 | CallConv: NearC | |
| 1427 | Options: [ None, Constructor ] | |
| 1428 | ParameterCount: 0 | |
| 1429 | ArgumentList: 4100 | |
| 1430 | ThisPointerAdjustment: 0 | |
| 1431 | - Kind: LF_METHODLIST | |
| 1432 | MethodOverloadList: | |
| 1433 | Methods: | |
| 1434 | - Type: 4217 | |
| 1435 | Attrs: 3 | |
| 1436 | VFTableOffset: -1 | |
| 1437 | Name: '' | |
| 1438 | - Type: 4218 | |
| 1439 | Attrs: 3 | |
| 1440 | VFTableOffset: -1 | |
| 1441 | Name: '' | |
| 1442 | - Kind: LF_FIELDLIST | |
| 1443 | FieldList: | |
| 1444 | - Kind: LF_NESTTYPE | |
| 1445 | NestedType: | |
| 1446 | Type: 4213 | |
| 1447 | Name: type_e | |
| 1448 | - Kind: LF_METHOD | |
| 1449 | OverloadedMethod: | |
| 1450 | NumOverloads: 2 | |
| 1451 | MethodList: 4219 | |
| 1452 | Name: aggregatableAttribute | |
| 1453 | - Kind: LF_MEMBER | |
| 1454 | DataMember: | |
| 1455 | Attrs: 3 | |
| 1456 | Type: 4213 | |
| 1457 | FieldOffset: 0 | |
| 1458 | Name: type | |
| 1459 | - Kind: LF_STRUCTURE | |
| 1460 | Class: | |
| 1461 | MemberCount: 4 | |
| 1462 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | |
| 1463 | FieldList: 4220 | |
| 1464 | Name: '__vc_attributes::aggregatableAttribute' | |
| 1465 | UniqueName: '.?AUaggregatableAttribute@__vc_attributes@@' | |
| 1466 | DerivationList: 0 | |
| 1467 | VTableShape: 0 | |
| 1468 | Size: 4 | |
| 1469 | - Kind: LF_UDT_SRC_LINE | |
| 1470 | UdtSourceLine: | |
| 1471 | UDT: 4221 | |
| 1472 | SourceFile: 4183 | |
| 1473 | LineNumber: 544 | |
| 1474 | - Kind: LF_STRUCTURE | |
| 1475 | Class: | |
| 1476 | MemberCount: 0 | |
| 1477 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 1478 | FieldList: 0 | |
| 1479 | Name: '__vc_attributes::threadingAttribute' | |
| 1480 | UniqueName: '.?AUthreadingAttribute@__vc_attributes@@' | |
| 1481 | DerivationList: 0 | |
| 1482 | VTableShape: 0 | |
| 1483 | Size: 0 | |
| 1484 | - Kind: LF_FIELDLIST | |
| 1485 | FieldList: | |
| 1486 | - Kind: LF_ENUMERATE | |
| 1487 | Enumerator: | |
| 1488 | Attrs: 3 | |
| 1489 | Value: 1 | |
| 1490 | Name: apartment | |
| 1491 | - Kind: LF_ENUMERATE | |
| 1492 | Enumerator: | |
| 1493 | Attrs: 3 | |
| 1494 | Value: 2 | |
| 1495 | Name: single | |
| 1496 | - Kind: LF_ENUMERATE | |
| 1497 | Enumerator: | |
| 1498 | Attrs: 3 | |
| 1499 | Value: 3 | |
| 1500 | Name: free | |
| 1501 | - Kind: LF_ENUMERATE | |
| 1502 | Enumerator: | |
| 1503 | Attrs: 3 | |
| 1504 | Value: 4 | |
| 1505 | Name: neutral | |
| 1506 | - Kind: LF_ENUMERATE | |
| 1507 | Enumerator: | |
| 1508 | Attrs: 3 | |
| 1509 | Value: 5 | |
| 1510 | Name: both | |
| 1511 | - Kind: LF_ENUM | |
| 1512 | Enum: | |
| 1513 | NumEnumerators: 5 | |
| 1514 | Options: [ None, Nested, HasUniqueName ] | |
| 1515 | FieldList: 4224 | |
| 1516 | Name: '__vc_attributes::threadingAttribute::threading_e' | |
| 1517 | UniqueName: '.?AW4threading_e@threadingAttribute@__vc_attributes@@' | |
| 1518 | UnderlyingType: 116 | |
| 1519 | - Kind: LF_UDT_SRC_LINE | |
| 1520 | UdtSourceLine: | |
| 1521 | UDT: 4225 | |
| 1522 | SourceFile: 4183 | |
| 1523 | LineNumber: 423 | |
| 1524 | - Kind: LF_ARGLIST | |
| 1525 | ArgList: | |
| 1526 | ArgIndices: [ 4225 ] | |
| 1527 | - Kind: LF_POINTER | |
| 1528 | Pointer: | |
| 1529 | ReferentType: 4223 | |
| 1530 | Attrs: 66572 | |
| 1531 | - Kind: LF_MFUNCTION | |
| 1532 | MemberFunction: | |
| 1533 | ReturnType: 3 | |
| 1534 | ClassType: 4223 | |
| 1535 | ThisType: 4228 | |
| 1536 | CallConv: NearC | |
| 1537 | Options: [ None, Constructor ] | |
| 1538 | ParameterCount: 1 | |
| 1539 | ArgumentList: 4227 | |
| 1540 | ThisPointerAdjustment: 0 | |
| 1541 | - Kind: LF_MFUNCTION | |
| 1542 | MemberFunction: | |
| 1543 | ReturnType: 3 | |
| 1544 | ClassType: 4223 | |
| 1545 | ThisType: 4228 | |
| 1546 | CallConv: NearC | |
| 1547 | Options: [ None, Constructor ] | |
| 1548 | ParameterCount: 0 | |
| 1549 | ArgumentList: 4100 | |
| 1550 | ThisPointerAdjustment: 0 | |
| 1551 | - Kind: LF_METHODLIST | |
| 1552 | MethodOverloadList: | |
| 1553 | Methods: | |
| 1554 | - Type: 4229 | |
| 1555 | Attrs: 3 | |
| 1556 | VFTableOffset: -1 | |
| 1557 | Name: '' | |
| 1558 | - Type: 4230 | |
| 1559 | Attrs: 3 | |
| 1560 | VFTableOffset: -1 | |
| 1561 | Name: '' | |
| 1562 | - Kind: LF_FIELDLIST | |
| 1563 | FieldList: | |
| 1564 | - Kind: LF_NESTTYPE | |
| 1565 | NestedType: | |
| 1566 | Type: 4225 | |
| 1567 | Name: threading_e | |
| 1568 | - Kind: LF_METHOD | |
| 1569 | OverloadedMethod: | |
| 1570 | NumOverloads: 2 | |
| 1571 | MethodList: 4231 | |
| 1572 | Name: threadingAttribute | |
| 1573 | - Kind: LF_MEMBER | |
| 1574 | DataMember: | |
| 1575 | Attrs: 3 | |
| 1576 | Type: 4225 | |
| 1577 | FieldOffset: 0 | |
| 1578 | Name: value | |
| 1579 | - Kind: LF_STRUCTURE | |
| 1580 | Class: | |
| 1581 | MemberCount: 4 | |
| 1582 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | |
| 1583 | FieldList: 4232 | |
| 1584 | Name: '__vc_attributes::threadingAttribute' | |
| 1585 | UniqueName: '.?AUthreadingAttribute@__vc_attributes@@' | |
| 1586 | DerivationList: 0 | |
| 1587 | VTableShape: 0 | |
| 1588 | Size: 4 | |
| 1589 | - Kind: LF_UDT_SRC_LINE | |
| 1590 | UdtSourceLine: | |
| 1591 | UDT: 4233 | |
| 1592 | SourceFile: 4183 | |
| 1593 | LineNumber: 422 | |
| 1594 | - Kind: LF_STRUCTURE | |
| 1595 | Class: | |
| 1596 | MemberCount: 0 | |
| 1597 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 1598 | FieldList: 0 | |
| 1599 | Name: '__vc_attributes::helper_attributes::usageAttribute' | |
| 1600 | UniqueName: '.?AUusageAttribute@helper_attributes@__vc_attributes@@' | |
| 1601 | DerivationList: 0 | |
| 1602 | VTableShape: 0 | |
| 1603 | Size: 0 | |
| 1604 | - Kind: LF_FIELDLIST | |
| 1605 | FieldList: | |
| 1606 | - Kind: LF_ENUMERATE | |
| 1607 | Enumerator: | |
| 1608 | Attrs: 3 | |
| 1609 | Value: 0 | |
| 1610 | Name: eAnyUsage | |
| 1611 | - Kind: LF_ENUMERATE | |
| 1612 | Enumerator: | |
| 1613 | Attrs: 3 | |
| 1614 | Value: 1 | |
| 1615 | Name: eCoClassUsage | |
| 1616 | - Kind: LF_ENUMERATE | |
| 1617 | Enumerator: | |
| 1618 | Attrs: 3 | |
| 1619 | Value: 2 | |
| 1620 | Name: eCOMInterfaceUsage | |
| 1621 | - Kind: LF_ENUMERATE | |
| 1622 | Enumerator: | |
| 1623 | Attrs: 3 | |
| 1624 | Value: 6 | |
| 1625 | Name: eInterfaceUsage | |
| 1626 | - Kind: LF_ENUMERATE | |
| 1627 | Enumerator: | |
| 1628 | Attrs: 3 | |
| 1629 | Value: 8 | |
| 1630 | Name: eMemberUsage | |
| 1631 | - Kind: LF_ENUMERATE | |
| 1632 | Enumerator: | |
| 1633 | Attrs: 3 | |
| 1634 | Value: 16 | |
| 1635 | Name: eMethodUsage | |
| 1636 | - Kind: LF_ENUMERATE | |
| 1637 | Enumerator: | |
| 1638 | Attrs: 3 | |
| 1639 | Value: 32 | |
| 1640 | Name: eInterfaceMethodUsage | |
| 1641 | - Kind: LF_ENUMERATE | |
| 1642 | Enumerator: | |
| 1643 | Attrs: 3 | |
| 1644 | Value: 64 | |
| 1645 | Name: eInterfaceMemberUsage | |
| 1646 | - Kind: LF_ENUMERATE | |
| 1647 | Enumerator: | |
| 1648 | Attrs: 3 | |
| 1649 | Value: 128 | |
| 1650 | Name: eCoClassMemberUsage | |
| 1651 | - Kind: LF_ENUMERATE | |
| 1652 | Enumerator: | |
| 1653 | Attrs: 3 | |
| 1654 | Value: 256 | |
| 1655 | Name: eCoClassMethodUsage | |
| 1656 | - Kind: LF_ENUMERATE | |
| 1657 | Enumerator: | |
| 1658 | Attrs: 3 | |
| 1659 | Value: 768 | |
| 1660 | Name: eGlobalMethodUsage | |
| 1661 | - Kind: LF_ENUMERATE | |
| 1662 | Enumerator: | |
| 1663 | Attrs: 3 | |
| 1664 | Value: 1024 | |
| 1665 | Name: eGlobalDataUsage | |
| 1666 | - Kind: LF_ENUMERATE | |
| 1667 | Enumerator: | |
| 1668 | Attrs: 3 | |
| 1669 | Value: 2048 | |
| 1670 | Name: eClassUsage | |
| 1671 | - Kind: LF_ENUMERATE | |
| 1672 | Enumerator: | |
| 1673 | Attrs: 3 | |
| 1674 | Value: 4096 | |
| 1675 | Name: eInterfaceParameterUsage | |
| 1676 | - Kind: LF_ENUMERATE | |
| 1677 | Enumerator: | |
| 1678 | Attrs: 3 | |
| 1679 | Value: 12288 | |
| 1680 | Name: eMethodParameterUsage | |
| 1681 | - Kind: LF_ENUMERATE | |
| 1682 | Enumerator: | |
| 1683 | Attrs: 3 | |
| 1684 | Value: 16384 | |
| 1685 | Name: eIDLModuleUsage | |
| 1686 | - Kind: LF_ENUMERATE | |
| 1687 | Enumerator: | |
| 1688 | Attrs: 3 | |
| 1689 | Value: 32768 | |
| 1690 | Name: eAnonymousUsage | |
| 1691 | - Kind: LF_ENUMERATE | |
| 1692 | Enumerator: | |
| 1693 | Attrs: 3 | |
| 1694 | Value: 65536 | |
| 1695 | Name: eTypedefUsage | |
| 1696 | - Kind: LF_ENUMERATE | |
| 1697 | Enumerator: | |
| 1698 | Attrs: 3 | |
| 1699 | Value: 131072 | |
| 1700 | Name: eUnionUsage | |
| 1701 | - Kind: LF_ENUMERATE | |
| 1702 | Enumerator: | |
| 1703 | Attrs: 3 | |
| 1704 | Value: 262144 | |
| 1705 | Name: eEnumUsage | |
| 1706 | - Kind: LF_ENUMERATE | |
| 1707 | Enumerator: | |
| 1708 | Attrs: 3 | |
| 1709 | Value: 524288 | |
| 1710 | Name: eDefineTagUsage | |
| 1711 | - Kind: LF_ENUMERATE | |
| 1712 | Enumerator: | |
| 1713 | Attrs: 3 | |
| 1714 | Value: 1048576 | |
| 1715 | Name: eStructUsage | |
| 1716 | - Kind: LF_ENUMERATE | |
| 1717 | Enumerator: | |
| 1718 | Attrs: 3 | |
| 1719 | Value: 2097152 | |
| 1720 | Name: eLocalUsage | |
| 1721 | - Kind: LF_ENUMERATE | |
| 1722 | Enumerator: | |
| 1723 | Attrs: 3 | |
| 1724 | Value: 4194304 | |
| 1725 | Name: ePropertyUsage | |
| 1726 | - Kind: LF_ENUMERATE | |
| 1727 | Enumerator: | |
| 1728 | Attrs: 3 | |
| 1729 | Value: 8388608 | |
| 1730 | Name: eEventUsage | |
| 1731 | - Kind: LF_ENUMERATE | |
| 1732 | Enumerator: | |
| 1733 | Attrs: 3 | |
| 1734 | Value: 16777216 | |
| 1735 | Name: eTemplateUsage | |
| 1736 | - Kind: LF_ENUMERATE | |
| 1737 | Enumerator: | |
| 1738 | Attrs: 3 | |
| 1739 | Value: 16777216 | |
| 1740 | Name: eModuleUsage | |
| 1741 | - Kind: LF_ENUMERATE | |
| 1742 | Enumerator: | |
| 1743 | Attrs: 3 | |
| 1744 | Value: 33554432 | |
| 1745 | Name: eIllegalUsage | |
| 1746 | - Kind: LF_ENUMERATE | |
| 1747 | Enumerator: | |
| 1748 | Attrs: 3 | |
| 1749 | Value: 67108864 | |
| 1750 | Name: eAsynchronousUsage | |
| 1751 | - Kind: LF_ENUMERATE | |
| 1752 | Enumerator: | |
| 1753 | Attrs: 3 | |
| 1754 | Value: 4161535 | |
| 1755 | Name: eAnyIDLUsage | |
| 1756 | - Kind: LF_ENUM | |
| 1757 | Enum: | |
| 1758 | NumEnumerators: 30 | |
| 1759 | Options: [ None, Nested, HasUniqueName ] | |
| 1760 | FieldList: 4236 | |
| 1761 | Name: '__vc_attributes::helper_attributes::usageAttribute::usage_e' | |
| 1762 | UniqueName: '.?AW4usage_e@usageAttribute@helper_attributes@__vc_attributes@@' | |
| 1763 | UnderlyingType: 116 | |
| 1764 | - Kind: LF_UDT_SRC_LINE | |
| 1765 | UdtSourceLine: | |
| 1766 | UDT: 4237 | |
| 1767 | SourceFile: 4183 | |
| 1768 | LineNumber: 51 | |
| 1769 | - Kind: LF_ARGLIST | |
| 1770 | ArgList: | |
| 1771 | ArgIndices: [ 117 ] | |
| 1772 | - Kind: LF_POINTER | |
| 1773 | Pointer: | |
| 1774 | ReferentType: 4235 | |
| 1775 | Attrs: 66572 | |
| 1776 | - Kind: LF_MFUNCTION | |
| 1777 | MemberFunction: | |
| 1778 | ReturnType: 3 | |
| 1779 | ClassType: 4235 | |
| 1780 | ThisType: 4240 | |
| 1781 | CallConv: NearC | |
| 1782 | Options: [ None, Constructor ] | |
| 1783 | ParameterCount: 1 | |
| 1784 | ArgumentList: 4239 | |
| 1785 | ThisPointerAdjustment: 0 | |
| 1786 | - Kind: LF_FIELDLIST | |
| 1787 | FieldList: | |
| 1788 | - Kind: LF_NESTTYPE | |
| 1789 | NestedType: | |
| 1790 | Type: 4237 | |
| 1791 | Name: usage_e | |
| 1792 | - Kind: LF_ONEMETHOD | |
| 1793 | OneMethod: | |
| 1794 | Type: 4241 | |
| 1795 | Attrs: 3 | |
| 1796 | VFTableOffset: -1 | |
| 1797 | Name: usageAttribute | |
| 1798 | - Kind: LF_MEMBER | |
| 1799 | DataMember: | |
| 1800 | Attrs: 3 | |
| 1801 | Type: 117 | |
| 1802 | FieldOffset: 0 | |
| 1803 | Name: value | |
| 1804 | - Kind: LF_STRUCTURE | |
| 1805 | Class: | |
| 1806 | MemberCount: 3 | |
| 1807 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | |
| 1808 | FieldList: 4242 | |
| 1809 | Name: '__vc_attributes::helper_attributes::usageAttribute' | |
| 1810 | UniqueName: '.?AUusageAttribute@helper_attributes@__vc_attributes@@' | |
| 1811 | DerivationList: 0 | |
| 1812 | VTableShape: 0 | |
| 1813 | Size: 4 | |
| 1814 | - Kind: LF_UDT_SRC_LINE | |
| 1815 | UdtSourceLine: | |
| 1816 | UDT: 4243 | |
| 1817 | SourceFile: 4183 | |
| 1818 | LineNumber: 49 | |
| 1819 | - Kind: LF_STRUCTURE | |
| 1820 | Class: | |
| 1821 | MemberCount: 0 | |
| 1822 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 1823 | FieldList: 0 | |
| 1824 | Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute' | |
| 1825 | UniqueName: '.?AUv1_alttypeAttribute@helper_attributes@__vc_attributes@@' | |
| 1826 | DerivationList: 0 | |
| 1827 | VTableShape: 0 | |
| 1828 | Size: 0 | |
| 1829 | - Kind: LF_FIELDLIST | |
| 1830 | FieldList: | |
| 1831 | - Kind: LF_ENUMERATE | |
| 1832 | Enumerator: | |
| 1833 | Attrs: 3 | |
| 1834 | Value: 0 | |
| 1835 | Name: eBoolean | |
| 1836 | - Kind: LF_ENUMERATE | |
| 1837 | Enumerator: | |
| 1838 | Attrs: 3 | |
| 1839 | Value: 1 | |
| 1840 | Name: eInteger | |
| 1841 | - Kind: LF_ENUMERATE | |
| 1842 | Enumerator: | |
| 1843 | Attrs: 3 | |
| 1844 | Value: 2 | |
| 1845 | Name: eFloat | |
| 1846 | - Kind: LF_ENUMERATE | |
| 1847 | Enumerator: | |
| 1848 | Attrs: 3 | |
| 1849 | Value: 3 | |
| 1850 | Name: eDouble | |
| 1851 | - Kind: LF_ENUM | |
| 1852 | Enum: | |
| 1853 | NumEnumerators: 4 | |
| 1854 | Options: [ None, Nested, HasUniqueName ] | |
| 1855 | FieldList: 4246 | |
| 1856 | Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute::type_e' | |
| 1857 | UniqueName: '.?AW4type_e@v1_alttypeAttribute@helper_attributes@__vc_attributes@@' | |
| 1858 | UnderlyingType: 116 | |
| 1859 | - Kind: LF_UDT_SRC_LINE | |
| 1860 | UdtSourceLine: | |
| 1861 | UDT: 4247 | |
| 1862 | SourceFile: 4183 | |
| 1863 | LineNumber: 38 | |
| 1864 | - Kind: LF_ARGLIST | |
| 1865 | ArgList: | |
| 1866 | ArgIndices: [ 4247 ] | |
| 1867 | - Kind: LF_POINTER | |
| 1868 | Pointer: | |
| 1869 | ReferentType: 4245 | |
| 1870 | Attrs: 66572 | |
| 1871 | - Kind: LF_MFUNCTION | |
| 1872 | MemberFunction: | |
| 1873 | ReturnType: 3 | |
| 1874 | ClassType: 4245 | |
| 1875 | ThisType: 4250 | |
| 1876 | CallConv: NearC | |
| 1877 | Options: [ None, Constructor ] | |
| 1878 | ParameterCount: 1 | |
| 1879 | ArgumentList: 4249 | |
| 1880 | ThisPointerAdjustment: 0 | |
| 1881 | - Kind: LF_FIELDLIST | |
| 1882 | FieldList: | |
| 1883 | - Kind: LF_NESTTYPE | |
| 1884 | NestedType: | |
| 1885 | Type: 4247 | |
| 1886 | Name: type_e | |
| 1887 | - Kind: LF_ONEMETHOD | |
| 1888 | OneMethod: | |
| 1889 | Type: 4251 | |
| 1890 | Attrs: 3 | |
| 1891 | VFTableOffset: -1 | |
| 1892 | Name: v1_alttypeAttribute | |
| 1893 | - Kind: LF_MEMBER | |
| 1894 | DataMember: | |
| 1895 | Attrs: 3 | |
| 1896 | Type: 4247 | |
| 1897 | FieldOffset: 0 | |
| 1898 | Name: type | |
| 1899 | - Kind: LF_STRUCTURE | |
| 1900 | Class: | |
| 1901 | MemberCount: 3 | |
| 1902 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | |
| 1903 | FieldList: 4252 | |
| 1904 | Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute' | |
| 1905 | UniqueName: '.?AUv1_alttypeAttribute@helper_attributes@__vc_attributes@@' | |
| 1906 | DerivationList: 0 | |
| 1907 | VTableShape: 0 | |
| 1908 | Size: 4 | |
| 1909 | - Kind: LF_UDT_SRC_LINE | |
| 1910 | UdtSourceLine: | |
| 1911 | UDT: 4253 | |
| 1912 | SourceFile: 4183 | |
| 1913 | LineNumber: 37 | |
| 1914 | - Kind: LF_STRUCTURE | |
| 1915 | Class: | |
| 1916 | MemberCount: 0 | |
| 1917 | Options: [ None, ForwardReference, HasUniqueName ] | |
| 1918 | FieldList: 0 | |
| 1919 | Name: '__vc_attributes::event_sourceAttribute' | |
| 1920 | UniqueName: '.?AUevent_sourceAttribute@__vc_attributes@@' | |
| 1921 | DerivationList: 0 | |
| 1922 | VTableShape: 0 | |
| 1923 | Size: 0 | |
| 1924 | - Kind: LF_FIELDLIST | |
| 1925 | FieldList: | |
| 1926 | - Kind: LF_ENUMERATE | |
| 1927 | Enumerator: | |
| 1928 | Attrs: 3 | |
| 1929 | Value: 0 | |
| 1930 | Name: native | |
| 1931 | - Kind: LF_ENUMERATE | |
| 1932 | Enumerator: | |
| 1933 | Attrs: 3 | |
| 1934 | Value: 1 | |
| 1935 | Name: com | |
| 1936 | - Kind: LF_ENUMERATE | |
| 1937 | Enumerator: | |
| 1938 | Attrs: 3 | |
| 1939 | Value: 2 | |
| 1940 | Name: managed | |
| 1941 | - Kind: LF_ENUM | |
| 1942 | Enum: | |
| 1943 | NumEnumerators: 3 | |
| 1944 | Options: [ None, Nested, HasUniqueName ] | |
| 1945 | FieldList: 4256 | |
| 1946 | Name: '__vc_attributes::event_sourceAttribute::type_e' | |
| 1947 | UniqueName: '.?AW4type_e@event_sourceAttribute@__vc_attributes@@' | |
| 1948 | UnderlyingType: 116 | |
| 1949 | - Kind: LF_UDT_SRC_LINE | |
| 1950 | UdtSourceLine: | |
| 1951 | UDT: 4257 | |
| 1952 | SourceFile: 4183 | |
| 1953 | LineNumber: 1142 | |
| 1954 | - Kind: LF_FIELDLIST | |
| 1955 | FieldList: | |
| 1956 | - Kind: LF_ENUMERATE | |
| 1957 | Enumerator: | |
| 1958 | Attrs: 3 | |
| 1959 | Value: 0 | |
| 1960 | Name: speed | |
| 1961 | - Kind: LF_ENUMERATE | |
| 1962 | Enumerator: | |
| 1963 | Attrs: 3 | |
| 1964 | Value: 1 | |
| 1965 | Name: size | |
| 1966 | - Kind: LF_ENUM | |
| 1967 | Enum: | |
| 1968 | NumEnumerators: 2 | |
| 1969 | Options: [ None, Nested, HasUniqueName ] | |
| 1970 | FieldList: 4259 | |
| 1971 | Name: '__vc_attributes::event_sourceAttribute::optimize_e' | |
| 1972 | UniqueName: '.?AW4optimize_e@event_sourceAttribute@__vc_attributes@@' | |
| 1973 | UnderlyingType: 116 | |
| 1974 | - Kind: LF_UDT_SRC_LINE | |
| 1975 | UdtSourceLine: | |
| 1976 | UDT: 4260 | |
| 1977 | SourceFile: 4183 | |
| 1978 | LineNumber: 1145 | |
| 1979 | - Kind: LF_ARGLIST | |
| 1980 | ArgList: | |
| 1981 | ArgIndices: [ 4257 ] | |
| 1982 | - Kind: LF_POINTER | |
| 1983 | Pointer: | |
| 1984 | ReferentType: 4255 | |
| 1985 | Attrs: 66572 | |
| 1986 | - Kind: LF_MFUNCTION | |
| 1987 | MemberFunction: | |
| 1988 | ReturnType: 3 | |
| 1989 | ClassType: 4255 | |
| 1990 | ThisType: 4263 | |
| 1991 | CallConv: NearC | |
| 1992 | Options: [ None, Constructor ] | |
| 1993 | ParameterCount: 1 | |
| 1994 | ArgumentList: 4262 | |
| 1995 | ThisPointerAdjustment: 0 | |
| 1996 | - Kind: LF_MFUNCTION | |
| 1997 | MemberFunction: | |
| 1998 | ReturnType: 3 | |
| 1999 | ClassType: 4255 | |
| 2000 | ThisType: 4263 | |
| 2001 | CallConv: NearC | |
| 2002 | Options: [ None, Constructor ] | |
| 2003 | ParameterCount: 0 | |
| 2004 | ArgumentList: 4100 | |
| 2005 | ThisPointerAdjustment: 0 | |
| 2006 | - Kind: LF_METHODLIST | |
| 2007 | MethodOverloadList: | |
| 2008 | Methods: | |
| 2009 | - Type: 4264 | |
| 2010 | Attrs: 3 | |
| 2011 | VFTableOffset: -1 | |
| 2012 | Name: '' | |
| 2013 | - Type: 4265 | |
| 2014 | Attrs: 3 | |
| 2015 | VFTableOffset: -1 | |
| 2016 | Name: '' | |
| 2017 | - Kind: LF_FIELDLIST | |
| 2018 | FieldList: | |
| 2019 | - Kind: LF_NESTTYPE | |
| 2020 | NestedType: | |
| 2021 | Type: 4257 | |
| 2022 | Name: type_e | |
| 2023 | - Kind: LF_NESTTYPE | |
| 2024 | NestedType: | |
| 2025 | Type: 4260 | |
| 2026 | Name: optimize_e | |
| 2027 | - Kind: LF_METHOD | |
| 2028 | OverloadedMethod: | |
| 2029 | NumOverloads: 2 | |
| 2030 | MethodList: 4266 | |
| 2031 | Name: event_sourceAttribute | |
| 2032 | - Kind: LF_MEMBER | |
| 2033 | DataMember: | |
| 2034 | Attrs: 3 | |
| 2035 | Type: 4257 | |
| 2036 | FieldOffset: 0 | |
| 2037 | Name: type | |
| 2038 | - Kind: LF_MEMBER | |
| 2039 | DataMember: | |
| 2040 | Attrs: 3 | |
| 2041 | Type: 4260 | |
| 2042 | FieldOffset: 4 | |
| 2043 | Name: optimize | |
| 2044 | - Kind: LF_MEMBER | |
| 2045 | DataMember: | |
| 2046 | Attrs: 3 | |
| 2047 | Type: 48 | |
| 2048 | FieldOffset: 8 | |
| 2049 | Name: decorate | |
| 2050 | - Kind: LF_STRUCTURE | |
| 2051 | Class: | |
| 2052 | MemberCount: 7 | |
| 2053 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | |
| 2054 | FieldList: 4267 | |
| 2055 | Name: '__vc_attributes::event_sourceAttribute' | |
| 2056 | UniqueName: '.?AUevent_sourceAttribute@__vc_attributes@@' | |
| 2057 | DerivationList: 0 | |
| 2058 | VTableShape: 0 | |
| 2059 | Size: 12 | |
| 2060 | - Kind: LF_UDT_SRC_LINE | |
| 2061 | UdtSourceLine: | |
| 2062 | UDT: 4268 | |
| 2063 | SourceFile: 4183 | |
| 2064 | LineNumber: 1141 | |
| 2065 | - Kind: LF_VFTABLE | |
| 2066 | VFTable: | |
| 2067 | CompleteClass: 4117 | |
| 2068 | OverriddenVFTable: 0 | |
| 2069 | VFPtrOffset: 0 | |
| 2070 | MethodNames: | |
| 2071 | - '??_7A@@6B@' | |
| 2072 | - '?f@A@@UEAAHXZ' | |
| 2073 | - Kind: LF_VFTABLE | |
| 2074 | VFTable: | |
| 2075 | CompleteClass: 4140 | |
| 2076 | OverriddenVFTable: 0 | |
| 2077 | VFPtrOffset: 0 | |
| 2078 | MethodNames: | |
| 2079 | - '??_7B@@6B@' | |
| 2080 | - '?f@B@@UEAAHXZ' | |
| 2081 | - Kind: LF_VFTABLE | |
| 2082 | VFTable: | |
| 2083 | CompleteClass: 4160 | |
| 2084 | OverriddenVFTable: 4270 | |
| 2085 | VFPtrOffset: 0 | |
| 2086 | MethodNames: | |
| 2087 | - '??_7C@@6BA@@@' | |
| 2088 | - '?f@C@@UEAAHXZ' | |
| 2089 | - Kind: LF_VFTABLE | |
| 2090 | VFTable: | |
| 2091 | CompleteClass: 4160 | |
| 2092 | OverriddenVFTable: 4271 | |
| 2093 | VFPtrOffset: 8 | |
| 2094 | MethodNames: | |
| 2095 | - '??_7C@@6BB@@@' | |
| 2096 | - '?f@C@@W7EAAHXZ' | |
| 2097 | - Kind: LF_STRING_ID | |
| 2098 | StringId: | |
| 2099 | Id: 0 | |
| 2100 | String: 'C:\src\llvm-project\build' | |
| 2101 | - Kind: LF_STRING_ID | |
| 2102 | StringId: | |
| 2103 | Id: 0 | |
| 2104 | String: 'C:\PROGRA~2\MICROS~1\2017\PROFES~1\VC\Tools\MSVC\14.11.25503\bin\HostX64\x64\cl.exe' | |
| 2105 | - Kind: LF_STRING_ID | |
| 2106 | StringId: | |
| 2107 | Id: 0 | |
| 2108 | String: '-GR- -Z7 -c -MT -IC:\PROGRA~2\MICROS~1\2017\PROFES~1\VC\Tools\MSVC\14.11.25503\ATLMFC\include -IC:\PROGRA~2\MICROS~1\2017\PROFES~1\VC\Tools\MSVC\14.11.25503\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.16299.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.162' | |
| 2109 | - Kind: LF_SUBSTR_LIST | |
| 2110 | StringList: | |
| 2111 | StringIndices: [ 4276 ] | |
| 2112 | - Kind: LF_STRING_ID | |
| 2113 | StringId: | |
| 2114 | Id: 4277 | |
| 2115 | String: '99.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.16299.0\um -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.16299.0\winrt -TP -X' | |
| 2116 | - Kind: LF_STRING_ID | |
| 2117 | StringId: | |
| 2118 | Id: 0 | |
| 2119 | String: t.cpp | |
| 2120 | - Kind: LF_STRING_ID | |
| 2121 | StringId: | |
| 2122 | Id: 0 | |
| 2123 | String: 'C:\src\llvm-project\build\vc140.pdb' | |
| 2124 | - Kind: LF_BUILDINFO | |
| 2125 | BuildInfo: | |
| 2126 | ArgIndices: [ 4274, 4275, 4279, 4280, 4278 ] | |
| 2127 | - Name: '.text$mn' | |
| 2128 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 2129 | Alignment: 16 | |
| 2130 | SectionData: 48894C240833C0C3CCCCCCCCCCCCCCCC48894C240833C0C3CCCCCCCCCCCCCCCC48894C24084883EC28488B4C2430E800000000488B4424304883C008488BC8E800000000488B442430488D0D00000000488908488B442430488D0D0000000048894808488B442430C740102A000000488B4424304883C428C3CCCCCCCCCCCCCC48894C2408488B4424088B4010C3 | |
| 2131 | Relocations: | |
| 2132 | - VirtualAddress: 47 | |
| 2133 | SymbolName: '??0A@@QEAA@XZ' | |
| 2134 | Type: IMAGE_REL_AMD64_REL32 | |
| 2135 | - VirtualAddress: 64 | |
| 2136 | SymbolName: '??0B@@QEAA@XZ' | |
| 2137 | Type: IMAGE_REL_AMD64_REL32 | |
| 2138 | - VirtualAddress: 76 | |
| 2139 | SymbolName: '??_7C@@6BA@@@' | |
| 2140 | Type: IMAGE_REL_AMD64_REL32 | |
| 2141 | - VirtualAddress: 91 | |
| 2142 | SymbolName: '??_7C@@6BB@@@' | |
| 2143 | Type: IMAGE_REL_AMD64_REL32 | |
| 2144 | - Name: '.text$mn' | |
| 2145 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 2146 | Alignment: 16 | |
| 2147 | SectionData: 48894C2408488B442408488D0D00000000488908488B442408C3 | |
| 2148 | Relocations: | |
| 2149 | - VirtualAddress: 13 | |
| 2150 | SymbolName: '??_7A@@6B@' | |
| 2151 | Type: IMAGE_REL_AMD64_REL32 | |
| 2152 | - Name: '.debug$S' | |
| 2153 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 2154 | Alignment: 1 | |
| 2155 | Subsections: | |
| 2156 | - !Symbols | |
| 2157 | Records: | |
| 2158 | - Kind: S_GPROC32_ID | |
| 2159 | ProcSym: | |
| 2160 | CodeSize: 26 | |
| 2161 | DbgStart: 5 | |
| 2162 | DbgEnd: 25 | |
| 2163 | FunctionType: 4176 | |
| 2164 | Flags: [ ] | |
| 2165 | DisplayName: 'A::A' | |
| 2166 | - Kind: S_FRAMEPROC | |
| 2167 | FrameProcSym: | |
| 2168 | TotalFrameBytes: 0 | |
| 2169 | PaddingFrameBytes: 0 | |
| 2170 | OffsetToPadding: 0 | |
| 2171 | BytesOfCalleeSavedRegisters: 0 | |
| 2172 | OffsetOfExceptionHandler: 0 | |
| 2173 | SectionIdOfExceptionHandler: 0 | |
| 2174 | Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ] | |
| 2175 | - Kind: S_REGREL32 | |
| 2176 | RegRelativeSym: | |
| 2177 | Offset: 8 | |
| 2178 | Type: 4097 | |
| 2179 | Register: RSP | |
| 2180 | VarName: this | |
| 2181 | - Kind: S_PROC_ID_END | |
| 2182 | ScopeEndSym: | |
| 2183 | Relocations: | |
| 2184 | - VirtualAddress: 44 | |
| 2185 | SymbolName: '??0A@@QEAA@XZ' | |
| 2186 | Type: IMAGE_REL_AMD64_SECREL | |
| 2187 | - VirtualAddress: 48 | |
| 2188 | SymbolName: '??0A@@QEAA@XZ' | |
| 2189 | Type: IMAGE_REL_AMD64_SECTION | |
| 2190 | - Name: '.text$mn' | |
| 2191 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 2192 | Alignment: 16 | |
| 2193 | SectionData: 48894C2408488B442408488D0D00000000488908488B442408C3 | |
| 2194 | Relocations: | |
| 2195 | - VirtualAddress: 13 | |
| 2196 | SymbolName: '??_7B@@6B@' | |
| 2197 | Type: IMAGE_REL_AMD64_REL32 | |
| 2198 | - Name: '.debug$S' | |
| 2199 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 2200 | Alignment: 1 | |
| 2201 | Subsections: | |
| 2202 | - !Symbols | |
| 2203 | Records: | |
| 2204 | - Kind: S_GPROC32_ID | |
| 2205 | ProcSym: | |
| 2206 | CodeSize: 26 | |
| 2207 | DbgStart: 5 | |
| 2208 | DbgEnd: 25 | |
| 2209 | FunctionType: 4177 | |
| 2210 | Flags: [ ] | |
| 2211 | DisplayName: 'B::B' | |
| 2212 | - Kind: S_FRAMEPROC | |
| 2213 | FrameProcSym: | |
| 2214 | TotalFrameBytes: 0 | |
| 2215 | PaddingFrameBytes: 0 | |
| 2216 | OffsetToPadding: 0 | |
| 2217 | BytesOfCalleeSavedRegisters: 0 | |
| 2218 | OffsetOfExceptionHandler: 0 | |
| 2219 | SectionIdOfExceptionHandler: 0 | |
| 2220 | Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ] | |
| 2221 | - Kind: S_REGREL32 | |
| 2222 | RegRelativeSym: | |
| 2223 | Offset: 8 | |
| 2224 | Type: 4121 | |
| 2225 | Register: RSP | |
| 2226 | VarName: this | |
| 2227 | - Kind: S_PROC_ID_END | |
| 2228 | ScopeEndSym: | |
| 2229 | Relocations: | |
| 2230 | - VirtualAddress: 44 | |
| 2231 | SymbolName: '??0B@@QEAA@XZ' | |
| 2232 | Type: IMAGE_REL_AMD64_SECREL | |
| 2233 | - VirtualAddress: 48 | |
| 2234 | SymbolName: '??0B@@QEAA@XZ' | |
| 2235 | Type: IMAGE_REL_AMD64_SECTION | |
| 2236 | - Name: '.text$mn' | |
| 2237 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | |
| 2238 | Alignment: 4 | |
| 2239 | SectionData: 4883E908E900000000 | |
| 2240 | Relocations: | |
| 2241 | - VirtualAddress: 5 | |
| 2242 | SymbolName: '?f@C@@UEAAHXZ' | |
| 2243 | Type: IMAGE_REL_AMD64_REL32 | |
| 2244 | - Name: '.debug$S' | |
| 2245 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 2246 | Alignment: 1 | |
| 2247 | Subsections: | |
| 2248 | - !Symbols | |
| 2249 | Records: | |
| 2250 | - Kind: S_THUNK32 | |
| 2251 | Thunk32Sym: | |
| 2252 | Parent: 0 | |
| 2253 | End: 0 | |
| 2254 | Next: 0 | |
| 2255 | Off: 0 | |
| 2256 | Seg: 0 | |
| 2257 | Len: 9 | |
| 2258 | Ordinal: Pcode | |
| 2259 | - Kind: S_FRAMEPROC | |
| 2260 | FrameProcSym: | |
| 2261 | TotalFrameBytes: 0 | |
| 2262 | PaddingFrameBytes: 0 | |
| 2263 | OffsetToPadding: 0 | |
| 2264 | BytesOfCalleeSavedRegisters: 0 | |
| 2265 | OffsetOfExceptionHandler: 0 | |
| 2266 | SectionIdOfExceptionHandler: 0 | |
| 2267 | Flags: [ MarkedInline, Naked, AsynchronousExceptionHandling ] | |
| 2268 | - Kind: S_PROC_ID_END | |
| 2269 | ScopeEndSym: | |
| 2270 | Relocations: | |
| 2271 | - VirtualAddress: 28 | |
| 2272 | SymbolName: '?f@C@@W7EAAHXZ' | |
| 2273 | Type: IMAGE_REL_AMD64_SECREL | |
| 2274 | - VirtualAddress: 32 | |
| 2275 | SymbolName: '?f@C@@W7EAAHXZ' | |
| 2276 | Type: IMAGE_REL_AMD64_SECTION | |
| 2277 | - Name: .xdata | |
| 2278 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | |
| 2279 | Alignment: 4 | |
| 2280 | SectionData: '0109010009420000' | |
| 2281 | - Name: .pdata | |
| 2282 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | |
| 2283 | Alignment: 4 | |
| 2284 | SectionData: '000000005900000000000000' | |
| 2285 | Relocations: | |
| 2286 | - VirtualAddress: 0 | |
| 2287 | SymbolName: '$LN3' | |
| 2288 | Type: IMAGE_REL_AMD64_ADDR32NB | |
| 2289 | - VirtualAddress: 4 | |
| 2290 | SymbolName: '$LN3' | |
| 2291 | Type: IMAGE_REL_AMD64_ADDR32NB | |
| 2292 | - VirtualAddress: 8 | |
| 2293 | SymbolName: '$unwind$??0C@@QEAA@XZ' | |
| 2294 | Type: IMAGE_REL_AMD64_ADDR32NB | |
| 2295 | - Name: .rdata | |
| 2296 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] | |
| 2297 | Alignment: 8 | |
| 2298 | SectionData: '0000000000000000' | |
| 2299 | Relocations: | |
| 2300 | - VirtualAddress: 0 | |
| 2301 | SymbolName: '?f@A@@UEAAHXZ' | |
| 2302 | Type: IMAGE_REL_AMD64_ADDR64 | |
| 2303 | - Name: .rdata | |
| 2304 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] | |
| 2305 | Alignment: 8 | |
| 2306 | SectionData: '0000000000000000' | |
| 2307 | Relocations: | |
| 2308 | - VirtualAddress: 0 | |
| 2309 | SymbolName: '?f@B@@UEAAHXZ' | |
| 2310 | Type: IMAGE_REL_AMD64_ADDR64 | |
| 2311 | - Name: .rdata | |
| 2312 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] | |
| 2313 | Alignment: 8 | |
| 2314 | SectionData: '0000000000000000' | |
| 2315 | Relocations: | |
| 2316 | - VirtualAddress: 0 | |
| 2317 | SymbolName: '?f@C@@UEAAHXZ' | |
| 2318 | Type: IMAGE_REL_AMD64_ADDR64 | |
| 2319 | - Name: .rdata | |
| 2320 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] | |
| 2321 | Alignment: 8 | |
| 2322 | SectionData: '0000000000000000' | |
| 2323 | Relocations: | |
| 2324 | - VirtualAddress: 0 | |
| 2325 | SymbolName: '?f@C@@W7EAAHXZ' | |
| 2326 | Type: IMAGE_REL_AMD64_ADDR64 | |
| 2327 | - Name: '.debug$S' | |
| 2328 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 2329 | Alignment: 1 | |
| 2330 | Subsections: | |
| 2331 | - !Symbols | |
| 2332 | Records: | |
| 2333 | - Kind: S_GDATA32 | |
| 2334 | DataSym: | |
| 2335 | Type: 4179 | |
| 2336 | DisplayName: 'A::`vftable''' | |
| 2337 | Relocations: | |
| 2338 | - VirtualAddress: 20 | |
| 2339 | SymbolName: '??_7A@@6B@' | |
| 2340 | Type: IMAGE_REL_AMD64_SECREL | |
| 2341 | - VirtualAddress: 24 | |
| 2342 | SymbolName: '??_7A@@6B@' | |
| 2343 | Type: IMAGE_REL_AMD64_SECTION | |
| 2344 | - Name: '.debug$S' | |
| 2345 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 2346 | Alignment: 1 | |
| 2347 | Subsections: | |
| 2348 | - !Symbols | |
| 2349 | Records: | |
| 2350 | - Kind: S_GDATA32 | |
| 2351 | DataSym: | |
| 2352 | Type: 4179 | |
| 2353 | DisplayName: 'B::`vftable''' | |
| 2354 | Relocations: | |
| 2355 | - VirtualAddress: 20 | |
| 2356 | SymbolName: '??_7B@@6B@' | |
| 2357 | Type: IMAGE_REL_AMD64_SECREL | |
| 2358 | - VirtualAddress: 24 | |
| 2359 | SymbolName: '??_7B@@6B@' | |
| 2360 | Type: IMAGE_REL_AMD64_SECTION | |
| 2361 | - Name: '.debug$S' | |
| 2362 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 2363 | Alignment: 1 | |
| 2364 | Subsections: | |
| 2365 | - !Symbols | |
| 2366 | Records: | |
| 2367 | - Kind: S_GDATA32 | |
| 2368 | DataSym: | |
| 2369 | Type: 4179 | |
| 2370 | DisplayName: 'C::`vftable''' | |
| 2371 | Relocations: | |
| 2372 | - VirtualAddress: 20 | |
| 2373 | SymbolName: '??_7C@@6BA@@@' | |
| 2374 | Type: IMAGE_REL_AMD64_SECREL | |
| 2375 | - VirtualAddress: 24 | |
| 2376 | SymbolName: '??_7C@@6BA@@@' | |
| 2377 | Type: IMAGE_REL_AMD64_SECTION | |
| 2378 | - Name: '.debug$S' | |
| 2379 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | |
| 2380 | Alignment: 1 | |
| 2381 | Subsections: | |
| 2382 | - !Symbols | |
| 2383 | Records: | |
| 2384 | - Kind: S_GDATA32 | |
| 2385 | DataSym: | |
| 2386 | Type: 4179 | |
| 2387 | DisplayName: 'C::`vftable''' | |
| 2388 | Relocations: | |
| 2389 | - VirtualAddress: 20 | |
| 2390 | SymbolName: '??_7C@@6BB@@@' | |
| 2391 | Type: IMAGE_REL_AMD64_SECREL | |
| 2392 | - VirtualAddress: 24 | |
| 2393 | SymbolName: '??_7C@@6BB@@@' | |
| 2394 | Type: IMAGE_REL_AMD64_SECTION | |
| 2395 | symbols: | |
| 2396 | - Name: '@comp.id' | |
| 2397 | Value: 17130404 | |
| 2398 | SectionNumber: -1 | |
| 2399 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2400 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2401 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2402 | - Name: '@feat.00' | |
| 2403 | Value: 2147484048 | |
| 2404 | SectionNumber: -1 | |
| 2405 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2406 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2407 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2408 | - Name: .drectve | |
| 2409 | Value: 0 | |
| 2410 | SectionNumber: 1 | |
| 2411 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2412 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2413 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2414 | SectionDefinition: | |
| 2415 | Length: 69 | |
| 2416 | NumberOfRelocations: 0 | |
| 2417 | NumberOfLinenumbers: 0 | |
| 2418 | CheckSum: 876125206 | |
| 2419 | Number: 0 | |
| 2420 | - Name: '.debug$S' | |
| 2421 | Value: 0 | |
| 2422 | SectionNumber: 2 | |
| 2423 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2424 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2425 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2426 | SectionDefinition: | |
| 2427 | Length: 1668 | |
| 2428 | NumberOfRelocations: 16 | |
| 2429 | NumberOfLinenumbers: 0 | |
| 2430 | CheckSum: 0 | |
| 2431 | Number: 0 | |
| 2432 | - Name: '.debug$T' | |
| 2433 | Value: 0 | |
| 2434 | SectionNumber: 3 | |
| 2435 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2436 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2437 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2438 | SectionDefinition: | |
| 2439 | Length: 8276 | |
| 2440 | NumberOfRelocations: 0 | |
| 2441 | NumberOfLinenumbers: 0 | |
| 2442 | CheckSum: 0 | |
| 2443 | Number: 0 | |
| 2444 | - Name: '.text$mn' | |
| 2445 | Value: 0 | |
| 2446 | SectionNumber: 4 | |
| 2447 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2448 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2449 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2450 | SectionDefinition: | |
| 2451 | Length: 142 | |
| 2452 | NumberOfRelocations: 4 | |
| 2453 | NumberOfLinenumbers: 0 | |
| 2454 | CheckSum: 1906691115 | |
| 2455 | Number: 0 | |
| 2456 | - Name: '.text$mn' | |
| 2457 | Value: 0 | |
| 2458 | SectionNumber: 5 | |
| 2459 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2460 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2461 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2462 | SectionDefinition: | |
| 2463 | Length: 26 | |
| 2464 | NumberOfRelocations: 1 | |
| 2465 | NumberOfLinenumbers: 0 | |
| 2466 | CheckSum: 2299407997 | |
| 2467 | Number: 0 | |
| 2468 | Selection: IMAGE_COMDAT_SELECT_ANY | |
| 2469 | - Name: '.debug$S' | |
| 2470 | Value: 0 | |
| 2471 | SectionNumber: 6 | |
| 2472 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2473 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2474 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2475 | SectionDefinition: | |
| 2476 | Length: 112 | |
| 2477 | NumberOfRelocations: 2 | |
| 2478 | NumberOfLinenumbers: 0 | |
| 2479 | CheckSum: 0 | |
| 2480 | Number: 5 | |
| 2481 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | |
| 2482 | - Name: '.text$mn' | |
| 2483 | Value: 0 | |
| 2484 | SectionNumber: 7 | |
| 2485 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2486 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2487 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2488 | SectionDefinition: | |
| 2489 | Length: 26 | |
| 2490 | NumberOfRelocations: 1 | |
| 2491 | NumberOfLinenumbers: 0 | |
| 2492 | CheckSum: 2299407997 | |
| 2493 | Number: 0 | |
| 2494 | Selection: IMAGE_COMDAT_SELECT_ANY | |
| 2495 | - Name: '.debug$S' | |
| 2496 | Value: 0 | |
| 2497 | SectionNumber: 8 | |
| 2498 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2499 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2500 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2501 | SectionDefinition: | |
| 2502 | Length: 112 | |
| 2503 | NumberOfRelocations: 2 | |
| 2504 | NumberOfLinenumbers: 0 | |
| 2505 | CheckSum: 0 | |
| 2506 | Number: 7 | |
| 2507 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | |
| 2508 | - Name: '.text$mn' | |
| 2509 | Value: 0 | |
| 2510 | SectionNumber: 9 | |
| 2511 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2512 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2513 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2514 | SectionDefinition: | |
| 2515 | Length: 9 | |
| 2516 | NumberOfRelocations: 1 | |
| 2517 | NumberOfLinenumbers: 0 | |
| 2518 | CheckSum: 3880904481 | |
| 2519 | Number: 0 | |
| 2520 | Selection: IMAGE_COMDAT_SELECT_ANY | |
| 2521 | - Name: '.debug$S' | |
| 2522 | Value: 0 | |
| 2523 | SectionNumber: 10 | |
| 2524 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2525 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2526 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2527 | SectionDefinition: | |
| 2528 | Length: 100 | |
| 2529 | NumberOfRelocations: 2 | |
| 2530 | NumberOfLinenumbers: 0 | |
| 2531 | CheckSum: 0 | |
| 2532 | Number: 9 | |
| 2533 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | |
| 2534 | - Name: '?f@A@@UEAAHXZ' | |
| 2535 | Value: 0 | |
| 2536 | SectionNumber: 4 | |
| 2537 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2538 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 2539 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 2540 | - Name: '??0A@@QEAA@XZ' | |
| 2541 | Value: 0 | |
| 2542 | SectionNumber: 5 | |
| 2543 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2544 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 2545 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 2546 | - Name: '?f@B@@UEAAHXZ' | |
| 2547 | Value: 16 | |
| 2548 | SectionNumber: 4 | |
| 2549 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2550 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 2551 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 2552 | - Name: '??0B@@QEAA@XZ' | |
| 2553 | Value: 0 | |
| 2554 | SectionNumber: 7 | |
| 2555 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2556 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 2557 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 2558 | - Name: '??0C@@QEAA@XZ' | |
| 2559 | Value: 32 | |
| 2560 | SectionNumber: 4 | |
| 2561 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2562 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 2563 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 2564 | - Name: '?f@C@@UEAAHXZ' | |
| 2565 | Value: 128 | |
| 2566 | SectionNumber: 4 | |
| 2567 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2568 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 2569 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 2570 | - Name: '?f@C@@W7EAAHXZ' | |
| 2571 | Value: 0 | |
| 2572 | SectionNumber: 9 | |
| 2573 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2574 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 2575 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 2576 | - Name: '$LN3' | |
| 2577 | Value: 32 | |
| 2578 | SectionNumber: 4 | |
| 2579 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2580 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2581 | StorageClass: IMAGE_SYM_CLASS_LABEL | |
| 2582 | - Name: .xdata | |
| 2583 | Value: 0 | |
| 2584 | SectionNumber: 11 | |
| 2585 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2586 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2587 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2588 | SectionDefinition: | |
| 2589 | Length: 8 | |
| 2590 | NumberOfRelocations: 0 | |
| 2591 | NumberOfLinenumbers: 0 | |
| 2592 | CheckSum: 2625142988 | |
| 2593 | Number: 0 | |
| 2594 | - Name: '$unwind$??0C@@QEAA@XZ' | |
| 2595 | Value: 0 | |
| 2596 | SectionNumber: 11 | |
| 2597 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2598 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2599 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2600 | - Name: .pdata | |
| 2601 | Value: 0 | |
| 2602 | SectionNumber: 12 | |
| 2603 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2604 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2605 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2606 | SectionDefinition: | |
| 2607 | Length: 12 | |
| 2608 | NumberOfRelocations: 3 | |
| 2609 | NumberOfLinenumbers: 0 | |
| 2610 | CheckSum: 1248454893 | |
| 2611 | Number: 0 | |
| 2612 | - Name: '$pdata$??0C@@QEAA@XZ' | |
| 2613 | Value: 0 | |
| 2614 | SectionNumber: 12 | |
| 2615 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2616 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2617 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2618 | - Name: .rdata | |
| 2619 | Value: 0 | |
| 2620 | SectionNumber: 13 | |
| 2621 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2622 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2623 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2624 | SectionDefinition: | |
| 2625 | Length: 8 | |
| 2626 | NumberOfRelocations: 1 | |
| 2627 | NumberOfLinenumbers: 0 | |
| 2628 | CheckSum: 0 | |
| 2629 | Number: 0 | |
| 2630 | Selection: IMAGE_COMDAT_SELECT_ANY | |
| 2631 | - Name: '??_7A@@6B@' | |
| 2632 | Value: 0 | |
| 2633 | SectionNumber: 13 | |
| 2634 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2635 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2636 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 2637 | - Name: .rdata | |
| 2638 | Value: 0 | |
| 2639 | SectionNumber: 14 | |
| 2640 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2641 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2642 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2643 | SectionDefinition: | |
| 2644 | Length: 8 | |
| 2645 | NumberOfRelocations: 1 | |
| 2646 | NumberOfLinenumbers: 0 | |
| 2647 | CheckSum: 0 | |
| 2648 | Number: 0 | |
| 2649 | Selection: IMAGE_COMDAT_SELECT_ANY | |
| 2650 | - Name: '??_7B@@6B@' | |
| 2651 | Value: 0 | |
| 2652 | SectionNumber: 14 | |
| 2653 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2654 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2655 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 2656 | - Name: .rdata | |
| 2657 | Value: 0 | |
| 2658 | SectionNumber: 15 | |
| 2659 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2660 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2661 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2662 | SectionDefinition: | |
| 2663 | Length: 8 | |
| 2664 | NumberOfRelocations: 1 | |
| 2665 | NumberOfLinenumbers: 0 | |
| 2666 | CheckSum: 0 | |
| 2667 | Number: 0 | |
| 2668 | Selection: IMAGE_COMDAT_SELECT_ANY | |
| 2669 | - Name: '??_7C@@6BA@@@' | |
| 2670 | Value: 0 | |
| 2671 | SectionNumber: 15 | |
| 2672 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2673 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2674 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 2675 | - Name: .rdata | |
| 2676 | Value: 0 | |
| 2677 | SectionNumber: 16 | |
| 2678 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2679 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2680 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2681 | SectionDefinition: | |
| 2682 | Length: 8 | |
| 2683 | NumberOfRelocations: 1 | |
| 2684 | NumberOfLinenumbers: 0 | |
| 2685 | CheckSum: 0 | |
| 2686 | Number: 0 | |
| 2687 | Selection: IMAGE_COMDAT_SELECT_ANY | |
| 2688 | - Name: '??_7C@@6BB@@@' | |
| 2689 | Value: 0 | |
| 2690 | SectionNumber: 16 | |
| 2691 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2692 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2693 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 2694 | - Name: '.debug$S' | |
| 2695 | Value: 0 | |
| 2696 | SectionNumber: 17 | |
| 2697 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2698 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2699 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2700 | SectionDefinition: | |
| 2701 | Length: 40 | |
| 2702 | NumberOfRelocations: 2 | |
| 2703 | NumberOfLinenumbers: 0 | |
| 2704 | CheckSum: 0 | |
| 2705 | Number: 13 | |
| 2706 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | |
| 2707 | - Name: '.debug$S' | |
| 2708 | Value: 0 | |
| 2709 | SectionNumber: 18 | |
| 2710 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2711 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2712 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2713 | SectionDefinition: | |
| 2714 | Length: 40 | |
| 2715 | NumberOfRelocations: 2 | |
| 2716 | NumberOfLinenumbers: 0 | |
| 2717 | CheckSum: 0 | |
| 2718 | Number: 14 | |
| 2719 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | |
| 2720 | - Name: '.debug$S' | |
| 2721 | Value: 0 | |
| 2722 | SectionNumber: 19 | |
| 2723 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2724 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2725 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2726 | SectionDefinition: | |
| 2727 | Length: 40 | |
| 2728 | NumberOfRelocations: 2 | |
| 2729 | NumberOfLinenumbers: 0 | |
| 2730 | CheckSum: 0 | |
| 2731 | Number: 15 | |
| 2732 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | |
| 2733 | - Name: '.debug$S' | |
| 2734 | Value: 0 | |
| 2735 | SectionNumber: 20 | |
| 2736 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 2737 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 2738 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 2739 | SectionDefinition: | |
| 2740 | Length: 40 | |
| 2741 | NumberOfRelocations: 2 | |
| 2742 | NumberOfLinenumbers: 0 | |
| 2743 | CheckSum: 0 | |
| 2744 | Number: 16 | |
| 2745 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | |
| 2746 | ... | |
| 2747 |
deps/lld/test/COFF/pdb-type-server-missing.yaml+2-5| ... | ... | @@ -1,13 +1,10 @@ |
| 1 | 1 | # This is an object compiled with /Zi (see the LF_TYPESERVER2 record) without an |
| 2 | 2 | # adjacent type server PDB. Test that LLD fails gracefully on it. |
| 3 | 3 | |
| 4 | # FIXME: Ideally we'd do what MSVC does, which is to warn and drop all debug | |
| 5 | # info in the object with the missing PDB. | |
| 6 | ||
| 7 | 4 | # RUN: yaml2obj %s -o %t.obj |
| 8 | # RUN: not lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s | |
| 5 | # RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s | |
| 9 | 6 | |
| 10 | # CHECK: error: Type server PDB was not found | |
| 7 | # CHECK: warning: Type server PDB for {{.*}}.obj is invalid, ignoring debug info. | |
| 11 | 8 | |
| 12 | 9 | --- !COFF |
| 13 | 10 | header: |
deps/lld/test/COFF/pdb-type-server-simple.test+14-10| ... | ... | @@ -21,7 +21,7 @@ RUN: yaml2obj %S/Inputs/pdb-type-server-simple-a.yaml -o a.obj |
| 21 | 21 | RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o b.obj |
| 22 | 22 | RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb |
| 23 | 23 | RUN: lld-link a.obj b.obj -entry:main -debug -out:t.exe -pdb:t.pdb -nodefaultlib |
| 24 | RUN: llvm-pdbutil dump -symbols -types -ids %t/t.pdb | FileCheck %s | |
| 24 | RUN: llvm-pdbutil dump -symbols -types -ids -globals %t/t.pdb | FileCheck %s | |
| 25 | 25 | |
| 26 | 26 | |
| 27 | 27 | CHECK-LABEL: Types (TPI Stream) |
| ... | ... | @@ -59,23 +59,29 @@ CHECK: {{.*}}: `a.c` |
| 59 | 59 | CHECK: [[B_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28] |
| 60 | 60 | CHECK: {{.*}}: `b.c` |
| 61 | 61 | |
| 62 | CHECK-LABEL: Global Symbols | |
| 63 | CHECK: ============================================================ | |
| 64 | CHECK-NEXT: Records | |
| 65 | CHECK-NEXT: 36 | S_PROCREF [size = 20] `main` | |
| 66 | CHECK-NEXT: module = 1, sum name = 0, offset = 104 | |
| 67 | CHECK-NEXT: 56 | S_PROCREF [size = 16] `g` | |
| 68 | CHECK-NEXT: module = 2, sum name = 0, offset = 104 | |
| 69 | ||
| 62 | 70 | CHECK-LABEL: Symbols |
| 63 | 71 | CHECK: ============================================================ |
| 64 | 72 | CHECK-LABEL: Mod 0000 | `{{.*}}a.obj`: |
| 65 | 73 | CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\a.obj` |
| 66 | CHECK: 104 | S_GPROC32_ID [size = 44] `main` | |
| 74 | CHECK: 104 | S_GPROC32 [size = 44] `main` | |
| 67 | 75 | CHECK: parent = 0, end = 196, addr = 0002:0000, code size = 27 |
| 68 | 76 | CHECK: type = {{.*}}, debug start = 4, debug end = 22, flags = none |
| 69 | CHECK: 200 | S_UDT [size = 12] `Foo` | |
| 70 | CHECK: original type = [[FOO_COMPLETE]] | |
| 71 | CHECK: 212 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]` | |
| 77 | CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]` | |
| 72 | 78 | CHECK-LABEL: Mod 0001 | `{{.*}}b.obj`: |
| 73 | 79 | CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\b.obj` |
| 74 | 80 | CHECK: 44 | S_COMPILE3 [size = 60] |
| 75 | 81 | CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c |
| 76 | 82 | CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 |
| 77 | 83 | CHECK: flags = security checks | hot patchable |
| 78 | CHECK: 104 | S_GPROC32_ID [size = 44] `g` | |
| 84 | CHECK: 104 | S_GPROC32 [size = 44] `g` | |
| 79 | 85 | CHECK: parent = 0, end = 196, addr = 0002:0032, code size = 13 |
| 80 | 86 | CHECK: type = {{.*}}, debug start = 5, debug end = 12, flags = none |
| 81 | 87 | CHECK: 148 | S_FRAMEPROC [size = 32] |
| ... | ... | @@ -83,9 +89,7 @@ CHECK: size = 0, padding size = 0, offset to padding = 0 |
| 83 | 89 | CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 |
| 84 | 90 | CHECK: flags = has async eh | opt speed |
| 85 | 91 | CHECK: 180 | S_REGREL32 [size = 16] `p` |
| 86 | CHECK: type = [[FOO_PTR]] (Foo*), register = rsp, offset = 8 | |
| 92 | CHECK: type = [[FOO_PTR]] (Foo*), register = RSP, offset = 8 | |
| 87 | 93 | CHECK: 196 | S_END [size = 4] |
| 88 | CHECK: 200 | S_UDT [size = 12] `Foo` | |
| 89 | CHECK: original type = [[FOO_COMPLETE]] | |
| 90 | CHECK: 212 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]` | |
| 94 | CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]` | |
| 91 | 95 | CHECK-LABEL: Mod 0002 | `* Linker *`: |
deps/lld/test/COFF/pdb.test+123-37| ... | ... | @@ -1,13 +1,15 @@ |
| 1 | 1 | # RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj |
| 2 | 2 | # RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj |
| 3 | # RUN: rm -f %t.dll %t.pdb | |
| 3 | 4 | # RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \ |
| 4 | 5 | # RUN: %t1.obj %t2.obj |
| 5 | 6 | |
| 6 | 7 | # RUN: llvm-pdbutil pdb2yaml -stream-metadata -stream-directory -pdb-stream \ |
| 7 | 8 | # RUN: -dbi-stream -ipi-stream -tpi-stream %t.pdb | FileCheck %s |
| 8 | 9 | |
| 9 | # RUN: llvm-pdbutil dump -modules -section-map -section-contribs \ | |
| 10 | # RUN: -types -ids %t.pdb | FileCheck -check-prefix RAW %s | |
| 10 | # RUN: llvm-pdbutil dump -modules -section-map -section-contribs -section-headers \ | |
| 11 | # RUN: -publics -public-extras -types -ids -type-extras -id-extras %t.pdb \ | |
| 12 | # RUN: | FileCheck -check-prefix RAW %s | |
| 11 | 13 | |
| 12 | 14 | # CHECK: MSF: |
| 13 | 15 | # CHECK-NEXT: SuperBlock: |
| ... | ... | @@ -117,86 +119,170 @@ |
| 117 | 119 | |
| 118 | 120 | RAW: Modules |
| 119 | 121 | RAW-NEXT: ============================================================ |
| 120 | RAW-NEXT: Mod 0000 | Name: `{{.*}}pdb.test.tmp1.obj`: | |
| 122 | RAW-NEXT: Mod 0000 | `{{.*}}pdb.test.tmp1.obj`: | |
| 121 | 123 | RAW-NEXT: Obj: `{{.*}}pdb.test.tmp1.obj`: |
| 122 | 124 | RAW-NEXT: debug stream: 9, # files: 1, has ec info: false |
| 123 | 125 | RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` |
| 124 | RAW-NEXT: Mod 0001 | Name: `{{.*}}pdb.test.tmp2.obj`: | |
| 126 | RAW-NEXT: Mod 0001 | `{{.*}}pdb.test.tmp2.obj`: | |
| 125 | 127 | RAW-NEXT: Obj: `{{.*}}pdb.test.tmp2.obj`: |
| 126 | 128 | RAW-NEXT: debug stream: 10, # files: 1, has ec info: false |
| 127 | 129 | RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` |
| 128 | RAW-NEXT: Mod 0002 | Name: `* Linker *`: | |
| 130 | RAW-NEXT: Mod 0002 | `* Linker *`: | |
| 129 | 131 | RAW-NEXT: Obj: ``: |
| 130 | 132 | RAW-NEXT: debug stream: 11, # files: 0, has ec info: false |
| 131 | 133 | RAW-NEXT: pdb file ni: 1 `{{.*pdb.test.tmp.pdb}}`, src file ni: 0 `` |
| 132 | 134 | RAW: Types (TPI Stream) |
| 133 | 135 | RAW-NEXT: ============================================================ |
| 134 | 136 | RAW-NEXT: Showing 5 records |
| 135 | RAW-NEXT: 0x1000 | LF_ARGLIST [size = 8] | |
| 136 | RAW-NEXT: 0x1001 | LF_PROCEDURE [size = 16] | |
| 137 | RAW-NEXT: 0x1000 | LF_ARGLIST [size = 8, hash = 0xEC0] | |
| 138 | RAW-NEXT: 0x1001 | LF_PROCEDURE [size = 16, hash = 0x7BC] | |
| 137 | 139 | RAW-NEXT: return type = 0x0074 (int), # args = 0, param list = 0x1000 |
| 138 | 140 | RAW-NEXT: calling conv = cdecl, options = None |
| 139 | RAW-NEXT: 0x1002 | LF_POINTER [size = 12] | |
| 141 | RAW-NEXT: 0x1002 | LF_POINTER [size = 12, hash = 0x884] | |
| 140 | 142 | RAW-NEXT: referent = 0x1001, mode = pointer, opts = None, kind = ptr64 |
| 141 | RAW-NEXT: 0x1003 | LF_ARGLIST [size = 12] | |
| 143 | RAW-NEXT: 0x1003 | LF_ARGLIST [size = 12, hash = 0x936] | |
| 142 | 144 | RAW-NEXT: <no type>: `` |
| 143 | RAW-NEXT: 0x1004 | LF_PROCEDURE [size = 16] | |
| 145 | RAW-NEXT: 0x1004 | LF_PROCEDURE [size = 16, hash = 0x852] | |
| 144 | 146 | RAW-NEXT: return type = 0x0074 (int), # args = 0, param list = 0x1003 |
| 145 | 147 | RAW-NEXT: calling conv = cdecl, options = None |
| 146 | 148 | RAW: Types (IPI Stream) |
| 147 | 149 | RAW-NEXT: ============================================================ |
| 148 | 150 | RAW-NEXT: Showing 12 records |
| 149 | RAW-NEXT: 0x1000 | LF_FUNC_ID [size = 20] | |
| 151 | RAW-NEXT: 0x1000 | LF_FUNC_ID [size = 20, hash = 0x330] | |
| 150 | 152 | RAW-NEXT: name = main, type = 0x1004, parent scope = <no type> |
| 151 | RAW-NEXT: 0x1001 | LF_FUNC_ID [size = 16] | |
| 153 | RAW-NEXT: 0x1001 | LF_FUNC_ID [size = 16, hash = 0x120] | |
| 152 | 154 | RAW-NEXT: name = foo, type = 0x1001, parent scope = <no type> |
| 153 | RAW-NEXT: 0x1002 | LF_STRING_ID [size = 16] ID: <no type>, String: D:\b | |
| 154 | RAW-NEXT: 0x1003 | LF_STRING_ID [size = 36] ID: <no type>, String: C:\vs14\VC\BIN\amd64\cl.exe | |
| 155 | RAW-NEXT: 0x1004 | LF_STRING_ID [size = 260] ID: <no type>, String: -Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared" | |
| 156 | RAW-NEXT: 0x1005 | LF_SUBSTR_LIST [size = 12] | |
| 155 | RAW-NEXT: 0x1002 | LF_STRING_ID [size = 16, hash = 0x757] ID: <no type>, String: D:\b | |
| 156 | RAW-NEXT: 0x1003 | LF_STRING_ID [size = 36, hash = 0xC3A] ID: <no type>, String: C:\vs14\VC\BIN\amd64\cl.exe | |
| 157 | RAW-NEXT: 0x1004 | LF_STRING_ID [size = 260, hash = 0x433] ID: <no type>, String: -Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared" | |
| 158 | RAW-NEXT: 0x1005 | LF_SUBSTR_LIST [size = 12, hash = 0x759] | |
| 157 | 159 | RAW-NEXT: 0x1004: `-Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"` |
| 158 | RAW-NEXT: 0x1006 | LF_STRING_ID [size = 132] ID: 0x1005, String: -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X | |
| 159 | RAW-NEXT: 0x1007 | LF_STRING_ID [size = 24] ID: <no type>, String: ret42-main.c | |
| 160 | RAW-NEXT: 0x1008 | LF_STRING_ID [size = 24] ID: <no type>, String: D:\b\vc140.pdb | |
| 161 | RAW-NEXT: 0x1009 | LF_BUILDINFO [size = 28] | |
| 160 | RAW-NEXT: 0x1006 | LF_STRING_ID [size = 132, hash = 0xF57] ID: 0x1005, String: -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X | |
| 161 | RAW-NEXT: 0x1007 | LF_STRING_ID [size = 24, hash = 0x2D1] ID: <no type>, String: ret42-main.c | |
| 162 | RAW-NEXT: 0x1008 | LF_STRING_ID [size = 24, hash = 0xB8B] ID: <no type>, String: D:\b\vc140.pdb | |
| 163 | RAW-NEXT: 0x1009 | LF_BUILDINFO [size = 28, hash = 0xA8C] | |
| 162 | 164 | RAW-NEXT: 0x1002: `D:\b` |
| 163 | 165 | RAW-NEXT: 0x1003: `C:\vs14\VC\BIN\amd64\cl.exe` |
| 164 | 166 | RAW-NEXT: 0x1007: `ret42-main.c` |
| 165 | 167 | RAW-NEXT: 0x1008: `D:\b\vc140.pdb` |
| 166 | 168 | RAW-NEXT: 0x1006: ` -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X` |
| 167 | RAW-NEXT: 0x100A | LF_STRING_ID [size = 20] ID: <no type>, String: ret42-sub.c | |
| 168 | RAW-NEXT: 0x100B | LF_BUILDINFO [size = 28] | |
| 169 | RAW-NEXT: 0x100A | LF_STRING_ID [size = 20, hash = 0x39C] ID: <no type>, String: ret42-sub.c | |
| 170 | RAW-NEXT: 0x100B | LF_BUILDINFO [size = 28, hash = 0xAD7] | |
| 169 | 171 | RAW-NEXT: 0x1002: `D:\b` |
| 170 | 172 | RAW-NEXT: 0x1003: `C:\vs14\VC\BIN\amd64\cl.exe` |
| 171 | 173 | RAW-NEXT: 0x100A: `ret42-sub.c` |
| 172 | 174 | RAW-NEXT: 0x1008: `D:\b\vc140.pdb` |
| 173 | 175 | RAW-NEXT: 0x1006: ` -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X` |
| 176 | RAW: Public Symbols | |
| 177 | RAW-NEXT: ============================================================ | |
| 178 | RAW-NEXT: Publics Header | |
| 179 | RAW-NEXT: sym hash = 556, thunk table addr = 0000:0000 | |
| 180 | RAW-NEXT: GSI Header | |
| 181 | RAW-NEXT: sig = 0xFFFFFFFF, hdr = 0xF12F091A, hr size = 16, num buckets = 524 | |
| 182 | RAW-NEXT: Records | |
| 183 | RAW-NEXT: 20 | S_PUB32 [size = 20] `main` | |
| 184 | RAW-NEXT: flags = function, addr = 0002:0000 | |
| 185 | RAW-NEXT: 0 | S_PUB32 [size = 20] `foo` | |
| 186 | RAW-NEXT: flags = function, addr = 0002:0016 | |
| 187 | RAW-NOT: S_PUB32 | |
| 188 | RAW-NEXT: Hash Entries | |
| 189 | RAW-NEXT: off = 21, refcnt = 1 | |
| 190 | RAW-NEXT: off = 1, refcnt = 1 | |
| 191 | RAW-NEXT: Hash Buckets | |
| 192 | RAW-NEXT: 0x00000000 | |
| 193 | RAW-NEXT: 0x0000000c | |
| 194 | RAW-NEXT: Address Map | |
| 195 | RAW-NEXT: off = 20 | |
| 196 | RAW-NEXT: off = 0 | |
| 197 | RAW: Section Headers | |
| 198 | RAW-NEXT: ============================================================ | |
| 199 | RAW: SECTION HEADER #1 | |
| 200 | RAW-NEXT: .pdata name | |
| 201 | RAW-NEXT: virtual size | |
| 202 | RAW-NEXT: 1000 virtual address | |
| 203 | RAW-NEXT: 200 size of raw data | |
| 204 | RAW-NEXT: 400 file pointer to raw data | |
| 205 | RAW-NEXT: 0 file pointer to relocation table | |
| 206 | RAW-NEXT: 0 file pointer to line numbers | |
| 207 | RAW-NEXT: 0 number of relocations | |
| 208 | RAW-NEXT: 0 number of line numbers | |
| 209 | RAW-NEXT: 40000040 flags | |
| 210 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | |
| 211 | RAW-NEXT: IMAGE_SCN_MEM_READ | |
| 212 | RAW: SECTION HEADER #2 | |
| 213 | RAW-NEXT: .text name | |
| 214 | RAW-NEXT: virtual size | |
| 215 | RAW-NEXT: 2000 virtual address | |
| 216 | RAW-NEXT: 200 size of raw data | |
| 217 | RAW-NEXT: 600 file pointer to raw data | |
| 218 | RAW-NEXT: 0 file pointer to relocation table | |
| 219 | RAW-NEXT: 0 file pointer to line numbers | |
| 220 | RAW-NEXT: 0 number of relocations | |
| 221 | RAW-NEXT: 0 number of line numbers | |
| 222 | RAW-NEXT: 60000020 flags | |
| 223 | RAW-NEXT: IMAGE_SCN_CNT_CODE | |
| 224 | RAW-NEXT: IMAGE_SCN_MEM_EXECUTE | |
| 225 | RAW-NEXT: IMAGE_SCN_MEM_READ | |
| 226 | RAW: SECTION HEADER #3 | |
| 227 | RAW-NEXT: .xdata name | |
| 228 | RAW-NEXT: virtual size | |
| 229 | RAW-NEXT: 3000 virtual address | |
| 230 | RAW-NEXT: 200 size of raw data | |
| 231 | RAW-NEXT: 800 file pointer to raw data | |
| 232 | RAW-NEXT: 0 file pointer to relocation table | |
| 233 | RAW-NEXT: 0 file pointer to line numbers | |
| 234 | RAW-NEXT: 0 number of relocations | |
| 235 | RAW-NEXT: 0 number of line numbers | |
| 236 | RAW-NEXT: 40000040 flags | |
| 237 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | |
| 238 | 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 | |
| 253 | RAW-NEXT: ============================================================ | |
| 254 | RAW-NEXT: PDB does not contain the requested image section header type | |
| 174 | 255 | RAW: Section Contributions |
| 175 | 256 | RAW-NEXT: ============================================================ |
| 176 | RAW-NEXT: SC | mod = 0, 65535:1288, size = 14, data crc = 0, reloc crc = 0 | |
| 177 | RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | | |
| 178 | RAW-NEXT: IMAGE_SCN_MEM_READ | |
| 179 | RAW-NEXT: SC | mod = 0, 65535:1312, size = 8, data crc = 0, reloc crc = 0 | |
| 180 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ | |
| 181 | RAW-NEXT: SC | mod = 0, 65535:1320, size = 12, data crc = 0, reloc crc = 0 | |
| 182 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ | |
| 183 | RAW-NEXT: SC | mod = 1, 65535:1144, size = 6, data crc = 0, reloc crc = 0 | |
| 184 | RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | | |
| 185 | RAW-NEXT: IMAGE_SCN_MEM_READ | |
| 257 | RAW-NEXT: SC[.pdata] | mod = 0, 0001:0000, size = 12, data crc = 361370162, reloc crc = 0 | |
| 258 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ | |
| 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 | | |
| 261 | RAW-NEXT: IMAGE_SCN_MEM_READ | |
| 262 | RAW-NEXT: SC[.text] | mod = 1, 0002:0016, size = 6, data crc = 2139436471, reloc crc = 0 | |
| 263 | RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | | |
| 264 | RAW-NEXT: IMAGE_SCN_MEM_READ | |
| 265 | RAW-NEXT: SC[.xdata] | mod = 0, 0003:0000, size = 8, data crc = 264583633, 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 | |
| 269 | RAW-NEXT: SC[???] | mod = 2, 0004:0028, size = {{[0-9]+}}, data crc = 0, reloc crc = 0 | |
| 270 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | |
| 271 | RAW-NOT: SC[ | |
| 186 | 272 | RAW: Section Map |
| 187 | 273 | RAW-NEXT: ============================================================ |
| 188 | RAW-NEXT: Section 0000 | ovl = 0, group = 0, frame = 0, name = 1 | |
| 274 | RAW-NEXT: Section 0000 | ovl = 0, group = 0, frame = 1, name = 65535 | |
| 189 | 275 | RAW-NEXT: class = 65535, offset = 0, size = |
| 190 | 276 | RAW-NEXT: flags = read | 32 bit addr | selector |
| 191 | RAW-NEXT: Section 0001 | ovl = 1, group = 0, frame = 0, name = 2 | |
| 277 | RAW-NEXT: Section 0001 | ovl = 0, group = 0, frame = 2, name = 65535 | |
| 192 | 278 | RAW-NEXT: class = 65535, offset = 0, size = |
| 193 | 279 | RAW-NEXT: flags = read | execute | 32 bit addr | selector |
| 194 | RAW-NEXT: Section 0002 | ovl = 2, group = 0, frame = 0, name = 3 | |
| 280 | RAW-NEXT: Section 0002 | ovl = 0, group = 0, frame = 3, name = 65535 | |
| 195 | 281 | RAW-NEXT: class = 65535, offset = 0, size = |
| 196 | 282 | RAW-NEXT: flags = read | 32 bit addr | selector |
| 197 | RAW-NEXT: Section 0003 | ovl = 3, group = 0, frame = 0, name = 4 | |
| 283 | RAW-NEXT: Section 0003 | ovl = 0, group = 0, frame = 4, name = 65535 | |
| 198 | 284 | RAW-NEXT: class = 65535, offset = 0, size = |
| 199 | 285 | RAW-NEXT: flags = read | 32 bit addr | selector |
| 200 | RAW-NEXT: Section 0004 | ovl = 4, group = 0, frame = 0, name = 5 | |
| 286 | RAW-NEXT: Section 0004 | ovl = 0, group = 0, frame = 5, name = 65535 | |
| 201 | 287 | RAW-NEXT: class = 65535, offset = 0, size = |
| 202 | 288 | RAW-NEXT: flags = 32 bit addr | absolute addr |
deps/lld/test/COFF/reloc-arm.test+8-8| ... | ... | @@ -28,28 +28,28 @@ sections: |
| 28 | 28 | Relocations: |
| 29 | 29 | - VirtualAddress: 0 |
| 30 | 30 | SymbolName: foo |
| 31 | Type: 1 # IMAGE_REL_ARM_ADDR32 | |
| 31 | Type: IMAGE_REL_ARM_ADDR32 | |
| 32 | 32 | - VirtualAddress: 16 |
| 33 | 33 | SymbolName: foo |
| 34 | Type: 2 # IMAGE_REL_ARM_ADDR32NB | |
| 34 | Type: IMAGE_REL_ARM_ADDR32NB | |
| 35 | 35 | - VirtualAddress: 32 |
| 36 | 36 | SymbolName: foo |
| 37 | Type: 17 # IMAGE_REL_ARM_MOV32T | |
| 37 | Type: IMAGE_REL_ARM_MOV32T | |
| 38 | 38 | - VirtualAddress: 48 |
| 39 | 39 | SymbolName: foo |
| 40 | Type: 20 # IMAGE_REL_ARM_BRANCH24T | |
| 40 | Type: IMAGE_REL_ARM_BRANCH24T | |
| 41 | 41 | - VirtualAddress: 64 |
| 42 | 42 | SymbolName: foo |
| 43 | Type: 18 # IMAGE_REL_ARM_BRANCH20T | |
| 43 | Type: IMAGE_REL_ARM_BRANCH20T | |
| 44 | 44 | - VirtualAddress: 80 |
| 45 | 45 | SymbolName: foo |
| 46 | Type: 21 # IMAGE_REL_ARM_BLX23T | |
| 46 | Type: IMAGE_REL_ARM_BLX23T | |
| 47 | 47 | - VirtualAddress: 96 |
| 48 | 48 | SymbolName: bar |
| 49 | Type: 20 # IMAGE_REL_ARM_BRANCH24T | |
| 49 | Type: IMAGE_REL_ARM_BRANCH24T | |
| 50 | 50 | - VirtualAddress: 112 |
| 51 | 51 | SymbolName: bar |
| 52 | Type: 15 # IMAGE_REL_ARM_SECREL | |
| 52 | Type: IMAGE_REL_ARM_SECREL | |
| 53 | 53 | symbols: |
| 54 | 54 | - Name: .aaa |
| 55 | 55 | Value: 0 |
deps/lld/test/COFF/reloc-discarded-dwarf.s+2| ... | ... | @@ -13,3 +13,5 @@ f: |
| 13 | 13 | |
| 14 | 14 | 	.section	.debug_info,"dr" |
| 15 | 15 | 	.quad	f |
| 16 | 	.section	.eh_frame,"dr" | |
| 17 | 	.quad	f |
deps/lld/test/COFF/reloc-discarded-early.s created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | # 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 | ||
| 4 | .section .debug_info,"dr" | |
| 5 | .quad .Ldrectve | |
| 6 | ||
| 7 | .section .drectve | |
| 8 | .Ldrectve: |
deps/lld/test/COFF/reloc-discarded-early2.s created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | # 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 | ||
| 4 | .text | |
| 5 | # CHECK: error: relocation against symbol in discarded section: .drectve | |
| 6 | .quad .Ldrectve | |
| 7 | ||
| 8 | .section .drectve | |
| 9 | .Ldrectve: |
deps/lld/test/COFF/reloc-discarded.s-1| ... | ... | @@ -18,7 +18,6 @@ main_global: |
| 18 | 18 | |
| 19 | 19 | 	.section	.CRT$XCU,"dr",associative,main_global |
| 20 | 20 | 	.p2align	3 |
| 21 | 	.globl assoc_global | |
| 22 | 21 | assoc_global: |
| 23 | 22 | 	.quad	main_global |
| 24 | 23 |
deps/lld/test/COFF/responsefile.test+19-1| ... | ... | @@ -3,5 +3,23 @@ |
| 3 | 3 | # RUN: echo /out:%t.exe /entry:main %t.obj > %t.rsp |
| 4 | 4 | # RUN: lld-link @%t.rsp /heap:0x3000 |
| 5 | 5 | # RUN: llvm-readobj -file-headers %t.exe | FileCheck %s |
| 6 | ||
| 7 | 6 | CHECK: SizeOfHeapReserve: 12288 |
| 7 | ||
| 8 | # RUN: not lld-link --rsp-quoting=foobar @%t.rsp 2>&1 | \ | |
| 9 | # RUN: FileCheck --check-prefix=INVRSP %s | |
| 10 | INVRSP: invalid response file quoting: foobar | |
| 11 | ||
| 12 | # RUN: echo "blah\foo" > %t.rsp | |
| 13 | # RUN: not lld-link @%t.rsp 2>&1 | \ | |
| 14 | # RUN: FileCheck --check-prefix=DEFRSP %s | |
| 15 | DEFRSP: error: could not open blah\foo | |
| 16 | ||
| 17 | # RUN: echo "blah\foo" > %t.rsp | |
| 18 | # RUN: not lld-link --rsp-quoting=windows @%t.rsp 2>&1 | \ | |
| 19 | # RUN: FileCheck --check-prefix=WINRSP %s | |
| 20 | WINRSP: error: could not open blah\foo | |
| 21 | ||
| 22 | # RUN: echo "blah\foo" > %t.rsp | |
| 23 | # RUN: not lld-link --rsp-quoting=posix @%t.rsp 2>&1 | \ | |
| 24 | # RUN: FileCheck --check-prefix=POSRSP %s | |
| 25 | POSRSP: error: could not open blahfoo |
deps/lld/test/COFF/rsds.test+34-6| ... | ... | @@ -1,11 +1,20 @@ |
| 1 | 1 | # RUN: yaml2obj %s > %t.obj |
| 2 | 2 | |
| 3 | # RUN: rm -f %t.dll %t.pdb | |
| 3 | 4 | # RUN: lld-link /debug /dll /out:%t.dll /entry:DllMain %t.obj |
| 4 | # RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck %s | |
| 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 | |
| 7 | # RUN: llvm-readobj -coff-debug-directory %t.dll > %t.2.txt | |
| 8 | # RUN: cat %t.1.txt %t.2.txt | FileCheck %s | |
| 5 | 9 | |
| 10 | # RUN: rm -f %t.dll %t.pdb | |
| 11 | # RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:DllMain %t.obj | |
| 12 | # RUN: llvm-readobj -coff-debug-directory %t.dll > %t.3.txt | |
| 6 | 13 | # RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:DllMain %t.obj |
| 7 | # RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck %s | |
| 14 | # RUN: llvm-readobj -coff-debug-directory %t.dll > %t.4.txt | |
| 15 | # RUN: cat %t.3.txt %t.4.txt | FileCheck %s | |
| 8 | 16 | |
| 17 | # CHECK: File: [[FILE:.*]].dll | |
| 9 | 18 | # CHECK: DebugDirectory [ |
| 10 | 19 | # CHECK: DebugEntry { |
| 11 | 20 | # CHECK: Characteristics: 0x0 |
| ... | ... | @@ -13,17 +22,36 @@ |
| 13 | 22 | # CHECK: MajorVersion: 0x0 |
| 14 | 23 | # CHECK: MinorVersion: 0x0 |
| 15 | 24 | # CHECK: Type: CodeView (0x2) |
| 16 | # CHECK: SizeOfData: | |
| 17 | # CHECK: AddressOfRawData: | |
| 18 | # CHECK: PointerToRawData: | |
| 25 | # CHECK: SizeOfData: 0x{{[^0]}} | |
| 26 | # CHECK: AddressOfRawData: 0x{{[^0]}} | |
| 27 | # CHECK: PointerToRawData: 0x{{[^0]}} | |
| 19 | 28 | # CHECK: PDBInfo { |
| 20 | 29 | # CHECK: PDBSignature: 0x53445352 |
| 21 | # CHECK: PDBGUID: | |
| 30 | # CHECK: PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]] | |
| 22 | 31 | # CHECK: PDBAge: 1 |
| 23 | 32 | # CHECK: PDBFileName: {{.*}}.pdb |
| 24 | 33 | # CHECK: } |
| 25 | 34 | # CHECK: } |
| 26 | 35 | # CHECK: ] |
| 36 | # CHECK: File: [[FILE]].dll | |
| 37 | # CHECK: DebugDirectory [ | |
| 38 | # CHECK: DebugEntry { | |
| 39 | # CHECK: Characteristics: 0x0 | |
| 40 | # CHECK: TimeDateStamp: 1970-01-01 00:00:00 (0x0) | |
| 41 | # CHECK: MajorVersion: 0x0 | |
| 42 | # CHECK: MinorVersion: 0x0 | |
| 43 | # CHECK: Type: CodeView (0x2) | |
| 44 | # CHECK: SizeOfData: 0x{{[^0]}} | |
| 45 | # CHECK: AddressOfRawData: 0x{{[^0]}} | |
| 46 | # CHECK: PointerToRawData: 0x{{[^0]}} | |
| 47 | # CHECK: PDBInfo { | |
| 48 | # CHECK: PDBSignature: 0x53445352 | |
| 49 | # CHECK: PDBGUID: [[GUID]] | |
| 50 | # CHECK: PDBAge: 2 | |
| 51 | # CHECK: PDBFileName: {{.*}}.pdb | |
| 52 | # CHECK: } | |
| 53 | # CHECK: } | |
| 54 | # CHECK: ] | |
| 27 | 55 | |
| 28 | 56 | --- !COFF |
| 29 | 57 | header: |
deps/lld/test/COFF/safeseh-md.s created+34| ... | ... | @@ -0,0 +1,34 @@ |
| 1 | # 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: llvm-readobj -coff-load-config %t.exe | FileCheck %s | |
| 4 | ||
| 5 | # CHECK: SEHTable [ | |
| 6 | # CHECK-NEXT: 0x | |
| 7 | # CHECK-NEXT: ] | |
| 8 | ||
| 9 | .def @feat.00; | |
| 10 | .scl 3; | |
| 11 | .type 0; | |
| 12 | .endef | |
| 13 | .globl @feat.00 | |
| 14 | @feat.00 = 1 | |
| 15 | ||
| 16 | .def _main; | |
| 17 | .scl 2; | |
| 18 | .type 32; | |
| 19 | .endef | |
| 20 | .section .text,"xr",one_only,_main | |
| 21 | .globl _main | |
| 22 | _main: | |
| 23 | movl $42, %eax | |
| 24 | ret | |
| 25 | ||
| 26 | .safeseh __except_handler3 | |
| 27 | ||
| 28 | 	.section .rdata,"dr" | |
| 29 | .globl __load_config_used | |
| 30 | __load_config_used: | |
| 31 | .long 72 | |
| 32 | .fill 60, 1, 0 | |
| 33 | .long ___safe_se_handler_table | |
| 34 | .long ___safe_se_handler_count |
deps/lld/test/COFF/safeseh.s+13-2| ... | ... | @@ -1,9 +1,15 @@ |
| 1 | 1 | # RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj |
| 2 | 2 | # RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:noref -entry:main |
| 3 | # RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC | |
| 3 | # RUN: llvm-readobj -coff-basereloc -coff-load-config -file-headers %t.exe | FileCheck %s --check-prefix=CHECK-NOGC | |
| 4 | 4 | # RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:ref -entry:main |
| 5 | # RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-GC | |
| 5 | # RUN: llvm-readobj -coff-basereloc -coff-load-config -file-headers %t.exe | FileCheck %s --check-prefix=CHECK-GC | |
| 6 | 6 | |
| 7 | # __safe_se_handler_table needs to be relocated against ImageBase. | |
| 8 | # check that the relocation is present. | |
| 9 | # CHECK-NOGC-NOT: IMAGE_DLL_CHARACTERISTICS_NO_SEH | |
| 10 | # CHECK-NOGC: BaseReloc [ | |
| 11 | # CHECK-NOGC: Entry { | |
| 12 | # CHECK-NOGC: Type: HIGHLOW | |
| 7 | 13 | # CHECK-NOGC: LoadConfig [ |
| 8 | 14 | # CHECK-NOGC: Size: 0x48 |
| 9 | 15 | # CHECK-NOGC: SEHandlerTable: 0x401048 |
| ... | ... | @@ -13,6 +19,11 @@ |
| 13 | 19 | # CHECK-NOGC-NEXT: 0x402006 |
| 14 | 20 | # CHECK-NOGC-NEXT: ] |
| 15 | 21 | |
| 22 | # Without the SEH table, the address is absolute, so check that we do | |
| 23 | # not have a relocation for it. | |
| 24 | # CHECK-GC-NOT: IMAGE_DLL_CHARACTERISTICS_NO_SEH | |
| 25 | # CHECK-GC: BaseReloc [ | |
| 26 | # CHECK-GC-NEXT: ] | |
| 16 | 27 | # CHECK-GC: LoadConfig [ |
| 17 | 28 | # CHECK-GC: Size: 0x48 |
| 18 | 29 | # CHECK-GC: SEHandlerTable: 0x0 |
deps/lld/test/COFF/section-size.s created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc %s -o %tmain.obj | |
| 3 | # RUN: echo '.lcomm s, 0x80000000' | llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %t1.obj | |
| 4 | # RUN: cp %t1.obj %t2.obj | |
| 5 | # RUN: echo '.lcomm s, 0xffffffff' | llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %t3.obj | |
| 6 | ||
| 7 | # Run: lld-link -entry:main %tmain.obj %t3.obj -out:%t.exe | |
| 8 | ||
| 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 | |
| 11 | ||
| 12 | .globl main | |
| 13 | main: | |
| 14 | 	retq |
deps/lld/test/COFF/seh-comdat.test created+66| ... | ... | @@ -0,0 +1,66 @@ |
| 1 | # RUN: yaml2obj < %s > %t1.obj | |
| 2 | # RUN: yaml2obj < %s > %t2.obj | |
| 3 | # RUN: lld-link /out:%t.exe /subsystem:console /entry:main %t1.obj %t2.obj | |
| 4 | # RUN: llvm-objdump -s %t.exe | FileCheck %s | |
| 5 | ||
| 6 | # CHECK: Contents of section .rdata: | |
| 7 | # CHECK: 1000 00200000 | |
| 8 | ||
| 9 | --- !COFF | |
| 10 | header: | |
| 11 | Machine: IMAGE_FILE_MACHINE_I386 | |
| 12 | Characteristics: [ ] | |
| 13 | sections: | |
| 14 | - Name: .text | |
| 15 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ, IMAGE_SCN_LNK_COMDAT ] | |
| 16 | Alignment: 1 | |
| 17 | SectionData: 0000000000000000 | |
| 18 | - Name: .sxdata | |
| 19 | Characteristics: [ IMAGE_SCN_LNK_INFO ] | |
| 20 | Alignment: 4 | |
| 21 | SectionData: 02000000 | |
| 22 | symbols: | |
| 23 | - Name: '@comp.id' | |
| 24 | Value: 14766605 | |
| 25 | SectionNumber: 65535 | |
| 26 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 27 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 28 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 29 | - Name: '@feat.00' | |
| 30 | Value: 2147484049 | |
| 31 | SectionNumber: 65535 | |
| 32 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 33 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 34 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 35 | - Name: .text | |
| 36 | Value: 0 | |
| 37 | SectionNumber: 1 | |
| 38 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 39 | ComplexType: IMAGE_SYM_DTYPE_NULL | |
| 40 | StorageClass: IMAGE_SYM_CLASS_STATIC | |
| 41 | SectionDefinition: | |
| 42 | Length: 4 | |
| 43 | NumberOfRelocations: 0 | |
| 44 | NumberOfLinenumbers: 0 | |
| 45 | CheckSum: 0 | |
| 46 | Number: 0 | |
| 47 | Selection: IMAGE_COMDAT_SELECT_ANY | |
| 48 | - Name: .sxdata | |
| 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: 8 | |
| 56 | NumberOfRelocations: 0 | |
| 57 | NumberOfLinenumbers: 0 | |
| 58 | CheckSum: 0 | |
| 59 | Number: 0 | |
| 60 | - Name: _main | |
| 61 | Value: 0 | |
| 62 | SectionNumber: 1 | |
| 63 | SimpleType: IMAGE_SYM_TYPE_NULL | |
| 64 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | |
| 65 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | |
| 66 | ... |
deps/lld/test/COFF/strtab-size.s created+216| ... | ... | @@ -0,0 +1,216 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # Test that the strtab size is included in the allocation even if the | |
| 4 | # strtab itself is empty. To achieve this, we need a number of symbols N | |
| 5 | # where alignTo(N*18, 512) < alignTo(N*18 + 4, 512), where the first | |
| 6 | # positive N fulfilling that is 199. | |
| 7 | ||
| 8 | # RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t.obj | |
| 9 | # RUN: lld-link -out:%t.exe -entry:main %t.obj -debug:dwarf | |
| 10 | ||
| 11 | # If the size of the strtab isn't allocated for, llvm-readobj would | |
| 12 | # output SymbolCount: 0 (and dumpbin.exe would error out with "invalid file | |
| 13 | # or disk full, cannot seek to 0x1602"). | |
| 14 | ||
| 15 | # RUN: llvm-readobj -file-headers %t.exe | FileCheck %s | |
| 16 | # CHECK: SymbolCount: 199 | |
| 17 | ||
| 18 | .global main | |
| 19 | .text | |
| 20 | main: | |
| 21 | sym0: | |
| 22 | sym1: | |
| 23 | sym2: | |
| 24 | sym3: | |
| 25 | sym4: | |
| 26 | sym5: | |
| 27 | sym6: | |
| 28 | sym7: | |
| 29 | sym8: | |
| 30 | sym9: | |
| 31 | sym10: | |
| 32 | sym11: | |
| 33 | sym12: | |
| 34 | sym13: | |
| 35 | sym14: | |
| 36 | sym15: | |
| 37 | sym16: | |
| 38 | sym17: | |
| 39 | sym18: | |
| 40 | sym19: | |
| 41 | sym20: | |
| 42 | sym21: | |
| 43 | sym22: | |
| 44 | sym23: | |
| 45 | sym24: | |
| 46 | sym25: | |
| 47 | sym26: | |
| 48 | sym27: | |
| 49 | sym28: | |
| 50 | sym29: | |
| 51 | sym30: | |
| 52 | sym31: | |
| 53 | sym32: | |
| 54 | sym33: | |
| 55 | sym34: | |
| 56 | sym35: | |
| 57 | sym36: | |
| 58 | sym37: | |
| 59 | sym38: | |
| 60 | sym39: | |
| 61 | sym40: | |
| 62 | sym41: | |
| 63 | sym42: | |
| 64 | sym43: | |
| 65 | sym44: | |
| 66 | sym45: | |
| 67 | sym46: | |
| 68 | sym47: | |
| 69 | sym48: | |
| 70 | sym49: | |
| 71 | sym50: | |
| 72 | sym51: | |
| 73 | sym52: | |
| 74 | sym53: | |
| 75 | sym54: | |
| 76 | sym55: | |
| 77 | sym56: | |
| 78 | sym57: | |
| 79 | sym58: | |
| 80 | sym59: | |
| 81 | sym60: | |
| 82 | sym61: | |
| 83 | sym62: | |
| 84 | sym63: | |
| 85 | sym64: | |
| 86 | sym65: | |
| 87 | sym66: | |
| 88 | sym67: | |
| 89 | sym68: | |
| 90 | sym69: | |
| 91 | sym70: | |
| 92 | sym71: | |
| 93 | sym72: | |
| 94 | sym73: | |
| 95 | sym74: | |
| 96 | sym75: | |
| 97 | sym76: | |
| 98 | sym77: | |
| 99 | sym78: | |
| 100 | sym79: | |
| 101 | sym80: | |
| 102 | sym81: | |
| 103 | sym82: | |
| 104 | sym83: | |
| 105 | sym84: | |
| 106 | sym85: | |
| 107 | sym86: | |
| 108 | sym87: | |
| 109 | sym88: | |
| 110 | sym89: | |
| 111 | sym90: | |
| 112 | sym91: | |
| 113 | sym92: | |
| 114 | sym93: | |
| 115 | sym94: | |
| 116 | sym95: | |
| 117 | sym96: | |
| 118 | sym97: | |
| 119 | sym98: | |
| 120 | sym99: | |
| 121 | sym100: | |
| 122 | sym101: | |
| 123 | sym102: | |
| 124 | sym103: | |
| 125 | sym104: | |
| 126 | sym105: | |
| 127 | sym106: | |
| 128 | sym107: | |
| 129 | sym108: | |
| 130 | sym109: | |
| 131 | sym110: | |
| 132 | sym111: | |
| 133 | sym112: | |
| 134 | sym113: | |
| 135 | sym114: | |
| 136 | sym115: | |
| 137 | sym116: | |
| 138 | sym117: | |
| 139 | sym118: | |
| 140 | sym119: | |
| 141 | sym120: | |
| 142 | sym121: | |
| 143 | sym122: | |
| 144 | sym123: | |
| 145 | sym124: | |
| 146 | sym125: | |
| 147 | sym126: | |
| 148 | sym127: | |
| 149 | sym128: | |
| 150 | sym129: | |
| 151 | sym130: | |
| 152 | sym131: | |
| 153 | sym132: | |
| 154 | sym133: | |
| 155 | sym134: | |
| 156 | sym135: | |
| 157 | sym136: | |
| 158 | sym137: | |
| 159 | sym138: | |
| 160 | sym139: | |
| 161 | sym140: | |
| 162 | sym141: | |
| 163 | sym142: | |
| 164 | sym143: | |
| 165 | sym144: | |
| 166 | sym145: | |
| 167 | sym146: | |
| 168 | sym147: | |
| 169 | sym148: | |
| 170 | sym149: | |
| 171 | sym150: | |
| 172 | sym151: | |
| 173 | sym152: | |
| 174 | sym153: | |
| 175 | sym154: | |
| 176 | sym155: | |
| 177 | sym156: | |
| 178 | sym157: | |
| 179 | sym158: | |
| 180 | sym159: | |
| 181 | sym160: | |
| 182 | sym161: | |
| 183 | sym162: | |
| 184 | sym163: | |
| 185 | sym164: | |
| 186 | sym165: | |
| 187 | sym166: | |
| 188 | sym167: | |
| 189 | sym168: | |
| 190 | sym169: | |
| 191 | sym170: | |
| 192 | sym171: | |
| 193 | sym172: | |
| 194 | sym173: | |
| 195 | sym174: | |
| 196 | sym175: | |
| 197 | sym176: | |
| 198 | sym177: | |
| 199 | sym178: | |
| 200 | sym179: | |
| 201 | sym180: | |
| 202 | sym181: | |
| 203 | sym182: | |
| 204 | sym183: | |
| 205 | sym184: | |
| 206 | sym185: | |
| 207 | sym186: | |
| 208 | sym187: | |
| 209 | sym188: | |
| 210 | sym189: | |
| 211 | sym190: | |
| 212 | sym191: | |
| 213 | sym192: | |
| 214 | sym193: | |
| 215 | sym194: | |
| 216 | ret |
deps/lld/test/COFF/subsystem-drectve.test created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | # RUN: yaml2obj < %s > %t.obj | |
| 2 | # RUN: lld-link /dll /noentry /out:%t.dll %t.obj | |
| 3 | # RUN: llvm-readobj -file-headers %t.dll | FileCheck %s | |
| 4 | ||
| 5 | # CHECK: MajorOperatingSystemVersion: 42 | |
| 6 | # CHECK: MinorOperatingSystemVersion: 43 | |
| 7 | # CHECK: MajorSubsystemVersion: 42 | |
| 8 | # CHECK: MinorSubsystemVersion: 43 | |
| 9 | # CHECK: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI | |
| 10 | ||
| 11 | --- !COFF | |
| 12 | header: | |
| 13 | Machine: IMAGE_FILE_MACHINE_I386 | |
| 14 | Characteristics: [] | |
| 15 | sections: | |
| 16 | - Name: .drectve | |
| 17 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | |
| 18 | Alignment: 1 | |
| 19 | SectionData: 2f73756273797374656d3a636f6e736f6c652c34322e343300 # /subsystem:console,42.43 | |
| 20 | symbols: | |
| 21 | ... |
deps/lld/test/COFF/symtab.test+3-3| ... | ... | @@ -1,10 +1,10 @@ |
| 1 | 1 | # RUN: yaml2obj < %s > %t.obj |
| 2 | # RUN: lld-link /debug /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib | |
| 2 | # RUN: lld-link /debug:dwarf /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib | |
| 3 | 3 | # RUN: llvm-readobj -symbols %t.exe | FileCheck %s |
| 4 | # RUN: lld-link /debug /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 | 5 | # RUN: llvm-readobj -symbols %t.exe | FileCheck %s |
| 6 | 6 | |
| 7 | # RUN: lld-link /debug /nosymtab /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib | |
| 7 | # RUN: lld-link /debug /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib | |
| 8 | 8 | # RUN: llvm-readobj -symbols %t.exe | FileCheck -check-prefix=NO %s |
| 9 | 9 | |
| 10 | 10 | # CHECK: Symbols [ |
deps/lld/test/COFF/thinlto.ll+1-1| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | ; RUN: opt -thinlto-bc -o %T/thinlto/main.obj %s |
| 5 | 5 | ; RUN: opt -thinlto-bc -o %T/thinlto/foo.obj %S/Inputs/lto-dep.ll |
| 6 | 6 | ; RUN: lld-link /lldsavetemps /out:%T/thinlto/main.exe /entry:main /subsystem:console %T/thinlto/main.obj %T/thinlto/foo.obj |
| 7 | ; RUN: llvm-nm %T/thinlto/main.exe.lto.obj | FileCheck %s | |
| 7 | ; RUN: llvm-nm %T/thinlto/main.exe1.lto.obj | FileCheck %s | |
| 8 | 8 | |
| 9 | 9 | ; CHECK-NOT: U foo |
| 10 | 10 |
deps/lld/test/COFF/wholearchive.s created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | # REQEUIRES: x86 | |
| 2 | ||
| 3 | # RUN: yaml2obj < %p/Inputs/export.yaml > %t.archive.obj | |
| 4 | # RUN: llvm-ar rcs %t.archive.lib %t.archive.obj | |
| 5 | # RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t.main.obj | |
| 6 | ||
| 7 | # RUN: lld-link -dll -out:%t.dll -entry:main %t.main.obj -wholearchive:%t.archive.lib -implib:%t.lib | |
| 8 | # RUN: llvm-readobj %t.lib | FileCheck %s -check-prefix CHECK-IMPLIB | |
| 9 | ||
| 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 | |
| 12 | ||
| 13 | # CHECK-IMPLIB: Symbol: __imp_exportfn3 | |
| 14 | # CHECK-IMPLIB: Symbol: exportfn3 | |
| 15 | ||
| 16 | .global main | |
| 17 | .text | |
| 18 | main: | |
| 19 | ret |
deps/lld/test/COFF/wx.s created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s | |
| 4 | # RUN: not lld-link /out:%t.exe /entry:main -notarealoption /WX %t.obj 2>&1 | \ | |
| 5 | # RUN: FileCheck -check-prefix=ERROR %s | |
| 6 | # RUN: not lld-link /out:%t.exe /entry:main -notarealoption /WX:NO /WX %t.obj 2>&1 | \ | |
| 7 | # RUN: FileCheck -check-prefix=ERROR %s | |
| 8 | # RUN: lld-link /out:%t.exe /entry:main -notarealoption /WX /WX:NO %t.obj 2>&1 | \ | |
| 9 | # RUN: FileCheck -check-prefix=WARNING %s | |
| 10 | ||
| 11 | # ERROR: error: ignoring unknown argument: -notarealoption | |
| 12 | # WARNING: warning: ignoring unknown argument: -notarealoption | |
| 13 | ||
| 14 | .text | |
| 15 | .global main | |
| 16 | main: | |
| 17 | 	ret |
deps/lld/test/ELF/Inputs/amdgpu-kernel-0.s created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | .text | |
| 2 | .globl kernel_0 | |
| 3 | .align 64 | |
| 4 | .amdgpu_hsa_kernel kernel_0 | |
| 5 | kernel_0: | |
| 6 | s_endpgm |
deps/lld/test/ELF/Inputs/amdgpu-kernel-1.s created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | .text | |
| 2 | .globl kernel_1 | |
| 3 | .align 64 | |
| 4 | .amdgpu_hsa_kernel kernel_1 | |
| 5 | kernel_1: | |
| 6 | s_endpgm |
deps/lld/test/ELF/Inputs/amdgpu-kernel-2.o created| Binary files /dev/null and b/deps/lld/test/ELF/Inputs/amdgpu-kernel-2.o differ |
deps/lld/test/ELF/Inputs/as-needed-lazy.s created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | .global foo | |
| 2 | foo: | |
| 3 | nop |
deps/lld/test/ELF/Inputs/compress-debug.s created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | .text | |
| 2 | .fill 0x44 | |
| 3 | ||
| 4 | .section .debug_info,"",@progbits | |
| 5 | .fill 0x43 |
deps/lld/test/ELF/Inputs/copy-rel-abs.s created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | .global foo | |
| 2 | .type foo, @object | |
| 3 | .size foo, 4 | |
| 4 | foo: | |
| 5 | .weak bar | |
| 6 | .type bar, @object | |
| 7 | .size bar, 4 | |
| 8 | bar: | |
| 9 | .long 42 | |
| 10 | ||
| 11 | .weak zed | |
| 12 | .type zed, @object | |
| 13 | zed = 0x1000 |
deps/lld/test/ELF/Inputs/copy-rel-large.s created+4| ... | ... | @@ -0,0 +1,4 @@ |
| 1 | .global foo | |
| 2 | .type foo, @object | |
| 3 | foo: | |
| 4 | .size foo, 0x100000001 |
deps/lld/test/ELF/Inputs/copy-rel-pie.s+1| ... | ... | @@ -9,3 +9,4 @@ foo: |
| 9 | 9 | .global bar |
| 10 | 10 | .type bar, @function |
| 11 | 11 | bar: |
| 12 | retq |
deps/lld/test/ELF/Inputs/corrupt-version-reference.so created| Binary files /dev/null and b/deps/lld/test/ELF/Inputs/corrupt-version-reference.so differ |
deps/lld/test/ELF/Inputs/dynamic-list-weak-archive.s created+2| ... | ... | @@ -0,0 +1,2 @@ |
| 1 | .globl foo | |
| 2 | foo: |
deps/lld/test/ELF/Inputs/eh-frame.s created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | .cfi_startproc | |
| 2 | .cfi_def_cfa_offset 32 | |
| 3 | .cfi_endproc |
deps/lld/test/ELF/Inputs/gc-sections-shared.s created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | .global baz | |
| 2 | .type baz, @function | |
| 3 | baz: |
deps/lld/test/ELF/Inputs/gc-sections-shared2.s created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | .global qux | |
| 2 | .type qux, @function | |
| 3 | qux: |
deps/lld/test/ELF/Inputs/local-symbol-in-dso.so created| Binary files /dev/null and b/deps/lld/test/ELF/Inputs/local-symbol-in-dso.so differ |
deps/lld/test/ELF/Inputs/map-file5.s created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | .bss | |
| 2 | .type sharedFoo,@object | |
| 3 | .globl sharedFoo | |
| 4 | sharedFoo: | |
| 5 | .long 0 | |
| 6 | .size sharedFoo, 4 | |
| 7 | ||
| 8 | .type sharedBar,@object | |
| 9 | .globl sharedBar | |
| 10 | sharedBar: | |
| 11 | .quad 0 | |
| 12 | .size sharedBar, 8 | |
| 13 | ||
| 14 | .text | |
| 15 | .globl sharedFunc1 | |
| 16 | .type sharedFunc1,@function | |
| 17 | sharedFunc1: | |
| 18 | nop | |
| 19 | ||
| 20 | .globl sharedFunc2 | |
| 21 | .type sharedFunc2,@function | |
| 22 | sharedFunc2: | |
| 23 | nop |
deps/lld/test/ELF/Inputs/mips-gp-dips-corrupt-ver.s created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | # Source file for mips-gp-dips-corrupt-ver.so | |
| 2 | # | |
| 3 | # % cat gpdisp.ver | |
| 4 | # LLD_1.0.0 { global: foo; }; | |
| 5 | # | |
| 6 | # % as mips-gp-dips-corrupt-ver.s -o mips-gp-dips-corrupt-ver.o | |
| 7 | # % ld -shared -o mips-gp-dips-corrupt-ver.so \ | |
| 8 | # --version-script gpdisp.ver mips-gp-dips-corrupt-ver.o | |
| 9 | ||
| 10 | .global foo | |
| 11 | .text | |
| 12 | foo: | |
| 13 | lui $t0, %hi(_gp_disp) | |
| 14 | addi $t0, $t0, %lo(_gp_disp) |
deps/lld/test/ELF/Inputs/mips-gp-dips-corrupt-ver.so created| Binary files /dev/null and b/deps/lld/test/ELF/Inputs/mips-gp-dips-corrupt-ver.so differ |
deps/lld/test/ELF/Inputs/mips-micro.s created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | .text | |
| 2 | .set micromips | |
| 3 | .global foo | |
| 4 | .type foo,@function | |
| 5 | foo: | |
| 6 | nop | |
| 7 | ||
| 8 | .set nomicromips | |
| 9 | .global bar | |
| 10 | .type bar,@function | |
| 11 | bar: | |
| 12 | nop |
deps/lld/test/ELF/Inputs/shared3.s+1-1| ... | ... | @@ -1,3 +1,3 @@ |
| 1 | 1 | .global baz |
| 2 | .type barz, @function | |
| 2 | .type baz, @function | |
| 3 | 3 | baz: |
deps/lld/test/ELF/Inputs/shlib-undefined-ref.s created+4| ... | ... | @@ -0,0 +1,4 @@ |
| 1 | .globl f | |
| 2 | f: | |
| 3 | 	call	should_not_be_exported@PLT | |
| 4 | 	ret |
deps/lld/test/ELF/Inputs/undefined-error.s created+1| ... | ... | @@ -0,0 +1 @@ |
| 1 | callq fmod@PLT |
deps/lld/test/ELF/Inputs/verdef-defaultver.s+3| ... | ... | @@ -1,4 +1,7 @@ |
| 1 | .global b@V1 | |
| 1 | 2 | b@V1 = b_1 |
| 3 | ||
| 4 | .global b@@V2 | |
| 2 | 5 | b@@V2 = b_2 |
| 3 | 6 | |
| 4 | 7 | .globl a |
deps/lld/test/ELF/Inputs/verneed.so.sh deleted-58| ... | ... | @@ -1,58 +0,0 @@ |
| 1 | #!/bin/sh -eu | |
| 2 | ||
| 3 | # This script was used to produce the verneed{1,2}.so files. | |
| 4 | ||
| 5 | tmp=$(mktemp -d) | |
| 6 | ||
| 7 | echo "v1 {}; v2 {}; v3 {}; { local: *; };" > $tmp/verneed.script | |
| 8 | ||
| 9 | cat > $tmp/verneed1.s <<eof | |
| 10 | .globl f1_v1 | |
| 11 | f1_v1: | |
| 12 | ret | |
| 13 | ||
| 14 | .globl f1_v2 | |
| 15 | f1_v2: | |
| 16 | ret | |
| 17 | ||
| 18 | .globl f1_v3 | |
| 19 | f1_v3: | |
| 20 | ret | |
| 21 | ||
| 22 | .symver f1_v1, f1@v1 | |
| 23 | .symver f1_v2, f1@v2 | |
| 24 | .symver f1_v3, f1@@v3 | |
| 25 | ||
| 26 | .globl f2_v1 | |
| 27 | f2_v1: | |
| 28 | ret | |
| 29 | ||
| 30 | .globl f2_v2 | |
| 31 | f2_v2: | |
| 32 | ret | |
| 33 | ||
| 34 | .symver f2_v1, f2@v1 | |
| 35 | .symver f2_v2, f2@@v2 | |
| 36 | ||
| 37 | .globl f3_v1 | |
| 38 | f3_v1: | |
| 39 | ret | |
| 40 | ||
| 41 | .symver f3_v1, f3@v1 | |
| 42 | eof | |
| 43 | ||
| 44 | as -o $tmp/verneed1.o $tmp/verneed1.s | |
| 45 | ld.gold -shared -o verneed1.so $tmp/verneed1.o --version-script $tmp/verneed.script -soname verneed1.so.0 | |
| 46 | ||
| 47 | cat > $tmp/verneed2.s <<eof | |
| 48 | .globl g1_v1 | |
| 49 | g1_v1: | |
| 50 | ret | |
| 51 | ||
| 52 | .symver g1_v1, g1@@v1 | |
| 53 | eof | |
| 54 | ||
| 55 | as -o $tmp/verneed2.o $tmp/verneed2.s | |
| 56 | ld.gold -shared -o verneed2.so $tmp/verneed2.o --version-script $tmp/verneed.script -soname verneed2.so.0 | |
| 57 | ||
| 58 | rm -rf $tmp |
deps/lld/test/ELF/Inputs/verneed1.s created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | .globl f1_v1 | |
| 2 | f1_v1: | |
| 3 | ret | |
| 4 | ||
| 5 | .globl f1_v2 | |
| 6 | f1_v2: | |
| 7 | ret | |
| 8 | ||
| 9 | .globl f1_v3 | |
| 10 | f1_v3: | |
| 11 | ret | |
| 12 | ||
| 13 | .symver f1_v1, f1@v1 | |
| 14 | .symver f1_v2, f1@v2 | |
| 15 | .symver f1_v3, f1@@v3 | |
| 16 | ||
| 17 | .globl f2_v1 | |
| 18 | f2_v1: | |
| 19 | ret | |
| 20 | ||
| 21 | .globl f2_v2 | |
| 22 | f2_v2: | |
| 23 | ret | |
| 24 | ||
| 25 | .symver f2_v1, f2@v1 | |
| 26 | .symver f2_v2, f2@@v2 | |
| 27 | ||
| 28 | .globl f3_v1 | |
| 29 | f3_v1: | |
| 30 | ret | |
| 31 | ||
| 32 | .symver f3_v1, f3@v1 |
deps/lld/test/ELF/Inputs/verneed1.so deleted| Binary files a/deps/lld/test/ELF/Inputs/verneed1.so and /dev/null differ |
deps/lld/test/ELF/Inputs/verneed2.s created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | .globl g1_v1 | |
| 2 | g1_v1: | |
| 3 | ret | |
| 4 | ||
| 5 | .symver g1_v1, g1@@v1 |
deps/lld/test/ELF/Inputs/verneed2.so deleted| Binary files a/deps/lld/test/ELF/Inputs/verneed2.so and /dev/null differ |
deps/lld/test/ELF/Inputs/weak-undef-lazy.s created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | .global foobar | |
| 2 | foobar: | |
| 3 | nop |
deps/lld/test/ELF/Inputs/wrap-no-real.s created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | .globl foo, __wrap_foo | |
| 2 | foo = 0x11000 | |
| 3 | __wrap_foo = 0x11010 |
deps/lld/test/ELF/Inputs/wrap-no-real2.s created+2| ... | ... | @@ -0,0 +1,2 @@ |
| 1 | .globl __real_foo | |
| 2 | __real_foo = 0x11020 |
deps/lld/test/ELF/Inputs/wrap.s+4-1| ... | ... | @@ -1,4 +1,7 @@ |
| 1 | .globl foo, __wrap_foo, __real_foo | |
| 1 | .global foo | |
| 2 | .weak __wrap_foo | |
| 3 | .protected __wrap_foo | |
| 4 | .global __real_foo | |
| 2 | 5 | foo = 0x11000 |
| 3 | 6 | __wrap_foo = 0x11010 |
| 4 | 7 | __real_foo = 0x11020 |
deps/lld/test/ELF/Inputs/writable-sec-plt-reloc.s created+4| ... | ... | @@ -0,0 +1,4 @@ |
| 1 | .global foo | |
| 2 | .type foo, @function | |
| 3 | foo: | |
| 4 | retq |
deps/lld/test/ELF/Inputs/znotext-copy-relocations.s created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | .global foo | |
| 2 | .type foo,@object | |
| 3 | .size foo, 8 | |
| 4 | foo: | |
| 5 | .quad 42 |
deps/lld/test/ELF/Inputs/znotext-plt-relocations-protected.s created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | .global foo | |
| 2 | .type foo,@function | |
| 3 | .protected foo | |
| 4 | foo: | |
| 5 | nop |
deps/lld/test/ELF/Inputs/znotext-plt-relocations.s created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | .text | |
| 2 | .global atexit | |
| 3 | .type atexit,@function | |
| 4 | atexit: | |
| 5 | nop | |
| 6 | ||
| 7 | .global foo | |
| 8 | .type foo,@function | |
| 9 | foo: | |
| 10 | nop |
deps/lld/test/ELF/aarch64-abs16.s+1-1| ... | ... | @@ -24,4 +24,4 @@ _start: |
| 24 | 24 | // | FileCheck %s --check-prefix=OVERFLOW |
| 25 | 25 | // RUN: not ld.lld %t.o %t257.o -o %t2 |
| 26 | 26 | // | FileCheck %s --check-prefix=OVERFLOW |
| 27 | // OVERFLOW: Relocation R_AARCH64_ABS16 out of range | |
| 27 | // OVERFLOW: Relocation R_AARCH64_ABS16 out of range: 65536 is not in [-32768, 65535] |
deps/lld/test/ELF/aarch64-abs32.s+1-1| ... | ... | @@ -24,4 +24,4 @@ _start: |
| 24 | 24 | // | FileCheck %s --check-prefix=OVERFLOW |
| 25 | 25 | // RUN: not ld.lld %t.o %t257.o -o %t2 |
| 26 | 26 | // | FileCheck %s --check-prefix=OVERFLOW |
| 27 | // OVERFLOW: Relocation R_AARCH64_ABS32 out of range | |
| 27 | // OVERFLOW: Relocation R_AARCH64_ABS32 out of range: 4294967296 is not in [-2147483648, 4294967295] |
deps/lld/test/ELF/aarch64-call26-error.s deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 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 -o %t | |
| 3 | // RUN: not ld.lld %t %tabs -o %t2 2>&1 | FileCheck %s | |
| 4 | // REQUIRES: aarch64 | |
| 5 | ||
| 6 | .text | |
| 7 | .globl _start | |
| 8 | _start: | |
| 9 | bl big | |
| 10 | ||
| 11 | // CHECK: R_AARCH64_CALL26 out of range |
deps/lld/test/ELF/aarch64-call26-thunk.s created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 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 -o %t | |
| 3 | // RUN: ld.lld %t %tabs -o %t2 2>&1 | |
| 4 | // RUN: llvm-objdump -d -triple=aarch64-pc-freebsd %t2 | FileCheck %s | |
| 5 | // REQUIRES: aarch64 | |
| 6 | ||
| 7 | .text | |
| 8 | .globl _start | |
| 9 | _start: | |
| 10 | bl big | |
| 11 | ||
| 12 | // CHECK: Disassembly of section .text: | |
| 13 | // CHECK-NEXT: _start: | |
| 14 | // CHECK-NEXT: 20000: 02 00 00 94 bl #8 | |
| 15 | // CHECK: __AArch64AbsLongThunk_big: | |
| 16 | // CHECK-NEXT: 20008: 50 00 00 58 ldr x16, #8 | |
| 17 | // CHECK-NEXT: 2000c: 00 02 1f d6 br x16 | |
| 18 | // CHECK: $d: | |
| 19 | // CHECK-NEXT: 20010: 00 00 00 00 .word 0x00000000 | |
| 20 | // CHECK-NEXT: 20014: 10 00 00 00 .word 0x00000010 | |
| 21 |
deps/lld/test/ELF/aarch64-cortex-a53-843419-address.s created+180| ... | ... | @@ -0,0 +1,180 @@ |
| 1 | // REQUIRES: aarch64 | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o | |
| 3 | // RUN: echo "SECTIONS { \ | |
| 4 | // RUN: .text : { *(.text) *(.text.*) *(.newisd) } \ | |
| 5 | // RUN: .text2 : { *.(newos) } \ | |
| 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 | |
| 8 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s | |
| 9 | ||
| 10 | // Test cases for Cortex-A53 Erratum 843419 that involve interactions | |
| 11 | // between the generated patches and the address of sections. | |
| 12 | ||
| 13 | // See ARM-EPM-048406 Cortex_A53_MPCore_Software_Developers_Errata_Notice.pdf | |
| 14 | // for full erratum details. | |
| 15 | // In Summary | |
| 16 | // 1.) | |
| 17 | // ADRP (0xff8 or 0xffc). | |
| 18 | // 2.) | |
| 19 | // - load or store single register or either integer or vector registers. | |
| 20 | // - STP or STNP of either vector or vector registers. | |
| 21 | // - Advanced SIMD ST1 store instruction. | |
| 22 | // - Must not write Rn. | |
| 23 | // 3.) optional instruction, can't be a branch, must not write Rn, may read Rn. | |
| 24 | // 4.) A load or store instruction from the Load/Store register unsigned | |
| 25 | // immediate class using Rn as the base register. | |
| 26 | ||
| 27 | // An aarch64 section can contain ranges of literal data embedded within the | |
| 28 | // code, these ranges are encoded with mapping symbols. This tests that we | |
| 29 | // can match the erratum sequence in code, but not data. | |
| 30 | // - We can handle more than one patch per code range (denoted by mapping | |
| 31 | // symbols). | |
| 32 | // - We can handle a patch in more than range of code, with literal data | |
| 33 | // inbetween. | |
| 34 | // - We can handle redundant mapping symbols (two or more consecutive mapping | |
| 35 | // symbols with the same type). | |
| 36 | // - We can ignore erratum sequences in multiple literal data ranges. | |
| 37 | ||
| 38 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at FF8 in unpatched output. | |
| 39 | // CHECK: t3_ff8_ldr: | |
| 40 | // CHECK-NEXT: ff8: 20 00 00 d0 adrp x0, #24576 | |
| 41 | // CHECK-NEXT: ffc: 21 00 40 f9 ldr x1, [x1] | |
| 42 | // CHECK-NEXT: 1000: f9 0f 00 14 b #16356 | |
| 43 | // CHECK-NEXT: 1004: c0 03 5f d6 ret | |
| 44 | .section .text.01, "ax", %progbits | |
| 45 | .balign 4096 | |
| 46 | .space 4096 - 8 | |
| 47 | .globl t3_ff8_ldr | |
| 48 | .type t3_ff8_ldr, %function | |
| 49 | t3_ff8_ldr: | |
| 50 | adrp x0, dat | |
| 51 | ldr x1, [x1, #0] | |
| 52 | ldr x0, [x0, :got_lo12:dat] | |
| 53 | ret | |
| 54 | ||
| 55 | // create a redundant mapping symbol as we are already in a $x range | |
| 56 | // some object producers unconditionally generate a mapping symbol on | |
| 57 | // every symbol so we need to handle the case of $x $x. | |
| 58 | .local $x.999 | |
| 59 | $x.999: | |
| 60 | // CHECK-PRINT-NEXT: detected cortex-a53-843419 erratum sequence starting at 1FFC in unpatched output. | |
| 61 | // CHECK: t3_ffc_ldrsimd: | |
| 62 | // CHECK-NEXT: 1ffc: 20 00 00 b0 adrp x0, #20480 | |
| 63 | // CHECK-NEXT: 2000: 21 00 40 bd ldr s1, [x1] | |
| 64 | // CHECK-NEXT: 2004: fa 0b 00 14 b #12264 | |
| 65 | // CHECK-NEXT: 2008: c0 03 5f d6 ret | |
| 66 | .globl t3_ffc_ldrsimd | |
| 67 | .type t3_ffc_ldrsimd, %function | |
| 68 | .space 4096 - 12 | |
| 69 | t3_ffc_ldrsimd: | |
| 70 | adrp x0, dat | |
| 71 | ldr s1, [x1, #0] | |
| 72 | ldr x2, [x0, :got_lo12:dat] | |
| 73 | ret | |
| 74 | ||
| 75 | // Inline data containing bit pattern of erratum sequence, expect no patch. | |
| 76 | .globl t3_ffc_ldralldata | |
| 77 | .type t3_ff8_ldralldata, %function | |
| 78 | .space 4096 - 20 | |
| 79 | t3_ff8_ldralldata: | |
| 80 | // 0x90000000 = adrp x0, #0 | |
| 81 | .byte 0x00 | |
| 82 | .byte 0x00 | |
| 83 | .byte 0x00 | |
| 84 | .byte 0x90 | |
| 85 | // 0xf9400021 = ldr x1, [x1] | |
| 86 | .byte 0x21 | |
| 87 | .byte 0x00 | |
| 88 | .byte 0x40 | |
| 89 | .byte 0xf9 | |
| 90 | // 0xf9400000 = ldr x0, [x0] | |
| 91 | .byte 0x00 | |
| 92 | .byte 0x00 | |
| 93 | .byte 0x40 | |
| 94 | .byte 0xf9 | |
| 95 | // Check that we can recognise the erratum sequence post literal data. | |
| 96 | ||
| 97 | // CHECK-PRINT-NEXT: detected cortex-a53-843419 erratum sequence starting at 3FF8 in unpatched output. | |
| 98 | // CHECK: t3_ffc_ldr: | |
| 99 | // CHECK-NEXT: 3ff8: 00 00 00 f0 adrp x0, #12288 | |
| 100 | // CHECK-NEXT: 3ffc: 21 00 40 f9 ldr x1, [x1] | |
| 101 | // CHECK-NEXT: 4000: fd 03 00 14 b #4084 | |
| 102 | // CHECK-NEXT: 4004: c0 03 5f d6 ret | |
| 103 | .space 4096 - 12 | |
| 104 | .globl t3_ffc_ldr | |
| 105 | .type t3_ffc_ldr, %function | |
| 106 | t3_ffc_ldr: | |
| 107 | adrp x0, dat | |
| 108 | ldr x1, [x1, #0] | |
| 109 | ldr x0, [x0, :got_lo12:dat] | |
| 110 | ret | |
| 111 | ||
| 112 | // CHECK: __CortexA53843419_1000: | |
| 113 | // CHECK-NEXT: 4fe4: 00 0c 40 f9 ldr x0, [x0, #24] | |
| 114 | // CHECK-NEXT: 4fe8: 07 f0 ff 17 b #-16356 | |
| 115 | // CHECK: __CortexA53843419_2004: | |
| 116 | // CHECK-NEXT: 4fec: 02 0c 40 f9 ldr x2, [x0, #24] | |
| 117 | // CHECK-NEXT: 4ff0: 06 f4 ff 17 b #-12264 | |
| 118 | // CHECK: __CortexA53843419_4000: | |
| 119 | // CHECK-NEXT: 4ff4: 00 0c 40 f9 ldr x0, [x0, #24] | |
| 120 | // CHECK-NEXT: 4ff8: 03 fc ff 17 b #-4084 | |
| 121 | ||
| 122 | .section .text.02, "ax", %progbits | |
| 123 | .space 4096 - 36 | |
| 124 | ||
| 125 | // Start a new InputSectionDescription (see Linker Script) so the | |
| 126 | // start address will be affected by any patches added to previous | |
| 127 | // InputSectionDescription. | |
| 128 | ||
| 129 | // CHECK-PRINT-NEXT: detected cortex-a53-843419 erratum sequence starting at 4FFC in unpatched output | |
| 130 | // CHECK: t3_ffc_str: | |
| 131 | // CHECK-NEXT: 4ffc: 00 00 00 d0 adrp x0, #8192 | |
| 132 | // CHECK-NEXT: 5000: 21 00 00 f9 str x1, [x1] | |
| 133 | // CHECK-NEXT: 5004: fb 03 00 14 b #4076 | |
| 134 | // CHECK-NEXT: 5008: c0 03 5f d6 ret | |
| 135 | ||
| 136 | .section .newisd, "ax", %progbits | |
| 137 | .globl t3_ffc_str | |
| 138 | .type t3_ffc_str, %function | |
| 139 | t3_ffc_str: | |
| 140 | adrp x0, dat | |
| 141 | str x1, [x1, #0] | |
| 142 | ldr x0, [x0, :got_lo12:dat] | |
| 143 | ret | |
| 144 | .space 4096 - 28 | |
| 145 | ||
| 146 | // CHECK: __CortexA53843419_5004: | |
| 147 | // CHECK-NEXT: 5ff0: 00 0c 40 f9 ldr x0, [x0, #24] | |
| 148 | // CHECK-NEXT: 5ff4: 05 fc ff 17 b #-4076 | |
| 149 | ||
| 150 | // Start a new OutputSection (see Linker Script) so the | |
| 151 | // start address will be affected by any patches added to previous | |
| 152 | // InputSectionDescription. | |
| 153 | ||
| 154 | //CHECK-PRINT-NEXT: detected cortex-a53-843419 erratum sequence starting at 5FF8 in unpatched output | |
| 155 | // CHECK: t3_ff8_str: | |
| 156 | // CHECK-NEXT: 5ff8: 00 00 00 b0 adrp x0, #4096 | |
| 157 | // CHECK-NEXT: 5ffc: 21 00 00 f9 str x1, [x1] | |
| 158 | // CHECK-NEXT: 6000: 03 00 00 14 b #12 | |
| 159 | // CHECK-NEXT: 6004: c0 03 5f d6 ret | |
| 160 | ||
| 161 | .section .newos, "ax", %progbits | |
| 162 | .globl t3_ff8_str | |
| 163 | .type t3_ff8_str, %function | |
| 164 | t3_ff8_str: | |
| 165 | adrp x0, dat | |
| 166 | str x1, [x1, #0] | |
| 167 | ldr x0, [x0, :got_lo12:dat] | |
| 168 | ret | |
| 169 | .globl _start | |
| 170 | .type _start, %function | |
| 171 | _start: | |
| 172 | ret | |
| 173 | ||
| 174 | // CHECK: __CortexA53843419_6000: | |
| 175 | // CHECK-NEXT: 600c: 00 0c 40 f9 ldr x0, [x0, #24] | |
| 176 | // CHECK-NEXT: 6010: fd ff ff 17 b #-12 | |
| 177 | ||
| 178 | .data | |
| 179 | .globl dat | |
| 180 | dat: .word 0 |
deps/lld/test/ELF/aarch64-cortex-a53-843419-cli.s created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | // REQUIRES: x86 | |
| 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 | |
| 4 | ||
| 5 | // CHECK: --fix-cortex-a53-843419 is only supported on AArch64 targets. | |
| 6 | .globl entry | |
| 7 | .text | |
| 8 | .quad 0 | |
| 9 | entry: | |
| 10 | ret |
deps/lld/test/ELF/aarch64-cortex-a53-843419-large.s created+115| ... | ... | @@ -0,0 +1,115 @@ |
| 1 | // REQUIRES: aarch64 | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o | |
| 3 | // RUN: ld.lld --fix-cortex-a53-843419 %t.o -o %t2 | |
| 4 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=131072 -stop-address=131084 | FileCheck --check-prefix=CHECK1 %s | |
| 5 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=135168 -stop-address=135172 | FileCheck --check-prefix=CHECK2 %s | |
| 6 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=139256 -stop-address=139272 | FileCheck --check-prefix=CHECK3 %s | |
| 7 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=67256312 -stop-address=67256328 | FileCheck --check-prefix=CHECK4 %s | |
| 8 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=100810760 -stop-address=100810776 | FileCheck --check-prefix=CHECK5 %s | |
| 9 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=134352908 -stop-address=134352912 | FileCheck --check-prefix=CHECK6 %s | |
| 10 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=134356988 -stop-address=134357012 | FileCheck --check-prefix=CHECK7 %s | |
| 11 | // Test case for Cortex-A53 Erratum 843419 in an OutputSection exceeding | |
| 12 | // the maximum branch range. Both range extension thunks and patches are | |
| 13 | // required. | |
| 14 | ||
| 15 | // CHECK1: __AArch64AbsLongThunk_need_thunk_after_patch: | |
| 16 | // CHECK1-NEXT: 20000: 50 00 00 58 ldr x16, #8 | |
| 17 | // CHECK1-NEXT: 20004: 00 02 1f d6 br x16 | |
| 18 | // CHECK1: $d: | |
| 19 | // CHECK1-NEXT: 20008: 0c 10 02 08 .word 0x0802100c | |
| 20 | ||
| 21 | .section .text.01, "ax", %progbits | |
| 22 | .balign 4096 | |
| 23 | .globl _start | |
| 24 | .type _start, %function | |
| 25 | _start: | |
| 26 | // Expect thunk on pass 2 | |
| 27 | bl need_thunk_after_patch | |
| 28 | .section .text.02, "ax", %progbits | |
| 29 | .space 4096 - 12 | |
| 30 | ||
| 31 | // CHECK2: _start: | |
| 32 | // CHECK2-NEXT: 21000: 00 fc ff 97 bl #-4096 | |
| 33 | ||
| 34 | // Expect patch on pass 1 | |
| 35 | .section .text.03, "ax", %progbits | |
| 36 | .globl t3_ff8_ldr | |
| 37 | .type t3_ff8_ldr, %function | |
| 38 | t3_ff8_ldr: | |
| 39 | adrp x0, dat | |
| 40 | ldr x1, [x1, #0] | |
| 41 | ldr x0, [x0, :got_lo12:dat] | |
| 42 | ret | |
| 43 | ||
| 44 | // CHECK3: t3_ff8_ldr: | |
| 45 | // CHECK3-NEXT: 21ff8: 60 00 04 f0 adrp x0, #134279168 | |
| 46 | // CHECK3-NEXT: 21ffc: 21 00 40 f9 ldr x1, [x1] | |
| 47 | // CHECK3-NEXT: 22000: 02 08 80 15 b #100671496 | |
| 48 | // CHECK3-NEXT: 22004: c0 03 5f d6 ret | |
| 49 | ||
| 50 | .section .text.04, "ax", %progbits | |
| 51 | .space 64 * 1024 * 1024 | |
| 52 | ||
| 53 | // Expect patch on pass 1 | |
| 54 | .section .text.05, "ax", %progbits | |
| 55 | .balign 4096 | |
| 56 | .space 4096 - 8 | |
| 57 | .globl t3_ff8_str | |
| 58 | .type t3_ff8_str, %function | |
| 59 | t3_ff8_str: | |
| 60 | adrp x0, dat | |
| 61 | ldr x1, [x1, #0] | |
| 62 | str x0, [x0, :got_lo12:dat] | |
| 63 | ret | |
| 64 | ||
| 65 | // CHECK4: t3_ff8_str: | |
| 66 | // CHECK4-NEXT: 4023ff8: 60 00 02 b0 adrp x0, #67162112 | |
| 67 | // CHECK4-NEXT: 4023ffc: 21 00 40 f9 ldr x1, [x1] | |
| 68 | // CHECK4-NEXT: 4024000: 04 00 80 14 b #33554448 | |
| 69 | // CHECK4-NEXT: 4024004: c0 03 5f d6 ret | |
| 70 | ||
| 71 | .section .text.06, "ax", %progbits | |
| 72 | .space 32 * 1024 * 1024 | |
| 73 | ||
| 74 | // CHECK5: __CortexA53843419_21000: | |
| 75 | // CHECK5-NEXT: 6024008: 00 00 40 f9 ldr x0, [x0] | |
| 76 | // CHECK5-NEXT: 602400c: fe f7 7f 16 b #-100671496 | |
| 77 | // CHECK5: __CortexA53843419_4023000: | |
| 78 | // CHECK5-NEXT: 6024010: 00 00 00 f9 str x0, [x0] | |
| 79 | // CHECK5-NEXT: 6024014: fc ff 7f 17 b #-33554448 | |
| 80 | ||
| 81 | .section .text.07, "ax", %progbits | |
| 82 | .space (32 * 1024 * 1024) - 12300 | |
| 83 | ||
| 84 | .section .text.08, "ax", %progbits | |
| 85 | .globl need_thunk_after_patch | |
| 86 | .type need_thunk_after_patch, %function | |
| 87 | need_thunk_after_patch: | |
| 88 | ret | |
| 89 | ||
| 90 | // CHECK6: need_thunk_after_patch: | |
| 91 | // CHECK6-NEXT: 802100c: c0 03 5f d6 ret | |
| 92 | ||
| 93 | // Will need a patch on pass 2 | |
| 94 | .section .text.09, "ax", %progbits | |
| 95 | .space 4096 - 20 | |
| 96 | .globl t3_ffc_ldr | |
| 97 | .type t3_ffc_ldr, %function | |
| 98 | t3_ffc_ldr: | |
| 99 | adrp x0, dat | |
| 100 | ldr x1, [x1, #0] | |
| 101 | ldr x0, [x0, :got_lo12:dat] | |
| 102 | ret | |
| 103 | ||
| 104 | // CHECK7: t3_ffc_ldr: | |
| 105 | // CHECK7-NEXT: 8021ffc: 60 00 00 f0 adrp x0, #61440 | |
| 106 | // CHECK7-NEXT: 8022000: 21 00 40 f9 ldr x1, [x1] | |
| 107 | // CHECK7-NEXT: 8022004: 02 00 00 14 b #8 | |
| 108 | // CHECK7-NEXT: 8022008: c0 03 5f d6 ret | |
| 109 | // CHECK7: __CortexA53843419_8022004: | |
| 110 | // CHECK7-NEXT: 802200c: 00 00 40 f9 ldr x0, [x0] | |
| 111 | // CHECK7-NEXT: 8022010: fe ff ff 17 b #-8 | |
| 112 | ||
| 113 | .section .data | |
| 114 | .globl dat | |
| 115 | dat: .quad 0 |
deps/lld/test/ELF/aarch64-cortex-a53-843419-nopatch.s created+338| ... | ... | @@ -0,0 +1,338 @@ |
| 1 | // REQUIRES: aarch64 | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o | |
| 3 | // RUN: ld.lld -fix-cortex-a53-843419 -verbose -t %t.o -o %t2 | FileCheck %s | |
| 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. | |
| 6 | // See ARM-EPM-048406 Cortex_A53_MPCore_Software_Developers_Errata_Notice.pdf | |
| 7 | // for full erratum details. | |
| 8 | // In Summary | |
| 9 | // 1.) | |
| 10 | // ADRP (0xff8 or 0xffc) | |
| 11 | // 2.) | |
| 12 | // - load or store single register or either integer or vector registers | |
| 13 | // - STP or STNP of either vector or vector registers | |
| 14 | // - Advanced SIMD ST1 store instruction | |
| 15 | // Must not write Rn | |
| 16 | // 3.) optional instruction, can't be a branch, must not write Rn, may read Rn | |
| 17 | // 4.) A load or store instruction from the Load/Store register unsigned | |
| 18 | // immediate class using Rn as the base register | |
| 19 | ||
| 20 | // Expect no patches detected. | |
| 21 | // CHECK-NOT: detected cortex-a53-843419 erratum sequence | |
| 22 | ||
| 23 | // erratum sequence but adrp (address & 0xfff) is not 0xff8 or 0xffc | |
| 24 | .section .text.01, "ax", %progbits | |
| 25 | .balign 4096 | |
| 26 | .globl t3_0_ldr | |
| 27 | .type t3_ff8_ldr, %function | |
| 28 | t3_0_ldr: | |
| 29 | adrp x0, dat | |
| 30 | ldr x1, [x1, #0] | |
| 31 | ldr x0, [x0, :got_lo12:dat] | |
| 32 | ret | |
| 33 | ||
| 34 | .section .text.02, "ax", %progbits | |
| 35 | .balign 4096 | |
| 36 | .globl t3_ff4_ldr | |
| 37 | .space 4096 - 12 | |
| 38 | .type t3_ff4_ldr, %function | |
| 39 | t3_ff4_ldr: | |
| 40 | adrp x0, dat | |
| 41 | ldr x1, [x1, #0] | |
| 42 | ldr x0, [x0, :got_lo12:dat] | |
| 43 | ret | |
| 44 | ||
| 45 | // Close matches for erratum sequence, with adrp at correct address but | |
| 46 | // instruction 2 is a load or store but not one that matches the erratum | |
| 47 | // conditions, but with a similar encoding to an instruction that does. | |
| 48 | ||
| 49 | // ldp is not part of sequence, although stp is. | |
| 50 | .section .text.03, "ax", %progbits | |
| 51 | .balign 4096 | |
| 52 | .globl t3_ff8_ldp | |
| 53 | .type t3_ff8_ldp, %function | |
| 54 | .space 4096 - 8 | |
| 55 | t3_ff8_ldp: | |
| 56 | adrp x16, dat | |
| 57 | ldp x1,x2, [x3, #0] | |
| 58 | ldr x13, [x16, :got_lo12:dat] | |
| 59 | ret | |
| 60 | ||
| 61 | // st2 is not part of sequence although st1 is. | |
| 62 | .section .text.04, "ax", %progbits | |
| 63 | .balign 4096 | |
| 64 | .globl t3_ffc_st2 | |
| 65 | .type t3_ffc_st2, %function | |
| 66 | .space 4096 - 4 | |
| 67 | t3_ffc_st2: | |
| 68 | adrp x16, dat | |
| 69 | st2 { v0.16b, v1.16b }, [x1] | |
| 70 | ldr x13, [x16, :got_lo12:dat] | |
| 71 | ret | |
| 72 | ||
| 73 | // st3 is not part of sequence although st1 is. | |
| 74 | .section .text.05, "ax", %progbits | |
| 75 | .balign 4096 | |
| 76 | .globl t3_ffc_st3 | |
| 77 | .type t3_ffc_st3, %function | |
| 78 | .space 4096 - 4 | |
| 79 | t3_ffc_st3: | |
| 80 | adrp x16, dat | |
| 81 | st3 { v0.16b, v1.16b, v2.16b }, [x1], x2 | |
| 82 | ldr x13, [x16, :got_lo12:dat] | |
| 83 | ret | |
| 84 | ||
| 85 | // ld1 is not part of sequence although st1 is. | |
| 86 | .section .text.06, "ax", %progbits | |
| 87 | .balign 4096 | |
| 88 | .globl t3_ffc_ld2 | |
| 89 | .type t3_ffc_st3, %function | |
| 90 | .space 4096 - 4 | |
| 91 | t3_ffc_ld1: | |
| 92 | adrp x16, dat | |
| 93 | ld1 { v0.16b }, [x2], x3 | |
| 94 | ldr x13, [x16, :got_lo12:dat] | |
| 95 | ret | |
| 96 | ||
| 97 | // ldnp is not part of sequence although stnp is. | |
| 98 | .section .text.07, "ax", %progbits | |
| 99 | .balign 4096 | |
| 100 | .globl t4_ff8_ldnp | |
| 101 | .type t4_ff8_ldnp, %function | |
| 102 | .space 4096 - 8 | |
| 103 | t4_ff8_ldnp: | |
| 104 | adrp x7, dat | |
| 105 | ldnp x1,x2, [x3, #0] | |
| 106 | nop | |
| 107 | ldr x10, [x7, :got_lo12:dat] | |
| 108 | ret | |
| 109 | ||
| 110 | // Close match for erratum sequence, with adrp at correct address but | |
| 111 | // instruction 2 writes to Rn, with Rn as either destination or as the | |
| 112 | // transfer register but with writeback. | |
| 113 | ||
| 114 | // ldr instruction writes to Rn | |
| 115 | .section .text.08, "ax", %progbits | |
| 116 | .balign 4096 | |
| 117 | .globl t3_ff8_ldr | |
| 118 | .type t3_ff8_ldr, %function | |
| 119 | .space 4096 - 8 | |
| 120 | t3_ff8_ldr: | |
| 121 | adrp x0, dat | |
| 122 | ldr x0, [x1, #0] | |
| 123 | ldr x0, [x0, :got_lo12:dat] | |
| 124 | ret | |
| 125 | ||
| 126 | // str instruction writes to Rn via writeback (pre index) | |
| 127 | .section .text.09, "ax", %progbits | |
| 128 | .balign 4096 | |
| 129 | .globl t3_ff8_str | |
| 130 | .type t3_ff8_str, %function | |
| 131 | .space 4096 - 8 | |
| 132 | t3_ff8_str: | |
| 133 | adrp x0, dat | |
| 134 | str x1, [x0, #4]! | |
| 135 | ldr x0, [x0, :got_lo12:dat] | |
| 136 | ret | |
| 137 | ||
| 138 | // ldr instruction writes to Rn via writeback (post index) | |
| 139 | .section .text.09, "ax", %progbits | |
| 140 | .balign 4096 | |
| 141 | .globl t3_ffc_ldr | |
| 142 | .type t3_ffc_ldr, %function | |
| 143 | .space 4096 - 8 | |
| 144 | t3_ffc_ldr: | |
| 145 | adrp x0, dat | |
| 146 | ldr x1, [x0], 0x8 | |
| 147 | ldr x0, [x0, :got_lo12:dat] | |
| 148 | ret | |
| 149 | ||
| 150 | // stp writes to Rn via writeback (pre index) | |
| 151 | .section .text.10, "ax", %progbits | |
| 152 | .balign 4096 | |
| 153 | .globl t4_ffc_stppre | |
| 154 | .type t4_ffc_stppre, %function | |
| 155 | .space 4096 - 4 | |
| 156 | t4_ffc_stppre: | |
| 157 | adrp x16, dat | |
| 158 | stp x1,x2, [x16, #16]! | |
| 159 | mul x3, x16, x16 | |
| 160 | ldr x14, [x16, #8] | |
| 161 | ret | |
| 162 | ||
| 163 | // stp writes to Rn via writeback (post index) | |
| 164 | .section .text.11, "ax", %progbits | |
| 165 | .balign 4096 | |
| 166 | .globl t4_ff8_stppost | |
| 167 | .type t4_ff8_stppost, %function | |
| 168 | .space 4096 - 8 | |
| 169 | t4_ff8_stppost: | |
| 170 | adrp x16, dat | |
| 171 | stp x1,x2, [x16], #16 | |
| 172 | mul x3, x16, x16 | |
| 173 | ldr x14, [x16, #8] | |
| 174 | ret | |
| 175 | ||
| 176 | // st1 writes to Rn via writeback | |
| 177 | .section .text.12, "ax", %progbits | |
| 178 | .balign 4096 | |
| 179 | .globl t3_ff8_st1 | |
| 180 | .type t3_ff8_st1, %function | |
| 181 | .space 4096 - 8 | |
| 182 | t3_ff8_st1: | |
| 183 | adrp x16, dat | |
| 184 | st1 { v0.16b}, [x16], x2 | |
| 185 | ldr x13, [x16, :got_lo12:dat] | |
| 186 | ret | |
| 187 | ||
| 188 | // Close match for erratum sequence, but with optional instruction 3 a branch | |
| 189 | ||
| 190 | // function call via immediate | |
| 191 | .section .text.13, "ax", %progbits | |
| 192 | .balign 4096 | |
| 193 | .globl t4_ffc_blimm | |
| 194 | .type t4_ffc_blimm, %function | |
| 195 | .space 4096 - 4 | |
| 196 | t4_ffc_blimm: | |
| 197 | adrp x7, dat | |
| 198 | stnp x1,x2, [x3, #0] | |
| 199 | bl t4_ffc_blimm | |
| 200 | ldr x10, [x7, :got_lo12:dat] | |
| 201 | ret | |
| 202 | ||
| 203 | // function call via register | |
| 204 | .section .text.14, "ax", %progbits | |
| 205 | .balign 4096 | |
| 206 | .globl t4_ffc_blreg | |
| 207 | .type t4_ffc_blreg, %function | |
| 208 | .space 4096 - 4 | |
| 209 | t4_ffc_blreg: | |
| 210 | adrp x7, dat | |
| 211 | stnp x1,x2, [x3, #0] | |
| 212 | blr x4 | |
| 213 | ldr x10, [x7, :got_lo12:dat] | |
| 214 | ret | |
| 215 | ||
| 216 | // Unconditional branch immediate | |
| 217 | .section .text.15, "ax", %progbits | |
| 218 | .balign 4096 | |
| 219 | .globl t4_ffc_branchimm | |
| 220 | .type t4_ffc_branchimm, %function | |
| 221 | .space 4096 - 4 | |
| 222 | t4_ffc_branchimm: | |
| 223 | adrp x7, dat | |
| 224 | stnp x1,x2, [x3, #0] | |
| 225 | b t4_ffc_branchimm | |
| 226 | ldr x10, [x7, :got_lo12:dat] | |
| 227 | ret | |
| 228 | ||
| 229 | // Unconditional branch register | |
| 230 | .section .text.16, "ax", %progbits | |
| 231 | .balign 4096 | |
| 232 | .globl t4_ffc_branchreg | |
| 233 | .type t4_ffc_branchreg, %function | |
| 234 | .space 4096 - 4 | |
| 235 | t4_ffc_branchreg: | |
| 236 | adrp x7, dat | |
| 237 | stnp x1,x2, [x3, #0] | |
| 238 | br x4 | |
| 239 | ldr x10, [x7, :got_lo12:dat] | |
| 240 | ret | |
| 241 | ||
| 242 | // Conditional branch | |
| 243 | .section .text.17, "ax", %progbits | |
| 244 | .balign 4096 | |
| 245 | .globl t4_ffc_branchcond | |
| 246 | .type t4_ffc_branchcond, %function | |
| 247 | .space 4096 - 4 | |
| 248 | t4_ffc_branchcond: | |
| 249 | adrp x7, dat | |
| 250 | stnp x1,x2, [x3, #0] | |
| 251 | cbz x5, t4_ffc_branchcond | |
| 252 | ldr x10, [x7, :got_lo12:dat] | |
| 253 | ret | |
| 254 | ||
| 255 | // Conditional branch immediate | |
| 256 | .section .text.18, "ax", %progbits | |
| 257 | .balign 4096 | |
| 258 | .globl t4_ffc_branchcondimm | |
| 259 | .type t4_ffc_branchcondimm, %function | |
| 260 | .space 4096 - 4 | |
| 261 | t4_ffc_branchcondimm: | |
| 262 | adrp x7, dat | |
| 263 | stnp x1,x2, [x3, #0] | |
| 264 | beq t4_ffc_branchcondimm | |
| 265 | ldr x10, [x7, :got_lo12:dat] | |
| 266 | ret | |
| 267 | ||
| 268 | // Bitpattern matches erratum sequence but either all or part of the sequence | |
| 269 | // is in inline literal data | |
| 270 | .section .text.19, "ax", %progbits | |
| 271 | .balign 4096 | |
| 272 | .globl t3_ffc_ldrtraildata | |
| 273 | .type t3_ff8_ldrtraildata, %function | |
| 274 | .space 4096 - 8 | |
| 275 | t3_ff8_ldrtraildata: | |
| 276 | adrp x0, dat | |
| 277 | ldr x1, [x1, #0] | |
| 278 | // 0xf9400000 = ldr x0, [x0] | |
| 279 | .byte 0x00 | |
| 280 | .byte 0x00 | |
| 281 | .byte 0x40 | |
| 282 | .byte 0xf9 | |
| 283 | ldr x0, [x0, :got_lo12:dat] | |
| 284 | ret | |
| 285 | ||
| 286 | .section .text.20, "ax", %progbits | |
| 287 | .balign 4096 | |
| 288 | .globl t3_ffc_ldrpredata | |
| 289 | .type t3_ff8_ldrpredata, %function | |
| 290 | .space 4096 - 8 | |
| 291 | t3_ff8_ldrpredata: | |
| 292 | // 0x90000000 = adrp x0, #0 | |
| 293 | .byte 0x00 | |
| 294 | .byte 0x00 | |
| 295 | .byte 0x00 | |
| 296 | .byte 0x90 | |
| 297 | ldr x1, [x1, #0] | |
| 298 | ldr x0, [x0, :got_lo12:dat] | |
| 299 | ret | |
| 300 | ||
| 301 | .section .text.21, "ax", %progbits | |
| 302 | .balign 4096 | |
| 303 | .globl t3_ffc_ldralldata | |
| 304 | .type t3_ff8_ldralldata, %function | |
| 305 | .space 4096 - 8 | |
| 306 | t3_ff8_ldralldata: | |
| 307 | // 0x90000000 = adrp x0, #0 | |
| 308 | .byte 0x00 | |
| 309 | .byte 0x00 | |
| 310 | .byte 0x00 | |
| 311 | .byte 0x90 | |
| 312 | // 0xf9400021 = ldr x1, [x1] | |
| 313 | .byte 0x21 | |
| 314 | .byte 0x00 | |
| 315 | .byte 0x40 | |
| 316 | .byte 0xf9 | |
| 317 | // 0xf9400000 = ldr x0, [x0] | |
| 318 | .byte 0x00 | |
| 319 | .byte 0x00 | |
| 320 | .byte 0x40 | |
| 321 | .byte 0xf9 | |
| 322 | ||
| 323 | ret | |
| 324 | ||
| 325 | .text | |
| 326 | .globl _start | |
| 327 | .type _start, %function | |
| 328 | _start: | |
| 329 | ret | |
| 330 | ||
| 331 | ||
| 332 | ||
| 333 | ||
| 334 | ||
| 335 | // Bitpattern matches erratum sequence but section is not executable | |
| 336 | .data | |
| 337 | .globl dat | |
| 338 | dat: .word 0 |
deps/lld/test/ELF/aarch64-cortex-a53-843419-recognize.s created+563| ... | ... | @@ -0,0 +1,563 @@ |
| 1 | // REQUIRES: aarch64 | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o | |
| 3 | // RUN: ld.lld -fix-cortex-a53-843419 -verbose %t.o -o %t2 | FileCheck -check-prefix CHECK-PRINT %s | |
| 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 | |
| 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 | |
| 8 | // See ARM-EPM-048406 Cortex_A53_MPCore_Software_Developers_Errata_Notice.pdf | |
| 9 | // for full erratum details. | |
| 10 | // In Summary | |
| 11 | // 1.) | |
| 12 | // ADRP (0xff8 or 0xffc). | |
| 13 | // 2.) | |
| 14 | // - load or store single register or either integer or vector registers. | |
| 15 | // - STP or STNP of either vector or vector registers. | |
| 16 | // - Advanced SIMD ST1 store instruction. | |
| 17 | // - Must not write Rn. | |
| 18 | // 3.) optional instruction, can't be a branch, must not write Rn, may read Rn. | |
| 19 | // 4.) A load or store instruction from the Load/Store register unsigned | |
| 20 | // immediate class using Rn as the base register. | |
| 21 | ||
| 22 | // Each section contains a sequence of instructions that should be recognized | |
| 23 | // as erratum 843419. The test cases cover the major variations such as: | |
| 24 | // - adrp starts at 0xfff8 or 0xfffc. | |
| 25 | // - Variations in instruction class for instruction 2. | |
| 26 | // - Optional instruction 3 present or not. | |
| 27 | // - Load or store for instruction 4. | |
| 28 | ||
| 29 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 21FF8 in unpatched output. | |
| 30 | // CHECK: t3_ff8_ldr: | |
| 31 | // CHECK-NEXT: 21ff8: e0 01 00 f0 adrp x0, #258048 | |
| 32 | // CHECK-NEXT: 21ffc: 21 00 40 f9 ldr x1, [x1] | |
| 33 | // CHECK-FIX: 22000: 03 b8 00 14 b #188428 | |
| 34 | // CHECK-NOFIX: 22000: 00 00 40 f9 ldr x0, [x0] | |
| 35 | // CHECK-NEXT: 22004: c0 03 5f d6 ret | |
| 36 | .section .text.01, "ax", %progbits | |
| 37 | .balign 4096 | |
| 38 | .globl t3_ff8_ldr | |
| 39 | .type t3_ff8_ldr, %function | |
| 40 | .space 4096 - 8 | |
| 41 | t3_ff8_ldr: | |
| 42 | adrp x0, dat1 | |
| 43 | ldr x1, [x1, #0] | |
| 44 | ldr x0, [x0, :got_lo12:dat1] | |
| 45 | ret | |
| 46 | ||
| 47 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 23FF8 in unpatched output. | |
| 48 | // CHECK: t3_ff8_ldrsimd: | |
| 49 | // CHECK-NEXT: 23ff8: e0 01 00 b0 adrp x0, #249856 | |
| 50 | // CHECK-NEXT: 23ffc: 21 00 40 bd ldr s1, [x1] | |
| 51 | // CHECK-FIX: 24000: 05 b0 00 14 b #180244 | |
| 52 | // CHECK-NOFIX: 24000: 02 04 40 f9 ldr x2, [x0, #8] | |
| 53 | // CHECK-NEXT: 24004: c0 03 5f d6 ret | |
| 54 | .section .text.02, "ax", %progbits | |
| 55 | .balign 4096 | |
| 56 | .globl t3_ff8_ldrsimd | |
| 57 | .type t3_ff8_ldrsimd, %function | |
| 58 | .space 4096 - 8 | |
| 59 | t3_ff8_ldrsimd: | |
| 60 | adrp x0, dat2 | |
| 61 | ldr s1, [x1, #0] | |
| 62 | ldr x2, [x0, :got_lo12:dat2] | |
| 63 | ret | |
| 64 | ||
| 65 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 25FFC in unpatched output. | |
| 66 | // CHECK: t3_ffc_ldrpost: | |
| 67 | // CHECK-NEXT: 25ffc: c0 01 00 f0 adrp x0, #241664 | |
| 68 | // CHECK-NEXT: 26000: 21 84 40 bc ldr s1, [x1], #8 | |
| 69 | // CHECK-FIX: 26004: 06 a8 00 14 b #172056 | |
| 70 | // CHECK-NOFIX: 26004: 03 08 40 f9 ldr x3, [x0, #16] | |
| 71 | // CHECK-NEXT: 26008: c0 03 5f d6 ret | |
| 72 | .section .text.03, "ax", %progbits | |
| 73 | .balign 4096 | |
| 74 | .globl t3_ffc_ldrpost | |
| 75 | .type t3_ffc_ldrpost, %function | |
| 76 | .space 4096 - 4 | |
| 77 | t3_ffc_ldrpost: | |
| 78 | adrp x0, dat3 | |
| 79 | ldr s1, [x1], #8 | |
| 80 | ldr x3, [x0, :got_lo12:dat3] | |
| 81 | ret | |
| 82 | ||
| 83 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 27FF8 in unpatched output. | |
| 84 | // CHECK: t3_ff8_strpre: | |
| 85 | // CHECK-NEXT: 27ff8: c0 01 00 b0 adrp x0, #233472 | |
| 86 | // CHECK-NEXT: 27ffc: 21 8c 00 bc str s1, [x1, #8]! | |
| 87 | // CHECK-FIX: 28000: 09 a0 00 14 b #163876 | |
| 88 | // CHECK-NOFIX: 28000: 02 00 40 f9 ldr x2, [x0] | |
| 89 | // CHECK-NEXT: 28004: c0 03 5f d6 ret | |
| 90 | .section .text.04, "ax", %progbits | |
| 91 | .balign 4096 | |
| 92 | .globl t3_ff8_strpre | |
| 93 | .type t3_ff8_strpre, %function | |
| 94 | .space 4096 - 8 | |
| 95 | t3_ff8_strpre: | |
| 96 | adrp x0, dat1 | |
| 97 | str s1, [x1, #8]! | |
| 98 | ldr x2, [x0, :lo12:dat1] | |
| 99 | ret | |
| 100 | ||
| 101 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 29FFC in unpatched output. | |
| 102 | // CHECK: t3_ffc_str: | |
| 103 | // CHECK-NEXT: 29ffc: bc 01 00 f0 adrp x28, #225280 | |
| 104 | // CHECK-NEXT: 2a000: 42 00 00 f9 str x2, [x2] | |
| 105 | // CHECK-FIX: 2a004: 0a 98 00 14 b #155688 | |
| 106 | // CHECK-NOFIX: 2a004: 9c 07 00 f9 str x28, [x28, #8] | |
| 107 | // CHECK-NEXT: 2a008: c0 03 5f d6 ret | |
| 108 | .section .text.05, "ax", %progbits | |
| 109 | .balign 4096 | |
| 110 | .globl t3_ffc_str | |
| 111 | .type t3_ffc_str, %function | |
| 112 | .space 4096 - 4 | |
| 113 | t3_ffc_str: | |
| 114 | adrp x28, dat2 | |
| 115 | str x2, [x2, #0] | |
| 116 | str x28, [x28, :lo12:dat2] | |
| 117 | ret | |
| 118 | ||
| 119 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2BFFC in unpatched output. | |
| 120 | // CHECK: t3_ffc_strsimd: | |
| 121 | // CHECK-NEXT: 2bffc: bc 01 00 b0 adrp x28, #217088 | |
| 122 | // CHECK-NEXT: 2c000: 44 00 00 b9 str w4, [x2] | |
| 123 | // CHECK-FIX: 2c004: 0c 90 00 14 b #147504 | |
| 124 | // CHECK-NOFIX: 2c004: 84 0b 00 f9 str x4, [x28, #16] | |
| 125 | // CHECK-NEXT: 2c008: c0 03 5f d6 ret | |
| 126 | .section .text.06, "ax", %progbits | |
| 127 | .balign 4096 | |
| 128 | .globl t3_ffc_strsimd | |
| 129 | .type t3_ffc_strsimd, %function | |
| 130 | .space 4096 - 4 | |
| 131 | t3_ffc_strsimd: | |
| 132 | adrp x28, dat3 | |
| 133 | str w4, [x2, #0] | |
| 134 | str x4, [x28, :lo12:dat3] | |
| 135 | ret | |
| 136 | ||
| 137 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2DFF8 in unpatched output. | |
| 138 | // CHECK: t3_ff8_ldrunpriv: | |
| 139 | // CHECK-NEXT: 2dff8: 9d 01 00 f0 adrp x29, #208896 | |
| 140 | // CHECK-NEXT: 2dffc: 41 08 40 38 ldtrb w1, [x2] | |
| 141 | // CHECK-FIX: 2e000: 0f 88 00 14 b #139324 | |
| 142 | // CHECK-NOFIX: 2e000: bd 03 40 f9 ldr x29, [x29] | |
| 143 | // CHECK-NEXT: 2e004: c0 03 5f d6 ret | |
| 144 | .section .text.07, "ax", %progbits | |
| 145 | .balign 4096 | |
| 146 | .globl t3_ff8_ldrunpriv | |
| 147 | .type t3_ff8_ldrunpriv, %function | |
| 148 | .space 4096 - 8 | |
| 149 | t3_ff8_ldrunpriv: | |
| 150 | adrp x29, dat1 | |
| 151 | ldtrb w1, [x2, #0] | |
| 152 | ldr x29, [x29, :got_lo12:dat1] | |
| 153 | ret | |
| 154 | ||
| 155 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2FFFC in unpatched output. | |
| 156 | // CHECK: t3_ffc_ldur: | |
| 157 | // CHECK-NEXT: 2fffc: 9d 01 00 b0 adrp x29, #200704 | |
| 158 | // CHECK-NEXT: 30000: 42 40 40 b8 ldur w2, [x2, #4] | |
| 159 | // CHECK-FIX: 30004: 10 80 00 14 b #131136 | |
| 160 | // CHECK-NOFIX: 30004: bd 07 40 f9 ldr x29, [x29, #8] | |
| 161 | // CHECK-NEXT: 30008: c0 03 5f d6 ret | |
| 162 | .balign 4096 | |
| 163 | .globl t3_ffc_ldur | |
| 164 | .type t3_ffc_ldur, %function | |
| 165 | .space 4096 - 4 | |
| 166 | t3_ffc_ldur: | |
| 167 | adrp x29, dat2 | |
| 168 | ldur w2, [x2, #4] | |
| 169 | ldr x29, [x29, :got_lo12:dat2] | |
| 170 | ret | |
| 171 | ||
| 172 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 31FFC in unpatched output. | |
| 173 | // CHECK: t3_ffc_sturh: | |
| 174 | // CHECK-NEXT: 31ffc: 72 01 00 f0 adrp x18, #192512 | |
| 175 | // CHECK-NEXT: 32000: 43 40 00 78 sturh w3, [x2, #4] | |
| 176 | // CHECK-FIX: 32004: 12 78 00 14 b #122952 | |
| 177 | // CHECK-NOFIX: 32004: 41 0a 40 f9 ldr x1, [x18, #16] | |
| 178 | // CHECK-NEXT: 32008: c0 03 5f d6 ret | |
| 179 | .section .text.09, "ax", %progbits | |
| 180 | .balign 4096 | |
| 181 | .globl t3_ffc_sturh | |
| 182 | .type t3_ffc_sturh, %function | |
| 183 | .space 4096 - 4 | |
| 184 | t3_ffc_sturh: | |
| 185 | adrp x18, dat3 | |
| 186 | sturh w3, [x2, #4] | |
| 187 | ldr x1, [x18, :got_lo12:dat3] | |
| 188 | ret | |
| 189 | ||
| 190 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 33FF8 in unpatched output. | |
| 191 | // CHECK: t3_ff8_literal: | |
| 192 | // CHECK-NEXT: 33ff8: 72 01 00 b0 adrp x18, #184320 | |
| 193 | // CHECK-NEXT: 33ffc: e3 ff ff 58 ldr x3, #-4 | |
| 194 | // CHECK-FIX: 34000: 15 70 00 14 b #114772 | |
| 195 | // CHECK-NOFIX: 34000: 52 02 40 f9 ldr x18, [x18] | |
| 196 | // CHECK-NEXT: 34004: c0 03 5f d6 ret | |
| 197 | .section .text.10, "ax", %progbits | |
| 198 | .balign 4096 | |
| 199 | .globl t3_ff8_literal | |
| 200 | .type t3_ff8_literal, %function | |
| 201 | .space 4096 - 8 | |
| 202 | t3_ff8_literal: | |
| 203 | adrp x18, dat1 | |
| 204 | ldr x3, t3_ff8_literal | |
| 205 | ldr x18, [x18, :lo12:dat1] | |
| 206 | ret | |
| 207 | ||
| 208 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 35FFC in unpatched output. | |
| 209 | // CHECK: t3_ffc_register: | |
| 210 | // CHECK-NEXT: 35ffc: 4f 01 00 f0 adrp x15, #176128 | |
| 211 | // CHECK-NEXT: 36000: 43 68 61 f8 ldr x3, [x2, x1] | |
| 212 | // CHECK-FIX: 36004: 16 68 00 14 b #106584 | |
| 213 | // CHECK-NOFIX: 36004: ea 05 40 f9 ldr x10, [x15, #8] | |
| 214 | // CHECK-NEXT: 36008: c0 03 5f d6 ret | |
| 215 | .section .text.11, "ax", %progbits | |
| 216 | .balign 4096 | |
| 217 | .globl t3_ffc_register | |
| 218 | .type t3_ffc_register, %function | |
| 219 | .space 4096 - 4 | |
| 220 | t3_ffc_register: | |
| 221 | adrp x15, dat2 | |
| 222 | ldr x3, [x2, x1] | |
| 223 | ldr x10, [x15, :lo12:dat2] | |
| 224 | ret | |
| 225 | ||
| 226 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 37FF8 in unpatched output. | |
| 227 | // CHECK: t3_ff8_stp: | |
| 228 | // CHECK-NEXT: 37ff8: 50 01 00 b0 adrp x16, #167936 | |
| 229 | // CHECK-NEXT: 37ffc: 61 08 00 a9 stp x1, x2, [x3] | |
| 230 | // CHECK-FIX: 38000: 19 60 00 14 b #98404 | |
| 231 | // CHECK-NOFIX: 38000: 0d 0a 40 f9 ldr x13, [x16, #16] | |
| 232 | // CHECK-NEXT: 38004: c0 03 5f d6 ret | |
| 233 | .section .text.12, "ax", %progbits | |
| 234 | .balign 4096 | |
| 235 | .globl t3_ff8_stp | |
| 236 | .type t3_ff8_stp, %function | |
| 237 | .space 4096 - 8 | |
| 238 | t3_ff8_stp: | |
| 239 | adrp x16, dat3 | |
| 240 | stp x1,x2, [x3, #0] | |
| 241 | ldr x13, [x16, :lo12:dat3] | |
| 242 | ret | |
| 243 | ||
| 244 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 39FFC in unpatched output. | |
| 245 | // CHECK: t3_ffc_stnp: | |
| 246 | // CHECK-NEXT: 39ffc: 27 01 00 f0 adrp x7, #159744 | |
| 247 | // CHECK-NEXT: 3a000: 61 08 00 a8 stnp x1, x2, [x3] | |
| 248 | // CHECK-FIX: 3a004: 1a 58 00 14 b #90216 | |
| 249 | // CHECK-NOFIX: 3a004: e9 00 40 f9 ldr x9, [x7] | |
| 250 | // CHECK-NEXT: 3a008: c0 03 5f d6 ret | |
| 251 | .section .text.13, "ax", %progbits | |
| 252 | .balign 4096 | |
| 253 | .globl t3_ffc_stnp | |
| 254 | .type t3_ffc_stnp, %function | |
| 255 | .space 4096 - 4 | |
| 256 | t3_ffc_stnp: | |
| 257 | adrp x7, dat1 | |
| 258 | stnp x1,x2, [x3, #0] | |
| 259 | ldr x9, [x7, :lo12:dat1] | |
| 260 | ret | |
| 261 | ||
| 262 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3BFFC in unpatched output. | |
| 263 | // CHECK: t3_ffc_st1singlepost: | |
| 264 | // CHECK-NEXT: 3bffc: 37 01 00 b0 adrp x23, #151552 | |
| 265 | // CHECK-NEXT: 3c000: 20 70 82 4c st1 { v0.16b }, [x1], x2 | |
| 266 | // CHECK-FIX: 3c004: 1c 50 00 14 b #82032 | |
| 267 | // CHECK-NOFIX: 3c004: f6 06 40 f9 ldr x22, [x23, #8] | |
| 268 | // CHECK-NEXT: 3c008: c0 03 5f d6 ret | |
| 269 | .section .text.14, "ax", %progbits | |
| 270 | .balign 4096 | |
| 271 | .globl t3_ffc_st1singlepost | |
| 272 | .type t3_ffc_st1singlepost, %function | |
| 273 | .space 4096 - 4 | |
| 274 | t3_ffc_st1singlepost: | |
| 275 | adrp x23, dat2 | |
| 276 | st1 { v0.16b }, [x1], x2 | |
| 277 | ldr x22, [x23, :lo12:dat2] | |
| 278 | ret | |
| 279 | ||
| 280 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3DFF8 in unpatched output. | |
| 281 | // CHECK: t3_ff8_st1multiple: | |
| 282 | // CHECK-NEXT: 3dff8: 17 01 00 f0 adrp x23, #143360 | |
| 283 | // CHECK-NEXT: 3dffc: 20 a0 00 4c st1 { v0.16b, v1.16b }, [x1] | |
| 284 | // CHECK-FIX: 3e000: 1f 48 00 14 b #73852 | |
| 285 | // CHECK-NOFIX: 3e000: f8 0a 40 f9 ldr x24, [x23, #16] | |
| 286 | // CHECK-NEXT: 3e004: c0 03 5f d6 ret | |
| 287 | .section .text.15, "ax", %progbits | |
| 288 | .balign 4096 | |
| 289 | .globl t3_ff8_st1multiple | |
| 290 | .type t3_ff8_st1muliple, %function | |
| 291 | .space 4096 - 8 | |
| 292 | t3_ff8_st1multiple: | |
| 293 | adrp x23, dat3 | |
| 294 | st1 { v0.16b, v1.16b }, [x1] | |
| 295 | ldr x24, [x23, :lo12:dat3] | |
| 296 | ret | |
| 297 | ||
| 298 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3FFF8 in unpatched output. | |
| 299 | // CHECK: t4_ff8_ldr: | |
| 300 | // CHECK-NEXT: 3fff8: 00 01 00 b0 adrp x0, #135168 | |
| 301 | // CHECK-NEXT: 3fffc: 21 00 40 f9 ldr x1, [x1] | |
| 302 | // CHECK-NEXT: 40000: 42 00 00 8b add x2, x2, x0 | |
| 303 | // CHECK-FIX: 40004: 20 40 00 14 b #65664 | |
| 304 | // CHECK-NOFIX: 40004: 02 00 40 f9 ldr x2, [x0] | |
| 305 | // CHECK-NEXT: 40008: c0 03 5f d6 ret | |
| 306 | .section .text.16, "ax", %progbits | |
| 307 | .balign 4096 | |
| 308 | .globl t4_ff8_ldr | |
| 309 | .type t4_ff8_ldr, %function | |
| 310 | .space 4096 - 8 | |
| 311 | t4_ff8_ldr: | |
| 312 | adrp x0, dat1 | |
| 313 | ldr x1, [x1, #0] | |
| 314 | add x2, x2, x0 | |
| 315 | ldr x2, [x0, :got_lo12:dat1] | |
| 316 | ret | |
| 317 | ||
| 318 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 41FFC in unpatched output. | |
| 319 | // CHECK: t4_ffc_str: | |
| 320 | // CHECK-NEXT: 41ffc: fc 00 00 f0 adrp x28, #126976 | |
| 321 | // CHECK-NEXT: 42000: 42 00 00 f9 str x2, [x2] | |
| 322 | // CHECK-NEXT: 42004: 20 00 02 cb sub x0, x1, x2 | |
| 323 | // CHECK-FIX: 42008: 21 38 00 14 b #57476 | |
| 324 | // CHECK-NOFIX: 42008: 9b 07 00 f9 str x27, [x28, #8] | |
| 325 | // CHECK-NEXT: 4200c: c0 03 5f d6 ret | |
| 326 | .section .text.17, "ax", %progbits | |
| 327 | .balign 4096 | |
| 328 | .globl t4_ffc_str | |
| 329 | .type t4_ffc_str, %function | |
| 330 | .space 4096 - 4 | |
| 331 | t4_ffc_str: | |
| 332 | adrp x28, dat2 | |
| 333 | str x2, [x2, #0] | |
| 334 | sub x0, x1, x2 | |
| 335 | str x27, [x28, :got_lo12:dat2] | |
| 336 | ret | |
| 337 | ||
| 338 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 43FF8 in unpatched output. | |
| 339 | // CHECK: t4_ff8_stp: | |
| 340 | // CHECK-NEXT: 43ff8: f0 00 00 b0 adrp x16, #118784 | |
| 341 | // CHECK-NEXT: 43ffc: 61 08 00 a9 stp x1, x2, [x3] | |
| 342 | // CHECK-NEXT: 44000: 03 7e 10 9b mul x3, x16, x16 | |
| 343 | // CHECK-FIX: 44004: 24 30 00 14 b #49296 | |
| 344 | // CHECK-NOFIX: 44004: 0e 0a 40 f9 ldr x14, [x16, #16] | |
| 345 | // CHECK-NEXT: 44008: c0 03 5f d6 ret | |
| 346 | .section .text.18, "ax", %progbits | |
| 347 | .balign 4096 | |
| 348 | .globl t4_ff8_stp | |
| 349 | .type t4_ff8_stp, %function | |
| 350 | .space 4096 - 8 | |
| 351 | t4_ff8_stp: | |
| 352 | adrp x16, dat3 | |
| 353 | stp x1,x2, [x3, #0] | |
| 354 | mul x3, x16, x16 | |
| 355 | ldr x14, [x16, :got_lo12:dat3] | |
| 356 | ret | |
| 357 | ||
| 358 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 45FF8 in unpatched output. | |
| 359 | // CHECK: t4_ff8_stppre: | |
| 360 | // CHECK-NEXT: 45ff8: d0 00 00 f0 adrp x16, #110592 | |
| 361 | // CHECK-NEXT: 45ffc: 61 08 81 a9 stp x1, x2, [x3, #16]! | |
| 362 | // CHECK-NEXT: 46000: 03 7e 10 9b mul x3, x16, x16 | |
| 363 | // CHECK-FIX: 46004: 26 28 00 14 b #41112 | |
| 364 | // CHECK-NOFIX: 46004: 0e 06 40 f9 ldr x14, [x16, #8] | |
| 365 | // CHECK-NEXT: 46008: c0 03 5f d6 ret | |
| 366 | .section .text.19, "ax", %progbits | |
| 367 | .balign 4096 | |
| 368 | .globl t4_ff8_stppre | |
| 369 | .type t4_ff8_stppre, %function | |
| 370 | .space 4096 - 8 | |
| 371 | t4_ff8_stppre: | |
| 372 | adrp x16, dat1 | |
| 373 | stp x1,x2, [x3, #16]! | |
| 374 | mul x3, x16, x16 | |
| 375 | ldr x14, [x16, #8] | |
| 376 | ret | |
| 377 | ||
| 378 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 47FF8 in unpatched output. | |
| 379 | // CHECK: t4_ff8_stppost: | |
| 380 | // CHECK-NEXT: 47ff8: d0 00 00 b0 adrp x16, #102400 | |
| 381 | // CHECK-NEXT: 47ffc: 61 08 81 a8 stp x1, x2, [x3], #16 | |
| 382 | // CHECK-NEXT: 48000: 03 7e 10 9b mul x3, x16, x16 | |
| 383 | // CHECK-FIX: 48004: 28 20 00 14 b #32928 | |
| 384 | // CHECK-NOFIX: 48004: 0e 06 40 f9 ldr x14, [x16, #8] | |
| 385 | // CHECK-NEXT: 48008: c0 03 5f d6 ret | |
| 386 | .section .text.20, "ax", %progbits | |
| 387 | .balign 4096 | |
| 388 | .globl t4_ff8_stppost | |
| 389 | .type t4_ff8_stppost, %function | |
| 390 | .space 4096 - 8 | |
| 391 | t4_ff8_stppost: | |
| 392 | adrp x16, dat2 | |
| 393 | stp x1,x2, [x3], #16 | |
| 394 | mul x3, x16, x16 | |
| 395 | ldr x14, [x16, #8] | |
| 396 | ret | |
| 397 | ||
| 398 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 49FFC in unpatched output. | |
| 399 | // CHECK: t4_ffc_stpsimd: | |
| 400 | // CHECK-NEXT: 49ffc: b0 00 00 f0 adrp x16, #94208 | |
| 401 | // CHECK-NEXT: 4a000: 61 08 00 ad stp q1, q2, [x3] | |
| 402 | // CHECK-NEXT: 4a004: 03 7e 10 9b mul x3, x16, x16 | |
| 403 | // CHECK-FIX: 4a008: 29 18 00 14 b #24740 | |
| 404 | // CHECK-NOFIX: 4a008: 0e 06 40 f9 ldr x14, [x16, #8] | |
| 405 | // CHECK-NEXT: 4a00c: c0 03 5f d6 ret | |
| 406 | .section .text.21, "ax", %progbits | |
| 407 | .balign 4096 | |
| 408 | .globl t4_ffc_stpsimd | |
| 409 | .type t4_ffc_stpsimd, %function | |
| 410 | .space 4096 - 4 | |
| 411 | t4_ffc_stpsimd: | |
| 412 | adrp x16, dat3 | |
| 413 | stp q1,q2, [x3, #0] | |
| 414 | mul x3, x16, x16 | |
| 415 | ldr x14, [x16, #8] | |
| 416 | ret | |
| 417 | ||
| 418 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4BFFC in unpatched output. | |
| 419 | // CHECK: t4_ffc_stnp: | |
| 420 | // CHECK-NEXT: 4bffc: a7 00 00 b0 adrp x7, #86016 | |
| 421 | // CHECK-NEXT: 4c000: 61 08 00 a8 stnp x1, x2, [x3] | |
| 422 | // CHECK-NEXT: 4c004: 1f 20 03 d5 nop | |
| 423 | // CHECK-FIX: 4c008: 2b 10 00 14 b #16556 | |
| 424 | // CHECK-NOFIX: 4c008: ea 00 40 f9 ldr x10, [x7] | |
| 425 | // CHECK-NEXT: 4c00c: c0 03 5f d6 ret | |
| 426 | .section .text.22, "ax", %progbits | |
| 427 | .balign 4096 | |
| 428 | .globl t4_ffc_stnp | |
| 429 | .type t4_ffc_stnp, %function | |
| 430 | .space 4096 - 4 | |
| 431 | t4_ffc_stnp: | |
| 432 | adrp x7, dat1 | |
| 433 | stnp x1,x2, [x3, #0] | |
| 434 | nop | |
| 435 | ldr x10, [x7, :got_lo12:dat1] | |
| 436 | ret | |
| 437 | ||
| 438 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4DFFC in unpatched output. | |
| 439 | // CHECK: t4_ffc_st1: | |
| 440 | // CHECK-NEXT: 4dffc: 98 00 00 f0 adrp x24, #77824 | |
| 441 | // CHECK-NEXT: 4e000: 20 70 00 4c st1 { v0.16b }, [x1] | |
| 442 | // CHECK-NEXT: 4e004: f6 06 40 f9 ldr x22, [x23, #8] | |
| 443 | // CHECK-FIX: 4e008: 2d 08 00 14 b #8372 | |
| 444 | // CHECK-NOFIX: 4e008: 18 ff 3f f9 str x24, [x24, #32760] | |
| 445 | // CHECK-NEXT: 4e00c: c0 03 5f d6 ret | |
| 446 | .section .text.23, "ax", %progbits | |
| 447 | .balign 4096 | |
| 448 | .globl t4_ffc_st1 | |
| 449 | .type t4_ffc_st1, %function | |
| 450 | .space 4096 - 4 | |
| 451 | t4_ffc_st1: | |
| 452 | adrp x24, dat2 | |
| 453 | st1 { v0.16b }, [x1] | |
| 454 | ldr x22, [x23, :got_lo12:dat2] | |
| 455 | str x24, [x24, #32760] | |
| 456 | ret | |
| 457 | ||
| 458 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4FFF8 in unpatched output. | |
| 459 | // CHECK: t3_ff8_ldr_once: | |
| 460 | // CHECK-NEXT: 4fff8: 80 00 00 b0 adrp x0, #69632 | |
| 461 | // CHECK-NEXT: 4fffc: 20 70 82 4c st1 { v0.16b }, [x1], x2 | |
| 462 | // CHECK-FIX: 50000: 31 00 00 14 b #196 | |
| 463 | // CHECK-NOFIX: 50000: 01 08 40 f9 ldr x1, [x0, #16] | |
| 464 | // CHECK-NEXT: 50004: 02 08 40 f9 ldr x2, [x0, #16] | |
| 465 | // CHECK-NEXT: 50008: c0 03 5f d6 ret | |
| 466 | .section .text.24, "ax", %progbits | |
| 467 | .balign 4096 | |
| 468 | .globl t3_ff8_ldr_once | |
| 469 | .type t3_ff8_ldr_once, %function | |
| 470 | .space 4096 - 8 | |
| 471 | t3_ff8_ldr_once: | |
| 472 | adrp x0, dat3 | |
| 473 | st1 { v0.16b }, [x1], x2 | |
| 474 | ldr x1, [x0, #16] | |
| 475 | ldr x2, [x0, #16] | |
| 476 | ret | |
| 477 | ||
| 478 | .text | |
| 479 | .globl _start | |
| 480 | .type _start, %function | |
| 481 | _start: | |
| 482 | ret | |
| 483 | ||
| 484 | // CHECK-FIX: __CortexA53843419_22000: | |
| 485 | // CHECK-FIX-NEXT: 5000c: 00 00 40 f9 ldr x0, [x0] | |
| 486 | // CHECK-FIX-NEXT: 50010: fd 47 ff 17 b #-188428 | |
| 487 | // CHECK-FIX: __CortexA53843419_24000: | |
| 488 | // CHECK-FIX-NEXT: 50014: 02 04 40 f9 ldr x2, [x0, #8] | |
| 489 | // CHECK-FIX-NEXT: 50018: fb 4f ff 17 b #-180244 | |
| 490 | // CHECK-FIX: __CortexA53843419_26004: | |
| 491 | // CHECK-FIX-NEXT: 5001c: 03 08 40 f9 ldr x3, [x0, #16] | |
| 492 | // CHECK-FIX-NEXT: 50020: fa 57 ff 17 b #-172056 | |
| 493 | // CHECK-FIX: __CortexA53843419_28000: | |
| 494 | // CHECK-FIX-NEXT: 50024: 02 00 40 f9 ldr x2, [x0] | |
| 495 | // CHECK-FIX-NEXT: 50028: f7 5f ff 17 b #-163876 | |
| 496 | // CHECK-FIX: __CortexA53843419_2A004: | |
| 497 | // CHECK-FIX-NEXT: 5002c: 9c 07 00 f9 str x28, [x28, #8] | |
| 498 | // CHECK-FIX-NEXT: 50030: f6 67 ff 17 b #-155688 | |
| 499 | // CHECK-FIX: __CortexA53843419_2C004: | |
| 500 | // CHECK-FIX-NEXT: 50034: 84 0b 00 f9 str x4, [x28, #16] | |
| 501 | // CHECK-FIX-NEXT: 50038: f4 6f ff 17 b #-147504 | |
| 502 | // CHECK-FIX: __CortexA53843419_2E000: | |
| 503 | // CHECK-FIX-NEXT: 5003c: bd 03 40 f9 ldr x29, [x29] | |
| 504 | // CHECK-FIX-NEXT: 50040: f1 77 ff 17 b #-139324 | |
| 505 | // CHECK-FIX: __CortexA53843419_30004: | |
| 506 | // CHECK-FIX-NEXT: 50044: bd 07 40 f9 ldr x29, [x29, #8] | |
| 507 | // CHECK-FIX-NEXT: 50048: f0 7f ff 17 b #-131136 | |
| 508 | // CHECK-FIX: __CortexA53843419_32004: | |
| 509 | // CHECK-FIX-NEXT: 5004c: 41 0a 40 f9 ldr x1, [x18, #16] | |
| 510 | // CHECK-FIX-NEXT: 50050: ee 87 ff 17 b #-122952 | |
| 511 | // CHECK-FIX: __CortexA53843419_34000: | |
| 512 | // CHECK-FIX-NEXT: 50054: 52 02 40 f9 ldr x18, [x18] | |
| 513 | // CHECK-FIX-NEXT: 50058: eb 8f ff 17 b #-114772 | |
| 514 | // CHECK-FIX: __CortexA53843419_36004: | |
| 515 | // CHECK-FIX-NEXT: 5005c: ea 05 40 f9 ldr x10, [x15, #8] | |
| 516 | // CHECK-FIX-NEXT: 50060: ea 97 ff 17 b #-106584 | |
| 517 | // CHECK-FIX: __CortexA53843419_38000: | |
| 518 | // CHECK-FIX-NEXT: 50064: 0d 0a 40 f9 ldr x13, [x16, #16] | |
| 519 | // CHECK-FIX-NEXT: 50068: e7 9f ff 17 b #-98404 | |
| 520 | // CHECK-FIX: __CortexA53843419_3A004: | |
| 521 | // CHECK-FIX-NEXT: 5006c: e9 00 40 f9 ldr x9, [x7] | |
| 522 | // CHECK-FIX-NEXT: 50070: e6 a7 ff 17 b #-90216 | |
| 523 | // CHECK-FIX: __CortexA53843419_3C004: | |
| 524 | // CHECK-FIX-NEXT: 50074: f6 06 40 f9 ldr x22, [x23, #8] | |
| 525 | // CHECK-FIX-NEXT: 50078: e4 af ff 17 b #-82032 | |
| 526 | // CHECK-FIX: __CortexA53843419_3E000: | |
| 527 | // CHECK-FIX-NEXT: 5007c: f8 0a 40 f9 ldr x24, [x23, #16] | |
| 528 | // CHECK-FIX-NEXT: 50080: e1 b7 ff 17 b #-73852 | |
| 529 | // CHECK-FIX: __CortexA53843419_40004: | |
| 530 | // CHECK-FIX-NEXT: 50084: 02 00 40 f9 ldr x2, [x0] | |
| 531 | // CHECK-FIX-NEXT: 50088: e0 bf ff 17 b #-65664 | |
| 532 | // CHECK-FIX: __CortexA53843419_42008: | |
| 533 | // CHECK-FIX-NEXT: 5008c: 9b 07 00 f9 str x27, [x28, #8] | |
| 534 | // CHECK-FIX-NEXT: 50090: df c7 ff 17 b #-57476 | |
| 535 | // CHECK-FIX: __CortexA53843419_44004: | |
| 536 | // CHECK-FIX-NEXT: 50094: 0e 0a 40 f9 ldr x14, [x16, #16] | |
| 537 | // CHECK-FIX-NEXT: 50098: dc cf ff 17 b #-49296 | |
| 538 | // CHECK-FIX: __CortexA53843419_46004: | |
| 539 | // CHECK-FIX-NEXT: 5009c: 0e 06 40 f9 ldr x14, [x16, #8] | |
| 540 | // CHECK-FIX-NEXT: 500a0: da d7 ff 17 b #-41112 | |
| 541 | // CHECK-FIX: __CortexA53843419_48004: | |
| 542 | // CHECK-FIX-NEXT: 500a4: 0e 06 40 f9 ldr x14, [x16, #8] | |
| 543 | // CHECK-FIX-NEXT: 500a8: d8 df ff 17 b #-32928 | |
| 544 | // CHECK-FIX: __CortexA53843419_4A008: | |
| 545 | // CHECK-FIX-NEXT: 500ac: 0e 06 40 f9 ldr x14, [x16, #8] | |
| 546 | // CHECK-FIX-NEXT: 500b0: d7 e7 ff 17 b #-24740 | |
| 547 | // CHECK-FIX: __CortexA53843419_4C008: | |
| 548 | // CHECK-FIX-NEXT: 500b4: ea 00 40 f9 ldr x10, [x7] | |
| 549 | // CHECK-FIX-NEXT: 500b8: d5 ef ff 17 b #-16556 | |
| 550 | // CHECK-FIX: __CortexA53843419_4E008: | |
| 551 | // CHECK-FIX-NEXT: 500bc: 18 ff 3f f9 str x24, [x24, #32760] | |
| 552 | // CHECK-FIX-NEXT: 500c0: d3 f7 ff 17 b #-8372 | |
| 553 | // CHECK-FIX: __CortexA53843419_50000: | |
| 554 | // CHECK-FIX-NEXT: 500c4: 01 08 40 f9 ldr x1, [x0, #16] | |
| 555 | // CHECK-FIX-NEXT: 500c8: cf ff ff 17 b #-196 | |
| 556 | ||
| 557 | .data | |
| 558 | .globl dat | |
| 559 | .globl dat2 | |
| 560 | .globl dat3 | |
| 561 | dat1: .quad 1 | |
| 562 | dat2: .quad 2 | |
| 563 | dat3: .quad 3 |
deps/lld/test/ELF/aarch64-cortex-a53-843419-thunk.s created+57| ... | ... | @@ -0,0 +1,57 @@ |
| 1 | // REQUIRES: aarch64 | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o | |
| 3 | // RUN: echo "SECTIONS { \ | |
| 4 | // RUN: .text1 0x10000 : { *(.text.01) *(.text.02) *(.text.03) } \ | |
| 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 | |
| 7 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s | |
| 8 | ||
| 9 | // %t2 is 128 Megabytes, so delete it early. | |
| 10 | // RUN: rm %t2 | |
| 11 | ||
| 12 | // Test cases for Cortex-A53 Erratum 843419 that involve interactions with | |
| 13 | // range extension thunks. Both erratum fixes and range extension thunks need | |
| 14 | // precise address information and after creation alter address information. | |
| 15 | ||
| 16 | ||
| 17 | .section .text.01, "ax", %progbits | |
| 18 | .balign 4096 | |
| 19 | .globl _start | |
| 20 | .type _start, %function | |
| 21 | _start: | |
| 22 | bl far_away | |
| 23 | // Thunk to far_away, size 16-bytes goes here. | |
| 24 | ||
| 25 | .section .text.02, "ax", %progbits | |
| 26 | .space 4096 - 28 | |
| 27 | ||
| 28 | // Erratum sequence will only line up at address 0 modulo 0xffc when | |
| 29 | // Thunk is inserted. | |
| 30 | .section .text.03, "ax", %progbits | |
| 31 | .globl t3_ff8_ldr | |
| 32 | .type t3_ff8_ldr, %function | |
| 33 | t3_ff8_ldr: | |
| 34 | adrp x0, dat | |
| 35 | ldr x1, [x1, #0] | |
| 36 | ldr x0, [x0, :got_lo12:dat] | |
| 37 | ret | |
| 38 | ||
| 39 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 10FFC in unpatched output. | |
| 40 | // CHECK: t3_ff8_ldr: | |
| 41 | // CHECK-NEXT: 10ffc: 00 00 04 90 adrp x0, #134217728 | |
| 42 | // CHECK-NEXT: 11000: 21 00 40 f9 ldr x1, [x1] | |
| 43 | // CHECK-NEXT: 11004: 02 00 00 14 b #8 | |
| 44 | // CHECK-NEXT: 11008: c0 03 5f d6 ret | |
| 45 | // CHECK: __CortexA53843419_11004: | |
| 46 | // CHECK-NEXT: 1100c: 00 08 40 f9 ldr x0, [x0, #16] | |
| 47 | // CHECK-NEXT: 11010: fe ff ff 17 b #-8 | |
| 48 | ||
| 49 | .section .text.04, "ax", %progbits | |
| 50 | .globl far_away | |
| 51 | .type far_away, function | |
| 52 | far_away: | |
| 53 | ret | |
| 54 | ||
| 55 | .section .data | |
| 56 | .globl dat | |
| 57 | dat: .quad 0 |
deps/lld/test/ELF/aarch64-gnu-ifunc-plt.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %S/Inputs/shared2.s -o %t1.o |
| 2 | 2 | // RUN: ld.lld %t1.o --shared -o %t.so |
| 3 | 3 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o |
| 4 | // RUN: ld.lld %t.so %t.o -o %tout | |
| 4 | // RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout | |
| 5 | 5 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM |
| 6 | 6 | // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT |
| 7 | 7 | // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s |
deps/lld/test/ELF/aarch64-gnu-ifunc.s+1-1| ... | ... | @@ -15,7 +15,7 @@ |
| 15 | 15 | // CHECK-NEXT: Address: [[RELA:.*]] |
| 16 | 16 | // CHECK-NEXT: Offset: 0x158 |
| 17 | 17 | // CHECK-NEXT: Size: 48 |
| 18 | // CHECK-NEXT: Link: 6 | |
| 18 | // CHECK-NEXT: Link: 0 | |
| 19 | 19 | // CHECK-NEXT: Info: 0 |
| 20 | 20 | // CHECK-NEXT: AddressAlignment: 8 |
| 21 | 21 | // CHECK-NEXT: EntrySize: 24 |
deps/lld/test/ELF/aarch64-got-reloc.s+2-2| ... | ... | @@ -9,8 +9,8 @@ |
| 9 | 9 | // CHECK-NEXT: SHF_ALLOC |
| 10 | 10 | // CHECK-NEXT: SHF_WRITE |
| 11 | 11 | // CHECK-NEXT: ] |
| 12 | // CHECK-NEXT: Address: 0x30000 | |
| 13 | // CHECK-NEXT: Offset: 0x20000 | |
| 12 | // CHECK-NEXT: Address: | |
| 13 | // CHECK-NEXT: Offset: | |
| 14 | 14 | // CHECK-NEXT: Size: 8 |
| 15 | 15 | // CHECK-NEXT: Link: 0 |
| 16 | 16 | // CHECK-NEXT: Info: 0 |
deps/lld/test/ELF/aarch64-got-relocations.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | # REQUIRES: aarch64 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-cloudabi %s -o %t.o |
| 3 | # RUN: ld.lld -pie %t.o -o %t | |
| 3 | # RUN: ld.lld --hash-style=sysv -pie %t.o -o %t | |
| 4 | 4 | # RUN: llvm-readobj -r %t | FileCheck %s |
| 5 | 5 | |
| 6 | 6 | # If we're addressing a global relatively through the GOT, we still need to |
deps/lld/test/ELF/aarch64-jump26-error.s deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 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 -o %t | |
| 3 | // RUN: not ld.lld %t %tabs -o %t2 2>&1 | FileCheck %s | |
| 4 | // REQUIRES: aarch64 | |
| 5 | ||
| 6 | .text | |
| 7 | .globl _start | |
| 8 | _start: | |
| 9 | b big | |
| 10 | ||
| 11 | // CHECK: R_AARCH64_JUMP26 out of range |
deps/lld/test/ELF/aarch64-jump26-thunk.s created+20| ... | ... | @@ -0,0 +1,20 @@ |
| 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 -o %t | |
| 3 | // RUN: ld.lld %t %tabs -o %t2 2>&1 | |
| 4 | // RUN: llvm-objdump -d -triple=aarch64-pc-freebsd %t2 | FileCheck %s | |
| 5 | // REQUIRES: aarch64 | |
| 6 | ||
| 7 | .text | |
| 8 | .globl _start | |
| 9 | _start: | |
| 10 | b big | |
| 11 | ||
| 12 | // CHECK: Disassembly of section .text: | |
| 13 | // CHECK-NEXT: _start: | |
| 14 | // CHECK-NEXT: 20000: 02 00 00 14 b #8 | |
| 15 | // CHECK: __AArch64AbsLongThunk_big: | |
| 16 | // CHECK-NEXT: 20008: 50 00 00 58 ldr x16, #8 | |
| 17 | // CHECK-NEXT: 2000c: 00 02 1f d6 br x16 | |
| 18 | // CHECK: $d: | |
| 19 | // CHECK-NEXT: 20010: 00 00 00 00 .word 0x00000000 | |
| 20 | // CHECK-NEXT: 20014: 10 00 00 00 .word 0x00000010 |
deps/lld/test/ELF/aarch64-ldprel-lo19-invalid.s created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | # REQUIRES: aarch64 | |
| 2 | ||
| 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 | |
| 5 | ||
| 6 | # CHECK: relocation R_AARCH64_LD_PREL_LO19 out of range: 2065536 is not in [-1048576, 1048575] | |
| 7 | ||
| 8 | ldr x8, patatino | |
| 9 | .data | |
| 10 | .zero 2000000 | |
| 11 | patatino: |
deps/lld/test/ELF/aarch64-lo12-alignment.s created+45| ... | ... | @@ -0,0 +1,45 @@ |
| 1 | // REQUIRES: aarch64 | |
| 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 | |
| 4 | ||
| 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. | |
| 7 | .section .text | |
| 8 | .globl _start | |
| 9 | .type _start, %function | |
| 10 | // Access foo2 as if it were an aligned 32-bit int, expect an error as | |
| 11 | // foo is not aligned | |
| 12 | ||
| 13 | _start: | |
| 14 | ldrb w2, [x0, #:lo12:foo1] // Ok as no shift involved | |
| 15 | ldrh w2, [x0, #:lo12:foo1] // Error foo1 is not 2-byte aligned | |
| 16 | ldrh w2, [x0, #:lo12:foo2] // Ok as foo2 is 2-byte aligned | |
| 17 | ldr w2, [x0, #:lo12:foo2] // Error foo2 is not 4-byte aligned | |
| 18 | ldr w2, [x0, #:lo12:foo4] // Ok as foo4 is 4-byte aligned | |
| 19 | ldr x3, [x0, #:lo12:foo4] // Error foo4 is not 8-byte aligned | |
| 20 | ldr x3, [x0, #:lo12:foo8] // Ok as foo8 is 8-byte aligned | |
| 21 | ldr q0, [x0, #:lo12:foo8] // Error foo8 is not 16-byte aligned | |
| 22 | ldr q0, [x0, #:lo12:foo16] // Ok as foo16 is 16-byte aligned | |
| 23 | ||
| 24 | .section .data.bool, "a", @nobits | |
| 25 | .balign 16 | |
| 26 | .globl foo16 | |
| 27 | .globl foo1 | |
| 28 | .globl foo2 | |
| 29 | .globl foo4 | |
| 30 | .globl foo8 | |
| 31 | foo16: | |
| 32 | .space 1 | |
| 33 | foo1: | |
| 34 | .space 1 | |
| 35 | foo2: | |
| 36 | .space 2 | |
| 37 | foo4: | |
| 38 | .space 4 | |
| 39 | foo8: | |
| 40 | .space 8 | |
| 41 | ||
| 42 | // CHECK: improper alignment for relocation R_AARCH64_LDST16_ABS_LO12_NC: 0x30001 is not aligned to 2 bytes | |
| 43 | // CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST32_ABS_LO12_NC: 0x30002 is not aligned to 4 bytes | |
| 44 | // CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST64_ABS_LO12_NC: 0x30004 is not aligned to 8 bytes | |
| 45 | // CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST128_ABS_LO12_NC: 0x30008 is not aligned to 16 bytes |
deps/lld/test/ELF/aarch64-load-alignment.s created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | # REQUIRES: aarch64 | |
| 2 | ||
| 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 | |
| 5 | ||
| 6 | # CHECK: improper alignment for relocation R_AARCH64_LD_PREL_LO19: 0x10005 is not aligned to 4 bytes | |
| 7 | ||
| 8 | ldr x8, patatino | |
| 9 | .data | |
| 10 | .zero 5 | |
| 11 | patatino: |
deps/lld/test/ELF/aarch64-prel16.s+1-1| ... | ... | @@ -28,4 +28,4 @@ _start: |
| 28 | 28 | // | FileCheck %s --check-prefix=OVERFLOW |
| 29 | 29 | // RUN: not ld.lld %t.o %t257.o -o %t2 |
| 30 | 30 | // | FileCheck %s --check-prefix=OVERFLOW |
| 31 | // OVERFLOW: Relocation R_AARCH64_PREL16 out of range | |
| 31 | // OVERFLOW: Relocation R_AARCH64_PREL16 out of range: -94209 is not in [-32768, 65535] |
deps/lld/test/ELF/aarch64-prel32.s+1-1| ... | ... | @@ -28,4 +28,4 @@ _start: |
| 28 | 28 | // | FileCheck %s --check-prefix=OVERFLOW |
| 29 | 29 | // RUN: not ld.lld %t.o %t257.o -o %t2 |
| 30 | 30 | // | FileCheck %s --check-prefix=OVERFLOW |
| 31 | // OVERFLOW: Relocation R_AARCH64_PREL32 out of range | |
| 31 | // OVERFLOW: Relocation R_AARCH64_PREL32 out of range: 18446744071562006527 is not in [-2147483648, 4294967295] |
deps/lld/test/ELF/aarch64-thunk-pi.s created+91| ... | ... | @@ -0,0 +1,91 @@ |
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t | |
| 2 | // RUN: echo "SECTIONS { \ | |
| 3 | // RUN: .text_low : { *(.text_low) } \ | |
| 4 | // RUN: .text_high 0x10000000 : { *(.text_high) } \ | |
| 5 | // RUN: } " > %t.script | |
| 6 | // 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 | // REQUIRES: aarch64 | |
| 9 | ||
| 10 | // Check that Position Independent thunks are generated for shared libraries. | |
| 11 | .section .text_low, "ax", %progbits | |
| 12 | .globl low_target | |
| 13 | .type low_target, %function | |
| 14 | low_target: | |
| 15 | // Need thunk to high_target@plt | |
| 16 | bl high_target | |
| 17 | ret | |
| 18 | // CHECK: low_target: | |
| 19 | // CHECK-NEXT: 0: 04 00 00 94 bl #16 | |
| 20 | // CHECK-NEXT: 4: c0 03 5f d6 ret | |
| 21 | ||
| 22 | .hidden low_target2 | |
| 23 | .globl low_target2 | |
| 24 | .type low_target2, %function | |
| 25 | low_target2: | |
| 26 | // Need thunk to high_target | |
| 27 | bl high_target2 | |
| 28 | ret | |
| 29 | // CHECK: low_target2: | |
| 30 | // CHECK-NEXT: 8: 05 00 00 94 bl #20 | |
| 31 | // CHECK-NEXT: c: c0 03 5f d6 ret | |
| 32 | ||
| 33 | // Expect range extension thunks for .text_low | |
| 34 | // adrp calculation is (PC + signed immediate) & (!0xfff) | |
| 35 | // CHECK: __AArch64ADRPThunk_high_target: | |
| 36 | // CHECK-NEXT: 10: 10 00 08 90 adrp x16, #268435456 | |
| 37 | // CHECK-NEXT: 14: 10 82 04 91 add x16, x16, #288 | |
| 38 | // CHECK-NEXT: 18: 00 02 1f d6 br x16 | |
| 39 | // CHECK: __AArch64ADRPThunk_high_target2: | |
| 40 | // CHECK-NEXT: 1c: 10 00 08 90 adrp x16, #268435456 | |
| 41 | // CHECK-NEXT: 20: 10 22 00 91 add x16, x16, #8 | |
| 42 | // CHECK-NEXT: 24: 00 02 1f d6 br x16 | |
| 43 | ||
| 44 | ||
| 45 | .section .text_high, "ax", %progbits | |
| 46 | .globl high_target | |
| 47 | .type high_target, %function | |
| 48 | high_target: | |
| 49 | // No thunk needed as we can reach low_target@plt | |
| 50 | bl low_target | |
| 51 | ret | |
| 52 | // CHECK: high_target: | |
| 53 | // CHECK-NEXT: 10000000: 4c 00 00 94 bl #304 | |
| 54 | // CHECK-NEXT: 10000004: c0 03 5f d6 ret | |
| 55 | ||
| 56 | .hidden high_target2 | |
| 57 | .globl high_target2 | |
| 58 | .type high_target2, %function | |
| 59 | high_target2: | |
| 60 | // Need thunk to low_target | |
| 61 | bl low_target2 | |
| 62 | ret | |
| 63 | // CHECK: high_target2: | |
| 64 | // CHECK-NEXT: 10000008: 02 00 00 94 bl #8 | |
| 65 | // CHECK-NEXT: 1000000c: c0 03 5f d6 ret | |
| 66 | ||
| 67 | // Expect Thunk for .text.high | |
| 68 | ||
| 69 | // CHECK: __AArch64ADRPThunk_low_target2: | |
| 70 | // CHECK-NEXT: 10000010:	10 00 f8 90 	adrp	x16, #-268435456 | |
| 71 | // CHECK-NEXT: 10000014:	10 22 00 91 	add	x16, x16, #8 | |
| 72 | // CHECK-NEXT: 10000018:	00 02 1f d6 	br	x16 | |
| 73 | ||
| 74 | // CHECK: Disassembly of section .plt: | |
| 75 | // CHECK-NEXT: .plt: | |
| 76 | // CHECK-NEXT: 10000100: f0 7b bf a9 stp x16, x30, [sp, #-16]! | |
| 77 | // CHECK-NEXT: 10000104: 10 00 00 90 adrp x16, #0 | |
| 78 | // CHECK-NEXT: 10000108: 11 aa 40 f9 ldr x17, [x16, #336] | |
| 79 | // CHECK-NEXT: 1000010c: 10 42 05 91 add x16, x16, #336 | |
| 80 | // CHECK-NEXT: 10000110: 20 02 1f d6 br x17 | |
| 81 | // CHECK-NEXT: 10000114: 1f 20 03 d5 nop | |
| 82 | // CHECK-NEXT: 10000118: 1f 20 03 d5 nop | |
| 83 | // CHECK-NEXT: 1000011c: 1f 20 03 d5 nop | |
| 84 | // CHECK-NEXT: 10000120: 10 00 00 90 adrp x16, #0 | |
| 85 | // CHECK-NEXT: 10000124: 11 ae 40 f9 ldr x17, [x16, #344] | |
| 86 | // CHECK-NEXT: 10000128: 10 62 05 91 add x16, x16, #344 | |
| 87 | // CHECK-NEXT: 1000012c: 20 02 1f d6 br x17 | |
| 88 | // CHECK-NEXT: 10000130: 10 00 00 90 adrp x16, #0 | |
| 89 | // CHECK-NEXT: 10000134: 11 b2 40 f9 ldr x17, [x16, #352] | |
| 90 | // CHECK-NEXT: 10000138: 10 82 05 91 add x16, x16, #352 | |
| 91 | // CHECK-NEXT: 1000013c: 20 02 1f d6 br x17 |
deps/lld/test/ELF/aarch64-thunk-script.s created+41| ... | ... | @@ -0,0 +1,41 @@ |
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t | |
| 2 | // RUN: echo "SECTIONS { \ | |
| 3 | // RUN: .text_low 0x2000: { *(.text_low) } \ | |
| 4 | // RUN: .text_high 0x8002000 : { *(.text_high) } \ | |
| 5 | // RUN: } " > %t.script | |
| 6 | // RUN: ld.lld --script %t.script %t -o %t2 2>&1 | |
| 7 | // RUN: llvm-objdump -d -triple=aarch64-linux-gnu %t2 | FileCheck %s | |
| 8 | // REQUIRES: aarch64 | |
| 9 | ||
| 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. | |
| 12 | .section .text_low, "ax", %progbits | |
| 13 | .globl _start | |
| 14 | .type _start, %function | |
| 15 | _start: | |
| 16 | // Need thunk to high_target@plt | |
| 17 | bl high_target | |
| 18 | ret | |
| 19 | ||
| 20 | .section .text_high, "ax", %progbits | |
| 21 | .globl high_target | |
| 22 | .type high_target, %function | |
| 23 | high_target: | |
| 24 | // No Thunk needed as we are within signed immediate range | |
| 25 | bl _start | |
| 26 | ret | |
| 27 | ||
| 28 | // CHECK: Disassembly of section .text_low: | |
| 29 | // CHECK-NEXT: _start: | |
| 30 | // CHECK-NEXT: 2000: 02 00 00 94 bl #8 | |
| 31 | // CHECK-NEXT: 2004: c0 03 5f d6 ret | |
| 32 | // CHECK: __AArch64AbsLongThunk_high_target: | |
| 33 | // CHECK-NEXT: 2008: 50 00 00 58 ldr x16, #8 | |
| 34 | // CHECK-NEXT: 200c: 00 02 1f d6 br x16 | |
| 35 | // CHECK: $d: | |
| 36 | // CHECK-NEXT: 2010: 00 20 00 08 .word 0x08002000 | |
| 37 | // CHECK-NEXT: 2014: 00 00 00 00 .word 0x00000000 | |
| 38 | // CHECK: Disassembly of section .text_high: | |
| 39 | // CHECK-NEXT: high_target: | |
| 40 | // CHECK-NEXT: 8002000: 00 00 00 96 bl #-134217728 | |
| 41 | // CHECK-NEXT: 8002004: c0 03 5f d6 ret |
deps/lld/test/ELF/aarch64-thunk-section-location.s created+41| ... | ... | @@ -0,0 +1,41 @@ |
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t | |
| 2 | // 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 | // REQUIRES: aarch64 | |
| 5 | // Check that the range extension thunks are dumped close to the aarch64 branch | |
| 6 | // range of 128 MiB | |
| 7 | .section .text.1, "ax", %progbits | |
| 8 | .balign 0x1000 | |
| 9 | .globl _start | |
| 10 | _start: | |
| 11 | bl high_target | |
| 12 | ret | |
| 13 | ||
| 14 | .section .text.2, "ax", %progbits | |
| 15 | .space 0x2000000 | |
| 16 | ||
| 17 | .section .text.2, "ax", %progbits | |
| 18 | .space 0x2000000 | |
| 19 | ||
| 20 | .section .text.3, "ax", %progbits | |
| 21 | .space 0x2000000 | |
| 22 | ||
| 23 | .section .text.4, "ax", %progbits | |
| 24 | .space 0x2000000 - 0x40000 | |
| 25 | ||
| 26 | .section .text.5, "ax", %progbits | |
| 27 | .space 0x40000 | |
| 28 | ||
| 29 | .section .text.6, "ax", %progbits | |
| 30 | .balign 0x1000 | |
| 31 | ||
| 32 | .globl high_target | |
| 33 | .type high_target, %function | |
| 34 | high_target: | |
| 35 | ret | |
| 36 | ||
| 37 | // CHECK: __AArch64AbsLongThunk_high_target: | |
| 38 | // CHECK-NEXT: 7fe0008: 50 00 00 58 ldr x16, #8 | |
| 39 | // CHECK-NEXT: 7fe000c: 00 02 1f d6 br x16 | |
| 40 | // CHECK: $d: | |
| 41 | // CHECK-NEXT: 7fe0010: 00 10 02 08 .word 0x08021000 |
deps/lld/test/ELF/aarch64-tls-gdie.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux |
| 3 | 3 | // RUN: llvm-mc %p/Inputs/aarch64-tls-gdie.s -o %t2.o -filetype=obj -triple=aarch64-pc-linux |
| 4 | 4 | // RUN: ld.lld %t2.o -o %t2.so -shared |
| 5 | // RUN: ld.lld %t.o %t2.so -o %t | |
| 5 | // RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t | |
| 6 | 6 | // RUN: llvm-readobj -s %t | FileCheck --check-prefix=SEC %s |
| 7 | 7 | // RUN: llvm-objdump -d %t | FileCheck %s |
| 8 | 8 |
deps/lld/test/ELF/aarch64-tls-ie.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/aarch64-tls-ie.s -o %tdso.o |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %tmain.o |
| 4 | 4 | # RUN: ld.lld -shared %tdso.o -o %tdso.so |
| 5 | # RUN: ld.lld %tmain.o %tdso.so -o %tout | |
| 5 | # RUN: ld.lld --hash-style=sysv %tmain.o %tdso.so -o %tout | |
| 6 | 6 | # RUN: llvm-objdump -d %tout | FileCheck %s |
| 7 | 7 | # RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s |
| 8 | 8 | # REQUIRES: aarch64 |
deps/lld/test/ELF/aarch64-tls-static.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: aarch64 |
| 2 | 2 | // RUN: llvm-mc %s -o %t.o -triple aarch64-pc-linux -filetype=obj |
| 3 | // RUN: ld.lld %t.o -o %t.so -shared | |
| 3 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | |
| 4 | 4 | // RUN: llvm-readobj -s %t.so | FileCheck --check-prefix=SEC %s |
| 5 | 5 | // RUN: llvm-objdump -d %t.so | FileCheck %s |
| 6 | 6 |
deps/lld/test/ELF/aarch64-tlsdesc.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: aarch64 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-linux %s -o %t.o |
| 3 | // RUN: ld.lld -shared %t.o -o %t.so | |
| 3 | // RUN: ld.lld --hash-style=sysv -shared %t.o -o %t.so | |
| 4 | 4 | // RUN: llvm-objdump -d %t.so | FileCheck %s |
| 5 | 5 | // RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=REL %s |
| 6 | 6 |
deps/lld/test/ELF/aarch64-undefined-weak.s+5-1| ... | ... | @@ -30,9 +30,11 @@ _start: |
| 30 | 30 | .xword target - . |
| 31 | 31 | // R_AARCH64_PREL16 |
| 32 | 32 | .hword target - . |
| 33 | // R_AARCH64_LD_PREL_LO19 | |
| 34 | ldr x8, target | |
| 33 | 35 | |
| 34 | 36 | // CHECK: Disassembly of section .text: |
| 35 | // 131076 = 0x20004 | |
| 37 | // 131072 = 0x20000 | |
| 36 | 38 | // CHECK: 20000: {{.*}} b #4 |
| 37 | 39 | // CHECK-NEXT: 20004: {{.*}} bl #4 |
| 38 | 40 | // CHECK-NEXT: 20008: {{.*}} b.eq #4 |
| ... | ... | @@ -43,3 +45,5 @@ _start: |
| 43 | 45 | // CHECK-NEXT: 2001c: {{.*}} .word 0x00000000 |
| 44 | 46 | // CHECK-NEXT: 20020: {{.*}} .word 0x00000000 |
| 45 | 47 | // CHECK-NEXT: 20024: {{.*}} .short 0x0000 |
| 48 | // CHECK: $x.2: | |
| 49 | // CHECK-NEXT: 20026: {{.*}} ldr x8, #0 |
deps/lld/test/ELF/abs-hidden.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/abs-hidden.s -o %t2.o |
| 4 | // RUN: ld.lld %t.o %t2.o -o %t.so -shared | |
| 4 | // RUN: ld.lld --hash-style=sysv %t.o %t2.o -o %t.so -shared | |
| 5 | 5 | // RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s |
| 6 | 6 | |
| 7 | 7 | .quad foo |
deps/lld/test/ELF/allow-multiple-definition.s+5| ... | ... | @@ -8,6 +8,11 @@ |
| 8 | 8 | # RUN: llvm-objdump -d %t3 | FileCheck %s |
| 9 | 9 | # RUN: llvm-objdump -d %t4 | FileCheck -check-prefix=REVERT %s |
| 10 | 10 | |
| 11 | # RUN: ld.lld -z muldefs %t1 %t2 -o %t3 | |
| 12 | # RUN: ld.lld -z muldefs %t2 %t1 -o %t4 | |
| 13 | # RUN: llvm-objdump -d %t3 | FileCheck %s | |
| 14 | # RUN: llvm-objdump -d %t4 | FileCheck -check-prefix=REVERT %s | |
| 15 | ||
| 11 | 16 | # inputs contain different constants for instuction movl. |
| 12 | 17 | # Tests below checks that order of files in command line |
| 13 | 18 | # affects on what symbol will be used. |
deps/lld/test/ELF/amdgpu-elf-flags-err.s created+7| ... | ... | @@ -0,0 +1,7 @@ |
| 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 | |
| 6 | ||
| 7 | # CHECK: error: incompatible e_flags: {{.*}}amdgpu-kernel-2.o |
deps/lld/test/ELF/amdgpu-elf-flags.s created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 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: ld.lld -shared %t-0.o %t-1.o -o %t.so | |
| 4 | # RUN: llvm-readobj -file-headers %t.so | FileCheck %s | |
| 5 | ||
| 6 | # REQUIRES: amdgpu | |
| 7 | ||
| 8 | # CHECK: Flags [ (0x2) | |
| 9 | # CHECK: EF_AMDGPU_ARCH_GCN (0x2) | |
| 10 | # CHECK: ] |
deps/lld/test/ELF/amdgpu-relocs.s+14-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | # RUN: llvm-mc -filetype=obj -triple=amdgcn--amdhsa -mcpu=fiji %s -o %t.o |
| 2 | # RUN: ld.lld -shared %t.o -o %t.so | |
| 2 | # RUN: ld.lld --hash-style=sysv -shared %t.o -o %t.so | |
| 3 | 3 | # RUN: llvm-readobj -r %t.so | FileCheck %s |
| 4 | 4 | # RUN: llvm-objdump -s %t.so | FileCheck %s --check-prefix=OBJDUMP |
| 5 | 5 | |
| ... | ... | @@ -65,10 +65,23 @@ ptr: |
| 65 | 65 | .quad temp |
| 66 | 66 | .size ptr, 8 |
| 67 | 67 | |
| 68 | # R_AMDGPU_RELATIVE64: | |
| 69 | .type temp2, @object | |
| 70 | .local temp2 | |
| 71 | .size temp2, 4 | |
| 72 | ||
| 73 | .type ptr2, @object | |
| 74 | .globl ptr2 | |
| 75 | .size ptr2, 8 | |
| 76 | .p2align 3 | |
| 77 | ptr2: | |
| 78 | .quad temp2 | |
| 79 | ||
| 68 | 80 | # The relocation for local_var{0, 1, 2} and var should be resolved by the |
| 69 | 81 | # linker. |
| 70 | 82 | # CHECK: Relocations [ |
| 71 | 83 | # CHECK: .rela.dyn { |
| 84 | # CHECK-NEXT: R_AMDGPU_RELATIVE64 - 0x0 | |
| 72 | 85 | # CHECK-NEXT: R_AMDGPU_ABS64 common_var0 0x0 |
| 73 | 86 | # CHECK-NEXT: R_AMDGPU_ABS64 common_var1 0x0 |
| 74 | 87 | # CHECK-NEXT: R_AMDGPU_ABS64 common_var2 0x0 |
deps/lld/test/ELF/arm-bl-v6.s created+51| ... | ... | @@ -0,0 +1,51 @@ |
| 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 | |
| 4 | ||
| 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 | |
| 7 | // BL that is out of range on ARM v6 and requires a range extension thunk. | |
| 8 | // As v6 does not support MOVT or MOVW instructions the Thunk must not | |
| 9 | // use these instructions either. At present we don't support v6 so we give a | |
| 10 | // warning for unsupported features. | |
| 11 | ||
| 12 | // CHECK: warning: lld uses extended branch encoding, no object with architecture supporting feature detected. | |
| 13 | // CHECK-NEXT: warning: lld may use movt/movw, no object with architecture supporting feature detected. | |
| 14 | // ARM v6 supports blx so we shouldn't see the blx not supported warning. | |
| 15 | // CHECK-NOT: warning: lld uses blx instruction, no object with architecture supporting feature detected. | |
| 16 | .text | |
| 17 | .syntax unified | |
| 18 | .cpu arm1176jzf-s | |
| 19 | .eabi_attribute 6, 6 @ Tag_CPU_arch | |
| 20 | .globl _start | |
| 21 | .type _start,%function | |
| 22 | .balign 0x1000 | |
| 23 | _start: | |
| 24 | bl thumbfunc | |
| 25 | bx lr | |
| 26 | ||
| 27 | .thumb | |
| 28 | .section .text.2, "ax", %progbits | |
| 29 | .globl thumbfunc | |
| 30 | .type thumbfunc,%function | |
| 31 | thumbfunc: | |
| 32 | bl farthumbfunc | |
| 33 | ||
| 34 | // 6 Megabytes, enough to make farthumbfunc out of range of caller on a v6 | |
| 35 | // Arm, but not on a v7 Arm. | |
| 36 | .section .text.3, "ax", %progbits | |
| 37 | .space 0x200000 | |
| 38 | ||
| 39 | .section .text.4, "ax", %progbits | |
| 40 | .space 0x200000 | |
| 41 | ||
| 42 | .section .text.5, "ax", %progbits | |
| 43 | .space 0x200000 | |
| 44 | ||
| 45 | .thumb | |
| 46 | .section .text.6, "ax", %progbits | |
| 47 | .balign 0x1000 | |
| 48 | .globl farthumbfunc | |
| 49 | .type farthumbfunc,%function | |
| 50 | farthumbfunc: | |
| 51 | bx lr |
deps/lld/test/ELF/arm-blx-v4t.s created+30| ... | ... | @@ -0,0 +1,30 @@ |
| 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 | |
| 4 | ||
| 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 | |
| 7 | // features. | |
| 8 | ||
| 9 | // CHECK: warning: lld uses blx instruction, no object with architecture supporting feature detected. | |
| 10 | // CHECK-NEXT: warning: lld uses extended branch encoding, no object with architecture supporting feature detected. | |
| 11 | // CHECK-NEXT: warning: lld may use movt/movw, no object with architecture supporting feature detected. | |
| 12 | ||
| 13 | .text | |
| 14 | .syntax unified | |
| 15 | .cpu arm7tdmi | |
| 16 | .eabi_attribute 6, 2 @ Tag_CPU_arch | |
| 17 | .arm | |
| 18 | .globl _start | |
| 19 | .type _start,%function | |
| 20 | .p2align 2 | |
| 21 | _start: | |
| 22 | bl thumbfunc | |
| 23 | bx lr | |
| 24 | ||
| 25 | .thumb | |
| 26 | .section .text.2, "ax", %progbits | |
| 27 | .globl thumbfunc | |
| 28 | .type thumbfunc,%function | |
| 29 | thumbfunc: | |
| 30 | bx lr |
deps/lld/test/ELF/arm-branch-error.s deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 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/Inputs/far-arm-abs.s -o %tfar | |
| 3 | // RUN: not ld.lld %t %tfar -o %t2 2>&1 | FileCheck %s | |
| 4 | // REQUIRES: arm | |
| 5 | .syntax unified | |
| 6 | .section .text, "ax",%progbits | |
| 7 | .globl _start | |
| 8 | .balign 0x10000 | |
| 9 | .type _start,%function | |
| 10 | _start: | |
| 11 | // address of too_far symbols are just out of range of ARM branch with | |
| 12 | // 26-bit immediate field and an addend of -8 | |
| 13 | bl too_far1 | |
| 14 | b too_far2 | |
| 15 | beq too_far3 | |
| 16 | ||
| 17 | // CHECK: R_ARM_CALL out of range | |
| 18 | // CHECK-NEXT: R_ARM_JUMP24 out of range | |
| 19 | // CHECK-NEXT: R_ARM_JUMP24 out of range |
deps/lld/test/ELF/arm-branch-rangethunk.s created+34| ... | ... | @@ -0,0 +1,34 @@ |
| 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/Inputs/far-arm-abs.s -o %tfar | |
| 3 | // RUN: ld.lld %t %tfar -o %t2 2>&1 | |
| 4 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s | |
| 5 | // REQUIRES: arm | |
| 6 | .syntax unified | |
| 7 | .section .text, "ax",%progbits | |
| 8 | .globl _start | |
| 9 | .balign 0x10000 | |
| 10 | .type _start,%function | |
| 11 | _start: | |
| 12 | // address of too_far symbols are just out of range of ARM branch with | |
| 13 | // 26-bit immediate field and an addend of -8 | |
| 14 | bl too_far1 | |
| 15 | b too_far2 | |
| 16 | beq too_far3 | |
| 17 | ||
| 18 | // CHECK: Disassembly of section .text: | |
| 19 | // CHECK-NEXT: _start: | |
| 20 | // CHECK-NEXT: 20000: 01 00 00 eb bl #4 <__ARMv7ABSLongThunk_too_far1> | |
| 21 | // CHECK-NEXT: 20004: 03 00 00 ea b #12 <__ARMv7ABSLongThunk_too_far2> | |
| 22 | // CHECK-NEXT: 20008: 05 00 00 0a beq #20 <__ARMv7ABSLongThunk_too_far3> | |
| 23 | // CHECK: __ARMv7ABSLongThunk_too_far1: | |
| 24 | // CHECK-NEXT: 2000c: 08 c0 00 e3 movw r12, #8 | |
| 25 | // CHECK-NEXT: 20010: 02 c2 40 e3 movt r12, #514 | |
| 26 | // CHECK-NEXT: 20014: 1c ff 2f e1 bx r12 | |
| 27 | // CHECK: __ARMv7ABSLongThunk_too_far2: | |
| 28 | // CHECK-NEXT: 20018: 0c c0 00 e3 movw r12, #12 | |
| 29 | // CHECK-NEXT: 2001c: 02 c2 40 e3 movt r12, #514 | |
| 30 | // CHECK-NEXT: 20020: 1c ff 2f e1 bx r12 | |
| 31 | // CHECK: __ARMv7ABSLongThunk_too_far3: | |
| 32 | // CHECK-NEXT: 20024: 10 c0 00 e3 movw r12, #16 | |
| 33 | // CHECK-NEXT: 20028: 02 c2 40 e3 movt r12, #514 | |
| 34 | // CHECK-NEXT: 2002c: 1c ff 2f e1 bx r12 |
deps/lld/test/ELF/arm-branch-undef-weak-plt-thunk.s created+35| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | // 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: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2 | |
| 4 | // 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 | // REQUIRES: arm | |
| 7 | ||
| 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. | |
| 10 | ||
| 11 | .text | |
| 12 | .globl bar2 | |
| 13 | .weak undefined_weak_we_expect_a_plt_entry_for | |
| 14 | _start: | |
| 15 | .globl _start | |
| 16 | .type _start, %function | |
| 17 | b undefined_weak_we_expect_a_plt_entry_for | |
| 18 | bl bar2 | |
| 19 | // Create 32 Mb gap between the call to the weak reference and the PLT so that | |
| 20 | // the b and bl need a range-extension thunk. | |
| 21 | .section .text.1, "ax", %progbits | |
| 22 | .space 32 * 1024 * 1024 | |
| 23 | ||
| 24 | // CHECK: Disassembly of section .text: | |
| 25 | // CHECK-NEXT: _start: | |
| 26 | // CHECK-NEXT: 11000: 00 00 00 ea b #0 <__ARMv7ABSLongThunk_undefined_weak_we_expect_a_plt_entry_for> | |
| 27 | // CHECK-NEXT: 11004: 02 00 00 eb bl #8 <__ARMv7ABSLongThunk_bar2> | |
| 28 | // CHECK: __ARMv7ABSLongThunk_undefined_weak_we_expect_a_plt_entry_for: | |
| 29 | // CHECK-NEXT: 11008: 40 c0 01 e3 movw r12, #4160 | |
| 30 | // CHECK-NEXT: 1100c: 01 c2 40 e3 movt r12, #513 | |
| 31 | // CHECK-NEXT: 11010: 1c ff 2f e1 bx r12 | |
| 32 | // CHECK: __ARMv7ABSLongThunk_bar2: | |
| 33 | // CHECK-NEXT: 11014: 50 c0 01 e3 movw r12, #4176 | |
| 34 | // CHECK-NEXT: 11018: 01 c2 40 e3 movt r12, #513 | |
| 35 | // CHECK-NEXT: 1101c: 1c ff 2f e1 bx r12 |
deps/lld/test/ELF/arm-copy.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o |
| 3 | 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/relocation-copy-arm.s -o %t2.o |
| 4 | 4 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| 5 | // RUN: ld.lld %t.o %t2.so -o %t3 | |
| 5 | // RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t3 | |
| 6 | 6 | // RUN: llvm-readobj -s -r --expand-relocs -symbols %t3 | FileCheck %s |
| 7 | 7 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CODE %s |
| 8 | 8 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi -section=.rodata %t3 | FileCheck -check-prefix=RODATA %s |
deps/lld/test/ELF/arm-exidx-dedup-and-sentinel.s created+29| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | // REQUIRES: arm | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | |
| 3 | // RUN: ld.lld %t.o -shared -o %t.so --section-start .text=0x2000 --section-start .ARM.exidx=0x1000 | |
| 4 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t.so | FileCheck %s | |
| 5 | ||
| 6 | .syntax unified | |
| 7 | ||
| 8 | .section .text.foo, "ax", %progbits | |
| 9 | .globl foo | |
| 10 | foo: | |
| 11 | .fnstart | |
| 12 | bx lr | |
| 13 | .cantunwind | |
| 14 | .fnend | |
| 15 | ||
| 16 | .section .text.bar, "ax", %progbits | |
| 17 | .globl bar | |
| 18 | bar: | |
| 19 | .fnstart | |
| 20 | bx lr | |
| 21 | .cantunwind | |
| 22 | .fnend | |
| 23 | ||
| 24 | // CHECK: Contents of section .ARM.exidx: | |
| 25 | // 1000 + 1000 = 0x2000 = foo | |
| 26 | // The entry for bar is the same as previous and is eliminated. | |
| 27 | // The sentinel entry should be preserved. | |
| 28 | // 1008 + 1000 = 0x2008 = bar + sizeof(bar) | |
| 29 | // CHECK-NEXT: 1000 00100000 01000000 00100000 01000000 |
deps/lld/test/ELF/arm-exidx-dedup.s created+126| ... | ... | @@ -0,0 +1,126 @@ |
| 1 | // 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: llvm-objdump -s %t2 | FileCheck --check-prefix CHECK-DUPS %s | |
| 4 | // RUN: ld.lld %t -o %t3 | |
| 5 | // RUN: llvm-objdump -s %t3 | FileCheck %s | |
| 6 | // REQUIRES: arm | |
| 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 | |
| 9 | // a .ARM.exidx section. | |
| 10 | ||
| 11 | // With duplicate entries | |
| 12 | // CHECK-DUPS: Contents of section .ARM.exidx: | |
| 13 | // CHECK-DUPS-NEXT: 100d4 2c0f0000 01000000 280f0000 01000000 | |
| 14 | // CHECK-DUPS-NEXT: 100e4 240f0000 01000000 200f0000 01000000 | |
| 15 | // CHECK-DUPS-NEXT: 100f4 1c0f0000 08849780 180f0000 08849780 | |
| 16 | // CHECK-DUPS-NEXT: 10104 140f0000 08849780 100f0000 14000000 | |
| 17 | // CHECK-DUPS-NEXT: 10114 0c0f0000 18000000 080f0000 01000000 | |
| 18 | // CHECK-DUPS-NEXT: Contents of section .ARM.extab: | |
| 19 | ||
| 20 | // After duplicate entry removal | |
| 21 | // CHECK: Contents of section .ARM.exidx: | |
| 22 | // CHECK-NEXT: 100d4 2c0f0000 01000000 340f0000 08849780 | |
| 23 | // CHECK-NEXT: 100e4 380f0000 14000000 340f0000 18000000 | |
| 24 | // CHECK-NEXT: 100f4 300f0000 01000000 | |
| 25 | // CHECK-NEXT: Contents of section .ARM.extab: | |
| 26 | .syntax unified | |
| 27 | ||
| 28 | // Expect 1 EXIDX_CANTUNWIND entry. | |
| 29 | .section .text.00, "ax", %progbits | |
| 30 | .globl _start | |
| 31 | _start: | |
| 32 | .fnstart | |
| 33 | bx lr | |
| 34 | .cantunwind | |
| 35 | .fnend | |
| 36 | ||
| 37 | // Expect .ARM.exidx.text.01 to be identical to .ARM.exidx.text.00 | |
| 38 | .section .text.01, "ax", %progbits | |
| 39 | .globl f1 | |
| 40 | f1: | |
| 41 | .fnstart | |
| 42 | bx lr | |
| 43 | .cantunwind | |
| 44 | .fnend | |
| 45 | ||
| 46 | // Expect 2 EXIDX_CANTUNWIND entries, these can be duplicated into | |
| 47 | // .ARM.exid.text.00 | |
| 48 | .section .text.02, "ax", %progbits | |
| 49 | .globl f2 | |
| 50 | f2: | |
| 51 | .fnstart | |
| 52 | bx lr | |
| 53 | .cantunwind | |
| 54 | .fnend | |
| 55 | ||
| 56 | .globl f3 | |
| 57 | f3: | |
| 58 | .fnstart | |
| 59 | bx lr | |
| 60 | .cantunwind | |
| 61 | .fnend | |
| 62 | ||
| 63 | // Expect inline unwind instructions, not a duplicate of previous entry. | |
| 64 | .section .text.03, "ax", %progbits | |
| 65 | .global f4 | |
| 66 | f4: | |
| 67 | .fnstart | |
| 68 | bx lr | |
| 69 | .save {r7, lr} | |
| 70 | .setfp r7, sp, #0 | |
| 71 | .fnend | |
| 72 | ||
| 73 | // Expect 2 inline unwind entries that are a duplicate of | |
| 74 | // .ARM.exidx.text.03 | |
| 75 | .section .text.04, "ax", %progbits | |
| 76 | .global f5 | |
| 77 | f5: | |
| 78 | .fnstart | |
| 79 | bx lr | |
| 80 | .save {r7, lr} | |
| 81 | .setfp r7, sp, #0 | |
| 82 | .fnend | |
| 83 | ||
| 84 | .global f6 | |
| 85 | f6: | |
| 86 | .fnstart | |
| 87 | bx lr | |
| 88 | .save {r7, lr} | |
| 89 | .setfp r7, sp, #0 | |
| 90 | .fnend | |
| 91 | ||
| 92 | // Expect a section with a reference to an .ARM.extab. Not a duplicate | |
| 93 | // of previous inline table entry. | |
| 94 | .section .text.05, "ax",%progbits | |
| 95 | .global f7 | |
| 96 | f7: | |
| 97 | .fnstart | |
| 98 | bx lr | |
| 99 | .personality __gxx_personality_v0 | |
| 100 | .handlerdata | |
| 101 | .long 0 | |
| 102 | .fnend | |
| 103 | ||
| 104 | // Expect a reference to an identical .ARM.extab. We do not try to | |
| 105 | // deduplicate references to .ARM.extab sections. | |
| 106 | .section .text.06, "ax",%progbits | |
| 107 | .global f8 | |
| 108 | f8: | |
| 109 | .fnstart | |
| 110 | bx lr | |
| 111 | .personality __gxx_personality_v0 | |
| 112 | .handlerdata | |
| 113 | .long 0 | |
| 114 | .fnend | |
| 115 | ||
| 116 | // Dummy implementation of personality routines to satisfy reference from | |
| 117 | // exception tables | |
| 118 | .section .text.__gcc_personality_v0, "ax", %progbits | |
| 119 | .global __gxx_personality_v0 | |
| 120 | __gxx_personality_v0: | |
| 121 | bx lr | |
| 122 | ||
| 123 | .section .text.__aeabi_unwind_cpp_pr0, "ax", %progbits | |
| 124 | .global __aeabi_unwind_cpp_pr0 | |
| 125 | __aeabi_unwind_cpp_pr0: | |
| 126 | bx lr |
deps/lld/test/ELF/arm-exidx-gc.s+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 --gc-sections 2>&1 | |
| 2 | // RUN: ld.lld %t --no-merge-exidx-entries -o %t2 --gc-sections 2>&1 | |
| 3 | 3 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s |
| 4 | 4 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXIDX %s |
| 5 | 5 | // REQUIRES: arm |
deps/lld/test/ELF/arm-exidx-order.s+2-2| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-exidx-cantunwind.s -o %tcantunwind |
| 3 | // RUN: ld.lld %t %tcantunwind -o %t2 2>&1 | |
| 3 | // RUN: ld.lld --no-merge-exidx-entries %t %tcantunwind -o %t2 2>&1 | |
| 4 | 4 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s |
| 5 | 5 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXIDX %s |
| 6 | 6 | // RUN: llvm-readobj --program-headers --sections %t2 | FileCheck -check-prefix=CHECK-PT %s |
| ... | ... | @@ -8,7 +8,7 @@ |
| 8 | 8 | // RUN: echo "SECTIONS { \ |
| 9 | 9 | // RUN: .text 0x11000 : { *(.text*) } \ |
| 10 | 10 | // RUN: .ARM.exidx : { *(.ARM.exidx) } } " > %t.script |
| 11 | // RUN: ld.lld --script %t.script %tcantunwind %t -o %t3 2>&1 | |
| 11 | // RUN: ld.lld --no-merge-exidx-entries --script %t.script %tcantunwind %t -o %t3 2>&1 | |
| 12 | 12 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-SCRIPT %s |
| 13 | 13 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-SCRIPT-EXIDX %s |
| 14 | 14 | // REQUIRES: arm |
deps/lld/test/ELF/arm-exidx-sentinel-orphan.s+1-1| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | // RUN: echo "SECTIONS { \ |
| 5 | 5 | // RUN: .text 0x11000 : { *(.text*) } \ |
| 6 | 6 | // RUN: } " > %t.script |
| 7 | // RUN: ld.lld --script %t.script %t -o %t2 | |
| 7 | // RUN: ld.lld --no-merge-exidx-entries --script %t.script %t -o %t2 | |
| 8 | 8 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s |
| 9 | 9 | // REQUIRES: arm |
| 10 | 10 |
deps/lld/test/ELF/arm-exidx-shared.s+3-3| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t --shared -o %t2 2>&1 | |
| 2 | // RUN: ld.lld --hash-style=sysv %t --shared -o %t2 2>&1 | |
| 3 | 3 | // RUN: llvm-readobj --relocations %t2 | FileCheck %s |
| 4 | 4 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXTAB %s |
| 5 | 5 | // REQUIRES: arm |
| ... | ... | @@ -41,5 +41,5 @@ __aeabi_unwind_cpp_pr0: |
| 41 | 41 | // CHECK-NEXT: 0x200C R_ARM_JUMP_SLOT __gxx_personality_v0 |
| 42 | 42 | |
| 43 | 43 | // CHECK-EXTAB: Contents of section .ARM.extab: |
| 44 | // 014c + 0ed8 = 0x1024 = __gxx_personality_v0(PLT) | |
| 45 | // CHECK-EXTAB-NEXT: 014c d80e0000 b0b0b000 00000000 | |
| 44 | // 014c + 0ee4 = 0x1030 = __gxx_personality_v0(PLT) | |
| 45 | // CHECK-EXTAB-NEXT: 014c e40e0000 b0b0b000 00000000 |
deps/lld/test/ELF/arm-gnu-ifunc-plt.s+28-28| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %S/Inputs/arm-shared.s -o %t1.o |
| 2 | 2 | // RUN: ld.lld %t1.o --shared -o %t.so |
| 3 | 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t.o |
| 4 | // RUN: ld.lld %t.so %t.o -o %tout | |
| 4 | // RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout | |
| 5 | 5 | // RUN: llvm-objdump -triple=armv7a-linux-gnueabihf -d %tout | FileCheck %s --check-prefix=DISASM |
| 6 | 6 | // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT |
| 7 | 7 | // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s |
| ... | ... | @@ -33,49 +33,49 @@ |
| 33 | 33 | // DISASM-NEXT: 11000: 1e ff 2f e1 bx lr |
| 34 | 34 | // DISASM: bar: |
| 35 | 35 | // DISASM-NEXT: 11004: 1e ff 2f e1 bx lr |
| 36 | // DISASM: _start: | |
| 36 | // DISASM: _start: | |
| 37 | 37 | // DISASM-NEXT: 11008: 14 00 00 eb bl #80 |
| 38 | 38 | // DISASM-NEXT: 1100c: 17 00 00 eb bl #92 |
| 39 | // DISASM: 11010: 00 00 00 00 .word 0x00000000 | |
| 39 | // DISASM: $d.1: | |
| 40 | // DISASM-NEXT: 11010: 00 00 00 00 .word 0x00000000 | |
| 40 | 41 | // DISASM-NEXT: 11014: 04 00 00 00 .word 0x00000004 |
| 41 | // DISASM: 11018: 05 00 00 eb bl #20 | |
| 42 | // DISASM-NEXT: 1101c: 08 00 00 eb bl #32 | |
| 42 | // DISASM: 11018: 08 00 00 eb bl #32 | |
| 43 | // DISASM-NEXT: 1101c: 0b 00 00 eb bl #44 | |
| 43 | 44 | // DISASM-NEXT: Disassembly of section .plt: |
| 44 | 45 | // DISASM-NEXT: $a: |
| 45 | 46 | // DISASM-NEXT: 11020: 04 e0 2d e5 str lr, [sp, #-4]! |
| 46 | // DISASM-NEXT: 11024: 04 e0 9f e5 ldr lr, [pc, #4] | |
| 47 | // DISASM-NEXT: 11028: 0e e0 8f e0 add lr, pc, lr | |
| 48 | // DISASM-NEXT: 1102c: 08 f0 be e5 ldr pc, [lr, #8]! | |
| 47 | // DISASM-NEXT: 11024: 00 e6 8f e2 add lr, pc, #0, #12 | |
| 48 | // DISASM-NEXT: 11028: 00 ea 8e e2 add lr, lr, #0, #20 | |
| 49 | // DISASM-NEXT: 1102c: dc ff be e5 ldr pc, [lr, #4060]! | |
| 49 | 50 | // DISASM: $d: |
| 50 | // DISASM-NEXT: 11030: d0 0f 00 00 .word 0x00000fd0 | |
| 51 | // DISASM-NEXT: 11030: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 52 | // DISASM-NEXT: 11034: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 53 | // DISASM-NEXT: 11038: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 54 | // DISASM-NEXT: 1103c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 51 | 55 | // DISASM: $a: |
| 52 | // DISASM-NEXT: 11034: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 53 | // DISASM-NEXT: 11038: 0f c0 8c e0 add r12, r12, pc | |
| 54 | // DISASM-NEXT: 1103c: 00 f0 9c e5 ldr pc, [r12] | |
| 56 | // DISASM-NEXT: 11040: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 57 | // DISASM-NEXT: 11044: 00 ca 8c e2 add r12, r12, #0, #20 | |
| 58 | // DISASM-NEXT: 11048: c4 ff bc e5 ldr pc, [r12, #4036]! | |
| 55 | 59 | // DISASM: $d: |
| 56 | // DISASM-NEXT: 11040: cc 0f 00 00 .word 0x00000fcc | |
| 60 | // DISASM-NEXT: 1104c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 57 | 61 | // DISASM: $a: |
| 58 | // DISASM-NEXT: 11044: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 59 | // DISASM-NEXT: 11048: 0f c0 8c e0 add r12, r12, pc | |
| 60 | // DISASM-NEXT: 1104c: 00 f0 9c e5 ldr pc, [r12] | |
| 62 | // DISASM-NEXT: 11050: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 63 | // DISASM-NEXT: 11054: 00 ca 8c e2 add r12, r12, #0, #20 | |
| 64 | // DISASM-NEXT: 11058: b8 ff bc e5 ldr pc, [r12, #4024]! | |
| 61 | 65 | // DISASM: $d: |
| 62 | // DISASM-NEXT: 11050: c0 0f 00 00 .word 0x00000fc0 | |
| 63 | // Alignment to 16 byte boundary not strictly necessary on ARM, but harmless | |
| 64 | // DISASM-NEXT: 11054: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 65 | // DISASM-NEXT: 11058: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 66 | 66 | // DISASM-NEXT: 1105c: d4 d4 d4 d4 .word 0xd4d4d4d4 |
| 67 | 67 | // DISASM: $a: |
| 68 | // DISASM-NEXT: 11060: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 69 | // DISASM-NEXT: 11064: 0f c0 8c e0 add r12, r12, pc | |
| 70 | // DISASM-NEXT: 11068: 00 f0 9c e5 ldr pc, [r12] | |
| 68 | // DISASM-NEXT: 11060: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 69 | // DISASM-NEXT: 11064: 02 ca 8c e2 add r12, r12, #8192 | |
| 70 | // DISASM-NEXT: 11068: 18 f0 bc e5 ldr pc, [r12, #24]! | |
| 71 | 71 | // DISASM: $d: |
| 72 | // DISASM-NEXT: 1106c: 14 20 00 00 .word 0x00002014 | |
| 72 | // DISASM-NEXT: 1106c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 73 | 73 | // DISASM: $a: |
| 74 | // DISASM-NEXT: 11070: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 75 | // DISASM-NEXT: 11074: 0f c0 8c e0 add r12, r12, pc | |
| 76 | // DISASM-NEXT: 11078: 00 f0 9c e5 ldr pc, [r12] | |
| 74 | // DISASM-NEXT: 11070: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 75 | // DISASM-NEXT: 11074: 02 ca 8c e2 add r12, r12, #8192 | |
| 76 | // DISASM-NEXT: 11078: 0c f0 bc e5 ldr pc, [r12, #12]! | |
| 77 | 77 | // DISASM: $d: |
| 78 | // DISASM-NEXT: 1107c: 08 20 00 00 .word 0x00002008 | |
| 78 | // DISASM-NEXT: 1107c:	d4 d4 d4 d4 	.word	0xd4d4d4d4 | |
| 79 | 79 | |
| 80 | 80 | .syntax unified |
| 81 | 81 | .text |
deps/lld/test/ELF/arm-gnu-ifunc.s+20-21| ... | ... | @@ -111,30 +111,29 @@ _start: |
| 111 | 111 | |
| 112 | 112 | // DISASM: Disassembly of section .text: |
| 113 | 113 | // DISASM-NEXT: foo: |
| 114 | // DISASM-NEXT: 11000:	1e ff 2f e1 	bx	lr | |
| 115 | // DISASM: bar: | |
| 116 | // DISASM-NEXT: 11004:	1e ff 2f e1 	bx	lr | |
| 117 | // DISASM: _start: | |
| 118 | // DISASM-NEXT: 11008:	04 00 00 eb 	bl	#16 | |
| 119 | // DISASM-NEXT: 1100c:	07 00 00 eb 	bl	#28 | |
| 114 | // DISASM-NEXT: 11000: 1e ff 2f e1 bx lr | |
| 115 | // DISASM: bar: | |
| 116 | // DISASM-NEXT: 11004: 1e ff 2f e1 bx lr | |
| 117 | // DISASM: _start: | |
| 118 | // DISASM-NEXT: 11008: 04 00 00 eb bl #16 | |
| 119 | // DISASM-NEXT: 1100c: 07 00 00 eb bl #28 | |
| 120 | 120 | // 1 * 65536 + 244 = 0x100f4 __rel_iplt_start |
| 121 | // DISASM-NEXT: 11010:	f4 00 00 e3 	movw	r0, #244 | |
| 122 | // DISASM-NEXT: 11014:	01 00 40 e3 	movt	r0, #1 | |
| 121 | // DISASM-NEXT: 11010: f4 00 00 e3 movw r0, #244 | |
| 122 | // DISASM-NEXT: 11014: 01 00 40 e3 movt r0, #1 | |
| 123 | 123 | // 1 * 65536 + 260 = 0x10104 __rel_iplt_end |
| 124 | // DISASM-NEXT: 11018:	04 01 00 e3 	movw	r0, #260 | |
| 125 | // DISASM-NEXT: 1101c:	01 00 40 e3 	movt	r0, #1 | |
| 124 | // DISASM-NEXT: 11018: 04 01 00 e3 movw r0, #260 | |
| 125 | // DISASM-NEXT: 1101c: 01 00 40 e3 movt r0, #1 | |
| 126 | 126 | // DISASM-NEXT: Disassembly of section .plt: |
| 127 | // DISASM: $a: | |
| 128 | // DISASM-NEXT: 11020: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 129 | // DISASM-NEXT: 11024: 0f c0 8c e0 add r12, r12, pc | |
| 130 | // 11024 + 8 + fd4 = 0x12000 | |
| 131 | // DISASM-NEXT: 11028: 00 f0 9c e5 ldr pc, [r12] | |
| 127 | // DISASM-NEXT: $a: | |
| 128 | // DISASM-NEXT: 11020: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 129 | // DISASM-NEXT: 11024: 00 ca 8c e2 add r12, r12, #0, #20 | |
| 130 | // DISASM-NEXT: 11028: d8 ff bc e5 ldr pc, [r12, #4056]! | |
| 132 | 131 | // DISASM: $d: |
| 133 | // DISASM-NEXT: 1102c: d4 0f 00 00 .word 0x00000fd4 | |
| 132 | // DISASM-NEXT: 1102c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 134 | 133 | // DISASM: $a: |
| 135 | // DISASM-NEXT: 11030: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 136 | // DISASM-NEXT: 11034: 0f c0 8c e0 add r12, r12, pc | |
| 137 | // 11034 + 8 + fc8 = 0x12004 | |
| 138 | // DISASM-NEXT: 11038: 00 f0 9c e5 ldr pc, [r12] | |
| 134 | // DISASM-NEXT: 11030: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 135 | // DISASM-NEXT: 11034: 00 ca 8c e2 add r12, r12, #0, #20 | |
| 136 | // DISASM-NEXT: 11038: cc ff bc e5 ldr pc, [r12, #4044]! | |
| 139 | 137 | // DISASM: $d: |
| 140 | // DISASM-NEXT: 1103c: c8 0f 00 00 .word 0x00000fc8 | |
| 138 | // DISASM-NEXT: 1103c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 139 |
deps/lld/test/ELF/arm-got-relative.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: arm |
| 2 | 2 | // RUN: llvm-mc -position-independent -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o |
| 3 | // RUN: ld.lld %t.o -shared -o %t | |
| 3 | // RUN: ld.lld --hash-style=sysv %t.o -shared -o %t | |
| 4 | 4 | // RUN: llvm-readobj -s -symbols -dyn-relocations %t | FileCheck %s |
| 5 | 5 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t | FileCheck -check-prefix=CODE %s |
| 6 | 6 | .syntax unified |
deps/lld/test/ELF/arm-icf-exidx.s+1-1| ... | ... | @@ -23,7 +23,7 @@ __aeabi_unwind_cpp_pr0: |
| 23 | 23 | bx lr |
| 24 | 24 | |
| 25 | 25 | // CHECK: Disassembly of section .text: |
| 26 | // CHECK-NEXT: f: | |
| 26 | // CHECK-NEXT: g: | |
| 27 | 27 | // CHECK-NEXT: 11000: 1e ff 2f e1 bx lr |
| 28 | 28 | // CHECK: __aeabi_unwind_cpp_pr0: |
| 29 | 29 | // CHECK-NEXT: 11004: 00 f0 20 e3 nop |
deps/lld/test/ELF/arm-pie-relative.s+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t --pie -o %t2 | |
| 2 | // RUN: ld.lld --hash-style=sysv %t --pie -o %t2 | |
| 3 | 3 | // RUN: llvm-readobj -r %t2 | FileCheck %s |
| 4 | 4 | // RUN: llvm-objdump -s %t2 | FileCheck %s --check-prefix=GOT |
| 5 | 5 | // REQUIRES: arm |
deps/lld/test/ELF/arm-plt-reloc.s+232-32| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2 |
| 3 | 3 | // RUN: ld.lld %t1 %t2 -o %t |
| 4 | 4 | // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t | FileCheck %s |
| 5 | // RUN: ld.lld -shared %t1 %t2 -o %t3 | |
| 5 | // RUN: ld.lld --hash-style=sysv -shared %t1 %t2 -o %t3 | |
| 6 | 6 | // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSO %s |
| 7 | 7 | // RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s |
| 8 | 8 | // REQUIRES: arm |
| ... | ... | @@ -32,51 +32,55 @@ _start: |
| 32 | 32 | // CHECK-NEXT: 11014: fb ff ff 0a beq #-20 <func3> |
| 33 | 33 | |
| 34 | 34 | // Expect PLT entries as symbols can be preempted |
| 35 | // The .got.plt and .plt displacement is small so we can use small PLT entries. | |
| 35 | 36 | // DSO: Disassembly of section .text: |
| 36 | 37 | // DSO-NEXT: func1: |
| 37 | // DSO-NEXT: 1000: 1e ff 2f e1 bx lr | |
| 38 | // DSO-NEXT: 1000: 1e ff 2f e1 bx lr | |
| 38 | 39 | // DSO: func2: |
| 39 | // DSO-NEXT: 1004: 1e ff 2f e1 bx lr | |
| 40 | // DSO-NEXT: 1004: 1e ff 2f e1 bx lr | |
| 40 | 41 | // DSO: func3: |
| 41 | // DSO-NEXT: 1008: 1e ff 2f e1 bx lr | |
| 42 | // DSO-NEXT: 1008: 1e ff 2f e1 bx lr | |
| 42 | 43 | // DSO: _start: |
| 43 | // S(0x1034) - P(0x100c) + A(-8) = 0x20 = 32 | |
| 44 | // DSO-NEXT: 100c: 08 00 00 ea b #32 | |
| 45 | // S(0x1044) - P(0x1010) + A(-8) = 0x2c = 44 | |
| 46 | // DSO-NEXT: 1010: 0b 00 00 eb bl #44 | |
| 47 | // S(0x1054) - P(0x1014) + A(-8) = 0x38 = 56 | |
| 48 | // DSO-NEXT: 1014: 0e 00 00 0a beq #56 | |
| 49 | ||
| 50 | // DSO: Disassembly of section .plt: | |
| 44 | // S(0x1040) - P(0x100c) + A(-8) = 0x2c = 32 | |
| 45 | // DSO-NEXT: 100c: 0b 00 00 ea b #44 | |
| 46 | // S(0x1050) - P(0x1010) + A(-8) = 0x38 = 56 | |
| 47 | // DSO-NEXT: 1010: 0e 00 00 eb bl #56 | |
| 48 | // S(0x10160) - P(0x1014) + A(-8) = 0x44 = 68 | |
| 49 | // DSO-NEXT: 1014: 11 00 00 0a beq #68 | |
| 50 | // DSO-NEXT: Disassembly of section .plt: | |
| 51 | 51 | // DSO-NEXT: $a: |
| 52 | 52 | // DSO-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]! |
| 53 | // DSO-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4] | |
| 54 | // DSO-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr | |
| 55 | // DSO-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]! | |
| 56 | // 0x1028 + 8 + 0fd0 = 0x2000 | |
| 53 | // (0x1024 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfdc) = 0x2008 = .got.plt[3] | |
| 54 | // DSO-NEXT: 1024: 00 e6 8f e2 add lr, pc, #0, #12 | |
| 55 | // DSO-NEXT: 1028: 00 ea 8e e2 add lr, lr, #0, #20 | |
| 56 | // DSO-NEXT: 102c: dc ff be e5 ldr pc, [lr, #4060]! | |
| 57 | 57 | // DSO: $d: |
| 58 | // DSO-NEXT: 1030: d0 0f 00 00 .word 0x00000fd0 | |
| 58 | // DSO-NEXT: 1030: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 59 | // DSO-NEXT: 1034: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 60 | // DSO-NEXT: 1038: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 61 | // DSO-NEXT: 103c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 59 | 62 | // DSO: $a: |
| 60 | // DSO-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 61 | // DSO-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc | |
| 62 | // DSO-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12] | |
| 63 | // 0x1038 + 8 + 0fcc = 0x200c | |
| 63 | // (0x1040 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfc4) = 0x200c | |
| 64 | // DSO-NEXT: 1040: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 65 | // DSO-NEXT: 1044: 00 ca 8c e2 add r12, r12, #0, #20 | |
| 66 | // DSO-NEXT: 1048: c4 ff bc e5 ldr pc, [r12, #4036]! | |
| 64 | 67 | // DSO: $d: |
| 65 | // DSO-NEXT: 1040: cc 0f 00 00 .word 0x00000fcc | |
| 68 | // DSO-NEXT: 104c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 66 | 69 | // DSO: $a: |
| 67 | // DSO-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 68 | // DSO-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc | |
| 69 | // DSO-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12] | |
| 70 | // 0x1048 + 8 + 0fc0 = 0x2010 | |
| 70 | // (0x1050 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfb8) = 0x2010 | |
| 71 | // DSO-NEXT: 1050: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 72 | // DSO-NEXT: 1054: 00 ca 8c e2 add r12, r12, #0, #20 | |
| 73 | // DSO-NEXT: 1058: b8 ff bc e5 ldr pc, [r12, #4024]! | |
| 71 | 74 | // DSO: $d: |
| 72 | // DSO-NEXT: 1050: c0 0f 00 00 .word 0x00000fc0 | |
| 75 | // DSO-NEXT: 105c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 73 | 76 | // DSO: $a: |
| 74 | // DSO-NEXT: 1054: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 75 | // DSO-NEXT: 1058: 0f c0 8c e0 add r12, r12, pc | |
| 76 | // DSO-NEXT: 105c: 00 f0 9c e5 ldr pc, [r12] | |
| 77 | // 0x1058 + 8 + 0fb4 = 0x2014 | |
| 77 | // (0x1060 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfac) = 0x2014 | |
| 78 | // DSO-NEXT: 1060: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 79 | // DSO-NEXT: 1064: 00 ca 8c e2 add r12, r12, #0, #20 | |
| 80 | // DSO-NEXT: 1068: ac ff bc e5 ldr pc, [r12, #4012]! | |
| 78 | 81 | // DSO: $d: |
| 79 | // DSO-NEXT: 1060: b4 0f 00 00 .word 0x00000fb4 | |
| 82 | // DSO-NEXT: 106c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 83 | ||
| 80 | 84 | |
| 81 | 85 | // DSOREL: Name: .got.plt |
| 82 | 86 | // DSOREL-NEXT: Type: SHT_PROGBITS |
| ... | ... | @@ -96,3 +100,199 @@ _start: |
| 96 | 100 | // DSOREL-NEXT: 0x200C R_ARM_JUMP_SLOT func1 0x0 |
| 97 | 101 | // DSOREL-NEXT: 0x2010 R_ARM_JUMP_SLOT func2 0x0 |
| 98 | 102 | // DSOREL-NEXT: 0x2014 R_ARM_JUMP_SLOT func3 0x0 |
| 103 | ||
| 104 | // Test a large separation between the .plt and .got.plt | |
| 105 | // The .got.plt and .plt displacement is large but still within the range | |
| 106 | // of the short plt sequence. | |
| 107 | // RUN: echo "SECTIONS { \ | |
| 108 | // RUN: .text 0x1000 : { *(.text) } \ | |
| 109 | // RUN: .plt 0x2000 : { *(.plt) *(.plt.*) } \ | |
| 110 | // RUN: .got.plt 0x1100000 : { *(.got.plt) } \ | |
| 111 | // RUN: }" > %t.script | |
| 112 | // RUN: ld.lld --hash-style=sysv --script %t.script -shared %t1 %t2 -o %t4 | |
| 113 | // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t4 | FileCheck --check-prefix=CHECKHIGH %s | |
| 114 | // RUN: llvm-readobj -s -r %t4 | FileCheck --check-prefix=DSORELHIGH %s | |
| 115 | ||
| 116 | // CHECKHIGH: Disassembly of section .text: | |
| 117 | // CHECKHIGH-NEXT: func1: | |
| 118 | // CHECKHIGH-NEXT: 1000: 1e ff 2f e1 bx lr | |
| 119 | // CHECKHIGH: func2: | |
| 120 | // CHECKHIGH-NEXT: 1004: 1e ff 2f e1 bx lr | |
| 121 | // CHECKHIGH: func3: | |
| 122 | // CHECKHIGH-NEXT: 1008: 1e ff 2f e1 bx lr | |
| 123 | // CHECKHIGH: _start: | |
| 124 | // CHECKHIGH-NEXT: 100c: 03 04 00 ea b #4108 <$a> | |
| 125 | // CHECKHIGH-NEXT: 1010: 06 04 00 eb bl #4120 <$a> | |
| 126 | // CHECKHIGH-NEXT: 1014: 09 04 00 0a beq #4132 <$a> | |
| 127 | // CHECKHIGH-NEXT: Disassembly of section .plt: | |
| 128 | // CHECKHIGH-NEXT: $a: | |
| 129 | // CHECKHIGH-NEXT: 2000: 04 e0 2d e5 str lr, [sp, #-4]! | |
| 130 | // CHECKHIGH-NEXT: 2004: 10 e6 8f e2 add lr, pc, #16, #12 | |
| 131 | // CHECKHIGH-NEXT: 2008: fd ea 8e e2 add lr, lr, #1036288 | |
| 132 | // CHECKHIGH-NEXT: 200c: fc ff be e5 ldr pc, [lr, #4092]! | |
| 133 | // CHECKHIGH: $d: | |
| 134 | // CHECKHIGH-NEXT: 2010: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 135 | // CHECKHIGH-NEXT: 2014: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 136 | // CHECKHIGH-NEXT: 2018: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 137 | // CHECKHIGH-NEXT: 201c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 138 | // CHECKHIGH: $a: | |
| 139 | // CHECKHIGH-NEXT: 2020: 10 c6 8f e2 add r12, pc, #16, #12 | |
| 140 | // CHECKHIGH-NEXT: 2024: fd ca 8c e2 add r12, r12, #1036288 | |
| 141 | // CHECKHIGH-NEXT: 2028: e4 ff bc e5 ldr pc, [r12, #4068]! | |
| 142 | // CHECKHIGH: $d: | |
| 143 | // CHECKHIGH-NEXT: 202c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 144 | // CHECKHIGH: $a: | |
| 145 | // CHECKHIGH-NEXT: 2030: 10 c6 8f e2 add r12, pc, #16, #12 | |
| 146 | // CHECKHIGH-NEXT: 2034: fd ca 8c e2 add r12, r12, #1036288 | |
| 147 | // CHECKHIGH-NEXT: 2038: d8 ff bc e5 ldr pc, [r12, #4056]! | |
| 148 | // CHECKHIGH: $d: | |
| 149 | // CHECKHIGH-NEXT: 203c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 150 | // CHECKHIGH: $a: | |
| 151 | // CHECKHIGH-NEXT: 2040: 10 c6 8f e2 add r12, pc, #16, #12 | |
| 152 | // CHECKHIGH-NEXT: 2044: fd ca 8c e2 add r12, r12, #1036288 | |
| 153 | // CHECKHIGH-NEXT: 2048: cc ff bc e5 ldr pc, [r12, #4044]! | |
| 154 | // CHECKHIGH: $d: | |
| 155 | // CHECKHIGH-NEXT: 204c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 156 | ||
| 157 | // DSORELHIGH: Name: .got.plt | |
| 158 | // DSORELHIGH-NEXT: Type: SHT_PROGBITS | |
| 159 | // DSORELHIGH-NEXT: Flags [ | |
| 160 | // DSORELHIGH-NEXT: SHF_ALLOC | |
| 161 | // DSORELHIGH-NEXT: SHF_WRITE | |
| 162 | // DSORELHIGH-NEXT: ] | |
| 163 | // DSORELHIGH-NEXT: Address: 0x1100000 | |
| 164 | // DSORELHIGH: Relocations [ | |
| 165 | // DSORELHIGH-NEXT: Section (6) .rel.plt { | |
| 166 | // DSORELHIGH-NEXT: 0x110000C R_ARM_JUMP_SLOT func1 0x0 | |
| 167 | // DSORELHIGH-NEXT: 0x1100010 R_ARM_JUMP_SLOT func2 0x0 | |
| 168 | // DSORELHIGH-NEXT: 0x1100014 R_ARM_JUMP_SLOT func3 0x0 | |
| 169 | ||
| 170 | // Test a very large separation between the .plt and .got.plt so we must use | |
| 171 | // large plt entries that do not have any range restriction. | |
| 172 | // RUN: echo "SECTIONS { \ | |
| 173 | // RUN: .text 0x1000 : { *(.text) } \ | |
| 174 | // RUN: .plt 0x2000 : { *(.plt) *(.plt.*) } \ | |
| 175 | // RUN: .got.plt 0x11111100 : { *(.got.plt) } \ | |
| 176 | // RUN: }" > %t2.script | |
| 177 | // RUN: ld.lld --hash-style=sysv --script %t2.script -shared %t1 %t2 -o %t5 | |
| 178 | // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t5 | FileCheck --check-prefix=CHECKLONG %s | |
| 179 | // RUN: llvm-readobj -s -r %t5 | FileCheck --check-prefix=DSORELLONG %s | |
| 180 | ||
| 181 | // CHECKLONG: Disassembly of section .text: | |
| 182 | // CHECKLONG-NEXT: func1: | |
| 183 | // CHECKLONG-NEXT: 1000: 1e ff 2f e1 bx lr | |
| 184 | // CHECKLONG: func2: | |
| 185 | // CHECKLONG-NEXT: 1004: 1e ff 2f e1 bx lr | |
| 186 | // CHECKLONG: func3: | |
| 187 | // CHECKLONG-NEXT: 1008: 1e ff 2f e1 bx lr | |
| 188 | // CHECKLONG: _start: | |
| 189 | // CHECKLONG-NEXT: 100c: 03 04 00 ea b #4108 <$a> | |
| 190 | // CHECKLONG-NEXT: 1010: 06 04 00 eb bl #4120 <$a> | |
| 191 | // CHECKLONG-NEXT: 1014: 09 04 00 0a beq #4132 <$a> | |
| 192 | // CHECKLONG-NEXT: Disassembly of section .plt: | |
| 193 | // CHECKLONG-NEXT: $a: | |
| 194 | // CHECKLONG-NEXT: 2000: 04 e0 2d e5 str lr, [sp, #-4]! | |
| 195 | // CHECKLONG-NEXT: 2004: 04 e0 9f e5 ldr lr, [pc, #4] | |
| 196 | // CHECKLONG-NEXT: 2008: 0e e0 8f e0 add lr, pc, lr | |
| 197 | // CHECKLONG-NEXT: 200c: 08 f0 be e5 ldr pc, [lr, #8]! | |
| 198 | // CHECKLONG: $d: | |
| 199 | // CHECKLONG-NEXT: 2010: f0 f0 10 11 .word 0x1110f0f0 | |
| 200 | // CHECKLONG-NEXT: 2014: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 201 | // CHECKLONG-NEXT: 2018: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 202 | // CHECKLONG-NEXT: 201c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 203 | // CHECKLONG: $a: | |
| 204 | // CHECKLONG-NEXT: 2020: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 205 | // CHECKLONG-NEXT: 2024: 0f c0 8c e0 add r12, r12, pc | |
| 206 | // CHECKLONG-NEXT: 2028: 00 f0 9c e5 ldr pc, [r12] | |
| 207 | // CHECKLONG: $d: | |
| 208 | // CHECKLONG-NEXT: 202c: e0 f0 10 11 .word 0x1110f0e0 | |
| 209 | // CHECKLONG: $a: | |
| 210 | // CHECKLONG-NEXT: 2030: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 211 | // CHECKLONG-NEXT: 2034: 0f c0 8c e0 add r12, r12, pc | |
| 212 | // CHECKLONG-NEXT: 2038: 00 f0 9c e5 ldr pc, [r12] | |
| 213 | // CHECKLONG: $d: | |
| 214 | // CHECKLONG-NEXT: 203c: d4 f0 10 11 .word 0x1110f0d4 | |
| 215 | // CHECKLONG: $a: | |
| 216 | // CHECKLONG-NEXT: 2040: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 217 | // CHECKLONG-NEXT: 2044: 0f c0 8c e0 add r12, r12, pc | |
| 218 | // CHECKLONG-NEXT: 2048: 00 f0 9c e5 ldr pc, [r12] | |
| 219 | // CHECKLONG: $d: | |
| 220 | // CHECKLONG-NEXT: 204c: c8 f0 10 11 .word 0x1110f0c8 | |
| 221 | ||
| 222 | // DSORELLONG: Name: .got.plt | |
| 223 | // DSORELLONG-NEXT: Type: SHT_PROGBITS | |
| 224 | // DSORELLONG-NEXT: Flags [ | |
| 225 | // DSORELLONG-NEXT: SHF_ALLOC | |
| 226 | // DSORELLONG-NEXT: SHF_WRITE | |
| 227 | // DSORELLONG-NEXT: ] | |
| 228 | // DSORELLONG-NEXT: Address: 0x11111100 | |
| 229 | // DSORELLONG: Relocations [ | |
| 230 | // DSORELLONG-NEXT: Section (6) .rel.plt { | |
| 231 | // DSORELLONG-NEXT: 0x1111110C R_ARM_JUMP_SLOT func1 0x0 | |
| 232 | // DSORELLONG-NEXT: 0x11111110 R_ARM_JUMP_SLOT func2 0x0 | |
| 233 | // DSORELLONG-NEXT: 0x11111114 R_ARM_JUMP_SLOT func3 0x0 | |
| 234 | ||
| 235 | // Test a separation between the .plt and .got.plt that is part in range of | |
| 236 | // short table entries and part needing long entries. We use the long entries | |
| 237 | // only when we need to. | |
| 238 | // RUN: echo "SECTIONS { \ | |
| 239 | // RUN: .text 0x1000 : { *(.text) } \ | |
| 240 | // RUN: .plt 0x2000 : { *(.plt) *(.plt.*) } \ | |
| 241 | // RUN: .got.plt 0x8002020 : { *(.got.plt) } \ | |
| 242 | // RUN: }" > %t3.script | |
| 243 | // RUN: ld.lld --hash-style=sysv --script %t3.script -shared %t1 %t2 -o %t6 | |
| 244 | // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t6 | FileCheck --check-prefix=CHECKMIX %s | |
| 245 | // RUN: llvm-readobj -s -r %t6 | FileCheck --check-prefix=DSORELMIX %s | |
| 246 | ||
| 247 | // CHECKMIX: Disassembly of section .text: | |
| 248 | // CHECKMIX-NEXT: func1: | |
| 249 | // CHECKMIX-NEXT: 1000: 1e ff 2f e1 bx lr | |
| 250 | // CHECKMIX: func2: | |
| 251 | // CHECKMIX-NEXT: 1004: 1e ff 2f e1 bx lr | |
| 252 | // CHECKMIX: func3: | |
| 253 | // CHECKMIX-NEXT: 1008: 1e ff 2f e1 bx lr | |
| 254 | // CHECKMIX: _start: | |
| 255 | // CHECKMIX-NEXT: 100c: 03 04 00 ea b #4108 <$a> | |
| 256 | // CHECKMIX-NEXT: 1010: 06 04 00 eb bl #4120 <$a> | |
| 257 | // CHECKMIX-NEXT: 1014: 09 04 00 0a beq #4132 <$a> | |
| 258 | // CHECKMIX-NEXT: Disassembly of section .plt: | |
| 259 | // CHECKMIX-NEXT: $a: | |
| 260 | // CHECKMIX-NEXT: 2000: 04 e0 2d e5 str lr, [sp, #-4]! | |
| 261 | // CHECKMIX-NEXT: 2004: 04 e0 9f e5 ldr lr, [pc, #4] | |
| 262 | // CHECKMIX-NEXT: 2008: 0e e0 8f e0 add lr, pc, lr | |
| 263 | // CHECKMIX-NEXT: 200c: 08 f0 be e5 ldr pc, [lr, #8]! | |
| 264 | // CHECKMIX: $d: | |
| 265 | // CHECKMIX-NEXT: 2010: 10 00 00 08 .word 0x08000010 | |
| 266 | // CHECKMIX-NEXT: 2014: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 267 | // CHECKMIX-NEXT: 2018: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 268 | // CHECKMIX-NEXT: 201c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 269 | // CHECKMIX: $a: | |
| 270 | // CHECKMIX-NEXT: 2020: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 271 | // CHECKMIX-NEXT: 2024: 0f c0 8c e0 add r12, r12, pc | |
| 272 | // CHECKMIX-NEXT: 2028: 00 f0 9c e5 ldr pc, [r12] | |
| 273 | // CHECKMIX: $d: | |
| 274 | // CHECKMIX-NEXT: 202c: 00 00 00 08 .word 0x08000000 | |
| 275 | // CHECKMIX: $a: | |
| 276 | // CHECKMIX-NEXT: 2030: 7f c6 8f e2 add r12, pc, #133169152 | |
| 277 | // CHECKMIX-NEXT: 2034: ff ca 8c e2 add r12, r12, #1044480 | |
| 278 | // CHECKMIX-NEXT: 2038: f8 ff bc e5 ldr pc, [r12, #4088]! | |
| 279 | // CHECKMIX: $d: | |
| 280 | // CHECKMIX-NEXT: 203c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 281 | // CHECKMIX: $a: | |
| 282 | // CHECKMIX-NEXT: 2040: 7f c6 8f e2 add r12, pc, #133169152 | |
| 283 | // CHECKMIX-NEXT: 2044: ff ca 8c e2 add r12, r12, #1044480 | |
| 284 | // CHECKMIX-NEXT: 2048: ec ff bc e5 ldr pc, [r12, #4076]! | |
| 285 | // CHECKMIX: $d: | |
| 286 | // CHECKMIX-NEXT: 204c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 287 | ||
| 288 | // DSORELMIX: Name: .got.plt | |
| 289 | // DSORELMIX-NEXT: Type: SHT_PROGBITS | |
| 290 | // DSORELMIX-NEXT: Flags [ | |
| 291 | // DSORELMIX-NEXT: SHF_ALLOC | |
| 292 | // DSORELMIX-NEXT: SHF_WRITE | |
| 293 | // DSORELMIX-NEXT: ] | |
| 294 | // DSORELMIX-NEXT: Address: 0x8002020 | |
| 295 | // DSORELMIX: Section (6) .rel.plt { | |
| 296 | // DSORELMIX-NEXT: 0x800202C R_ARM_JUMP_SLOT func1 0x0 | |
| 297 | // DSORELMIX-NEXT: 0x8002030 R_ARM_JUMP_SLOT func2 0x0 | |
| 298 | // DSORELMIX-NEXT: 0x8002034 R_ARM_JUMP_SLOT func3 0x0 |
deps/lld/test/ELF/arm-static-defines.s+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t --static -o %t2 2>&1 | |
| 2 | // RUN: ld.lld --no-merge-exidx-entries %t --static -o %t2 2>&1 | |
| 3 | 3 | // RUN: llvm-readobj --symbols %t2 | FileCheck %s |
| 4 | 4 | // REQUIRES: arm |
| 5 | 5 |
deps/lld/test/ELF/arm-thumb-branch-error.s deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 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/Inputs/far-arm-thumb-abs.s -o %tfar | |
| 3 | // RUN: not ld.lld %t %tfar -o %t2 2>&1 | FileCheck %s | |
| 4 | // REQUIRES: arm | |
| 5 | .syntax unified | |
| 6 | .section .text, "ax",%progbits | |
| 7 | .globl _start | |
| 8 | .balign 0x10000 | |
| 9 | .type _start,%function | |
| 10 | _start: | |
| 11 | // address of too_far symbols are just out of range of ARM branch with | |
| 12 | // 26-bit immediate field and an addend of -8 | |
| 13 | bl too_far1 | |
| 14 | b too_far2 | |
| 15 | beq.w too_far3 | |
| 16 | ||
| 17 | // CHECK: R_ARM_THM_CALL out of range | |
| 18 | // CHECK-NEXT: R_ARM_THM_JUMP24 out of range | |
| 19 | // CHECK-NEXT: R_ARM_THM_JUMP19 out of range |
deps/lld/test/ELF/arm-thumb-branch-rangethunk.s created+36| ... | ... | @@ -0,0 +1,36 @@ |
| 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/Inputs/far-arm-thumb-abs.s -o %tfar | |
| 3 | // RUN: ld.lld %t %tfar -o %t2 2>&1 | |
| 4 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | |
| 5 | // REQUIRES: arm | |
| 6 | .syntax unified | |
| 7 | .thumb | |
| 8 | .section .text, "ax",%progbits | |
| 9 | .globl _start | |
| 10 | .balign 0x10000 | |
| 11 | .type _start,%function | |
| 12 | _start: | |
| 13 | // address of too_far symbols are just out of range of ARM branch with | |
| 14 | // 26-bit immediate field and an addend of -8 | |
| 15 | bl too_far1 | |
| 16 | b too_far2 | |
| 17 | beq.w too_far3 | |
| 18 | ||
| 19 | // CHECK: Disassembly of section .text: | |
| 20 | // CHECK-NEXT: _start: | |
| 21 | // CHECK-NEXT: 20000: 00 f0 04 f8 bl #8 | |
| 22 | // CHECK-NEXT: 20004: 00 f0 07 b8 b.w #14 <__Thumbv7ABSLongThunk_too_far2> | |
| 23 | // CHECK-NEXT: 20008: 00 f0 0a 80 beq.w #20 <__Thumbv7ABSLongThunk_too_far3> | |
| 24 | // CHECK: __Thumbv7ABSLongThunk_too_far1: | |
| 25 | // CHECK-NEXT: 2000c: 40 f2 05 0c movw r12, #5 | |
| 26 | // CHECK-NEXT: 20010: c0 f2 02 1c movt r12, #258 | |
| 27 | // CHECK-NEXT: 20014: 60 47 bx r12 | |
| 28 | // CHECK: __Thumbv7ABSLongThunk_too_far2: | |
| 29 | // CHECK-NEXT: 20016: 40 f2 09 0c movw r12, #9 | |
| 30 | // CHECK-NEXT: 2001a: c0 f2 02 1c movt r12, #258 | |
| 31 | // CHECK-NEXT: 2001e: 60 47 bx r12 | |
| 32 | // CHECK: __Thumbv7ABSLongThunk_too_far3: | |
| 33 | // CHECK-NEXT: 20020: 40 f2 0d 0c movw r12, #13 | |
| 34 | // CHECK-NEXT: 20024: c0 f2 12 0c movt r12, #18 | |
| 35 | // CHECK-NEXT: 20028: 60 47 bx r12 | |
| 36 | // CHECK-NEXT: 2002a: 00 00 movs r0, r0 |
deps/lld/test/ELF/arm-thumb-condbranch-thunk.s created+117| ... | ... | @@ -0,0 +1,117 @@ |
| 1 | // REQUIRES: arm | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | |
| 3 | // RUN: ld.lld %t -o %t2 2>&1 | |
| 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 | |
| 6 | // RUN: llvm-objdump -d %t2 -start-address=524288 -stop-address=524316 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s | |
| 7 | // RUN: llvm-objdump -d %t2 -start-address=1048576 -stop-address=1048584 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s | |
| 8 | // RUN: llvm-objdump -d %t2 -start-address=1572864 -stop-address=1572872 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s | |
| 9 | // RUN: llvm-objdump -d %t2 -start-address=5242884 -stop-address=5242894 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s | |
| 10 | // RUN: llvm-objdump -d %t2 -start-address=5767168 -stop-address=5767174 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK5 %s | |
| 11 | // RUN: llvm-objdump -d %t2 -start-address=16777220 -stop-address=16777240 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK6 %s | |
| 12 | // RUN: llvm-objdump -d %t2 -start-address=17825792 -stop-address=17825798 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK7 %s | |
| 13 | // Test Range extension Thunks for the Thumb conditional branch instruction. | |
| 14 | // This instruction only has a range of 1Mb whereas all the other Thumb wide | |
| 15 | // Branch instructions have 16Mb range. We still place our pre-created Thunk | |
| 16 | // Sections at 16Mb intervals as conditional branches to a target defined | |
| 17 | // in a different section are rare. | |
| 18 | .syntax unified | |
| 19 | // Define a function aligned on a half megabyte boundary | |
| 20 | .macro FUNCTION suff | |
| 21 | .section .text.\suff\(), "ax", %progbits | |
| 22 | .thumb | |
| 23 | .balign 0x80000 | |
| 24 | .globl tfunc\suff\() | |
| 25 | .type tfunc\suff\(), %function | |
| 26 | tfunc\suff\(): | |
| 27 | bx lr | |
| 28 | .endm | |
| 29 | ||
| 30 | .globl _start | |
| 31 | _start: | |
| 32 | FUNCTION 00 | |
| 33 | // Long Range Thunk needed for 16Mb range branch, can reach pre-created Thunk | |
| 34 | // Section | |
| 35 | bl tfunc33 | |
| 36 | // CHECK1: Disassembly of section .text: | |
| 37 | // CHECK1-NEXT: tfunc00: | |
| 38 | // CHECK1-NEXT: 80000: 70 47 bx lr | |
| 39 | // CHECK1-NEXT: 80002: 7f f3 ff d7 bl #16252926 | |
| 40 | // CHECK1: __Thumbv7ABSLongThunk_tfunc05: | |
| 41 | // CHECK1-NEXT: 80008: 40 f2 01 0c movw r12, #1 | |
| 42 | // CHECK1-NEXT: 8000c: c0 f2 30 0c movt r12, #48 | |
| 43 | // CHECK1-NEXT: 80010: 60 47 bx r12 | |
| 44 | // CHECK1: __Thumbv7ABSLongThunk_tfunc00: | |
| 45 | // CHECK1-NEXT: 80012: 40 f2 01 0c movw r12, #1 | |
| 46 | // CHECK1-NEXT: 80016: c0 f2 08 0c movt r12, #8 | |
| 47 | // CHECK1-NEXT: 8001a: 60 47 bx r12 | |
| 48 | FUNCTION 01 | |
| 49 | // tfunc02 is within range of tfunc02 | |
| 50 | beq.w tfunc02 | |
| 51 | // tfunc05 is out of range, and we can't reach the pre-created Thunk Section | |
| 52 | // create a new one. | |
| 53 | bne.w tfunc05 | |
| 54 | // CHECK2: tfunc01: | |
| 55 | // CHECK2-NEXT: 100000: 70 47 bx lr | |
| 56 | // CHECK2-NEXT: 100002: 3f f0 fd a7 beq.w #524282 <tfunc02> | |
| 57 | // CHECK2-NEXT: 100006: 7f f4 ff a7 bne.w #-524290 <__Thumbv7ABSLongThunk_tfunc05> | |
| 58 | FUNCTION 02 | |
| 59 | // We can reach the Thunk Section created for bne.w tfunc05 | |
| 60 | bne.w tfunc05 | |
| 61 | beq.w tfunc00 | |
| 62 | // CHECK3: 180000: 70 47 bx lr | |
| 63 | // 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> | |
| 65 | FUNCTION 03 | |
| 66 | FUNCTION 04 | |
| 67 | FUNCTION 05 | |
| 68 | FUNCTION 06 | |
| 69 | FUNCTION 07 | |
| 70 | FUNCTION 08 | |
| 71 | FUNCTION 09 | |
| 72 | // CHECK4: __Thumbv7ABSLongThunk_tfunc03: | |
| 73 | // CHECK4-NEXT: 500004: 40 f2 01 0c movw r12, #1 | |
| 74 | // CHECK4-NEXT: 500008: c0 f2 20 0c movt r12, #32 | |
| 75 | // CHECK4-NEXT: 50000c: 60 47 bx r12 | |
| 76 | FUNCTION 10 | |
| 77 | // We can't reach any Thunk Section, create a new one | |
| 78 | beq.w tfunc03 | |
| 79 | // CHECK5: tfunc10: | |
| 80 | // CHECK5-NEXT: 580000: 70 47 bx lr | |
| 81 | // CHECK5-NEXT: 580002: 3f f4 ff a7 beq.w #-524290 <__Thumbv7ABSLongThunk_tfunc03> | |
| 82 | FUNCTION 11 | |
| 83 | FUNCTION 12 | |
| 84 | FUNCTION 13 | |
| 85 | FUNCTION 14 | |
| 86 | FUNCTION 15 | |
| 87 | FUNCTION 16 | |
| 88 | FUNCTION 17 | |
| 89 | FUNCTION 18 | |
| 90 | FUNCTION 19 | |
| 91 | FUNCTION 20 | |
| 92 | FUNCTION 21 | |
| 93 | FUNCTION 22 | |
| 94 | FUNCTION 23 | |
| 95 | FUNCTION 24 | |
| 96 | FUNCTION 25 | |
| 97 | FUNCTION 26 | |
| 98 | FUNCTION 27 | |
| 99 | FUNCTION 28 | |
| 100 | FUNCTION 29 | |
| 101 | FUNCTION 30 | |
| 102 | FUNCTION 31 | |
| 103 | // CHECK6: __Thumbv7ABSLongThunk_tfunc33: | |
| 104 | // CHECK6-NEXT: 1000004: 40 f2 01 0c movw r12, #1 | |
| 105 | // CHECK6-NEXT: 1000008: c0 f2 10 1c movt r12, #272 | |
| 106 | // CHECK6-NEXT: 100000c: 60 47 bx r12 | |
| 107 | // CHECK6: __Thumbv7ABSLongThunk_tfunc00: | |
| 108 | // CHECK6-NEXT: 100000e: 40 f2 01 0c movw r12, #1 | |
| 109 | // CHECK6-NEXT: 1000012: c0 f2 08 0c movt r12, #8 | |
| 110 | // CHECK6-NEXT: 1000016: 60 47 bx r12 | |
| 111 | FUNCTION 32 | |
| 112 | FUNCTION 33 | |
| 113 | // We should be able to reach an existing ThunkSection. | |
| 114 | b.w tfunc00 | |
| 115 | // CHECK7: tfunc33: | |
| 116 | // CHECK7-NEXT: 1100000: 70 47 bx lr | |
| 117 | // CHECK7-NEXT: 1100002: 00 f7 04 b8 b.w #-1048568 <__Thumbv7ABSLongThunk_tfunc00> |
deps/lld/test/ELF/arm-thumb-interwork-shared.s+20-17| ... | ... | @@ -19,34 +19,37 @@ sym1: |
| 19 | 19 | // CHECK-NEXT: 1000: 00 f0 02 b8 b.w #4 <__ThumbV7PILongThunk_elsewhere> |
| 20 | 20 | // CHECK-NEXT: 1004: 00 f0 06 b8 b.w #12 <__ThumbV7PILongThunk_weakref> |
| 21 | 21 | // CHECK: __ThumbV7PILongThunk_elsewhere: |
| 22 | // CHECK-NEXT: 1008: 40 f2 20 0c movw r12, #32 | |
| 22 | // CHECK-NEXT: 1008: 40 f2 2c 0c movw r12, #44 | |
| 23 | 23 | // CHECK-NEXT: 100c: c0 f2 00 0c movt r12, #0 |
| 24 | 24 | // CHECK-NEXT: 1010: fc 44 add r12, pc |
| 25 | 25 | // CHECK-NEXT: 1012: 60 47 bx r12 |
| 26 | ||
| 27 | 26 | // CHECK: __ThumbV7PILongThunk_weakref: |
| 28 | // CHECK-NEXT: 1014: 40 f2 24 0c movw r12, #36 | |
| 27 | // CHECK-NEXT: 1014: 40 f2 30 0c movw r12, #48 | |
| 29 | 28 | // CHECK-NEXT: 1018: c0 f2 00 0c movt r12, #0 |
| 30 | 29 | // CHECK-NEXT: 101c: fc 44 add r12, pc |
| 31 | 30 | // CHECK-NEXT: 101e: 60 47 bx r12 |
| 32 | 31 | |
| 33 | 32 | // PLT: Disassembly of section .plt: |
| 34 | // PLT: $a: | |
| 35 | // PLT-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]! | |
| 36 | // PLT-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4] | |
| 37 | // PLT-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr | |
| 38 | // PLT-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]! | |
| 33 | // PLT-NEXT: $a: | |
| 34 | // PLT-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]! | |
| 35 | // PLT-NEXT: 1024: 00 e6 8f e2 add lr, pc, #0, #12 | |
| 36 | // PLT-NEXT: 1028: 00 ea 8e e2 add lr, lr, #0, #20 | |
| 37 | // PLT-NEXT: 102c: dc ff be e5 ldr pc, [lr, #4060]! | |
| 39 | 38 | // PLT: $d: |
| 40 | // PLT-NEXT: 1030: d0 0f 00 00 .word 0x00000fd0 | |
| 39 | // PLT-NEXT: 1030: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 40 | // PLT-NEXT: 1034: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 41 | // PLT-NEXT: 1038: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 42 | // PLT-NEXT: 103c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 41 | 43 | // PLT: $a: |
| 42 | // PLT-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 43 | // PLT-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc | |
| 44 | // PLT-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12] | |
| 44 | // PLT-NEXT: 1040: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 45 | // PLT-NEXT: 1044: 00 ca 8c e2 add r12, r12, #0, #20 | |
| 46 | // PLT-NEXT: 1048: c4 ff bc e5 ldr pc, [r12, #4036]! | |
| 45 | 47 | // PLT: $d: |
| 46 | // PLT-NEXT: 1040: cc 0f 00 00 .word 0x00000fcc | |
| 48 | // PLT-NEXT: 104c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 47 | 49 | // PLT: $a: |
| 48 | // PLT-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 49 | // PLT-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc | |
| 50 | // PLT-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12] | |
| 50 | // PLT-NEXT: 1050: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 51 | // PLT-NEXT: 1054: 00 ca 8c e2 add r12, r12, #0, #20 | |
| 52 | // PLT-NEXT: 1058: b8 ff bc e5 ldr pc, [r12, #4024]! | |
| 51 | 53 | // PLT: $d: |
| 52 | // PLT-NEXT: 1050: c0 0f 00 00 .word 0x00000fc0 | |
| 54 | // PLT-NEXT: 105c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 55 |
deps/lld/test/ELF/arm-thumb-mix-range-thunk-os.s created+195| ... | ... | @@ -0,0 +1,195 @@ |
| 1 | // REQUIRES: arm | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | |
| 3 | // RUN: ld.lld %t -o %t2 2>&1 | |
| 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 | |
| 6 | // RUN: llvm-objdump -d %t2 -start-address=1048576 -stop-address=1048604 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s | |
| 7 | // RUN: llvm-objdump -d %t2 -start-address=2097152 -stop-address=2097162 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s | |
| 8 | // RUN: llvm-objdump -d %t2 -start-address=16777220 -stop-address=16777232 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s | |
| 9 | // RUN: llvm-objdump -d %t2 -start-address=16777232 -stop-address=16777242 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s | |
| 10 | // RUN: llvm-objdump -d %t2 -start-address=32505860 -stop-address=32505870 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK5 %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 | |
| 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 | |
| 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 | |
| 17 | ||
| 18 | // Test the Range extension Thunks for ARM and Thumb when all the code is in a | |
| 19 | // single OutputSection. The ARM branches and branch and link instructions | |
| 20 | // have a range of 32Mb, the Thumb unconditional branch and | |
| 21 | // branch and link instructions have . We create a series of Functions a | |
| 22 | // megabyte apart. We expect range extension thunks to be created when a | |
| 23 | // branch is out of range. Thunks will be reused whenever they are in range | |
| 24 | .syntax unified | |
| 25 | ||
| 26 | // Define a function aligned on a megabyte boundary | |
| 27 | .macro ARMFUNCTION suff | |
| 28 | .section .text.\suff\(), "ax", %progbits | |
| 29 | .arm | |
| 30 | .balign 0x100000 | |
| 31 | .globl afunc\suff\() | |
| 32 | .type afunc\suff\(), %function | |
| 33 | afunc\suff\(): | |
| 34 | bx lr | |
| 35 | .endm | |
| 36 | ||
| 37 | // Define a function aligned on a megabyte boundary | |
| 38 | .macro THUMBFUNCTION suff | |
| 39 | .section .text.\suff\(), "ax", %progbits | |
| 40 | .thumb | |
| 41 | .balign 0x100000 | |
| 42 | .globl tfunc\suff\() | |
| 43 | .type tfunc\suff\(), %function | |
| 44 | tfunc\suff\(): | |
| 45 | bx lr | |
| 46 | .endm | |
| 47 | ||
| 48 | .section .text, "ax", %progbits | |
| 49 | .thumb | |
| 50 | .globl _start | |
| 51 | _start: | |
| 52 | ||
| 53 | ARMFUNCTION 00 | |
| 54 | // Expect ARM bl to be in range (can use blx to change state) | |
| 55 | bl tfunc31 | |
| 56 | // ARM b and beq are in range but need Thunk to change state to Thumb | |
| 57 | b tfunc31 | |
| 58 | beq tfunc31 | |
| 59 | // afunc32 is out of range of ARM branch and branch and link | |
| 60 | bl afunc32 | |
| 61 | b afunc32 | |
| 62 | bne afunc32 | |
| 63 | // CHECK1: afunc00: | |
| 64 | // CHECK1-NEXT: 100000: 1e ff 2f e1 bx lr | |
| 65 | // CHECK1-NEXT: 100004: fd ff 7b fa blx #32505844 | |
| 66 | // CHECK1-NEXT: 100008: fd ff 3b ea b #15728628 | |
| 67 | // CHECK1-NEXT: 10000c: fc ff 3b 0a beq #15728624 | |
| 68 | // CHECK1-NEXT: 100010: fa ff 7f eb bl #33554408 | |
| 69 | // CHECK1-NEXT: 100014: f9 ff 7f ea b #33554404 | |
| 70 | // CHECK1-NEXT: 100018: f8 ff 7f 1a bne #33554400 | |
| 71 | THUMBFUNCTION 01 | |
| 72 | // Expect Thumb bl to be in range (can use blx to change state) | |
| 73 | bl afunc14 | |
| 74 | // In range but need thunk to change state to Thumb | |
| 75 | b.w afunc14 | |
| 76 | // CHECK2: tfunc01: | |
| 77 | // CHECK2-NEXT: 200000: 70 47 bx lr | |
| 78 | // CHECK2-NEXT: 200002: ff f0 fe c7 blx #13631484 | |
| 79 | // CHECK2-NEXT: 200006: 00 f2 03 90 b.w #14680070 <__Thumbv7ABSLongThunk_afunc14> | |
| 80 | ||
| 81 | ARMFUNCTION 02 | |
| 82 | THUMBFUNCTION 03 | |
| 83 | ARMFUNCTION 04 | |
| 84 | THUMBFUNCTION 05 | |
| 85 | ARMFUNCTION 06 | |
| 86 | THUMBFUNCTION 07 | |
| 87 | ARMFUNCTION 08 | |
| 88 | THUMBFUNCTION 09 | |
| 89 | ARMFUNCTION 10 | |
| 90 | THUMBFUNCTION 11 | |
| 91 | ARMFUNCTION 12 | |
| 92 | THUMBFUNCTION 13 | |
| 93 | ARMFUNCTION 14 | |
| 94 | // CHECK3: __ARMv7ABSLongThunk_tfunc31: | |
| 95 | // CHECK3-NEXT: 1000004: 01 c0 00 e3 movw r12, #1 | |
| 96 | // CHECK3-NEXT: 1000008: 00 c2 40 e3 movt r12, #512 | |
| 97 | // CHECK3-NEXT: 100000c: 1c ff 2f e1 bx r12 | |
| 98 | // CHECK4: __Thumbv7ABSLongThunk_afunc14: | |
| 99 | // CHECK4-NEXT: 1000010: 40 f2 00 0c movw r12, #0 | |
| 100 | // CHECK4-NEXT: 1000014: c0 f2 f0 0c movt r12, #240 | |
| 101 | // CHECK4-NEXT: 1000018: 60 47 bx r12 | |
| 102 | THUMBFUNCTION 15 | |
| 103 | ARMFUNCTION 16 | |
| 104 | THUMBFUNCTION 17 | |
| 105 | ARMFUNCTION 18 | |
| 106 | THUMBFUNCTION 19 | |
| 107 | ARMFUNCTION 20 | |
| 108 | THUMBFUNCTION 21 | |
| 109 | ARMFUNCTION 22 | |
| 110 | THUMBFUNCTION 23 | |
| 111 | ARMFUNCTION 24 | |
| 112 | THUMBFUNCTION 25 | |
| 113 | ARMFUNCTION 26 | |
| 114 | THUMBFUNCTION 27 | |
| 115 | ARMFUNCTION 28 | |
| 116 | THUMBFUNCTION 29 | |
| 117 | ARMFUNCTION 30 | |
| 118 | // Expect precreated Thunk Section here | |
| 119 | // CHECK5: __Thumbv7ABSLongThunk_afunc00: | |
| 120 | // CHECK5-NEXT: 1f00004: 40 f2 00 0c movw r12, #0 | |
| 121 | // CHECK5-NEXT: 1f00008: c0 f2 10 0c movt r12, #16 | |
| 122 | // CHECK5-NEXT: 1f0000c: 60 47 bx r12 | |
| 123 | THUMBFUNCTION 31 | |
| 124 | ARMFUNCTION 32 | |
| 125 | THUMBFUNCTION 33 | |
| 126 | // Out of range, can only reach closest Thunk Section | |
| 127 | bl afunc00 | |
| 128 | // CHECK6: tfunc33: | |
| 129 | // CHECK6-NEXT: 2200000: 70 47 bx lr | |
| 130 | // CHECK6-NEXT: 2200002: ff f4 ff ff bl #-3145730 | |
| 131 | ARMFUNCTION 34 | |
| 132 | // Out of range, can reach earlier Thunk Section | |
| 133 | // CHECK7: afunc34: | |
| 134 | // CHECK7-NEXT: 2300000: 1e ff 2f e1 bx lr | |
| 135 | // CHECK7-NEXT: 2300004: fe ff ef fa blx #-4194312 <__Thumbv7ABSLongThunk_afunc00 | |
| 136 | bl afunc00 | |
| 137 | THUMBFUNCTION 35 | |
| 138 | ARMFUNCTION 36 | |
| 139 | THUMBFUNCTION 37 | |
| 140 | ARMFUNCTION 38 | |
| 141 | THUMBFUNCTION 39 | |
| 142 | ARMFUNCTION 40 | |
| 143 | THUMBFUNCTION 41 | |
| 144 | ARMFUNCTION 42 | |
| 145 | THUMBFUNCTION 43 | |
| 146 | ARMFUNCTION 44 | |
| 147 | THUMBFUNCTION 45 | |
| 148 | // Expect precreated Thunk Section here | |
| 149 | // CHECK8: __ARMv7ABSLongThunk_tfunc35: | |
| 150 | // CHECK8-NEXT: 2e00004: 01 c0 00 e3 movw r12, #1 | |
| 151 | // CHECK8-NEXT: 2e00008: 40 c2 40 e3 movt r12, #576 | |
| 152 | // CHECK8-NEXT: 2e0000c: 1c ff 2f e1 bx r12 | |
| 153 | ARMFUNCTION 46 | |
| 154 | THUMBFUNCTION 47 | |
| 155 | ARMFUNCTION 48 | |
| 156 | THUMBFUNCTION 49 | |
| 157 | ARMFUNCTION 50 | |
| 158 | THUMBFUNCTION 51 | |
| 159 | ARMFUNCTION 52 | |
| 160 | THUMBFUNCTION 53 | |
| 161 | ARMFUNCTION 54 | |
| 162 | THUMBFUNCTION 55 | |
| 163 | ARMFUNCTION 56 | |
| 164 | THUMBFUNCTION 57 | |
| 165 | ARMFUNCTION 58 | |
| 166 | THUMBFUNCTION 59 | |
| 167 | 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 | |
| 178 | ARMFUNCTION 62 | |
| 179 | THUMBFUNCTION 63 | |
| 180 | ARMFUNCTION 64 | |
| 181 | // afunc34 is in range, as is tfunc35 but a branch needs a state change Thunk | |
| 182 | bl afunc34 | |
| 183 | b tfunc35 | |
| 184 | // CHECK10: afunc64: | |
| 185 | // CHECK10-NEXT: 4100000: 1e ff 2f e1 bx lr | |
| 186 | // CHECK10-NEXT: 4100004: fd ff 87 eb bl #-31457292 <afunc34> | |
| 187 | // CHECK10-NEXT: 4100008: fd ff b3 ea b #-19922956 <__ARMv7ABSLongThunk_tfunc35> | |
| 188 | THUMBFUNCTION 65 | |
| 189 | // afunc34 and tfunc35 are both out of range | |
| 190 | bl afunc34 | |
| 191 | bl tfunc35 | |
| 192 | // CHECK11: tfunc65: | |
| 193 | // CHECK11: 4200000: 70 47 bx lr | |
| 194 | // CHECK11-NEXT: 4200002: ff f6 ff f7 bl #-5242882 | |
| 195 | // CHECK11-NEXT: 4200006: 00 f7 02 f0 bl #-5242876 |
deps/lld/test/ELF/arm-thumb-no-undefined-thunk.s+1-1| ... | ... | @@ -21,4 +21,4 @@ _start: |
| 21 | 21 | // 69636 = 0x11004 = next instruction |
| 22 | 22 | // CHECK: 11000: {{.*}} bl #0 |
| 23 | 23 | // CHECK-NEXT: 11004: {{.*}} b.w #0 <_start+0x8> |
| 24 | // CHECK-NEXT: 11008: {{.*}} b.w #0 <_start+0xC> | |
| 24 | // CHECK-NEXT: 11008: {{.*}} b.w #0 <_start+0xc> |
deps/lld/test/ELF/arm-thumb-plt-range-thunk-os.s created+92| ... | ... | @@ -0,0 +1,92 @@ |
| 1 | // REQUIRES: arm | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | |
| 3 | // RUN: ld.lld %t --shared -o %t.so | |
| 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 | |
| 6 | // RUN: llvm-objdump -d %t.so -start-address=8388608 -stop-address=8388624 -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 | |
| 8 | // RUN: llvm-objdump -d %t.so -start-address=25165824 -stop-address=25165828 -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 | |
| 10 | .syntax unified | |
| 11 | .thumb | |
| 12 | ||
| 13 | // Make sure that we generate a range extension thunk to a PLT entry | |
| 14 | .section ".text.1", "ax", %progbits | |
| 15 | .global sym1 | |
| 16 | .global elsewhere | |
| 17 | .type elsewhere, %function | |
| 18 | .global preemptible | |
| 19 | .type preemptible, %function | |
| 20 | .global far_preemptible | |
| 21 | .type far_preemptible, %function | |
| 22 | sym1: | |
| 23 | bl elsewhere | |
| 24 | bl preemptible | |
| 25 | bx lr | |
| 26 | preemptible: | |
| 27 | bl far_preemptible | |
| 28 | bx lr | |
| 29 | // CHECK1: Disassembly of section .text: | |
| 30 | // CHECK1-NEXT: sym1: | |
| 31 | // CHECK1-NEXT: 800000: 00 f0 00 d8 bl #8388608 | |
| 32 | // CHECK1-NEXT: 800004: 00 f0 04 d8 bl #8388616 | |
| 33 | // CHECK1-NEXT: 800008: 70 47 bx lr | |
| 34 | // CHECK1: preemptible: | |
| 35 | // CHECK1-NEXT: 80000a: 00 f0 07 d8 bl #8388622 | |
| 36 | // CHECK1-NEXT: 80000e: 70 47 bx lr | |
| 37 | ||
| 38 | .section .text.2, "ax", %progbits | |
| 39 | .balign 0x0800000 | |
| 40 | bx lr | |
| 41 | // CHECK2: __ThumbV7PILongThunk_elsewhere: | |
| 42 | // CHECK2-NEXT: 1000004: 40 f2 20 0c movw r12, #32 | |
| 43 | // CHECK2-NEXT: 1000008: c0 f2 80 0c movt r12, #128 | |
| 44 | // CHECK2-NEXT: 100000c: fc 44 add r12, pc | |
| 45 | // CHECK2-NEXT: 100000e: 60 47 bx r12 | |
| 46 | // CHECK2: __ThumbV7PILongThunk_preemptible: | |
| 47 | // CHECK2-NEXT: 1000010: 40 f2 24 0c movw r12, #36 | |
| 48 | // CHECK2-NEXT: 1000014: c0 f2 80 0c movt r12, #128 | |
| 49 | // CHECK2-NEXT: 1000018: fc 44 add r12, pc | |
| 50 | // CHECK2-NEXT: 100001a: 60 47 bx r12 | |
| 51 | // CHECK2: __ThumbV7PILongThunk_far_preemptible: | |
| 52 | // CHECK2-NEXT: 100001c: 40 f2 28 0c movw r12, #40 | |
| 53 | // CHECK2-NEXT: 1000020: c0 f2 80 0c movt r12, #128 | |
| 54 | // CHECK2-NEXT: 1000024: fc 44 add r12, pc | |
| 55 | // CHECK2-NEXT: 1000026: 60 47 bx r12 | |
| 56 | ||
| 57 | .section .text.3, "ax", %progbits | |
| 58 | .balign 0x0800000 | |
| 59 | far_preemptible: | |
| 60 | bl elsewhere | |
| 61 | // CHECK3: far_preemptible: | |
| 62 | // CHECK3: 1800000: 00 f0 16 e8 blx #44 | |
| 63 | ||
| 64 | // CHECK4: Disassembly of section .plt: | |
| 65 | // CHECK4-NEXT: $a: | |
| 66 | // CHECK4-NEXT: 1800010:	04 e0 2d e5 	str	lr, [sp, #-4]! | |
| 67 | // CHECK4-NEXT: 1800014:	00 e6 8f e2 	add	lr, pc, #0, #12 | |
| 68 | // CHECK4-NEXT: 1800018:	00 ea 8e e2 	add	lr, lr, #0, #20 | |
| 69 | // CHECK4-NEXT: 180001c:	ec ff be e5 	ldr	pc, [lr, #4076]! | |
| 70 | // CHECK4: $d: | |
| 71 | // CHECK4-NEXT: 1800020:	d4 d4 d4 d4 	.word	0xd4d4d4d4 | |
| 72 | // CHECK4-NEXT: 1800024:	d4 d4 d4 d4 	.word	0xd4d4d4d4 | |
| 73 | // CHECK4-NEXT: 1800028:	d4 d4 d4 d4 	.word	0xd4d4d4d4 | |
| 74 | // CHECK4-NEXT: 180002c:	d4 d4 d4 d4 	.word	0xd4d4d4d4 | |
| 75 | // CHECK4: $a: | |
| 76 | // CHECK4-NEXT: 1800030:	00 c6 8f e2 	add	r12, pc, #0, #12 | |
| 77 | // CHECK4-NEXT: 1800034:	00 ca 8c e2 	add	r12, r12, #0, #20 | |
| 78 | // CHECK4-NEXT: 1800038:	d4 ff bc e5 	ldr	pc, [r12, #4052]! | |
| 79 | // CHECK4: $d: | |
| 80 | // CHECK4-NEXT: 180003c:	d4 d4 d4 d4 	.word	0xd4d4d4d4 | |
| 81 | // CHECK4: $a: | |
| 82 | // CHECK4-NEXT: 1800040:	00 c6 8f e2 	add	r12, pc, #0, #12 | |
| 83 | // CHECK4-NEXT: 1800044:	00 ca 8c e2 	add	r12, r12, #0, #20 | |
| 84 | // CHECK4-NEXT: 1800048:	c8 ff bc e5 	ldr	pc, [r12, #4040]! | |
| 85 | // CHECK4: $d: | |
| 86 | // CHECK4-NEXT: 180004c:	d4 d4 d4 d4 	.word	0xd4d4d4d4 | |
| 87 | // CHECK4: $a: | |
| 88 | // CHECK4-NEXT: 1800050:	00 c6 8f e2 	add	r12, pc, #0, #12 | |
| 89 | // CHECK4-NEXT: 1800054:	00 ca 8c e2 	add	r12, r12, #0, #20 | |
| 90 | // CHECK4-NEXT: 1800058:	bc ff bc e5 	ldr	pc, [r12, #4028]! | |
| 91 | // CHECK4: $d: | |
| 92 | // CHECK4-NEXT: 180005c:	d4 d4 d4 d4 	.word	0xd4d4d4d4 |
deps/lld/test/ELF/arm-thumb-plt-reloc.s+37-33| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2 |
| 3 | 3 | // RUN: ld.lld %t1 %t2 -o %t |
| 4 | 4 | // RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t | FileCheck %s |
| 5 | // RUN: ld.lld -shared %t1 %t2 -o %t3 | |
| 5 | // RUN: ld.lld --hash-style=sysv -shared %t1 %t2 -o %t3 | |
| 6 | 6 | // RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOTHUMB %s |
| 7 | 7 | // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOARM %s |
| 8 | 8 | // RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s |
| ... | ... | @@ -43,50 +43,54 @@ _start: |
| 43 | 43 | // .text is Thumb and .plt is ARM, llvm-objdump can currently only disassemble |
| 44 | 44 | // as ARM or Thumb. Work around by disassembling twice. |
| 45 | 45 | // DSOTHUMB: Disassembly of section .text: |
| 46 | // DSOTHUMB: func1: | |
| 47 | // DSOTHUMB-NEXT: 1000: 70 47 bx lr | |
| 46 | // DSOTHUMB-NEXT: func1: | |
| 47 | // DSOTHUMB-NEXT: 1000: 70 47 bx lr | |
| 48 | 48 | // DSOTHUMB: func2: |
| 49 | // DSOTHUMB-NEXT: 1002: 70 47 bx lr | |
| 49 | // DSOTHUMB-NEXT: 1002: 70 47 bx lr | |
| 50 | 50 | // DSOTHUMB: func3: |
| 51 | // DSOTHUMB-NEXT: 1004: 70 47 bx lr | |
| 52 | // DSOTHUMB-NEXT: 1006: d4 d4 | |
| 51 | // DSOTHUMB-NEXT: 1004: 70 47 bx lr | |
| 52 | // DSOTHUMB-NEXT: 1006: d4 d4 bmi #-88 | |
| 53 | 53 | // DSOTHUMB: _start: |
| 54 | // 0x1008 + 0x28 + 4 = 0x1034 = PLT func1 | |
| 55 | // DSOTHUMB-NEXT: 1008: 00 f0 14 e8 blx #40 | |
| 56 | // 0x100c + 0x34 + 4 = 0x1044 = PLT func2 | |
| 57 | // DSOTHUMB-NEXT: 100c: 00 f0 1a e8 blx #52 | |
| 58 | // 0x1010 + 0x40 + 4 = 0x1054 = PLT func3 | |
| 59 | // DSOTHUMB-NEXT: 1010: 00 f0 20 e8 blx #64 | |
| 54 | // 0x1008 + 0x34 + 4 = 0x1040 = PLT func1 | |
| 55 | // DSOTHUMB-NEXT: 1008: 00 f0 1a e8 blx #52 | |
| 56 | // 0x100c + 0x40 + 4 = 0x1050 = PLT func2 | |
| 57 | // DSOTHUMB-NEXT: 100c: 00 f0 20 e8 blx #64 | |
| 58 | // 0x1010 + 0x4C + 4 = 0x1060 = PLT func3 | |
| 59 | // DSOTHUMB-NEXT: 1010: 00 f0 26 e8 blx #76 | |
| 60 | 60 | // DSOARM: Disassembly of section .plt: |
| 61 | 61 | // DSOARM-NEXT: $a: |
| 62 | // DSOARM-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]! | |
| 63 | // DSOARM-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4] | |
| 64 | // DSOARM-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr | |
| 65 | // DSOARM-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]! | |
| 62 | // DSOARM-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]! | |
| 63 | // (0x1024 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfdc) = 0x2008 = .got.plt[3] | |
| 64 | // DSOARM-NEXT: 1024: 00 e6 8f e2 add lr, pc, #0, #12 | |
| 65 | // DSOARM-NEXT: 1028: 00 ea 8e e2 add lr, lr, #0, #20 | |
| 66 | // DSOARM-NEXT: 102c: dc ff be e5 ldr pc, [lr, #4060]! | |
| 66 | 67 | // DSOARM: $d: |
| 67 | // DSOARM-NEXT: 1030: d0 0f 00 00 .word 0x00000fd0 | |
| 68 | // 0x1028 + 8 + 0fd0 = 0x2000 | |
| 68 | ||
| 69 | // DSOARM-NEXT: 1030: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 70 | // DSOARM-NEXT: 1034: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 71 | // DSOARM-NEXT: 1038: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 72 | // DSOARM-NEXT: 103c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 69 | 73 | // DSOARM: $a: |
| 70 | // DSOARM-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 71 | // DSOARM-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc | |
| 72 | // DSOARM-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12] | |
| 74 | // (0x1040 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfc4) = 0x200c | |
| 75 | // DSOARM-NEXT: 1040: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 76 | // DSOARM-NEXT: 1044: 00 ca 8c e2 add r12, r12, #0, #20 | |
| 77 | // DSOARM-NEXT: 1048: c4 ff bc e5 ldr pc, [r12, #4036]! | |
| 73 | 78 | // DSOARM: $d: |
| 74 | // DSOARM-NEXT: 1040: cc 0f 00 00 .word 0x00000fcc | |
| 75 | // 0x1038 + 8 + 0fcc = 0x200c | |
| 79 | // DSOARM-NEXT: 104c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 76 | 80 | // DSOARM: $a: |
| 77 | // DSOARM-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 78 | // DSOARM-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc | |
| 79 | // DSOARM-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12] | |
| 81 | // (0x1050 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfb8) = 0x2010 | |
| 82 | // DSOARM-NEXT: 1050: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 83 | // DSOARM-NEXT: 1054: 00 ca 8c e2 add r12, r12, #0, #20 | |
| 84 | // DSOARM-NEXT: 1058: b8 ff bc e5 ldr pc, [r12, #4024]! | |
| 80 | 85 | // DSOARM: $d: |
| 81 | // DSOARM-NEXT: 1050: c0 0f 00 00 .word 0x00000fc0 | |
| 82 | // 0x1048 + 8 + 0fc0 = 0x2010 | |
| 86 | // DSOARM-NEXT: 105c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 83 | 87 | // DSOARM: $a: |
| 84 | // DSOARM-NEXT: 1054: 04 c0 9f e5 ldr r12, [pc, #4] | |
| 85 | // DSOARM-NEXT: 1058: 0f c0 8c e0 add r12, r12, pc | |
| 86 | // DSOARM-NEXT: 105c: 00 f0 9c e5 ldr pc, [r12] | |
| 88 | // (0x1060 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfac) = 0x2014 | |
| 89 | // DSOARM-NEXT: 1060: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 90 | // DSOARM-NEXT: 1064: 00 ca 8c e2 add r12, r12, #0, #20 | |
| 91 | // DSOARM-NEXT: 1068: ac ff bc e5 ldr pc, [r12, #4012]! | |
| 87 | 92 | // DSOARM: $d: |
| 88 | // DSOARM-NEXT: 1060: b4 0f 00 00 .word 0x00000fb4 | |
| 89 | // 0x1058 + 8 + 0fb4 = 0x2014 | |
| 93 | // DSOARM-NEXT: 106c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 90 | 94 | |
| 91 | 95 | // DSOREL: Name: .got.plt |
| 92 | 96 | // DSOREL-NEXT: Type: SHT_PROGBITS |
deps/lld/test/ELF/arm-thumb-range-thunk-os.s created+159| ... | ... | @@ -0,0 +1,159 @@ |
| 1 | // REQUIRES: arm | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | |
| 3 | // RUN: ld.lld %t -o %t2 2>&1 | |
| 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 | |
| 6 | // RUN: llvm-objdump -d %t2 -start-address=1048576 -stop-address=1048588 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s | |
| 7 | // RUN: llvm-objdump -d %t2 -start-address=2097152 -stop-address=2097154 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s | |
| 8 | // RUN: llvm-objdump -d %t2 -start-address=3145728 -stop-address=3145730 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %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 | |
| 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 | |
| 13 | // RUN: llvm-objdump -d %t2 -start-address=32505860 -stop-address=32505880 -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 | |
| 15 | // RUN: llvm-objdump -d %t2 -start-address=36700160 -stop-address=36700170 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK10 %s | |
| 16 | ||
| 17 | // Test the Range extension Thunks for Thumb when all the code is in a single | |
| 18 | // OutputSection. The Thumb unconditional branch b.w and branch and link bl | |
| 19 | // instructions have a range of 16Mb. We create a series of Functions a | |
| 20 | // megabyte apart. We expect range extension thunks to be created when a | |
| 21 | // branch is out of range. Thunks will be reused whenever they are in range | |
| 22 | .syntax unified | |
| 23 | ||
| 24 | // Define a function aligned on a megabyte boundary | |
| 25 | .macro FUNCTION suff | |
| 26 | .section .text.\suff\(), "ax", %progbits | |
| 27 | .thumb | |
| 28 | .balign 0x100000 | |
| 29 | .globl tfunc\suff\() | |
| 30 | .type tfunc\suff\(), %function | |
| 31 | tfunc\suff\(): | |
| 32 | bx lr | |
| 33 | .endm | |
| 34 | ||
| 35 | .section .text, "ax", %progbits | |
| 36 | .thumb | |
| 37 | .globl _start | |
| 38 | _start: | |
| 39 | // tfunc00 and tfunc15 are within 16Mb no Range Thunks expected | |
| 40 | bl tfunc00 | |
| 41 | bl tfunc15 | |
| 42 | // tfunc16 is > 16Mb away, expect a Range Thunk to be generated, to go into | |
| 43 | // the first of the pre-created ThunkSections. | |
| 44 | bl tfunc16 | |
| 45 | // CHECK1: Disassembly of section .text: | |
| 46 | // CHECK1-NEXT: _start: | |
| 47 | // CHECK1-NEXT: 100000: ff f0 fe ff bl #1048572 | |
| 48 | // CHECK1-NEXT: 100004: ff f3 fc d7 bl #16777208 | |
| 49 | // CHECK1-NEXT: 100008: ff f2 fc d7 bl #15728632 | |
| 50 | ||
| 51 | FUNCTION 00 | |
| 52 | // CHECK2: tfunc00: | |
| 53 | // CHECK2-NEXT: 200000: 70 47 bx lr | |
| 54 | FUNCTION 01 | |
| 55 | // CHECK3: tfunc01: | |
| 56 | // CHECK3-NEXT: 300000: 70 47 bx lr | |
| 57 | FUNCTION 02 | |
| 58 | // tfunc28 is > 16Mb away, expect a Range Thunk to be generated, to go into | |
| 59 | // the first of the pre-created ThunkSections. | |
| 60 | b.w tfunc28 | |
| 61 | // CHECK4: tfunc02: | |
| 62 | // CHECK4-NEXT: 400000: 70 47 bx lr | |
| 63 | // CHECK4-NEXT: 400002: 00 f0 04 90 b.w #12582920 <__Thumbv7ABSLongThunk_tfunc28> | |
| 64 | FUNCTION 03 | |
| 65 | FUNCTION 04 | |
| 66 | FUNCTION 05 | |
| 67 | FUNCTION 06 | |
| 68 | FUNCTION 07 | |
| 69 | FUNCTION 08 | |
| 70 | FUNCTION 09 | |
| 71 | FUNCTION 10 | |
| 72 | FUNCTION 11 | |
| 73 | FUNCTION 12 | |
| 74 | FUNCTION 13 | |
| 75 | FUNCTION 14 | |
| 76 | // Expect precreated ThunkSection here | |
| 77 | // CHECK5: __Thumbv7ABSLongThunk_tfunc16: | |
| 78 | // CHECK5-NEXT: 1000004: 40 f2 01 0c movw r12, #1 | |
| 79 | // CHECK5-NEXT: 1000008: c0 f2 20 1c movt r12, #288 | |
| 80 | // CHECK5-NEXT: 100000c: 60 47 bx r12 | |
| 81 | // CHECK5: __Thumbv7ABSLongThunk_tfunc28: | |
| 82 | // CHECK5-NEXT: 100000e: 40 f2 01 0c movw r12, #1 | |
| 83 | // CHECK5-NEXT: 1000012: c0 f2 e0 1c movt r12, #480 | |
| 84 | // CHECK5-NEXT: 1000016: 60 47 bx r12 | |
| 85 | // CHECK5: __Thumbv7ABSLongThunk_tfunc32: | |
| 86 | // CHECK5-NEXT: 1000018: 40 f2 01 0c movw r12, #1 | |
| 87 | // CHECK5-NEXT: 100001c: c0 f2 20 2c movt r12, #544 | |
| 88 | // CHECK5-NEXT: 1000020: 60 47 bx r12 | |
| 89 | // CHECK5: __Thumbv7ABSLongThunk_tfunc33: | |
| 90 | // CHECK5-NEXT: 1000022: 40 f2 01 0c movw r12, #1 | |
| 91 | // CHECK5-NEXT: 1000026: c0 f2 30 2c movt r12, #560 | |
| 92 | // CHECK5-NEXT: 100002a: 60 47 bx r12 | |
| 93 | // CHECK5: __Thumbv7ABSLongThunk_tfunc02: | |
| 94 | // CHECK5-NEXT: 100002c: 40 f2 01 0c movw r12, #1 | |
| 95 | // CHECK5-NEXT: 1000030: c0 f2 40 0c movt r12, #64 | |
| 96 | // CHECK5-NEXT: 1000034: 60 47 bx r12 | |
| 97 | FUNCTION 15 | |
| 98 | // tfunc00 and tfunc01 are < 16Mb away, expect no range extension thunks | |
| 99 | bl tfunc00 | |
| 100 | bl tfunc01 | |
| 101 | // tfunc32 and tfunc33 are > 16Mb away, expect range extension thunks in the | |
| 102 | // precreated thunk section | |
| 103 | bl tfunc32 | |
| 104 | bl tfunc33 | |
| 105 | // CHECK6: tfunc15: | |
| 106 | // CHECK6-NEXT: 1100000: 70 47 bx lr | |
| 107 | // CHECK6-NEXT: 1100002: ff f4 fd d7 bl #-15728646 | |
| 108 | // CHECK6-NEXT: 1100006: ff f5 fb d7 bl #-14680074 | |
| 109 | // CHECK6-NEXT: 110000a: 00 f7 05 f8 bl #-1048566 | |
| 110 | // CHECK6-NEXT: 110000e: 00 f7 08 f8 bl #-1048560 | |
| 111 | FUNCTION 16 | |
| 112 | FUNCTION 17 | |
| 113 | FUNCTION 18 | |
| 114 | FUNCTION 19 | |
| 115 | FUNCTION 20 | |
| 116 | FUNCTION 21 | |
| 117 | FUNCTION 22 | |
| 118 | FUNCTION 23 | |
| 119 | FUNCTION 24 | |
| 120 | FUNCTION 25 | |
| 121 | FUNCTION 26 | |
| 122 | FUNCTION 27 | |
| 123 | FUNCTION 28 | |
| 124 | // tfunc02 is > 16Mb away, expect range extension thunks in precreated thunk | |
| 125 | // section | |
| 126 | // CHECK7: tfunc28: | |
| 127 | // CHECK7-NEXT: 1e00000: 70 47 bx lr | |
| 128 | // CHECK7-NEXT: 1e00002: 00 f6 13 90 b.w #-14680026 <__Thumbv7ABSLongThunk_tfunc02> | |
| 129 | ||
| 130 | b.w tfunc02 | |
| 131 | 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 | |
| 142 | FUNCTION 31 | |
| 143 | FUNCTION 32 | |
| 144 | // tfunc15 and tfunc16 are > 16 Mb away expect Thunks in the nearest | |
| 145 | // precreated thunk section. | |
| 146 | bl tfunc15 | |
| 147 | bl tfunc16 | |
| 148 | // CHECK9: tfunc32: | |
| 149 | // CHECK9: 2200000: 70 47 bx lr | |
| 150 | // CHECK9-NEXT: 2200002: ff f4 ff ff bl #-3145730 | |
| 151 | // CHECK9-NEXT: 2200006: 00 f5 02 f8 bl #-3145724 | |
| 152 | ||
| 153 | FUNCTION 33 | |
| 154 | bl tfunc15 | |
| 155 | bl tfunc16 | |
| 156 | // CHECK10: tfunc33: | |
| 157 | // CHECK10: 2300000: 70 47 bx lr | |
| 158 | // CHECK10-NEXT: 2300002: ff f7 ff f7 bl #-4194306 | |
| 159 | // CHECK10-NEXT: 2300006: 00 f4 02 f8 bl #-4194300 |
deps/lld/test/ELF/arm-thumb-thunk-empty-pass.s created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | // REQUIRES: arm | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | |
| 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 | |
| 5 | // RUN: llvm-objdump -d %t2 -start-address=16846860 -stop-address=16846874 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s | |
| 6 | .syntax unified | |
| 7 | .global _start, foo | |
| 8 | .type _start, %function | |
| 9 | .section .text.start,"ax",%progbits | |
| 10 | _start: | |
| 11 | bl _start | |
| 12 | .section .text.dummy1,"ax",%progbits | |
| 13 | .space 0xfffffe | |
| 14 | .section .text.foo,"ax",%progbits | |
| 15 | .type foo, %function | |
| 16 | foo: | |
| 17 | bl _start | |
| 18 | ||
| 19 | // CHECK1: Disassembly of section .text: | |
| 20 | // CHECK1-NEXT: _start: | |
| 21 | // CHECK1-NEXT: 11000: ff f7 fe ff bl #-4 | |
| 22 | // CHECK1: __Thumbv7ABSLongThunk__start: | |
| 23 | // CHECK1-NEXT: 11004: 41 f2 01 0c movw r12, #4097 | |
| 24 | // CHECK1-NEXT: 11008: c0 f2 01 0c movt r12, #1 | |
| 25 | // CHECK1-NEXT: 1100c: 60 47 bx r12 | |
| 26 | ||
| 27 | // CHECK2: __Thumbv7ABSLongThunk__start: | |
| 28 | // CHECK2: 101100c: 41 f2 01 0c movw r12, #4097 | |
| 29 | // CHECK2-NEXT: 1011010: c0 f2 01 0c movt r12, #1 | |
| 30 | // CHECK2-NEXT: 1011014: 60 47 bx r12 | |
| 31 | // CHECK2: foo: | |
| 32 | // CHECK2-NEXT: 1011016: ff f7 f9 ff bl #-14 |
deps/lld/test/ELF/arm-thumb-thunk-symbols.s+3-3| ... | ... | @@ -25,18 +25,18 @@ arm_fn: |
| 25 | 25 | b thumb_fn |
| 26 | 26 | |
| 27 | 27 | // CHECK: Name: __Thumbv7ABSLongThunk_arm_fn |
| 28 | // CHECK-NEXT: Value: 0x11005 | |
| 28 | // CHECK-NEXT: Value: 0x12005 | |
| 29 | 29 | // CHECK-NEXT: Size: 10 |
| 30 | 30 | // CHECK-NEXT: Binding: Local (0x0) |
| 31 | 31 | // CHECK-NEXT: Type: Function (0x2) |
| 32 | 32 | // CHECK: Name: __ARMv7ABSLongThunk_thumb_fn |
| 33 | // CHECK-NEXT: Value: 0x11010 | |
| 33 | // CHECK-NEXT: Value: 0x12010 | |
| 34 | 34 | // CHECK-NEXT: Size: 12 |
| 35 | 35 | // CHECK-NEXT: Binding: Local (0x0) |
| 36 | 36 | // CHECK-NEXT: Type: Function (0x2) |
| 37 | 37 | |
| 38 | 38 | // CHECK-PI: Name: __ThumbV7PILongThunk_arm_fn |
| 39 | // CHECK-PI-NEXT: Value: 0x1005 | |
| 39 | // CHECK-PI-NEXT: Value: 0x2005 | |
| 40 | 40 | // CHECK-PI-NEXT: Size: 12 |
| 41 | 41 | // CHECK-PI-NEXT: Binding: Local (0x0) |
| 42 | 42 | // CHECK-PI-NEXT: Type: Function (0x2) |
deps/lld/test/ELF/arm-thunk-edgecase.s created+37| ... | ... | @@ -0,0 +1,37 @@ |
| 1 | // REQUIRES: arm | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | |
| 3 | // RUN: echo "SECTIONS { \ | |
| 4 | // RUN: .text_armfunc 0x1000 : { *(.text_armfunc) } \ | |
| 5 | // RUN: .text_thumbfunc 0x11010 : { *(.text_thumbfunc) } \ | |
| 6 | // RUN: }" > %tarm_to_thumb.script | |
| 7 | // RUN: echo "SECTIONS { \ | |
| 8 | // RUN: .text_thumbfunc 0x1000 : { *(.text_thumbfunc) } \ | |
| 9 | // RUN: .text_armfunc 0x1100c : { *(.text_armfunc) } \ | |
| 10 | // RUN: }" > %tthumb_to_arm.script | |
| 11 | // RUN: ld.lld -shared -Bsymbolic -script %tarm_to_thumb.script %t.o -o %tarm_to_thumb.so | |
| 12 | // RUN: ld.lld -shared -Bsymbolic -script %tthumb_to_arm.script %t.o -o %tthumb_to_arm.so | |
| 13 | // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %tarm_to_thumb.so | FileCheck -check-prefix=ARM-TO-THUMB %s | |
| 14 | // RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %tthumb_to_arm.so | FileCheck -check-prefix=THUMB-TO-ARM %s | |
| 15 | ||
| 16 | .syntax unified | |
| 17 | ||
| 18 | .arm | |
| 19 | .section .text_armfunc, "ax", %progbits | |
| 20 | .globl armfunc | |
| 21 | armfunc: | |
| 22 | 	b	thumbfunc | |
| 23 | ||
| 24 | .thumb | |
| 25 | .section .text_thumbfunc, "ax", %progbits | |
| 26 | .globl thumbfunc | |
| 27 | .thumb_func | |
| 28 | thumbfunc: | |
| 29 | 	b.w	armfunc | |
| 30 | ||
| 31 | // ARM-TO-THUMB: __ARMV7PILongThunk_thumbfunc: | |
| 32 | // ARM-TO-THUMB-NEXT: 1004: fd cf 0f e3 movw r12, #65533 | |
| 33 | // ARM-TO-THUMB-NEXT: 1008: 00 c0 40 e3 movt r12, #0 | |
| 34 | ||
| 35 | // THUMB-TO-ARM: __ThumbV7PILongThunk_armfunc: | |
| 36 | // THUMB-TO-ARM-NEXT: 1004: 4f f6 fc 7c movw r12, #65532 | |
| 37 | // THUMB-TO-ARM-NEXT: 1008: c0 f2 00 0c movt r12, #0 |
deps/lld/test/ELF/arm-thunk-largesection.s created+42| ... | ... | @@ -0,0 +1,42 @@ |
| 1 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | |
| 2 | // 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=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=33628160 -stop-address=33628164 %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 | // REQUIRES: arm | |
| 9 | .syntax unified | |
| 10 | .balign 0x1000 | |
| 11 | .thumb | |
| 12 | .text | |
| 13 | .globl _start | |
| 14 | .type _start, %function | |
| 15 | _start: | |
| 16 | bx lr | |
| 17 | .space 0x1000 | |
| 18 | // CHECK1: Disassembly of section .text: | |
| 19 | // CHECK1-NEXT: _start: | |
| 20 | // CHECK1-NEXT: 11000: 70 47 bx lr | |
| 21 | // CHECK1-NEXT: 11002: 00 00 movs r0, r0 | |
| 22 | ||
| 23 | // CHECK2: __Thumbv7ABSLongThunk__start: | |
| 24 | // CHECK2-NEXT: 12004: 41 f2 01 0c movw r12, #4097 | |
| 25 | // CHECK2-NEXT: 12008: c0 f2 01 0c movt r12, #1 | |
| 26 | // CHECK2-NEXT: 1200c: 60 47 bx r12 | |
| 27 | ||
| 28 | // Gigantic section where we need a ThunkSection either side of it | |
| 29 | .section .text.large1, "ax", %progbits | |
| 30 | .balign 4 | |
| 31 | .space (16 * 1024 * 1024) - 16 | |
| 32 | bl _start | |
| 33 | .space (16 * 1024 * 1024) - 4 | |
| 34 | bl _start | |
| 35 | .space (16 * 1024 * 1024) - 16 | |
| 36 | // CHECK3: 1012000: 00 f4 00 d0 bl #-16777216 | |
| 37 | // CHECK4: 2012000: ff f3 f8 d7 bl #16777200 | |
| 38 | ||
| 39 | // CHECK5: __Thumbv7ABSLongThunk__start: | |
| 40 | // CHECK5-NEXT: 3011ff4: 41 f2 01 0c movw r12, #4097 | |
| 41 | // CHECK5-NEXT: 3011ff8: c0 f2 01 0c movt r12, #1 | |
| 42 | // CHECK5-NEXT: 3011ffc: 60 47 bx r12 |
deps/lld/test/ELF/arm-thunk-linkerscript-dotexpr.s created+77| ... | ... | @@ -0,0 +1,77 @@ |
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | |
| 2 | // RUN: echo "SECTIONS { \ | |
| 3 | // RUN: . = SIZEOF_HEADERS; \ | |
| 4 | // RUN: .text_low : { *(.text_low) *(.text_low2) . = . + 0x2000000 ; *(.text_high) *(.text_high2) } \ | |
| 5 | // RUN: } " > %t.script | |
| 6 | // 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=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 | |
| 11 | // a Section Description | |
| 12 | .syntax unified | |
| 13 | .section .text_low, "ax", %progbits | |
| 14 | .thumb | |
| 15 | .globl _start | |
| 16 | _start: bx lr | |
| 17 | .globl low_target | |
| 18 | .type low_target, %function | |
| 19 | low_target: | |
| 20 | bl high_target | |
| 21 | bl high_target2 | |
| 22 | ||
| 23 | .section .text_low2, "ax", %progbits | |
| 24 | .thumb | |
| 25 | .globl low_target2 | |
| 26 | .type low_target2, %function | |
| 27 | low_target2: | |
| 28 | bl high_target | |
| 29 | bl high_target2 | |
| 30 | // CHECK1: Disassembly of section .text_low: | |
| 31 | // CHECK1-NEXT: _start: | |
| 32 | // CHECK1-NEXT: 94: 70 47 bx lr | |
| 33 | // CHECK1: low_target: | |
| 34 | // CHECK1-NEXT: 96: 00 f0 03 f8 bl #6 | |
| 35 | // CHECK1-NEXT: 9a: 00 f0 06 f8 bl #12 | |
| 36 | // CHECK1: __Thumbv7ABSLongThunk_high_target: | |
| 37 | // CHECK1-NEXT: a0: 40 f2 bd 0c movw r12, #189 | |
| 38 | // CHECK1-NEXT: a4: c0 f2 00 2c movt r12, #512 | |
| 39 | // CHECK1-NEXT: a8: 60 47 bx r12 | |
| 40 | // CHECK1: __Thumbv7ABSLongThunk_high_target2: | |
| 41 | // CHECK1-NEXT: aa: 40 f2 d9 0c movw r12, #217 | |
| 42 | // CHECK1-NEXT: ae: c0 f2 00 2c movt r12, #512 | |
| 43 | // CHECK1-NEXT: b2: 60 47 bx r12 | |
| 44 | // CHECK1: low_target2: | |
| 45 | // CHECK1-NEXT: b4: ff f7 f4 ff bl #-24 | |
| 46 | // CHECK1-NEXT: b8: ff f7 f7 ff bl #-18 | |
| 47 | ||
| 48 | .section .text_high, "ax", %progbits | |
| 49 | .thumb | |
| 50 | .globl high_target | |
| 51 | .type high_target, %function | |
| 52 | high_target: | |
| 53 | bl low_target | |
| 54 | bl low_target2 | |
| 55 | ||
| 56 | .section .text_high2, "ax", %progbits | |
| 57 | .thumb | |
| 58 | .globl high_target2 | |
| 59 | .type high_target2, %function | |
| 60 | high_target2: | |
| 61 | bl low_target | |
| 62 | bl low_target2 | |
| 63 | ||
| 64 | // CHECK2: high_target: | |
| 65 | // CHECK2-NEXT: 20000bc: 00 f0 02 f8 bl #4 | |
| 66 | // CHECK2-NEXT: 20000c0: 00 f0 05 f8 bl #10 | |
| 67 | // CHECK2: __Thumbv7ABSLongThunk_low_target: | |
| 68 | // CHECK2-NEXT: 20000c4: 40 f2 97 0c movw r12, #151 | |
| 69 | // CHECK2-NEXT: 20000c8: c0 f2 00 0c movt r12, #0 | |
| 70 | // CHECK2-NEXT: 20000cc: 60 47 bx r12 | |
| 71 | // CHECK2: __Thumbv7ABSLongThunk_low_target2: | |
| 72 | // CHECK2-NEXT: 20000ce: 40 f2 b5 0c movw r12, #181 | |
| 73 | // CHECK2-NEXT: 20000d2: c0 f2 00 0c movt r12, #0 | |
| 74 | // CHECK2-NEXT: 20000d6: 60 47 bx r12 | |
| 75 | // CHECK2: high_target2: | |
| 76 | // CHECK2-NEXT: 20000d8: ff f7 f4 ff bl #-24 | |
| 77 | // CHECK2-NEXT: 20000dc: ff f7 f7 ff bl #-18 |
deps/lld/test/ELF/arm-thunk-linkerscript-large.s created+176| ... | ... | @@ -0,0 +1,176 @@ |
| 1 | // REQUIRES: arm | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | |
| 3 | // RUN: echo "SECTIONS { \ | |
| 4 | // RUN: .text 0x100000 : { *(.text) } \ | |
| 5 | // RUN: .textl : { *(.text_l0*) *(.text_l1*) *(.text_l2*) *(.text_l3*) } \ | |
| 6 | // RUN: .texth : { *(.text_h0*) *(.text_h1*) *(.text_h2*) *(.text_h3*) } \ | |
| 7 | // RUN: }" > %t.script | |
| 8 | // RUN: ld.lld --script %t.script %t -o %t2 2>&1 | |
| 9 | // The output file is large, most of it zeroes. We dissassemble only the | |
| 10 | // parts we need to speed up the test and avoid a large output file | |
| 11 | // RUN: llvm-objdump -d %t2 -start-address=1048576 -stop-address=1048594 -triple=thumbv7a-linux-gnueabihf | FileCheck --check-prefix=CHECK1 %s | |
| 12 | // RUN: llvm-objdump -d %t2 -start-address=2097152 -stop-address=2097160 -triple=thumbv7a-linux-gnueabihf | FileCheck --check-prefix=CHECK2 %s | |
| 13 | // RUN: llvm-objdump -d %t2 -start-address=11534340 -stop-address=11534350 -triple=thumbv7a-linux-gnueabihf | FileCheck --check-prefix=CHECK3 %s | |
| 14 | // RUN: llvm-objdump -d %t2 -start-address=34603008 -stop-address=34603034 -triple=thumbv7a-linux-gnueabihf | FileCheck --check-prefix=CHECK4 %s | |
| 15 | // RUN: llvm-objdump -d %t2 -start-address=35651584 -stop-address=35651598 -triple=thumbv7a-linux-gnueabihf | FileCheck --check-prefix=CHECK5 %s | |
| 16 | // RUN: llvm-objdump -d %t2 -start-address=68157440 -stop-address=68157472 -triple=thumbv7a-linux-gnueabihf | FileCheck --check-prefix=CHECK6 %s | |
| 17 | ||
| 18 | // Test the range extensions in a linker script where there are several | |
| 19 | // OutputSections requiring range extension Thunks. We should be able to reuse | |
| 20 | // Thunks between OutputSections but our placement of new Thunks is done on a | |
| 21 | // per OutputSection basis | |
| 22 | .syntax unified | |
| 23 | ||
| 24 | // Define a function that we can match with .text_l* aligned on a megabyte // boundary | |
| 25 | .macro FUNCTIONL suff | |
| 26 | .section .text_l\suff\(), "ax", %progbits | |
| 27 | .thumb | |
| 28 | .balign 0x100000 | |
| 29 | .globl tfuncl\suff\() | |
| 30 | .type tfuncl\suff\(), %function | |
| 31 | tfuncl\suff\(): | |
| 32 | bx lr | |
| 33 | .endm | |
| 34 | ||
| 35 | // Define a function that we can match with .text_h* aligned on a megabyte | |
| 36 | // boundary | |
| 37 | .macro FUNCTIONH suff | |
| 38 | .section .text_h\suff\(), "ax", %progbits | |
| 39 | .thumb | |
| 40 | .balign 0x100000 | |
| 41 | .globl tfunch\suff\() | |
| 42 | .type tfunch\suff\(), %function | |
| 43 | tfunch\suff\(): | |
| 44 | bx lr | |
| 45 | .endm | |
| 46 | ||
| 47 | .section .text, "ax", %progbits | |
| 48 | .thumb | |
| 49 | .globl _start | |
| 50 | _start: | |
| 51 | bl tfuncl00 | |
| 52 | // Expect a range extension thunk in .text OutputSection | |
| 53 | bl tfunch31 | |
| 54 | // CHECK1: Disassembly of section .text: | |
| 55 | // CHECK1-NEXT: _start: | |
| 56 | // CHECK1-NEXT: 100000: ff f0 fe ff bl #1048572 | |
| 57 | // CHECK1-NEXT: 100004: 00 f0 00 f8 bl #0 | |
| 58 | // CHECK1: __Thumbv7ABSLongThunk_tfunch31: | |
| 59 | // CHECK1-NEXT: 100008: 40 f2 01 0c movw r12, #1 | |
| 60 | // CHECK1-NEXT: 10000c: c0 f2 10 4c movt r12, #1040 | |
| 61 | // CHECK1-NEXT: 100010: 60 47 bx r12 | |
| 62 | FUNCTIONL 00 | |
| 63 | // Create a range extension thunk in .textl | |
| 64 | bl tfuncl24 | |
| 65 | // We can reuse existing thunk in .text | |
| 66 | bl tfunch31 | |
| 67 | // CHECK2: Disassembly of section .textl: | |
| 68 | // CHECK2-NEXT: tfuncl00: | |
| 69 | // CHECK2-NEXT: 200000:	70 47 	bx	lr | |
| 70 | // CHECK2-NEXT: 200002:	ff f0 ff df 	bl	#9437182 | |
| 71 | // CHECK2-NEXT: 200006:	ff f6 ff ff 	bl	#-1048578 | |
| 72 | FUNCTIONL 01 | |
| 73 | FUNCTIONL 02 | |
| 74 | FUNCTIONL 03 | |
| 75 | FUNCTIONL 04 | |
| 76 | FUNCTIONL 05 | |
| 77 | FUNCTIONL 06 | |
| 78 | FUNCTIONL 07 | |
| 79 | FUNCTIONL 08 | |
| 80 | FUNCTIONL 09 | |
| 81 | // CHECK3: __Thumbv7ABSLongThunk_tfuncl24: | |
| 82 | // CHECK3-NEXT: b00004:	40 f2 01 0c 	movw	r12, #1 | |
| 83 | // CHECK3-NEXT: b00008:	c0 f2 a0 1c 	movt	r12, #416 | |
| 84 | // CHECK3-NEXT: b0000c:	60 47 	bx	r12 | |
| 85 | FUNCTIONL 10 | |
| 86 | FUNCTIONL 11 | |
| 87 | FUNCTIONL 12 | |
| 88 | FUNCTIONL 13 | |
| 89 | FUNCTIONL 14 | |
| 90 | FUNCTIONL 15 | |
| 91 | FUNCTIONL 16 | |
| 92 | FUNCTIONL 17 | |
| 93 | FUNCTIONL 18 | |
| 94 | FUNCTIONL 19 | |
| 95 | FUNCTIONL 20 | |
| 96 | FUNCTIONL 21 | |
| 97 | FUNCTIONL 22 | |
| 98 | FUNCTIONL 23 | |
| 99 | FUNCTIONL 24 | |
| 100 | FUNCTIONL 25 | |
| 101 | FUNCTIONL 26 | |
| 102 | FUNCTIONL 27 | |
| 103 | FUNCTIONL 28 | |
| 104 | FUNCTIONL 29 | |
| 105 | FUNCTIONL 30 | |
| 106 | FUNCTIONL 31 | |
| 107 | // Create range extension thunks in .textl | |
| 108 | bl tfuncl00 | |
| 109 | bl tfuncl24 | |
| 110 | // Shouldn't need a thunk | |
| 111 | bl tfunch00 | |
| 112 | // CHECK4: 2100002: 00 f0 05 f8 bl #10 | |
| 113 | // CHECK4-NEXT: 2100006: ff f4 fb f7 bl #-7340042 | |
| 114 | // CHECK4-NEXT: 210000a: ff f0 f9 ff bl #1048562 | |
| 115 | // CHECK4: __Thumbv7ABSLongThunk_tfuncl00: | |
| 116 | // CHECK4-NEXT: 2100010: 40 f2 01 0c movw r12, #1 | |
| 117 | // CHECK4-NEXT: 2100014: c0 f2 20 0c movt r12, #32 | |
| 118 | // CHECK4-NEXT: 2100018: 60 47 bx r12 | |
| 119 | FUNCTIONH 00 | |
| 120 | // Can reuse existing thunks in .textl | |
| 121 | bl tfuncl00 | |
| 122 | bl tfuncl24 | |
| 123 | // Shouldn't need a thunk | |
| 124 | bl tfuncl31 | |
| 125 | // CHECK5: Disassembly of section .texth: | |
| 126 | // CHECK5-NEXT: tfunch00: | |
| 127 | // CHECK5-NEXT: 2200000: 70 47 bx lr | |
| 128 | // CHECK5-NEXT: 2200002: 00 f7 05 f8 bl #-1048566 | |
| 129 | // CHECK5-NEXT: 2200006: ff f7 fb df bl #-8388618 | |
| 130 | // CHECK5-NEXT: 220000a: ff f6 f9 ff bl #-1048590 | |
| 131 | FUNCTIONH 01 | |
| 132 | FUNCTIONH 02 | |
| 133 | FUNCTIONH 03 | |
| 134 | FUNCTIONH 04 | |
| 135 | FUNCTIONH 05 | |
| 136 | FUNCTIONH 06 | |
| 137 | FUNCTIONH 07 | |
| 138 | FUNCTIONH 08 | |
| 139 | FUNCTIONH 09 | |
| 140 | FUNCTIONH 10 | |
| 141 | FUNCTIONH 11 | |
| 142 | FUNCTIONH 12 | |
| 143 | FUNCTIONH 13 | |
| 144 | FUNCTIONH 14 | |
| 145 | FUNCTIONH 15 | |
| 146 | FUNCTIONH 16 | |
| 147 | FUNCTIONH 17 | |
| 148 | FUNCTIONH 18 | |
| 149 | FUNCTIONH 19 | |
| 150 | FUNCTIONH 20 | |
| 151 | FUNCTIONH 21 | |
| 152 | FUNCTIONH 22 | |
| 153 | FUNCTIONH 23 | |
| 154 | FUNCTIONH 24 | |
| 155 | FUNCTIONH 25 | |
| 156 | FUNCTIONH 26 | |
| 157 | FUNCTIONH 27 | |
| 158 | FUNCTIONH 28 | |
| 159 | FUNCTIONH 29 | |
| 160 | FUNCTIONH 30 | |
| 161 | FUNCTIONH 31 | |
| 162 | // expect Thunks in .texth | |
| 163 | bl tfuncl00 | |
| 164 | bl tfunch00 | |
| 165 | // CHECK6: tfunch31: | |
| 166 | // CHECK6-NEXT: 4100000: 70 47 bx lr | |
| 167 | // CHECK6-NEXT: 4100002: 00 f0 03 f8 bl #6 | |
| 168 | // CHECK6-NEXT: 4100006: 00 f0 06 f8 bl #12 | |
| 169 | // CHECK6: __Thumbv7ABSLongThunk_tfuncl00: | |
| 170 | // CHECK6-NEXT: 410000c: 40 f2 01 0c movw r12, #1 | |
| 171 | // CHECK6-NEXT: 4100010: c0 f2 20 0c movt r12, #32 | |
| 172 | // CHECK6-NEXT: 4100014: 60 47 bx r12 | |
| 173 | // CHECK6: __Thumbv7ABSLongThunk_tfunch00: | |
| 174 | // CHECK6-NEXT: 4100016: 40 f2 01 0c movw r12, #1 | |
| 175 | // CHECK6-NEXT: 410001a: c0 f2 20 2c movt r12, #544 | |
| 176 | // CHECK6-NEXT: 410001e: 60 47 bx r12 |
deps/lld/test/ELF/arm-thunk-linkerscript-orphan.s created+63| ... | ... | @@ -0,0 +1,63 @@ |
| 1 | // REQUIRES: arm | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | |
| 3 | // RUN: echo "SECTIONS { \ | |
| 4 | // RUN: .text_low 0x100000 : { *(.text_low) } \ | |
| 5 | // RUN: .text_high 0x2000000 : { *(.text_high) } \ | |
| 6 | // RUN: .data : { *(.data) } \ | |
| 7 | // RUN: }" > %t.script | |
| 8 | // RUN: ld.lld --script %t.script %t -o %t2 2>&1 | |
| 9 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s | |
| 10 | .syntax unified | |
| 11 | .section .text_low, "ax", %progbits | |
| 12 | .thumb | |
| 13 | .globl _start | |
| 14 | _start: bx lr | |
| 15 | .globl low_target | |
| 16 | .type low_target, %function | |
| 17 | low_target: | |
| 18 | bl high_target | |
| 19 | bl orphan_target | |
| 20 | // CHECK: Disassembly of section .text_low: | |
| 21 | // CHECK-NEXT: _start: | |
| 22 | // CHECK-NEXT: 100000: 70 47 bx lr | |
| 23 | // CHECK: low_target: | |
| 24 | // CHECK-NEXT: 100002: 00 f0 03 f8 bl #6 | |
| 25 | // CHECK-NEXT: 100006: 00 f0 06 f8 bl #12 | |
| 26 | // CHECK: __Thumbv7ABSLongThunk_high_target: | |
| 27 | // CHECK-NEXT: 10000c: 40 f2 01 0c movw r12, #1 | |
| 28 | // CHECK-NEXT: 100010: c0 f2 00 2c movt r12, #512 | |
| 29 | // CHECK-NEXT: 100014: 60 47 bx r12 | |
| 30 | // CHECK: __Thumbv7ABSLongThunk_orphan_target: | |
| 31 | // CHECK-NEXT: 100016: 40 f2 15 0c movw r12, #21 | |
| 32 | // CHECK-NEXT: 10001a: c0 f2 00 2c movt r12, #512 | |
| 33 | // CHECK-NEXT: 10001e: 60 47 bx r12 | |
| 34 | .section .text_high, "ax", %progbits | |
| 35 | .thumb | |
| 36 | .globl high_target | |
| 37 | .type high_target, %function | |
| 38 | high_target: | |
| 39 | bl low_target | |
| 40 | bl orphan_target | |
| 41 | // CHECK: Disassembly of section .text_high: | |
| 42 | // CHECK-NEXT: high_target: | |
| 43 | // CHECK-NEXT: 2000000: 00 f0 02 f8 bl #4 | |
| 44 | // CHECK-NEXT: 2000004: 00 f0 06 f8 bl #12 | |
| 45 | // CHECK: __Thumbv7ABSLongThunk_low_target: | |
| 46 | // CHECK-NEXT: 2000008: 40 f2 03 0c movw r12, #3 | |
| 47 | // CHECK-NEXT: 200000c: c0 f2 10 0c movt r12, #16 | |
| 48 | // CHECK-NEXT: 2000010: 60 47 bx r12 | |
| 49 | ||
| 50 | .section orphan, "ax", %progbits | |
| 51 | .thumb | |
| 52 | .globl orphan_target | |
| 53 | .type orphan_target, %function | |
| 54 | orphan_target: | |
| 55 | bl low_target | |
| 56 | bl high_target | |
| 57 | // CHECK: Disassembly of section orphan: | |
| 58 | // CHECK-NEXT: orphan_target: | |
| 59 | // CHECK-NEXT: 2000014: ff f7 f8 ff bl #-16 | |
| 60 | // CHECK-NEXT: 2000018: ff f7 f2 ff bl #-28 | |
| 61 | ||
| 62 | .data | |
| 63 | .word 10 |
deps/lld/test/ELF/arm-thunk-linkerscript-sort.s created+71| ... | ... | @@ -0,0 +1,71 @@ |
| 1 | // REQUIRES: arm | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | |
| 3 | // RUN: echo "SECTIONS { \ | |
| 4 | // RUN: .text 0x100000 : { *(SORT_BY_NAME(.text.*)) } \ | |
| 5 | // RUN: }" > %t.script | |
| 6 | // RUN: ld.lld --script %t.script %t -o %t2 2>&1 | |
| 7 | // RUN: llvm-objdump -d %t2 -start-address=1048576 -stop-address=1048584 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s | |
| 8 | // RUN: llvm-objdump -d %t2 -start-address=16777220 -stop-address=16777230 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s | |
| 9 | ||
| 10 | .syntax unified | |
| 11 | ||
| 12 | // Test that linkerscript sorting does not apply to Thunks, we expect that the | |
| 13 | // sort will reverse the order of sections presented here. | |
| 14 | ||
| 15 | // Define a function aligned on a megabyte boundary | |
| 16 | .macro FUNCTION suff | |
| 17 | .section .text.\suff\(), "ax", %progbits | |
| 18 | .thumb | |
| 19 | .balign 0x100000 | |
| 20 | .globl tfunc\suff\() | |
| 21 | .type tfunc\suff\(), %function | |
| 22 | tfunc\suff\(): | |
| 23 | bx lr | |
| 24 | .endm | |
| 25 | ||
| 26 | FUNCTION 31 | |
| 27 | FUNCTION 30 | |
| 28 | FUNCTION 29 | |
| 29 | FUNCTION 28 | |
| 30 | FUNCTION 27 | |
| 31 | FUNCTION 26 | |
| 32 | FUNCTION 25 | |
| 33 | FUNCTION 24 | |
| 34 | FUNCTION 23 | |
| 35 | FUNCTION 22 | |
| 36 | FUNCTION 21 | |
| 37 | FUNCTION 20 | |
| 38 | FUNCTION 19 | |
| 39 | FUNCTION 18 | |
| 40 | FUNCTION 17 | |
| 41 | FUNCTION 16 | |
| 42 | FUNCTION 15 | |
| 43 | // CHECK2: __Thumbv7ABSLongThunk_tfunc31: | |
| 44 | // CHECK2-NEXT: 1000004: 40 f2 01 0c movw r12, #1 | |
| 45 | // CHECK2-NEXT: 1000008: c0 f2 00 2c movt r12, #512 | |
| 46 | // CHECK2-NEXT: 100000c: 60 47 bx r12 | |
| 47 | FUNCTION 14 | |
| 48 | FUNCTION 13 | |
| 49 | FUNCTION 12 | |
| 50 | FUNCTION 11 | |
| 51 | FUNCTION 10 | |
| 52 | FUNCTION 09 | |
| 53 | FUNCTION 08 | |
| 54 | FUNCTION 07 | |
| 55 | FUNCTION 06 | |
| 56 | FUNCTION 05 | |
| 57 | FUNCTION 04 | |
| 58 | FUNCTION 03 | |
| 59 | FUNCTION 02 | |
| 60 | FUNCTION 01 | |
| 61 | .section .text.00, "ax", %progbits | |
| 62 | .thumb | |
| 63 | .globl _start | |
| 64 | _start: | |
| 65 | // Expect no range extension needed for tfunc01 and an extension needed for | |
| 66 | // tfunc31 | |
| 67 | bl tfunc01 | |
| 68 | bl tfunc31 | |
| 69 | // CHECK1: _start: | |
| 70 | // CHECK1-NEXT: 100000: ff f0 fe ff bl #1048572 | |
| 71 | // CHECK1-NEXT: 100004: ff f2 fe d7 bl #15728636 |
deps/lld/test/ELF/arm-thunk-linkerscript.s created+78| ... | ... | @@ -0,0 +1,78 @@ |
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | |
| 2 | // RUN: echo "SECTIONS { \ | |
| 3 | // RUN: . = SIZEOF_HEADERS; \ | |
| 4 | // RUN: .text_low : { *(.text_low) *(.text_low2) } \ | |
| 5 | // RUN: .text_high 0x2000000 : { *(.text_high) *(.text_high2) } \ | |
| 6 | // RUN: } " > %t.script | |
| 7 | // 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 | // REQUIRES: arm | |
| 10 | // Simple test that we can support range extension thunks with linker scripts | |
| 11 | .syntax unified | |
| 12 | .section .text_low, "ax", %progbits | |
| 13 | .thumb | |
| 14 | .globl _start | |
| 15 | _start: bx lr | |
| 16 | .globl low_target | |
| 17 | .type low_target, %function | |
| 18 | low_target: | |
| 19 | bl high_target | |
| 20 | bl high_target2 | |
| 21 | ||
| 22 | .section .text_low2, "ax", %progbits | |
| 23 | .thumb | |
| 24 | .globl low_target2 | |
| 25 | .type low_target2, %function | |
| 26 | low_target2: | |
| 27 | bl high_target | |
| 28 | bl high_target2 | |
| 29 | ||
| 30 | // CHECK: Disassembly of section .text_low: | |
| 31 | // CHECK-NEXT: _start: | |
| 32 | // CHECK-NEXT: 94: 70 47 bx lr | |
| 33 | // CHECK: low_target: | |
| 34 | // CHECK-NEXT: 96: 00 f0 03 f8 bl #6 | |
| 35 | // CHECK-NEXT: 9a: 00 f0 06 f8 bl #12 | |
| 36 | // CHECK: __Thumbv7ABSLongThunk_high_target: | |
| 37 | // CHECK-NEXT: a0: 40 f2 01 0c movw r12, #1 | |
| 38 | // CHECK-NEXT: a4: c0 f2 00 2c movt r12, #512 | |
| 39 | // CHECK-NEXT: a8: 60 47 bx r12 | |
| 40 | // CHECK: __Thumbv7ABSLongThunk_high_target2: | |
| 41 | // CHECK-NEXT: aa: 40 f2 1d 0c movw r12, #29 | |
| 42 | // CHECK-NEXT: ae: c0 f2 00 2c movt r12, #512 | |
| 43 | // CHECK-NEXT: b2: 60 47 bx r12 | |
| 44 | // CHECK: low_target2: | |
| 45 | // CHECK-NEXT: b4: ff f7 f4 ff bl #-24 | |
| 46 | // CHECK-NEXT: b8: ff f7 f7 ff bl #-18 | |
| 47 | ||
| 48 | .section .text_high, "ax", %progbits | |
| 49 | .thumb | |
| 50 | .globl high_target | |
| 51 | .type high_target, %function | |
| 52 | high_target: | |
| 53 | bl low_target | |
| 54 | bl low_target2 | |
| 55 | ||
| 56 | .section .text_high2, "ax", %progbits | |
| 57 | .thumb | |
| 58 | .globl high_target2 | |
| 59 | .type high_target2, %function | |
| 60 | high_target2: | |
| 61 | bl low_target | |
| 62 | bl low_target2 | |
| 63 | ||
| 64 | // CHECK: Disassembly of section .text_high: | |
| 65 | // CHECK-NEXT: high_target: | |
| 66 | // CHECK-NEXT: 2000000: 00 f0 02 f8 bl #4 | |
| 67 | // CHECK-NEXT: 2000004: 00 f0 05 f8 bl #10 | |
| 68 | // CHECK: __Thumbv7ABSLongThunk_low_target: | |
| 69 | // CHECK-NEXT: 2000008: 40 f2 97 0c movw r12, #151 | |
| 70 | // CHECK-NEXT: 200000c: c0 f2 00 0c movt r12, #0 | |
| 71 | // CHECK-NEXT: 2000010: 60 47 bx r12 | |
| 72 | // CHECK: __Thumbv7ABSLongThunk_low_target2: | |
| 73 | // CHECK-NEXT: 2000012: 40 f2 b5 0c movw r12, #181 | |
| 74 | // CHECK-NEXT: 2000016: c0 f2 00 0c movt r12, #0 | |
| 75 | // CHECK-NEXT: 200001a: 60 47 bx r12 | |
| 76 | // CHECK: high_target2: | |
| 77 | // CHECK-NEXT: 200001c: ff f7 f4 ff bl #-24 | |
| 78 | // CHECK-NEXT: 2000020: ff f7 f7 ff bl #-18 |
deps/lld/test/ELF/arm-thunk-multipass.s created+96| ... | ... | @@ -0,0 +1,96 @@ |
| 1 | // REQUIRES: arm | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | |
| 3 | // RUN: ld.lld %t -o %t2 2>&1 | |
| 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 | |
| 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 | |
| 8 | // RUN: llvm-objdump -d %t2 -start-address=17825818 -stop-address=17825828 -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 | |
| 10 | // extended can be pushed out of range by another Thunk, necessitating another | |
| 11 | // pass | |
| 12 | ||
| 13 | .macro FUNCTION suff | |
| 14 | .section .text.\suff\(), "ax", %progbits | |
| 15 | .thumb | |
| 16 | .balign 0x100000 | |
| 17 | .globl tfunc\suff\() | |
| 18 | .type tfunc\suff\(), %function | |
| 19 | tfunc\suff\(): | |
| 20 | bx lr | |
| 21 | .endm | |
| 22 | ||
| 23 | FUNCTION 00 | |
| 24 | .globl _start | |
| 25 | _start: | |
| 26 | bl target | |
| 27 | b.w arm_target | |
| 28 | // arm_target is in range but needs an interworking thunk | |
| 29 | // CHECK1: _start: | |
| 30 | // CHECK1-NEXT: 100002: 00 f3 06 d0 bl #15728652 | |
| 31 | // CHECK1-NEXT: 100006: ff f2 ff 97 b.w #15728638 <__Thumbv7ABSLongThunk_arm_target> | |
| 32 | nop | |
| 33 | nop | |
| 34 | nop | |
| 35 | .globl target2 | |
| 36 | .type target2, %function | |
| 37 | nop | |
| 38 | ||
| 39 | target2: | |
| 40 | FUNCTION 01 | |
| 41 | FUNCTION 02 | |
| 42 | FUNCTION 03 | |
| 43 | FUNCTION 04 | |
| 44 | FUNCTION 05 | |
| 45 | FUNCTION 06 | |
| 46 | FUNCTION 07 | |
| 47 | FUNCTION 08 | |
| 48 | FUNCTION 09 | |
| 49 | FUNCTION 10 | |
| 50 | FUNCTION 11 | |
| 51 | FUNCTION 12 | |
| 52 | FUNCTION 13 | |
| 53 | FUNCTION 14 | |
| 54 | FUNCTION 15 | |
| 55 | ||
| 56 | .section .text.16, "ax", %progbits | |
| 57 | .arm | |
| 58 | .globl arm_target | |
| 59 | .type arm_target, %function | |
| 60 | arm_target: | |
| 61 | bx lr | |
| 62 | // CHECK2: __Thumbv7ABSLongThunk_arm_target: | |
| 63 | // CHECK2-NEXT: 1000008: 40 f2 02 0c movw r12, #2 | |
| 64 | // CHECK2-NEXT: 100000c: c0 f2 00 1c movt r12, #256 | |
| 65 | // CHECK2-NEXT: 1000010: 60 47 bx r12 | |
| 66 | // CHECK2: __Thumbv7ABSLongThunk_target: | |
| 67 | // CHECK2-NEXT: 1000012: 40 f2 1b 0c movw r12, #27 | |
| 68 | // CHECK2-NEXT: 1000016: c0 f2 10 1c movt r12, #272 | |
| 69 | // CHECK2-NEXT: 100001a: 60 47 bx r12 | |
| 70 | // CHECK2: __Thumbv7ABSLongThunk_target2: | |
| 71 | // CHECK2-NEXT: 100001c: 40 f2 13 0c movw r12, #19 | |
| 72 | // CHECK2-NEXT: 1000020: c0 f2 10 0c movt r12, #16 | |
| 73 | // CHECK2-NEXT: 1000024: 60 47 bx r12 | |
| 74 | ||
| 75 | .section .text.17, "ax", %progbits | |
| 76 | // Just enough space so that bl target is in range if no extension thunks are | |
| 77 | // generated. | |
| 78 | ||
| 79 | .space 0x100000 - 12 | |
| 80 | ||
| 81 | .section .text.18, "ax", %progbits | |
| 82 | .thumb | |
| 83 | .globl target | |
| 84 | .type target, %function | |
| 85 | // target is at maximum ARM branch range away from caller. | |
| 86 | target: | |
| 87 | // Similar case in the backwards direction | |
| 88 | bl target2 | |
| 89 | nop | |
| 90 | nop | |
| 91 | bx lr | |
| 92 | // CHECK3: target: | |
| 93 | // CHECK3-NEXT: 110001a: ff f6 ff ff bl #-1048578 | |
| 94 | // CHECK3-NEXT: 110001e: 00 bf nop | |
| 95 | // CHECK3-NEXT: 1100020: 00 bf nop | |
| 96 | // CHECK3-NEXT: 1100022: 70 47 bx lr |
deps/lld/test/ELF/arm-thunk-re-add.s created+123| ... | ... | @@ -0,0 +1,123 @@ |
| 1 | // REQUIRES: arm | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | |
| 3 | // RUN: ld.lld %t --shared -o %t.so | |
| 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 | |
| 6 | // RUN: llvm-objdump -d %t.so -start-address=16777220 -stop-address=16777244 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s | |
| 7 | // RUN: llvm-objdump -d %t.so -start-address=17825800 -stop-address=17825826 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s | |
| 8 | // RUN: llvm-objdump -d %t.so -start-address=17825824 -stop-address=17825892 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s | |
| 9 | ||
| 10 | // A branch to a Thunk that we create on pass N, can drift out of range if | |
| 11 | // other Thunks are added in between. In this case we must create a new Thunk | |
| 12 | // for the branch that is in range. We also need to make sure that if the | |
| 13 | // destination of the Thunk is in the PLT the new Thunk also targets the PLT | |
| 14 | .syntax unified | |
| 15 | .thumb | |
| 16 | ||
| 17 | .macro FUNCTION suff | |
| 18 | .section .text.\suff\(), "ax", %progbits | |
| 19 | .thumb | |
| 20 | .balign 0x80000 | |
| 21 | .globl tfunc\suff\() | |
| 22 | .type tfunc\suff\(), %function | |
| 23 | tfunc\suff\(): | |
| 24 | bx lr | |
| 25 | .endm | |
| 26 | ||
| 27 | .globl imported | |
| 28 | .type imported, %function | |
| 29 | .globl imported2 | |
| 30 | .type imported2, %function | |
| 31 | .globl imported3 | |
| 32 | .type imported3, %function | |
| 33 | .globl imported4 | |
| 34 | .type imported4, %function | |
| 35 | FUNCTION 00 | |
| 36 | FUNCTION 01 | |
| 37 | FUNCTION 02 | |
| 38 | FUNCTION 03 | |
| 39 | FUNCTION 04 | |
| 40 | FUNCTION 05 | |
| 41 | FUNCTION 06 | |
| 42 | FUNCTION 07 | |
| 43 | FUNCTION 08 | |
| 44 | FUNCTION 09 | |
| 45 | FUNCTION 10 | |
| 46 | FUNCTION 11 | |
| 47 | FUNCTION 12 | |
| 48 | FUNCTION 13 | |
| 49 | FUNCTION 14 | |
| 50 | FUNCTION 15 | |
| 51 | FUNCTION 16 | |
| 52 | FUNCTION 17 | |
| 53 | FUNCTION 18 | |
| 54 | FUNCTION 19 | |
| 55 | FUNCTION 20 | |
| 56 | FUNCTION 21 | |
| 57 | FUNCTION 22 | |
| 58 | FUNCTION 23 | |
| 59 | FUNCTION 24 | |
| 60 | FUNCTION 25 | |
| 61 | FUNCTION 26 | |
| 62 | FUNCTION 27 | |
| 63 | FUNCTION 28 | |
| 64 | FUNCTION 29 | |
| 65 | FUNCTION 30 | |
| 66 | FUNCTION 31 | |
| 67 | // Precreated Thunk Pool goes here | |
| 68 | // CHECK1: __ThumbV7PILongThunk_imported: | |
| 69 | // CHECK1-NEXT: 1000004: 40 f2 30 0c movw r12, #48 | |
| 70 | // CHECK1-NEXT: 1000008: c0 f2 10 0c movt r12, #16 | |
| 71 | // CHECK1-NEXT: 100000c: fc 44 add r12, pc | |
| 72 | // CHECK1-NEXT: 100000e: 60 47 bx r12 | |
| 73 | // CHECK1: __ThumbV7PILongThunk_imported2: | |
| 74 | // CHECK1-NEXT: 1000010: 40 f2 34 0c movw r12, #52 | |
| 75 | // CHECK1-NEXT: 1000014: c0 f2 10 0c movt r12, #16 | |
| 76 | // CHECK1-NEXT: 1000018: fc 44 add r12, pc | |
| 77 | // CHECK1-NEXT: 100001a: 60 47 bx r12 | |
| 78 | ||
| 79 | .section .text.32, "ax", %progbits | |
| 80 | .space 0x80000 | |
| 81 | .section .text.33, "ax", %progbits | |
| 82 | .space 0x80000 - 0x14 | |
| 83 | .section .text.34, "ax", %progbits | |
| 84 | // Need a Thunk to the PLT entry, can use precreated ThunkSection | |
| 85 | .globl callers | |
| 86 | .type callers, %function | |
| 87 | callers: | |
| 88 | b.w imported | |
| 89 | beq.w imported | |
| 90 | b.w imported2 | |
| 91 | // CHECK2: __ThumbV7PILongThunk_imported: | |
| 92 | // CHECK2-NEXT: 1100008: 40 f2 2c 0c movw r12, #44 | |
| 93 | // CHECK2-NEXT: 110000c: c0 f2 00 0c movt r12, #0 | |
| 94 | // CHECK2-NEXT: 1100010: fc 44 add r12, pc | |
| 95 | // CHECK2-NEXT: 1100012: 60 47 bx r12 | |
| 96 | // CHECK2: callers: | |
| 97 | // CHECK2-NEXT: 1100014: ff f6 f6 bf b.w #-1048596 <__ThumbV7PILongThunk_imported> | |
| 98 | // CHECK2-NEXT: 1100018: 3f f4 f6 af beq.w #-20 <__ThumbV7PILongThunk_imported> | |
| 99 | // CHECK2-NEXT: 110001c: ff f6 f8 bf b.w #-1048592 <__ThumbV7PILongThunk_imported2> | |
| 100 | ||
| 101 | // CHECK3: Disassembly of section .plt: | |
| 102 | // CHECK3-NEXT: $a: | |
| 103 | // CHECK3-NEXT: 1100020: 04 e0 2d e5 str lr, [sp, #-4]! | |
| 104 | // CHECK3-NEXT: 1100024: 00 e6 8f e2 add lr, pc, #0, #12 | |
| 105 | // CHECK3-NEXT: 1100028: 00 ea 8e e2 add lr, lr, #0, #20 | |
| 106 | // CHECK3-NEXT: 110002c: dc ff be e5 ldr pc, [lr, #4060]! | |
| 107 | // CHECK3: $d: | |
| 108 | // CHECK3-NEXT: 1100030: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 109 | // CHECK3-NEXT: 1100034: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 110 | // CHECK3-NEXT: 1100038: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 111 | // CHECK3-NEXT: 110003c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 112 | // CHECK3: $a: | |
| 113 | // CHECK3-NEXT: 1100040: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 114 | // CHECK3-NEXT: 1100044: 00 ca 8c e2 add r12, r12, #0, #20 | |
| 115 | // CHECK3-NEXT: 1100048: c4 ff bc e5 ldr pc, [r12, #4036]! | |
| 116 | // CHECK3: $d: | |
| 117 | // CHECK3-NEXT: 110004c: d4 d4 d4 d4 .word 0xd4d4d4d4 | |
| 118 | // CHECK3: $a: | |
| 119 | // CHECK3-NEXT: 1100050: 00 c6 8f e2 add r12, pc, #0, #12 | |
| 120 | // CHECK3-NEXT: 1100054: 00 ca 8c e2 add r12, r12, #0, #20 | |
| 121 | // CHECK3-NEXT: 1100058: b8 ff bc e5 ldr pc, [r12, #4024]! | |
| 122 | // CHECK3: $d: | |
| 123 | // CHECK3-NEXT: 110005c: d4 d4 d4 d4 .word 0xd4d4d4d4 |
deps/lld/test/ELF/arm-thunk-toolargesection.s created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 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 | |
| 4 | .syntax unified | |
| 5 | .balign 0x1000 | |
| 6 | .thumb | |
| 7 | .text | |
| 8 | .globl _start | |
| 9 | .type _start, %function | |
| 10 | _start: | |
| 11 | bx lr | |
| 12 | ||
| 13 | .section .text.large1, "ax", %progbits | |
| 14 | .balign 4 | |
| 15 | .space (17 * 1024 * 1024) | |
| 16 | bl _start | |
| 17 | .space (17 * 1024 * 1024) | |
| 18 | ||
| 19 | // CHECK: error: InputSection too large for range extension thunk {{.*}}.text.large1 |
deps/lld/test/ELF/arm-tls-gd-nonpreemptible.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | // RUN: ld.lld %t -o %t2 |
| 3 | 3 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 4 | 4 | // RUN: llvm-objdump -s %t2 | FileCheck %s |
| 5 | // RUN: ld.lld %t --shared -o %t3.so | |
| 5 | // RUN: ld.lld --hash-style=sysv %t --shared -o %t3.so | |
| 6 | 6 | // RUN: llvm-objdump -s %t3.so | FileCheck -check-prefix=CHECK-SHARED %s |
| 7 | 7 | // REQUIRES: arm |
| 8 | 8 |
deps/lld/test/ELF/arm-tls-gd32.s+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 2 | // RUN: ld.lld %t.o -o %t.so -shared | |
| 2 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | |
| 3 | 3 | // RUN: llvm-readobj -s -dyn-relocations %t.so | FileCheck --check-prefix=SEC %s |
| 4 | 4 | // RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s |
| 5 | 5 | // REQUIRES: arm |
deps/lld/test/ELF/arm-tls-ie32.s+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 2 | // RUN: ld.lld %t.o -o %t.so -shared | |
| 2 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | |
| 3 | 3 | // RUN: llvm-readobj -s -dyn-relocations %t.so | FileCheck --check-prefix=SEC %s |
| 4 | 4 | // RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s |
| 5 | 5 | // REQUIRES: arm |
deps/lld/test/ELF/arm-tls-ldm32.s+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 2 | // RUN: ld.lld %t.o -o %t.so -shared | |
| 2 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | |
| 3 | 3 | // RUN: llvm-readobj -s -dyn-relocations %t.so | FileCheck --check-prefix=SEC %s |
| 4 | 4 | // RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s |
| 5 | 5 | // REQUIRES: arm |
deps/lld/test/ELF/arm-tls-norelax-gd-ie.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 |
| 2 | 2 | // RUN: ld.lld %t1 --shared -o %t1.so |
| 3 | 3 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 4 | // RUN: ld.lld %t1.so %t.o -o %t | |
| 4 | // RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t | |
| 5 | 5 | // RUN: llvm-readobj -s -dyn-relocations %t | FileCheck %s |
| 6 | 6 | // REQUIRES: arm |
| 7 | 7 |
deps/lld/test/ELF/arm-tls-norelax-gd-le.s+5-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 |
| 2 | 2 | // RUN: ld.lld %t1 --shared -o %t1.so |
| 3 | 3 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 4 | // RUN: ld.lld %t1.so %t.o -o %t | |
| 4 | // RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t | |
| 5 | 5 | // RUN: llvm-objdump -s %t | FileCheck %s |
| 6 | 6 | // REQUIRES: arm |
| 7 | 7 | |
| ... | ... | @@ -35,3 +35,7 @@ x: |
| 35 | 35 | // Module index is always 1 for executable |
| 36 | 36 | // CHECK-NEXT: 13060 01000000 00000000 |
| 37 | 37 | |
| 38 | ||
| 39 | // Without any definition of __tls_get_addr we get an error | |
| 40 | // RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck --check-prefix=ERR %s | |
| 41 | // ERR: error: undefined symbol: __tls_get_addr |
deps/lld/test/ELF/arm-tls-norelax-ie-le.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 |
| 2 | 2 | // RUN: ld.lld %t1 --shared -o %t1.so |
| 3 | 3 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 4 | // RUN: ld.lld %t1.so %t.o -o %t | |
| 4 | // RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t | |
| 5 | 5 | // RUN: llvm-objdump -s -triple=armv7a-linux-gnueabi %t | FileCheck %s |
| 6 | 6 | // REQUIRES: arm |
| 7 | 7 |
deps/lld/test/ELF/arm-tls-norelax-ld-le.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 |
| 2 | 2 | // RUN: ld.lld %t1 --shared -o %t1.so |
| 3 | 3 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 4 | // RUN: ld.lld %t1.so %t.o -o %t | |
| 4 | // RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t | |
| 5 | 5 | // RUN: llvm-objdump -s %t | FileCheck %s |
| 6 | 6 | // REQUIRES: arm |
| 7 | 7 |
deps/lld/test/ELF/arm-undefined-weak.s+1-1| ... | ... | @@ -32,7 +32,7 @@ _start: |
| 32 | 32 | // CHECK: 11000: {{.*}} b #-4 <_start+0x4> |
| 33 | 33 | // CHECK-NEXT: 11004: {{.*}} bl #-4 <_start+0x8> |
| 34 | 34 | // blx is transformed into bl so we don't change state |
| 35 | // CHECK-NEXT: 11008: {{.*}} bl #-4 <_start+0xC> | |
| 35 | // CHECK-NEXT: 11008: {{.*}} bl #-4 <_start+0xc> | |
| 36 | 36 | // CHECK-NEXT: 1100c: {{.*}} movt r0, #0 |
| 37 | 37 | // CHECK-NEXT: 11010: {{.*}} movw r0, #0 |
| 38 | 38 | // CHECK: 11014: {{.*}} .word 0x00000000 |
deps/lld/test/ELF/as-needed-lazy.s created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 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/as-needed-lazy.s -o %t2.o | |
| 4 | # RUN: ld.lld %t2.o -o %t2.so -shared | |
| 5 | # RUN: rm -f %t2.a | |
| 6 | # RUN: llvm-ar rc %t2.a %t2.o | |
| 7 | # RUN: ld.lld %t1.o %t2.a --as-needed %t2.so -o %t | |
| 8 | # RUN: llvm-readobj -d %t | FileCheck %s | |
| 9 | ||
| 10 | # CHECK-NOT: NEEDED | |
| 11 | ||
| 12 | .global _start | |
| 13 | _start: | |
| 14 | nop |
deps/lld/test/ELF/as-needed.s+4| ... | ... | @@ -15,6 +15,10 @@ |
| 15 | 15 | // RUN: ld.lld --as-needed %t.o %t2.so %t3.so %t4.so -o %t2 |
| 16 | 16 | // RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s |
| 17 | 17 | |
| 18 | // Test with the .o last | |
| 19 | // RUN: ld.lld --as-needed %t2.so %t3.so %t4.so %t.o -o %t2 | |
| 20 | // RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s | |
| 21 | ||
| 18 | 22 | // RUN: ld.lld --as-needed %t.o %t2.so --no-as-needed %t3.so %t4.so -o %t2 |
| 19 | 23 | // RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s |
| 20 | 24 |
deps/lld/test/ELF/assignment-archive.s created+27| ... | ... | @@ -0,0 +1,27 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %ta.o | |
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -o %t.o < /dev/null | |
| 4 | # RUN: rm -f %tar.a | |
| 5 | # RUN: llvm-ar rcs %tar.a %ta.o | |
| 6 | ||
| 7 | # RUN: echo "SECTIONS { foo = 1; }" > %t1.script | |
| 8 | # RUN: ld.lld -o %t1.exe --script %t1.script %tar.a %t.o | |
| 9 | # RUN: llvm-readobj -symbols %t1.exe | FileCheck %s | |
| 10 | # CHECK-NOT: bar | |
| 11 | # CHECK: foo | |
| 12 | # CHECK-NOT: bar | |
| 13 | ||
| 14 | # RUN: echo "SECTIONS { zed = foo; }" > %t2.script | |
| 15 | # RUN: ld.lld -o %t2.exe --script %t2.script %tar.a %t.o | |
| 16 | # RUN: llvm-readobj -symbols %t2.exe | FileCheck %s --check-prefix=SYMS | |
| 17 | # SYMS: bar | |
| 18 | # SYMS: foo | |
| 19 | ||
| 20 | .text | |
| 21 | .globl foo | |
| 22 | foo: | |
| 23 | nop | |
| 24 | ||
| 25 | .globl bar | |
| 26 | bar: | |
| 27 | nop |
deps/lld/test/ELF/avoid-empty-program-headers.s+3-3| ... | ... | @@ -42,8 +42,8 @@ _start: |
| 42 | 42 | // CHECK-NEXT: Offset: 0x1000 |
| 43 | 43 | // CHECK-NEXT: VirtualAddress: 0x201000 |
| 44 | 44 | // CHECK-NEXT: PhysicalAddress: 0x201000 |
| 45 | // CHECK-NEXT: FileSize: 1 | |
| 46 | // CHECK-NEXT: MemSize: 1 | |
| 45 | // CHECK-NEXT: FileSize: 4096 | |
| 46 | // CHECK-NEXT: MemSize: 4096 | |
| 47 | 47 | // CHECK-NEXT: Flags [ (0x5) |
| 48 | 48 | // CHECK-NEXT: PF_R (0x4) |
| 49 | 49 | // CHECK-NEXT: PF_X (0x1) |
| ... | ... | @@ -52,7 +52,7 @@ _start: |
| 52 | 52 | // CHECK-NEXT: } |
| 53 | 53 | // CHECK-NEXT: ProgramHeader { |
| 54 | 54 | // CHECK-NEXT: Type: PT_TLS (0x7) |
| 55 | // CHECK-NEXT: Offset: 0x1001 | |
| 55 | // CHECK-NEXT: Offset: 0x2000 | |
| 56 | 56 | // CHECK-NEXT: VirtualAddress: 0x201001 |
| 57 | 57 | // CHECK-NEXT: PhysicalAddress: 0x201001 |
| 58 | 58 | // CHECK-NEXT: FileSize: 0 |
deps/lld/test/ELF/basic-aarch64.s+8-8| ... | ... | @@ -26,7 +26,7 @@ _start: |
| 26 | 26 | # CHECK-NEXT: Version: 1 |
| 27 | 27 | # CHECK-NEXT: Entry: [[ENTRY:0x[0-9A-F]+]] |
| 28 | 28 | # CHECK-NEXT: ProgramHeaderOffset: 0x40 |
| 29 | # CHECK-NEXT: SectionHeaderOffset: 0x10098 | |
| 29 | # CHECK-NEXT: SectionHeaderOffset: 0x11088 | |
| 30 | 30 | # CHECK-NEXT: Flags [ (0x0) |
| 31 | 31 | # CHECK-NEXT: ] |
| 32 | 32 | # CHECK-NEXT: HeaderSize: 64 |
| ... | ... | @@ -76,12 +76,12 @@ _start: |
| 76 | 76 | # CHECK-NEXT: SHF_STRINGS (0x20) |
| 77 | 77 | # CHECK-NEXT: ] |
| 78 | 78 | # CHECK-NEXT: Address: 0x0 |
| 79 | # CHECK-NEXT: Offset: 0x1000C | |
| 79 | # CHECK-NEXT: Offset: 0x11000 | |
| 80 | 80 | # CHECK-NEXT: Size: 8 |
| 81 | 81 | # CHECK-NEXT: Link: 0 |
| 82 | 82 | # CHECK-NEXT: Info: 0 |
| 83 | 83 | # CHECK-NEXT: AddressAlignment: 1 |
| 84 | # CHECK-NEXT: EntrySize: 0 | |
| 84 | # CHECK-NEXT: EntrySize: 1 | |
| 85 | 85 | # CHECK-NEXT: } |
| 86 | 86 | # CHECK-NEXT: Section { |
| 87 | 87 | # CHECK-NEXT: Index: 3 |
| ... | ... | @@ -90,7 +90,7 @@ _start: |
| 90 | 90 | # CHECK-NEXT: Flags [ (0x0) |
| 91 | 91 | # CHECK-NEXT: ] |
| 92 | 92 | # CHECK-NEXT: Address: 0x0 |
| 93 | # CHECK-NEXT: Offset: 0x10018 | |
| 93 | # CHECK-NEXT: Offset: 0x11008 | |
| 94 | 94 | # CHECK-NEXT: Size: 72 |
| 95 | 95 | # CHECK-NEXT: Link: 5 |
| 96 | 96 | # CHECK-NEXT: Info: 2 |
| ... | ... | @@ -104,7 +104,7 @@ _start: |
| 104 | 104 | # CHECK-NEXT: Flags [ (0x0) |
| 105 | 105 | # CHECK-NEXT: ] |
| 106 | 106 | # CHECK-NEXT: Address: 0x0 |
| 107 | # CHECK-NEXT: Offset: 0x10060 | |
| 107 | # CHECK-NEXT: Offset: 0x11050 | |
| 108 | 108 | # CHECK-NEXT: Size: 42 |
| 109 | 109 | # CHECK-NEXT: Link: 0 |
| 110 | 110 | # CHECK-NEXT: Info: 0 |
| ... | ... | @@ -118,7 +118,7 @@ _start: |
| 118 | 118 | # CHECK-NEXT: Flags [ (0x0) |
| 119 | 119 | # CHECK-NEXT: ] |
| 120 | 120 | # CHECK-NEXT: Address: 0x0 |
| 121 | # CHECK-NEXT: Offset: 0x1008A | |
| 121 | # CHECK-NEXT: Offset: 0x1107A | |
| 122 | 122 | # CHECK-NEXT: Size: 13 |
| 123 | 123 | # CHECK-NEXT: Link: 0 |
| 124 | 124 | # CHECK-NEXT: Info: 0 |
| ... | ... | @@ -185,8 +185,8 @@ _start: |
| 185 | 185 | # CHECK-NEXT: Offset: 0x1000 |
| 186 | 186 | # CHECK-NEXT: VirtualAddress: 0x20000 |
| 187 | 187 | # CHECK-NEXT: PhysicalAddress: 0x20000 |
| 188 | # CHECK-NEXT: FileSize: 12 | |
| 189 | # CHECK-NEXT: MemSize: 12 | |
| 188 | # CHECK-NEXT: FileSize: 4096 | |
| 189 | # CHECK-NEXT: MemSize: 4096 | |
| 190 | 190 | # CHECK-NEXT: Flags [ (0x5) |
| 191 | 191 | # CHECK-NEXT: PF_R (0x4) |
| 192 | 192 | # CHECK-NEXT: PF_X (0x1) |
deps/lld/test/ELF/basic-mips.s+2-2| ... | ... | @@ -164,7 +164,7 @@ __start: |
| 164 | 164 | # CHECK-NEXT: Link: 0 |
| 165 | 165 | # CHECK-NEXT: Info: 0 |
| 166 | 166 | # CHECK-NEXT: AddressAlignment: 1 |
| 167 | # CHECK-NEXT: EntrySize: 0 | |
| 167 | # CHECK-NEXT: EntrySize: 1 | |
| 168 | 168 | # CHECK-NEXT: } |
| 169 | 169 | # CHECK-NEXT: Section { |
| 170 | 170 | # CHECK-NEXT: Index: 8 |
| ... | ... | @@ -228,7 +228,7 @@ __start: |
| 228 | 228 | # CHECK-NEXT: Other [ (0x2) |
| 229 | 229 | # CHECK-NEXT: STV_HIDDEN (0x2) |
| 230 | 230 | # CHECK-NEXT: ] |
| 231 | # CHECK-NEXT: Section: Absolute | |
| 231 | # CHECK-NEXT: Section: .got | |
| 232 | 232 | # CHECK-NEXT: } |
| 233 | 233 | # CHECK-NEXT: Symbol { |
| 234 | 234 | # CHECK-NEXT: Name: __start |
deps/lld/test/ELF/basic-ppc.s+2-2| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | # RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-freebsd %s -o %t |
| 2 | # RUN: ld.lld -discard-all -shared %t -o %t2 | |
| 2 | # RUN: ld.lld --hash-style=sysv -discard-all -shared %t -o %t2 | |
| 3 | 3 | # RUN: llvm-readobj -file-headers -sections -section-data -program-headers %t2 | FileCheck %s |
| 4 | 4 | # REQUIRES: ppc |
| 5 | 5 | |
| ... | ... | @@ -163,7 +163,7 @@ |
| 163 | 163 | // CHECK-NEXT: Link: 0 |
| 164 | 164 | // CHECK-NEXT: Info: 0 |
| 165 | 165 | // CHECK-NEXT: AddressAlignment: 1 |
| 166 | // CHECK-NEXT: EntrySize: 0 | |
| 166 | // CHECK-NEXT: EntrySize: 1 | |
| 167 | 167 | // CHECK-NEXT: SectionData ( |
| 168 | 168 | // CHECK-NEXT: 0000: 4C4C4420 312E3000 |LLD 1.0.| |
| 169 | 169 | // CHECK-NEXT: ) |
deps/lld/test/ELF/basic-sparcv9.s+8-8| ... | ... | @@ -26,7 +26,7 @@ _start: |
| 26 | 26 | # CHECK-NEXT: Version: 1 |
| 27 | 27 | # CHECK-NEXT: Entry: [[ENTRY:0x[0-9A-F]+]] |
| 28 | 28 | # CHECK-NEXT: ProgramHeaderOffset: 0x40 |
| 29 | # CHECK-NEXT: SectionHeaderOffset: 0x100080 | |
| 29 | # CHECK-NEXT: SectionHeaderOffset: 0x102070 | |
| 30 | 30 | # CHECK-NEXT: Flags [ (0x0) |
| 31 | 31 | # CHECK-NEXT: ] |
| 32 | 32 | # CHECK-NEXT: HeaderSize: 64 |
| ... | ... | @@ -76,12 +76,12 @@ _start: |
| 76 | 76 | # CHECK-NEXT: SHF_STRINGS (0x20) |
| 77 | 77 | # CHECK-NEXT: ] |
| 78 | 78 | # CHECK-NEXT: Address: 0x0 |
| 79 | # CHECK-NEXT: Offset: 0x10000C | |
| 79 | # CHECK-NEXT: Offset: 0x102000 | |
| 80 | 80 | # CHECK-NEXT: Size: 8 |
| 81 | 81 | # CHECK-NEXT: Link: 0 |
| 82 | 82 | # CHECK-NEXT: Info: 0 |
| 83 | 83 | # CHECK-NEXT: AddressAlignment: 1 |
| 84 | # CHECK-NEXT: EntrySize: 0 | |
| 84 | # CHECK-NEXT: EntrySize: 1 | |
| 85 | 85 | # CHECK-NEXT: } |
| 86 | 86 | # CHECK-NEXT: Section { |
| 87 | 87 | # CHECK-NEXT: Index: 3 |
| ... | ... | @@ -90,7 +90,7 @@ _start: |
| 90 | 90 | # CHECK-NEXT: Flags [ (0x0) |
| 91 | 91 | # CHECK-NEXT: ] |
| 92 | 92 | # CHECK-NEXT: Address: 0x0 |
| 93 | # CHECK-NEXT: Offset: 0x100018 | |
| 93 | # CHECK-NEXT: Offset: 0x102008 | |
| 94 | 94 | # CHECK-NEXT: Size: 48 |
| 95 | 95 | # CHECK-NEXT: Link: 5 |
| 96 | 96 | # CHECK-NEXT: Info: 1 |
| ... | ... | @@ -104,7 +104,7 @@ _start: |
| 104 | 104 | # CHECK-NEXT: Flags [ (0x0) |
| 105 | 105 | # CHECK-NEXT: ] |
| 106 | 106 | # CHECK-NEXT: Address: 0x0 |
| 107 | # CHECK-NEXT: Offset: 0x100048 | |
| 107 | # CHECK-NEXT: Offset: 0x102038 | |
| 108 | 108 | # CHECK-NEXT: Size: 42 |
| 109 | 109 | # CHECK-NEXT: Link: 0 |
| 110 | 110 | # CHECK-NEXT: Info: 0 |
| ... | ... | @@ -118,7 +118,7 @@ _start: |
| 118 | 118 | # CHECK-NEXT: Flags [ (0x0) |
| 119 | 119 | # CHECK-NEXT: ] |
| 120 | 120 | # CHECK-NEXT: Address: 0x0 |
| 121 | # CHECK-NEXT: Offset: 0x100072 | |
| 121 | # CHECK-NEXT: Offset: 0x102062 | |
| 122 | 122 | # CHECK-NEXT: Size: 8 |
| 123 | 123 | # CHECK-NEXT: Link: 0 |
| 124 | 124 | # CHECK-NEXT: Info: 0 |
| ... | ... | @@ -176,8 +176,8 @@ _start: |
| 176 | 176 | # CHECK-NEXT: Offset: 0x100000 |
| 177 | 177 | # CHECK-NEXT: VirtualAddress: 0x200000 |
| 178 | 178 | # CHECK-NEXT: PhysicalAddress: 0x200000 |
| 179 | # CHECK-NEXT: FileSize: 12 | |
| 180 | # CHECK-NEXT: MemSize: 12 | |
| 179 | # CHECK-NEXT: FileSize: 8192 | |
| 180 | # CHECK-NEXT: MemSize: 8192 | |
| 181 | 181 | # CHECK-NEXT: Flags [ (0x5) |
| 182 | 182 | # CHECK-NEXT: PF_R (0x4) |
| 183 | 183 | # CHECK-NEXT: PF_X (0x1) |
deps/lld/test/ELF/basic.s+10-8| ... | ... | @@ -28,7 +28,7 @@ _start: |
| 28 | 28 | # CHECK-NEXT: Version: 1 |
| 29 | 29 | # CHECK-NEXT: Entry: [[ENTRY:0x[0-9A-F]+]] |
| 30 | 30 | # CHECK-NEXT: ProgramHeaderOffset: 0x40 |
| 31 | # CHECK-NEXT: SectionHeaderOffset: 0x1080 | |
| 31 | # CHECK-NEXT: SectionHeaderOffset: 0x2070 | |
| 32 | 32 | # CHECK-NEXT: Flags [ (0x0) |
| 33 | 33 | # CHECK-NEXT: ] |
| 34 | 34 | # CHECK-NEXT: HeaderSize: 64 |
| ... | ... | @@ -78,12 +78,12 @@ _start: |
| 78 | 78 | # CHECK-NEXT: SHF_STRINGS (0x20) |
| 79 | 79 | # CHECK-NEXT: ] |
| 80 | 80 | # CHECK-NEXT: Address: 0x0 |
| 81 | # CHECK-NEXT: Offset: 0x1010 | |
| 81 | # CHECK-NEXT: Offset: 0x2000 | |
| 82 | 82 | # CHECK-NEXT: Size: 8 |
| 83 | 83 | # CHECK-NEXT: Link: 0 |
| 84 | 84 | # CHECK-NEXT: Info: 0 |
| 85 | 85 | # CHECK-NEXT: AddressAlignment: 1 |
| 86 | # CHECK-NEXT: EntrySize: 0 | |
| 86 | # CHECK-NEXT: EntrySize: 1 | |
| 87 | 87 | # CHECK-NEXT: } |
| 88 | 88 | # CHECK-NEXT: Section { |
| 89 | 89 | # CHECK-NEXT: Index: 3 |
| ... | ... | @@ -92,7 +92,7 @@ _start: |
| 92 | 92 | # CHECK-NEXT: Flags [ (0x0) |
| 93 | 93 | # CHECK-NEXT: ] |
| 94 | 94 | # CHECK-NEXT: Address: 0x0 |
| 95 | # CHECK-NEXT: Offset: 0x1018 | |
| 95 | # CHECK-NEXT: Offset: 0x2008 | |
| 96 | 96 | # CHECK-NEXT: Size: 48 |
| 97 | 97 | # CHECK-NEXT: Link: 5 |
| 98 | 98 | # CHECK-NEXT: Info: 1 |
| ... | ... | @@ -106,7 +106,7 @@ _start: |
| 106 | 106 | # CHECK-NEXT: Flags [ (0x0) |
| 107 | 107 | # CHECK-NEXT: ] |
| 108 | 108 | # CHECK-NEXT: Address: 0x0 |
| 109 | # CHECK-NEXT: Offset: 0x1048 | |
| 109 | # CHECK-NEXT: Offset: 0x2038 | |
| 110 | 110 | # CHECK-NEXT: Size: 42 |
| 111 | 111 | # CHECK-NEXT: Link: 0 |
| 112 | 112 | # CHECK-NEXT: Info: 0 |
| ... | ... | @@ -120,7 +120,7 @@ _start: |
| 120 | 120 | # CHECK-NEXT: Flags [ (0x0) |
| 121 | 121 | # CHECK-NEXT: ] |
| 122 | 122 | # CHECK-NEXT: Address: 0x0 |
| 123 | # CHECK-NEXT: Offset: 0x1072 | |
| 123 | # CHECK-NEXT: Offset: 0x2062 | |
| 124 | 124 | # CHECK-NEXT: Size: 8 |
| 125 | 125 | # CHECK-NEXT: Link: 0 |
| 126 | 126 | # CHECK-NEXT: Info: 0 |
| ... | ... | @@ -178,8 +178,8 @@ _start: |
| 178 | 178 | # CHECK-NEXT: Offset: 0x1000 |
| 179 | 179 | # CHECK-NEXT: VirtualAddress: 0x201000 |
| 180 | 180 | # CHECK-NEXT: PhysicalAddress: 0x201000 |
| 181 | # CHECK-NEXT: FileSize: 16 | |
| 182 | # CHECK-NEXT: MemSize: 16 | |
| 181 | # CHECK-NEXT: FileSize: 4096 | |
| 182 | # CHECK-NEXT: MemSize: 4096 | |
| 183 | 183 | # CHECK-NEXT: Flags [ (0x5) |
| 184 | 184 | # CHECK-NEXT: PF_R (0x4) |
| 185 | 185 | # CHECK-NEXT: PF_X (0x1) |
| ... | ... | @@ -246,7 +246,9 @@ _start: |
| 246 | 246 | # UNKNOWN_EMUL: unknown emulation: wrong_emul_fbsd |
| 247 | 247 | |
| 248 | 248 | # RUN: not ld.lld %t --lto-partitions=0 2>&1 | FileCheck --check-prefix=NOTHREADS %s |
| 249 | # RUN: not ld.lld %t --plugin-opt=lto-partitions=0 2>&1 | FileCheck --check-prefix=NOTHREADS %s | |
| 249 | 250 | # NOTHREADS: --lto-partitions: number of threads must be > 0 |
| 250 | 251 | |
| 251 | 252 | # RUN: not ld.lld %t --thinlto-jobs=0 2>&1 | FileCheck --check-prefix=NOTHREADSTHIN %s |
| 253 | # RUN: not ld.lld %t --plugin-opt=jobs=0 2>&1 | FileCheck --check-prefix=NOTHREADSTHIN %s | |
| 252 | 254 | # NOTHREADSTHIN: --thinlto-jobs: number of threads must be > 0 |
deps/lld/test/ELF/basic32.s+8-8| ... | ... | @@ -25,7 +25,7 @@ _start: |
| 25 | 25 | # CHECK-NEXT: Version: 1 |
| 26 | 26 | # CHECK-NEXT: Entry: 0x11000 |
| 27 | 27 | # CHECK-NEXT: ProgramHeaderOffset: 0x34 |
| 28 | # CHECK-NEXT: SectionHeaderOffset: 0x1068 | |
| 28 | # CHECK-NEXT: SectionHeaderOffset: 0x205C | |
| 29 | 29 | # CHECK-NEXT: Flags [ (0x0) |
| 30 | 30 | # CHECK-NEXT: ] |
| 31 | 31 | # CHECK-NEXT: HeaderSize: 52 |
| ... | ... | @@ -75,12 +75,12 @@ _start: |
| 75 | 75 | # CHECK-NEXT: SHF_STRINGS (0x20) |
| 76 | 76 | # CHECK-NEXT: ] |
| 77 | 77 | # CHECK-NEXT: Address: 0x0 |
| 78 | # CHECK-NEXT: Offset: 0x100C | |
| 78 | # CHECK-NEXT: Offset: 0x2000 | |
| 79 | 79 | # CHECK-NEXT: Size: 8 |
| 80 | 80 | # CHECK-NEXT: Link: 0 |
| 81 | 81 | # CHECK-NEXT: Info: 0 |
| 82 | 82 | # CHECK-NEXT: AddressAlignment: 1 |
| 83 | # CHECK-NEXT: EntrySize: 0 | |
| 83 | # CHECK-NEXT: EntrySize: 1 | |
| 84 | 84 | # CHECK-NEXT: } |
| 85 | 85 | # CHECK-NEXT: Section { |
| 86 | 86 | # CHECK-NEXT: Index: 3 |
| ... | ... | @@ -89,7 +89,7 @@ _start: |
| 89 | 89 | # CHECK-NEXT: Flags [ |
| 90 | 90 | # CHECK-NEXT: ] |
| 91 | 91 | # CHECK-NEXT: Address: 0x0 |
| 92 | # CHECK-NEXT: Offset: 0x1014 | |
| 92 | # CHECK-NEXT: Offset: 0x2008 | |
| 93 | 93 | # CHECK-NEXT: Size: 32 |
| 94 | 94 | # CHECK-NEXT: Link: 5 |
| 95 | 95 | # CHECK-NEXT: Info: 1 |
| ... | ... | @@ -103,7 +103,7 @@ _start: |
| 103 | 103 | # CHECK-NEXT: Flags [ (0x0) |
| 104 | 104 | # CHECK-NEXT: ] |
| 105 | 105 | # CHECK-NEXT: Address: 0x0 |
| 106 | # CHECK-NEXT: Offset: 0x1034 | |
| 106 | # CHECK-NEXT: Offset: 0x2028 | |
| 107 | 107 | # CHECK-NEXT: Size: 42 |
| 108 | 108 | # CHECK-NEXT: Link: 0 |
| 109 | 109 | # CHECK-NEXT: Info: 0 |
| ... | ... | @@ -117,7 +117,7 @@ _start: |
| 117 | 117 | # CHECK-NEXT: Flags [ (0x0) |
| 118 | 118 | # CHECK-NEXT: ] |
| 119 | 119 | # CHECK-NEXT: Address: 0x0 |
| 120 | # CHECK-NEXT: Offset: 0x105E | |
| 120 | # CHECK-NEXT: Offset: 0x2052 | |
| 121 | 121 | # CHECK-NEXT: Size: 8 |
| 122 | 122 | # CHECK-NEXT: Link: 0 |
| 123 | 123 | # CHECK-NEXT: Info: 0 |
| ... | ... | @@ -155,8 +155,8 @@ _start: |
| 155 | 155 | # CHECK-NEXT: Offset: 0x1000 |
| 156 | 156 | # CHECK-NEXT: VirtualAddress: 0x11000 |
| 157 | 157 | # CHECK-NEXT: PhysicalAddress: 0x11000 |
| 158 | # CHECK-NEXT: FileSize: 12 | |
| 159 | # CHECK-NEXT: MemSize: 12 | |
| 158 | # CHECK-NEXT: FileSize: 4096 | |
| 159 | # CHECK-NEXT: MemSize: 4096 | |
| 160 | 160 | # CHECK-NEXT: Flags [ (0x5) |
| 161 | 161 | # CHECK-NEXT: PF_R (0x4) |
| 162 | 162 | # CHECK-NEXT: PF_X (0x1) |
deps/lld/test/ELF/basic64be.s+1-1| ... | ... | @@ -175,7 +175,7 @@ _start: |
| 175 | 175 | # CHECK-NEXT: Link: 0 |
| 176 | 176 | # CHECK-NEXT: Info: 0 |
| 177 | 177 | # CHECK-NEXT: AddressAlignment: 1 |
| 178 | # CHECK-NEXT: EntrySize: 0 | |
| 178 | # CHECK-NEXT: EntrySize: 1 | |
| 179 | 179 | # CHECK-NEXT: SectionData ( |
| 180 | 180 | # CHECK-NEXT: 0000: 4C4C4420 312E3000 |LLD 1.0.| |
| 181 | 181 | # CHECK-NEXT: ) |
deps/lld/test/ELF/build-id.s+18-3| ... | ... | @@ -2,6 +2,9 @@ |
| 2 | 2 | |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | 4 | |
| 5 | # RUN: ld.lld --build-id %t -o %t2 | |
| 6 | # RUN: llvm-readobj -s %t2 | FileCheck -check-prefix=ALIGN %s | |
| 7 | ||
| 5 | 8 | # RUN: ld.lld --build-id %t -o %t2 -threads |
| 6 | 9 | # RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DEFAULT %s |
| 7 | 10 | # RUN: ld.lld --build-id %t -o %t2 -no-threads |
| ... | ... | @@ -45,18 +48,30 @@ _start: |
| 45 | 48 | .section .note.test, "a", @note |
| 46 | 49 | .quad 42 |
| 47 | 50 | |
| 51 | # ALIGN: Name: .note.gnu.build-id | |
| 52 | # ALIGN-NEXT: Type: SHT_NOTE | |
| 53 | # ALIGN-NEXT: Flags [ | |
| 54 | # ALIGN-NEXT: SHF_ALLOC | |
| 55 | # ALIGN-NEXT: ] | |
| 56 | # ALIGN-NEXT: Address: | |
| 57 | # ALIGN-NEXT: Offset: [[_:0x[0-9A-Z]*(0|4|8|C)$]] | |
| 58 | # ALIGN-NEXT: Size: | |
| 59 | # ALIGN-NEXT: Link: | |
| 60 | # ALIGN-NEXT: Info: | |
| 61 | # ALIGN-NEXT: AddressAlignment: 4 | |
| 62 | ||
| 48 | 63 | # DEFAULT: Contents of section .note.test: |
| 49 | 64 | # DEFAULT: Contents of section .note.gnu.build-id: |
| 50 | 65 | # DEFAULT-NEXT: 04000000 08000000 03000000 474e5500 ............GNU. |
| 51 | # DEFAULT-NEXT: fd36edb1 f6ff02af | |
| 66 | # DEFAULT-NEXT: 894c04e8 fbf5556b | |
| 52 | 67 | |
| 53 | 68 | # MD5: Contents of section .note.gnu.build-id: |
| 54 | 69 | # MD5-NEXT: 04000000 10000000 03000000 474e5500 ............GNU. |
| 55 | # MD5-NEXT: fc | |
| 70 | # MD5-NEXT: 6a51bbd7 9e8ee3f9 2e02d213 711cfec9 | |
| 56 | 71 | |
| 57 | 72 | # SHA1: Contents of section .note.gnu.build-id: |
| 58 | 73 | # SHA1-NEXT: 04000000 14000000 03000000 474e5500 ............GNU. |
| 59 | # SHA1-NEXT: 55b1eedb 03b588e1 09987d1d e9a79be7 | |
| 74 | # SHA1-NEXT: 9a8618b1 d6fd0e5c eda73dd8 76de5596 | |
| 60 | 75 | |
| 61 | 76 | # UUID: Contents of section .note.gnu.build-id: |
| 62 | 77 | # UUID-NEXT: 04000000 10000000 03000000 474e5500 ............GNU. |
deps/lld/test/ELF/chroot.s created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: rm -rf %t.dir | |
| 3 | # RUN: mkdir %t.dir | |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/chroot.o | |
| 5 | # RUN: ld.lld --chroot %t.dir -o %t.exe /chroot.o | |
| 6 | ||
| 7 | # RUN: echo 'INPUT(/chroot.o)' > %t.dir/scr | |
| 8 | # RUN: ld.lld --chroot %t.dir -o %t.exe /scr | |
| 9 | ||
| 10 | .globl _start | |
| 11 | _start: | |
| 12 | ret |
deps/lld/test/ELF/comment-gc.s+1-2| ... | ... | @@ -5,8 +5,7 @@ |
| 5 | 5 | # RUN: llvm-objdump -s %t1 | FileCheck %s |
| 6 | 6 | |
| 7 | 7 | # CHECK: Contents of section .comment: |
| 8 | # CHECK-NEXT: 0000 00666f6f 00626172 004c4c44 20312e30 .foo.bar.LLD 1.0 | |
| 9 | # CHECK-NEXT: 0010 00 . | |
| 8 | # CHECK-NEXT: foo..LLD 1.0.bar | |
| 10 | 9 | |
| 11 | 10 | .ident "foo" |
| 12 | 11 |
deps/lld/test/ELF/common-gc.s created+41| ... | ... | @@ -0,0 +1,41 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | |
| 3 | ||
| 4 | # RUN: ld.lld %t -o %t2 | |
| 5 | # RUN: llvm-readobj -sections -symbols %t2 | FileCheck %s --check-prefix=NOGC | |
| 6 | ||
| 7 | # NOGC: Name: .bss | |
| 8 | # NOGC-NEXT: Type: | |
| 9 | # NOGC-NEXT: Flags [ | |
| 10 | # NOGC-NEXT: SHF_ALLOC | |
| 11 | # NOGC-NEXT: SHF_WRITE | |
| 12 | # NOGC-NEXT: ] | |
| 13 | # NOGC-NEXT: Address: | |
| 14 | # NOGC-NEXT: Offset: | |
| 15 | # NOGC-NEXT: Size: 8 | |
| 16 | ||
| 17 | # NOGC: Name: bar | |
| 18 | # NOGC: Name: foo | |
| 19 | ||
| 20 | # RUN: ld.lld -gc-sections %t -o %t1 | |
| 21 | # RUN: llvm-readobj -sections -symbols %t1 | FileCheck %s --check-prefix=GC | |
| 22 | ||
| 23 | # GC: Name: .bss | |
| 24 | # GC-NEXT: Type: | |
| 25 | # GC-NEXT: Flags [ | |
| 26 | # GC-NEXT: SHF_ALLOC | |
| 27 | # GC-NEXT: SHF_WRITE | |
| 28 | # GC-NEXT: ] | |
| 29 | # GC-NEXT: Address: | |
| 30 | # GC-NEXT: Offset: | |
| 31 | # GC-NEXT: Size: 4 | |
| 32 | ||
| 33 | # GC-NOT: Name: bar | |
| 34 | ||
| 35 | .comm foo,4,4 | |
| 36 | .comm bar,4,4 | |
| 37 | ||
| 38 | .text | |
| 39 | .globl _start | |
| 40 | _start: | |
| 41 | .quad foo |
deps/lld/test/ELF/common-gc2.s created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | |
| 3 | # RUN: ld.lld -gc-sections -export-dynamic %t -o %t1 | |
| 4 | # RUN: llvm-readobj --dyn-symbols %t1 | FileCheck %s | |
| 5 | ||
| 6 | # CHECK: Name: bar@ | |
| 7 | # CHECK: Name: foo@ | |
| 8 | ||
| 9 | .comm foo,4,4 | |
| 10 | .comm bar,4,4 | |
| 11 | ||
| 12 | .text | |
| 13 | .globl _start | |
| 14 | _start: | |
| 15 | .quad foo |
deps/lld/test/ELF/common-gc3.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 | # RUN: ld.lld %t.o -o %t1 --gc-sections | |
| 4 | # RUN: llvm-objdump -s %t1 | FileCheck %s | |
| 5 | ||
| 6 | # CHECK: Contents of section .noalloc: | |
| 7 | # 0000 00000000 00000000 ........ | |
| 8 | ||
| 9 | 	.section	.text._start,"ax",@progbits | |
| 10 | 	.globl	_start | |
| 11 | _start: | |
| 12 | 	retq | |
| 13 | ||
| 14 | 	.type	unused,@object | |
| 15 | 	.comm	unused,4,4 | |
| 16 | ||
| 17 | 	.section	.noalloc,"",@progbits | |
| 18 | 	.quad	unused |
deps/lld/test/ELF/common.s+5-5| ... | ... | @@ -12,13 +12,13 @@ |
| 12 | 12 | // CHECK-NEXT: ] |
| 13 | 13 | // CHECK-NEXT: Address: 0x201000 |
| 14 | 14 | // CHECK-NEXT: Offset: |
| 15 | // CHECK-NEXT: Size: 22 | |
| 15 | // CHECK-NEXT: Size: 36 | |
| 16 | 16 | // CHECK-NEXT: Link: 0 |
| 17 | 17 | // CHECK-NEXT: Info: 0 |
| 18 | 18 | // CHECK-NEXT: AddressAlignment: 16 |
| 19 | 19 | |
| 20 | 20 | // CHECK: Name: sym1 |
| 21 | // CHECK-NEXT: Value: 0x201004 | |
| 21 | // CHECK-NEXT: Value: 0x201000 | |
| 22 | 22 | // CHECK-NEXT: Size: 8 |
| 23 | 23 | // CHECK-NEXT: Binding: Global |
| 24 | 24 | // CHECK-NEXT: Type: Object |
| ... | ... | @@ -26,7 +26,7 @@ |
| 26 | 26 | // CHECK-NEXT: Section: .bss |
| 27 | 27 | |
| 28 | 28 | // CHECK: Name: sym2 |
| 29 | // CHECK-NEXT: Value: 0x20100C | |
| 29 | // CHECK-NEXT: Value: 0x201008 | |
| 30 | 30 | // CHECK-NEXT: Size: 8 |
| 31 | 31 | // CHECK-NEXT: Binding: Global |
| 32 | 32 | // CHECK-NEXT: Type: Object |
| ... | ... | @@ -34,7 +34,7 @@ |
| 34 | 34 | // CHECK-NEXT: Section: .bss |
| 35 | 35 | |
| 36 | 36 | // CHECK: Name: sym3 |
| 37 | // CHECK-NEXT: Value: 0x201014 | |
| 37 | // CHECK-NEXT: Value: 0x201010 | |
| 38 | 38 | // CHECK-NEXT: Size: 2 |
| 39 | 39 | // CHECK-NEXT: Binding: Global |
| 40 | 40 | // CHECK-NEXT: Type: Object |
| ... | ... | @@ -42,7 +42,7 @@ |
| 42 | 42 | // CHECK-NEXT: Section: .bss |
| 43 | 43 | |
| 44 | 44 | // CHECK: Name: sym4 |
| 45 | // CHECK-NEXT: Value: 0x201000 | |
| 45 | // CHECK-NEXT: Value: 0x201020 | |
| 46 | 46 | // CHECK-NEXT: Size: 4 |
| 47 | 47 | // CHECK-NEXT: Binding: Global |
| 48 | 48 | // CHECK-NEXT: Type: Object |
deps/lld/test/ELF/compress-debug-sections-reloc.s created+26| ... | ... | @@ -0,0 +1,26 @@ |
| 1 | # REQUIRES: x86, zlib | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/compress-debug.s -o %t2.o | |
| 5 | # RUN: ld.lld %t2.o %t.o -o %t1 --compress-debug-sections=zlib -Ttext=0 | |
| 6 | # RUN: llvm-dwarfdump %t1 -debug-str | FileCheck %s | |
| 7 | # These two checks correspond to the patched values of a_sym and a_debug_sym. | |
| 8 | # D = 0x44 - address of .text input section for this file (the start address of | |
| 9 | # .text is 0 as requested on the command line, and the size of the | |
| 10 | #	 preceding .text in the other input file is 0x44). | |
| 11 | # C = 0x43 - offset of .debug_info section for this file (the size of | |
| 12 | # the preceding .debug_info from the other input file is 0x43). | |
| 13 | # CHECK: 0x00000000: "D" | |
| 14 | # CHECK: 0x00000004: "C" | |
| 15 | ||
| 16 | .text | |
| 17 | a_sym: | |
| 18 | nop | |
| 19 | ||
| 20 | .section .debug_str,"",@progbits | |
| 21 | .long a_sym | |
| 22 | .long a_debug_sym | |
| 23 | ||
| 24 | .section .debug_info,"",@progbits | |
| 25 | a_debug_sym: | |
| 26 | .long 0x88776655 |
deps/lld/test/ELF/compress-debug-sections.s+6-1| ... | ... | @@ -15,12 +15,17 @@ |
| 15 | 15 | # ZLIBFLAGS-NEXT: Flags [ |
| 16 | 16 | # ZLIBFLAGS-NEXT: SHF_COMPRESSED |
| 17 | 17 | |
| 18 | # RUN: llvm-dwarfdump %t1 -debug-dump=str | \ | |
| 18 | # RUN: llvm-dwarfdump %t1 -debug-str | \ | |
| 19 | 19 | # RUN: FileCheck %s --check-prefix=DEBUGSTR |
| 20 | 20 | # DEBUGSTR: .debug_str contents: |
| 21 | 21 | # DEBUGSTR-NEXT: AAAAAAAAAAAAAAAAAAAAAAAAAAA |
| 22 | 22 | # DEBUGSTR-NEXT: BBBBBBBBBBBBBBBBBBBBBBBBBBB |
| 23 | 23 | |
| 24 | ## Test alias. | |
| 25 | # RUN: ld.lld %t.o -o %t2 --compress-debug-sections zlib | |
| 26 | # RUN: llvm-objdump -s %t2 | FileCheck %s --check-prefix=ZLIBCONTENT | |
| 27 | # RUN: llvm-readobj -s %t2 | FileCheck %s --check-prefix=ZLIBFLAGS | |
| 28 | ||
| 24 | 29 | # RUN: not ld.lld %t.o -o %t1 --compress-debug-sections=zlib-gabi 2>&1 | \ |
| 25 | 30 | # RUN: FileCheck -check-prefix=ERR %s |
| 26 | 31 | # ERR: unknown --compress-debug-sections value: zlib-gabi |
deps/lld/test/ELF/compressed-debug-conflict.s created+29| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | # REQUIRES: x86, zlib | |
| 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 | |
| 4 | # RUN: not ld.lld %t.o %t.o -o %tout 2>&1 | FileCheck -check-prefix=ERROR %s | |
| 5 | ||
| 6 | # OBJ: Sections [ | |
| 7 | # OBJ: Section { | |
| 8 | # OBJ: Index: 3 | |
| 9 | # OBJ-NEXT: Name: .debug_line (16) | |
| 10 | # OBJ-NEXT: Type: SHT_PROGBITS (0x1) | |
| 11 | # OBJ-NEXT: Flags [ (0x800) | |
| 12 | # OBJ-NEXT: SHF_COMPRESSED (0x800) | |
| 13 | # OBJ-NEXT: ] | |
| 14 | ||
| 15 | # ERROR: error: duplicate symbol: main | |
| 16 | # ERROR-NEXT: >>> defined at reduced.c:2 (/tmp/reduced.c:2) | |
| 17 | # ERROR-NEXT: >>> | |
| 18 | # ERROR-NEXT: >>> defined at reduced.c:2 (/tmp/reduced.c:2) | |
| 19 | # ERROR-NEXT: >>> | |
| 20 | ||
| 21 | 	.text | |
| 22 | 	.file	"reduced.c" | |
| 23 | 	.globl	main | |
| 24 | main: | |
| 25 | 	.file	1 "/tmp" "reduced.c" | |
| 26 | 	.loc	1 2 0 | |
| 27 | 	xorl	%eax, %eax | |
| 28 | 	retl | |
| 29 | 	.file	2 "/tmp/repeat/repeat/repeat/repeat" "repeat.h" |
deps/lld/test/ELF/compressed-debug-input.s+8-8| ... | ... | @@ -39,10 +39,10 @@ |
| 39 | 39 | # GNU-NEXT: EntrySize: 1 |
| 40 | 40 | # GNU-NEXT: } |
| 41 | 41 | |
| 42 | # RUN: ld.lld %t -o %t.so -shared | |
| 42 | # RUN: ld.lld --hash-style=sysv %t -o %t.so -shared | |
| 43 | 43 | # RUN: llvm-readobj -sections -section-data %t.so | FileCheck -check-prefix=DATA %s |
| 44 | 44 | |
| 45 | # RUN: ld.lld %t2 -o %t2.so -shared | |
| 45 | # RUN: ld.lld --hash-style=sysv %t2 -o %t2.so -shared | |
| 46 | 46 | # RUN: llvm-readobj -sections -section-data %t2.so | FileCheck -check-prefix=DATA %s |
| 47 | 47 | |
| 48 | 48 | # DATA: Section { |
| ... | ... | @@ -59,13 +59,13 @@ |
| 59 | 59 | # DATA-NEXT: Link: 0 |
| 60 | 60 | # DATA-NEXT: Info: 0 |
| 61 | 61 | # DATA-NEXT: AddressAlignment: 1 |
| 62 | # DATA-NEXT: EntrySize: 0 | |
| 62 | # DATA-NEXT: EntrySize: 1 | |
| 63 | 63 | # DATA-NEXT: SectionData ( |
| 64 | # DATA-NEXT: 0000: 73686F72 7420756E 7369676E 65642069 |short unsigned i| | |
| 65 | # DATA-NEXT: 0010: 6E740075 6E736967 6E656420 696E7400 |nt.unsigned int.| | |
| 66 | # DATA-NEXT: 0020: 6C6F6E67 20756E73 69676E65 6420696E |long unsigned in| | |
| 67 | # DATA-NEXT: 0030: 74006368 61720075 6E736967 6E656420 |t.char.unsigned | | |
| 68 | # DATA-NEXT: 0040: 63686172 00 |char.| | |
| 64 | # DATA-NEXT: 0000: 6C6F6E67 20756E73 69676E65 6420696E |long unsigned in| | |
| 65 | # DATA-NEXT: 0010: 7400756E 7369676E 65642063 68617200 |t.unsigned char.| | |
| 66 | # DATA-NEXT: 0020: 756E7369 676E6564 20696E74 00636861 |unsigned int.cha| | |
| 67 | # DATA-NEXT: 0030: 72007368 6F727420 756E7369 676E6564 |r.short unsigned| | |
| 68 | # DATA-NEXT: 0040: 20696E74 00 | int.| | |
| 69 | 69 | # DATA-NEXT: ) |
| 70 | 70 | # DATA-NEXT: } |
| 71 | 71 |
deps/lld/test/ELF/conflict-debug-variable.s created+144| ... | ... | @@ -0,0 +1,144 @@ |
| 1 | # 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: not ld.lld %t.o %t.o -o %t 2>&1 | FileCheck %s | |
| 4 | ||
| 5 | # INPUT: .debug_info contents: | |
| 6 | # INPUT: DW_TAG_variable | |
| 7 | # INPUT-NEXT: DW_AT_name ("foo") | |
| 8 | # INPUT-NEXT: DW_AT_decl_file ("1.c") | |
| 9 | # INPUT-NEXT: DW_AT_decl_line (1) | |
| 10 | # INPUT-NEXT: DW_AT_type (cu + 0x0032 "int") | |
| 11 | # INPUT-NEXT: DW_AT_external (true) | |
| 12 | # INPUT-NEXT: DW_AT_location (DW_OP_addr 0x0) | |
| 13 | # INPUT: DW_TAG_variable | |
| 14 | # INPUT-NEXT: DW_AT_name ("bar") | |
| 15 | # INPUT-NEXT: DW_AT_decl_file ("1.c") | |
| 16 | # INPUT-NEXT: DW_AT_decl_line (2) | |
| 17 | # INPUT-NEXT: DW_AT_type (cu + 0x0032 "int") | |
| 18 | # INPUT-NEXT: DW_AT_external (true) | |
| 19 | # INPUT-NEXT: DW_AT_location (DW_OP_addr 0x0) | |
| 20 | ||
| 21 | ## Check we use information from .debug_info in messages. | |
| 22 | # CHECK: duplicate symbol: bar | |
| 23 | # CHECK-NEXT: >>> defined at 1.c:2 | |
| 24 | # CHECK-NEXT: >>> {{.*}}:(bar) | |
| 25 | # CHECK-NEXT: >>> defined at 1.c:2 | |
| 26 | # CHECK-NEXT: >>> {{.*}}:(.data+0x0) | |
| 27 | # CHECK: duplicate symbol: foo | |
| 28 | # CHECK-NEXT: >>> defined at 1.c:1 | |
| 29 | # CHECK-NEXT: >>> {{.*}}:(foo) | |
| 30 | # CHECK-NEXT: >>> defined at 1.c:1 | |
| 31 | # CHECK-NEXT: >>> {{.*}}:(.bss+0x0) | |
| 32 | ||
| 33 | ## Check that stripping debug sections does not break error reporting. | |
| 34 | # RUN: not ld.lld --strip-debug %t.o %t.o -o %t 2>&1 | FileCheck %s | |
| 35 | ||
| 36 | # Used reduced output from following code and gcc 7.1.0 | |
| 37 | # to produce this input file: | |
| 38 | # Source (1.c): | |
| 39 | # int foo = 0; | |
| 40 | # int bar = 1; | |
| 41 | # Invocation: g++ -g -S 1.c | |
| 42 | ||
| 43 | .bss | |
| 44 | .globl foo | |
| 45 | .type foo, @object | |
| 46 | .size foo, 4 | |
| 47 | foo: | |
| 48 | ||
| 49 | .data | |
| 50 | .globl bar | |
| 51 | .type bar, @object | |
| 52 | .size bar, 4 | |
| 53 | bar: | |
| 54 | ||
| 55 | .text | |
| 56 | .file 1 "1.c" | |
| 57 | ||
| 58 | .section .debug_info,"",@progbits | |
| 59 | .long 0x4b # Compile Unit: length = 0x0000004b) | |
| 60 | .value 0x4 # version = 0x0004 | |
| 61 | .long 0 # abbr_offset = 0x0 | |
| 62 | .byte 0x8 # addr_size = 0x08 | |
| 63 | ||
| 64 | .uleb128 0x1 # DW_TAG_compile_unit [1] * | |
| 65 | .long 0 # DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000000] = ) | |
| 66 | .byte 0x4 # DW_AT_language [DW_FORM_data1] (DW_LANG_C_plus_plus) | |
| 67 | .string "1.c" # DW_AT_name [DW_FORM_string] ("1.c") | |
| 68 | .long 0 # DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000000] = ) | |
| 69 | .long 0 # DW_AT_stmt_list [DW_FORM_sec_offset] (0x00000000) | |
| 70 | ||
| 71 | .uleb128 0x2 # DW_TAG_variable [2] | |
| 72 | .string "foo" # DW_AT_name [DW_FORM_string] ("foo") | |
| 73 | .byte 0x1 # DW_AT_decl_file [DW_FORM_data1] ("1.c") | |
| 74 | .byte 0x1 # DW_AT_decl_line [DW_FORM_data1] (1) | |
| 75 | .long 0x32 # DW_AT_type [DW_FORM_ref4] (cu + 0x0032 => {0x00000032}) | |
| 76 | .uleb128 0x9 # DW_AT_external [DW_FORM_flag_present] (true) | |
| 77 | .byte 0x3 | |
| 78 | .quad foo # DW_AT_location [DW_FORM_exprloc] (DW_OP_addr 0x0) | |
| 79 | ||
| 80 | .uleb128 0x3 # DW_TAG_base_type [3] | |
| 81 | .byte 0x4 # DW_AT_byte_size [DW_FORM_data1] (0x04) | |
| 82 | .byte 0x5 # DW_AT_encoding [DW_FORM_data1] (DW_ATE_signed) | |
| 83 | .string "int" # DW_AT_name [DW_FORM_string] ("int") | |
| 84 | ||
| 85 | .uleb128 0x2 # DW_TAG_variable [2] | |
| 86 | .string "bar" # DW_AT_name [DW_FORM_string] ("bar") | |
| 87 | .byte 0x1 # DW_AT_decl_file [DW_FORM_data1] ("1.c") | |
| 88 | .byte 0x2 # DW_AT_decl_line [DW_FORM_data1] (2) | |
| 89 | .long 0x32 # DW_AT_type [DW_FORM_ref4] (cu + 0x0032 => {0x00000032}) | |
| 90 | .uleb128 0x9 # DW_AT_external [DW_FORM_flag_present] (true) | |
| 91 | .byte 0x3 | |
| 92 | .quad bar # DW_AT_location [DW_FORM_exprloc] (DW_OP_addr 0x0) | |
| 93 | .byte 0 # END | |
| 94 | ||
| 95 | ||
| 96 | .section .debug_abbrev,"",@progbits | |
| 97 | .uleb128 0x1 # Abbreviation code. | |
| 98 | .uleb128 0x11 # DW_TAG_compile_unit | |
| 99 | ||
| 100 | .byte 0x1 # ID | |
| 101 | .uleb128 0x25 # DW_AT_producer, DW_FORM_strp | |
| 102 | .uleb128 0xe | |
| 103 | .uleb128 0x13 # DW_AT_language, DW_FORM_data1 | |
| 104 | .uleb128 0xb | |
| 105 | .uleb128 0x3 # DW_AT_name, DW_FORM_string | |
| 106 | .uleb128 0x8 | |
| 107 | .uleb128 0x1b # DW_AT_comp_dir, DW_FORM_strp | |
| 108 | .uleb128 0xe | |
| 109 | .uleb128 0x10 # DW_AT_stmt_list, DW_FORM_sec_offset | |
| 110 | .uleb128 0x17 | |
| 111 | .byte 0 | |
| 112 | .byte 0 | |
| 113 | ||
| 114 | .uleb128 0x2 # ID | |
| 115 | .uleb128 0x34 # DW_TAG_variable, DW_CHILDREN_no | |
| 116 | .byte 0 | |
| 117 | .uleb128 0x3 # DW_AT_name, DW_FORM_string | |
| 118 | .uleb128 0x8 | |
| 119 | .uleb128 0x3a # DW_AT_decl_file, DW_FORM_data1 | |
| 120 | .uleb128 0xb | |
| 121 | .uleb128 0x3b # DW_AT_decl_line, DW_FORM_data1 | |
| 122 | .uleb128 0xb | |
| 123 | .uleb128 0x49 # DW_AT_type, DW_FORM_ref4 | |
| 124 | .uleb128 0x13 | |
| 125 | .uleb128 0x3f # DW_AT_external, DW_FORM_flag_present | |
| 126 | .uleb128 0x19 | |
| 127 | .uleb128 0x2 # DW_AT_location, DW_FORM_exprloc | |
| 128 | .uleb128 0x18 | |
| 129 | .byte 0 | |
| 130 | .byte 0 | |
| 131 | ||
| 132 | .uleb128 0x3 # ID | |
| 133 | .uleb128 0x24 # DW_TAG_base_type, DW_CHILDREN_no | |
| 134 | .byte 0 | |
| 135 | .uleb128 0xb # DW_AT_byte_size, DW_FORM_data1 | |
| 136 | .uleb128 0xb | |
| 137 | .uleb128 0x3e # DW_AT_encoding, DW_FORM_data1 | |
| 138 | .uleb128 0xb | |
| 139 | .uleb128 0x3 # DW_AT_name, DW_FORM_string | |
| 140 | .uleb128 0x8 | |
| 141 | .byte 0 | |
| 142 | .byte 0 | |
| 143 | .byte 0 | |
| 144 |
deps/lld/test/ELF/conflict-debug-variable2.s created+160| ... | ... | @@ -0,0 +1,160 @@ |
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | |
| 2 | ||
| 3 | # RUN: llvm-dwarfdump -v %t.o | FileCheck -check-prefix=INPUT %s | |
| 4 | # INPUT: .debug_info contents: | |
| 5 | # INPUT: DW_TAG_variable | |
| 6 | # INPUT-NEXT: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000027] = "foo") | |
| 7 | # INPUT-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x0033 => {0x00000033} "int") | |
| 8 | # INPUT-NEXT: DW_AT_external [DW_FORM_flag_present] (true) | |
| 9 | # INPUT-NEXT: DW_AT_decl_file [DW_FORM_data1] ("/home/path/test.c") | |
| 10 | # INPUT-NEXT: DW_AT_decl_line [DW_FORM_data1] (1) | |
| 11 | # INPUT-NEXT: DW_AT_location [DW_FORM_exprloc] (DW_OP_addr 0x0) | |
| 12 | # INPUT: DW_TAG_variable | |
| 13 | # INPUT-NEXT: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000002f] = "bar") | |
| 14 | # INPUT-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x0033 => {0x00000033} "int") | |
| 15 | # INPUT-NEXT: DW_AT_external [DW_FORM_flag_present] (true) | |
| 16 | # INPUT-NEXT: DW_AT_decl_file [DW_FORM_data1] ("/home/path/test.c") | |
| 17 | # INPUT-NEXT: DW_AT_decl_line [DW_FORM_data1] (2) | |
| 18 | # INPUT-NEXT: DW_AT_location [DW_FORM_exprloc] (DW_OP_addr 0x0) | |
| 19 | ||
| 20 | ## 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 | # CHECK: duplicate symbol: bar | |
| 23 | # CHECK-NEXT: >>> defined at test.c:2 | |
| 24 | # CHECK-NEXT: >>> {{.*}}:(bar) | |
| 25 | # CHECK-NEXT: >>> defined at test.c:2 | |
| 26 | # CHECK-NEXT: >>> {{.*}}:(.data+0x0) | |
| 27 | # CHECK: duplicate symbol: foo | |
| 28 | # CHECK-NEXT: >>> defined at test.c:1 | |
| 29 | # CHECK-NEXT: >>> {{.*}}:(foo) | |
| 30 | # CHECK-NEXT: >>> defined at test.c:1 | |
| 31 | # CHECK-NEXT: >>> {{.*}}:(.bss+0x0) | |
| 32 | ||
| 33 | # Used reduced output from following code and clang | |
| 34 | # version 6.0.0 (trunk 316661) to produce this input file: | |
| 35 | # Source (test.c): | |
| 36 | # int foo = 0; | |
| 37 | # int bar = 1; | |
| 38 | # Invocation: clang -g -S test.c | |
| 39 | ||
| 40 | .text | |
| 41 | .file "test.c" | |
| 42 | .file 1 "test.c" | |
| 43 | ||
| 44 | .type foo,@object | |
| 45 | .bss | |
| 46 | .globl foo | |
| 47 | .p2align 2 | |
| 48 | foo: | |
| 49 | .long 0 | |
| 50 | .size foo, 4 | |
| 51 | ||
| 52 | .type bar,@object | |
| 53 | .data | |
| 54 | .globl bar | |
| 55 | .p2align 2 | |
| 56 | bar: | |
| 57 | .long 1 | |
| 58 | .size bar, 4 | |
| 59 | ||
| 60 | .section .debug_str,"MS",@progbits,1 | |
| 61 | .Linfo_string0: | |
| 62 | .asciz "clang version 6.0.0" | |
| 63 | .Linfo_string1: | |
| 64 | .asciz "test.c" | |
| 65 | .Linfo_string2: | |
| 66 | .asciz "/home/path/" | |
| 67 | .Linfo_string3: | |
| 68 | .asciz "foo" | |
| 69 | .Linfo_string4: | |
| 70 | .asciz "int" | |
| 71 | .Linfo_string5: | |
| 72 | .asciz "bar" | |
| 73 | ||
| 74 | .section .debug_abbrev,"",@progbits | |
| 75 | .byte 1 # Abbreviation Code | |
| 76 | .byte 17 # DW_TAG_compile_unit | |
| 77 | .byte 1 # DW_CHILDREN_yes | |
| 78 | .byte 37 # DW_AT_producer | |
| 79 | .byte 14 # DW_FORM_strp | |
| 80 | .byte 19 # DW_AT_language | |
| 81 | .byte 5 # DW_FORM_data2 | |
| 82 | .byte 3 # DW_AT_name | |
| 83 | .byte 14 # DW_FORM_strp | |
| 84 | .byte 16 # DW_AT_stmt_list | |
| 85 | .byte 23 # DW_FORM_sec_offset | |
| 86 | .byte 27 # DW_AT_comp_dir | |
| 87 | .byte 14 # DW_FORM_strp | |
| 88 | .ascii "\264B" # DW_AT_GNU_pubnames | |
| 89 | .byte 25 # DW_FORM_flag_present | |
| 90 | .byte 0 # EOM(1) | |
| 91 | .byte 0 # EOM(2) | |
| 92 | ||
| 93 | .byte 2 # Abbreviation Code | |
| 94 | .byte 52 # DW_TAG_variable | |
| 95 | .byte 0 # DW_CHILDREN_no | |
| 96 | .byte 3 # DW_AT_name | |
| 97 | .byte 14 # DW_FORM_strp | |
| 98 | .byte 73 # DW_AT_type | |
| 99 | .byte 19 # DW_FORM_ref4 | |
| 100 | .byte 63 # DW_AT_external | |
| 101 | .byte 25 # DW_FORM_flag_present | |
| 102 | .byte 58 # DW_AT_decl_file | |
| 103 | .byte 11 # DW_FORM_data1 | |
| 104 | .byte 59 # DW_AT_decl_line | |
| 105 | .byte 11 # DW_FORM_data1 | |
| 106 | .byte 2 # DW_AT_location | |
| 107 | .byte 24 # DW_FORM_exprloc | |
| 108 | .byte 0 # EOM(1) | |
| 109 | .byte 0 # EOM(2) | |
| 110 | ||
| 111 | .byte 3 # Abbreviation Code | |
| 112 | .byte 36 # DW_TAG_base_type | |
| 113 | .byte 0 # DW_CHILDREN_no | |
| 114 | .byte 3 # DW_AT_name | |
| 115 | .byte 14 # DW_FORM_strp | |
| 116 | .byte 62 # DW_AT_encoding | |
| 117 | .byte 11 # DW_FORM_data1 | |
| 118 | .byte 11 # DW_AT_byte_size | |
| 119 | .byte 11 # DW_FORM_data1 | |
| 120 | .byte 0 # EOM(1) | |
| 121 | .byte 0 # EOM(2) | |
| 122 | .byte 0 # EOM(3) | |
| 123 | ||
| 124 | .section .debug_info,"",@progbits | |
| 125 | .Lcu_begin0: | |
| 126 | .long 76 # Length of Unit | |
| 127 | .short 4 # DWARF version number | |
| 128 | .long .debug_abbrev # Offset Into Abbrev. Section | |
| 129 | .byte 8 # Address Size (in bytes) | |
| 130 | ||
| 131 | .byte 1 # Abbrev [1] 0xb:0x45 DW_TAG_compile_unit | |
| 132 | .long .Linfo_string0 # DW_AT_producer | |
| 133 | .short 12 # DW_AT_language | |
| 134 | .long .Linfo_string1 # DW_AT_name | |
| 135 | .long 0 # DW_AT_stmt_list | |
| 136 | .long .Linfo_string2 # DW_AT_comp_dir | |
| 137 | ||
| 138 | .byte 2 # Abbrev [2] 0x1e:0x15 DW_TAG_variable | |
| 139 | .long .Linfo_string3 # DW_AT_name | |
| 140 | .long 51 # DW_AT_type | |
| 141 | .byte 1 # DW_AT_decl_file | |
| 142 | .byte 1 # DW_AT_decl_line | |
| 143 | .byte 9 # DW_AT_location | |
| 144 | .byte 3 | |
| 145 | .quad foo | |
| 146 | ||
| 147 | .byte 3 # Abbrev [3] 0x33:0x7 DW_TAG_base_type | |
| 148 | .long .Linfo_string4 # DW_AT_name | |
| 149 | .byte 5 # DW_AT_encoding | |
| 150 | .byte 4 # DW_AT_byte_size | |
| 151 | ||
| 152 | .byte 2 # Abbrev [2] 0x3a:0x15 DW_TAG_variable | |
| 153 | .long .Linfo_string5 # DW_AT_name | |
| 154 | .long 51 # DW_AT_type | |
| 155 | .byte 1 # DW_AT_decl_file | |
| 156 | .byte 2 # DW_AT_decl_line | |
| 157 | .byte 9 # DW_AT_location | |
| 158 | .byte 3 | |
| 159 | .quad bar | |
| 160 | .byte 0 # End Of Children Mark |
deps/lld/test/ELF/copy-errors.s+3| ... | ... | @@ -9,6 +9,9 @@ |
| 9 | 9 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x1) |
| 10 | 10 | // CHECK: symbol 'zed' defined in {{.*}}.so has no type |
| 11 | 11 | |
| 12 | // 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 | |
| 14 | ||
| 12 | 15 | .global _start |
| 13 | 16 | _start: |
| 14 | 17 | call bar |
deps/lld/test/ELF/copy-rel-abs.s created+47| ... | ... | @@ -0,0 +1,47 @@ |
| 1 | // REQUIRES: x86 | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-rel-abs.s -o %t1.o | |
| 3 | // RUN: ld.lld --hash-style=gnu -shared %t1.o -o %t1.so | |
| 4 | // RUN: llvm-readelf --dyn-symbols %t1.so | FileCheck --check-prefix=SYMS %s | |
| 5 | ||
| 6 | // The symbols have the same st_value, but one is ABS. | |
| 7 | // SYMS: 0000000000001000 {{.*}} 4 bar | |
| 8 | // SYMS: 0000000000001000 {{.*}} 4 foo | |
| 9 | // SYMS: 0000000000001000 {{.*}} ABS zed | |
| 10 | ||
| 11 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o | |
| 12 | // RUN: ld.lld %t2.o %t1.so -o %t2 | |
| 13 | // RUN: llvm-readobj --dyn-symbols %t2 | FileCheck %s | |
| 14 | ||
| 15 | // CHECK: DynamicSymbols [ | |
| 16 | // CHECK-NEXT: Symbol { | |
| 17 | // CHECK-NEXT: Name: | |
| 18 | // CHECK-NEXT: Value: | |
| 19 | // CHECK-NEXT: Size: | |
| 20 | // CHECK-NEXT: Binding: | |
| 21 | // CHECK-NEXT: Type: | |
| 22 | // CHECK-NEXT: Other: | |
| 23 | // CHECK-NEXT: Section: | |
| 24 | // CHECK-NEXT: } | |
| 25 | // CHECK-NEXT: Symbol { | |
| 26 | // CHECK-NEXT: Name: foo | |
| 27 | // CHECK-NEXT: Value: | |
| 28 | // CHECK-NEXT: Size: | |
| 29 | // CHECK-NEXT: Binding: | |
| 30 | // CHECK-NEXT: Type: | |
| 31 | // CHECK-NEXT: Other: | |
| 32 | // CHECK-NEXT: Section: .bss.rel.ro | |
| 33 | // CHECK-NEXT: } | |
| 34 | // CHECK-NEXT: Symbol { | |
| 35 | // CHECK-NEXT: Name: bar | |
| 36 | // CHECK-NEXT: Value: | |
| 37 | // CHECK-NEXT: Size: | |
| 38 | // CHECK-NEXT: Binding: | |
| 39 | // CHECK-NEXT: Type: | |
| 40 | // CHECK-NEXT: Other: | |
| 41 | // CHECK-NEXT: Section: .bss.rel.ro | |
| 42 | // CHECK-NEXT: } | |
| 43 | // CHECK-NEXT: ] | |
| 44 | ||
| 45 | .global _start | |
| 46 | _start: | |
| 47 | .quad foo |
deps/lld/test/ELF/copy-rel-large.s created+20| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | // REQUIRES: x86 | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-rel-large.s -o %t1.o | |
| 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 | |
| 5 | // RUN: ld.lld %t2.o %t1.so -o %t2 | |
| 6 | // RUN: llvm-readobj --dyn-symbols %t2 | FileCheck %s | |
| 7 | ||
| 8 | .global _start | |
| 9 | _start: | |
| 10 | .quad foo | |
| 11 | ||
| 12 | // CHECK: Symbol { | |
| 13 | // CHECK: Name: foo | |
| 14 | // CHECK-NEXT: Value: | |
| 15 | // CHECK-NEXT: Size: 4294967297 | |
| 16 | // CHECK-NEXT: Binding: | |
| 17 | // CHECK-NEXT: Type: | |
| 18 | // CHECK-NEXT: Other: | |
| 19 | // CHECK-NEXT: Section: .bss.rel.ro | |
| 20 | // CHECK-NEXT: } |
deps/lld/test/ELF/copy-rel-pie.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 2 | 2 | // RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux |
| 3 | 3 | // RUN: ld.lld %t2.o -o %t2.so -shared |
| 4 | // RUN: ld.lld %t.o %t2.so -o %t.exe -pie | |
| 4 | // RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t.exe -pie | |
| 5 | 5 | // RUN: llvm-readobj -s -r %t.exe | FileCheck %s |
| 6 | 6 | // RUN: llvm-objdump -d %t.exe | FileCheck --check-prefix=DISASM %s |
| 7 | 7 |
deps/lld/test/ELF/corrupted-version-reference.s created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 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 | |
| 4 | ||
| 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 | |
| 7 | ||
| 8 | # CHECK: error: corrupt input file: version definition index 0 for symbol _Jv_RegisterClasses is out of bounds | |
| 9 | # CHECK-NEXT: >>> defined in {{.*}}/corrupt-version-reference.so | |
| 10 | ||
| 11 | .globl __start | |
| 12 | __start: | |
| 13 | dla $a0, __cxa_finalize | |
| 14 | nop |
deps/lld/test/ELF/debug-gc.s+2-2| ... | ... | @@ -4,11 +4,11 @@ |
| 4 | 4 | # RUN: llvm-objdump -s %t1 | FileCheck %s |
| 5 | 5 | |
| 6 | 6 | # CHECK: Contents of section .debug_str: |
| 7 | # CHECK-NEXT: 0000 41414100 42424200 43434300 AAA.BBB.CCC. | |
| 7 | # CHECK-NEXT: 0000 41414100 43434300 42424200 AAA.CCC.BBB. | |
| 8 | 8 | # CHECK: Contents of section .foo: |
| 9 | 9 | # CHECK-NEXT: 0000 2a000000 |
| 10 | 10 | # CHECK: Contents of section .debug_info: |
| 11 | # CHECK-NEXT: 0000 00000000 04000000 | |
| 11 | # CHECK-NEXT: 0000 00000000 08000000 | |
| 12 | 12 | |
| 13 | 13 | .globl _start |
| 14 | 14 | _start: |
deps/lld/test/ELF/defsym-dynamic.s created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 3 | # RUN: ld.lld -o %t.so -shared %t.o --defsym=foo2=foo1 | |
| 4 | # RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s | |
| 5 | ||
| 6 | # CHECK: Name: foo1 | |
| 7 | # CHECK: Name: foo2 | |
| 8 | ||
| 9 | .globl foo1 | |
| 10 | foo1 = 0x123 |
deps/lld/test/ELF/defsym.s+37-5| ... | ... | @@ -19,7 +19,7 @@ |
| 19 | 19 | # CHECK-NEXT: Section: Absolute |
| 20 | 20 | # CHECK-NEXT: } |
| 21 | 21 | # CHECK-NEXT: Symbol { |
| 22 | # CHECK-NEXT: Name: foo1 | |
| 22 | # CHECK-NEXT: Name: foo2 | |
| 23 | 23 | # CHECK-NEXT: Value: 0x123 |
| 24 | 24 | # CHECK-NEXT: Size: |
| 25 | 25 | # CHECK-NEXT: Binding: Global |
| ... | ... | @@ -33,11 +33,43 @@ |
| 33 | 33 | # USE-NEXT: _start: |
| 34 | 34 | # USE-NEXT: movl $0x123, %edx |
| 35 | 35 | |
| 36 | # RUN: not ld.lld -o %t %t.o --defsym=foo2=1 2>&1 | FileCheck %s -check-prefix=ERR1 | |
| 37 | # ERR1: error: --defsym: symbol name expected, but got 1 | |
| 36 | # RUN: ld.lld -o %t %t.o --defsym=foo2=1 | |
| 37 | # RUN: llvm-readobj -t -s %t | FileCheck %s --check-prefix=ABS | |
| 38 | 38 | |
| 39 | # RUN: not ld.lld -o %t %t.o --defsym=foo2=und 2>&1 | FileCheck %s -check-prefix=ERR2 | |
| 40 | # ERR2: error: -defsym: undefined symbol: und | |
| 39 | # ABS: Symbol { | |
| 40 | # ABS: Name: foo2 | |
| 41 | # ABS-NEXT: Value: 0x1 | |
| 42 | # ABS-NEXT: Size: | |
| 43 | # ABS-NEXT: Binding: Global | |
| 44 | # ABS-NEXT: Type: | |
| 45 | # ABS-NEXT: Other: | |
| 46 | # ABS-NEXT: Section: Absolute | |
| 47 | # ABS-NEXT: } | |
| 48 | ||
| 49 | # RUN: ld.lld -o %t %t.o --defsym=foo2=foo1+5 | |
| 50 | # RUN: llvm-readobj -t -s %t | FileCheck %s --check-prefix=EXPR | |
| 51 | ||
| 52 | # EXPR: Symbol { | |
| 53 | # EXPR: Name: foo1 | |
| 54 | # EXPR-NEXT: Value: 0x123 | |
| 55 | # EXPR-NEXT: Size: | |
| 56 | # EXPR-NEXT: Binding: Global | |
| 57 | # EXPR-NEXT: Type: | |
| 58 | # EXPR-NEXT: Other: | |
| 59 | # EXPR-NEXT: Section: Absolute | |
| 60 | # EXPR-NEXT: } | |
| 61 | # EXPR-NEXT: Symbol { | |
| 62 | # EXPR-NEXT: Name: foo2 | |
| 63 | # EXPR-NEXT: Value: 0x128 | |
| 64 | # EXPR-NEXT: Size: | |
| 65 | # EXPR-NEXT: Binding: Global | |
| 66 | # EXPR-NEXT: Type: | |
| 67 | # EXPR-NEXT: Other: | |
| 68 | # EXPR-NEXT: Section: Absolute | |
| 69 | # EXPR-NEXT: } | |
| 70 | ||
| 71 | # RUN: not ld.lld -o %t %t.o --defsym=foo2=und 2>&1 | FileCheck %s -check-prefix=ERR | |
| 72 | # ERR: error: -defsym:1: symbol not found: und | |
| 41 | 73 | |
| 42 | 74 | .globl foo1 |
| 43 | 75 | foo1 = 0x123 |
deps/lld/test/ELF/driver-access.test+1-1| ... | ... | @@ -7,7 +7,7 @@ |
| 7 | 7 | # RUN: mkdir -p %t.dir |
| 8 | 8 | # RUN: chmod 100 %t.dir |
| 9 | 9 | # RUN: cd %t.dir |
| 10 | # RUN: ld.lld %t.o -o %t.exe | |
| 10 | # RUN: ld.lld %t.o -o %t.exe -M | |
| 11 | 11 | # RUN: chmod 755 %t.dir |
| 12 | 12 | |
| 13 | 13 | .globl _start |
deps/lld/test/ELF/driver.test+2-2| ... | ... | @@ -18,10 +18,10 @@ |
| 18 | 18 | # HELP: : supported targets:{{.*}} elf |
| 19 | 19 | |
| 20 | 20 | # RUN: ld.lld --version 2>&1 | FileCheck -check-prefix=VERSION %s |
| 21 | # RUN: ld.lld -v 2>&1 | FileCheck -check-prefix=VERSION %s | |
| 22 | # RUN: not ld.lld -v xyz 2>&1 | FileCheck -check-prefix=VERSION %s | |
| 21 | 23 | # VERSION: LLD {{.*}} (compatible with GNU linkers) |
| 22 | 24 | |
| 23 | # RUN: not ld.lld -v 2>&1 | FileCheck -check-prefix=VERSION %s | |
| 24 | ||
| 25 | 25 | ## Attempt to link DSO with -r |
| 26 | 26 | # RUN: ld.lld -shared %t -o %t.so |
| 27 | 27 | # RUN: not ld.lld -r %t.so %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR %s |
deps/lld/test/ELF/duplicated-synthetic-sym.s+2-1| ... | ... | @@ -1,9 +1,10 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | 2 | // RUN: cd %S |
| 3 | 3 | // RUN: not ld.lld %t.o --format=binary duplicated-synthetic-sym.s -o %t.elf 2>&1 | FileCheck %s |
| 4 | // RUN: not ld.lld %t.o --format binary duplicated-synthetic-sym.s -o %t.elf 2>&1 | FileCheck %s | |
| 4 | 5 | |
| 5 | 6 | // CHECK: duplicate symbol: _binary_duplicated_synthetic_sym_s_start |
| 6 | // CHECK: defined at (internal):(.data+0x0) | |
| 7 | // CHECK: defined at <internal>:(.data+0x0) | |
| 7 | 8 | |
| 8 | 9 | .globl _binary_duplicated_synthetic_sym_s_start |
| 9 | 10 | _binary_duplicated_synthetic_sym_s_start: |
deps/lld/test/ELF/dynamic-got.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o |
| 3 | // RUN: ld.lld %t.o -o %t.so -shared | |
| 3 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | |
| 4 | 4 | // RUN: llvm-readobj -s -l -section-data -r %t.so | FileCheck %s |
| 5 | 5 | |
| 6 | 6 | // CHECK: Name: .got |
deps/lld/test/ELF/dynamic-list-empty.s created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # BFD reports a parse error on empty lists, but it is clear how to | |
| 4 | # handle it. | |
| 5 | ||
| 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 7 | # RUN: echo "{ };" > %t.list | |
| 8 | # RUN: ld.lld -dynamic-list %t.list -shared %t.o -o %t.so | |
| 9 | # RUN: llvm-readobj -r %t.so | FileCheck %s | |
| 10 | ||
| 11 | # CHECK: Relocations [ | |
| 12 | # CHECK-NEXT: ] | |
| 13 | ||
| 14 | .globl foo | |
| 15 | foo: | |
| 16 | ret | |
| 17 | ||
| 18 | call foo@PLT |
deps/lld/test/ELF/dynamic-list-preempt.s created+76| ... | ... | @@ -0,0 +1,76 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 4 | # RUN: echo "{ foo; zed; };" > %t.list | |
| 5 | # RUN: echo "{ global: foo; bar; local: *; };" > %t.vers | |
| 6 | # RUN: ld.lld --hash-style=sysv -fatal-warnings -dynamic-list %t.list -version-script %t.vers -shared %t.o -o %t.so | |
| 7 | # RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOCS %s | |
| 8 | # RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=DYNSYMS %s | |
| 9 | ||
| 10 | # RELOCS: Relocations [ | |
| 11 | # RELOCS-NEXT: Section ({{.*}}) .rela.plt { | |
| 12 | # RELOCS-NEXT: R_X86_64_JUMP_SLOT foo 0x0 | |
| 13 | # RELOCS-NEXT: R_X86_64_JUMP_SLOT ext 0x0 | |
| 14 | # RELOCS-NEXT: } | |
| 15 | # RELOCS-NEXT: ] | |
| 16 | ||
| 17 | # DYNSYMS: DynamicSymbols [ | |
| 18 | # DYNSYMS-NEXT: Symbol { | |
| 19 | # DYNSYMS-NEXT: Name: @ (0) | |
| 20 | # DYNSYMS-NEXT: Value: 0x0 | |
| 21 | # DYNSYMS-NEXT: Size: 0 | |
| 22 | # DYNSYMS-NEXT: Binding: Local | |
| 23 | # DYNSYMS-NEXT: Type: None | |
| 24 | # DYNSYMS-NEXT: Other: 0 | |
| 25 | # DYNSYMS-NEXT: Section: Undefined | |
| 26 | # DYNSYMS-NEXT: } | |
| 27 | # DYNSYMS-NEXT: Symbol { | |
| 28 | # DYNSYMS-NEXT: Name: bar@ | |
| 29 | # DYNSYMS-NEXT: Value: | |
| 30 | # DYNSYMS-NEXT: Size: | |
| 31 | # DYNSYMS-NEXT: Binding: Global | |
| 32 | # DYNSYMS-NEXT: Type: | |
| 33 | # DYNSYMS-NEXT: Other: | |
| 34 | # DYNSYMS-NEXT: Section: | |
| 35 | # DYNSYMS-NEXT: } | |
| 36 | # DYNSYMS-NEXT: Symbol { | |
| 37 | # DYNSYMS-NEXT: Name: ext@ | |
| 38 | # DYNSYMS-NEXT: Value: | |
| 39 | # DYNSYMS-NEXT: Size: | |
| 40 | # DYNSYMS-NEXT: Binding: Global | |
| 41 | # DYNSYMS-NEXT: Type: | |
| 42 | # DYNSYMS-NEXT: Other: | |
| 43 | # DYNSYMS-NEXT: Section: | |
| 44 | # DYNSYMS-NEXT: } | |
| 45 | # DYNSYMS-NEXT: Symbol { | |
| 46 | # DYNSYMS-NEXT: Name: foo@ | |
| 47 | # DYNSYMS-NEXT: Value: | |
| 48 | # DYNSYMS-NEXT: Size: | |
| 49 | # DYNSYMS-NEXT: Binding: Global | |
| 50 | # DYNSYMS-NEXT: Type: | |
| 51 | # DYNSYMS-NEXT: Other: | |
| 52 | # DYNSYMS-NEXT: Section: | |
| 53 | # DYNSYMS-NEXT: } | |
| 54 | # DYNSYMS-NEXT: ] | |
| 55 | ||
| 56 | .globl foo | |
| 57 | foo: | |
| 58 | ret | |
| 59 | ||
| 60 | .globl bar | |
| 61 | bar: | |
| 62 | ret | |
| 63 | ||
| 64 | .globl baz | |
| 65 | baz: | |
| 66 | ret | |
| 67 | ||
| 68 | .globl zed | |
| 69 | zed: | |
| 70 | ret | |
| 71 | ||
| 72 | call foo@PLT | |
| 73 | call bar@PLT | |
| 74 | call baz@PLT | |
| 75 | call zed@PLT | |
| 76 | call ext@PLT |
deps/lld/test/ELF/dynamic-list-weak-archive.s created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/dynamic-list-weak-archive.s -o %t2.o | |
| 5 | # RUN: rm -f %t.a | |
| 6 | # RUN: llvm-ar rcs %t.a %t2.o | |
| 7 | # RUN: echo "{ zed; };" > %t.list | |
| 8 | # RUN: ld.lld -shared --dynamic-list %t.list %t1.o %t.a -o %t.so | |
| 9 | # RUN: llvm-readobj -r %t.so | FileCheck %s | |
| 10 | ||
| 11 | # CHECK: Relocations [ | |
| 12 | # CHECK-NEXT: Section ({{.*}}) .rela.plt { | |
| 13 | # CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT foo | |
| 14 | # CHECK-NEXT: } | |
| 15 | # CHECK-NEXT: ] | |
| 16 | ||
| 17 | callq foo@PLT | |
| 18 | .weak foo |
deps/lld/test/ELF/dynamic-list-wildcard.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 "{ foo1*; };" > %t.list | |
| 6 | # RUN: ld.lld --hash-style=sysv -pie --dynamic-list %t.list %t -o %t.exe | |
| 7 | # RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s | |
| 8 | ||
| 9 | # CHECK: DynamicSymbols [ | |
| 10 | # CHECK-NEXT: Symbol { | |
| 11 | # CHECK-NEXT: Name:	 @ (0) | |
| 12 | # CHECK-NEXT: Value:	 0x0 | |
| 13 | # CHECK-NEXT: Size:	 0 | |
| 14 | # CHECK-NEXT: Binding:	 Local (0x0) | |
| 15 | # CHECK-NEXT: Type:	 None (0x0) | |
| 16 | # CHECK-NEXT: Other:	 0 | |
| 17 | # CHECK-NEXT: Section:	 Undefined (0x0) | |
| 18 | # CHECK-NEXT: } | |
| 19 | # CHECK-NEXT: Symbol { | |
| 20 | # CHECK-NEXT: Name:	 foo1@ (1) | |
| 21 | # CHECK-NEXT: Value:	 0x1000 | |
| 22 | # CHECK-NEXT: Size:	 0 | |
| 23 | # CHECK-NEXT: Binding:	 Global (0x1) | |
| 24 | # CHECK-NEXT: Type:	 None (0x0) | |
| 25 | # CHECK-NEXT: Other:	 0 | |
| 26 | # CHECK-NEXT: Section:	 .text (0x4) | |
| 27 | # CHECK-NEXT: } | |
| 28 | # CHECK-NEXT: Symbol { | |
| 29 | # CHECK-NEXT: Name:	 foo11@ (6) | |
| 30 | # CHECK-NEXT: Value:	 0x1001 | |
| 31 | # CHECK-NEXT: Size:	 0 | |
| 32 | # CHECK-NEXT: Binding:	 Global (0x1) | |
| 33 | # CHECK-NEXT: Type:	 None (0x0) | |
| 34 | # CHECK-NEXT: Other:	 0 | |
| 35 | # CHECK-NEXT: Section:	 .text (0x4) | |
| 36 | # CHECK-NEXT: } | |
| 37 | # CHECK-NEXT: ] | |
| 38 | ||
| 39 | .globl foo1 | |
| 40 | foo1: | |
| 41 | ret | |
| 42 | ||
| 43 | .globl foo11 | |
| 44 | foo11: | |
| 45 | ret | |
| 46 | ||
| 47 | .globl foo2 | |
| 48 | foo2: | |
| 49 | ret | |
| 50 | ||
| 51 | .globl _start | |
| 52 | _start: | |
| 53 | retq |
deps/lld/test/ELF/dynamic-list.s+9-13| ... | ... | @@ -1,28 +1,24 @@ |
| 1 | ## There is some bad quoting interaction between lit's internal shell, which is | |
| 2 | ## implemented in Python, and the Cygwin implementations of the Unix utilities. | |
| 3 | ## Avoid running these tests on Windows for now by requiring a real shell. | |
| 4 | ||
| 5 | 1 | # REQUIRES: x86 |
| 6 | 2 | |
| 7 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 8 | # RUN: ld.lld -shared %t2.o -soname shared -o %t2.so | |
| 4 | # RUN: ld.lld --hash-style=sysv -shared %t2.o -soname shared -o %t2.so | |
| 9 | 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 10 | 6 | |
| 11 | 7 | ## Check exporting only one symbol. |
| 12 | 8 | # RUN: echo "{ foo1; };" > %t.list |
| 13 | # RUN: ld.lld --dynamic-list %t.list %t %t2.so -o %t.exe | |
| 9 | # RUN: ld.lld --hash-style=sysv --dynamic-list %t.list %t %t2.so -o %t.exe | |
| 14 | 10 | # RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s |
| 15 | 11 | |
| 16 | 12 | ## And now using quoted strings (the output is the same since it does |
| 17 | 13 | ## use any wildcard character). |
| 18 | 14 | # RUN: echo "{ \"foo1\"; };" > %t.list |
| 19 | # RUN: ld.lld --dynamic-list %t.list %t %t2.so -o %t.exe | |
| 15 | # RUN: ld.lld --hash-style=sysv --dynamic-list %t.list %t %t2.so -o %t.exe | |
| 20 | 16 | # RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s |
| 21 | 17 | |
| 22 | 18 | ## And now using --export-dynamic-symbol. |
| 23 | # RUN: ld.lld --export-dynamic-symbol foo1 %t %t2.so -o %t.exe | |
| 19 | # RUN: ld.lld --hash-style=sysv --export-dynamic-symbol foo1 %t %t2.so -o %t.exe | |
| 24 | 20 | # RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s |
| 25 | # RUN: ld.lld --export-dynamic-symbol=foo1 %t %t2.so -o %t.exe | |
| 21 | # RUN: ld.lld --hash-style=sysv --export-dynamic-symbol=foo1 %t %t2.so -o %t.exe | |
| 26 | 22 | # RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s |
| 27 | 23 | |
| 28 | 24 | # CHECK: DynamicSymbols [ |
| ... | ... | @@ -49,11 +45,11 @@ |
| 49 | 45 | |
| 50 | 46 | ## Now export all the foo1, foo2, and foo31 symbols |
| 51 | 47 | # RUN: echo "{ foo1; foo2; foo31; };" > %t.list |
| 52 | # RUN: ld.lld --dynamic-list %t.list %t %t2.so -o %t.exe | |
| 48 | # RUN: ld.lld --hash-style=sysv --dynamic-list %t.list %t %t2.so -o %t.exe | |
| 53 | 49 | # RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK2 %s |
| 54 | 50 | # RUN: echo "{ foo1; foo2; };" > %t1.list |
| 55 | 51 | # RUN: echo "{ foo31; };" > %t2.list |
| 56 | # RUN: ld.lld --dynamic-list %t1.list --dynamic-list %t2.list %t %t2.so -o %t.exe | |
| 52 | # RUN: ld.lld --hash-style=sysv --dynamic-list %t1.list --dynamic-list %t2.list %t %t2.so -o %t.exe | |
| 57 | 53 | # RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK2 %s |
| 58 | 54 | |
| 59 | 55 | # CHECK2: DynamicSymbols [ |
| ... | ... | @@ -99,11 +95,11 @@ |
| 99 | 95 | ## --export-dynamic overrides --dynamic-list, i.e. --export-dynamic with an |
| 100 | 96 | ## incomplete dynamic-list still exports everything. |
| 101 | 97 | # RUN: echo "{ foo2; };" > %t.list |
| 102 | # RUN: ld.lld --dynamic-list %t.list --export-dynamic %t %t2.so -o %t.exe | |
| 98 | # RUN: ld.lld --hash-style=sysv --dynamic-list %t.list --export-dynamic %t %t2.so -o %t.exe | |
| 103 | 99 | # RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK3 %s |
| 104 | 100 | |
| 105 | 101 | ## The same with --export-dynamic-symbol. |
| 106 | # RUN: ld.lld --export-dynamic-symbol=foo2 --export-dynamic %t %t2.so -o %t.exe | |
| 102 | # RUN: ld.lld --hash-style=sysv --export-dynamic-symbol=foo2 --export-dynamic %t %t2.so -o %t.exe | |
| 107 | 103 | # RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK3 %s |
| 108 | 104 | |
| 109 | 105 | # CHECK3: DynamicSymbols [ |
deps/lld/test/ELF/dynamic-no-rosegment.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: ld.lld -shared --no-rosegment -z rodynamic -o %t %t.o | |
| 4 | # RUN: llvm-readobj -dynamic-table -s %t | FileCheck %s | |
| 5 | ||
| 6 | # CHECK: DynamicSection [ (7 entries) | |
| 7 | # CHECK-NEXT: Tag Type Name/Value | |
| 8 | # CHECK-NEXT: 0x0000000000000006 SYMTAB 0x120 | |
| 9 | # CHECK-NEXT: 0x000000000000000B SYMENT 24 (bytes) | |
| 10 | # CHECK-NEXT: 0x0000000000000005 STRTAB 0x1D0 | |
| 11 | # CHECK-NEXT: 0x000000000000000A STRSZ 1 (bytes) | |
| 12 | # CHECK-NEXT: 0x000000006FFFFEF5 GNU_HASH 0x138 | |
| 13 | # CHECK-NEXT: 0x0000000000000004 HASH 0x150 | |
| 14 | # CHECK-NEXT: 0x0000000000000000 NULL 0x0 | |
| 15 | # CHECK-NEXT: ] |
deps/lld/test/ELF/dynamic-reloc-in-ro.s+3-3| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | // RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s |
| 4 | 4 | |
| 5 | // CHECK: can't create dynamic relocation R_X86_64_64 against local symbol in readonly segment | |
| 6 | // CHECK: >>> defined in {{.*}}.o | |
| 7 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) | |
| 5 | // CHECK: can't create dynamic relocation R_X86_64_64 against local symbol in readonly segment; recompile object files with -fPIC | |
| 6 | // CHECK-NEXT: >>> defined in {{.*}}.o | |
| 7 | // CHECK-NEXT: >>> referenced by {{.*}}.o:(.text+0x0) | |
| 8 | 8 | |
| 9 | 9 | foo: |
| 10 | 10 | .quad foo |
deps/lld/test/ELF/dynamic-reloc.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/dynamic-reloc.s -o %t3.o |
| 4 | 4 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| 5 | // RUN: ld.lld %t.o %t3.o %t2.so -o %t | |
| 5 | // RUN: ld.lld --hash-style=sysv %t.o %t3.o %t2.so -o %t | |
| 6 | 6 | // RUN: llvm-readobj -dynamic-table -r --expand-relocs -s %t | FileCheck %s |
| 7 | 7 | // REQUIRES: x86 |
| 8 | 8 |
deps/lld/test/ELF/dynstr-no-rosegment.s created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | # Verify that a .dynstr in the .text segment has null byte terminators | |
| 2 | ||
| 3 | # REQUIRES: x86 | |
| 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 | |
| 6 | # RUN: llvm-objdump %t.so -s -j .dynstr | FileCheck %s | |
| 7 | ||
| 8 | # CHECK: 00666f6f 00 .foo. | |
| 9 | ||
| 10 | .globl foo | |
| 11 | foo: | |
| 12 | ret |
deps/lld/test/ELF/dynsym-no-rosegment.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 -shared --no-rosegment -o %t %t.o | |
| 4 | # RUN: llvm-readobj -dyn-symbols -s %t | FileCheck %s | |
| 5 | ||
| 6 | # CHECK: DynamicSymbols [ | |
| 7 | # CHECK-NEXT: Symbol { | |
| 8 | # CHECK-NEXT: Name: @ (0) | |
| 9 | # CHECK-NEXT: Value: 0x0 | |
| 10 | # CHECK-NEXT: Size: 0 | |
| 11 | # CHECK-NEXT: Binding: Local | |
| 12 | # CHECK-NEXT: Type: None | |
| 13 | # CHECK-NEXT: Other: 0 | |
| 14 | # CHECK-NEXT: Section: Undefined | |
| 15 | # CHECK-NEXT: } | |
| 16 | # CHECK-NEXT: Symbol { | |
| 17 | # CHECK-NEXT: Name: undef@ | |
| 18 | # CHECK-NEXT: Value: 0x0 | |
| 19 | # CHECK-NEXT: Size: 0 | |
| 20 | # CHECK-NEXT: Binding: Global | |
| 21 | # CHECK-NEXT: Type: None | |
| 22 | # CHECK-NEXT: Other: 0 | |
| 23 | # CHECK-NEXT: Section: Undefined | |
| 24 | # CHECK-NEXT: } | |
| 25 | # CHECK-NEXT: ] | |
| 26 | ||
| 27 | callq undef@PLT |
deps/lld/test/ELF/dynsym-pie.s+48-4| ... | ... | @@ -3,6 +3,51 @@ |
| 3 | 3 | # RUN: ld.lld -pie %t -o %t.out |
| 4 | 4 | # RUN: llvm-readobj -t -dyn-symbols %t.out | FileCheck %s |
| 5 | 5 | |
| 6 | # CHECK: Symbols [ | |
| 7 | # CHECK: Symbol { | |
| 8 | # CHECK: Name: hidden | |
| 9 | # CHECK-NEXT: Value: 0x1000 | |
| 10 | # CHECK-NEXT: Size: 0 | |
| 11 | # CHECK-NEXT: Binding: Local | |
| 12 | # CHECK-NEXT: Type: None | |
| 13 | # CHECK-NEXT: Other [ | |
| 14 | # CHECK-NEXT: STV_HIDDEN | |
| 15 | # CHECK-NEXT: ] | |
| 16 | # CHECK-NEXT: Section: .text | |
| 17 | # CHECK-NEXT: } | |
| 18 | # CHECK: Symbol { | |
| 19 | # CHECK: Name: internal | |
| 20 | # CHECK-NEXT: Value: 0x1000 | |
| 21 | # CHECK-NEXT: Size: 0 | |
| 22 | # CHECK-NEXT: Binding: Local | |
| 23 | # CHECK-NEXT: Type: None | |
| 24 | # CHECK-NEXT: Other [ | |
| 25 | # CHECK-NEXT: STV_INTERNAL | |
| 26 | # CHECK-NEXT: ] | |
| 27 | # CHECK-NEXT: Section: .text | |
| 28 | # CHECK-NEXT: } | |
| 29 | # CHECK: Symbol { | |
| 30 | # CHECK: Name: default | |
| 31 | # CHECK-NEXT: Value: 0x1000 | |
| 32 | # CHECK-NEXT: Size: 0 | |
| 33 | # CHECK-NEXT: Binding: Global | |
| 34 | # CHECK-NEXT: Type: None | |
| 35 | # CHECK-NEXT: Other: 0 | |
| 36 | # CHECK-NEXT: Section: .text | |
| 37 | # CHECK-NEXT: } | |
| 38 | # CHECK: Symbol { | |
| 39 | # CHECK: Name: protected | |
| 40 | # CHECK-NEXT: Value: 0x1000 | |
| 41 | # CHECK-NEXT: Size: 0 | |
| 42 | # CHECK-NEXT: Binding: Global | |
| 43 | # CHECK-NEXT: Type: None | |
| 44 | # CHECK-NEXT: Other [ | |
| 45 | # CHECK-NEXT: STV_PROTECTED | |
| 46 | # CHECK-NEXT: ] | |
| 47 | # CHECK-NEXT: Section: .text | |
| 48 | # CHECK-NEXT: } | |
| 49 | # CHECK-NEXT: ] | |
| 50 | ||
| 6 | 51 | # CHECK: DynamicSymbols [ |
| 7 | 52 | # CHECK-NEXT: Symbol { |
| 8 | 53 | # CHECK-NEXT: Name: @ |
| ... | ... | @@ -23,14 +68,13 @@ _start: |
| 23 | 68 | default: |
| 24 | 69 | |
| 25 | 70 | .global protected |
| 71 | .protected protected | |
| 26 | 72 | protected: |
| 27 | 73 | |
| 28 | 74 | .global hidden |
| 75 | .hidden hidden | |
| 29 | 76 | hidden: |
| 30 | 77 | |
| 31 | 78 | .global internal |
| 79 | .internal internal | |
| 32 | 80 | internal: |
| 33 | ||
| 34 | .global protected_with_hidden | |
| 35 | .protected | |
| 36 | protected_with_hidden: |
deps/lld/test/ELF/edata-etext.s+1-1| ... | ... | @@ -19,7 +19,7 @@ |
| 19 | 19 | # CHECK: SYMBOL TABLE: |
| 20 | 20 | # CHECK-NEXT: 0000000000000000 *UND* 00000000 |
| 21 | 21 | # CHECK-NEXT: 0000000000202002 .data 00000000 _edata |
| 22 | # CHECK-NEXT: 000000000020200a .data 00000000 _end | |
| 22 | # CHECK-NEXT: 000000000020200a .bss 00000000 _end | |
| 23 | 23 | # CHECK-NEXT: 0000000000201001 .text 00000000 _etext |
| 24 | 24 | # CHECK-NEXT: 0000000000201000 .text 00000000 _start |
| 25 | 25 |
deps/lld/test/ELF/edata-no-bss.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 %t --gc-sections | |
| 4 | # RUN: llvm-objdump -t -section-headers %t | FileCheck %s | |
| 5 | ||
| 6 | # CHECK: .data 00000008 0000000000202000 DATA | |
| 7 | ||
| 8 | # CHECK: 0000000000202008 .data 00000000 _edata | |
| 9 | ||
| 10 | .text | |
| 11 | .globl _start | |
| 12 | _start: | |
| 13 | .long .data - . | |
| 14 | ||
| 15 | .data | |
| 16 | .quad 0 | |
| 17 | ||
| 18 | .globl _edata |
deps/lld/test/ELF/eh-align-cie.s+1-1| ... | ... | @@ -31,7 +31,7 @@ bar: |
| 31 | 31 | // OBJ-NEXT: ) |
| 32 | 32 | |
| 33 | 33 | |
| 34 | // RUN: ld.lld %t.o -o %t -shared | |
| 34 | // RUN: ld.lld --hash-style=sysv %t.o -o %t -shared | |
| 35 | 35 | // RUN: llvm-readobj -s -section-data %t | FileCheck %s |
| 36 | 36 | |
| 37 | 37 | // Check that the size of the CIE was changed to (0x1C + 4) and the FDE one was |
deps/lld/test/ELF/eh-frame-hdr-augmentation.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: ld.lld --eh-frame-hdr %t.o -o %t -shared | |
| 3 | // RUN: ld.lld --hash-style=sysv --eh-frame-hdr %t.o -o %t -shared | |
| 4 | 4 | // RUN: llvm-objdump --dwarf=frames %t | FileCheck %s |
| 5 | 5 | |
| 6 | 6 | // CHECK: .eh_frame contents: |
deps/lld/test/ELF/eh-frame-hdr-icf-fde.s created+95| ... | ... | @@ -0,0 +1,95 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | ## Testcase checks that we correctly deduplicate FDEs when ICF | |
| 4 | ## merges two sections. | |
| 5 | ||
| 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | |
| 7 | # RUN: ld.lld %t -o %t2 --icf=all --eh-frame-hdr | |
| 8 | # RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=OBJ | |
| 9 | # RUN: llvm-readobj -s -section-data %t2 | FileCheck %s | |
| 10 | ||
| 11 | # OBJ: Relocations [ | |
| 12 | # OBJ-NEXT: Section {{.*}} .rela.eh_frame { | |
| 13 | # OBJ-NEXT: 0x20 R_X86_64_PC32 .text.f1 0x0 | |
| 14 | # OBJ-NEXT: 0x34 R_X86_64_PC32 .text.f1 0x2 | |
| 15 | # OBJ-NEXT: 0x48 R_X86_64_PC32 .text.f2 0x0 | |
| 16 | # OBJ-NEXT: 0x5C R_X86_64_PC32 .text.f2 0x2 | |
| 17 | # OBJ-NEXT: } | |
| 18 | # OBJ-NEXT: ] | |
| 19 | ||
| 20 | # CHECK: Section { | |
| 21 | # CHECK: Index: 1 | |
| 22 | # CHECK: Name: .eh_frame_hdr | |
| 23 | # CHECK-NEXT: Type: SHT_PROGBITS | |
| 24 | # CHECK-NEXT: Flags [ | |
| 25 | # CHECK-NEXT: SHF_ALLOC | |
| 26 | # CHECK-NEXT: ] | |
| 27 | # CHECK-NEXT: Address: 0x200158 | |
| 28 | # CHECK-NEXT: Offset: 0x158 | |
| 29 | # CHECK-NEXT: Size: 28 | |
| 30 | # CHECK-NEXT: Link: 0 | |
| 31 | # CHECK-NEXT: Info: 0 | |
| 32 | # CHECK-NEXT: AddressAlignment: | |
| 33 | # CHECK-NEXT: EntrySize: 0 | |
| 34 | # CHECK-NEXT: SectionData ( | |
| 35 | # CHECK-NEXT: 0000: 011B033B 1C000000 02000000 A80E0000 | |
| 36 | ## ^ ^-- FDE(1) PC | |
| 37 | ## ^-- Number of FDEs | |
| 38 | # CHECK-NEXT: 0010: 38000000 AA0E0000 50000000 | |
| 39 | ## ^-- FDE(2) PC | |
| 40 | # CHECK-NEXT: ) | |
| 41 | # CHECK-NEXT: } | |
| 42 | ## FDE(1) == 0x201000 - .eh_frame_hdr(0x200158) = 0xEA8 | |
| 43 | ## FDE(2) == 0x201000 - .eh_frame_hdr(0x200158) + 2(relocation addend) = 0xEAA | |
| 44 | ||
| 45 | ## Check .eh_frame contains CIE and two FDEs remaining after ICF. | |
| 46 | # CHECK-NEXT: Section { | |
| 47 | # CHECK-NEXT: Index: 2 | |
| 48 | # CHECK-NEXT: Name: .eh_frame | |
| 49 | # CHECK-NEXT: Type: SHT_PROGBITS | |
| 50 | # CHECK-NEXT: Flags [ | |
| 51 | # CHECK-NEXT: SHF_ALLOC | |
| 52 | # CHECK-NEXT: ] | |
| 53 | # CHECK-NEXT: Address: 0x200178 | |
| 54 | # CHECK-NEXT: Offset: 0x178 | |
| 55 | # CHECK-NEXT: Size: 72 | |
| 56 | # CHECK-NEXT: Link: 0 | |
| 57 | # CHECK-NEXT: Info: 0 | |
| 58 | # CHECK-NEXT: AddressAlignment: 8 | |
| 59 | # CHECK-NEXT: EntrySize: 0 | |
| 60 | # CHECK-NEXT: SectionData ( | |
| 61 | # CHECK-NEXT: 0000: 14000000 00000000 017A5200 01781001 | |
| 62 | # CHECK-NEXT: 0010: 1B0C0708 90010000 14000000 1C000000 | |
| 63 | # CHECK-NEXT: 0020: 680E0000 01000000 00000000 00000000 | |
| 64 | # CHECK-NEXT: 0030: 14000000 34000000 520E0000 01000000 | |
| 65 | # CHECK-NEXT: 0040: 00000000 00000000 | |
| 66 | # CHECK-NEXT: ) | |
| 67 | # CHECK-NEXT: } | |
| 68 | ||
| 69 | # CHECK: Section { | |
| 70 | # CHECK: Index: | |
| 71 | # CHECK: Name: .text | |
| 72 | # CHECK-NEXT: Type: SHT_PROGBITS | |
| 73 | # CHECK-NEXT: Flags [ | |
| 74 | # CHECK-NEXT: SHF_ALLOC | |
| 75 | # CHECK-NEXT: SHF_EXECINSTR | |
| 76 | # CHECK-NEXT: ] | |
| 77 | # CHECK-NEXT: Address: 0x201000 | |
| 78 | ||
| 79 | .section .text.f1, "ax" | |
| 80 | .cfi_startproc | |
| 81 | nop | |
| 82 | .cfi_endproc | |
| 83 | nop | |
| 84 | .cfi_startproc | |
| 85 | ret | |
| 86 | .cfi_endproc | |
| 87 | ||
| 88 | .section .text.f2, "ax" | |
| 89 | .cfi_startproc | |
| 90 | nop | |
| 91 | .cfi_endproc | |
| 92 | nop | |
| 93 | .cfi_startproc | |
| 94 | ret | |
| 95 | .cfi_endproc |
deps/lld/test/ELF/eh-frame-hdr-icf.s+8-7| ... | ... | @@ -2,17 +2,18 @@ |
| 2 | 2 | |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | 4 | # RUN: ld.lld %t -o %t2 --icf=all --eh-frame-hdr |
| 5 | # RUN: llvm-objdump -s %t2 | FileCheck %s | |
| 5 | # RUN: llvm-objdump -s -section-headers %t2 | FileCheck %s | |
| 6 | ||
| 7 | ## Check .eh_frame_hdr contains single FDE and no garbage data at tail. | |
| 8 | # CHECK: Sections: | |
| 9 | # CHECK: Idx Name Size | |
| 10 | # CHECK: .eh_frame_hdr 00000014 | |
| 6 | 11 | |
| 7 | 12 | # CHECK: Contents of section .eh_frame_hdr: |
| 8 | # CHECK-NEXT: 200158 011b033b 1c000000 01000000 a80e0000 | |
| 13 | # CHECK-NEXT: 200158 011b033b 14000000 01000000 | |
| 9 | 14 | # ^ FDE count |
| 10 | # CHECK-NEXT: 200168 38000000 00000000 00000000 | |
| 11 | # ^ FDE for f2 | |
| 12 | 15 | |
| 13 | .globl _start, f1, f2 | |
| 14 | _start: | |
| 15 | ret | |
| 16 | .globl f1, f2 | |
| 16 | 17 | |
| 17 | 18 | .section .text.f1, "ax" |
| 18 | 19 | f1: |
deps/lld/test/ELF/eh-frame-hdr.s+10-2| ... | ... | @@ -1,9 +1,17 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | ||
| 3 | 4 | // RUN: ld.lld %t.o -o %t |
| 4 | // RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t | FileCheck %s --check-prefix=NOHDR | |
| 5 | // RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t \ | |
| 6 | // RUN: | FileCheck %s --check-prefix=NOHDR | |
| 7 | ||
| 8 | // RUN: ld.lld -eh-frame-hdr -no-eh-frame-hdr %t.o -o %t | |
| 9 | // RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t \ | |
| 10 | // RUN: | FileCheck %s --check-prefix=NOHDR | |
| 11 | ||
| 5 | 12 | // RUN: ld.lld --eh-frame-hdr %t.o -o %t |
| 6 | // RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t | FileCheck %s --check-prefix=HDR | |
| 13 | // RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t \ | |
| 14 | // RUN: | FileCheck %s --check-prefix=HDR | |
| 7 | 15 | // RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=HDRDISASM |
| 8 | 16 | |
| 9 | 17 | .section foo,"ax",@progbits |
deps/lld/test/ELF/eh-frame-merge.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: ld.lld %t.o %t.o -o %t -shared | |
| 3 | // RUN: ld.lld --hash-style=sysv %t.o %t.o -o %t -shared | |
| 4 | 4 | // RUN: llvm-readobj -s -section-data %t | FileCheck %s |
| 5 | 5 | |
| 6 | 6 | .section	foo,"ax",@progbits |
deps/lld/test/ELF/eh-frame-padding-no-rosegment.s+1-1| ... | ... | @@ -31,7 +31,7 @@ bar: |
| 31 | 31 | // OBJ-NEXT: 0020: 20000000 00000000 00000000 00000000 |
| 32 | 32 | // OBJ-NEXT: ) |
| 33 | 33 | |
| 34 | // RUN: ld.lld %t.o -no-rosegment -o %t -shared | |
| 34 | // RUN: ld.lld --hash-style=sysv %t.o -no-rosegment -o %t -shared | |
| 35 | 35 | |
| 36 | 36 | // Check that .eh_frame is in the same segment as .text |
| 37 | 37 | // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=PHDR %s |
deps/lld/test/ELF/eh-frame.s created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 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/eh-frame.s -o %t2.o | |
| 4 | // RUN: ld.lld %t1.o %t2.o -o %t | |
| 5 | // RUN: llvm-dwarfdump -eh-frame %t | FileCheck %s | |
| 6 | ||
| 7 | // CHECK: DW_CFA_def_cfa_offset: +64 | |
| 8 | // CHECK: DW_CFA_def_cfa_offset: +32 | |
| 9 | ||
| 10 | .cfi_startproc | |
| 11 | .cfi_def_cfa_offset 64 | |
| 12 | .cfi_endproc |
deps/lld/test/ELF/emit-relocs-gc.s created+30| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | |
| 3 | ||
| 4 | ## Show that we emit .rela.bar and .rela.text when GC is disabled. | |
| 5 | # RUN: ld.lld --emit-relocs %t.o -o %t | |
| 6 | # RUN: llvm-objdump %t -section-headers | FileCheck %s --check-prefix=NOGC | |
| 7 | # NOGC: .rela.text | |
| 8 | # NOGC: .rela.bar | |
| 9 | ||
| 10 | ## GC collects .bar section and we exclude .rela.bar from output. We keep | |
| 11 | ## .rela.text because we keep .text. | |
| 12 | # RUN: ld.lld --gc-sections --emit-relocs --print-gc-sections %t.o -o %t \ | |
| 13 | # RUN: | FileCheck --check-prefix=MSG %s | |
| 14 | # MSG: removing unused section from '.bar' in file | |
| 15 | # MSG: removing unused section from '.rela.bar' in file | |
| 16 | # RUN: llvm-objdump %t -section-headers | FileCheck %s --check-prefix=GC | |
| 17 | # GC-NOT: rela.bar | |
| 18 | # GC: rela.text | |
| 19 | # GC-NOT: rela.bar | |
| 20 | ||
| 21 | .section .bar,"a" | |
| 22 | .quad .bar | |
| 23 | ||
| 24 | .text | |
| 25 | relocs: | |
| 26 | .quad _start | |
| 27 | ||
| 28 | .global _start | |
| 29 | _start: | |
| 30 | nop |
deps/lld/test/ELF/emit-relocs-merge.s+1-1| ... | ... | @@ -8,7 +8,7 @@ |
| 8 | 8 | # CHECK-NEXT: 0x1000 R_X86_64_64 zed 0x0 |
| 9 | 9 | # CHECK-NEXT: 0x1008 R_X86_64_64 zed 0x0 |
| 10 | 10 | # CHECK-NEXT: } |
| 11 | # CHECK-NEXT: Section ({{.*}}) .rela.data.foo { | |
| 11 | # CHECK-NEXT: Section ({{.*}}) .rela.data { | |
| 12 | 12 | # CHECK-NEXT: 0x1000 R_X86_64_64 zed 0x0 |
| 13 | 13 | # CHECK-NEXT: 0x1008 R_X86_64_64 zed 0x0 |
| 14 | 14 | # CHECK-NEXT: } |
deps/lld/test/ELF/emit-relocs-mergeable-i386.s created+66| ... | ... | @@ -0,0 +1,66 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t1 | |
| 3 | # RUN: ld.lld --emit-relocs %t1 -o %t2 | |
| 4 | # RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s | |
| 5 | ||
| 6 | ## Check lf we produce proper relocations when doing merging of SHF_MERGE sections. | |
| 7 | ||
| 8 | ## Check addends of relocations are: 0x0, 0x8, 0x8, 0x4 | |
| 9 | # CHECK: Section { | |
| 10 | # CHECK: Index: | |
| 11 | # CHECK: Name: .foo | |
| 12 | # CHECK-NEXT: Type: SHT_PROGBITS | |
| 13 | # CHECK-NEXT: Flags [ | |
| 14 | # CHECK-NEXT: SHF_ALLOC | |
| 15 | # CHECK-NEXT: SHF_EXECINSTR | |
| 16 | # CHECK-NEXT: ] | |
| 17 | # CHECK-NEXT: Address: | |
| 18 | # CHECK-NEXT: Offset: | |
| 19 | # CHECK-NEXT: Size: | |
| 20 | # CHECK-NEXT: Link: | |
| 21 | # CHECK-NEXT: Info: | |
| 22 | # CHECK-NEXT: AddressAlignment: | |
| 23 | # CHECK-NEXT: EntrySize: | |
| 24 | # CHECK-NEXT: SectionData ( | |
| 25 | # CHECK-NEXT: 0000: 00000000 08000000 08000000 04000000 | |
| 26 | # CHECK-NEXT: ) | |
| 27 | # CHECK-NEXT: } | |
| 28 | ||
| 29 | ## Check that offsets for AAA is 0x0, for BBB is 0x8 and CCC has offset 0x4. | |
| 30 | # CHECK: Section { | |
| 31 | # CHECK: Index: | |
| 32 | # CHECK: Name: .strings | |
| 33 | # CHECK-NEXT: Type: SHT_PROGBITS | |
| 34 | # CHECK-NEXT: Flags [ | |
| 35 | # CHECK-NEXT: SHF_MERGE | |
| 36 | # CHECK-NEXT: SHF_STRINGS | |
| 37 | # CHECK-NEXT: ] | |
| 38 | # CHECK-NEXT: Address: | |
| 39 | # CHECK-NEXT: Offset: | |
| 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: |AAA.CCC.BBB.| | |
| 47 | # CHECK-NEXT: ) | |
| 48 | # CHECK-NEXT: } | |
| 49 | ||
| 50 | .section .strings,"MS",@progbits,1,unique,10 | |
| 51 | .Linfo_string0: | |
| 52 | .asciz "AAA" | |
| 53 | .Linfo_string1: | |
| 54 | .asciz "BBB" | |
| 55 | ||
| 56 | .section .strings,"MS",@progbits,1,unique,20 | |
| 57 | .Linfo_string2: | |
| 58 | .asciz "BBB" | |
| 59 | .Linfo_string3: | |
| 60 | .asciz "CCC" | |
| 61 | ||
| 62 | .section .foo,"ax",@progbits | |
| 63 | .long .Linfo_string0 | |
| 64 | .long .Linfo_string1 | |
| 65 | .long .Linfo_string2 | |
| 66 | .long .Linfo_string3 |
deps/lld/test/ELF/emit-relocs-mergeable.s created+53| ... | ... | @@ -0,0 +1,53 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 | |
| 3 | # RUN: ld.lld --emit-relocs %t1 -o %t2 | |
| 4 | # RUN: llvm-readobj -sections -section-data -r %t2 | FileCheck %s | |
| 5 | ||
| 6 | ## Check if we produce proper relocations when doing merging of SHF_MERGE sections. | |
| 7 | ||
| 8 | # CHECK: Section { | |
| 9 | # CHECK: Index: | |
| 10 | # CHECK: Name: .strings | |
| 11 | # CHECK-NEXT: Type: SHT_PROGBITS | |
| 12 | # CHECK-NEXT: Flags [ | |
| 13 | # CHECK-NEXT: SHF_MERGE | |
| 14 | # CHECK-NEXT: SHF_STRINGS | |
| 15 | # CHECK-NEXT: ] | |
| 16 | # CHECK-NEXT: Address: | |
| 17 | # CHECK-NEXT: Offset: | |
| 18 | # CHECK-NEXT: Size: 12 | |
| 19 | # CHECK-NEXT: Link: | |
| 20 | # CHECK-NEXT: Info: | |
| 21 | # CHECK-NEXT: AddressAlignment: | |
| 22 | # CHECK-NEXT: EntrySize: | |
| 23 | # CHECK-NEXT: SectionData ( | |
| 24 | # CHECK-NEXT: 0000: 41414100 43434300 42424200 |AAA.CCC.BBB.| | |
| 25 | # CHECK-NEXT: ) | |
| 26 | # CHECK-NEXT: } | |
| 27 | ||
| 28 | # CHECK: Relocations [ | |
| 29 | # CHECK-NEXT: Section {{.*}} .rela.foo { | |
| 30 | # CHECK-NEXT: 0x201000 R_X86_64_64 .strings 0x0 | |
| 31 | # CHECK-NEXT: 0x201008 R_X86_64_64 .strings 0x8 | |
| 32 | # CHECK-NEXT: 0x201010 R_X86_64_64 .strings 0x8 | |
| 33 | # CHECK-NEXT: 0x201018 R_X86_64_64 .strings 0x4 | |
| 34 | # CHECK-NEXT: } | |
| 35 | # CHECK-NEXT: ] | |
| 36 | ||
| 37 | .section .strings,"MS",@progbits,1,unique,10 | |
| 38 | .Linfo_string0: | |
| 39 | .asciz "AAA" | |
| 40 | .Linfo_string1: | |
| 41 | .asciz "BBB" | |
| 42 | ||
| 43 | .section .strings,"MS",@progbits,1,unique,20 | |
| 44 | .Linfo_string2: | |
| 45 | .asciz "BBB" | |
| 46 | .Linfo_string3: | |
| 47 | .asciz "CCC" | |
| 48 | ||
| 49 | .section .foo,"ax",@progbits | |
| 50 | .quad .Linfo_string0 | |
| 51 | .quad .Linfo_string1 | |
| 52 | .quad .Linfo_string2 | |
| 53 | .quad .Linfo_string3 |
deps/lld/test/ELF/emit-relocs-shared.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: ld.lld --emit-relocs %t.o -o %t.so -shared | |
| 3 | # RUN: ld.lld --hash-style=sysv --emit-relocs %t.o -o %t.so -shared | |
| 4 | 4 | # RUN: llvm-readobj -r %t.so | FileCheck %s |
| 5 | 5 | |
| 6 | 6 | .data |
deps/lld/test/ELF/emit-relocs.s+11-2| ... | ... | @@ -64,6 +64,15 @@ |
| 64 | 64 | # CHECK-NEXT: Section: .text |
| 65 | 65 | # CHECK-NEXT: } |
| 66 | 66 | # CHECK-NEXT: Symbol { |
| 67 | # CHECK-NEXT: Name: | |
| 68 | # CHECK-NEXT: Value: 0x0 | |
| 69 | # CHECK-NEXT: Size: 0 | |
| 70 | # CHECK-NEXT: Binding: Local | |
| 71 | # CHECK-NEXT: Type: Section | |
| 72 | # CHECK-NEXT: Other: 0 | |
| 73 | # CHECK-NEXT: Section: .comment | |
| 74 | # CHECK-NEXT: } | |
| 75 | # CHECK-NEXT: Symbol { | |
| 67 | 76 | # CHECK-NEXT: Name: fn |
| 68 | 77 | # CHECK-NEXT: Value: 0x201000 |
| 69 | 78 | # CHECK-NEXT: Size: 0 |
| ... | ... | @@ -83,7 +92,7 @@ |
| 83 | 92 | # CHECK-NEXT: } |
| 84 | 93 | # CHECK-NEXT: ] |
| 85 | 94 | |
| 86 | .section .text,"ax",@progbits,unique,0 | |
| 95 | .section .text.fn,"ax",@progbits,unique,0 | |
| 87 | 96 | .globl fn |
| 88 | 97 | .type fn,@function |
| 89 | 98 | fn: |
| ... | ... | @@ -94,7 +103,7 @@ bar: |
| 94 | 103 | callq fn@PLT |
| 95 | 104 | nop |
| 96 | 105 | |
| 97 | .section .text,"ax",@progbits,unique,1 | |
| 106 | .section .text.fn2,"ax",@progbits,unique,1 | |
| 98 | 107 | .globl fn2 |
| 99 | 108 | .type fn2,@function |
| 100 | 109 | fn2: |
deps/lld/test/ELF/exclude-libs.s+6| ... | ... | @@ -22,6 +22,12 @@ |
| 22 | 22 | // RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL |
| 23 | 23 | // RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s |
| 24 | 24 | |
| 25 | // 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 | |
| 27 | ||
| 28 | // RUN: ld.lld -shared --whole-archive %t.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL | |
| 29 | // RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s | |
| 30 | ||
| 25 | 31 | // DEFAULT: Name: fn |
| 26 | 32 | // EXCLUDE-NOT: Name: fn |
| 27 | 33 |
deps/lld/test/ELF/executable-undefined-ignoreall.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 %tout --unresolved-symbols=ignore-all -pie | |
| 4 | # RUN: llvm-readobj -r %tout | FileCheck %s | |
| 5 | ||
| 6 | # CHECK: Relocations [ | |
| 7 | # CHECK-NEXT: Section ({{.*}}) .rela.plt { | |
| 8 | # CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT foo 0x0 | |
| 9 | # CHECK-NEXT: } | |
| 10 | # CHECK-NEXT: ] | |
| 11 | ||
| 12 | _start: | |
| 13 | callq foo@PLT |
deps/lld/test/ELF/executable-undefined-protected-ignoreall.s created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | # REQUIRES: x86 | |
| 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 | |
| 4 | # CHECK: error: undefined symbol: foo | |
| 5 | ||
| 6 | .protected foo | |
| 7 | _start: | |
| 8 | callq foo@PLT |
deps/lld/test/ELF/file-access.s created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | # REQUIRES: x86, shell | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | |
| 4 | # RUN: ld.lld -r %t.o -o %t1.o | |
| 5 | # RUN: [ ! -x %t1.o ] | |
| 6 | # RUN: ld.lld -shared %t.o -o %t2.so | |
| 7 | # RUN: [ -x %t2.so ] | |
| 8 | # RUN: ld.lld %t.o -o %t3 | |
| 9 | # RUN: [ -x %t3 ] | |
| 10 | ||
| 11 | .global _start | |
| 12 | _start: | |
| 13 | nop |
deps/lld/test/ELF/fill-trap.s created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 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 | |
| 5 | # RUN: llvm-readobj -program-headers %t2 | FileCheck %s | |
| 6 | # RUN: od -Ax -x -N16 -j0x1ff0 %t2 | FileCheck %s -check-prefix=FILL | |
| 7 | ||
| 8 | # CHECK: ProgramHeader { | |
| 9 | # CHECK: Type: PT_LOAD | |
| 10 | # CHECK: Offset: 0x1000 | |
| 11 | # CHECK-NEXT: VirtualAddress: | |
| 12 | # CHECK-NEXT: PhysicalAddress: | |
| 13 | # CHECK-NEXT: FileSize: 4096 | |
| 14 | # CHECK-NEXT: MemSize: | |
| 15 | # CHECK-NEXT: Flags [ | |
| 16 | # CHECK-NEXT: PF_R | |
| 17 | # CHECK-NEXT: PF_X | |
| 18 | # CHECK-NEXT: ] | |
| 19 | ||
| 20 | ## Check that executable page is filled with traps at its end. | |
| 21 | # FILL: 001ff0 cccc cccc cccc cccc cccc cccc cccc cccc | |
| 22 | ||
| 23 | .globl _start | |
| 24 | _start: | |
| 25 | nop |
deps/lld/test/ELF/filter.s+5-1| ... | ... | @@ -2,10 +2,14 @@ |
| 2 | 2 | # RUN: ld.lld %t.o -shared -F foo.so -F boo.so -o %t1 |
| 3 | 3 | # RUN: llvm-readobj --dynamic-table %t1 | FileCheck %s |
| 4 | 4 | |
| 5 | # Test alias. | |
| 5 | # Test alias #1. | |
| 6 | 6 | # RUN: ld.lld %t.o -shared --filter=foo.so --filter=boo.so -o %t2 |
| 7 | 7 | # RUN: llvm-readobj --dynamic-table %t2 | FileCheck %s |
| 8 | 8 | |
| 9 | # Test alias #2. | |
| 10 | # RUN: ld.lld %t.o -shared --filter foo.so --filter boo.so -o %t3 | |
| 11 | # RUN: llvm-readobj --dynamic-table %t3 | FileCheck %s | |
| 12 | ||
| 9 | 13 | # CHECK: DynamicSection [ |
| 10 | 14 | # CHECK-NEXT: Tag Type Name/Value |
| 11 | 15 | # CHECK-NEXT: 0x000000007FFFFFFF FILTER Filter library: [foo.so] |
deps/lld/test/ELF/format-binary-non-ascii.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: ld.lld -o %t.elf %t£.o --format=binary %t£.o | |
| 5 | # RUN: llvm-readobj -symbols %t.elf | FileCheck %s | |
| 6 | ||
| 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 | |
| 9 | # CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp___o_size | |
| 10 | ||
| 11 | .text | |
| 12 | .align 4 | |
| 13 | .globl _start | |
| 14 | _start: | |
| 15 | nop |
deps/lld/test/ELF/gc-collect-undefined.s created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | |
| 3 | # RUN: ld.lld %t -o %tout --gc-sections -shared | |
| 4 | # RUN: llvm-nm -D %tout | FileCheck %s | |
| 5 | ||
| 6 | # CHECK-NOT: qux | |
| 7 | # CHECK: bar | |
| 8 | # CHECK-NOT: qux | |
| 9 | ||
| 10 | 	.global foo,bar,qux | |
| 11 | 	.local baz | |
| 12 | ||
| 13 | 	.section .data.foo,"aw",%progbits | |
| 14 | foo: | |
| 15 | 	.dc.a	bar | |
| 16 | ||
| 17 | 	.section .bata.baz,"aw",%progbits | |
| 18 | baz: | |
| 19 | 	.dc.a	qux |
deps/lld/test/ELF/gc-merge-local-sym.s+1-1| ... | ... | @@ -15,7 +15,7 @@ |
| 15 | 15 | // CHECK-NEXT: Link: 0 |
| 16 | 16 | // CHECK-NEXT: Info: 0 |
| 17 | 17 | // CHECK-NEXT: AddressAlignment: 1 |
| 18 | // CHECK-NEXT: EntrySize: 0 | |
| 18 | // CHECK-NEXT: EntrySize: 1 | |
| 19 | 19 | // CHECK-NEXT: SectionData ( |
| 20 | 20 | // CHECK-NEXT: 0000: 61626300 |abc.| |
| 21 | 21 | // CHECK-NEXT: ) |
deps/lld/test/ELF/gc-sections-linker-defined-symbol.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.so --gc-sections -shared | |
| 5 | # RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s | |
| 6 | ||
| 7 | # CHECK: Name: _end@ | |
| 8 | # CHECK-NEXT: Value: | |
| 9 | # CHECK-NEXT: Size: | |
| 10 | # CHECK-NEXT: Binding: Global | |
| 11 | # CHECK-NEXT: Type: None | |
| 12 | # CHECK-NEXT: Other: | |
| 13 | # CHECK-NEXT: Section: .dynamic | |
| 14 | ||
| 15 | .data | |
| 16 | .globl g | |
| 17 | g: | |
| 18 | .quad _end |
deps/lld/test/ELF/gc-sections-merge-addend.s+1-1| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | // CHECK-NEXT: Link: 0 |
| 17 | 17 | // CHECK-NEXT: Info: 0 |
| 18 | 18 | // CHECK-NEXT: AddressAlignment: 1 |
| 19 | // CHECK-NEXT: EntrySize: 0 | |
| 19 | // CHECK-NEXT: EntrySize: 1 | |
| 20 | 20 | // CHECK-NEXT: SectionData ( |
| 21 | 21 | // CHECK-NEXT: 0000: 62617200 |bar.| |
| 22 | 22 | // CHECK-NEXT: ) |
deps/lld/test/ELF/gc-sections-merge-implicit-addend.s+1-1| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | // CHECK-NEXT: Link: 0 |
| 17 | 17 | // CHECK-NEXT: Info: 0 |
| 18 | 18 | // CHECK-NEXT: AddressAlignment: 1 |
| 19 | // CHECK-NEXT: EntrySize: 0 | |
| 19 | // CHECK-NEXT: EntrySize: 1 | |
| 20 | 20 | // CHECK-NEXT: SectionData ( |
| 21 | 21 | // CHECK-NEXT: 0000: 62617200 |bar.| |
| 22 | 22 | // CHECK-NEXT: ) |
deps/lld/test/ELF/gc-sections-merge.s+2-2| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | // CHECK-NEXT: Link: 0 |
| 19 | 19 | // CHECK-NEXT: Info: 0 |
| 20 | 20 | // CHECK-NEXT: AddressAlignment: 1 |
| 21 | // CHECK-NEXT: EntrySize: 0 | |
| 21 | // CHECK-NEXT: EntrySize: 1 | |
| 22 | 22 | // CHECK-NEXT: SectionData ( |
| 23 | 23 | // CHECK-NEXT: 0000: 666F6F00 62617200 |foo.bar.| |
| 24 | 24 | // CHECK-NEXT: ) |
| ... | ... | @@ -36,7 +36,7 @@ |
| 36 | 36 | // GC-NEXT: Link: 0 |
| 37 | 37 | // GC-NEXT: Info: 0 |
| 38 | 38 | // GC-NEXT: AddressAlignment: 1 |
| 39 | // GC-NEXT: EntrySize: 0 | |
| 39 | // GC-NEXT: EntrySize: 1 | |
| 40 | 40 | // GC-NEXT: SectionData ( |
| 41 | 41 | // GC-NEXT: 0000: 666F6F00 |foo.| |
| 42 | 42 | // GC-NEXT: ) |
deps/lld/test/ELF/gc-sections-print.s+6| ... | ... | @@ -5,6 +5,12 @@ |
| 5 | 5 | # PRINT: removing unused section from '.text.x' in file |
| 6 | 6 | # PRINT-NEXT: removing unused section from '.text.y' in file |
| 7 | 7 | |
| 8 | # RUN: ld.lld %t --gc-sections --print-gc-sections --no-print-gc-sections -o %t2 >& %t.log | |
| 9 | # RUN: echo >> %t.log | |
| 10 | # RUN: FileCheck -check-prefix=NOPRINT %s < %t.log | |
| 11 | ||
| 12 | # NOPRINT-NOT: removing | |
| 13 | ||
| 8 | 14 | .globl _start |
| 9 | 15 | .protected a, x, y |
| 10 | 16 | _start: |
deps/lld/test/ELF/gc-sections-shared.s+89-4| ... | ... | @@ -1,12 +1,18 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 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/gc-sections-shared.s -o %t3.o | |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/gc-sections-shared2.s -o %t4.o | |
| 3 | 5 | # RUN: ld.lld -shared %t2.o -o %t2.so |
| 6 | # RUN: ld.lld -shared %t3.o -o %t3.so | |
| 7 | # RUN: ld.lld -shared %t4.o -o %t4.so | |
| 4 | 8 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 5 | # RUN: ld.lld --gc-sections --export-dynamic-symbol foo -o %t %t.o --as-needed %t2.so | |
| 9 | # RUN: ld.lld --gc-sections --export-dynamic-symbol foo -o %t %t.o --as-needed %t2.so %t3.so %t4.so | |
| 6 | 10 | # RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck %s |
| 7 | 11 | |
| 8 | 12 | # This test the property that we have a needed line for every undefined. |
| 9 | # It would also be OK to drop bar2 and the need for the .so | |
| 13 | # It would also be OK to keep bar2 and the need for %t2.so | |
| 14 | # At the same time, weak symbols should not cause adding DT_NEEDED; | |
| 15 | # this case is checked with symbol qux and %t4.so. | |
| 10 | 16 | |
| 11 | 17 | # CHECK: DynamicSymbols [ |
| 12 | 18 | # CHECK-NEXT: Symbol { |
| ... | ... | @@ -19,7 +25,16 @@ |
| 19 | 25 | # CHECK-NEXT: Section: Undefined (0x0) |
| 20 | 26 | # CHECK-NEXT: } |
| 21 | 27 | # CHECK-NEXT: Symbol { |
| 22 | # CHECK-NEXT: Name: bar2 | |
| 28 | # CHECK-NEXT: Name: bar | |
| 29 | # CHECK-NEXT: Value: | |
| 30 | # CHECK-NEXT: Size: | |
| 31 | # CHECK-NEXT: Binding: Global | |
| 32 | # CHECK-NEXT: Type: | |
| 33 | # CHECK-NEXT: Other: | |
| 34 | # CHECK-NEXT: Section: .text | |
| 35 | # CHECK-NEXT: } | |
| 36 | # CHECK-NEXT: Symbol { | |
| 37 | # CHECK-NEXT: Name: baz | |
| 23 | 38 | # CHECK-NEXT: Value: |
| 24 | 39 | # CHECK-NEXT: Size: |
| 25 | 40 | # CHECK-NEXT: Binding: Global |
| ... | ... | @@ -36,9 +51,76 @@ |
| 36 | 51 | # CHECK-NEXT: Other: |
| 37 | 52 | # CHECK-NEXT: Section: .text |
| 38 | 53 | # 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: } | |
| 39 | 63 | # CHECK-NEXT: ] |
| 40 | 64 | |
| 41 | # CHECK: NEEDED Shared library: [{{.*}}.so] | |
| 65 | # CHECK-NOT: NEEDED | |
| 66 | # CHECK: NEEDED Shared library: [{{.*}}3.so] | |
| 67 | # CHECK-NOT: NEEDED | |
| 68 | ||
| 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 | |
| 71 | # RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck --check-prefix=CHECK2 %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 | |
| 42 | 124 | |
| 43 | 125 | .section .text.foo, "ax" |
| 44 | 126 | .globl foo |
| ... | ... | @@ -52,7 +134,10 @@ ret |
| 52 | 134 | |
| 53 | 135 | .section .text._start, "ax" |
| 54 | 136 | .globl _start |
| 137 | .weak qux | |
| 55 | 138 | _start: |
| 139 | call baz | |
| 140 | call qux | |
| 56 | 141 | ret |
| 57 | 142 | |
| 58 | 143 | .section .text.unused, "ax" |
deps/lld/test/ELF/gc-sections-undefined.s created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | |
| 3 | # RUN: ld.lld %t -o %t1 --gc-sections --undefined=foo | |
| 4 | # RUN: llvm-readobj -t %t1 | FileCheck %s | |
| 5 | ||
| 6 | # CHECK: foo | |
| 7 | ||
| 8 | .section .foo,"ax" | |
| 9 | .global foo | |
| 10 | foo: |
deps/lld/test/ELF/gdb-index-base-addr.s created+70| ... | ... | @@ -0,0 +1,70 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | |
| 3 | # RUN: ld.lld --gdb-index %t1.o -o %t | |
| 4 | # RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s | |
| 5 | ||
| 6 | # CHECK: .gnu_index contents: | |
| 7 | # CHECK: Address area offset = 0x28, has 2 entries: | |
| 8 | # CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0 | |
| 9 | # CHECK-NEXT: Low/High address = [0x201003, 0x201006) (Size: 0x3), CU id = 0 | |
| 10 | ||
| 11 | .text | |
| 12 | .globl foo | |
| 13 | .type foo,@function | |
| 14 | foo: | |
| 15 | .Lfunc_begin0: | |
| 16 | nop | |
| 17 | .Ltmp0: | |
| 18 | nop | |
| 19 | nop | |
| 20 | .Ltmp1: | |
| 21 | nop | |
| 22 | nop | |
| 23 | nop | |
| 24 | .Ltmp2: | |
| 25 | ||
| 26 | .section .debug_abbrev,"",@progbits | |
| 27 | .byte 1 # Abbreviation Code | |
| 28 | .byte 17 # DW_TAG_compile_unit | |
| 29 | .byte 0 # DW_CHILDREN_no | |
| 30 | .byte 37 # DW_AT_producer | |
| 31 | .byte 14 # DW_FORM_strp | |
| 32 | .byte 19 # DW_AT_language | |
| 33 | .byte 5 # DW_FORM_data2 | |
| 34 | .byte 3 # DW_AT_name | |
| 35 | .byte 14 # DW_FORM_strp | |
| 36 | .byte 16 # DW_AT_stmt_list | |
| 37 | .byte 23 # DW_FORM_sec_offset | |
| 38 | .byte 27 # DW_AT_comp_dir | |
| 39 | .byte 14 # DW_FORM_strp | |
| 40 | .byte 17 # DW_AT_low_pc | |
| 41 | .byte 1 # DW_FORM_addr | |
| 42 | .byte 85 # DW_AT_ranges | |
| 43 | .byte 23 # DW_FORM_sec_offset | |
| 44 | .byte 0 # EOM(1) | |
| 45 | .byte 0 # EOM(2) | |
| 46 | .byte 0 # EOM(3) | |
| 47 | ||
| 48 | .section .debug_info,"",@progbits | |
| 49 | .Lcu_begin0: | |
| 50 | .long 38 # Length of Unit | |
| 51 | .short 4 # DWARF version number | |
| 52 | .long .debug_abbrev # Offset Into Abbrev. Section | |
| 53 | .byte 8 # Address Size (in bytes) | |
| 54 | .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit | |
| 55 | .long 0 # DW_AT_producer | |
| 56 | .short 4 # DW_AT_language | |
| 57 | .long 0 # DW_AT_name | |
| 58 | .long 0 # DW_AT_stmt_list | |
| 59 | .long 0 # DW_AT_comp_dir | |
| 60 | .quad .Lfunc_begin0 # DW_AT_low_pc | |
| 61 | .long .Ldebug_ranges0 # DW_AT_ranges | |
| 62 | ||
| 63 | .section .debug_ranges,"",@progbits | |
| 64 | .Ldebug_ranges0: | |
| 65 | .quad .Lfunc_begin0-.Lfunc_begin0 | |
| 66 | .quad .Ltmp0-.Lfunc_begin0 | |
| 67 | .quad .Ltmp1-.Lfunc_begin0 | |
| 68 | .quad .Ltmp2-.Lfunc_begin0 | |
| 69 | .quad 0 | |
| 70 | .quad 0 |
deps/lld/test/ELF/gdb-index-dup-types.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 3 | 3 | # RUN: ld.lld --gdb-index %t.o -o %t |
| 4 | # RUN: llvm-dwarfdump -debug-dump=gdb_index %t | FileCheck %s | |
| 4 | # RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s | |
| 5 | 5 | |
| 6 | 6 | ## Testcase is based on output produced by gcc version 5.4.1 20160904 |
| 7 | 7 | ## it has duplicate entries in .debug_gnu_pubtypes which seems to be |
deps/lld/test/ELF/gdb-index-empty.s+2-2| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -o %t %s |
| 3 | 3 | # RUN: ld.lld --gdb-index --gc-sections -o %t2 %t |
| 4 | # RUN: llvm-dwarfdump -debug-dump=gdb_index %t2 | FileCheck %s | |
| 4 | # RUN: llvm-dwarfdump -gdb-index %t2 | FileCheck %s | |
| 5 | 5 | |
| 6 | 6 | # CHECK: Address area offset = 0x28, has 0 entries: |
| 7 | 7 | |
| ... | ... | @@ -74,7 +74,7 @@ _start: |
| 74 | 74 | .quad .Lfunc_begin0 # DW_AT_low_pc |
| 75 | 75 | .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc |
| 76 | 76 | .byte 1 # DW_AT_frame_base |
| 77 | .byte 87 | |
| 77 | .byte 87 | |
| 78 | 78 | .long 0 # DW_AT_name |
| 79 | 79 | .byte 1 # DW_AT_decl_file |
| 80 | 80 | .byte 1 # DW_AT_decl_line |
deps/lld/test/ELF/gdb-index-gc-sections.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -o %t %s |
| 3 | 3 | # RUN: ld.lld --gdb-index --gc-sections -o %t2 %t |
| 4 | # RUN: llvm-dwarfdump -debug-dump=gdb_index %t2 | FileCheck %s | |
| 4 | # RUN: llvm-dwarfdump -gdb-index %t2 | FileCheck %s | |
| 5 | 5 | |
| 6 | 6 | # CHECK: Address area offset = 0x28, has 1 entries: |
| 7 | 7 | # CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0 |
deps/lld/test/ELF/gdb-index-noranges.s created+49| ... | ... | @@ -0,0 +1,49 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | |
| 3 | ||
| 4 | ## Input is reduced from following code and invocation: | |
| 5 | ## clang++ -gsplit-dwarf -c test.ii -o test.s -S | |
| 6 | ## clang version: 6.0.0 (trunk 318293) | |
| 7 | ## | |
| 8 | ## test.ii: | |
| 9 | ## int a; | |
| 10 | ## | |
| 11 | ## Debug information does not contain any address ranges. | |
| 12 | ## We crashed in that case. Check we don't. | |
| 13 | # RUN: ld.lld --gdb-index %t1.o -o %t | |
| 14 | ||
| 15 | .section .debug_str,"MS",@progbits,1 | |
| 16 | .Lskel_string0: | |
| 17 | .asciz "t.dwo" | |
| 18 | .Lskel_string1: | |
| 19 | .asciz "path" | |
| 20 | ||
| 21 | .section .debug_abbrev,"",@progbits | |
| 22 | .byte 1 # Abbreviation Code | |
| 23 | .byte 17 # DW_TAG_compile_unit | |
| 24 | .byte 0 # DW_CHILDREN_no | |
| 25 | .byte 16 # DW_AT_stmt_list | |
| 26 | .byte 23 # DW_FORM_sec_offset | |
| 27 | .ascii "\260B" # DW_AT_GNU_dwo_name | |
| 28 | .byte 14 # DW_FORM_strp | |
| 29 | .byte 27 # DW_AT_comp_dir | |
| 30 | .byte 14 # DW_FORM_strp | |
| 31 | .ascii "\261B" # DW_AT_GNU_dwo_id | |
| 32 | .byte 7 # DW_FORM_data8 | |
| 33 | .ascii "\263B" # DW_AT_GNU_addr_base | |
| 34 | .byte 23 # DW_FORM_sec_offset | |
| 35 | .byte 0 # EOM(1) | |
| 36 | .byte 0 # EOM(2) | |
| 37 | .byte 0 # EOM(3) | |
| 38 | ||
| 39 | .section .debug_info,"",@progbits | |
| 40 | .long 32 # Length of Unit | |
| 41 | .short 4 # DWARF version number | |
| 42 | .long .debug_abbrev # Offset Into Abbrev. Section | |
| 43 | .byte 8 # Address Size (in bytes) | |
| 44 | .byte 1 # Abbrev [1] 0xb:0x19 DW_TAG_compile_unit | |
| 45 | .long 0 # DW_AT_stmt_list | |
| 46 | .long .Lskel_string0 # DW_AT_GNU_dwo_name | |
| 47 | .long .Lskel_string1 # DW_AT_comp_dir | |
| 48 | .quad -3824446529333676116 # DW_AT_GNU_dwo_id | |
| 49 | .long 0 # DW_AT_GNU_addr_base |
deps/lld/test/ELF/gdb-index-ranges.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 3 | 3 | # RUN: ld.lld --gdb-index -e main %t.o -o %t |
| 4 | # RUN: llvm-dwarfdump -debug-dump=gdb_index %t | FileCheck %s | |
| 4 | # RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s | |
| 5 | 5 | |
| 6 | 6 | # CHECK: .gnu_index contents: |
| 7 | 7 | # CHECK: Address area offset = 0x28, has 2 entries: |
deps/lld/test/ELF/gdb-index-tls.s created+91| ... | ... | @@ -0,0 +1,91 @@ |
| 1 | # REQUIRES: x86 | |
| 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 | |
| 4 | ||
| 5 | # This used to fail trying to compute R_X86_64_DTPOFF64 | |
| 6 | ||
| 7 | 	.section	.tdata,"awT",@progbits | |
| 8 | PrettyStackTraceHead: | |
| 9 | 	.long	42 # 0x2a | |
| 10 | ||
| 11 | 	.section	.debug_str,"MS",@progbits,1 | |
| 12 | 	.asciz	"" | |
| 13 | ||
| 14 | 	.section	.debug_abbrev,"",@progbits | |
| 15 | 	.byte	1 # Abbreviation Code | |
| 16 | 	.byte	17 # DW_TAG_compile_unit | |
| 17 | 	.byte	1 # DW_CHILDREN_yes | |
| 18 | 	.byte	37 # DW_AT_producer | |
| 19 | 	.byte	14 # DW_FORM_strp | |
| 20 | 	.byte	19 # DW_AT_language | |
| 21 | 	.byte	5 # DW_FORM_data2 | |
| 22 | 	.byte	3 # DW_AT_name | |
| 23 | 	.byte	14 # DW_FORM_strp | |
| 24 | 	.byte	16 # DW_AT_stmt_list | |
| 25 | 	.byte	23 # DW_FORM_sec_offset | |
| 26 | 	.byte	27 # DW_AT_comp_dir | |
| 27 | 	.byte	14 # DW_FORM_strp | |
| 28 | 	.ascii	"\264B" # DW_AT_GNU_pubnames | |
| 29 | 	.byte	25 # DW_FORM_flag_present | |
| 30 | 	.byte	0 # EOM(1) | |
| 31 | 	.byte	0 # EOM(2) | |
| 32 | 	.byte	2 # Abbreviation Code | |
| 33 | 	.byte	52 # DW_TAG_variable | |
| 34 | 	.byte	0 # DW_CHILDREN_no | |
| 35 | 	.byte	3 # DW_AT_name | |
| 36 | 	.byte	14 # DW_FORM_strp | |
| 37 | 	.byte	73 # DW_AT_type | |
| 38 | 	.byte	19 # DW_FORM_ref4 | |
| 39 | 	.byte	63 # DW_AT_external | |
| 40 | 	.byte	25 # DW_FORM_flag_present | |
| 41 | 	.byte	58 # DW_AT_decl_file | |
| 42 | 	.byte	11 # DW_FORM_data1 | |
| 43 | 	.byte	59 # DW_AT_decl_line | |
| 44 | 	.byte	11 # DW_FORM_data1 | |
| 45 | 	.byte	2 # DW_AT_location | |
| 46 | 	.byte	24 # DW_FORM_exprloc | |
| 47 | 	.byte	0 # EOM(1) | |
| 48 | 	.byte	0 # EOM(2) | |
| 49 | 	.byte	3 # Abbreviation Code | |
| 50 | 	.byte	36 # DW_TAG_base_type | |
| 51 | 	.byte	0 # DW_CHILDREN_no | |
| 52 | 	.byte	3 # DW_AT_name | |
| 53 | 	.byte	14 # DW_FORM_strp | |
| 54 | 	.byte	62 # DW_AT_encoding | |
| 55 | 	.byte	11 # DW_FORM_data1 | |
| 56 | 	.byte	11 # DW_AT_byte_size | |
| 57 | 	.byte	11 # DW_FORM_data1 | |
| 58 | 	.byte	0 # EOM(1) | |
| 59 | 	.byte	0 # EOM(2) | |
| 60 | 	.byte	0 # EOM(3) | |
| 61 | ||
| 62 | 	.section	.debug_info,"",@progbits | |
| 63 | .Lcu_begin0: | |
| 64 | 	.long	56 # Length of Unit | |
| 65 | 	.short	4 # DWARF version number | |
| 66 | 	.long	.debug_abbrev # Offset Into Abbrev. Section | |
| 67 | 	.byte	8 # Address Size (in bytes) | |
| 68 | 	.byte	1 # Abbrev [1] 0xb:0x31 DW_TAG_compile_unit | |
| 69 | 	.long	.debug_str # DW_AT_producer | |
| 70 | 	.short	4 # DW_AT_language | |
| 71 | 	.long	.debug_str # DW_AT_name | |
| 72 | 	.long	.debug_line # DW_AT_stmt_list | |
| 73 | 	.long	.debug_str # DW_AT_comp_dir | |
| 74 | # DW_AT_GNU_pubnames | |
| 75 | 	.byte	2 # Abbrev [2] 0x1e:0x16 DW_TAG_variable | |
| 76 | 	.long	.debug_str # DW_AT_name | |
| 77 | 	.long	52 # DW_AT_type | |
| 78 | # DW_AT_external | |
| 79 | 	.byte	1 # DW_AT_decl_file | |
| 80 | 	.byte	1 # DW_AT_decl_line | |
| 81 | 	.byte	10 # DW_AT_location | |
| 82 | 	.byte	14 | |
| 83 | 	.quad	PrettyStackTraceHead@DTPOFF | |
| 84 | 	.byte	224 | |
| 85 | 	.byte	3 # Abbrev [3] 0x34:0x7 DW_TAG_base_type | |
| 86 | 	.long	.debug_str # DW_AT_name | |
| 87 | 	.byte	5 # DW_AT_encoding | |
| 88 | 	.byte	4 # DW_AT_byte_size | |
| 89 | 	.byte	0 # End Of Children Mark | |
| 90 | ||
| 91 | 	.section	.debug_line,"",@progbits |
deps/lld/test/ELF/gdb-index.s+17-13| ... | ... | @@ -1,12 +1,12 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o |
| 3 | 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 -e main %t1.o %t2.o -o %t | |
| 5 | # RUN: llvm-dwarfdump -debug-dump=gdb_index %t | FileCheck %s | |
| 4 | # RUN: ld.lld --gdb-index %t1.o %t2.o -o %t | |
| 5 | # RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s | |
| 6 | 6 | # RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DISASM |
| 7 | 7 | |
| 8 | 8 | # DISASM: Disassembly of section .text: |
| 9 | # DISASM: main: | |
| 9 | # DISASM: entrypoint: | |
| 10 | 10 | # DISASM-CHECK: 201000: 90 nop |
| 11 | 11 | # DISASM-CHECK: 201001: cc int3 |
| 12 | 12 | # DISASM-CHECK: 201002: cc int3 |
| ... | ... | @@ -24,25 +24,29 @@ |
| 24 | 24 | # CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0 |
| 25 | 25 | # CHECK-NEXT: Low/High address = [0x201004, 0x201006) (Size: 0x2), CU id = 1 |
| 26 | 26 | # CHECK: Symbol table offset = 0x60, size = 1024, filled slots: |
| 27 | # CHECK-NEXT: 489: Name offset = 0x1d, CU vector offset = 0x0 | |
| 28 | # CHECK-NEXT: String name: main, CU vector index: 0 | |
| 29 | # CHECK-NEXT: 754: Name offset = 0x22, CU vector offset = 0x8 | |
| 30 | # CHECK-NEXT: String name: int, CU vector index: 1 | |
| 31 | # CHECK-NEXT: 956: Name offset = 0x26, CU vector offset = 0x14 | |
| 27 | # CHECK-NEXT: 754: Name offset = 0x27, CU vector offset = 0x8 | |
| 28 | # CHECK-NEXT:	 String name: int, CU vector index: 1 | |
| 29 | # CHECK-NEXT: 822: Name offset = 0x1c, CU vector offset = 0x0 | |
| 30 | # CHECK-NEXT:	 String name: entrypoint, CU vector index: 0 | |
| 31 | # CHECK-NEXT: 956: Name offset = 0x2b, CU vector offset = 0x14 | |
| 32 | 32 | # CHECK-NEXT: String name: main2, CU vector index: 2 |
| 33 | 33 | # CHECK: Constant pool offset = 0x2060, has 3 CU vectors: |
| 34 | 34 | # CHECK-NEXT: 0(0x0): 0x30000000 |
| 35 | 35 | # CHECK-NEXT: 1(0x8): 0x90000000 0x90000001 |
| 36 | 36 | # CHECK-NEXT: 2(0x14): 0x30000001 |
| 37 | 37 | |
| 38 | # 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 | |
| 40 | # NOGDB-NOT: Name: .gdb_index | |
| 41 | ||
| 38 | 42 | ## The following section contents are created by this using gcc 7.1.0: |
| 39 | ## echo 'int main() { return 0; }' | gcc -gsplit-dwarf -xc++ -S -o- - | |
| 43 | ## echo 'int entrypoint() { return 0; }' | gcc -gsplit-dwarf -xc++ -S -o- - | |
| 40 | 44 | |
| 41 | 45 | .text |
| 42 | 46 | .Ltext0: |
| 43 | .globl main | |
| 44 | .type main, @function | |
| 45 | main: | |
| 47 | .globl entrypoint | |
| 48 | .type entrypoint, @function | |
| 49 | entrypoint: | |
| 46 | 50 | nop |
| 47 | 51 | .Letext0: |
| 48 | 52 | |
| ... | ... | @@ -98,7 +102,7 @@ main: |
| 98 | 102 | .long 0x33 |
| 99 | 103 | .long 0x18 |
| 100 | 104 | .byte 0x30 |
| 101 | .string "main" | |
| 105 | .string "entrypoint" | |
| 102 | 106 | .long 0 |
| 103 | 107 | |
| 104 | 108 | .section .debug_gnu_pubtypes,"",@progbits |
deps/lld/test/ELF/global-offset-table-position-aarch64.s+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t |
| 2 | // RUN: ld.lld -shared %t -o %t2 | |
| 2 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 | |
| 3 | 3 | // RUN: llvm-readobj -t %t2 | FileCheck %s |
| 4 | 4 | // REQUIRES: aarch64 |
| 5 | 5 | .globl a |
deps/lld/test/ELF/global-offset-table-position-arm.s+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t |
| 2 | // RUN: ld.lld -shared %t -o %t2 | |
| 2 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 | |
| 3 | 3 | // RUN: llvm-readobj -t %t2 | FileCheck %s |
| 4 | 4 | // REQUIRES: arm |
| 5 | 5 |
deps/lld/test/ELF/global-offset-table-position-i386.s+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t |
| 2 | // RUN: ld.lld -shared %t -o %t2 | |
| 2 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 | |
| 3 | 3 | // RUN: llvm-readobj -t %t2 | FileCheck %s |
| 4 | 4 | // REQUIRES: x86 |
| 5 | 5 |
deps/lld/test/ELF/global-offset-table-position.s+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | // RUN: ld.lld -shared %t -o %t2 | |
| 2 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 | |
| 3 | 3 | // RUN: llvm-readobj -t %t2 | FileCheck %s |
| 4 | 4 | // REQUIRES: x86 |
| 5 | 5 |
deps/lld/test/ELF/global_offset_table_shared.s+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | // RUN: ld.lld -shared %t -o %t2 | |
| 2 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 | |
| 3 | 3 | // RUN: llvm-readobj -t %t2 | FileCheck %s |
| 4 | 4 | .long _GLOBAL_OFFSET_TABLE_ - . |
| 5 | 5 |
deps/lld/test/ELF/gnu-hash-table-copy.s created+30| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # RUN: echo ".global foo; .type foo, @object; .size foo, 4; foo:; .long 0" > %t.s | |
| 4 | # RUN: echo ".global bar; .type bar, @object; .size bar, 4; bar:; .long 0" >> %t.s | |
| 5 | # RUN: echo ".global zed; .type zed, @function; zed:" >> %t.s | |
| 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t.s -o %t1.o | |
| 7 | # RUN: ld.lld %t1.o -o %t1.so -shared | |
| 8 | ||
| 9 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o | |
| 10 | # RUN: ld.lld --hash-style=gnu %t2.o %t1.so -o %t2 | |
| 11 | ||
| 12 | # RUN: llvm-readelf --symbols --gnu-hash-table %t2 | FileCheck %s | |
| 13 | ||
| 14 | # CHECK: Symbol table '.dynsym' contains 4 entries: | |
| 15 | # CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name | |
| 16 | # CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND @ | |
| 17 | # CHECK-NEXT: 1: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND foo@ | |
| 18 | # CHECK-DAG: : {{.*}} 4 OBJECT GLOBAL DEFAULT {{.*}} bar@ | |
| 19 | # CHECK-DAG: : {{.*}} 0 FUNC GLOBAL DEFAULT UND zed@ | |
| 20 | ||
| 21 | # CHECK: First Hashed Symbol Index: 2 | |
| 22 | ||
| 23 | .global _start | |
| 24 | _start: | |
| 25 | ||
| 26 | .quad bar | |
| 27 | .quad zed | |
| 28 | ||
| 29 | .data | |
| 30 | .quad foo |
deps/lld/test/ELF/gnu-hash-table-many.s created+55| ... | ... | @@ -0,0 +1,55 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 4 | # RUN: ld.lld -hash-style=gnu %t.o -o %t.so -shared | |
| 5 | # RUN: llvm-readelf --gnu-hash-table %t.so | FileCheck %s | |
| 6 | ||
| 7 | # CHECK: Num Buckets: 4 | |
| 8 | ||
| 9 | .global sym1 | |
| 10 | sym1: | |
| 11 | ||
| 12 | .global sym2 | |
| 13 | sym2: | |
| 14 | ||
| 15 | .global sym3 | |
| 16 | sym3: | |
| 17 | ||
| 18 | .global sym4 | |
| 19 | sym4: | |
| 20 | ||
| 21 | .global sym5 | |
| 22 | sym5: | |
| 23 | ||
| 24 | .global sym6 | |
| 25 | sym6: | |
| 26 | ||
| 27 | .global sym7 | |
| 28 | sym7: | |
| 29 | ||
| 30 | .global sym8 | |
| 31 | sym8: | |
| 32 | ||
| 33 | .global sym9 | |
| 34 | sym9: | |
| 35 | ||
| 36 | .global sym10 | |
| 37 | sym10: | |
| 38 | ||
| 39 | .global sym11 | |
| 40 | sym11: | |
| 41 | ||
| 42 | .global sym12 | |
| 43 | sym12: | |
| 44 | ||
| 45 | .global sym13 | |
| 46 | sym13: | |
| 47 | ||
| 48 | .global sym14 | |
| 49 | sym14: | |
| 50 | ||
| 51 | .global sym15 | |
| 52 | sym15: | |
| 53 | ||
| 54 | .global sym16 | |
| 55 | sym16: |
deps/lld/test/ELF/gnu-hash-table-rwsegment.s created+20| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 4 | # RUN: ld.lld -shared -hash-style=gnu --no-rosegment -o %t.so %t.o | |
| 5 | # RUN: llvm-readobj -gnu-hash-table %t.so | FileCheck %s | |
| 6 | ||
| 7 | # CHECK: GnuHashTable { | |
| 8 | # CHECK-NEXT: Num Buckets: 1 | |
| 9 | # CHECK-NEXT: First Hashed Symbol Index: 1 | |
| 10 | # CHECK-NEXT: Num Mask Words: 1 | |
| 11 | # CHECK-NEXT: Shift Count: 6 | |
| 12 | # CHECK-NEXT: Bloom Filter: [0x400000000004204] | |
| 13 | # CHECK-NEXT: Buckets: [1] | |
| 14 | # CHECK-NEXT: Values: [0xB8860BA, 0xB887389] | |
| 15 | # CHECK-NEXT: } | |
| 16 | ||
| 17 | .globl foo, bar | |
| 18 | foo: | |
| 19 | bar: | |
| 20 | ret |
deps/lld/test/ELF/gnu-hash-table.s+66-13| ... | ... | @@ -1,15 +1,34 @@ |
| 1 | 1 | # REQUIRES: x86,ppc |
| 2 | 2 | |
| 3 | # RUN: echo ".globl foo" > %te.s | |
| 3 | # RUN: echo ".globl foo; .data; .dc.a foo" > %te.s | |
| 4 | 4 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %te.s -o %te-i386.o |
| 5 | 5 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t-i386.o |
| 6 | 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t-x86_64.o |
| 7 | 7 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %s -o %t-ppc64.o |
| 8 | 8 | |
| 9 | # 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=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 | ||
| 14 | # RUN: rm -f %t2-i386.a %t2-x86_64.a %t2-ppc64.a | |
| 15 | # RUN: llvm-ar rc %t2-i386.a %t2-i386.o | |
| 16 | # RUN: llvm-ar rc %t2-x86_64.a %t2-x86_64.o | |
| 17 | # RUN: llvm-ar rc %t2-ppc64.a %t2-ppc64.o | |
| 18 | ||
| 19 | # RUN: echo ".global xyz; xyz:" > %t3.s | |
| 20 | # 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 | |
| 22 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %t3.s -o %t3-ppc64.o | |
| 23 | ||
| 24 | # 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 | |
| 26 | # RUN: ld.lld -shared %t3-ppc64.o -o %t3-ppc64.so | |
| 27 | ||
| 9 | 28 | # RUN: ld.lld -shared --hash-style=gnu -o %te-i386.so %te-i386.o |
| 10 | # RUN: ld.lld -shared -hash-style=gnu -o %t-i386.so %t-i386.o | |
| 11 | # RUN: ld.lld -shared -hash-style=gnu -o %t-x86_64.so %t-x86_64.o | |
| 12 | # RUN: ld.lld -shared --hash-style both -o %t-ppc64.so %t-ppc64.o | |
| 29 | # 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 | |
| 31 | # RUN: ld.lld -shared --hash-style both -o %t-ppc64.so %t-ppc64.o %t2-ppc64.a %t3-ppc64.so | |
| 13 | 32 | |
| 14 | 33 | # RUN: llvm-readobj -dyn-symbols -gnu-hash-table %te-i386.so \ |
| 15 | 34 | # RUN: | FileCheck %s -check-prefix=EMPTY |
| ... | ... | @@ -70,6 +89,16 @@ |
| 70 | 89 | # I386: Section: Undefined |
| 71 | 90 | # I386: } |
| 72 | 91 | # I386: Symbol { |
| 92 | # I386: Name: xyz@ | |
| 93 | # I386: Binding: Global | |
| 94 | # I386: Section: Undefined | |
| 95 | # I386: } | |
| 96 | # I386: Symbol { | |
| 97 | # I386: Name: zed@ | |
| 98 | # I386: Binding: Weak | |
| 99 | # I386: Section: Undefined | |
| 100 | # I386: } | |
| 101 | # I386: Symbol { | |
| 73 | 102 | # I386: Name: bar@ |
| 74 | 103 | # I386: Binding: Global |
| 75 | 104 | # I386: Section: .text |
| ... | ... | @@ -82,11 +111,11 @@ |
| 82 | 111 | # I386: ] |
| 83 | 112 | # I386: GnuHashTable { |
| 84 | 113 | # I386-NEXT: Num Buckets: 1 |
| 85 | # I386-NEXT: First Hashed Symbol Index: 2 | |
| 114 | # I386-NEXT: First Hashed Symbol Index: 4 | |
| 86 | 115 | # I386-NEXT: Num Mask Words: 1 |
| 87 | 116 | # I386-NEXT: Shift Count: 5 |
| 88 | 117 | # I386-NEXT: Bloom Filter: [0x14000220] |
| 89 | # I386-NEXT: Buckets: [2] | |
| 118 | # I386-NEXT: Buckets: [4] | |
| 90 | 119 | # I386-NEXT: Values: [0xB8860BA, 0xB887389] |
| 91 | 120 | # I386-NEXT: } |
| 92 | 121 | |
| ... | ... | @@ -120,6 +149,16 @@ |
| 120 | 149 | # X86_64: Section: Undefined |
| 121 | 150 | # X86_64: } |
| 122 | 151 | # X86_64: Symbol { |
| 152 | # X86_64: Name: xyz@ | |
| 153 | # X86_64: Binding: Global | |
| 154 | # X86_64: Section: Undefined | |
| 155 | # X86_64: } | |
| 156 | # X86_64: Symbol { | |
| 157 | # X86_64: Name: zed@ | |
| 158 | # X86_64: Binding: Weak | |
| 159 | # X86_64: Section: Undefined | |
| 160 | # X86_64: } | |
| 161 | # X86_64: Symbol { | |
| 123 | 162 | # X86_64: Name: bar@ |
| 124 | 163 | # X86_64: Binding: Global |
| 125 | 164 | # X86_64: Section: .text |
| ... | ... | @@ -132,11 +171,11 @@ |
| 132 | 171 | # X86_64: ] |
| 133 | 172 | # X86_64: GnuHashTable { |
| 134 | 173 | # X86_64-NEXT: Num Buckets: 1 |
| 135 | # X86_64-NEXT: First Hashed Symbol Index: 2 | |
| 174 | # X86_64-NEXT: First Hashed Symbol Index: 4 | |
| 136 | 175 | # X86_64-NEXT: Num Mask Words: 1 |
| 137 | 176 | # X86_64-NEXT: Shift Count: 6 |
| 138 | 177 | # X86_64-NEXT: Bloom Filter: [0x400000000004204] |
| 139 | # X86_64-NEXT: Buckets: [2] | |
| 178 | # X86_64-NEXT: Buckets: [4] | |
| 140 | 179 | # X86_64-NEXT: Values: [0xB8860BA, 0xB887389] |
| 141 | 180 | # X86_64-NEXT: } |
| 142 | 181 | |
| ... | ... | @@ -149,10 +188,10 @@ |
| 149 | 188 | # PPC64-NEXT: Flags [ |
| 150 | 189 | # PPC64-NEXT: SHF_ALLOC |
| 151 | 190 | # PPC64-NEXT: ] |
| 152 | # PPC64-NEXT: Address: 0x228 | |
| 153 | # PPC64-NEXT: Offset: 0x228 | |
| 191 | # PPC64-NEXT: Address: | |
| 192 | # PPC64-NEXT: Offset: | |
| 154 | 193 | # PPC64-NEXT: Size: 36 |
| 155 | # PPC64-NEXT: Link: 1 | |
| 194 | # PPC64-NEXT: Link: | |
| 156 | 195 | # PPC64-NEXT: Info: 0 |
| 157 | 196 | # PPC64-NEXT: AddressAlignment: 8 |
| 158 | 197 | # PPC64-NEXT: EntrySize: 0 |
| ... | ... | @@ -170,6 +209,16 @@ |
| 170 | 209 | # PPC64: Section: Undefined |
| 171 | 210 | # PPC64: } |
| 172 | 211 | # PPC64: Symbol { |
| 212 | # PPC64: Name: xyz@ | |
| 213 | # PPC64: Binding: Global | |
| 214 | # PPC64: Section: Undefined | |
| 215 | # PPC64: } | |
| 216 | # PPC64: Symbol { | |
| 217 | # PPC64: Name: zed@ | |
| 218 | # PPC64: Binding: Weak | |
| 219 | # PPC64: Section: Undefined | |
| 220 | # PPC64: } | |
| 221 | # PPC64: Symbol { | |
| 173 | 222 | # PPC64: Name: bar@ |
| 174 | 223 | # PPC64: Binding: Global |
| 175 | 224 | # PPC64: Section: .text |
| ... | ... | @@ -182,14 +231,18 @@ |
| 182 | 231 | # PPC64: ] |
| 183 | 232 | # PPC64: GnuHashTable { |
| 184 | 233 | # PPC64-NEXT: Num Buckets: 1 |
| 185 | # PPC64-NEXT: First Hashed Symbol Index: 2 | |
| 234 | # PPC64-NEXT: First Hashed Symbol Index: 4 | |
| 186 | 235 | # PPC64-NEXT: Num Mask Words: 1 |
| 187 | 236 | # PPC64-NEXT: Shift Count: 6 |
| 188 | 237 | # PPC64-NEXT: Bloom Filter: [0x400000000004204] |
| 189 | # PPC64-NEXT: Buckets: [2] | |
| 238 | # PPC64-NEXT: Buckets: [4] | |
| 190 | 239 | # PPC64-NEXT: Values: [0xB8860BA, 0xB887389] |
| 191 | 240 | # PPC64-NEXT: } |
| 192 | 241 | |
| 193 | 242 | .globl foo,bar,baz |
| 194 | 243 | foo: |
| 195 | 244 | bar: |
| 245 | .weak zed | |
| 246 | .global xyz | |
| 247 | .data | |
| 248 | .dc.a baz |
deps/lld/test/ELF/gnu-ifunc-dynsym.s created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 2 | // RUN: ld.lld -static -export-dynamic %t.o -o %tout | |
| 3 | // RUN: llvm-nm -U %tout | FileCheck %s | |
| 4 | // REQUIRES: x86 | |
| 5 | ||
| 6 | // CHECK: __rela_iplt_end | |
| 7 | // CHECK: __rela_iplt_start | |
| 8 | ||
| 9 | .text | |
| 10 | .type foo STT_GNU_IFUNC | |
| 11 | .globl foo | |
| 12 | foo: | |
| 13 | ret | |
| 14 | ||
| 15 | .globl _start | |
| 16 | _start: | |
| 17 | call foo | |
| 18 | movl $__rela_iplt_start,%edx | |
| 19 | movl $__rela_iplt_end,%edx |
deps/lld/test/ELF/gnu-ifunc-dyntags.s created+41| ... | ... | @@ -0,0 +1,41 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 3 | # RUN: ld.lld -pie %t.o -o %tout | |
| 4 | # RUN: llvm-objdump -section-headers %tout | FileCheck %s | |
| 5 | # RUN: llvm-readobj -dynamic-table -r %tout | FileCheck %s --check-prefix=TAGS | |
| 6 | ||
| 7 | ## Check we produce DT_PLTREL/DT_JMPREL/DT_PLTGOT and DT_PLTRELSZ tags | |
| 8 | ## when there are no other relocations except R_*_IRELATIVE. | |
| 9 | ||
| 10 | # CHECK: Name Size Address | |
| 11 | # CHECK: .rela.plt 00000030 0000000000000210 | |
| 12 | # CHECK: .got.plt 00000010 0000000000002000 | |
| 13 | ||
| 14 | # TAGS: Relocations [ | |
| 15 | # TAGS-NEXT: Section {{.*}} .rela.plt { | |
| 16 | # TAGS-NEXT: R_X86_64_IRELATIVE | |
| 17 | # TAGS-NEXT: R_X86_64_IRELATIVE | |
| 18 | # TAGS-NEXT: } | |
| 19 | # TAGS-NEXT: ] | |
| 20 | ||
| 21 | # TAGS: Tag Type Name/Value | |
| 22 | # TAGS: 0x0000000000000017 JMPREL 0x210 | |
| 23 | # TAGS: 0x0000000000000002 PLTRELSZ 48 | |
| 24 | # TAGS: 0x0000000000000003 PLTGOT 0x2000 | |
| 25 | # TAGS: 0x0000000000000014 PLTREL RELA | |
| 26 | ||
| 27 | .text | |
| 28 | .type foo STT_GNU_IFUNC | |
| 29 | .globl foo | |
| 30 | foo: | |
| 31 | ret | |
| 32 | ||
| 33 | .type bar STT_GNU_IFUNC | |
| 34 | .globl bar | |
| 35 | bar: | |
| 36 | ret | |
| 37 | ||
| 38 | .globl _start | |
| 39 | _start: | |
| 40 | call foo | |
| 41 | call bar |
deps/lld/test/ELF/gnu-ifunc-gotpcrel.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/gnu-ifunc-gotpcrel.s -o %t2.o |
| 3 | 3 | # RUN: ld.lld -shared %t2.o -o %t2.so |
| 4 | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 5 | # RUN: ld.lld %t.o %t2.so -o %t | |
| 5 | # RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t | |
| 6 | 6 | # RUN: llvm-readobj -dyn-relocations %t | FileCheck %s |
| 7 | 7 | |
| 8 | 8 | # CHECK: Dynamic Relocations { |
deps/lld/test/ELF/gnu-ifunc-i386.s+3-3| ... | ... | @@ -15,7 +15,7 @@ |
| 15 | 15 | // CHECK-NEXT: Address: [[RELA:.*]] |
| 16 | 16 | // CHECK-NEXT: Offset: 0xD4 |
| 17 | 17 | // CHECK-NEXT: Size: 16 |
| 18 | // CHECK-NEXT: Link: 6 | |
| 18 | // CHECK-NEXT: Link: 0 | |
| 19 | 19 | // CHECK-NEXT: Info: 0 |
| 20 | 20 | // CHECK-NEXT: AddressAlignment: 4 |
| 21 | 21 | // CHECK-NEXT: EntrySize: 8 |
| ... | ... | @@ -102,10 +102,10 @@ |
| 102 | 102 | // DISASM-NEXT: .plt: |
| 103 | 103 | // DISASM-NEXT: 11020: ff 25 00 20 01 00 jmpl *73728 |
| 104 | 104 | // DISASM-NEXT: 11026: 68 10 00 00 00 pushl $16 |
| 105 | // DISASM-NEXT: 1102b: e9 e0 ff ff ff jmp -32 <_start+0xE> | |
| 105 | // DISASM-NEXT: 1102b: e9 e0 ff ff ff jmp -32 <_start+0xe> | |
| 106 | 106 | // DISASM-NEXT: 11030: ff 25 04 20 01 00 jmpl *73732 |
| 107 | 107 | // DISASM-NEXT: 11036: 68 18 00 00 00 pushl $24 |
| 108 | // DISASM-NEXT: 1103b: e9 d0 ff ff ff jmp -48 <_start+0xE> | |
| 108 | // DISASM-NEXT: 1103b: e9 d0 ff ff ff jmp -48 <_start+0xe> | |
| 109 | 109 | |
| 110 | 110 | .text |
| 111 | 111 | .type foo STT_GNU_IFUNC |
deps/lld/test/ELF/gnu-ifunc-plt-i386.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/shared2-x86-64.s -o %t1.o |
| 2 | 2 | // RUN: ld.lld %t1.o --shared -o %t.so |
| 3 | 3 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| 4 | // RUN: ld.lld %t.so %t.o -o %tout | |
| 4 | // RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout | |
| 5 | 5 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM |
| 6 | 6 | // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT |
| 7 | 7 | // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s |
deps/lld/test/ELF/gnu-ifunc-plt.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/shared2-x86-64.s -o %t1.o |
| 2 | 2 | // RUN: ld.lld %t1.o --shared -o %t.so |
| 3 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 4 | // RUN: ld.lld %t.so %t.o -o %tout | |
| 4 | // RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout | |
| 5 | 5 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM |
| 6 | 6 | // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT |
| 7 | 7 | // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s |
deps/lld/test/ELF/gnu-ifunc-shared.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 3 | // RUN: ld.lld --shared -o %t.so %t.o | |
| 3 | // RUN: ld.lld --hash-style=sysv --shared -o %t.so %t.o | |
| 4 | 4 | // RUN: llvm-objdump -d %t.so | FileCheck %s --check-prefix=DISASM |
| 5 | 5 | // RUN: llvm-readobj -r %t.so | FileCheck %s |
| 6 | 6 |
deps/lld/test/ELF/gnu-ifunc.s+3-3| ... | ... | @@ -15,7 +15,7 @@ |
| 15 | 15 | // CHECK-NEXT: Address: [[RELA:.*]] |
| 16 | 16 | // CHECK-NEXT: Offset: 0x158 |
| 17 | 17 | // CHECK-NEXT: Size: 48 |
| 18 | // CHECK-NEXT: Link: 6 | |
| 18 | // CHECK-NEXT: Link: 0 | |
| 19 | 19 | // CHECK-NEXT: Info: 0 |
| 20 | 20 | // CHECK-NEXT: AddressAlignment: 8 |
| 21 | 21 | // CHECK-NEXT: EntrySize: 24 |
| ... | ... | @@ -102,10 +102,10 @@ |
| 102 | 102 | // DISASM-NEXT: .plt: |
| 103 | 103 | // DISASM-NEXT: 201020: {{.*}} jmpq *4058(%rip) |
| 104 | 104 | // DISASM-NEXT: 201026: {{.*}} pushq $0 |
| 105 | // DISASM-NEXT: 20102b: {{.*}} jmp -32 <_start+0xE> | |
| 105 | // DISASM-NEXT: 20102b: {{.*}} jmp -32 <_start+0xe> | |
| 106 | 106 | // DISASM-NEXT: 201030: {{.*}} jmpq *4050(%rip) |
| 107 | 107 | // DISASM-NEXT: 201036: {{.*}} pushq $1 |
| 108 | // DISASM-NEXT: 20103b: {{.*}} jmp -48 <_start+0xE> | |
| 108 | // DISASM-NEXT: 20103b: {{.*}} jmp -48 <_start+0xe> | |
| 109 | 109 | |
| 110 | 110 | .text |
| 111 | 111 | .type foo STT_GNU_IFUNC |
deps/lld/test/ELF/got-aarch64.s+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.o |
| 2 | // RUN: ld.lld -shared %t.o -o %t.so | |
| 2 | // RUN: ld.lld --hash-style=sysv -shared %t.o -o %t.so | |
| 3 | 3 | // RUN: llvm-readobj -s -r %t.so | FileCheck %s |
| 4 | 4 | // RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s |
| 5 | 5 | // REQUIRES: aarch64 |
deps/lld/test/ELF/got.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | 3 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| 4 | // RUN: ld.lld %t.o %t2.so -o %t | |
| 4 | // RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t | |
| 5 | 5 | // RUN: llvm-readobj -s -r %t | FileCheck %s |
| 6 | 6 | // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s |
| 7 | 7 | // REQUIRES: x86 |
deps/lld/test/ELF/got32-i386-pie-rw.s created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o | |
| 3 | # RUN: ld.lld %t.o -o %t -pie | |
| 4 | # RUN: llvm-readelf -r -s %t | FileCheck %s | |
| 5 | ||
| 6 | # Unlike bfd and gold we accept this. | |
| 7 | ||
| 8 | # CHECK: .foobar PROGBITS 00001000 | |
| 9 | # CHECK: .got PROGBITS [[GOT:[0-9a-z]*]] | |
| 10 | # CHECK: [[GOT]] 00000008 R_386_RELATIVE | |
| 11 | # CHECK: 00001002 00000008 R_386_RELATIVE | |
| 12 | foo: | |
| 13 | ||
| 14 | .section .foobar, "awx" | |
| 15 | .global _start | |
| 16 | _start: | |
| 17 | movl foo@GOT, %ebx |
deps/lld/test/ELF/got32-i386.s+1-1| ... | ... | @@ -20,4 +20,4 @@ _start: |
| 20 | 20 | # CHECK: .got 00000004 0000000000012000 |
| 21 | 21 | |
| 22 | 22 | # RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s --check-prefix=ERR |
| 23 | # ERR: relocation R_386_GOT32 against 'foo' without base register can not be used when PIC enabled | |
| 23 | # ERR: error: can't create dynamic relocation R_386_GOT32 against symbol: foo in readonly segment; recompile object files with -fPIC |
deps/lld/test/ELF/got32x-i386.s+2-2| ... | ... | @@ -43,5 +43,5 @@ |
| 43 | 43 | |
| 44 | 44 | # RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \ |
| 45 | 45 | # RUN: FileCheck %s --check-prefix=ERR |
| 46 | # ERR: relocation R_386_GOT32X against 'foo' without base register can not be used when PIC enabled | |
| 47 | # ERR: relocation R_386_GOT32X against 'foo' without base register can not be used when PIC enabled | |
| 46 | # 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 |
deps/lld/test/ELF/gotpc-relax-nopic.s+3-3| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o |
| 3 | # RUN: ld.lld %t.o -o %t1 | |
| 3 | # RUN: ld.lld --hash-style=sysv %t.o -o %t1 | |
| 4 | 4 | # RUN: llvm-readobj -symbols -r %t1 | FileCheck --check-prefix=SYMRELOC %s |
| 5 | 5 | # RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s |
| 6 | 6 | |
| ... | ... | @@ -25,7 +25,7 @@ |
| 25 | 25 | # DISASM-NEXT: 201031: {{.*}} xorq $2105344, %r8 |
| 26 | 26 | # DISASM-NEXT: 201038: {{.*}} testq $2105344, %r15 |
| 27 | 27 | |
| 28 | # RUN: ld.lld -shared %t.o -o %t2 | |
| 28 | # RUN: ld.lld --hash-style=sysv -shared %t.o -o %t2 | |
| 29 | 29 | # RUN: llvm-readobj -s -r -d %t2 | FileCheck --check-prefix=SEC-PIC %s |
| 30 | 30 | # RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM-PIC %s |
| 31 | 31 | # SEC-PIC: Section { |
| ... | ... | @@ -64,7 +64,7 @@ |
| 64 | 64 | # DISASM-PIC-NEXT: 1023: {{.*}} sbbq 8310(%rip), %rsi |
| 65 | 65 | # DISASM-PIC-NEXT: 102a: {{.*}} subq 8303(%rip), %rbp |
| 66 | 66 | # DISASM-PIC-NEXT: 1031: {{.*}} xorq 8296(%rip), %r8 |
| 67 | # DISASM-PIC-NEXT: 1038: {{.*}} testq 8289(%rip), %r15 | |
| 67 | # DISASM-PIC-NEXT: 1038: {{.*}} testq %r15, 8289(%rip) | |
| 68 | 68 | |
| 69 | 69 | .data |
| 70 | 70 | .type bar, @object |
deps/lld/test/ELF/gotpc-relax-und-dso.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux %S/Inputs/gotpc-relax-und-dso.s -o %tdso.o |
| 4 | 4 | # RUN: ld.lld -shared %tdso.o -o %t.so |
| 5 | # RUN: ld.lld -shared %t.o %t.so -o %tout | |
| 5 | # RUN: ld.lld --hash-style=sysv -shared %t.o %t.so -o %tout | |
| 6 | 6 | # RUN: llvm-readobj -r -s %tout | FileCheck --check-prefix=RELOC %s |
| 7 | 7 | # RUN: llvm-objdump -d %tout | FileCheck --check-prefix=DISASM %s |
| 8 | 8 |
deps/lld/test/ELF/gotpcrelx.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -relax-relocations -triple x86_64-pc-linux-gnu \ |
| 2 | 2 | // RUN: %s -o %t.o |
| 3 | 3 | // RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELS %s |
| 4 | // RUN: ld.lld %t.o -o %t.so -shared | |
| 4 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | |
| 5 | 5 | // RUN: llvm-readobj -s -r %t.so | FileCheck %s |
| 6 | 6 | |
| 7 | 7 | movq foo@GOTPCREL(%rip), %rax |
deps/lld/test/ELF/help.s created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | # RUN: ld.lld --help 2>&1 | FileCheck %s | |
| 2 | # CHECK: OPTIONS: | |
| 3 | # CHECK: --output=<value> Path to file to write output | |
| 4 | # CHECK: --output <value> Path to file to write output | |
| 5 | # CHECK: -o <path> Path to file to write output |
deps/lld/test/ELF/i386-debug-noabs.test created+33| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # RUN: yaml2obj %s -o %t.o | |
| 4 | # RUN: ld.lld %t.o -o %t.exe | |
| 5 | ||
| 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 | |
| 8 | ## in non-allocated sections. It is illegal, but we want to make sure that | |
| 9 | ## lld skips them instead of reporting errors. | |
| 10 | ||
| 11 | --- !ELF | |
| 12 | FileHeader: | |
| 13 | Class: ELFCLASS32 | |
| 14 | Data: ELFDATA2LSB | |
| 15 | Type: ET_REL | |
| 16 | Machine: EM_386 | |
| 17 | Sections: | |
| 18 | - Name: .debug_info | |
| 19 | Type: SHT_PROGBITS | |
| 20 | AddressAlign: 0x0000000000000001 | |
| 21 | Content: 0000000000000000 | |
| 22 | - Name: .rel.debug_info | |
| 23 | Type: SHT_REL | |
| 24 | Link: .symtab | |
| 25 | AddressAlign: 0x0000000000000004 | |
| 26 | Info: .debug_info | |
| 27 | Relocations: | |
| 28 | - Offset: 0x000000000000041F | |
| 29 | Symbol: _GLOBAL_OFFSET_TABLE_ | |
| 30 | Type: R_386_GOTPC | |
| 31 | Symbols: | |
| 32 | Global: | |
| 33 | - Name: _GLOBAL_OFFSET_TABLE_ |
deps/lld/test/ELF/i386-got-and-copy.s+1-1| ... | ... | @@ -9,7 +9,7 @@ |
| 9 | 9 | # RUN: %S/Inputs/copy-in-shared.s -o %t.so.o |
| 10 | 10 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o |
| 11 | 11 | # RUN: ld.lld %t.so.o -shared -o %t.so |
| 12 | # RUN: ld.lld %t.o %t.so -o %t.exe | |
| 12 | # RUN: ld.lld --hash-style=sysv %t.o %t.so -o %t.exe | |
| 13 | 13 | # RUN: llvm-readobj -r %t.exe | FileCheck %s |
| 14 | 14 | |
| 15 | 15 | # CHECK: Relocations [ |
deps/lld/test/ELF/i386-got-value.s created+33| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | # 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: llvm-readobj --relocations --sections --section-data %t.so | FileCheck %s | |
| 4 | ||
| 5 | # Check that the value of a preemptible symbol is not written to the | |
| 6 | # got entry when using Elf_Rel. It is not needed since the dynamic | |
| 7 | # linker will write the final value. | |
| 8 | ||
| 9 | # CHECK: Name: .got | |
| 10 | # CHECK-NEXT: Type: SHT_PROGBITS | |
| 11 | # CHECK-NEXT: Flags [ | |
| 12 | # CHECK-NEXT: SHF_ALLOC | |
| 13 | # CHECK-NEXT: SHF_WRITE | |
| 14 | # CHECK-NEXT: ] | |
| 15 | # CHECK-NEXT: Address: | |
| 16 | # CHECK-NEXT: Offset: | |
| 17 | # CHECK-NEXT: Size: 4 | |
| 18 | # CHECK-NEXT: Link: | |
| 19 | # CHECK-NEXT: Info: | |
| 20 | # CHECK-NEXT: AddressAlignment: | |
| 21 | # CHECK-NEXT: EntrySize: | |
| 22 | # CHECK-NEXT: SectionData ( | |
| 23 | # CHECK-NEXT: 0000: 00000000 | |
| 24 | # CHECK-NEXT: ) | |
| 25 | ||
| 26 | # CHECK: R_386_GLOB_DAT bar 0x0 | |
| 27 | ||
| 28 | movl bar@GOT(%eax), %eax | |
| 29 | ||
| 30 | .data | |
| 31 | .globl bar | |
| 32 | bar: | |
| 33 | .long 42 |
deps/lld/test/ELF/i386-gotoff-shared.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| 3 | // RUN: ld.lld %t.o -o %t.so -shared | |
| 3 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | |
| 4 | 4 | // RUN: llvm-readobj -s %t.so | FileCheck %s |
| 5 | 5 | // RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s |
| 6 | 6 |
deps/lld/test/ELF/i386-gotpc-dynamic.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| 3 | # RUN: ld.lld %t.o -o %t.so -shared | |
| 3 | # RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | |
| 4 | 4 | # RUN: llvm-readobj -s %t.so | FileCheck %s |
| 5 | 5 | # RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s |
| 6 | 6 |
deps/lld/test/ELF/i386-gotpc.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| 3 | // RUN: ld.lld %t.o -o %t.so -shared | |
| 3 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | |
| 4 | 4 | // RUN: llvm-readobj -s %t.so | FileCheck %s |
| 5 | 5 | // RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s |
| 6 | 6 |
deps/lld/test/ELF/i386-pc8-pc16-addend.s+1-1| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | # RUN: ld.lld %t1.o -o %t.out |
| 5 | 5 | # RUN: llvm-objdump -s -t %t.out | FileCheck %s |
| 6 | 6 | # CHECK: Contents of section .text: |
| 7 | # CHECK-NEXT: 11000 020000 | |
| 7 | # CHECK-NEXT: 11000 020000 | |
| 8 | 8 | ## 0x11003 - 0x11000 + addend(-1) = 0x02 |
| 9 | 9 | ## 0x11003 - 0x11001 + addend(-2) = 0x0000 |
| 10 | 10 | # CHECK: SYMBOL TABLE: |
deps/lld/test/ELF/i386-reloc-16.s+1-1| ... | ... | @@ -9,6 +9,6 @@ |
| 9 | 9 | // CHECK-NEXT: 200000 42 |
| 10 | 10 | |
| 11 | 11 | // RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s |
| 12 | // ERROR: relocation R_386_16 out of range | |
| 12 | // ERROR: relocation R_386_16 out of range: 65536 is not in [0, 65535] | |
| 13 | 13 | |
| 14 | 14 | .short foo |
deps/lld/test/ELF/i386-reloc-8.s+1-1| ... | ... | @@ -9,6 +9,6 @@ |
| 9 | 9 | // CHECK-NEXT: 200000 42 |
| 10 | 10 | |
| 11 | 11 | // RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s |
| 12 | // ERROR: relocation R_386_8 out of range | |
| 12 | // ERROR: relocation R_386_8 out of range: 256 is not in [0, 255] | |
| 13 | 13 | |
| 14 | 14 | .byte foo |
deps/lld/test/ELF/i386-reloc-range.s+1-1| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | |
| 17 | 17 | // RUN: not ld.lld -Ttext 0x200 %t.o %t2.o -o %t2 2>&1 | FileCheck --check-prefix=ERR %s |
| 18 | 18 | |
| 19 | // ERR: {{.*}}:(.text+0x1): relocation R_386_PC16 out of range | |
| 19 | // ERR: {{.*}}:(.text+0x1): relocation R_386_PC16 out of range: 65536 is not in [-65536, 65535] | |
| 20 | 20 | |
| 21 | 21 | .global _start |
| 22 | 22 | _start: |
deps/lld/test/ELF/i386-reloc8-reloc16-addend.s+1-1| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | # RUN: ld.lld -Ttext=0x0 %t1.o -o %t.out |
| 5 | 5 | # RUN: llvm-objdump -s -t %t.out | FileCheck %s |
| 6 | 6 | # CHECK: Contents of section .text: |
| 7 | # CHECK-NEXT: 0000 020100 | |
| 7 | # CHECK-NEXT: 0000 020100 | |
| 8 | 8 | ## 0x3 + addend(-1) = 0x02 |
| 9 | 9 | ## 0x3 + addend(-2) = 0x0100 |
| 10 | 10 | # CHECK: SYMBOL TABLE: |
deps/lld/test/ELF/i386-retpoline-nopic.s created+65| ... | ... | @@ -0,0 +1,65 @@ |
| 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: ld.lld %t1.o %t2.so -o %t.exe -z retpolineplt | |
| 7 | // RUN: llvm-objdump -d -s %t.exe | FileCheck %s | |
| 8 | ||
| 9 | // CHECK: Disassembly of section .plt: | |
| 10 | // CHECK-NEXT: .plt: | |
| 11 | // CHECK-NEXT: 11010: ff 35 04 20 01 00 pushl 73732 | |
| 12 | // CHECK-NEXT: 11016: 50 pushl %eax | |
| 13 | // CHECK-NEXT: 11017: a1 08 20 01 00 movl 73736, %eax | |
| 14 | // CHECK-NEXT: 1101c: e8 0f 00 00 00 calll 15 <.plt+0x20> | |
| 15 | // CHECK-NEXT: 11021: f3 90 pause | |
| 16 | // CHECK-NEXT: 11023: 0f ae e8 lfence | |
| 17 | // CHECK-NEXT: 11026: eb f9 jmp -7 <.plt+0x11> | |
| 18 | // CHECK-NEXT: 11028: cc int3 | |
| 19 | // CHECK-NEXT: 11029: cc int3 | |
| 20 | // CHECK-NEXT: 1102a: cc int3 | |
| 21 | // CHECK-NEXT: 1102b: cc int3 | |
| 22 | // CHECK-NEXT: 1102c: cc int3 | |
| 23 | // CHECK-NEXT: 1102d: cc int3 | |
| 24 | // CHECK-NEXT: 1102e: cc int3 | |
| 25 | // CHECK-NEXT: 1102f: cc int3 | |
| 26 | // CHECK-NEXT: 11030: 89 0c 24 movl %ecx, (%esp) | |
| 27 | // CHECK-NEXT: 11033: 8b 4c 24 04 movl 4(%esp), %ecx | |
| 28 | // CHECK-NEXT: 11037: 89 44 24 04 movl %eax, 4(%esp) | |
| 29 | // CHECK-NEXT: 1103b: 89 c8 movl %ecx, %eax | |
| 30 | // CHECK-NEXT: 1103d: 59 popl %ecx | |
| 31 | // CHECK-NEXT: 1103e: c3 retl | |
| 32 | // CHECK-NEXT: 1103f: cc int3 | |
| 33 | // CHECK-NEXT: 11040: 50 pushl %eax | |
| 34 | // CHECK-NEXT: 11041: a1 0c 20 01 00 movl 73740, %eax | |
| 35 | // CHECK-NEXT: 11046: e8 e5 ff ff ff calll -27 <.plt+0x20> | |
| 36 | // CHECK-NEXT: 1104b: e9 d1 ff ff ff jmp -47 <.plt+0x11> | |
| 37 | // CHECK-NEXT: 11050: 68 00 00 00 00 pushl $0 | |
| 38 | // CHECK-NEXT: 11055: e9 b6 ff ff ff jmp -74 <.plt> | |
| 39 | // CHECK-NEXT: 1105a: cc int3 | |
| 40 | // CHECK-NEXT: 1105b: cc int3 | |
| 41 | // CHECK-NEXT: 1105c: cc int3 | |
| 42 | // CHECK-NEXT: 1105d: cc int3 | |
| 43 | // CHECK-NEXT: 1105e: cc int3 | |
| 44 | // CHECK-NEXT: 1105f: cc int3 | |
| 45 | // CHECK-NEXT: 11060: 50 pushl %eax | |
| 46 | // CHECK-NEXT: 11061: a1 10 20 01 00 movl 73744, %eax | |
| 47 | // CHECK-NEXT: 11066: e8 c5 ff ff ff calll -59 <.plt+0x20> | |
| 48 | // CHECK-NEXT: 1106b: e9 b1 ff ff ff jmp -79 <.plt+0x11> | |
| 49 | // CHECK-NEXT: 11070: 68 08 00 00 00 pushl $8 | |
| 50 | // CHECK-NEXT: 11075: e9 96 ff ff ff jmp -106 <.plt> | |
| 51 | // CHECK-NEXT: 1107a: cc int3 | |
| 52 | // CHECK-NEXT: 1107b: cc int3 | |
| 53 | // CHECK-NEXT: 1107c: cc int3 | |
| 54 | // CHECK-NEXT: 1107d: cc int3 | |
| 55 | // CHECK-NEXT: 1107e: cc int3 | |
| 56 | // CHECK-NEXT: 1107f: cc int3 | |
| 57 | ||
| 58 | // CHECK: Contents of section .got.plt: | |
| 59 | // CHECK-NEXT: 00300100 00000000 00000000 50100100 | |
| 60 | // CHECK-NEXT: 70100100 | |
| 61 | ||
| 62 | .global _start | |
| 63 | _start: | |
| 64 | jmp bar@PLT | |
| 65 | jmp zed@PLT |
deps/lld/test/ELF/i386-retpoline-pic.s created+62| ... | ... | @@ -0,0 +1,62 @@ |
| 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: ld.lld %t1.o %t2.so -o %t.exe -z retpolineplt -pie | |
| 7 | // RUN: llvm-objdump -d -s %t.exe | FileCheck %s | |
| 8 | ||
| 9 | // CHECK: Disassembly of section .plt: | |
| 10 | // CHECK-NEXT: .plt: | |
| 11 | // CHECK-NEXT: 1010: ff b3 04 20 00 00 pushl 8196(%ebx) | |
| 12 | // CHECK-NEXT: 1016: 50 pushl %eax | |
| 13 | // CHECK-NEXT: 1017: 8b 83 08 20 00 00 movl 8200(%ebx), %eax | |
| 14 | // CHECK-NEXT: 101d: e8 0e 00 00 00 calll 14 <.plt+0x20> | |
| 15 | // CHECK-NEXT: 1022: f3 90 pause | |
| 16 | // CHECK-NEXT: 1024: 0f ae e8 lfence | |
| 17 | // CHECK-NEXT: 1027: eb f9 jmp -7 <.plt+0x12> | |
| 18 | // CHECK-NEXT: 1029: cc int3 | |
| 19 | // CHECK-NEXT: 102a: cc int3 | |
| 20 | // CHECK-NEXT: 102b: cc int3 | |
| 21 | // CHECK-NEXT: 102c: cc int3 | |
| 22 | // CHECK-NEXT: 102d: cc int3 | |
| 23 | // CHECK-NEXT: 102e: cc int3 | |
| 24 | // CHECK-NEXT: 102f: cc int3 | |
| 25 | // CHECK-NEXT: 1030: 89 0c 24 movl %ecx, (%esp) | |
| 26 | // CHECK-NEXT: 1033: 8b 4c 24 04 movl 4(%esp), %ecx | |
| 27 | // CHECK-NEXT: 1037: 89 44 24 04 movl %eax, 4(%esp) | |
| 28 | // CHECK-NEXT: 103b: 89 c8 movl %ecx, %eax | |
| 29 | // CHECK-NEXT: 103d: 59 popl %ecx | |
| 30 | // CHECK-NEXT: 103e: c3 retl | |
| 31 | // CHECK-NEXT: 103f: cc int3 | |
| 32 | // CHECK-NEXT: 1040: 50 pushl %eax | |
| 33 | // CHECK-NEXT: 1041: 8b 83 0c 20 00 00 movl 8204(%ebx), %eax | |
| 34 | // CHECK-NEXT: 1047: e8 e4 ff ff ff calll -28 <.plt+0x20> | |
| 35 | // CHECK-NEXT: 104c: e9 d1 ff ff ff jmp -47 <.plt+0x12> | |
| 36 | // CHECK-NEXT: 1051: 68 00 00 00 00 pushl $0 | |
| 37 | // CHECK-NEXT: 1056: e9 b5 ff ff ff jmp -75 <.plt> | |
| 38 | // CHECK-NEXT: 105b: cc int3 | |
| 39 | // CHECK-NEXT: 105c: cc int3 | |
| 40 | // CHECK-NEXT: 105d: cc int3 | |
| 41 | // CHECK-NEXT: 105e: cc int3 | |
| 42 | // CHECK-NEXT: 105f: cc int3 | |
| 43 | // CHECK-NEXT: 1060: 50 pushl %eax | |
| 44 | // CHECK-NEXT: 1061: 8b 83 10 20 00 00 movl 8208(%ebx), %eax | |
| 45 | // CHECK-NEXT: 1067: e8 c4 ff ff ff calll -60 <.plt+0x20> | |
| 46 | // CHECK-NEXT: 106c: e9 b1 ff ff ff jmp -79 <.plt+0x12> | |
| 47 | // CHECK-NEXT: 1071: 68 08 00 00 00 pushl $8 | |
| 48 | // CHECK-NEXT: 1076: e9 95 ff ff ff jmp -107 <.plt> | |
| 49 | // CHECK-NEXT: 107b: cc int3 | |
| 50 | // CHECK-NEXT: 107c: cc int3 | |
| 51 | // CHECK-NEXT: 107d: cc int3 | |
| 52 | // CHECK-NEXT: 107e: cc int3 | |
| 53 | // CHECK-NEXT: 107f: cc int3 | |
| 54 | ||
| 55 | // CHECK: Contents of section .got.plt: | |
| 56 | // CHECK-NEXT: 2000 00300000 00000000 00000000 51100000 | |
| 57 | // CHECK-NEXT: 2010 71100000 | |
| 58 | ||
| 59 | .global _start | |
| 60 | _start: | |
| 61 | jmp bar@PLT | |
| 62 | jmp zed@PLT |
deps/lld/test/ELF/i386-tls-ie-shared.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o %tso.o |
| 3 | 3 | // RUN: ld.lld -shared %tso.o -o %tso |
| 4 | // RUN: ld.lld -shared %t.o %tso -o %t1 | |
| 4 | // RUN: ld.lld --hash-style=sysv -shared %t.o %tso -o %t1 | |
| 5 | 5 | // RUN: llvm-readobj -s -r -d %t1 | FileCheck --check-prefix=GOTRELSHARED %s |
| 6 | 6 | // RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASMSHARED %s |
| 7 | 7 |
deps/lld/test/ELF/i386-tls-initial-exec-local.s created+36| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc %s -o %t.o -filetype=obj -triple=i386-pc-linux | |
| 3 | # RUN: ld.lld %t.o -o %t.so -shared | |
| 4 | # RUN: llvm-readobj --relocations --sections --section-data %t.so | FileCheck %s | |
| 5 | ||
| 6 | # Check initial exec access to a local symbol. | |
| 7 | ||
| 8 | # CHECK: Name: .got ( | |
| 9 | # CHECK-NEXT: Type: | |
| 10 | # CHECK-NEXT: Flags [ | |
| 11 | # CHECK-NEXT: SHF_ALLOC | |
| 12 | # CHECK-NEXT: SHF_WRITE | |
| 13 | # CHECK-NEXT: ] | |
| 14 | # CHECK-NEXT: Address: | |
| 15 | # CHECK-NEXT: Offset: | |
| 16 | # CHECK-NEXT: Size: 8 | |
| 17 | # CHECK-NEXT: Link: | |
| 18 | # CHECK-NEXT: Info: | |
| 19 | # CHECK-NEXT: AddressAlignment: | |
| 20 | # CHECK-NEXT: EntrySize: | |
| 21 | # CHECK-NEXT: SectionData ( | |
| 22 | # CHECK-NEXT: 0000: 00000000 04000000 | |
| 23 | # CHECK-NEXT: ) | |
| 24 | ||
| 25 | # CHECK: R_386_TLS_TPOFF - 0x0 | |
| 26 | # CHECK-NEXT: R_386_TLS_TPOFF - 0x0 | |
| 27 | ||
| 28 | 	movl	bar1@GOTNTPOFF(%eax), %ecx | |
| 29 | 	movl	bar2@GOTNTPOFF(%eax), %eax | |
| 30 | ||
| 31 | 	.section	.tdata,"awT",@progbits | |
| 32 | bar1: | |
| 33 | 	.long	42 | |
| 34 | ||
| 35 | bar2: | |
| 36 | 	.long	42 |
deps/lld/test/ELF/icf-absolute.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | 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 | FileCheck %s | |
| 5 | # RUN: ld.lld %t %t2 -o %t3 --icf=all --verbose 2>&1 | FileCheck %s | |
| 6 | 6 | |
| 7 | 7 | # CHECK: selected .text.f1 |
| 8 | 8 | # CHECK: removed .text.f2 |
deps/lld/test/ELF/icf-comdat.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s | |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | |
| 5 | 5 | |
| 6 | 6 | # CHECK: selected .text.f1 |
| 7 | 7 | # CHECK: removed .text.f2 |
deps/lld/test/ELF/icf-i386.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | # This test is to make sure that we can handle implicit addends properly. |
| 3 | 3 | |
| 4 | 4 | # RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %s -o %t |
| 5 | # RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s | |
| 5 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | |
| 6 | 6 | |
| 7 | 7 | # CHECK: selected .text.f1 |
| 8 | 8 | # CHECK: removed .text.f2 |
deps/lld/test/ELF/icf-merge-sec.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | 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 | FileCheck %s | |
| 5 | # RUN: ld.lld %t %t2 -o %t3 --icf=all --verbose 2>&1 | FileCheck %s | |
| 6 | 6 | |
| 7 | 7 | # CHECK: selected .text.f1 |
| 8 | 8 | # CHECK: removed .text.f2 |
deps/lld/test/ELF/icf-merge.s+3-3| ... | ... | @@ -2,13 +2,13 @@ |
| 2 | 2 | |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | 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 | FileCheck %s | |
| 5 | # RUN: ld.lld %t %t1 -o %t1.out --icf=all --verbose 2>&1 | FileCheck %s | |
| 6 | 6 | |
| 7 | 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 | FileCheck --check-prefix=NOMERGE %s | |
| 8 | # RUN: ld.lld %t %t2 -o %t3.out --icf=all --verbose 2>&1 | FileCheck --check-prefix=NOMERGE %s | |
| 9 | 9 | |
| 10 | 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 | FileCheck --check-prefix=NOMERGE %s | |
| 11 | # RUN: ld.lld %t %t3 -o %t3.out --icf=all --verbose 2>&1 | FileCheck --check-prefix=NOMERGE %s | |
| 12 | 12 | |
| 13 | 13 | # CHECK: selected .text.f1 |
| 14 | 14 | # CHECK: removed .text.f2 |
deps/lld/test/ELF/icf-non-mergeable.s+2-2| ... | ... | @@ -1,14 +1,14 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | |
| 3 | 3 | // This file contains two functions. They are themselves identical, |
| 4 | // but because they have reloactions against different data section, | |
| 4 | // but because they have relocations against different data sections, | |
| 5 | 5 | // they are not mergeable. |
| 6 | 6 | |
| 7 | 7 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 |
| 8 | 8 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ |
| 9 | 9 | // RUN: %p/Inputs/icf-non-mergeable.s -o %t2 |
| 10 | 10 | |
| 11 | // RUN: ld.lld %t1 %t2 -o %t3 --icf=all --verbose | FileCheck %s | |
| 11 | // RUN: ld.lld %t1 %t2 -o %t3 --icf=all --verbose 2>&1 | FileCheck %s | |
| 12 | 12 | |
| 13 | 13 | // CHECK-NOT: selected .text.f1 |
| 14 | 14 | // CHECK-NOT: removed .text.f2 |
deps/lld/test/ELF/icf-none.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | |
| 3 | 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 | FileCheck %s | |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --icf=none --verbose 2>&1 | FileCheck %s | |
| 5 | 5 | |
| 6 | 6 | # CHECK-NOT: selected .text.f1 |
| 7 | 7 |
deps/lld/test/ELF/icf-symbol-type.s created+26| ... | ... | @@ -0,0 +1,26 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 4 | # RUN: ld.lld --hash-style=sysv %t.o -o %t --icf=all -shared | |
| 5 | # RUN: llvm-readelf --dyn-symbols --sections %t | FileCheck %s | |
| 6 | ||
| 7 | # We used to mark bar as absolute. | |
| 8 | ||
| 9 | # CHECK: .text PROGBITS 0000000000001000 | |
| 10 | # CHECK: 0000000000001001 0 NOTYPE GLOBAL DEFAULT 4 foo | |
| 11 | # CHECK: 0000000000001001 0 NOTYPE GLOBAL DEFAULT 4 bar | |
| 12 | ||
| 13 | # The nop makes the test more interesting by making the offset of | |
| 14 | # text.f non zero. | |
| 15 | ||
| 16 | nop | |
| 17 | ||
| 18 | .section .text.f,"ax",@progbits | |
| 19 | .globl foo | |
| 20 | foo: | |
| 21 | retq | |
| 22 | ||
| 23 | .section .text.g,"ax",@progbits | |
| 24 | .globl bar | |
| 25 | bar: | |
| 26 | retq |
deps/lld/test/ELF/icf1.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s | |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | |
| 5 | 5 | |
| 6 | 6 | # CHECK: selected .text.f1 |
| 7 | 7 | # CHECK: removed .text.f2 |
deps/lld/test/ELF/icf2.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 |
| 4 | 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 | FileCheck %s | |
| 5 | # RUN: ld.lld %t1 %t2 -o %t --icf=all --verbose 2>&1 | FileCheck %s | |
| 6 | 6 | |
| 7 | 7 | # CHECK: selected .text.f1 |
| 8 | 8 | # CHECK: removed .text.f2 |
deps/lld/test/ELF/icf3.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 |
| 4 | 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 | FileCheck %s | |
| 5 | # RUN: ld.lld %t1 %t2 -o %t --icf=all --verbose 2>&1 | FileCheck %s | |
| 6 | 6 | |
| 7 | 7 | # CHECK-NOT: Selected .text.f1 |
| 8 | 8 | # CHECK-NOT: Selected .text.f2 |
deps/lld/test/ELF/icf4.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s | |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | |
| 5 | 5 | |
| 6 | 6 | # CHECK-NOT: Selected .text.f1 |
| 7 | 7 | # CHECK-NOT: Selected .text.f2 |
deps/lld/test/ELF/icf5.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s | |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | |
| 5 | 5 | |
| 6 | 6 | # CHECK-NOT: Selected .text.f1 |
| 7 | 7 | # CHECK-NOT: Selected .text.f2 |
deps/lld/test/ELF/icf6.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s | |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | |
| 5 | 5 | |
| 6 | 6 | # CHECK-NOT: Selected .text.f1 |
| 7 | 7 | # CHECK-NOT: Selected .text.f2 |
deps/lld/test/ELF/icf7.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s | |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | |
| 5 | 5 | # RUN: llvm-objdump -t %t2 | FileCheck -check-prefix=ALIGN %s |
| 6 | 6 | |
| 7 | 7 | # CHECK: selected .text.f1 |
deps/lld/test/ELF/icf9.s+17-5| ... | ... | @@ -2,19 +2,31 @@ |
| 2 | 2 | |
| 3 | 3 | ### Make sure that we do not merge data. |
| 4 | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 5 | # RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s | |
| 5 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | |
| 6 | # RUN: llvm-readelf -S -W %t2 | FileCheck --check-prefix=SEC %s | |
| 6 | 7 | |
| 7 | # CHECK-NOT: selected .data.d1 | |
| 8 | # CHECK-NOT: selected .data.d2 | |
| 8 | # SEC: .rodata PROGBITS 0000000000200120 000120 000002 00 A 0 0 1 | |
| 9 | ||
| 10 | # CHECK-NOT: selected .rodata.d1 | |
| 11 | # CHECK-NOT: selected .rodata.d2 | |
| 12 | ||
| 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 | |
| 15 | # RUN: llvm-readelf -S -W %t2 | FileCheck --check-prefix=DATA-SEC %s | |
| 16 | ||
| 17 | # DATA: selected .rodata.d1 | |
| 18 | # DATA: removed .rodata.d2 | |
| 19 | ||
| 20 | # DATA-SEC: .rodata PROGBITS 0000000000200120 000120 000001 00 A 0 0 1 | |
| 9 | 21 | |
| 10 | 22 | .globl _start, d1, d2 |
| 11 | 23 | _start: |
| 12 | 24 | ret |
| 13 | 25 | |
| 14 | .section .data.f1, "a" | |
| 26 | .section .rodata.d1, "a" | |
| 15 | 27 | d1: |
| 16 | 28 | .byte 1 |
| 17 | 29 | |
| 18 | .section .data.f2, "a" | |
| 30 | .section .rodata.d2, "a" | |
| 19 | 31 | d2: |
| 20 | 32 | .byte 1 |
deps/lld/test/ELF/image-base.s+5-2| ... | ... | @@ -6,6 +6,9 @@ |
| 6 | 6 | # RUN: ld.lld -image-base=0x1000 -z max-page-size=0x2000 %t -o %t1 2>&1 | FileCheck --check-prefix=WARN %s |
| 7 | 7 | # WARN: warning: -image-base: address isn't multiple of page size: 0x1000 |
| 8 | 8 | |
| 9 | # Check alias. | |
| 10 | # RUN: ld.lld -image-base 0x1000000 %t -o %t1 | |
| 11 | # RUN: llvm-readobj -program-headers %t1 | FileCheck %s | |
| 9 | 12 | |
| 10 | 13 | .global _start |
| 11 | 14 | _start: |
| ... | ... | @@ -41,8 +44,8 @@ _start: |
| 41 | 44 | # CHECK-NEXT: Offset: 0x1000 |
| 42 | 45 | # CHECK-NEXT: VirtualAddress: 0x1001000 |
| 43 | 46 | # CHECK-NEXT: PhysicalAddress: 0x1001000 |
| 44 | # CHECK-NEXT: FileSize: 1 | |
| 45 | # CHECK-NEXT: MemSize: 1 | |
| 47 | # CHECK-NEXT: FileSize: 4096 | |
| 48 | # CHECK-NEXT: MemSize: 4096 | |
| 46 | 49 | # CHECK-NEXT: Flags [ (0x5) |
| 47 | 50 | # CHECK-NEXT: PF_R (0x4) |
| 48 | 51 | # CHECK-NEXT: PF_X (0x1) |
deps/lld/test/ELF/init_fini_priority.s+18-6| ... | ... | @@ -1,34 +1,46 @@ |
| 1 | 1 | // 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 | |
| 2 | 3 | // RUN: ld.lld %t -o %t.exe |
| 3 | 4 | // RUN: llvm-objdump -s %t.exe | FileCheck %s |
| 4 | 5 | // REQUIRES: x86 |
| 5 | 6 | |
| 7 | // OBJ: 3 .init_array | |
| 8 | // OBJ-NEXT: 4 .init_array.100 | |
| 9 | // OBJ-NEXT: 5 .init_array.5 | |
| 10 | // OBJ-NEXT: 6 .init_array | |
| 11 | // OBJ-NEXT: 7 .init_array | |
| 12 | // OBJ-NEXT: 8 .fini_array | |
| 13 | // OBJ-NEXT: 9 .fini_array.100 | |
| 14 | // OBJ-NEXT: 10 .fini_array.5 | |
| 15 | // OBJ-NEXT: 11 .fini_array | |
| 16 | // OBJ-NEXT: 12 .fini_array | |
| 17 | ||
| 6 | 18 | .globl _start |
| 7 | 19 | _start: |
| 8 | 20 | nop |
| 9 | 21 | |
| 10 | .section .init_array, "aw", @init_array | |
| 22 | .section .init_array, "aw", @init_array, unique, 0 | |
| 11 | 23 | .align 8 |
| 12 | 24 | .byte 1 |
| 13 | 25 | .section .init_array.100, "aw", @init_array |
| 14 | 26 | .long 2 |
| 15 | 27 | .section .init_array.5, "aw", @init_array |
| 16 | 28 | .byte 3 |
| 17 | .section .init_array, "aw", @init_array | |
| 29 | .section .init_array, "aw", @init_array, unique, 1 | |
| 18 | 30 | .byte 4 |
| 19 | .section .init_array, "aw", @init_array | |
| 31 | .section .init_array, "aw", @init_array, unique, 2 | |
| 20 | 32 | .byte 5 |
| 21 | 33 | |
| 22 | .section .fini_array, "aw", @fini_array | |
| 34 | .section .fini_array, "aw", @fini_array, unique, 0 | |
| 23 | 35 | .align 8 |
| 24 | 36 | .byte 0x11 |
| 25 | 37 | .section .fini_array.100, "aw", @fini_array |
| 26 | 38 | .long 0x12 |
| 27 | 39 | .section .fini_array.5, "aw", @fini_array |
| 28 | 40 | .byte 0x13 |
| 29 | .section .fini_array, "aw", @fini_array | |
| 41 | .section .fini_array, "aw", @fini_array, unique, 1 | |
| 30 | 42 | .byte 0x14 |
| 31 | .section .fini_array, "aw", @fini_array | |
| 43 | .section .fini_array, "aw", @fini_array, unique, 2 | |
| 32 | 44 | .byte 0x15 |
| 33 | 45 | |
| 34 | 46 | // CHECK: Contents of section .init_array: |
deps/lld/test/ELF/invalid-linkerscript.test+1-1| ... | ... | @@ -45,7 +45,7 @@ |
| 45 | 45 | |
| 46 | 46 | # RUN: echo "INCLUDE /no/such/file" > %t7 |
| 47 | 47 | # RUN: not ld.lld %t7 no-such-file 2>&1 | FileCheck -check-prefix=ERR7 %s |
| 48 | # ERR7: cannot open /no/such/file | |
| 48 | # ERR7: cannot find linker script /no/such/file | |
| 49 | 49 | # ERR7: cannot open no-such-file: |
| 50 | 50 | |
| 51 | 51 | # RUN: echo "OUTPUT_FORMAT(x y z)" > %t8 |
deps/lld/test/ELF/invalid-local-symbol-in-dso.s created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # We used to crash on this | |
| 4 | # RUN: ld.lld %p/Inputs/local-symbol-in-dso.so -o %t 2>&1 | \ | |
| 5 | # RUN: FileCheck -check-prefix=WARN %s | |
| 6 | # WARN: found local symbol 'foo' in global part of symbol table in file {{.*}}local-symbol-in-dso.so | |
| 7 | ||
| 8 | # RUN: llvm-mc %s -o %t.o -filetype=obj -triple x86_64-pc-linux | |
| 9 | # RUN: not ld.lld %t.o %p/Inputs/local-symbol-in-dso.so -o %t | |
| 10 | ||
| 11 | .globl main | |
| 12 | main: | |
| 13 | movq foo@GOTTPOFF(%rip), %rax |
deps/lld/test/ELF/invalid-undef-section-symbol.test created+27| ... | ... | @@ -0,0 +1,27 @@ |
| 1 | # RUN: yaml2obj %s -o %t.o | |
| 2 | # RUN: not ld.lld -r %t.o -o %2.o 2>&1 | FileCheck %s | |
| 3 | ||
| 4 | # We used to crash at this. | |
| 5 | # CHECK: STT_SECTION symbol should be defined | |
| 6 | ||
| 7 | --- !ELF | |
| 8 | FileHeader: | |
| 9 | Class: ELFCLASS64 | |
| 10 | Data: ELFDATA2LSB | |
| 11 | Type: ET_REL | |
| 12 | Machine: EM_X86_64 | |
| 13 | Sections: | |
| 14 | - Name: .text | |
| 15 | Type: SHT_PROGBITS | |
| 16 | - Name: .rela.text | |
| 17 | Type: SHT_RELA | |
| 18 | AddressAlign: 0x0000000000000008 | |
| 19 | Info: .text | |
| 20 | Relocations: | |
| 21 | - Offset: 0x0000000000000000 | |
| 22 | Symbol: .text | |
| 23 | Type: R_X86_64_NONE | |
| 24 | Symbols: | |
| 25 | Local: | |
| 26 | - Name: .text | |
| 27 | Type: STT_SECTION |
deps/lld/test/ELF/invalid/Inputs/section-index2.elf deleted| Binary files a/deps/lld/test/ELF/invalid/Inputs/section-index2.elf and /dev/null differ |
deps/lld/test/ELF/invalid/invalid-debug-relocations.test+1-2| ... | ... | @@ -2,8 +2,7 @@ |
| 2 | 2 | # RUN: yaml2obj %s -o %t.o |
| 3 | 3 | # RUN: not ld.lld -gdb-index %t.o -o %t.exe 2>&1 | FileCheck %s |
| 4 | 4 | |
| 5 | # CHECK: error: {{.*}}.o: error parsing DWARF data: | |
| 6 | # CHECK-NEXT: >>> failed to compute relocation: Unknown, Invalid data was encountered while parsing the file | |
| 5 | # CHECK: error: {{.*}}invalid-debug-relocations.test.tmp.o:(.debug_info+0x0): has non-ABS relocation Unknown (255) against symbol '_start' | |
| 7 | 6 | |
| 8 | 7 | !ELF |
| 9 | 8 | FileHeader: |
deps/lld/test/ELF/invalid/invalid-elf.test-4| ... | ... | @@ -20,10 +20,6 @@ |
| 20 | 20 | # RUN: FileCheck --check-prefix=INVALID-SECTION-INDEX-LLD %s |
| 21 | 21 | # INVALID-SECTION-INDEX-LLD: invalid section index |
| 22 | 22 | |
| 23 | ## section-index2.elf has local symbol with incorrect section index. | |
| 24 | # RUN: not ld.lld %p/Inputs/section-index2.elf -o %t2 2>&1 | \ | |
| 25 | # RUN: FileCheck --check-prefix=INVALID-SECTION-INDEX-LLD %s | |
| 26 | ||
| 27 | 23 | # RUN: not ld.lld %p/Inputs/multiple-eh-relocs.elf -o %t2 2>&1 | \ |
| 28 | 24 | # RUN: FileCheck --check-prefix=INVALID-EH-RELOCS %s |
| 29 | 25 | # INVALID-EH-RELOCS: multiple relocation sections to one section are not supported |
deps/lld/test/ELF/invalid/invalid-relocation-x64.test+12-6| ... | ... | @@ -1,7 +1,10 @@ |
| 1 | # RUN: yaml2obj %s -o %t.o | |
| 2 | # RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s | |
| 3 | # CHECK: {{.*}}.o: unknown relocation type: Unknown (152) | |
| 4 | # CHECK: {{.*}}.o: unknown relocation type: Unknown (153) | |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: yaml2obj %s -o %t1.o | |
| 3 | # RUN: echo ".global foo; foo:" > %t2.s | |
| 4 | # RUN: llvm-mc %t2.s -o %t2.o -filetype=obj -triple x86_64-pc-linux | |
| 5 | # RUN: not ld.lld %t1.o %t2.o -o /dev/null 2>&1 | FileCheck %s | |
| 6 | # CHECK: error: unrecognized reloc 152 | |
| 7 | # CHECK: error: unrecognized reloc 153 | |
| 5 | 8 | |
| 6 | 9 | !ELF |
| 7 | 10 | FileHeader: |
| ... | ... | @@ -20,8 +23,11 @@ Sections: |
| 20 | 23 | Info: .text |
| 21 | 24 | Relocations: |
| 22 | 25 | - Offset: 0x0000000000000000 |
| 23 | Symbol: '' | |
| 26 | Symbol: foo | |
| 24 | 27 | Type: 0x98 |
| 25 | 28 | - Offset: 0x0000000000000000 |
| 26 | Symbol: '' | |
| 29 | Symbol: foo | |
| 27 | 30 | Type: 0x99 |
| 31 | Symbols: | |
| 32 | Global: | |
| 33 | - Name: foo |
deps/lld/test/ELF/libsearch.s+1| ... | ... | @@ -60,6 +60,7 @@ |
| 60 | 60 | |
| 61 | 61 | // Check long forms as well |
| 62 | 62 | // RUN: ld.lld -o %t3 %t.o --library-path=%t.dir --library=ls |
| 63 | // RUN: ld.lld -o %t3 %t.o --library-path %t.dir --library ls | |
| 63 | 64 | |
| 64 | 65 | // Should not search for dynamic libraries if -Bstatic is specified |
| 65 | 66 | // RUN: ld.lld -o %t3 %t.o -L%t.dir -Bstatic -lls |
deps/lld/test/ELF/linkerscript/Inputs/common-filespec1.s created+2| ... | ... | @@ -0,0 +1,2 @@ |
| 1 | .comm common_uniq_1,8,8 | |
| 2 | .comm common_multiple,16,8 |
deps/lld/test/ELF/linkerscript/Inputs/common-filespec2.s created+2| ... | ... | @@ -0,0 +1,2 @@ |
| 1 | .comm common_uniq_2,16,16 | |
| 2 | .comm common_multiple,32,8 |
deps/lld/test/ELF/linkerscript/Inputs/copy-rel-symbol-value.s created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | .global bar | |
| 2 | .type bar, @object | |
| 3 | .size bar, 8 | |
| 4 | bar: | |
| 5 | .quad 0 |
deps/lld/test/ELF/linkerscript/Inputs/provide-shared.s created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | .global foo | |
| 2 | .size foo, 8 | |
| 3 | .type foo, @object | |
| 4 | foo: | |
| 5 | .quad 42 |
deps/lld/test/ELF/linkerscript/Inputs/symbol-reserved.script created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | SECTIONS | |
| 2 | { | |
| 3 | .text : { *(.text) } | |
| 4 | PROVIDE_HIDDEN(_end = .); | |
| 5 | } |
deps/lld/test/ELF/linkerscript/absolute2.s created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | |
| 3 | ||
| 4 | # RUN: echo "SECTIONS { .text : { *(.text) } foo = ABSOLUTE(_start) + _start; };" > %t.script | |
| 5 | # RUN: ld.lld -o %t --script %t.script %t.o | |
| 6 | # RUN: llvm-objdump -t %t | FileCheck %s | |
| 7 | ||
| 8 | # RUN: echo "SECTIONS { .text : { *(.text) } foo = _start + ABSOLUTE(_start); };" > %t.script | |
| 9 | # RUN: ld.lld -o %t --script %t.script %t.o | |
| 10 | # RUN: llvm-objdump -t %t | FileCheck %s | |
| 11 | ||
| 12 | # CHECK: 0000000000000001 .text 00000000 _start | |
| 13 | # CHECK: 0000000000000002 .text 00000000 foo | |
| 14 | ||
| 15 | .global _start | |
| 16 | nop | |
| 17 | _start: |
deps/lld/test/ELF/linkerscript/align-section-offset.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 "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.s created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 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.s+45| ... | ... | @@ -66,6 +66,51 @@ |
| 66 | 66 | # SYMBOLS-NEXT: 0000000000011000 .bbb 00000000 __start_bbb |
| 67 | 67 | # SYMBOLS-NEXT: 0000000000012000 .bbb 00000000 __end_bbb |
| 68 | 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 | ||
| 69 | 114 | .global _start |
| 70 | 115 | _start: |
| 71 | 116 | nop |
deps/lld/test/ELF/linkerscript/arm-exidx-order.s created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 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-sentinel-and-assignment.s created+41| ... | ... | @@ -0,0 +1,41 @@ |
| 1 | # REQUIRES: arm | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | |
| 3 | # RUN: echo "SECTIONS { \ | |
| 4 | # RUN: .ARM.exidx 0x1000 : { *(.ARM.exidx*) foo = .; } \ | |
| 5 | # RUN: .text 0x2000 : { *(.text*) } \ | |
| 6 | # RUN: }" > %t.script | |
| 7 | ## We used to crash if the last output section command for .ARM.exidx | |
| 8 | ## was anything but an input section description. | |
| 9 | # RUN: ld.lld --no-merge-exidx-entries -T %t.script %t.o -shared -o %t.so | |
| 10 | # RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t.so | FileCheck %s | |
| 11 | # RUN: llvm-readobj -s -t %t.so | FileCheck %s --check-prefix=SYMBOL | |
| 12 | ||
| 13 | .syntax unified | |
| 14 | .text | |
| 15 | .global _start | |
| 16 | _start: | |
| 17 | .fnstart | |
| 18 | .cantunwind | |
| 19 | bx lr | |
| 20 | .fnend | |
| 21 | ||
| 22 | # CHECK: Contents of section .ARM.exidx: | |
| 23 | # 1000 + 1000 = 0x2000 = _start | |
| 24 | # 1008 + 0ffc = 0x2004 = _start + sizeof(_start) | |
| 25 | # CHECK-NEXT: 1000 00100000 01000000 fc0f0000 01000000 | |
| 26 | ||
| 27 | # SYMBOL: Section { | |
| 28 | # SYMBOL: Name: .ARM.exidx | |
| 29 | # SYMBOL-NEXT: Type: SHT_ARM_EXIDX | |
| 30 | # SYMBOL-NEXT: Flags [ | |
| 31 | # SYMBOL-NEXT: SHF_ALLOC | |
| 32 | # SYMBOL-NEXT: SHF_LINK_ORDER | |
| 33 | # SYMBOL-NEXT: ] | |
| 34 | # SYMBOL-NEXT: Address: 0x1000 | |
| 35 | # SYMBOL-NEXT: Offset: | |
| 36 | # SYMBOL-NEXT: Size: 16 | |
| 37 | ||
| 38 | # Symbol 'foo' is expected to point at the end of the section. | |
| 39 | # SYMBOL: Symbol { | |
| 40 | # SYMBOL: Name: foo | |
| 41 | # SYMBOL-NEXT: Value: 0x1010 |
deps/lld/test/ELF/linkerscript/at-addr.s-4| ... | ... | @@ -8,10 +8,6 @@ |
| 8 | 8 | # RUN: ld.lld %t --script %t.script -o %t2 |
| 9 | 9 | # RUN: llvm-readobj -program-headers %t2 | FileCheck %s |
| 10 | 10 | |
| 11 | # CHECK: Type: PT_LOAD | |
| 12 | # CHECK-NEXT: Offset: 0x0 | |
| 13 | # CHECK-NEXT: VirtualAddress: 0x0 | |
| 14 | # CHECK-NEXT: PhysicalAddress: 0x0 | |
| 15 | 11 | # CHECK: Type: PT_LOAD |
| 16 | 12 | # CHECK-NEXT: Offset: 0x1000 |
| 17 | 13 | # CHECK-NEXT: VirtualAddress: 0x1000 |
deps/lld/test/ELF/linkerscript/at-self-reference.s created+63| ... | ... | @@ -0,0 +1,63 @@ |
| 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 : AT(ADDR(.aaa)) { *(.aaa) } \ | |
| 6 | # RUN: .bbb : AT(ADDR(.bbb)) { *(.bbb) } \ | |
| 7 | # RUN: }" > %t.script | |
| 8 | # RUN: ld.lld %t --script %t.script -o %t2 | |
| 9 | # RUN: llvm-readobj -program-headers %t2 | FileCheck %s | |
| 10 | ||
| 11 | # CHECK: ProgramHeaders [ | |
| 12 | # CHECK-NEXT: ProgramHeader { | |
| 13 | # CHECK-NEXT: Type: PT_LOAD (0x1) | |
| 14 | # CHECK-NEXT: Offset: 0x1000 | |
| 15 | # CHECK-NEXT: VirtualAddress: 0x1000 | |
| 16 | # CHECK-NEXT: PhysicalAddress: 0x1000 | |
| 17 | # CHECK-NEXT: FileSize: 3 | |
| 18 | # CHECK-NEXT: MemSize: 3 | |
| 19 | # CHECK-NEXT: Flags [ (0x5) | |
| 20 | # CHECK-NEXT: PF_R (0x4) | |
| 21 | # CHECK-NEXT: PF_X (0x1) | |
| 22 | # CHECK-NEXT: ] | |
| 23 | # CHECK-NEXT: Alignment: 4096 | |
| 24 | # CHECK-NEXT: } | |
| 25 | # CHECK-NEXT: ProgramHeader { | |
| 26 | # CHECK-NEXT: Type: PT_LOAD (0x1) | |
| 27 | # CHECK-NEXT: Offset: 0x1008 | |
| 28 | # CHECK-NEXT: VirtualAddress: 0x1008 | |
| 29 | # CHECK-NEXT: PhysicalAddress: 0x1008 | |
| 30 | # CHECK-NEXT: FileSize: 9 | |
| 31 | # CHECK-NEXT: MemSize: 9 | |
| 32 | # CHECK-NEXT: Flags [ (0x5) | |
| 33 | # CHECK-NEXT: PF_R (0x4) | |
| 34 | # CHECK-NEXT: PF_X (0x1) | |
| 35 | # CHECK-NEXT: ] | |
| 36 | # CHECK-NEXT: Alignment: 4096 | |
| 37 | # CHECK-NEXT: } | |
| 38 | # CHECK-NEXT: ProgramHeader { | |
| 39 | # CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551) | |
| 40 | # CHECK-NEXT: Offset: 0x0 | |
| 41 | # CHECK-NEXT: VirtualAddress: 0x0 | |
| 42 | # CHECK-NEXT: PhysicalAddress: 0x0 | |
| 43 | # CHECK-NEXT: FileSize: 0 | |
| 44 | # CHECK-NEXT: MemSize: 0 | |
| 45 | # CHECK-NEXT: Flags [ (0x6) | |
| 46 | # CHECK-NEXT: PF_R (0x4) | |
| 47 | # CHECK-NEXT: PF_W (0x2) | |
| 48 | # CHECK-NEXT: ] | |
| 49 | # CHECK-NEXT: Alignment: 0 | |
| 50 | # CHECK-NEXT: } | |
| 51 | # CHECK-NEXT:] | |
| 52 | ||
| 53 | .global _start | |
| 54 | _start: | |
| 55 | nop | |
| 56 | ||
| 57 | ||
| 58 | .section .aaa, "a" | |
| 59 | .asciz "aa" | |
| 60 | ||
| 61 | .section .bbb, "a" | |
| 62 | .align 8 | |
| 63 | .quad 0 |
deps/lld/test/ELF/linkerscript/at.s-25| ... | ... | @@ -13,31 +13,6 @@ |
| 13 | 13 | |
| 14 | 14 | # CHECK: ProgramHeaders [ |
| 15 | 15 | # CHECK-NEXT: ProgramHeader { |
| 16 | # CHECK-NEXT: Type: PT_PHDR | |
| 17 | # CHECK-NEXT: Offset: 0x40 | |
| 18 | # CHECK-NEXT: VirtualAddress: 0x40 | |
| 19 | # CHECK-NEXT: PhysicalAddress: 0x40 | |
| 20 | # CHECK-NEXT: FileSize: | |
| 21 | # CHECK-NEXT: MemSize: | |
| 22 | # CHECK-NEXT: Flags [ | |
| 23 | # CHECK-NEXT: PF_R | |
| 24 | # CHECK-NEXT: ] | |
| 25 | # CHECK-NEXT: Alignment: 8 | |
| 26 | # CHECK-NEXT: } | |
| 27 | # CHECK-NEXT: ProgramHeader { | |
| 28 | # CHECK-NEXT: Type: PT_LOAD | |
| 29 | # CHECK-NEXT: Offset: 0x0 | |
| 30 | # CHECK-NEXT: VirtualAddress: 0x0 | |
| 31 | # CHECK-NEXT: PhysicalAddress: 0x0 | |
| 32 | # CHECK-NEXT: FileSize: | |
| 33 | # CHECK-NEXT: MemSize: | |
| 34 | # CHECK-NEXT: Flags [ | |
| 35 | # CHECK-NEXT: PF_R | |
| 36 | # CHECK-NEXT: PF_X | |
| 37 | # CHECK-NEXT: ] | |
| 38 | # CHECK-NEXT: Alignment: | |
| 39 | # CHECK-NEXT: } | |
| 40 | # CHECK-NEXT: ProgramHeader { | |
| 41 | 16 | # CHECK-NEXT: Type: PT_LOAD |
| 42 | 17 | # CHECK-NEXT: Offset: 0x1000 |
| 43 | 18 | # CHECK-NEXT: VirtualAddress: 0x1000 |
deps/lld/test/ELF/linkerscript/at2.s created+81| ... | ... | @@ -0,0 +1,81 @@ |
| 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/at3.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: 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/common-exclude.s created+86| ... | ... | @@ -0,0 +1,86 @@ |
| 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.incl : { *(EXCLUDE_FILE (*file2.o) COMMON) } .common.excl : { *(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 | # Commons from file0 and file1 are not excluded, so they must be in .common.incl | |
| 10 | # Commons from file2 are excluded from the first rule and should be caught by | |
| 11 | # the second in .common.excl | |
| 12 | # CHECK: Section { | |
| 13 | # CHECK: Index: | |
| 14 | # CHECK: Name: .common.incl | |
| 15 | # CHECK-NEXT: Type: SHT_NOBITS | |
| 16 | # CHECK-NEXT: Flags [ | |
| 17 | # CHECK-NEXT: SHF_ALLOC | |
| 18 | # CHECK-NEXT: SHF_WRITE | |
| 19 | # CHECK-NEXT: ] | |
| 20 | # CHECK-NEXT: Address: 0x8 | |
| 21 | # CHECK-NEXT: Offset: 0x | |
| 22 | # CHECK-NEXT: Size: 16 | |
| 23 | # CHECK-NEXT: Link: 0 | |
| 24 | # CHECK-NEXT: Info: 0 | |
| 25 | # CHECK-NEXT: AddressAlignment: 8 | |
| 26 | # CHECK-NEXT: EntrySize: 0 | |
| 27 | # CHECK-NEXT: } | |
| 28 | # CHECK: Section { | |
| 29 | # CHECK: Index: | |
| 30 | # CHECK: Name: .common.excl | |
| 31 | # CHECK-NEXT: Type: SHT_NOBITS | |
| 32 | # CHECK-NEXT: Flags [ | |
| 33 | # CHECK-NEXT: SHF_ALLOC | |
| 34 | # CHECK-NEXT: SHF_WRITE | |
| 35 | # CHECK-NEXT: ] | |
| 36 | # CHECK-NEXT: Address: 0x20 | |
| 37 | # CHECK-NEXT: Offset: 0x | |
| 38 | # CHECK-NEXT: Size: 48 | |
| 39 | # CHECK-NEXT: Link: 0 | |
| 40 | # CHECK-NEXT: Info: 0 | |
| 41 | # CHECK-NEXT: AddressAlignment: 16 | |
| 42 | # CHECK-NEXT: EntrySize: 0 | |
| 43 | # CHECK-NEXT: } | |
| 44 | # CHECK: Symbol { | |
| 45 | # CHECK: Name: common_multiple | |
| 46 | # CHECK-NEXT: Value: 0x20 | |
| 47 | # CHECK-NEXT: Size: 32 | |
| 48 | # CHECK-NEXT: Binding: Global | |
| 49 | # CHECK-NEXT: Type: Object | |
| 50 | # CHECK-NEXT: Other: 0 | |
| 51 | # CHECK-NEXT: Section: .common.excl | |
| 52 | # CHECK-NEXT: } | |
| 53 | # CHECK: Symbol { | |
| 54 | # CHECK: Name: common_uniq_0 | |
| 55 | # CHECK-NEXT: Value: 0x8 | |
| 56 | # CHECK-NEXT: Size: 4 | |
| 57 | # CHECK-NEXT: Binding: Global | |
| 58 | # CHECK-NEXT: Type: Object | |
| 59 | # CHECK-NEXT: Other: 0 | |
| 60 | # CHECK-NEXT: Section: .common.incl | |
| 61 | # CHECK-NEXT: } | |
| 62 | # CHECK: Symbol { | |
| 63 | # CHECK: Name: common_uniq_1 | |
| 64 | # CHECK-NEXT: Value: 0x10 | |
| 65 | # CHECK-NEXT: Size: 8 | |
| 66 | # CHECK-NEXT: Binding: Global | |
| 67 | # CHECK-NEXT: Type: Object | |
| 68 | # CHECK-NEXT: Other: 0 | |
| 69 | # CHECK-NEXT: Section: .common.incl | |
| 70 | # CHECK-NEXT: } | |
| 71 | # CHECK: Symbol { | |
| 72 | # CHECK: Name: common_uniq_2 | |
| 73 | # CHECK-NEXT: Value: 0x40 | |
| 74 | # CHECK-NEXT: Size: 16 | |
| 75 | # CHECK-NEXT: Binding: Global | |
| 76 | # CHECK-NEXT: Type: Object | |
| 77 | # CHECK-NEXT: Other: 0 | |
| 78 | # CHECK-NEXT: Section: .common.excl | |
| 79 | # CHECK-NEXT: } | |
| 80 | ||
| 81 | .globl _start | |
| 82 | _start: | |
| 83 | jmp _start | |
| 84 | ||
| 85 | .comm common_uniq_0,4,4 | |
| 86 | .comm common_multiple,8,8 |
deps/lld/test/ELF/linkerscript/common-filespec.s created+105| ... | ... | @@ -0,0 +1,105 @@ |
| 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.s+3-5| ... | ... | @@ -4,8 +4,6 @@ |
| 4 | 4 | # RUN: ld.lld -o %t1 --script %t.script %t |
| 5 | 5 | # RUN: llvm-readobj -s -t %t1 | FileCheck %s |
| 6 | 6 | |
| 7 | # q2 alignment is greater than q1, so it should have smaller offset | |
| 8 | # because of sorting | |
| 9 | 7 | # CHECK: Section { |
| 10 | 8 | # CHECK: Index: |
| 11 | 9 | # CHECK: Name: .common |
| ... | ... | @@ -16,7 +14,7 @@ |
| 16 | 14 | # CHECK-NEXT: ] |
| 17 | 15 | # CHECK-NEXT: Address: 0x200 |
| 18 | 16 | # CHECK-NEXT: Offset: 0x |
| 19 | # CHECK-NEXT: Size: 256 | |
| 17 | # CHECK-NEXT: Size: 384 | |
| 20 | 18 | # CHECK-NEXT: Link: 0 |
| 21 | 19 | # CHECK-NEXT: Info: 0 |
| 22 | 20 | # CHECK-NEXT: AddressAlignment: 256 |
| ... | ... | @@ -24,7 +22,7 @@ |
| 24 | 22 | # CHECK-NEXT: } |
| 25 | 23 | # CHECK: Symbol { |
| 26 | 24 | # CHECK: Name: q1 |
| 27 | # CHECK-NEXT: Value: 0x280 | |
| 25 | # CHECK-NEXT: Value: 0x200 | |
| 28 | 26 | # CHECK-NEXT: Size: 128 |
| 29 | 27 | # CHECK-NEXT: Binding: Global |
| 30 | 28 | # CHECK-NEXT: Type: Object |
| ... | ... | @@ -33,7 +31,7 @@ |
| 33 | 31 | # CHECK-NEXT: } |
| 34 | 32 | # CHECK-NEXT: Symbol { |
| 35 | 33 | # CHECK-NEXT: Name: q2 |
| 36 | # CHECK-NEXT: Value: 0x200 | |
| 34 | # CHECK-NEXT: Value: 0x300 | |
| 37 | 35 | # CHECK-NEXT: Size: 128 |
| 38 | 36 | # CHECK-NEXT: Binding: Global |
| 39 | 37 | # CHECK-NEXT: Type: Object |
deps/lld/test/ELF/linkerscript/compress-debug-sections-custom.s created+35| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | # REQUIRES: x86, zlib | |
| 2 | ||
| 3 | # RUN: echo "SECTIONS { \ | |
| 4 | # RUN: .text : { . += 0x10; *(.text) } \ | |
| 5 | # RUN: .debug_str : { . += 0x10; *(.debug_str) } \ | |
| 6 | # RUN: .debug_info : { . += 0x10; *(.debug_info) } \ | |
| 7 | # RUN: }" > %t.script | |
| 8 | ||
| 9 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | |
| 10 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/../Inputs/compress-debug.s -o %t2.o | |
| 11 | # RUN: ld.lld %t2.o %t.o -o %t1 --compress-debug-sections=zlib -T %t.script | |
| 12 | # RUN: llvm-dwarfdump %t1 -debug-str | FileCheck %s | |
| 13 | # These two checks correspond to the patched values of a_sym and a_debug_sym. | |
| 14 | # T = 0x54 - address of .text input section for this file (the start address of | |
| 15 | # .text is 0 by default, the size of the preceding .text in the other input | |
| 16 | #	 file is 0x44, and the linker script adds an additional 0x10). | |
| 17 | # S = 0x53 - offset of .debug_info section for this file (the size of | |
| 18 | # the preceding .debug_info from the other input file is 0x43, and the | |
| 19 | #	 linker script adds an additional 0x10). | |
| 20 | # Also note that the .debug_str offsets are also offset by 0x10, as directed by | |
| 21 | # the linker script. | |
| 22 | # CHECK: 0x00000010: "T" | |
| 23 | # CHECK: 0x00000014: "S" | |
| 24 | ||
| 25 | .text | |
| 26 | a_sym: | |
| 27 | nop | |
| 28 | ||
| 29 | .section .debug_str,"",@progbits | |
| 30 | .long a_sym | |
| 31 | .long a_debug_sym | |
| 32 | ||
| 33 | .section .debug_info,"",@progbits | |
| 34 | a_debug_sym: | |
| 35 | .long 0x88776655 |
deps/lld/test/ELF/linkerscript/compress-debug-sections.s+2-2| ... | ... | @@ -10,12 +10,12 @@ |
| 10 | 10 | |
| 11 | 11 | # RUN: echo "SECTIONS { }" > %t.script |
| 12 | 12 | # RUN: ld.lld -O0 %t1.o %t2.o %t.script -o %t1 --compress-debug-sections=zlib |
| 13 | # RUN: llvm-dwarfdump %t1 | FileCheck %s | |
| 13 | # RUN: llvm-dwarfdump -a %t1 | FileCheck %s | |
| 14 | 14 | # RUN: llvm-readobj -s %t1 | FileCheck %s --check-prefix=ZLIBFLAGS |
| 15 | 15 | |
| 16 | 16 | # RUN: echo "SECTIONS { .debug_str 0 : { *(.debug_str) } }" > %t2.script |
| 17 | 17 | # RUN: ld.lld -O0 %t1.o %t2.o %t2.script -o %t2 --compress-debug-sections=zlib |
| 18 | # RUN: llvm-dwarfdump %t2 | FileCheck %s | |
| 18 | # RUN: llvm-dwarfdump -a %t2 | FileCheck %s | |
| 19 | 19 | # RUN: llvm-readobj -s %t2 | FileCheck %s --check-prefix=ZLIBFLAGS |
| 20 | 20 | |
| 21 | 21 | # CHECK: .debug_str contents: |
deps/lld/test/ELF/linkerscript/copy-rel-symbol-value-err.s created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 3 | # RUN: 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 | |
| 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 | |
| 7 | ||
| 8 | # CHECK: symbol not found: bar | |
| 9 | ||
| 10 | .global _start | |
| 11 | _start: | |
| 12 | .quad bar@got |
deps/lld/test/ELF/linkerscript/copy-rel-symbol-value.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: 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 | |
| 5 | # RUN: echo "SECTIONS { . = . + SIZEOF_HEADERS; foo = bar; }" > %t.script | |
| 6 | # RUN: ld.lld %t.o %t2.so --script %t.script -o %t | |
| 7 | # RUN: llvm-readobj -t %t | FileCheck %s | |
| 8 | ||
| 9 | # CHECK: Name: bar | |
| 10 | # CHECK-NEXT: Value: 0x[[VAL:.*]] | |
| 11 | # CHECK-NEXT: Size: 8 | |
| 12 | # CHECK-NEXT: Binding: Global | |
| 13 | # CHECK-NEXT: Type: Object | |
| 14 | # CHECK-NEXT: Other: 0 | |
| 15 | # CHECK-NEXT: Section: .bss.rel.ro | |
| 16 | ||
| 17 | # CHECK: Name: foo | |
| 18 | # CHECK-NEXT: Value: 0x[[VAL]] | |
| 19 | # CHECK-NEXT: Size: | |
| 20 | # CHECK-NEXT: Binding: Global | |
| 21 | # CHECK-NEXT: Type: | |
| 22 | # CHECK-NEXT: Other: 0 | |
| 23 | # CHECK-NEXT: Section: .bss.rel.ro | |
| 24 | ||
| 25 | .global _start | |
| 26 | _start: | |
| 27 | .quad bar |
deps/lld/test/ELF/linkerscript/data-commands.s+36| ... | ... | @@ -44,6 +44,42 @@ |
| 44 | 44 | # BE-NEXT: ff12ff11 22ff1122 3346ff11 22334455 |
| 45 | 45 | # BE-NEXT: 667788 |
| 46 | 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 | ||
| 47 | 83 | .global a |
| 48 | 84 | a = 0x11 |
| 49 | 85 |
deps/lld/test/ELF/linkerscript/data-segment-relro.s+2-2| ... | ... | @@ -19,9 +19,9 @@ |
| 19 | 19 | |
| 20 | 20 | ## With relro or without DATA_SEGMENT_RELRO_END just aligns to |
| 21 | 21 | ## page boundary. |
| 22 | # RUN: ld.lld -z norelro %t1.o %t2.so --script %t.script -o %t | |
| 22 | # RUN: ld.lld --hash-style=sysv -z norelro %t1.o %t2.so --script %t.script -o %t | |
| 23 | 23 | # RUN: llvm-readobj -s %t | FileCheck %s |
| 24 | # RUN: ld.lld -z relro %t1.o %t2.so --script %t.script -o %t2 | |
| 24 | # RUN: ld.lld --hash-style=sysv -z relro %t1.o %t2.so --script %t.script -o %t2 | |
| 25 | 25 | # RUN: llvm-readobj -s %t2 | FileCheck %s |
| 26 | 26 | |
| 27 | 27 | # CHECK: Section { |
deps/lld/test/ELF/linkerscript/diagnostic.s+7-7| ... | ... | @@ -50,9 +50,9 @@ |
| 50 | 50 | # RUN: echo ".temp : { *(.temp) } }" >> %t.script |
| 51 | 51 | # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ |
| 52 | 52 | # RUN: FileCheck -check-prefix=ERR6 -strict-whitespace %s |
| 53 | # ERR6: error: {{.*}}.script:1: | |
| 54 | # ERR6-NEXT: error: {{.*}}.script:1: UNKNOWN_TAG { | |
| 55 | # ERR6-NEXT: error: {{.*}}.script:1: ^ | |
| 53 | # ERR6: error: {{.*}}.script:1: unknown directive: UNKNOWN_TAG | |
| 54 | # ERR6-NEXT: >>> UNKNOWN_TAG { | |
| 55 | # ERR6-NEXT: >>> ^ | |
| 56 | 56 | |
| 57 | 57 | ## One more check that text of lines and pointer to 'bad' token are working ok. |
| 58 | 58 | # RUN: echo "SECTIONS {" > %t.script |
| ... | ... | @@ -62,8 +62,8 @@ |
| 62 | 62 | # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ |
| 63 | 63 | # RUN: FileCheck -check-prefix=ERR7 -strict-whitespace %s |
| 64 | 64 | # ERR7: error: {{.*}}.script:4: malformed number: .temp |
| 65 | # ERR7-NEXT: error: {{.*}}.script:4: boom .temp : { *(.temp) } } | |
| 66 | # ERR7-NEXT: error: {{.*}}.script:4: ^ | |
| 65 | # ERR7-NEXT: >>> boom .temp : { *(.temp) } } | |
| 66 | # ERR7-NEXT: >>> ^ | |
| 67 | 67 | |
| 68 | 68 | ## Check tokenize() error |
| 69 | 69 | # RUN: echo "SECTIONS {}" > %t.script |
| ... | ... | @@ -89,8 +89,8 @@ |
| 89 | 89 | # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ |
| 90 | 90 | # RUN: FileCheck -check-prefix=ERR10 -strict-whitespace %s |
| 91 | 91 | # ERR10: error: {{.*}}.script.inc:4: malformed number: .temp |
| 92 | # ERR10-NEXT: error: {{.*}}.script.inc:4: boom .temp : { *(.temp) } } | |
| 93 | # ERR10-NEXT: error: {{.*}}.script.inc:4: ^ | |
| 92 | # ERR10-NEXT: >>> boom .temp : { *(.temp) } } | |
| 93 | # ERR10-NEXT: >>> ^ | |
| 94 | 94 | |
| 95 | 95 | ## Check error reporting in script with INCLUDE directive. |
| 96 | 96 | # RUN: echo "SECTIONS {" > %t.script.inc |
deps/lld/test/ELF/linkerscript/discard-section-err.s+2| ... | ... | @@ -21,3 +21,5 @@ |
| 21 | 21 | # RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \ |
| 22 | 22 | # RUN: FileCheck -check-prefix=DYNSTR %s |
| 23 | 23 | # DYNSTR: discarding .dynstr section is not allowed |
| 24 | ||
| 25 | .comm foo,4,4 |
deps/lld/test/ELF/linkerscript/early-assign-symbol.s+19-5| ... | ... | @@ -1,14 +1,28 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 3 | 3 | |
| 4 | # RUN: echo "SECTIONS { aaa = 1 + ABSOLUTE(foo - 1); .text : { *(.text*) } }" > %t1.script | |
| 5 | # RUN: not ld.lld -o %t --script %t1.script %t.o 2>&1 | FileCheck %s | |
| 6 | ||
| 7 | # RUN: echo "SECTIONS { aaa = ABSOLUTE(foo - 1) + 1; .text : { *(.text*) } }" > %t2.script | |
| 8 | # RUN: not ld.lld -o %t --script %t2.script %t.o 2>&1 | FileCheck %s | |
| 4 | # RUN: echo "SECTIONS { aaa = foo | 1; .text : { *(.text*) } }" > %t3.script | |
| 5 | # RUN: not ld.lld -o %t --script %t3.script %t.o 2>&1 | FileCheck %s | |
| 9 | 6 | |
| 10 | 7 | # CHECK: error: {{.*}}.script:1: unable to evaluate expression: input section .text has no output section assigned |
| 11 | 8 | |
| 9 | # Simple cases that we can handle. | |
| 10 | ||
| 11 | # RUN: echo "SECTIONS { aaa = ABSOLUTE(foo - 1) + 1; .text : { *(.text*) } }" > %t.script | |
| 12 | # RUN: ld.lld -o %t --script %t.script %t.o | |
| 13 | # RUN: llvm-objdump -t %t | FileCheck --check-prefix=VAL %s | |
| 14 | ||
| 15 | # RUN: echo "SECTIONS { aaa = 1 + ABSOLUTE(foo - 1); .text : { *(.text*) } }" > %t.script | |
| 16 | # RUN: ld.lld -o %t --script %t.script %t.o | |
| 17 | # RUN: llvm-objdump -t %t | FileCheck --check-prefix=VAL %s | |
| 18 | ||
| 19 | # RUN: echo "SECTIONS { aaa = ABSOLUTE(foo); .text : { *(.text*) } }" > %t4.script | |
| 20 | # RUN: ld.lld -o %t --script %t4.script %t.o | |
| 21 | # RUN: llvm-objdump -t %t | FileCheck --check-prefix=VAL %s | |
| 22 | ||
| 23 | # VAL: 0000000000000000 .text 00000000 foo | |
| 24 | # VAL: 0000000000000000 *ABS* 00000000 aaa | |
| 25 | ||
| 12 | 26 | .section .text |
| 13 | 27 | .globl foo |
| 14 | 28 | foo: |
deps/lld/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s+1-1| ... | ... | @@ -12,7 +12,7 @@ |
| 12 | 12 | # RUN: }" > %t.script |
| 13 | 13 | # RUN: not ld.lld %t.o -T %t.script -o %t 2>&1 | FileCheck %s |
| 14 | 14 | |
| 15 | # CHECK: error: {{.*}}:(.eh_frame+0x20): relocation R_X86_64_PC32 out of range | |
| 15 | # CHECK: error: {{.*}}:(.eh_frame+0x20): relocation R_X86_64_PC32 out of range: 64424443872 is not in [-2147483648, 2147483647] | |
| 16 | 16 | |
| 17 | 17 | 	.text |
| 18 | 18 | .globl _start |
deps/lld/test/ELF/linkerscript/emit-reloc-section-names.s created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 3 | # RUN: echo "SECTIONS { .text.zed : { *(.text.foo) } \ | |
| 4 | # RUN: .text.qux : { *(.text.bar) } }" > %t.script | |
| 5 | # RUN: ld.lld -T %t.script --emit-relocs %t.o -o %t | |
| 6 | # RUN: llvm-objdump -section-headers %t | FileCheck %s | |
| 7 | ||
| 8 | ## Check we name relocation sections in according to | |
| 9 | ## their target sections names. | |
| 10 | ||
| 11 | # CHECK: .text.zed | |
| 12 | # CHECK: .text.qux | |
| 13 | # CHECK: .rela.text.zed | |
| 14 | # CHECK: .rela.text.qux | |
| 15 | ||
| 16 | .section .text.foo,"ax" | |
| 17 | foo: | |
| 18 | mov $bar, %rax | |
| 19 | ||
| 20 | .section .text.bar,"ax" | |
| 21 | bar: | |
| 22 | mov $foo, %rax |
deps/lld/test/ELF/linkerscript/emit-reloc.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | # RUN: echo "SECTIONS { .rela.dyn : { *(.rela.data) } }" > %t.script |
| 4 | # RUN: ld.lld -T %t.script --emit-relocs %t.o -o %t.so -shared | |
| 4 | # RUN: ld.lld --hash-style=sysv -T %t.script --emit-relocs %t.o -o %t.so -shared | |
| 5 | 5 | # RUN: llvm-readobj -r %t.so | FileCheck %s |
| 6 | 6 | |
| 7 | 7 | .data |
deps/lld/test/ELF/linkerscript/emit-relocs-multiple.s+1-1| ... | ... | @@ -5,7 +5,7 @@ |
| 5 | 5 | # RUN: llvm-readobj -r %t1 | FileCheck %s |
| 6 | 6 | |
| 7 | 7 | # CHECK: Relocations [ |
| 8 | # CHECK-NEXT: Section {{.*}} .rela.foo { | |
| 8 | # CHECK-NEXT: Section {{.*}} .rela.zed { | |
| 9 | 9 | # CHECK-NEXT: 0x1 R_X86_64_32 .zed 0x0 |
| 10 | 10 | # CHECK-NEXT: 0x6 R_X86_64_32 .zed 0x5 |
| 11 | 11 | # CHECK-NEXT: } |
deps/lld/test/ELF/linkerscript/extend-pt-load.s+6-7| ... | ... | @@ -15,7 +15,7 @@ |
| 15 | 15 | # RUN: . = ALIGN(0x1000); \ |
| 16 | 16 | # RUN: .data.rel.ro : { *(.data.rel.ro) } \ |
| 17 | 17 | # RUN: }" > %t.script |
| 18 | # RUN: ld.lld -o %t1 --script %t.script %t.o -shared | |
| 18 | # RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t.o -shared | |
| 19 | 19 | # RUN: llvm-readobj --elf-output-style=GNU -l -s %t1 | FileCheck --check-prefix=CHECK1 %s |
| 20 | 20 | |
| 21 | 21 | # CHECK1: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX |
| ... | ... | @@ -33,18 +33,17 @@ |
| 33 | 33 | # RUN:	.hash : { } \ |
| 34 | 34 | # RUN:	.dynstr : { } \ |
| 35 | 35 | # RUN: .text : { *(.text) } \ |
| 36 | # RUN: . = ALIGN(0x1000); \ | |
| 37 | # RUN: bar : { HIDDEN(bar_sym = .); } \ | |
| 36 | # RUN: bar : { . = ALIGN(0x1000); } \ | |
| 38 | 37 | # RUN: .data.rel.ro : { *(.data.rel.ro) } \ |
| 39 | 38 | # RUN: }" > %t.script |
| 40 | # RUN: ld.lld -o %t2 --script %t.script %t.o -shared | |
| 39 | # RUN: ld.lld --hash-style=sysv -o %t2 --script %t.script %t.o -shared | |
| 41 | 40 | # RUN: llvm-readobj --elf-output-style=GNU -l -s %t2 | FileCheck --check-prefix=CHECK2 %s |
| 42 | 41 | |
| 43 | 42 | # CHECK2: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX |
| 44 | # CHECK2-NEXT: bar PROGBITS 0000000000001000 001000 000000 00 AX | |
| 43 | # CHECK2-NEXT: bar NOBITS 00000000000001bd 0001bd 000e43 00 AX | |
| 45 | 44 | # CHECK2-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA |
| 46 | 45 | |
| 47 | # CHECK2: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x001000 0x001000 R E | |
| 46 | # CHECK2: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001bd 0x001000 R E | |
| 48 | 47 | # CHECK2-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW |
| 49 | 48 | |
| 50 | 49 | # If the current behavior becomes a problem we should consider just moving the commands out |
| ... | ... | @@ -60,7 +59,7 @@ |
| 60 | 59 | # RUN: HIDDEN(bar_sym = .); \ |
| 61 | 60 | # RUN: .data.rel.ro : { *(.data.rel.ro) } \ |
| 62 | 61 | # RUN: }" > %t.script |
| 63 | # RUN: ld.lld -o %t3 --script %t.script %t.o -shared | |
| 62 | # RUN: ld.lld --hash-style=sysv -o %t3 --script %t.script %t.o -shared | |
| 64 | 63 | # RUN: llvm-readobj --elf-output-style=GNU -l -s %t3 | FileCheck --check-prefix=CHECK1 %s |
| 65 | 64 | |
| 66 | 65 | nop |
deps/lld/test/ELF/linkerscript/filename-spec.s+43-4| ... | ... | @@ -33,24 +33,63 @@ |
| 33 | 33 | # RUN: ld.lld -o %t4 --script %t4.script %tfirst.o %tsecond.o |
| 34 | 34 | # RUN: llvm-objdump -s %t4 | FileCheck --check-prefix=SECONDFIRST %s |
| 35 | 35 | |
| 36 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %T/filename-spec1.o | |
| 36 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o filename-spec1.o | |
| 37 | 37 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ |
| 38 | # RUN: %p/Inputs/filename-spec.s -o %T/filename-spec2.o | |
| 38 | # RUN: %p/Inputs/filename-spec.s -o filename-spec2.o | |
| 39 | 39 | |
| 40 | 40 | # RUN: echo "SECTIONS { .foo : { \ |
| 41 | 41 | # RUN: filename-spec2.o(.foo) \ |
| 42 | 42 | # RUN: filename-spec1.o(.foo) } }" > %t5.script |
| 43 | 43 | # RUN: ld.lld -o %t5 --script %t5.script \ |
| 44 | # RUN: %T/filename-spec1.o %T/filename-spec2.o | |
| 44 | # RUN: filename-spec1.o filename-spec2.o | |
| 45 | 45 | # RUN: llvm-objdump -s %t5 | FileCheck --check-prefix=SECONDFIRST %s |
| 46 | 46 | |
| 47 | 47 | # RUN: echo "SECTIONS { .foo : { \ |
| 48 | 48 | # RUN: filename-spec1.o(.foo) \ |
| 49 | 49 | # RUN: filename-spec2.o(.foo) } }" > %t6.script |
| 50 | 50 | # RUN: ld.lld -o %t6 --script %t6.script \ |
| 51 | # RUN: %T/filename-spec1.o %T/filename-spec2.o | |
| 51 | # RUN: filename-spec1.o filename-spec2.o | |
| 52 | 52 | # RUN: llvm-objdump -s %t6 | FileCheck --check-prefix=FIRSTSECOND %s |
| 53 | 53 | |
| 54 | # 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 | |
| 56 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ | |
| 57 | # RUN: %p/Inputs/filename-spec.s -o %t.testdir2/filename-spec2.o | |
| 58 | # RUN: llvm-ar rsc %t.testdir1/lib1.a %t.testdir1/filename-spec1.o | |
| 59 | # RUN: llvm-ar rsc %t.testdir2/lib2.a %t.testdir2/filename-spec2.o | |
| 60 | ||
| 61 | # Verify matching of archive library names. | |
| 62 | # RUN: echo "SECTIONS { .foo : { \ | |
| 63 | # RUN: *lib2*(.foo) \ | |
| 64 | # RUN: *lib1*(.foo) } }" > %t7.script | |
| 65 | # RUN: ld.lld -o %t7 --script %t7.script --whole-archive \ | |
| 66 | # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a | |
| 67 | # RUN: llvm-objdump -s %t7 | FileCheck --check-prefix=SECONDFIRST %s | |
| 68 | ||
| 69 | # Verify matching directories. | |
| 70 | # RUN: echo "SECTIONS { .foo : { \ | |
| 71 | # RUN: *testdir2*(.foo) \ | |
| 72 | # RUN: *testdir1*(.foo) } }" > %t8.script | |
| 73 | # RUN: ld.lld -o %t8 --script %t8.script --whole-archive \ | |
| 74 | # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a | |
| 75 | # RUN: llvm-objdump -s %t8 | FileCheck --check-prefix=SECONDFIRST %s | |
| 76 | ||
| 77 | # Verify matching of archive library names in KEEP. | |
| 78 | # RUN: echo "SECTIONS { .foo : { \ | |
| 79 | # RUN: KEEP(*lib2*(.foo)) \ | |
| 80 | # RUN: KEEP(*lib1*(.foo)) } }" > %t9.script | |
| 81 | # RUN: ld.lld -o %t9 --script %t9.script --whole-archive \ | |
| 82 | # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a | |
| 83 | # RUN: llvm-objdump -s %t9 | FileCheck --check-prefix=SECONDFIRST %s | |
| 84 | ||
| 85 | # Verify matching directories in KEEP. | |
| 86 | # RUN: echo "SECTIONS { .foo : { \ | |
| 87 | # RUN: KEEP(*testdir2*(.foo)) \ | |
| 88 | # RUN: KEEP(*testdir1*(.foo)) } }" > %t10.script | |
| 89 | # RUN: ld.lld -o %t10 --script %t10.script --whole-archive \ | |
| 90 | # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a | |
| 91 | # RUN: llvm-objdump -s %t10 | FileCheck --check-prefix=SECONDFIRST %s | |
| 92 | ||
| 54 | 93 | .global _start |
| 55 | 94 | _start: |
| 56 | 95 | nop |
deps/lld/test/ELF/linkerscript/header-addr.s+11-11| ... | ... | @@ -2,20 +2,20 @@ |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | # RUN: echo "PHDRS {all PT_LOAD PHDRS;} \ |
| 4 | 4 | # RUN: SECTIONS { \ |
| 5 | # RUN: . = 0x2000; \ | |
| 5 | # RUN: . = 0x2000 + SIZEOF_HEADERS; \ | |
| 6 | 6 | # RUN: .text : {*(.text)} :all \ |
| 7 | 7 | # RUN: }" > %t.script |
| 8 | # RUN: ld.lld -o %t.so --script %t.script %t.o -shared | |
| 8 | # RUN: ld.lld --hash-style=sysv -o %t.so --script %t.script %t.o -shared | |
| 9 | 9 | # RUN: llvm-readobj -program-headers %t.so | FileCheck %s |
| 10 | 10 | |
| 11 | 11 | # CHECK: ProgramHeaders [ |
| 12 | 12 | # CHECK-NEXT: ProgramHeader { |
| 13 | 13 | # CHECK-NEXT: Type: PT_LOAD |
| 14 | 14 | # CHECK-NEXT: Offset: 0x40 |
| 15 | # CHECK-NEXT: VirtualAddress: 0x1040 | |
| 16 | # CHECK-NEXT: PhysicalAddress: 0x1040 | |
| 17 | # CHECK-NEXT: FileSize: 4176 | |
| 18 | # CHECK-NEXT: MemSize: 4176 | |
| 15 | # CHECK-NEXT: VirtualAddress: 0x2040 | |
| 16 | # CHECK-NEXT: PhysicalAddress: 0x2040 | |
| 17 | # CHECK-NEXT: FileSize: 200 | |
| 18 | # CHECK-NEXT: MemSize: 200 | |
| 19 | 19 | # CHECK-NEXT: Flags [ |
| 20 | 20 | # CHECK-NEXT: PF_R (0x4) |
| 21 | 21 | # CHECK-NEXT: PF_W (0x2) |
| ... | ... | @@ -25,7 +25,7 @@ |
| 25 | 25 | # CHECK-NEXT: } |
| 26 | 26 | # CHECK-NEXT: ] |
| 27 | 27 | |
| 28 | # RUN: ld.lld -o %t2.so --script %t.script %t.o -shared -z max-page-size=0x2000 | |
| 28 | # RUN: ld.lld --hash-style=sysv -o %t2.so --script %t.script %t.o -shared -z max-page-size=0x2000 | |
| 29 | 29 | # RUN: llvm-readobj -program-headers %t2.so \ |
| 30 | 30 | # RUN: | FileCheck --check-prefix=MAXPAGE %s |
| 31 | 31 | |
| ... | ... | @@ -33,10 +33,10 @@ |
| 33 | 33 | # MAXPAGE-NEXT: ProgramHeader { |
| 34 | 34 | # MAXPAGE-NEXT: Type: PT_LOAD |
| 35 | 35 | # MAXPAGE-NEXT: Offset: 0x40 |
| 36 | # MAXPAGE-NEXT: VirtualAddress: 0x40 | |
| 37 | # MAXPAGE-NEXT: PhysicalAddress: 0x40 | |
| 38 | # MAXPAGE-NEXT: FileSize: 8272 | |
| 39 | # MAXPAGE-NEXT: MemSize: 8272 | |
| 36 | # MAXPAGE-NEXT: VirtualAddress: 0x2040 | |
| 37 | # MAXPAGE-NEXT: PhysicalAddress: 0x2040 | |
| 38 | # MAXPAGE-NEXT: FileSize: 200 | |
| 39 | # MAXPAGE-NEXT: MemSize: 200 | |
| 40 | 40 | # MAXPAGE-NEXT: Flags [ |
| 41 | 41 | # MAXPAGE-NEXT: PF_R |
| 42 | 42 | # MAXPAGE-NEXT: PF_W |
deps/lld/test/ELF/linkerscript/header-phdr.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: 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/image-base.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: echo "SECTIONS { mysym = .; }" > %t.script | |
| 5 | ||
| 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 | |
| 8 | # DEFAULT: Name: mysym | |
| 9 | # DEFAULT-NEXT: Value: 0x0 | |
| 10 | ||
| 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 | |
| 13 | # SWITCH: Name: mysym | |
| 14 | # SWITCH-NEXT: Value: 0x100000 | |
| 15 | ||
| 16 | .global _start | |
| 17 | _start: | |
| 18 | nop |
deps/lld/test/ELF/linkerscript/implicit-program-header.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: ld.lld -o %t1 --script %S/Inputs/implicit-program-header.script \ | |
| 3 | # RUN: ld.lld --hash-style=sysv -o %t1 --script %S/Inputs/implicit-program-header.script \ | |
| 4 | 4 | # RUN: %t.o -shared |
| 5 | 5 | # RUN: llvm-readobj -elf-output-style=GNU -l %t1 | FileCheck %s |
| 6 | 6 |
deps/lld/test/ELF/linkerscript/include-cycle.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 "INCLUDE \"%t1.script\"" > %t1.script | |
| 5 | # RUN: not ld.lld %t.o %t1.script 2>&1 | FileCheck %s | |
| 6 | ||
| 7 | # RUN: echo "INCLUDE \"%t2.script\"" > %t1.script | |
| 8 | # RUN: echo "INCLUDE \"%t1.script\"" > %t2.script | |
| 9 | # RUN: not ld.lld %t.o %t1.script 2>&1 | FileCheck %s | |
| 10 | ||
| 11 | # CHECK: there is a cycle in linker script INCLUDEs | |
| 12 | ||
| 13 | .globl _start | |
| 14 | _start: | |
| 15 | ret |
deps/lld/test/ELF/linkerscript/linker-script-in-search-path.s created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # Check that we fall back to search paths if a linker script was not found | |
| 3 | # This behaviour matches ld.bfd and various projects appear to rely on this | |
| 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 "OUTPUT(\"%t.out\")" > %T/searchpath/foo.script | |
| 8 | # RUN: ld.lld -T%T/searchpath/foo.script %t.o | |
| 9 | # RUN: llvm-readobj %t.out | FileCheck %s | |
| 10 | # CHECK: Format: ELF64-x86-64 | |
| 11 | ||
| 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 | |
| 14 | # ERROR: error: cannot find linker script foo.script | |
| 15 | ||
| 16 | # But if it exists in the search path we should fall back to that instead: | |
| 17 | # RUN: rm %t.out | |
| 18 | # RUN: ld.lld -L %T/searchpath -Tfoo.script %t.o | |
| 19 | # RUN: llvm-readobj %t.out | FileCheck %s |
deps/lld/test/ELF/linkerscript/linkerscript.s+2-2| ... | ... | @@ -37,8 +37,8 @@ |
| 37 | 37 | # RUN: echo "OUTPUT(\"%t.out\")" > %T/foo.script |
| 38 | 38 | # RUN: not ld.lld %t.script > %t.log 2>&1 |
| 39 | 39 | # RUN: FileCheck -check-prefix=INCLUDE_ERR %s < %t.log |
| 40 | # INCLUDE_ERR: error: {{.+}}.script:1: cannot open foo.script | |
| 41 | # INCLUDE_ERR-NEXT: error: {{.+}}.script:1: INCLUDE "foo.script" | |
| 40 | # INCLUDE_ERR: error: {{.+}}.script:1: cannot find linker script foo.script | |
| 41 | # INCLUDE_ERR-NEXT: INCLUDE "foo.script" | |
| 42 | 42 | # RUN: ld.lld -L %T %t.script %t |
| 43 | 43 | |
| 44 | 44 | # RUN: echo "FOO(BAR)" > %t.script |
deps/lld/test/ELF/linkerscript/memory-at.s created+46| ... | ... | @@ -0,0 +1,46 @@ |
| 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-err.s created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | |
| 3 | # RUN: echo "MEMORY { name : ORIGIN = DATA_SEGMENT_RELRO_END; }" > %t.script | |
| 4 | # RUN: not ld.lld -shared -o %t2 --script %t.script %t 2>&1 | FileCheck %s | |
| 5 | # CHECK: error: {{.*}}.script:1: unable to calculate page size | |
| 6 | ||
| 7 | # RUN: echo "MEMORY { name : ORIGIN = CONSTANT(COMMONPAGESIZE); }" > %t.script | |
| 8 | # RUN: not ld.lld -shared -o %t2 --script %t.script %t 2>&1 |\ | |
| 9 | # RUN: FileCheck %s --check-prefix=ERR2 | |
| 10 | # ERR2: error: {{.*}}.script:1: unable to calculate page size | |
| 11 | ||
| 12 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | |
| 13 | # RUN: echo "MEMORY { name : ORIGIN = .; }" > %t.script | |
| 14 | # RUN: not ld.lld -shared -o %t2 --script %t.script %t 2>&1 |\ | |
| 15 | # RUN: FileCheck %s --check-prefix=ERR3 | |
| 16 | # ERR3: error: {{.*}}.script:1: unable to get location counter value |
deps/lld/test/ELF/linkerscript/memory.s+2-2| ... | ... | @@ -21,8 +21,8 @@ |
| 21 | 21 | # RUN: rom (rx) : org = (0x80 * 0x1000 * 0x1000), len = 64M \ |
| 22 | 22 | # RUN: } \ |
| 23 | 23 | # RUN: SECTIONS { \ |
| 24 | # RUN: .text : { *(.text) } > rom \ | |
| 25 | # RUN: .data : { *(.data) } > ram \ | |
| 24 | # RUN: .text : { *(.text) } >rom \ | |
| 25 | # RUN: .data : { *(.data) } >ram \ | |
| 26 | 26 | # RUN: }" > %t.script |
| 27 | 27 | # RUN: ld.lld -o %t1 --script %t.script %t |
| 28 | 28 | # RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=RAMROM %s |
deps/lld/test/ELF/linkerscript/memory2.s created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | |
| 3 | # RUN: echo "MEMORY { ram (rwx) : ORIGIN = 0, LENGTH = 2K } \ | |
| 4 | # RUN: SECTIONS { .text : { *(.text*) } > ram }" > %t.script | |
| 5 | # RUN: ld.lld -o %t2 --script %t.script %t | |
| 6 | ||
| 7 | .text | |
| 8 | .global _start | |
| 9 | _start: | |
| 10 | .zero 1024 | |
| 11 | ||
| 12 | .section .text.foo,"ax",%progbits | |
| 13 | foo: | |
| 14 | nop |
deps/lld/test/ELF/linkerscript/memory3.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 | # RUN: echo "MEMORY { ram2 (ax) : ORIGIN = 0x1000, LENGTH = 1K \ | |
| 4 | # RUN: ram1 (ax) : ORIGIN = 0x4000, LENGTH = 1K } \ | |
| 5 | # RUN: SECTIONS {}" > %t1.script | |
| 6 | # RUN: ld.lld -o %t1 --script %t1.script %t | |
| 7 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | |
| 8 | ||
| 9 | # RUN: echo "MEMORY { ram1 (ax) : ORIGIN = 0x1000, LENGTH = 1K \ | |
| 10 | # RUN: ram2 (ax) : ORIGIN = 0x4000, LENGTH = 1K } \ | |
| 11 | # RUN: SECTIONS {}" > %t2.script | |
| 12 | # RUN: ld.lld -o %t2 --script %t2.script %t | |
| 13 | # RUN: llvm-objdump -section-headers %t2 | FileCheck %s | |
| 14 | ||
| 15 | ## Check we place .text into first defined memory region with appropriate flags. | |
| 16 | # CHECK: Sections: | |
| 17 | # CHECK: Idx Name Size Address | |
| 18 | # CHECK: 0 00000000 0000000000000000 | |
| 19 | # CHECK: 1 .text 00000001 0000000000001000 | |
| 20 | ||
| 21 | .section .text.foo,"ax",%progbits | |
| 22 | foo: | |
| 23 | nop |
deps/lld/test/ELF/linkerscript/merge-header-load.s created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 3 | # RUN: echo "SECTIONS { \ | |
| 4 | # RUN: . = 0xffffffff80000200; \ | |
| 5 | # RUN: .text : AT (0x4200) { *(.text) } \ | |
| 6 | # RUN: }" > %t.script | |
| 7 | # RUN: ld.lld %t.o --script %t.script -o %t | |
| 8 | # RUN: llvm-readelf -program-headers %t | FileCheck %s | |
| 9 | ||
| 10 | # Test that we put the header in the first PT_LOAD. We used to create a PT_LOAD | |
| 11 | # just for it and it would have a different virtual to physical address delta. | |
| 12 | ||
| 13 | # CHECK: Program Headers: | |
| 14 | # CHECK: Type Offset VirtAddr PhysAddr | |
| 15 | # CHECK-NEXT: PHDR 0x000040 0xffffffff80000040 0x0000000000004040 | |
| 16 | # CHECK-NEXT: LOAD 0x000000 0xffffffff80000000 0x0000000000004000 | |
| 17 | # CHECK-NOT: LOAD | |
| 18 | ||
| 19 | .global _start | |
| 20 | _start: | |
| 21 | nop |
deps/lld/test/ELF/linkerscript/merge-sections.s+1-1| ... | ... | @@ -36,7 +36,7 @@ |
| 36 | 36 | # RUN: llvm-readobj -s -t %t2 | FileCheck %s --check-prefix=GC |
| 37 | 37 | |
| 38 | 38 | # GC: Name: .foo |
| 39 | # GC-NEXT: Type: SHT_PROGBITS | |
| 39 | # GC-NEXT: Type: SHT_NOBITS | |
| 40 | 40 | # GC-NEXT: Flags [ |
| 41 | 41 | # GC-NEXT: SHF_ALLOC |
| 42 | 42 | # GC-NEXT: ] |
deps/lld/test/ELF/linkerscript/no-space.s+2-2| ... | ... | @@ -2,11 +2,11 @@ |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | |
| 4 | 4 | # RUN: echo "SECTIONS {foo 0 : {*(foo*)} }" > %t.script |
| 5 | # RUN: ld.lld -o %t --script %t.script %t.o -shared | |
| 5 | # RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared | |
| 6 | 6 | # RUN: llvm-readobj -elf-output-style=GNU -l %t | FileCheck %s |
| 7 | 7 | |
| 8 | 8 | # RUN: echo "SECTIONS {foo : {*(foo*)} }" > %t.script |
| 9 | # RUN: ld.lld -o %t --script %t.script %t.o -shared | |
| 9 | # RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared | |
| 10 | 10 | # RUN: llvm-readobj -elf-output-style=GNU -l %t | FileCheck %s |
| 11 | 11 | |
| 12 | 12 | # There is not enough address space available for the header, so just start the PT_LOAD |
deps/lld/test/ELF/linkerscript/nobits-offset.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: echo "SECTIONS { \ | |
| 4 | # RUN: .sec1 (NOLOAD) : { . += 1; } \ | |
| 5 | # RUN: .text : { *(.text) } \ | |
| 6 | # RUN: };" > %t.script | |
| 7 | # RUN: ld.lld %t.o -T %t.script -o %t | |
| 8 | # RUN: llvm-readelf --sections %t | FileCheck %s | |
| 9 | ||
| 10 | # We used to misalign section offsets if the first section in a | |
| 11 | # PT_LOAD was SHT_NOBITS. | |
| 12 | ||
| 13 | # CHECK: [ 2] .text PROGBITS 0000000000000010 001010 000010 00 AX 0 0 16 | |
| 14 | ||
| 15 | .global _start | |
| 16 | _start: | |
| 17 | nop | |
| 18 | .p2align 4 |
deps/lld/test/ELF/linkerscript/noload.s+2-2| ... | ... | @@ -4,10 +4,10 @@ |
| 4 | 4 | # RUN: .data_noload_a (NOLOAD) : { *(.data_noload_a) } \ |
| 5 | 5 | # RUN: .data_noload_b (0x10000) (NOLOAD) : { *(.data_noload_b) } };" > %t.script |
| 6 | 6 | # RUN: ld.lld -o %t --script %t.script %t.o |
| 7 | # RUN: llvm-readobj --symbols -sections %t | |
| 7 | # RUN: llvm-readobj --symbols -sections %t | FileCheck %s | |
| 8 | 8 | |
| 9 | 9 | # CHECK: Section { |
| 10 | # CHECK-NEXT: Index: 2 | |
| 10 | # CHECK: Index: 2 | |
| 11 | 11 | # CHECK-NEXT: Name: .data_noload_a |
| 12 | 12 | # CHECK-NEXT: Type: SHT_NOBITS |
| 13 | 13 | # CHECK-NEXT: Flags [ |
deps/lld/test/ELF/linkerscript/non-alloc.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 3 | 3 | |
| 4 | 4 | # RUN: echo "SECTIONS { .foo 0 : {*(foo)} }" > %t.script |
| 5 | # RUN: ld.lld -o %t1 --script %t.script %t -shared | |
| 5 | # RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t -shared | |
| 6 | 6 | # RUN: llvm-readobj -elf-output-style=GNU -s -l %t1 | FileCheck %s |
| 7 | 7 | |
| 8 | 8 | # Test that we create all necessary PT_LOAD. We use to stop at the first |
deps/lld/test/ELF/linkerscript/operators.s+8| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | 3 | # RUN: echo "SECTIONS { \ |
| 4 | # RUN: _start = .; \ | |
| 4 | 5 | # RUN: plus = 1 + 2 + 3; \ |
| 5 | 6 | # RUN: minus = 5 - 1; \ |
| 6 | 7 | # RUN: div = 6 / 2; \ |
| ... | ... | @@ -25,6 +26,10 @@ |
| 25 | 26 | # RUN: commonpagesize = CONSTANT (COMMONPAGESIZE); \ |
| 26 | 27 | # RUN: . = 0xfff0; \ |
| 27 | 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; \ | |
| 28 | 33 | # RUN: }" > %t.script |
| 29 | 34 | # RUN: ld.lld %t --script %t.script -o %t2 |
| 30 | 35 | # RUN: llvm-objdump -t %t2 | FileCheck %s |
| ... | ... | @@ -51,6 +56,9 @@ |
| 51 | 56 | # CHECK: 00000000001000 *ABS* 00000000 maxpagesize |
| 52 | 57 | # CHECK: 00000000001000 *ABS* 00000000 commonpagesize |
| 53 | 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 | |
| 54 | 62 | |
| 55 | 63 | ## Mailformed number error. |
| 56 | 64 | # RUN: echo "SECTIONS { . = 0x12Q41; }" > %t.script |
deps/lld/test/ELF/linkerscript/orphan-discard.s created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -position-independent -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | |
| 3 | # RUN: echo "SECTIONS { \ | |
| 4 | # RUN: . = 0xffffffff80000000; \ | |
| 5 | # RUN: .text : ALIGN(4096) { *(.text) } \ | |
| 6 | # RUN: .data : ALIGN(4096) { *(.data) } \ | |
| 7 | # RUN: .bss : ALIGN(4096) { *(.bss); } \ | |
| 8 | # RUN: . = ALIGN(4096); \ | |
| 9 | # RUN: _end = .; \ | |
| 10 | # RUN: /DISCARD/ : { *(.comment) } \ | |
| 11 | # RUN: }" > %t.script | |
| 12 | # RUN: ld.lld -o %t --script %t.script %t.o | |
| 13 | # RUN: llvm-readelf -s -symbols %t | FileCheck %s | |
| 14 | ||
| 15 | # CHECK: .bss NOBITS ffffffff80002000 002008 000002 00 WA 0 0 4096 | |
| 16 | # CHECK: ffffffff80003000 0 NOTYPE GLOBAL DEFAULT 3 _end | |
| 17 | ||
| 18 | .section .text, "ax" | |
| 19 | ret | |
| 20 | ||
| 21 | .section .data, "aw" | |
| 22 | .quad 0 | |
| 23 | ||
| 24 | .section .bss, "", @nobits | |
| 25 | .short 0 |
deps/lld/test/ELF/linkerscript/orphan-end.s created+57| ... | ... | @@ -0,0 +1,57 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 3 | ||
| 4 | # Test that .orphan_rx is placed after __stack_end. This matches bfd's | |
| 5 | # behavior when the orphan section is the last one. | |
| 6 | ||
| 7 | # RUN: echo "SECTIONS { \ | |
| 8 | # RUN: __start_text = .; \ | |
| 9 | # RUN: .text : { *(.text*) } \ | |
| 10 | # RUN: __end_text = .; \ | |
| 11 | # RUN: __stack_start = .; \ | |
| 12 | # RUN: . = . + 0x1000; \ | |
| 13 | # RUN: __stack_end = .; \ | |
| 14 | # RUN: }" > %t.script | |
| 15 | # RUN: ld.lld -o %t --script %t.script %t.o | |
| 16 | # RUN: llvm-readelf -S --symbols %t | FileCheck %s | |
| 17 | ||
| 18 | # CHECK-DAG: .text PROGBITS 0000000000000000 | |
| 19 | # CHECK-DAG: .orphan_rx PROGBITS 0000000000001004 | |
| 20 | ||
| 21 | # CHECK-DAG: 0000000000000000 {{.*}} __start_text | |
| 22 | # CHECK-DAG: 0000000000000004 {{.*}} __end_text | |
| 23 | # CHECK-DAG: 0000000000000004 {{.*}} __stack_start | |
| 24 | # CHECK-DAG: 0000000000001004 {{.*}} __stack_end | |
| 25 | ||
| 26 | # Test that .orphan_rx is now placed before __stack_end. This matches bfd's | |
| 27 | # behavior when the orphan section is not the last one. | |
| 28 | ||
| 29 | # RUN: echo "SECTIONS { \ | |
| 30 | # RUN: __start_text = .; \ | |
| 31 | # RUN: .text : { *(.text*) } \ | |
| 32 | # RUN: __end_text = .; \ | |
| 33 | # RUN: __stack_start = .; \ | |
| 34 | # RUN: . = . + 0x1000; \ | |
| 35 | # RUN: __stack_end = .; \ | |
| 36 | # RUN: .orphan_rw : { *(.orphan_rw*) } \ | |
| 37 | # RUN: }" > %t.script | |
| 38 | # RUN: ld.lld -o %t --script %t.script %t.o | |
| 39 | # RUN: llvm-readelf -S --symbols %t | FileCheck --check-prefix=MIDDLE %s | |
| 40 | ||
| 41 | # MIDDLE-DAG: .text PROGBITS 0000000000000000 | |
| 42 | # MIDDLE-DAG: .orphan_rx PROGBITS 0000000000000004 | |
| 43 | ||
| 44 | # MIDDLE-DAG: 0000000000000000 {{.*}} __start_text | |
| 45 | # MIDDLE-DAG: 0000000000000004 {{.*}} __end_text | |
| 46 | # MIDDLE-DAG: 0000000000000004 {{.*}} __stack_start | |
| 47 | # MIDDLE-DAG: 0000000000001008 {{.*}} __stack_end | |
| 48 | ||
| 49 | .global _start | |
| 50 | _start: | |
| 51 | .zero 4 | |
| 52 | ||
| 53 | .section .orphan_rx,"ax" | |
| 54 | .zero 4 | |
| 55 | ||
| 56 | .section .orphan_rw,"aw" | |
| 57 | .zero 4 |
deps/lld/test/ELF/linkerscript/orphan-phdrs.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: echo "PHDRS { \ | |
| 4 | # RUN: exec PT_LOAD FLAGS(0x4 | 0x1); \ | |
| 5 | # RUN: rw PT_LOAD FLAGS(0x4 | 0x2); \ | |
| 6 | # RUN: } \ | |
| 7 | # RUN: SECTIONS { \ | |
| 8 | # RUN: .text : { *(.text) } :exec \ | |
| 9 | # RUN: .empty : { *(.empty) } :rw \ | |
| 10 | # RUN: .rw : { *(.rw) } \ | |
| 11 | # RUN: }" > %t.script | |
| 12 | # RUN: ld.lld -o %t --script %t.script %t.o | |
| 13 | # RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s | |
| 14 | ||
| 15 | ## Check that the orphan section is placed correctly and belongs to | |
| 16 | ## the correct segment. | |
| 17 | ||
| 18 | # CHECK: Section Headers | |
| 19 | # CHECK: .text | |
| 20 | # CHECK-NEXT: .orphan | |
| 21 | # CHECK-NEXT: .rw | |
| 22 | ||
| 23 | # CHECK: Segment Sections | |
| 24 | # CHECK-NEXT: .text .orphan | |
| 25 | # CHECK-NEXT: .rw | |
| 26 | ||
| 27 | .section .text, "ax" | |
| 28 | ret | |
| 29 | ||
| 30 | .section .rw, "aw" | |
| 31 | .quad 0 | |
| 32 | ||
| 33 | .section .orphan, "ax" | |
| 34 | ret |
deps/lld/test/ELF/linkerscript/orphan-report.s created+54| ... | ... | @@ -0,0 +1,54 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | |
| 3 | # RUN: echo "SECTIONS { .text : { *(.text.1) } }" > %t.script | |
| 4 | ||
| 5 | ## Check we do not report orphans by default even with -verbose. | |
| 6 | # RUN: ld.lld -shared -o %t.out --script %t.script %t.o 2>&1 -verbose \ | |
| 7 | # RUN: | FileCheck %s --check-prefix=DEFAULT | |
| 8 | # DEFAULT-NOT: placed | |
| 9 | ||
| 10 | ## Check --orphan-handling=place has the same behavior as default. | |
| 11 | # RUN: ld.lld -shared --orphan-handling=place -o %t.out --script %t.script \ | |
| 12 | # RUN: %t.o 2>&1 -verbose -error-limit=0 | FileCheck %s --check-prefix=DEFAULT | |
| 13 | ||
| 14 | ## Check --orphan-handling=error reports errors about orphans. | |
| 15 | # RUN: not ld.lld -shared --orphan-handling=error -o %t.out --script %t.script \ | |
| 16 | # RUN: %t.o 2>&1 -verbose -error-limit=0 | FileCheck %s --check-prefix=REPORT | |
| 17 | # REPORT: {{.*}}.o:(.text) is being placed in '.text' | |
| 18 | # REPORT-NEXT: {{.*}}.o:(.text.2) is being placed in '.text' | |
| 19 | # REPORT-NEXT: <internal>:(.comment) is being placed in '.comment' | |
| 20 | # REPORT-NEXT: <internal>:(.bss) is being placed in '.bss' | |
| 21 | # REPORT-NEXT: <internal>:(.bss.rel.ro) is being placed in '.bss.rel.ro' | |
| 22 | # REPORT-NEXT: <internal>:(.dynsym) is being placed in '.dynsym' | |
| 23 | # REPORT-NEXT: <internal>:(.gnu.version) is being placed in '.gnu.version' | |
| 24 | # REPORT-NEXT: <internal>:(.gnu.version_r) is being placed in '.gnu.version_r' | |
| 25 | # REPORT-NEXT: <internal>:(.gnu.hash) is being placed in '.gnu.hash' | |
| 26 | # REPORT-NEXT: <internal>:(.hash) is being placed in '.hash' | |
| 27 | # REPORT-NEXT: <internal>:(.dynamic) is being placed in '.dynamic' | |
| 28 | # REPORT-NEXT: <internal>:(.dynstr) is being placed in '.dynstr' | |
| 29 | # REPORT-NEXT: <internal>:(.rela.dyn) is being placed in '.rela.dyn' | |
| 30 | # REPORT-NEXT: <internal>:(.got) is being placed in '.got' | |
| 31 | # REPORT-NEXT: <internal>:(.got.plt) is being placed in '.got.plt' | |
| 32 | # REPORT-NEXT: <internal>:(.got.plt) is being placed in '.got.plt' | |
| 33 | # REPORT-NEXT: <internal>:(.rela.plt) is being placed in '.rela.plt' | |
| 34 | # REPORT-NEXT: <internal>:(.rela.plt) is being placed in '.rela.plt' | |
| 35 | # 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' | |
| 38 | # REPORT-NEXT: <internal>:(.symtab) is being placed in '.symtab' | |
| 39 | # REPORT-NEXT: <internal>:(.shstrtab) is being placed in '.shstrtab' | |
| 40 | # REPORT-NEXT: <internal>:(.strtab) is being placed in '.strtab' | |
| 41 | ||
| 42 | ## Check --orphan-handling=warn reports warnings about orphans. | |
| 43 | # RUN: ld.lld -shared --orphan-handling=warn -o %t.out --script %t.script \ | |
| 44 | # RUN: %t.o 2>&1 -verbose | FileCheck %s --check-prefix=REPORT | |
| 45 | ||
| 46 | # RUN: not ld.lld --orphan-handling=foo -o %t.out --script %t.script %t.o 2>&1 \ | |
| 47 | # RUN: | FileCheck %s --check-prefix=UNKNOWN | |
| 48 | # UNKNOWN: unknown --orphan-handling mode: foo | |
| 49 | ||
| 50 | .section .text.1,"a" | |
| 51 | nop | |
| 52 | ||
| 53 | .section .text.2,"a" | |
| 54 | nop |
deps/lld/test/ELF/linkerscript/out-of-order.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-linux %s -o %t.o |
| 3 | 3 | # RUN: echo "SECTIONS { .data 0x4000 : { *(.data) } .text 0x2000 : { *(.text) } }" > %t.script |
| 4 | # RUN: ld.lld -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 | 5 | # RUN: llvm-objdump -section-headers %t.so | FileCheck %s |
| 6 | 6 | |
| 7 | 7 | # CHECK: Sections: |
deps/lld/test/ELF/linkerscript/parse-section-in-addr.s created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 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/phdr-check.s+2-2| ... | ... | @@ -1,14 +1,14 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | 3 | |
| 4 | # RUN: echo "SECTIONS { . = 0x10000000; .text : {*(.text.*)} }" > %t.script | |
| 4 | # RUN: echo "SECTIONS { . = 0x10000000 + SIZEOF_HEADERS; .text : {*(.text.*)} }" > %t.script | |
| 5 | 5 | # RUN: ld.lld -o %t1 --script %t.script %t |
| 6 | 6 | # RUN: llvm-readobj -program-headers %t1 | FileCheck %s |
| 7 | 7 | # CHECK: ProgramHeaders [ |
| 8 | 8 | # CHECK-NEXT: ProgramHeader { |
| 9 | 9 | # CHECK-NEXT: Type: PT_PHDR (0x6) |
| 10 | 10 | # CHECK-NEXT: Offset: 0x40 |
| 11 | # CHECK-NEXT: VirtualAddress: 0xFFFF040 | |
| 11 | # CHECK-NEXT: VirtualAddress: 0x10000040 | |
| 12 | 12 | |
| 13 | 13 | .global _start |
| 14 | 14 | _start: |
deps/lld/test/ELF/linkerscript/phdrs.s+2-2| ... | ... | @@ -39,9 +39,9 @@ |
| 39 | 39 | # RUN: ld.lld -o %t1 --script %t.script %t |
| 40 | 40 | # RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=DEFHDR %s |
| 41 | 41 | |
| 42 | ## Check that error is reported when trying to use phdr which is not listed | |
| 42 | ## Check that error is reported when trying to use phdr which is not listed | |
| 43 | 43 | ## inside PHDRS {} block |
| 44 | ## TODO: If script doesn't contain PHDRS {} block then default phdr is always | |
| 44 | ## TODO: If script doesn't contain PHDRS {} block then default phdr is always | |
| 45 | 45 | ## created and error is not reported. |
| 46 | 46 | # RUN: echo "PHDRS { all PT_LOAD; } \ |
| 47 | 47 | # RUN: SECTIONS { .baz : {*(.foo.*)} :bar }" > %t.script |
deps/lld/test/ELF/linkerscript/provide-shared.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-shared.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-objdump -t %t | FileCheck %s | |
| 8 | ||
| 9 | # CHECK: 000000000000002a *ABS* 00000000 foo | |
| 10 | ||
| 11 | .global _start | |
| 12 | _start: | |
| 13 | .quad foo |
deps/lld/test/ELF/linkerscript/region-alias.s created+54| ... | ... | @@ -0,0 +1,54 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | |
| 3 | # RUN: echo "MEMORY { \ | |
| 4 | # RUN: ROM (rwx): ORIGIN = 0x1000, LENGTH = 0x100 \ | |
| 5 | # RUN: RAM (rwx): ORIGIN = 0x2000, LENGTH = 0x100 \ | |
| 6 | # RUN: } \ | |
| 7 | # RUN: INCLUDE \"%t.script.inc\" \ | |
| 8 | # RUN: SECTIONS { \ | |
| 9 | # RUN: .text : { *(.text*) } > ALIAS_TEXT \ | |
| 10 | # RUN: .data : { *(.data*) } > ALIAS_DATA \ | |
| 11 | # RUN: }" > %t.script | |
| 12 | ||
| 13 | ## .text to ROM, .data to RAM. | |
| 14 | # RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" > %t.script.inc | |
| 15 | # RUN: echo "REGION_ALIAS (\"ALIAS_DATA\", RAM);" >> %t.script.inc | |
| 16 | # RUN: ld.lld %t --script %t.script -o %t2 | |
| 17 | # RUN: llvm-objdump -section-headers %t2 | FileCheck %s | |
| 18 | # CHECK: .text 00000001 0000000000001000 TEXT DATA | |
| 19 | # CHECK: .data 00000008 0000000000002000 DATA | |
| 20 | ||
| 21 | ## All to ROM. | |
| 22 | # RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", 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 | |
| 25 | # RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=RAM | |
| 26 | # RAM: .text 00000001 0000000000001000 TEXT DATA | |
| 27 | # RAM: .data 00000008 0000000000001001 DATA | |
| 28 | ||
| 29 | ## Redefinition of region. | |
| 30 | # RUN: echo "REGION_ALIAS (\"ROM\", ROM);" > %t.script.inc | |
| 31 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | |
| 32 | # RUN: FileCheck %s --check-prefix=ERR1 | |
| 33 | # ERR1: {{.*}}script.inc:1: redefinition of memory region 'ROM' | |
| 34 | ||
| 35 | ## Redefinition of alias. | |
| 36 | # RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" > %t.script.inc | |
| 37 | # RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" >> %t.script.inc | |
| 38 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | |
| 39 | # RUN: FileCheck %s --check-prefix=ERR2 | |
| 40 | # ERR2: {{.*}}script.inc:2: redefinition of memory region 'ALIAS_TEXT' | |
| 41 | ||
| 42 | ## Attemp to create an alias for undefined region. | |
| 43 | # RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", FOO);" > %t.script.inc | |
| 44 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | |
| 45 | # RUN: FileCheck %s --check-prefix=ERR3 | |
| 46 | # ERR3: {{.*}}script.inc:1: memory region 'FOO' is not defined | |
| 47 | ||
| 48 | .text | |
| 49 | .global _start | |
| 50 | _start: | |
| 51 | nop | |
| 52 | ||
| 53 | .section .data,"aw" | |
| 54 | .quad 0 |
deps/lld/test/ELF/linkerscript/repsection-symbol.s+1-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | # RUN: .text : { *(.text) } \ |
| 7 | 7 | # RUN: .foo : {foo1 = .; *(.foo.*) foo2 = .; *(.bar) foo3 = .;} \ |
| 8 | 8 | # RUN: }" > %t.script |
| 9 | # RUN: ld.lld -o %t1 --script %t.script %t -shared | |
| 9 | # RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t -shared | |
| 10 | 10 | # RUN: llvm-readobj -t %t1 | FileCheck %s |
| 11 | 11 | |
| 12 | 12 | # CHECK: Name: foo1 |
deps/lld/test/ELF/linkerscript/sections-sort.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 3 | 3 | |
| 4 | 4 | # RUN: echo "SECTIONS { .text : {*(.text)} foo : {*(foo)}}" > %t.script |
| 5 | # RUN: ld.lld -o %t --script %t.script %t.o -shared | |
| 5 | # RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared | |
| 6 | 6 | # RUN: llvm-objdump --section-headers %t | FileCheck %s |
| 7 | 7 | |
| 8 | 8 | # Test the section order. This is a case where at least with libstdc++'s |
deps/lld/test/ELF/linkerscript/segment-headers.s created+26| ... | ... | @@ -0,0 +1,26 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | |
| 3 | # RUN: echo "SECTIONS { . = 0x2000; .text : AT(0x100000) { *(.text) } }" > %t.script | |
| 4 | # RUN: ld.lld -o %t --script %t.script %t.o | |
| 5 | # RUN: llvm-readobj -l %t | FileCheck %s | |
| 6 | ||
| 7 | # CHECK: ProgramHeaders [ | |
| 8 | # CHECK-NEXT: ProgramHeader { | |
| 9 | # CHECK-NEXT: Type: PT_LOAD (0x1) | |
| 10 | # CHECK-NEXT: Offset: 0x1000 | |
| 11 | # CHECK-NEXT: VirtualAddress: 0x2000 | |
| 12 | # CHECK-NEXT: PhysicalAddress: 0x100000 | |
| 13 | # CHECK-NEXT: FileSize: 1 | |
| 14 | # CHECK-NEXT: MemSize: 1 | |
| 15 | # CHECK-NEXT: Flags [ (0x5) | |
| 16 | # CHECK-NEXT: PF_R (0x4) | |
| 17 | # CHECK-NEXT: PF_X (0x1) | |
| 18 | # CHECK-NEXT: ] | |
| 19 | # CHECK-NEXT: Alignment: 4096 | |
| 20 | # CHECK-NEXT: } | |
| 21 | ||
| 22 | .section .text | |
| 23 | .global _start | |
| 24 | ||
| 25 | _start: | |
| 26 | ret |
deps/lld/test/ELF/linkerscript/segment-start.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: ld.lld %t.o %S/Inputs/segment-start.script -shared -o %t.so | |
| 3 | // RUN: ld.lld --hash-style=sysv %t.o %S/Inputs/segment-start.script -shared -o %t.so | |
| 4 | 4 | // RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s |
| 5 | 5 | |
| 6 | 6 | // CHECK: Name: foobar1 |
deps/lld/test/ELF/linkerscript/sort-non-script.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 3 | 3 | |
| 4 | 4 | # RUN: echo "SECTIONS { foo : {*(foo)} }" > %t.script |
| 5 | # RUN: ld.lld -o %t1 --script %t.script %t -shared | |
| 5 | # RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t -shared | |
| 6 | 6 | # RUN: llvm-readobj -elf-output-style=GNU -s %t1 | FileCheck %s |
| 7 | 7 | |
| 8 | 8 | # CHECK: .text {{.*}} AX |
deps/lld/test/ELF/linkerscript/subalign.s+17| ... | ... | @@ -22,6 +22,23 @@ |
| 22 | 22 | # SUBALIGN: 01000000 00000000 02000000 00000000 |
| 23 | 23 | # SUBALIGN: 03000000 00000000 04000000 00000000 |
| 24 | 24 | |
| 25 | ## Test we do not assert or crash when dot(.) is used inside SUBALIGN. | |
| 26 | ## ld.bfd does not allow to use dot in such expressions, our behavior is | |
| 27 | ## different for simplicity of implementation. Value of dot is undefined. | |
| 28 | # RUN: echo "SECTIONS { . = 0x32; .aaa : SUBALIGN(.) { *(.aaa*) } }" > %t3.script | |
| 29 | # RUN: ld.lld %t1.o --script %t3.script -o %t3 | |
| 30 | # RUN: llvm-objdump -s %t3 > /dev/null | |
| 31 | ||
| 32 | ## Test we are able to link with zero alignment, this is consistent with bfd 2.26.1. | |
| 33 | # RUN: echo "SECTIONS { .aaa : SUBALIGN(0) { *(.aaa*) } }" > %t4.script | |
| 34 | # RUN: ld.lld %t1.o --script %t4.script -o %t4 | |
| 35 | # RUN: llvm-objdump -s %t4 | FileCheck -check-prefix=SUBALIGN %s | |
| 36 | ||
| 37 | ## Test we fail gracefuly when alignment value is not a power of 2. | |
| 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 | |
| 40 | # ERR: {{.*}}.script:1: alignment must be power of 2 | |
| 41 | ||
| 25 | 42 | .global _start |
| 26 | 43 | _start: |
| 27 | 44 | nop |
deps/lld/test/ELF/linkerscript/symbol-assignexpr.s+7-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | # RUN: symbol2 = symbol + 0x1234; \ |
| 7 | 7 | # RUN: symbol3 = symbol2; \ |
| 8 | 8 | # RUN: symbol4 = symbol + -4; \ |
| 9 | # RUN: symbol5 = symbol - ~ 0xfffb; \ | |
| 9 | # RUN: symbol5 = symbol - ~0xfffb; \ | |
| 10 | 10 | # RUN: symbol6 = symbol - ~(0xfff0 + 0xb); \ |
| 11 | 11 | # RUN: symbol7 = symbol - ~ 0xfffb + 4; \ |
| 12 | 12 | # RUN: symbol8 = ~ 0xffff + 4; \ |
| ... | ... | @@ -15,6 +15,9 @@ |
| 15 | 15 | # RUN: symbol11 = ((0x28000 + 0x1fff) & ~(0x1000 + -1)); \ |
| 16 | 16 | # RUN: symbol12 = 0x1234; \ |
| 17 | 17 | # RUN: symbol12 += 1; \ |
| 18 | # RUN: symbol13 = !1; \ | |
| 19 | # RUN: symbol14 = !0; \ | |
| 20 | # RUN: symbol15 = 0!=1; \ | |
| 18 | 21 | # RUN: bar = 0x5678; \ |
| 19 | 22 | # RUN: baz = 0x9abc; \ |
| 20 | 23 | # RUN: }" > %t.script |
| ... | ... | @@ -39,6 +42,9 @@ |
| 39 | 42 | # CHECK-NEXT: fedcba9876543210 *ABS* 00000000 symbol10 |
| 40 | 43 | # CHECK-NEXT: 0000000000029000 *ABS* 00000000 symbol11 |
| 41 | 44 | # CHECK-NEXT: 0000000000001235 *ABS* 00000000 symbol12 |
| 45 | # CHECK-NEXT: 0000000000000000 *ABS* 00000000 symbol13 | |
| 46 | # CHECK-NEXT: 0000000000000001 *ABS* 00000000 symbol14 | |
| 47 | # CHECK-NEXT: 0000000000000001 *ABS* 00000000 symbol15 | |
| 42 | 48 | |
| 43 | 49 | # RUN: echo "SECTIONS { symbol2 = symbol; }" > %t2.script |
| 44 | 50 | # RUN: not ld.lld -o %t2 --script %t2.script %t 2>&1 \ |
deps/lld/test/ELF/linkerscript/symbol-only-flags.s created+20| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | |
| 3 | # RUN: echo "SECTIONS { . = 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.s+1-1| ... | ... | @@ -12,7 +12,7 @@ |
| 12 | 12 | # CHECK: Sections: |
| 13 | 13 | # CHECK-NEXT: Idx Name Size Address |
| 14 | 14 | # CHECK-NEXT: 0 00000000 0000000000000000 |
| 15 | # CHECK: abc 00000000 [[ADDR:[0-9a-f]*]] DATA | |
| 15 | # CHECK: abc 00000000 [[ADDR:[0-9a-f]*]] BSS | |
| 16 | 16 | # CHECK-NEXT: bar 00000000 0000000000001000 DATA |
| 17 | 17 | |
| 18 | 18 | # CHECK: SYMBOL TABLE: |
deps/lld/test/ELF/linkerscript/symbol-ordering-file.s created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 3 | # RUN: echo "SECTIONS { .foo : { *(.foo) } }" > %t.script | |
| 4 | ||
| 5 | # RUN: ld.lld %t.o --script %t.script -o %t.out | |
| 6 | # RUN: llvm-objdump -s %t.out| FileCheck %s --check-prefix=BEFORE | |
| 7 | # BEFORE: Contents of section .foo: | |
| 8 | # BEFORE-NEXT: 1122 | |
| 9 | ||
| 10 | # RUN: echo "_foo2" > %t.ord | |
| 11 | # RUN: echo "_foo1" >> %t.ord | |
| 12 | # RUN: ld.lld --symbol-ordering-file %t.ord %t.o --script %t.script -o %t2.out | |
| 13 | # RUN: llvm-objdump -s %t2.out| FileCheck %s --check-prefix=AFTER | |
| 14 | # AFTER: Contents of section .foo: | |
| 15 | # AFTER-NEXT: 2211 | |
| 16 | ||
| 17 | .section .foo,"ax",@progbits,unique,1 | |
| 18 | _foo1: | |
| 19 | .byte 0x11 | |
| 20 | ||
| 21 | .section .foo,"ax",@progbits,unique,2 | |
| 22 | _foo2: | |
| 23 | .byte 0x22 |
deps/lld/test/ELF/linkerscript/symbol-reserved.s+28| ... | ... | @@ -17,6 +17,34 @@ |
| 17 | 17 | |
| 18 | 18 | # ALIGNED: 0000000000200005 .text 00000000 .hidden newsym |
| 19 | 19 | |
| 20 | # RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(3, 8) + 10);" > %t.script | |
| 21 | # RUN: ld.lld -o %t1 %t.script %t | |
| 22 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=ALIGN-ADD %s | |
| 23 | # ALIGN-ADD: 0000000000000012 *ABS* 00000000 .hidden newsym | |
| 24 | ||
| 25 | # RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(11, 8) - 10);" > %t.script | |
| 26 | # RUN: ld.lld -o %t1 %t.script %t | |
| 27 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=ALIGN-SUB %s | |
| 28 | # ALIGN-SUB: 0000000000000006 *ABS* 00000000 .hidden newsym | |
| 29 | ||
| 30 | # RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(_end, CONSTANT(MAXPAGESIZE)) + 5);" > %t.script | |
| 31 | # RUN: ld.lld -o %t1 %t %t.script | |
| 32 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=RELATIVE %s | |
| 33 | # RELATIVE: 0000000000202005 .text 00000000 .hidden newsym | |
| 34 | # RELATIVE: 0000000000201007 .text 00000000 _end | |
| 35 | ||
| 36 | # RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(_end, CONSTANT(MAXPAGESIZE)) + 5);" > %t.script | |
| 37 | # RUN: ld.lld -o %t1 --script %p/Inputs/symbol-reserved.script %t %t.script | |
| 38 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=RELATIVE-ADD %s | |
| 39 | # RELATIVE-ADD: 0000000000001005 .text 00000000 .hidden newsym | |
| 40 | # RELATIVE-ADD: 0000000000000007 .text 00000000 .hidden _end | |
| 41 | ||
| 42 | # RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(_end, CONSTANT(MAXPAGESIZE)) - 5);" > %t.script | |
| 43 | # RUN: ld.lld -o %t1 --script %p/Inputs/symbol-reserved.script %t %t.script | |
| 44 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=RELATIVE-SUB %s | |
| 45 | # RELATIVE-SUB: 0000000000000ffb .text 00000000 .hidden newsym | |
| 46 | # RELATIVE-SUB: 0000000000000007 .text 00000000 .hidden _end | |
| 47 | ||
| 20 | 48 | .global _start |
| 21 | 49 | _start: |
| 22 | 50 | lea newsym(%rip),%rax |
deps/lld/test/ELF/linkerscript/symbols.s+5-8| ... | ... | @@ -12,14 +12,13 @@ |
| 12 | 12 | # The symbol is not referenced. Don't provide it. |
| 13 | 13 | # RUN: echo "SECTIONS { PROVIDE(newsym = 1);}" > %t.script |
| 14 | 14 | # RUN: ld.lld -o %t1 --script %t.script %t |
| 15 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=PROVIDE1 %s | |
| 16 | # PROVIDE1-NOT: 0000000000000001 *ABS* 00000000 newsym | |
| 15 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=DONTPROVIDE %s | |
| 16 | # DONTPROVIDE-NOT: newsym | |
| 17 | 17 | |
| 18 | 18 | # The symbol is not referenced. Don't provide it. |
| 19 | 19 | # RUN: echo "SECTIONS { PROVIDE_HIDDEN(newsym = 1);}" > %t.script |
| 20 | 20 | # RUN: ld.lld -o %t1 --script %t.script %t |
| 21 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN1 %s | |
| 22 | # HIDDEN1-NOT: 0000000000000001 *ABS* 00000000 .hidden newsym | |
| 21 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=DONTPROVIDE %s | |
| 23 | 22 | |
| 24 | 23 | # Provide existing symbol. The value should be 0, even though we |
| 25 | 24 | # have value of 1 in PROVIDE() |
| ... | ... | @@ -44,14 +43,12 @@ |
| 44 | 43 | # The symbol is not referenced. Don't provide it. |
| 45 | 44 | # RUN: echo "PROVIDE(newsym = 1);" > %t.script |
| 46 | 45 | # RUN: ld.lld -o %t1 --script %t.script %t |
| 47 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=PROVIDE4 %s | |
| 48 | # PROVIDE4-NOT: 0000000000000001 *ABS* 00000000 newsym | |
| 46 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=DONTPROVIDE %s | |
| 49 | 47 | |
| 50 | 48 | # The symbol is not referenced. Don't provide it. |
| 51 | 49 | # RUN: echo "PROVIDE_HIDDEN(newsym = 1);" > %t.script |
| 52 | 50 | # RUN: ld.lld -o %t1 --script %t.script %t |
| 53 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN4 %s | |
| 54 | # HIDDEN4-NOT: 0000000000000001 *ABS* 00000000 .hidden newsym | |
| 51 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=DONTPROVIDE %s | |
| 55 | 52 | |
| 56 | 53 | # Provide existing symbol. The value should be 0, even though we |
| 57 | 54 | # have value of 1 in PROVIDE() |
deps/lld/test/ELF/linkerscript/thunk-gen-mips.s created+40| ... | ... | @@ -0,0 +1,40 @@ |
| 1 | # REQUIRES: mips | |
| 2 | # RUN:	llvm-mc -filetype=obj -defsym=MAIN=1 -triple=mips-unknown-freebsd %s -o %t | |
| 3 | # RUN:	llvm-mc -filetype=obj -defsym=TARGET=1 -triple=mips-unknown-freebsd %s -o %t1 | |
| 4 | ||
| 5 | # SECTIONS command with the first pattern that does not match. | |
| 6 | # Linking a PIC and non-PIC object files triggers the LA25 thunk generation. | |
| 7 | # RUN:		echo "SECTIONS { \ | |
| 8 | # RUN:		.text : { \ | |
| 9 | # RUN:			*(.nomatch) \ | |
| 10 | # RUN:			%t(.text) \ | |
| 11 | # RUN:			. = . + 0x100000 ; \ | |
| 12 | # RUN:			%t1(.text) \ | |
| 13 | # RUN:		} \ | |
| 14 | # RUN:	}" > %t.script | |
| 15 | # RUN: ld.lld -o %t.exe --script %t.script %t %t1 | |
| 16 | # RUN: llvm-objdump -t %t.exe | FileCheck %s | |
| 17 | # CHECK: SYMBOL TABLE: | |
| 18 | # CHECK-ANY: 00000000 .text 00000000 _start | |
| 19 | # CHECK-ANY: 0010000c l F .text 00000010 __LA25Thunk_too_far | |
| 20 | # CHECK-ANY: 00100020 g F .text 00000024 too_far | |
| 21 | ||
| 22 | .ifdef MAIN | |
| 23 | .global _start | |
| 24 | _start: | |
| 25 | 	j too_far | |
| 26 | 	nop | |
| 27 | .endif | |
| 28 | ||
| 29 | .ifdef TARGET | |
| 30 | 	.text | |
| 31 | 	.abicalls | |
| 32 | 	.set noreorder | |
| 33 | 	.globl too_far | |
| 34 | 	.ent too_far | |
| 35 | too_far: | |
| 36 | 	nop | |
| 37 | 	jr $ra | |
| 38 | 	nop | |
| 39 | 	.end too_far | |
| 40 | .endif |
deps/lld/test/ELF/linkerscript/unused-synthetic.s+10| ... | ... | @@ -13,6 +13,16 @@ |
| 13 | 13 | # CHECK: .text |
| 14 | 14 | # CHECK-NEXT: .dynsym |
| 15 | 15 | |
| 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 | |
| 18 | # the output section, but does not cause the section size to be recomputed. | |
| 19 | # RUN: echo "SECTIONS { \ | |
| 20 | # RUN: .got.plt : { a_sym = .; *(.got.plt) } \ | |
| 21 | # RUN: }" > %t2.script | |
| 22 | # RUN: ld.lld -shared -o %t2.so --script %t2.script %t.o | |
| 23 | # RUN: llvm-objdump -section-headers %t2.so | FileCheck %s --check-prefix=CHECK2 | |
| 24 | # CHECK2: .got.plt 00000000 | |
| 25 | ||
| 16 | 26 | .global _start |
| 17 | 27 | _start: |
| 18 | 28 | nop |
deps/lld/test/ELF/linkerscript/version-linker-symbol.s created+28| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # RUN: echo "VER1 { global: _end; foo ; local: * ; } ;" > %t.script | |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 5 | # RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so | |
| 6 | # RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s | |
| 7 | ||
| 8 | # CHECK: Name: _end@@VER1 | |
| 9 | # CHECK-NEXT: Value: 0 | |
| 10 | # CHECK-NEXT: Size: 0 | |
| 11 | # CHECK-NEXT: Binding: Global | |
| 12 | # CHECK-NEXT: Type: None | |
| 13 | # CHECK-NEXT: Other: 0 | |
| 14 | # CHECK-NEXT: Section: .dynamic | |
| 15 | ||
| 16 | # CHECK: Name: foo@@VER1 | |
| 17 | # CHECK-NEXT: Value: 0 | |
| 18 | # CHECK-NEXT: Size: 0 | |
| 19 | # CHECK-NEXT: Binding: Global | |
| 20 | # CHECK-NEXT: Type: None | |
| 21 | # CHECK-NEXT: Other: 0 | |
| 22 | # CHECK-NEXT: Section: .text | |
| 23 | ||
| 24 | .global foo | |
| 25 | foo: | |
| 26 | .data | |
| 27 | .quad _end | |
| 28 | .quad foo |
deps/lld/test/ELF/lit.local.cfg-1| ... | ... | @@ -1,2 +1 @@ |
| 1 | 1 | config.suffixes = ['.test', '.s', '.ll'] |
| 2 |
deps/lld/test/ELF/local-got-pie.s+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: ld.lld %t.o -o %t -pie | |
| 2 | // RUN: ld.lld --hash-style=sysv %t.o -o %t -pie | |
| 3 | 3 | // RUN: llvm-readobj -s -r -d %t | FileCheck %s |
| 4 | 4 | // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s |
| 5 | 5 |
deps/lld/test/ELF/local-got-shared.s+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: ld.lld %t.o -o %t -shared | |
| 2 | // RUN: ld.lld --hash-style=sysv %t.o -o %t -shared | |
| 3 | 3 | // RUN: llvm-readobj -s -r -d %t | FileCheck %s |
| 4 | 4 | // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s |
| 5 | 5 |
deps/lld/test/ELF/local-got.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | 3 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| 4 | // RUN: ld.lld %t.o %t2.so -o %t | |
| 4 | // RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t | |
| 5 | 5 | // RUN: llvm-readobj -s -r -section-data %t | FileCheck %s |
| 6 | 6 | // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s |
| 7 | 7 |
deps/lld/test/ELF/lto-plugin-ignore.s created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | |
| 4 | # RUN: ld.lld %t -plugin-opt=/foo/bar -plugin-opt=-fresolution=zed \ | |
| 5 | # RUN: -plugin-opt=-pass-through=-lgcc -plugin-opt=-function-sections \ | |
| 6 | # RUN: -plugin-opt=-data-sections -o /dev/null | |
| 7 | ||
| 8 | # RUN: not ld.lld %t -plugin-opt=-data-sectionssss \ | |
| 9 | # RUN: -plugin-opt=-function-sectionsss 2>&1 | FileCheck %s | |
| 10 | # CHECK: unknown option: -data-sectionsss | |
| 11 | # CHECK: unknown option: -function-sectionsss |
deps/lld/test/ELF/lto/Inputs/data-ordering-lto.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-scei-ps4" | |
| 3 | ||
| 4 | @pat = global i32 33, align 4 | |
| 5 | @tin = global i32 33, align 4 | |
| 6 | @dipsy = global i32 33, align 4 |
deps/lld/test/ELF/lto/Inputs/linker-script-symbols-ipo.ll created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 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 i32 @bar() | |
| 5 | ||
| 6 | define i32 @_start() { | |
| 7 | %1 = tail call i32 @bar() | |
| 8 | ret i32 %1 | |
| 9 | } |
deps/lld/test/ELF/lto/Inputs/symbol-ordering-lto.ll created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
| 2 | target triple = "x86_64-scei-ps4" | |
| 3 | ||
| 4 | define i32 @tin() { | |
| 5 | ret i32 22 | |
| 6 | } | |
| 7 | ||
| 8 | define i32 @pat() { | |
| 9 | ret i32 42 | |
| 10 | } |
deps/lld/test/ELF/lto/cache.ll+11-3| ... | ... | @@ -7,7 +7,7 @@ |
| 7 | 7 | ; Create two files that would be removed by cache pruning due to age. |
| 8 | 8 | ; We should only remove files matching the pattern "llvmcache-*". |
| 9 | 9 | ; RUN: touch -t 197001011200 %t.cache/llvmcache-foo %t.cache/foo |
| 10 | ; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=1h -o %t3 %t2.o %t.o | |
| 10 | ; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=1h:prune_interval=0s -o %t3 %t2.o %t.o | |
| 11 | 11 | |
| 12 | 12 | ; Two cached objects, plus a timestamp file and "foo", minus the file we removed. |
| 13 | 13 | ; RUN: ls %t.cache | count 4 |
| ... | ... | @@ -16,13 +16,21 @@ |
| 16 | 16 | ; RUN: %python -c "print(' ' * 65536)" > %t.cache/llvmcache-foo |
| 17 | 17 | |
| 18 | 18 | ; This should leave the file in place. |
| 19 | ; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k -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 | |
| 20 | 20 | ; RUN: ls %t.cache | count 5 |
| 21 | 21 | |
| 22 | 22 | ; This should remove it. |
| 23 | ; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=32k -o %t3 %t2.o %t.o | |
| 23 | ; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=32k:prune_interval=0s -o %t3 %t2.o %t.o | |
| 24 | 24 | ; RUN: ls %t.cache | count 4 |
| 25 | 25 | |
| 26 | ; Setting max number of files to 0 should disable the limit, not delete everything. | |
| 27 | ; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=0s:cache_size=0%:cache_size_files=0:prune_interval=0s -o %t3 %t2.o %t.o | |
| 28 | ; RUN: ls %t.cache | count 4 | |
| 29 | ||
| 30 | ; Delete everything except for the timestamp, "foo" and one cache file. | |
| 31 | ; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=0s:cache_size=0%:cache_size_files=1:prune_interval=0s -o %t3 %t2.o %t.o | |
| 32 | ; RUN: ls %t.cache | count 3 | |
| 33 | ||
| 26 | 34 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 27 | 35 | target triple = "x86_64-unknown-linux-gnu" |
| 28 | 36 |
deps/lld/test/ELF/lto/data-ordering-lto.s created+27| ... | ... | @@ -0,0 +1,27 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-scei-ps4 %s -o %t.o | |
| 3 | # RUN: llvm-as %p/Inputs/data-ordering-lto.ll -o %t.bc | |
| 4 | ||
| 5 | # Set up the symbol file | |
| 6 | # RUN: echo "tin " > %t_order_lto.txt | |
| 7 | # RUN: echo "dipsy " >> %t_order_lto.txt | |
| 8 | # RUN: echo "pat " >> %t_order_lto.txt | |
| 9 | ||
| 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 | |
| 12 | ||
| 13 | # Check that the order is tin -> dipsy -> pat. | |
| 14 | ||
| 15 | # CHECK: Symbol table '.symtab' contains 5 entries: | |
| 16 | # CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name | |
| 17 | # CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND | |
| 18 | # CHECK-NEXT: 1: 0000000000201000 0 NOTYPE GLOBAL DEFAULT 1 _start | |
| 19 | # CHECK-NEXT: 2: 0000000000202004 4 OBJECT GLOBAL DEFAULT 2 dipsy | |
| 20 | # CHECK-NEXT: 3: 0000000000202008 4 OBJECT GLOBAL DEFAULT 2 pat | |
| 21 | # CHECK-NEXT: 4: 0000000000202000 4 OBJECT GLOBAL DEFAULT 2 tin | |
| 22 | ||
| 23 | .globl _start | |
| 24 | _start: | |
| 25 | movl $pat, %ecx | |
| 26 | movl $dipsy, %ebx | |
| 27 | movl $tin, %eax |
deps/lld/test/ELF/lto/keep-undefined.ll created+20| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | ; REQUIRES: x86 | |
| 2 | ; This test checks that symbols which are specified in "-u" switches | |
| 3 | ; are kept over LTO if we link an executable. | |
| 4 | ; RUN: llvm-as %s -o %t.o | |
| 5 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %tout -u foo | |
| 6 | ; RUN: llvm-nm %tout | FileCheck %s | |
| 7 | ||
| 8 | ; CHECK: T foo | |
| 9 | ||
| 10 | target triple = "x86_64-unknown-linux-gnu" | |
| 11 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
| 12 | ||
| 13 | define void @foo() { | |
| 14 | ret void | |
| 15 | } | |
| 16 | ||
| 17 | define void @_start() { | |
| 18 | call void @foo() | |
| 19 | ret void | |
| 20 | } |
deps/lld/test/ELF/lto/linker-script-symbols-assign.ll created+48| ... | ... | @@ -0,0 +1,48 @@ |
| 1 | ; REQUIRES: x86 | |
| 2 | ; RUN: llvm-as %s -o %t.o | |
| 3 | ||
| 4 | ; RUN: echo "foo = 1;" > %t.script | |
| 5 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 --script %t.script -save-temps | |
| 6 | ; RUN: llvm-readobj -symbols %t2.lto.o | FileCheck %s | |
| 7 | ||
| 8 | ; CHECK-NOT: bar | |
| 9 | ; CHECK: Symbol { | |
| 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 | ||
| 20 | ; RUN: llvm-readobj -symbols %t2 | FileCheck %s --check-prefix=VAL | |
| 21 | ; VAL: Symbol { | |
| 22 | ; VAL: Name: foo | |
| 23 | ; VAL-NEXT: Value: 0x1 | |
| 24 | ; VAL-NEXT: Size: | |
| 25 | ; VAL-NEXT: Binding: Global | |
| 26 | ; VAL-NEXT: Type: None | |
| 27 | ; VAL-NEXT: Other: | |
| 28 | ; VAL-NEXT: Section: Absolute | |
| 29 | ; VAL-NEXT: } | |
| 30 | ||
| 31 | ; RUN: echo "zed = 1;" > %t2.script | |
| 32 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t3 --script %t2.script | |
| 33 | ; RUN: llvm-readobj -symbols %t3 | FileCheck %s --check-prefix=ABS | |
| 34 | ; ABS: Symbol { | |
| 35 | ; ABS: Name: zed | |
| 36 | ; ABS-NEXT: Value: 0x1 | |
| 37 | ; ABS-NEXT: Size: 0 | |
| 38 | ; ABS-NEXT: Binding: Global | |
| 39 | ; ABS-NEXT: Type: None | |
| 40 | ; ABS-NEXT: Other: 0 | |
| 41 | ; ABS-NEXT: Section: Absolute | |
| 42 | ; ABS-NEXT: } | |
| 43 | ||
| 44 | target triple = "x86_64-unknown-linux-gnu" | |
| 45 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
| 46 | ||
| 47 | @foo = global i32 0 | |
| 48 | @bar = global i32 0 |
deps/lld/test/ELF/lto/linker-script-symbols-ipo.ll created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | ; REQUIRES: x86 | |
| 2 | ; RUN: llvm-as %s -o %t1.o | |
| 3 | ; RUN: llvm-as %S/Inputs/linker-script-symbols-ipo.ll -o %t2.o | |
| 4 | ; RUN: echo "bar = foo;" > %t.script | |
| 5 | ||
| 6 | ;; Check that without linkerscript bar is inlined. | |
| 7 | ; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t3 -save-temps | |
| 8 | ; RUN: llvm-objdump -d %t3 | FileCheck %s --check-prefix=IPO | |
| 9 | ; IPO: Disassembly of section .text: | |
| 10 | ; IPO: _start: | |
| 11 | ; IPO-NEXT: 201000: {{.*}} movl $1, %eax | |
| 12 | ; IPO-NEXT: 201005: {{.*}} retq | |
| 13 | ||
| 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 | |
| 16 | ; RUN: llvm-objdump -d %t4 | FileCheck %s --check-prefix=NOIPO | |
| 17 | ; NOIPO: Disassembly of section .text: | |
| 18 | ; NOIPO: foo: | |
| 19 | ; NOIPO-NEXT: 201010: {{.*}} movl $2, %eax | |
| 20 | ; NOIPO: _start: | |
| 21 | ; NOIPO-NEXT: 201020: {{.*}} jmp -21 <foo> | |
| 22 | ||
| 23 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
| 24 | target triple = "x86_64-unknown-linux-gnu" | |
| 25 | ||
| 26 | define i32 @bar() { | |
| 27 | ret i32 1 | |
| 28 | } | |
| 29 | ||
| 30 | define i32 @foo() { | |
| 31 | ret i32 2 | |
| 32 | } |
deps/lld/test/ELF/lto/linker-script-symbols.ll created+29| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | ; REQUIRES: x86 | |
| 2 | ; RUN: llvm-as %s -o %t.o | |
| 3 | ; RUN: echo "foo = bar;" > %t.script | |
| 4 | ||
| 5 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 --script %t.script -save-temps | |
| 6 | ; RUN: llvm-readobj -symbols %t2.lto.o | FileCheck %s | |
| 7 | ||
| 8 | ; CHECK-NOT: zed | |
| 9 | ; CHECK: Symbol { | |
| 10 | ; CHECK: Name: bar | |
| 11 | ; CHECK-NEXT: Value: | |
| 12 | ; CHECK-NEXT: Size: | |
| 13 | ; CHECK-NEXT: Binding: Global | |
| 14 | ; CHECK-NEXT: Type: Function | |
| 15 | ; CHECK-NEXT: Other: | |
| 16 | ; CHECK-NEXT: Section: | |
| 17 | ; CHECK-NEXT: } | |
| 18 | ; CHECK-NOT: zed | |
| 19 | ||
| 20 | target triple = "x86_64-unknown-linux-gnu" | |
| 21 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
| 22 | ||
| 23 | define void @bar() { | |
| 24 | ret void | |
| 25 | } | |
| 26 | ||
| 27 | define void @zed() { | |
| 28 | ret void | |
| 29 | } |
deps/lld/test/ELF/lto/opt-level.ll+17-4| ... | ... | @@ -2,18 +2,31 @@ |
| 2 | 2 | ; RUN: llvm-as -o %t.o %s |
| 3 | 3 | ; RUN: ld.lld -o %t0 -m elf_x86_64 -e main --lto-O0 %t.o |
| 4 | 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 | |
| 6 | ; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s | |
| 5 | 7 | ; RUN: ld.lld -o %t2 -m elf_x86_64 -e main --lto-O2 %t.o |
| 6 | 8 | ; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s |
| 7 | 9 | ; RUN: ld.lld -o %t2a -m elf_x86_64 -e main %t.o |
| 8 | 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 | |
| 12 | ; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s | |
| 9 | 13 | |
| 10 | 14 | ; Reject invalid optimization levels. |
| 11 | 15 | ; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O6 %t.o 2>&1 | \ |
| 12 | ; RUN: FileCheck --check-prefix=INVALID %s | |
| 13 | ; INVALID: invalid optimization level for LTO: 6 | |
| 16 | ; RUN: FileCheck --check-prefix=INVALID1 %s | |
| 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 | \ | |
| 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 | \ | |
| 21 | ; RUN: FileCheck --check-prefix=INVALID2 %s | |
| 22 | ; INVALID2: --plugin-opt: number expected, but got 'foo' | |
| 23 | ||
| 14 | 24 | ; 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: -1 | |
| 25 | ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE1 %s | |
| 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 | \ | |
| 28 | ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE2 %s | |
| 29 | ; INVALIDNEGATIVE2: invalid optimization level for LTO: 4294967295 | |
| 17 | 30 | |
| 18 | 31 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 19 | 32 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/lto/opt-remarks.ll+10-15| ... | ... | @@ -15,13 +15,13 @@ |
| 15 | 15 | ; CHECK-NEXT: ret i32 %a.i |
| 16 | 16 | ; CHECK-NEXT: } |
| 17 | 17 | |
| 18 | ; YAML: --- !Analysis | |
| 18 | ; YAML: --- !Passed | |
| 19 | 19 | ; YAML-NEXT: Pass: inline |
| 20 | ; YAML-NEXT: Name: CanBeInlined | |
| 20 | ; YAML-NEXT: Name: Inlined | |
| 21 | 21 | ; YAML-NEXT: Function: main |
| 22 | 22 | ; YAML-NEXT: Args: |
| 23 | 23 | ; YAML-NEXT: - Callee: tinkywinky |
| 24 | ; YAML-NEXT: - String: ' can be inlined into ' | |
| 24 | ; YAML-NEXT: - String: ' inlined into ' | |
| 25 | 25 | ; YAML-NEXT: - Caller: main |
| 26 | 26 | ; YAML-NEXT: - String: ' with cost=' |
| 27 | 27 | ; YAML-NEXT: - Cost: '0' |
| ... | ... | @@ -29,19 +29,9 @@ |
| 29 | 29 | ; YAML-NEXT: - Threshold: '337' |
| 30 | 30 | ; YAML-NEXT: - String: ')' |
| 31 | 31 | ; YAML-NEXT: ... |
| 32 | ; YAML-NEXT: --- !Passed | |
| 33 | ; YAML-NEXT: Pass: inline | |
| 34 | ; YAML-NEXT: Name: Inlined | |
| 35 | ; YAML-NEXT: Function: main | |
| 36 | ; YAML-NEXT: Args: | |
| 37 | ; YAML-NEXT: - Callee: tinkywinky | |
| 38 | ; YAML-NEXT: - String: ' inlined into ' | |
| 39 | ; YAML-NEXT: - Caller: main | |
| 40 | ; YAML-NEXT: ... | |
| 41 | 32 | |
| 42 | ; YAML-HOT: ... | |
| 43 | ; YAML-HOT: --- !Passed | |
| 44 | ; YAML-HOT: Pass: inline | |
| 33 | ; YAML-HOT: --- !Passed | |
| 34 | ; YAML-HOT-NEXT: Pass: inline | |
| 45 | 35 | ; YAML-HOT-NEXT: Name: Inlined |
| 46 | 36 | ; YAML-HOT-NEXT: Function: main |
| 47 | 37 | ; YAML-HOT-NEXT: Hotness: 300 |
| ... | ... | @@ -49,6 +39,11 @@ |
| 49 | 39 | ; YAML-HOT-NEXT: - Callee: tinkywinky |
| 50 | 40 | ; YAML-HOT-NEXT: - String: ' inlined into ' |
| 51 | 41 | ; YAML-HOT-NEXT: - Caller: main |
| 42 | ; YAML-HOT-NEXT: - String: ' with cost=' | |
| 43 | ; YAML-HOT-NEXT: - Cost: '0' | |
| 44 | ; YAML-HOT-NEXT: - String: ' (threshold=' | |
| 45 | ; YAML-HOT-NEXT: - Threshold: '337' | |
| 46 | ; YAML-HOT-NEXT: - String: ')' | |
| 52 | 47 | ; YAML-HOT-NEXT: ... |
| 53 | 48 | |
| 54 | 49 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/ELF/lto/relocatable.ll created+55| ... | ... | @@ -0,0 +1,55 @@ |
| 1 | ; REQUIRES: x86 | |
| 2 | ; RUN: llvm-as %s -o %t1.o | |
| 3 | ; RUN: ld.lld %t1.o -r -o %t | |
| 4 | ; RUN: llvm-readobj -symbols %t | FileCheck %s | |
| 5 | ||
| 6 | ; CHECK: Symbols [ | |
| 7 | ; CHECK-NEXT: Symbol { | |
| 8 | ; CHECK-NEXT: Name: | |
| 9 | ; CHECK-NEXT: Value: 0x0 | |
| 10 | ; CHECK-NEXT: Size: 0 | |
| 11 | ; CHECK-NEXT: Binding: Local | |
| 12 | ; CHECK-NEXT: Type: None | |
| 13 | ; CHECK-NEXT: Other: 0 | |
| 14 | ; CHECK-NEXT: Section: Undefined | |
| 15 | ; CHECK-NEXT: } | |
| 16 | ; CHECK-NEXT: Symbol { | |
| 17 | ; CHECK-NEXT: Name: | |
| 18 | ; CHECK-NEXT: Value: 0x0 | |
| 19 | ; CHECK-NEXT: Size: 0 | |
| 20 | ; CHECK-NEXT: Binding: Local | |
| 21 | ; CHECK-NEXT: Type: Section | |
| 22 | ; CHECK-NEXT: Other: 0 | |
| 23 | ; CHECK-NEXT: Section: .text | |
| 24 | ; CHECK-NEXT: } | |
| 25 | ; CHECK-NEXT: Symbol { | |
| 26 | ; CHECK-NEXT: Name: | |
| 27 | ; CHECK-NEXT: Value: 0x0 | |
| 28 | ; CHECK-NEXT: Size: 0 | |
| 29 | ; CHECK-NEXT: Binding: Local | |
| 30 | ; CHECK-NEXT: Type: Section | |
| 31 | ; CHECK-NEXT: Other: 0 | |
| 32 | ; CHECK-NEXT: Section: .text.foo | |
| 33 | ; CHECK-NEXT: } | |
| 34 | ; CHECK-NEXT: Symbol { | |
| 35 | ; CHECK-NEXT: Name: foo | |
| 36 | ; CHECK-NEXT: Value: 0x0 | |
| 37 | ; CHECK-NEXT: Size: 1 | |
| 38 | ; CHECK-NEXT: Binding: Global | |
| 39 | ; CHECK-NEXT: Type: Function | |
| 40 | ; CHECK-NEXT: Other: 0 | |
| 41 | ; CHECK-NEXT: Section: .text.foo | |
| 42 | ; CHECK-NEXT: } | |
| 43 | ; CHECK-NEXT: ] | |
| 44 | ||
| 45 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
| 46 | target triple = "x86_64-unknown-linux-gnu" | |
| 47 | ||
| 48 | define void @foo() { | |
| 49 | call void @bar() | |
| 50 | ret void | |
| 51 | } | |
| 52 | ||
| 53 | define internal void @bar() { | |
| 54 | ret void | |
| 55 | } |
deps/lld/test/ELF/lto/save-temps.ll+7| ... | ... | @@ -9,6 +9,13 @@ |
| 9 | 9 | ; RUN: llvm-nm a.out.lto.o | FileCheck %s |
| 10 | 10 | ; RUN: llvm-dis a.out.0.0.preopt.bc |
| 11 | 11 | |
| 12 | ; RUN: rm -f a.out a.out.lto.bc a.out.lto.o | |
| 13 | ; RUN: ld.lld -shared -m elf_x86_64 %t.o %t2.o --plugin-opt=save-temps | |
| 14 | ; RUN: llvm-nm a.out | FileCheck %s | |
| 15 | ; RUN: llvm-nm a.out.0.0.preopt.bc | FileCheck %s | |
| 16 | ; RUN: llvm-nm a.out.lto.o | FileCheck %s | |
| 17 | ; RUN: llvm-dis a.out.0.0.preopt.bc | |
| 18 | ||
| 12 | 19 | target triple = "x86_64-unknown-linux-gnu" |
| 13 | 20 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 14 | 21 |
deps/lld/test/ELF/lto/section-name.ll created+35| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | ; REQUIRES: x86 | |
| 2 | ; RUN: llvm-as %s -o %t.o | |
| 3 | ; RUN: ld.lld %t.o -o %t.so -shared | |
| 4 | ; RUN: llvm-readelf -s %t.so | FileCheck %s | |
| 5 | ; RUN: ld.lld %t.o -o %t.so -shared --gc-sections | |
| 6 | ; RUN: llvm-readelf -s %t.so | FileCheck --check-prefix=GC %s | |
| 7 | ||
| 8 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
| 9 | target triple = "x86_64-unknown-linux-gnu" | |
| 10 | ||
| 11 | @foo = hidden global i32 42, section "foo_section" | |
| 12 | @bar = hidden global i32 42, section "bar_section" | |
| 13 | @zed = hidden global i32 42, section "zed_section" | |
| 14 | ||
| 15 | @__start_foo_section = external global i32 | |
| 16 | @__stop_bar_section = external global i32 | |
| 17 | ||
| 18 | define hidden i32* @use1() { | |
| 19 | ret i32* @__start_foo_section | |
| 20 | } | |
| 21 | ||
| 22 | define i32* @use2() { | |
| 23 | ret i32* @__stop_bar_section | |
| 24 | } | |
| 25 | ||
| 26 | ; CHECK-NOT: zed_section | |
| 27 | ; CHECK: foo_section PROGBITS | |
| 28 | ; CHECK-NEXT: bar_section PROGBITS | |
| 29 | ; CHECK-NOT: zed_section | |
| 30 | ||
| 31 | ; GC-NOT: zed_section | |
| 32 | ; GC-NOT: foo_section | |
| 33 | ; GC: bar_section PROGBITS | |
| 34 | ; GC-NOT: zed_section | |
| 35 | ; GC-NOT: foo_section |
deps/lld/test/ELF/lto/shlib-undefined.ll+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | ; REQUIRES: x86 |
| 2 | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: echo .global __progname > %t2.s | |
| 3 | ; RUN: echo ".global __progname; .data; .dc.a __progname" > %t2.s | |
| 4 | 4 | ; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t2.s -o %t2.o |
| 5 | 5 | ; RUN: ld.lld -shared %t2.o -o %t2.so |
| 6 | 6 | ; RUN: ld.lld -o %t %t.o %t2.so |
deps/lld/test/ELF/lto/symbol-ordering-lto.s created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-scei-ps4 %s -o %t.o | |
| 3 | # RUN: llvm-as %p/Inputs/symbol-ordering-lto.ll -o %t.bc | |
| 4 | ||
| 5 | # Set up the symbol file | |
| 6 | # RUN: echo "tin " > %t_order_lto.txt | |
| 7 | # RUN: echo "_start " >> %t_order_lto.txt | |
| 8 | # RUN: echo "pat " >> %t_order_lto.txt | |
| 9 | ||
| 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 | |
| 12 | ||
| 13 | # Check that the order is tin -> _start -> pat. | |
| 14 | ||
| 15 | # CHECK: Symbol table '.symtab' contains 4 entries: | |
| 16 | # CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name | |
| 17 | # CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND | |
| 18 | # CHECK-NEXT: 1: 0000000000201008 0 NOTYPE GLOBAL DEFAULT 1 _start | |
| 19 | # CHECK-NEXT: 2: 0000000000201020 6 FUNC GLOBAL DEFAULT 1 pat | |
| 20 | # CHECK-NEXT: 3: 0000000000201000 6 FUNC GLOBAL DEFAULT 1 tin | |
| 21 | ||
| 22 | .globl _start | |
| 23 | _start: | |
| 24 | call pat | |
| 25 | call tin |
deps/lld/test/ELF/lto/thinlto.ll+4-4| ... | ... | @@ -6,14 +6,14 @@ |
| 6 | 6 | ; First force single-threaded mode |
| 7 | 7 | ; RUN: rm -f %t.lto.o %t1.lto.o |
| 8 | 8 | ; RUN: ld.lld -save-temps --thinlto-jobs=1 -shared %t.o %t2.o -o %t |
| 9 | ; RUN: llvm-nm %t.lto.o | FileCheck %s --check-prefix=NM1 | |
| 10 | ; RUN: llvm-nm %t1.lto.o | FileCheck %s --check-prefix=NM2 | |
| 9 | ; RUN: llvm-nm %t1.lto.o | FileCheck %s --check-prefix=NM1 | |
| 10 | ; RUN: llvm-nm %t2.lto.o | FileCheck %s --check-prefix=NM2 | |
| 11 | 11 | |
| 12 | 12 | ; Next force multi-threaded mode |
| 13 | 13 | ; RUN: rm -f %t2.lto.o %t21.lto.o |
| 14 | 14 | ; RUN: ld.lld -save-temps --thinlto-jobs=2 -shared %t.o %t2.o -o %t2 |
| 15 | ; RUN: llvm-nm %t2.lto.o | FileCheck %s --check-prefix=NM1 | |
| 16 | ; RUN: llvm-nm %t21.lto.o | FileCheck %s --check-prefix=NM2 | |
| 15 | ; RUN: llvm-nm %t21.lto.o | FileCheck %s --check-prefix=NM1 | |
| 16 | ; RUN: llvm-nm %t22.lto.o | FileCheck %s --check-prefix=NM2 | |
| 17 | 17 | |
| 18 | 18 | ; NM1: T f |
| 19 | 19 | ; NM1-NOT: U g |
deps/lld/test/ELF/lto/verify-invalid.ll+2| ... | ... | @@ -4,6 +4,8 @@ |
| 4 | 4 | ; RUN: 2>&1 | FileCheck -check-prefix=DEFAULT %s |
| 5 | 5 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \ |
| 6 | 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 \ | |
| 8 | ; RUN: --plugin-opt=disable-verify 2>&1 | FileCheck -check-prefix=DISABLE %s | |
| 7 | 9 | |
| 8 | 10 | target triple = "x86_64-unknown-linux-gnu" |
| 9 | 11 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/ELF/lto/wrap-1.ll+1-1| ... | ... | @@ -19,7 +19,7 @@ |
| 19 | 19 | |
| 20 | 20 | ; Make sure that the 'r' (linker redefined) bit is set for bar and __wrap_bar |
| 21 | 21 | ; in the resolutions file. |
| 22 | ; RESOLS: ,bar,r | |
| 22 | ; RESOLS: ,bar,xr | |
| 23 | 23 | ; RESOLS: ,__wrap_bar,px |
| 24 | 24 | ; RESOLS: ,__real_bar,pxr |
| 25 | 25 |
deps/lld/test/ELF/lto/wrap-2.ll+2-2| ... | ... | @@ -28,11 +28,11 @@ |
| 28 | 28 | ; THIN-NEXT: jmp{{.*}}<bar> |
| 29 | 29 | |
| 30 | 30 | ; Check that bar and __wrap_bar retain their original binding. |
| 31 | ; BIND: Name: bar | |
| 31 | ; BIND: Name: __wrap_bar | |
| 32 | 32 | ; BIND-NEXT: Value: |
| 33 | 33 | ; BIND-NEXT: Size: |
| 34 | 34 | ; BIND-NEXT: Binding: Local |
| 35 | ; BIND: Name: __wrap_bar | |
| 35 | ; BIND: Name: bar | |
| 36 | 36 | ; BIND-NEXT: Value: |
| 37 | 37 | ; BIND-NEXT: Size: |
| 38 | 38 | ; BIND-NEXT: Binding: Local |
deps/lld/test/ELF/many-alloc-sections.s+1-2| ... | ... | @@ -1,8 +1,7 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t.o |
| 3 | 3 | // RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } }" > %t.script |
| 4 | // FIXME: threads are disable because the test is too slow with them (PR32942). | |
| 5 | // RUN: ld.lld -T %t.script %t.o -o %t --no-threads | |
| 4 | // RUN: ld.lld -T %t.script %t.o -o %t | |
| 6 | 5 | // RUN: llvm-readobj -t %t | FileCheck %s |
| 7 | 6 | |
| 8 | 7 | // Test that _start is in the correct section. |
deps/lld/test/ELF/many-sections.s+2-5| ... | ... | @@ -11,15 +11,12 @@ |
| 11 | 11 | // CHECK-NEXT: Other: 0 |
| 12 | 12 | // CHECK-NEXT: Section: dm (0xFF00) |
| 13 | 13 | |
| 14 | ||
| 15 | // FIXME: threads are disable because the test is too slow with them (PR32942). | |
| 16 | // RUN: ld.lld %t -o %t2 --no-threads | |
| 14 | // RUN: ld.lld %t -o %t2 | |
| 17 | 15 | // RUN: llvm-readobj -t %t2 | FileCheck --check-prefix=LINKED %s |
| 18 | 16 | |
| 19 | 17 | // Test also with a linker script. |
| 20 | 18 | // RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } }" > %t.script |
| 21 | // FIXME: threads are disable because the test is too slow with them (PR32942). | |
| 22 | // RUN: ld.lld -T %t.script %t -o %t2 --no-threads | |
| 19 | // RUN: ld.lld -T %t.script %t -o %t2 | |
| 23 | 20 | // RUN: llvm-readobj -t %t2 | FileCheck --check-prefix=LINKED %s |
| 24 | 21 | |
| 25 | 22 | // Test that _start is in the correct section. |
deps/lld/test/ELF/map-file.s+60-26| ... | ... | @@ -4,15 +4,21 @@ |
| 4 | 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/map-file2.s -o %t2.o |
| 5 | 5 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/map-file3.s -o %t3.o |
| 6 | 6 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/map-file4.s -o %t4.o |
| 7 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/map-file5.s -o %t5.o | |
| 8 | // RUN: ld.lld -shared %t5.o -o %t5.so -soname dso | |
| 7 | 9 | // RUN: rm -f %t4.a |
| 8 | 10 | // RUN: llvm-ar rc %t4.a %t4.o |
| 9 | // RUN: ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -M | FileCheck -strict-whitespace %s | |
| 10 | // RUN: ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -print-map | FileCheck -strict-whitespace %s | |
| 11 | // RUN: ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -Map=%t.map | |
| 11 | // RUN: ld.lld %t1.o %t2.o %t3.o %t4.a %t5.so -o %t -M | FileCheck -strict-whitespace %s | |
| 12 | // RUN: ld.lld %t1.o %t2.o %t3.o %t4.a %t5.so -o %t -print-map | FileCheck -strict-whitespace %s | |
| 13 | // RUN: ld.lld %t1.o %t2.o %t3.o %t4.a %t5.so -o %t -Map=%t.map | |
| 12 | 14 | // RUN: FileCheck -strict-whitespace %s < %t.map |
| 13 | 15 | |
| 14 | 16 | .global _start |
| 15 | 17 | _start: |
| 18 | .quad sharedFoo | |
| 19 | .quad sharedBar | |
| 20 | callq sharedFunc1 | |
| 21 | callq sharedFunc2 | |
| 16 | 22 | call baz |
| 17 | 23 | .global _Z1fi |
| 18 | 24 | _Z1fi: |
| ... | ... | @@ -25,34 +31,62 @@ bar: |
| 25 | 31 | .long zed - . |
| 26 | 32 | local: |
| 27 | 33 | .comm common,4,16 |
| 34 | .global abs | |
| 35 | abs = 0xAB5 | |
| 36 | labs = 0x1AB5 | |
| 28 | 37 | |
| 29 | 38 | // CHECK: Address Size Align Out In Symbol |
| 30 | // CHECK-NEXT: 0000000000200158 0000000000000030 8 .eh_frame | |
| 31 | // CHECK-NEXT: 0000000000200158 0000000000000030 8 <internal>:(.eh_frame) | |
| 32 | // CHECK-NEXT: 0000000000201000 0000000000000015 4 .text | |
| 33 | // CHECK-NEXT: 0000000000201000 000000000000000e 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.text) | |
| 39 | // CHECK-NEXT: 00000000002001c8 0000000000000078 8 .dynsym | |
| 40 | // CHECK-NEXT: 00000000002001c8 0000000000000078 8 <internal>:(.dynsym) | |
| 41 | // CHECK-NEXT: 0000000000200240 000000000000002c 8 .gnu.hash | |
| 42 | // CHECK-NEXT: 0000000000200240 000000000000002c 8 <internal>:(.gnu.hash) | |
| 43 | // CHECK-NEXT: 000000000020026c 0000000000000030 4 .hash | |
| 44 | // CHECK-NEXT: 000000000020026c 0000000000000030 4 <internal>:(.hash) | |
| 45 | // CHECK-NEXT: 000000000020029c 0000000000000031 1 .dynstr | |
| 46 | // CHECK-NEXT: 000000000020029c 0000000000000031 1 <internal>:(.dynstr) | |
| 47 | // CHECK-NEXT: 00000000002002d0 0000000000000030 8 .rela.dyn | |
| 48 | // CHECK-NEXT: 00000000002002d0 0000000000000030 8 <internal>:(.rela.dyn) | |
| 49 | // CHECK-NEXT: 0000000000200300 0000000000000030 8 .rela.plt | |
| 50 | // CHECK-NEXT: 0000000000200300 0000000000000030 8 <internal>:(.rela.plt) | |
| 51 | // CHECK-NEXT: 0000000000200330 0000000000000030 8 .eh_frame | |
| 52 | // CHECK-NEXT: 0000000000200330 0000000000000030 8 <internal>:(.eh_frame) | |
| 53 | // CHECK-NEXT: 0000000000201000 000000000000002d 4 .text | |
| 54 | // CHECK-NEXT: 0000000000201000 0000000000000028 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.text) | |
| 34 | 55 | // CHECK-NEXT: 0000000000201000 0000000000000000 0 _start |
| 35 | // CHECK-NEXT: 0000000000201005 0000000000000000 0 f(int) | |
| 36 | // CHECK-NEXT: 000000000020100e 0000000000000000 0 local | |
| 37 | // CHECK-NEXT: 0000000000201010 0000000000000002 4 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text) | |
| 38 | // CHECK-NEXT: 0000000000201010 0000000000000000 0 foo | |
| 39 | // CHECK-NEXT: 0000000000201011 0000000000000000 0 bar | |
| 40 | // CHECK-NEXT: 0000000000201012 0000000000000000 1 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text.zed) | |
| 41 | // CHECK-NEXT: 0000000000201012 0000000000000000 0 zed | |
| 42 | // CHECK-NEXT: 0000000000201014 0000000000000000 4 {{.*}}{{/|\\}}map-file.s.tmp3.o:(.text) | |
| 43 | // CHECK-NEXT: 0000000000201014 0000000000000000 0 bah | |
| 44 | // CHECK-NEXT: 0000000000201014 0000000000000001 4 {{.*}}{{/|\\}}map-file.s.tmp4.a(map-file.s.tmp4.o):(.text) | |
| 45 | // CHECK-NEXT: 0000000000201014 0000000000000000 0 baz | |
| 46 | // CHECK-NEXT: 0000000000202000 0000000000000004 16 .bss | |
| 47 | // CHECK-NEXT: 0000000000202000 0000000000000004 16 <internal>:(COMMON) | |
| 56 | // CHECK-NEXT: 000000000020101f 0000000000000000 0 f(int) | |
| 57 | // CHECK-NEXT: 0000000000201028 0000000000000000 0 local | |
| 58 | // CHECK-NEXT: 0000000000201028 0000000000000002 4 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text) | |
| 59 | // CHECK-NEXT: 0000000000201028 0000000000000000 0 foo | |
| 60 | // CHECK-NEXT: 0000000000201029 0000000000000000 0 bar | |
| 61 | // CHECK-NEXT: 000000000020102a 0000000000000000 1 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text.zed) | |
| 62 | // CHECK-NEXT: 000000000020102a 0000000000000000 0 zed | |
| 63 | // CHECK-NEXT: 000000000020102c 0000000000000000 4 {{.*}}{{/|\\}}map-file.s.tmp3.o:(.text) | |
| 64 | // CHECK-NEXT: 000000000020102c 0000000000000000 0 bah | |
| 65 | // CHECK-NEXT: 000000000020102c 0000000000000001 4 {{.*}}{{/|\\}}map-file.s.tmp4.a(map-file.s.tmp4.o):(.text) | |
| 66 | // CHECK-NEXT: 000000000020102c 0000000000000000 0 baz | |
| 67 | // CHECK-NEXT: 0000000000201030 0000000000000030 16 .plt | |
| 68 | // CHECK-NEXT: 0000000000201030 0000000000000030 16 <internal>:(.plt) | |
| 69 | // CHECK-NEXT: 0000000000201040 0000000000000000 0 sharedFunc1 | |
| 70 | // CHECK-NEXT: 0000000000201050 0000000000000000 0 sharedFunc2 | |
| 71 | // CHECK-NEXT: 0000000000202000 0000000000000028 8 .got.plt | |
| 72 | // CHECK-NEXT: 0000000000202000 0000000000000028 8 <internal>:(.got.plt) | |
| 73 | // CHECK-NEXT: 0000000000203000 0000000000000100 8 .dynamic | |
| 74 | // CHECK-NEXT: 0000000000203000 0000000000000100 8 <internal>:(.dynamic) | |
| 75 | // CHECK-NEXT: 0000000000204000 0000000000000010 16 .bss | |
| 76 | // CHECK-NEXT: 0000000000204000 0000000000000004 16 {{.*}}{{/|\\}}map-file.s.tmp1.o:(COMMON) | |
| 77 | // CHECK-NEXT: 0000000000204000 0000000000000004 0 common | |
| 78 | // CHECK-NEXT: 0000000000204004 0000000000000004 1 <internal>:(.bss) | |
| 79 | // CHECK-NEXT: 0000000000204004 0000000000000004 0 sharedFoo | |
| 80 | // CHECK-NEXT: 0000000000204008 0000000000000008 1 <internal>:(.bss) | |
| 81 | // CHECK-NEXT: 0000000000204008 0000000000000008 0 sharedBar | |
| 48 | 82 | // CHECK-NEXT: 0000000000000000 0000000000000008 1 .comment |
| 49 | 83 | // CHECK-NEXT: 0000000000000000 0000000000000008 1 <internal>:(.comment) |
| 50 | // CHECK-NEXT: 0000000000000000 00000000000000f0 8 .symtab | |
| 51 | // CHECK-NEXT: 0000000000000000 00000000000000f0 8 <internal>:(.symtab) | |
| 52 | // CHECK-NEXT: 0000000000000000 0000000000000039 1 .shstrtab | |
| 53 | // CHECK-NEXT: 0000000000000000 0000000000000039 1 <internal>:(.shstrtab) | |
| 54 | // CHECK-NEXT: 0000000000000000 000000000000002f 1 .strtab | |
| 55 | // CHECK-NEXT: 0000000000000000 000000000000002f 1 <internal>:(.strtab) | |
| 84 | // CHECK-NEXT: 0000000000000000 0000000000000198 8 .symtab | |
| 85 | // CHECK-NEXT: 0000000000000000 0000000000000198 8 <internal>:(.symtab) | |
| 86 | // CHECK-NEXT: 0000000000000000 0000000000000084 1 .shstrtab | |
| 87 | // CHECK-NEXT: 0000000000000000 0000000000000084 1 <internal>:(.shstrtab) | |
| 88 | // CHECK-NEXT: 0000000000000000 000000000000006d 1 .strtab | |
| 89 | // CHECK-NEXT: 0000000000000000 000000000000006d 1 <internal>:(.strtab) | |
| 56 | 90 | |
| 57 | 91 | // RUN: not ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -Map=/ 2>&1 \ |
| 58 | 92 | // RUN: | FileCheck -check-prefix=FAIL %s |
deps/lld/test/ELF/merge-align.s created+34| ... | ... | @@ -0,0 +1,34 @@ |
| 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.so | FileCheck %s | |
| 5 | ||
| 6 | .section .rodata.foo,"aM",@progbits,1 | |
| 7 | .align 16 | |
| 8 | .byte 0x42 | |
| 9 | ||
| 10 | .section .rodata.bar,"aM",@progbits,1 | |
| 11 | .align 16 | |
| 12 | .byte 0x42 | |
| 13 | ||
| 14 | .section .rodata.zed,"aM",@progbits,1 | |
| 15 | .align 16 | |
| 16 | .byte 0x41 | |
| 17 | ||
| 18 | // CHECK: Name: .rodata ( | |
| 19 | // CHECK-NEXT: Type: SHT_PROGBITS | |
| 20 | // CHECK-NEXT: Flags [ | |
| 21 | // CHECK-NEXT: SHF_ALLOC | |
| 22 | // CHECK-NEXT: SHF_MERGE | |
| 23 | // CHECK-NEXT: ] | |
| 24 | // CHECK-NEXT: Address: | |
| 25 | // CHECK-NEXT: Offset: | |
| 26 | // CHECK-NEXT: Size: 17 | |
| 27 | // CHECK-NEXT: Link: 0 | |
| 28 | // CHECK-NEXT: Info: 0 | |
| 29 | // CHECK-NEXT: AddressAlignment: 16 | |
| 30 | // CHECK-NEXT: EntrySize: 1 | |
| 31 | // CHECK-NEXT: SectionData ( | |
| 32 | // CHECK-NEXT: 0000: 42000000 00000000 00000000 00000000 | | |
| 33 | // CHECK-NEXT: 0010: 41 | | |
| 34 | // CHECK-NEXT: ) |
deps/lld/test/ELF/merge-entsize.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 | |
| 4 | // RUN: llvm-readobj -s %t | FileCheck %s | |
| 5 | ||
| 6 | .section .rodata.1,"aM",@progbits,1 | |
| 7 | .byte 0x42 | |
| 8 | ||
| 9 | .section .rodata.2,"aM",@progbits,2 | |
| 10 | .short 0x42 | |
| 11 | ||
| 12 | // Since the output section has both .rodata.1 and .rodata.2, it | |
| 13 | // contains elements of different sizes and we use an entsize of 0. | |
| 14 | ||
| 15 | // CHECK: Name: .rodata ( | |
| 16 | // CHECK-NEXT: Type: SHT_PROGBITS | |
| 17 | // CHECK-NEXT: Flags [ | |
| 18 | // CHECK-NEXT: SHF_ALLOC | |
| 19 | // CHECK-NEXT: SHF_MERGE | |
| 20 | // CHECK-NEXT: ] | |
| 21 | // CHECK-NEXT: Address: | |
| 22 | // CHECK-NEXT: Offset: | |
| 23 | // CHECK-NEXT: Size: | |
| 24 | // CHECK-NEXT: Link: | |
| 25 | // CHECK-NEXT: Info: | |
| 26 | // CHECK-NEXT: AddressAlignment: | |
| 27 | // CHECK-NEXT: EntrySize: 0 |
deps/lld/test/ELF/merge-reloc.s+9-10| ... | ... | @@ -3,14 +3,13 @@ |
| 3 | 3 | # RUN: ld.lld %t.o -r -o %t-rel |
| 4 | 4 | # RUN: llvm-readobj -s -section-data %t-rel | FileCheck %s |
| 5 | 5 | |
| 6 | # When linker generates a relocatable object it should keep "merge" | |
| 7 | # sections as-is: do not merge content, do not join regular and | |
| 8 | # "merge" sections, do not joint "merge" sections with different | |
| 9 | # entry size. | |
| 6 | # When linker generates a relocatable object it does string merging in the same | |
| 7 | # way as for regular link. It should keep SHF_MERGE flag and set proper sh_entsize | |
| 8 | # value so that final link can perform the final merging optimization. | |
| 10 | 9 | |
| 11 | 10 | # CHECK: Section { |
| 12 | 11 | # CHECK: Index: |
| 13 | # CHECK: Name: .rodata | |
| 12 | # CHECK: Name: .rodata.1 ( | |
| 14 | 13 | # CHECK-NEXT: Type: SHT_PROGBITS |
| 15 | 14 | # CHECK-NEXT: Flags [ |
| 16 | 15 | # CHECK-NEXT: SHF_ALLOC |
| ... | ... | @@ -18,18 +17,18 @@ |
| 18 | 17 | # CHECK-NEXT: ] |
| 19 | 18 | # CHECK-NEXT: Address: |
| 20 | 19 | # CHECK-NEXT: Offset: |
| 21 | # CHECK-NEXT: Size: 12 | |
| 20 | # CHECK-NEXT: Size: 4 | |
| 22 | 21 | # CHECK-NEXT: Link: 0 |
| 23 | 22 | # CHECK-NEXT: Info: 0 |
| 24 | 23 | # CHECK-NEXT: AddressAlignment: 4 |
| 25 | 24 | # CHECK-NEXT: EntrySize: 4 |
| 26 | 25 | # CHECK-NEXT: SectionData ( |
| 27 | # CHECK-NEXT: 0000: 42000000 42000000 42000000 | |
| 26 | # CHECK-NEXT: 0000: 42000000 | |
| 28 | 27 | # CHECK-NEXT: ) |
| 29 | 28 | # CHECK-NEXT: } |
| 30 | 29 | # CHECK: Section { |
| 31 | 30 | # CHECK: Index: |
| 32 | # CHECK: Name: .rodata | |
| 31 | # CHECK: Name: .rodata.2 ( | |
| 33 | 32 | # CHECK-NEXT: Type: SHT_PROGBITS |
| 34 | 33 | # CHECK-NEXT: Flags [ |
| 35 | 34 | # CHECK-NEXT: SHF_ALLOC |
| ... | ... | @@ -37,13 +36,13 @@ |
| 37 | 36 | # CHECK-NEXT: ] |
| 38 | 37 | # CHECK-NEXT: Address: |
| 39 | 38 | # CHECK-NEXT: Offset: |
| 40 | # CHECK-NEXT: Size: 16 | |
| 39 | # CHECK-NEXT: Size: 8 | |
| 41 | 40 | # CHECK-NEXT: Link: 0 |
| 42 | 41 | # CHECK-NEXT: Info: 0 |
| 43 | 42 | # CHECK-NEXT: AddressAlignment: 8 |
| 44 | 43 | # CHECK-NEXT: EntrySize: 8 |
| 45 | 44 | # CHECK-NEXT: SectionData ( |
| 46 | # CHECK-NEXT: 0000: 42000000 42000000 42000000 42000000 | |
| 45 | # CHECK-NEXT: 0000: 42000000 42000000 | |
| 47 | 46 | # CHECK-NEXT: ) |
| 48 | 47 | # CHECK-NEXT: } |
| 49 | 48 | # CHECK: Section { |
deps/lld/test/ELF/merge-string.s+7-7| ... | ... | @@ -1,10 +1,10 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: ld.lld -O2 %t.o -o %t.so -shared | |
| 3 | // RUN: ld.lld -O 2 %t.o -o %t.so -shared | |
| 4 | 4 | // RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s |
| 5 | // RUN: ld.lld -O1 %t.o -o %t.so -shared | |
| 5 | // RUN: ld.lld -O 1 %t.o -o %t.so -shared | |
| 6 | 6 | // RUN: llvm-readobj -s -section-data -t %t.so | FileCheck --check-prefix=NOTAIL %s |
| 7 | // RUN: ld.lld -O0 %t.o -o %t.so -shared | |
| 7 | // RUN: ld.lld -O 0 %t.o -o %t.so -shared | |
| 8 | 8 | // RUN: llvm-readobj -s -section-data -t %t.so | FileCheck --check-prefix=NOMERGE %s |
| 9 | 9 | |
| 10 | 10 | .section	.rodata1,"aMS",@progbits,1 |
| ... | ... | @@ -34,7 +34,7 @@ zed: |
| 34 | 34 | // CHECK-NEXT: Link: 0 |
| 35 | 35 | // CHECK-NEXT: Info: 0 |
| 36 | 36 | // CHECK-NEXT: AddressAlignment: 1 |
| 37 | // CHECK-NEXT: EntrySize: 0 | |
| 37 | // CHECK-NEXT: EntrySize: 1 | |
| 38 | 38 | // CHECK-NEXT: SectionData ( |
| 39 | 39 | // CHECK-NEXT: 0000: 61626300 |abc.| |
| 40 | 40 | // CHECK-NEXT: ) |
| ... | ... | @@ -52,9 +52,9 @@ zed: |
| 52 | 52 | // NOTAIL-NEXT: Link: 0 |
| 53 | 53 | // NOTAIL-NEXT: Info: 0 |
| 54 | 54 | // NOTAIL-NEXT: AddressAlignment: 1 |
| 55 | // NOTAIL-NEXT: EntrySize: 0 | |
| 55 | // NOTAIL-NEXT: EntrySize: 1 | |
| 56 | 56 | // NOTAIL-NEXT: SectionData ( |
| 57 | // NOTAIL-NEXT: 0000: 61626300 626300 |abc.bc.| | |
| 57 | // NOTAIL-NEXT: 0000: 62630061 626300 |bc.abc.| | |
| 58 | 58 | // NOTAIL-NEXT: ) |
| 59 | 59 | |
| 60 | 60 | // NOMERGE: Name: .rodata1 |
| ... | ... | @@ -88,7 +88,7 @@ zed: |
| 88 | 88 | // CHECK-NEXT: Link: 0 |
| 89 | 89 | // CHECK-NEXT: Info: 0 |
| 90 | 90 | // CHECK-NEXT: AddressAlignment: 2 |
| 91 | // CHECK-NEXT: EntrySize: 0 | |
| 91 | // CHECK-NEXT: EntrySize: 2 | |
| 92 | 92 | // CHECK-NEXT: SectionData ( |
| 93 | 93 | // CHECK-NEXT: 0000: 14000000 |....| |
| 94 | 94 | // CHECK-NEXT: ) |
deps/lld/test/ELF/merge.s+1-1| ... | ... | @@ -29,7 +29,7 @@ zed: |
| 29 | 29 | // CHECK-NEXT: Link: 0 |
| 30 | 30 | // CHECK-NEXT: Info: 0 |
| 31 | 31 | // CHECK-NEXT: AddressAlignment: 4 |
| 32 | // CHECK-NEXT: EntrySize: 0 | |
| 32 | // CHECK-NEXT: EntrySize: 4 | |
| 33 | 33 | // CHECK-NEXT: SectionData ( |
| 34 | 34 | // CHECK-NEXT: 0000: 10000000 42000000 |
| 35 | 35 | // CHECK-NEXT: ) |
deps/lld/test/ELF/mips-26-n32-n64.s created+35| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | # Check R_MIPS_26 relocation handling in case of N64 ABIs. | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ | |
| 4 | # RUN: %S/Inputs/mips-dynamic.s -o %t-so.o | |
| 5 | # 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: ld.lld %t.o %t.so -o %t.exe | |
| 8 | # RUN: llvm-objdump -d %t.exe | FileCheck %s | |
| 9 | ||
| 10 | # REQUIRES: mips | |
| 11 | ||
| 12 | # CHECK: Disassembly of section .text: | |
| 13 | # CHECK-NEXT: __start: | |
| 14 | # CHECK-NEXT: 20000: 0c 00 80 0c jal 131120 | |
| 15 | # CHECK-NEXT: 20004: 00 00 00 00 nop | |
| 16 | # CHECK-NEXT: Disassembly of section .plt: | |
| 17 | # CHECK-NEXT: .plt: | |
| 18 | # CHECK-NEXT: 20010: 3c 0e 00 03 lui $14, 3 | |
| 19 | # CHECK-NEXT: 20014: dd d9 00 08 ld $25, 8($14) | |
| 20 | # CHECK-NEXT: 20018: 25 ce 00 08 addiu $14, $14, 8 | |
| 21 | # CHECK-NEXT: 2001c: 03 0e c0 23 subu $24, $24, $14 | |
| 22 | # CHECK-NEXT: 20020: 03 e0 78 25 move $15, $ra | |
| 23 | # CHECK-NEXT: 20024: 00 18 c0 c2 srl $24, $24, 3 | |
| 24 | # CHECK-NEXT: 20028: 03 20 f8 09 jalr $25 | |
| 25 | # CHECK-NEXT: 2002c: 27 18 ff fe addiu $24, $24, -2 | |
| 26 | # CHECK-NEXT: 20030: 3c 0f 00 03 lui $15, 3 | |
| 27 | # CHECK-NEXT: 20034: 8d f9 00 18 lw $25, 24($15) | |
| 28 | # CHECK-NEXT: 20038: 03 20 00 08 jr $25 | |
| 29 | # CHECK-NEXT: 2003c: 25 f8 00 18 addiu $24, $15, 24 | |
| 30 | ||
| 31 | .text | |
| 32 | .option pic0 | |
| 33 | .global __start | |
| 34 | __start: | |
| 35 | jal foo0 |
deps/lld/test/ELF/mips-64-gprel-so.s+1-1| ... | ... | @@ -12,7 +12,7 @@ |
| 12 | 12 | # CHECK-NEXT: 10004: 03 99 e0 2d daddu $gp, $gp, $25 |
| 13 | 13 | # CHECK-NEXT: 10008: 67 9c 7f f0 daddiu $gp, $gp, 32752 |
| 14 | 14 | |
| 15 | # CHECK: 0000000000027ff0 *ABS* 00000000 .hidden _gp | |
| 15 | # CHECK: 0000000000027ff0 .got 00000000 .hidden _gp | |
| 16 | 16 | # CHECK: 0000000000010000 .text 00000000 foo |
| 17 | 17 | |
| 18 | 18 | .text |
deps/lld/test/ELF/mips-64-rels.s+3-3| ... | ... | @@ -20,11 +20,11 @@ |
| 20 | 20 | # ^-- %lo(0x17ff0) |
| 21 | 21 | |
| 22 | 22 | # CHECK: Contents of section .rodata: |
| 23 | # CHECK-NEXT: 10158 ffffffff fffe8014 | |
| 24 | # ^-- 0x20004 - 0x37ff0 = 0xfffffffffffe8014 | |
| 23 | # CHECK-NEXT: {{[0-9a-f]+}} ffffffff fffe8014 | |
| 24 | # ^-- 0x20004 - 0x37ff0 = 0xfffffffffffe8014 | |
| 25 | 25 | |
| 26 | 26 | # CHECK: 0000000000020004 .text 00000000 loc |
| 27 | # CHECK: 0000000000037ff0 *ABS* 00000000 .hidden _gp | |
| 27 | # CHECK: 0000000000037ff0 .got 00000000 .hidden _gp | |
| 28 | 28 | # CHECK: 0000000000020000 .text 00000000 __start |
| 29 | 29 | |
| 30 | 30 | # REL: Relocations [ |
deps/lld/test/ELF/mips-align-err.s+1-1| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ |
| 5 | 5 | # RUN: -mcpu=mips32r6 %S/Inputs/mips-align-err.s -o %t2.o |
| 6 | 6 | # RUN: not ld.lld %t.o %t2.o -o %t.exe 2>&1 | FileCheck %s |
| 7 | # CHECK: {{.*}}:(.text+0x1): improper alignment for relocation R_MIPS_PC16 | |
| 7 | # CHECK: {{.*}}:(.text+0x1): improper alignment for relocation R_MIPS_PC16: 0xB is not aligned to 4 bytes | |
| 8 | 8 | |
| 9 | 9 | .globl __start |
| 10 | 10 | __start: |
deps/lld/test/ELF/mips-elf-flags-err.s+8-2| ... | ... | @@ -71,8 +71,14 @@ __start: |
| 71 | 71 | # R1R2-NEXT: EF_MIPS_CPIC |
| 72 | 72 | # R1R2-NEXT: ] |
| 73 | 73 | |
| 74 | # R3R32: target ISA 'mips3' is incompatible with 'mips32': {{.*}}mips-elf-flags-err.s.tmp2.o | |
| 75 | # R6OCTEON: target ISA 'mips64r6' is incompatible with 'octeon': {{.*}}mips-elf-flags-err.s.tmp2.o | |
| 74 | # R3R32: error: incompatible target ISA: | |
| 75 | # R3R32-NEXT: >>> {{.+}}mips-elf-flags-err.s.tmp1.o: mips3 | |
| 76 | # R3R32-NEXT: >>> {{.+}}mips-elf-flags-err.s.tmp2.o: mips32 | |
| 77 | ||
| 78 | # R6OCTEON: error: incompatible target ISA: | |
| 79 | # R6OCTEON-NEXT: >>> {{.+}}mips-elf-flags-err.s.tmp1.o: mips64r6 | |
| 80 | # R6OCTEON-NEXT: >>> {{.+}}mips-elf-flags-err.s.tmp2.o: mips64r2 (octeon) | |
| 81 | ||
| 76 | 82 | # FPABI: target floating point ABI '-mdouble-float' is incompatible with '-mgp32 -mfp64': {{.*}}mips-elf-flags-err.s.tmp2.o |
| 77 | 83 | |
| 78 | 84 | # OCTEON: Flags [ |
deps/lld/test/ELF/mips-elf-flags.s+29| ... | ... | @@ -35,6 +35,12 @@ |
| 35 | 35 | # RUN: llvm-readobj -h -mips-abi-flags %t.exe \ |
| 36 | 36 | # RUN: | FileCheck -check-prefix=OCTEON %s |
| 37 | 37 | |
| 38 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | |
| 39 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | |
| 40 | # RUN: -mattr=micromips %S/Inputs/mips-fpic.s -o %t-mm.o | |
| 41 | # 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 | ||
| 38 | 44 | # REQUIRES: mips |
| 39 | 45 | |
| 40 | 46 | .text |
| ... | ... | @@ -170,3 +176,26 @@ __start: |
| 170 | 176 | # OCTEON-NEXT: ] |
| 171 | 177 | # OCTEON-NEXT: Flags 2: 0x0 |
| 172 | 178 | # OCTEON-NEXT: } |
| 179 | ||
| 180 | # MICRO: Flags [ | |
| 181 | # MICRO-NEXT: EF_MIPS_ABI_O32 | |
| 182 | # MICRO-NEXT: EF_MIPS_ARCH_32 | |
| 183 | # MICRO-NEXT: EF_MIPS_CPIC | |
| 184 | # MICRO-NEXT: EF_MIPS_MICROMIPS | |
| 185 | # MICRO-NEXT: ] | |
| 186 | # MICRO: MIPS ABI Flags { | |
| 187 | # MICRO-NEXT: Version: 0 | |
| 188 | # MICRO-NEXT: ISA: MIPS32 | |
| 189 | # MICRO-NEXT: ISA Extension: None | |
| 190 | # MICRO-NEXT: ASEs [ | |
| 191 | # MICRO-NEXT: microMIPS | |
| 192 | # MICRO-NEXT: ] | |
| 193 | # MICRO-NEXT: FP ABI: Hard float (double precision) | |
| 194 | # MICRO-NEXT: GPR size: 32 | |
| 195 | # MICRO-NEXT: CPR1 size: 32 | |
| 196 | # MICRO-NEXT: CPR2 size: 0 | |
| 197 | # MICRO-NEXT: Flags 1 [ | |
| 198 | # MICRO-NEXT: ODDSPREG | |
| 199 | # MICRO-NEXT: ] | |
| 200 | # MICRO-NEXT: Flags 2: 0x0 | |
| 201 | # MICRO-NEXT: } |
deps/lld/test/ELF/mips-got-page-script.s created+65| ... | ... | @@ -0,0 +1,65 @@ |
| 1 | # Check calculation of MIPS GOT page address entries number | |
| 2 | # when a linker script is provided. | |
| 3 | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -o %t.o %s | |
| 5 | # RUN: echo "SECTIONS { \ | |
| 6 | # RUN: .text : { *(.text) } \ | |
| 7 | # RUN: .data 0x10000 : { *(.data) } }" > %t.script | |
| 8 | # 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 | ||
| 11 | # REQUIRES: mips | |
| 12 | ||
| 13 | # CHECK: Name: foo1 | |
| 14 | # CHECK-NEXT: Value: 0x10000 | |
| 15 | # CHECK: Name: foo2 | |
| 16 | # CHECK-NEXT: Value: 0x20000 | |
| 17 | # CHECK: Name: foo3 | |
| 18 | # CHECK-NEXT: Value: 0x30000 | |
| 19 | # CHECK: Name: foo4 | |
| 20 | # CHECK-NEXT: Value: 0x40000 | |
| 21 | ||
| 22 | # CHECK: Local entries [ | |
| 23 | # CHECK-BEXT: Entry { | |
| 24 | # CHECK-BEXT: Address: | |
| 25 | # CHECK-BEXT: Access: | |
| 26 | # CHECK-BEXT: Initial: 0x10000 | |
| 27 | # CHECK-BEXT: } | |
| 28 | # CHECK-BEXT: Entry { | |
| 29 | # CHECK-BEXT: Address: | |
| 30 | # CHECK-BEXT: Access: | |
| 31 | # CHECK-BEXT: Initial: 0x20000 | |
| 32 | # CHECK-BEXT: } | |
| 33 | # CHECK-BEXT: Entry { | |
| 34 | # CHECK-BEXT: Address: | |
| 35 | # CHECK-BEXT: Access: | |
| 36 | # CHECK-BEXT: Initial: 0x30000 | |
| 37 | # CHECK-BEXT: } | |
| 38 | # CHECK-BEXT: Entry { | |
| 39 | # CHECK-BEXT: Address: | |
| 40 | # CHECK-BEXT: Access: | |
| 41 | # CHECK-BEXT: Initial: 0x40000 | |
| 42 | # CHECK-BEXT: } | |
| 43 | # CHECK-BEXT: Entry { | |
| 44 | # CHECK-BEXT: Address: | |
| 45 | # CHECK-BEXT: Access: | |
| 46 | # CHECK-BEXT: Initial: 0x50000 | |
| 47 | # CHECK-BEXT: } | |
| 48 | # CHECK-BEXT: ] | |
| 49 | ||
| 50 | .option pic2 | |
| 51 | .text | |
| 52 | ld $v0,%got_page(foo1)($gp) | |
| 53 | ld $v0,%got_page(foo2)($gp) | |
| 54 | ld $v0,%got_page(foo3)($gp) | |
| 55 | ld $v0,%got_page(foo4)($gp) | |
| 56 | ||
| 57 | .data | |
| 58 | foo1: | |
| 59 | .space 0x10000 | |
| 60 | foo2: | |
| 61 | .space 0x10000 | |
| 62 | foo3: | |
| 63 | .space 0x10000 | |
| 64 | foo4: | |
| 65 | .word 0 |
deps/lld/test/ELF/mips-got-relocs.s+2-2| ... | ... | @@ -47,7 +47,7 @@ v1: |
| 47 | 47 | # EXE_SYM: Sections: |
| 48 | 48 | # EXE_SYM: .got 0000000c 0000000000030010 DATA |
| 49 | 49 | # EXE_SYM: SYMBOL TABLE: |
| 50 | # EXE_SYM: 00038000 *ABS* 00000000 .hidden _gp | |
| 50 | # EXE_SYM: 00038000 .got 00000000 .hidden _gp | |
| 51 | 51 | # ^-- .got + GP offset (0x7ff0) |
| 52 | 52 | # EXE_SYM: 00030000 g .data		 00000004 v1 |
| 53 | 53 | |
| ... | ... | @@ -71,7 +71,7 @@ v1: |
| 71 | 71 | # DSO_SYM: Sections: |
| 72 | 72 | # DSO_SYM: .got 0000000c 0000000000020010 DATA |
| 73 | 73 | # DSO_SYM: SYMBOL TABLE: |
| 74 | # DSO_SYM: 00028000 *ABS* 00000000 .hidden _gp | |
| 74 | # DSO_SYM: 00028000 .got 00000000 .hidden _gp | |
| 75 | 75 | # ^-- .got + GP offset (0x7ff0) |
| 76 | 76 | # DSO_SYM: 00020000 g .data		 00000004 v1 |
| 77 | 77 |
deps/lld/test/ELF/mips-got-script.s created+47| ... | ... | @@ -0,0 +1,47 @@ |
| 1 | # Check number of got entries is adjusted for linker script-added space. | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | |
| 4 | # RUN: echo "SECTIONS { .data : { *(.data.1); . += 0x10000; *(.data.2) } }" > %t.script | |
| 5 | # 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 | ||
| 8 | # REQUIRES: mips | |
| 9 | ||
| 10 | # CHECK: 0x7000000A MIPS_LOCAL_GOTNO 5 | |
| 11 | # ^-- 2 * header + 3 local entries | |
| 12 | # CHECK: Local entries [ | |
| 13 | # CHECK-NEXT: Entry { | |
| 14 | # CHECK-NEXT: Address: | |
| 15 | # CHECK-NEXT: Access: -32744 | |
| 16 | # CHECK-NEXT: Initial: 0x0 | |
| 17 | # ^-- loc1 | |
| 18 | # CHECK-NEXT: } | |
| 19 | # CHECK-NEXT: Entry { | |
| 20 | # CHECK-NEXT: Address: | |
| 21 | # CHECK-NEXT: Access: -32740 | |
| 22 | # CHECK-NEXT: Initial: 0x10000 | |
| 23 | # ^-- loc2 | |
| 24 | # 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: ] | |
| 32 | ||
| 33 | .text | |
| 34 | .globl foo | |
| 35 | foo: | |
| 36 | lw $t0, %got(loc1)($gp) | |
| 37 | addi $t0, $t0, %lo(loc1) | |
| 38 | lw $t0, %got(loc2)($gp) | |
| 39 | addi $t0, $t0, %lo(loc2) | |
| 40 | ||
| 41 | .section .data.1,"aw",%progbits | |
| 42 | loc1: | |
| 43 | .word 0 | |
| 44 | ||
| 45 | .section .data.2,"aw",%progbits | |
| 46 | loc2: | |
| 47 | .word 0 |
deps/lld/test/ELF/mips-gp-disp-ver.s created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | # 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 | # while _gp_disp is a section global symbol. We have to handle this bug | |
| 4 | # in the LLD because BFD linker is used for building MIPS toolchain | |
| 5 | # libraries. This test checks such handling. | |
| 6 | ||
| 7 | # 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 | ||
| 10 | # REQUIRES: mips | |
| 11 | ||
| 12 | .global __start | |
| 13 | .text | |
| 14 | __start: | |
| 15 | lw $t0, %got(foo)($gp) |
deps/lld/test/ELF/mips-gp-disp.s+1-1| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | # DIS-NEXT: 10000: 3c 08 00 01 lui $8, 1 |
| 25 | 25 | # DIS-NEXT: 10004: 21 08 7f f0 addi $8, $8, 32752 |
| 26 | 26 | # ^-- 0x37ff0 & 0xffff |
| 27 | # DIS: 00027ff0 *ABS* 00000000 .hidden _gp | |
| 27 | # DIS: 00027ff0 .got 00000000 .hidden _gp | |
| 28 | 28 | |
| 29 | 29 | # REL: Relocations [ |
| 30 | 30 | # REL-NEXT: ] |
deps/lld/test/ELF/mips-gp-ext.s+7| ... | ... | @@ -10,6 +10,13 @@ |
| 10 | 10 | # RUN: ld.lld -shared -o %t.rel.so --script %t.rel.script %t.o |
| 11 | 11 | # RUN: llvm-objdump -s -t %t.rel.so | FileCheck --check-prefix=REL %s |
| 12 | 12 | |
| 13 | # RUN: echo "SECTIONS { \ | |
| 14 | # RUN: .text : { *(.text) } \ | |
| 15 | # RUN: _gp = 0x100 + ABSOLUTE(.); \ | |
| 16 | # RUN: .got : { *(.got) } }" > %t.rel.script | |
| 17 | # RUN: ld.lld -shared -o %t.rel.so --script %t.rel.script %t.o | |
| 18 | # RUN: llvm-objdump -s -t %t.rel.so | FileCheck --check-prefix=REL %s | |
| 19 | ||
| 13 | 20 | # RUN: echo "SECTIONS { \ |
| 14 | 21 | # RUN: .text : { *(.text) } \ |
| 15 | 22 | # RUN: _gp = 0x200; \ |
deps/lld/test/ELF/mips-gp-local.s+1-1| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | # CHECK-NEXT: 20000: 3c 08 00 03 lui $8, 3 |
| 12 | 12 | # CHECK-NEXT: 20004: 21 08 7f f0 addi $8, $8, 32752 |
| 13 | 13 | |
| 14 | # CHECK: 00037ff0 *ABS* 00000000 .hidden _gp | |
| 14 | # CHECK: 00037ff0 .got 00000000 .hidden _gp | |
| 15 | 15 | |
| 16 | 16 | .text |
| 17 | 17 | .globl __start |
deps/lld/test/ELF/mips-gprel32-relocs-gp0.s+4-4| ... | ... | @@ -22,14 +22,14 @@ |
| 22 | 22 | # DSO: GP: 0x27FF0 |
| 23 | 23 | |
| 24 | 24 | # DUMP: Contents of section .rodata: |
| 25 | # DUMP: 00f4 ffff0004 ffff0008 | |
| 26 | # ^ 0x10004 + 0x7ff0 - 0x27ff0 | |
| 27 | # ^ 0x10008 + 0x7ff0 - 0x27ff0 | |
| 25 | # DUMP: {{[0-9a-f]+}} ffff0004 ffff0008 | |
| 26 | # ^ 0x10004 + 0x7ff0 - 0x27ff0 | |
| 27 | # ^ 0x10008 + 0x7ff0 - 0x27ff0 | |
| 28 | 28 | |
| 29 | 29 | # DUMP: SYMBOL TABLE: |
| 30 | 30 | # DUMP: 00010008 .text 00000000 bar |
| 31 | 31 | # DUMP: 00010004 .text 00000000 foo |
| 32 | # DUMP: 00027ff0 *ABS* 00000000 .hidden _gp | |
| 32 | # DUMP: 00027ff0 .got 00000000 .hidden _gp | |
| 33 | 33 | |
| 34 | 34 | # ERR: error: {{.*}}mips-gp0-non-zero.o: unsupported non-zero ri_gp_value |
| 35 | 35 |
deps/lld/test/ELF/mips-gprel32-relocs.s+4-4| ... | ... | @@ -21,11 +21,11 @@ v1: |
| 21 | 21 | .gpword bar |
| 22 | 22 | |
| 23 | 23 | # CHECK: Contents of section .rodata: |
| 24 | # CHECK: 00f4 fffe8014 fffe8018 | |
| 25 | # ^ 0x10004 - 0x27ff0 | |
| 26 | # ^ 0x10008 - 0x27ff0 | |
| 24 | # CHECK: {{[0-9a-f]+}} fffe8014 fffe8018 | |
| 25 | # ^ 0x10004 - 0x27ff0 | |
| 26 | # ^ 0x10008 - 0x27ff0 | |
| 27 | 27 | |
| 28 | 28 | # CHECK: SYMBOL TABLE: |
| 29 | 29 | # CHECK: 00010008 .text 00000000 bar |
| 30 | 30 | # CHECK: 00010004 .text 00000000 foo |
| 31 | # CHECK: 00027ff0 *ABS* 00000000 .hidden _gp | |
| 31 | # CHECK: 00027ff0 .got 00000000 .hidden _gp |
deps/lld/test/ELF/mips-hilo-gp-disp.s+2-2| ... | ... | @@ -34,7 +34,7 @@ bar: |
| 34 | 34 | |
| 35 | 35 | # EXE: SYMBOL TABLE: |
| 36 | 36 | # EXE: 0002000c .text 00000000 bar |
| 37 | # EXE: 00038000 *ABS* 00000000 .hidden _gp | |
| 37 | # EXE: 00038000 .got 00000000 .hidden _gp | |
| 38 | 38 | # EXE: 00020000 .text 00000000 __start |
| 39 | 39 | |
| 40 | 40 | # SO: Disassembly of section .text: |
| ... | ... | @@ -51,5 +51,5 @@ bar: |
| 51 | 51 | |
| 52 | 52 | # SO: SYMBOL TABLE: |
| 53 | 53 | # SO: 0001000c .text 00000000 bar |
| 54 | # SO: 00028000 *ABS* 00000000 .hidden _gp | |
| 54 | # SO: 00028000 .got 00000000 .hidden _gp | |
| 55 | 55 | # SO: 00010000 .text 00000000 __start |
deps/lld/test/ELF/mips-hilo-hi-only.s+1-1| ... | ... | @@ -18,7 +18,7 @@ _label: |
| 18 | 18 | |
| 19 | 19 | # CHECK: Disassembly of section .text: |
| 20 | 20 | # CHECK-NEXT: __start: |
| 21 | # CHECK-NEXT: 20000: 3c 08 00 02 lui $8, 2 | |
| 21 | # CHECK-NEXT: 20000: 3c 08 00 03 lui $8, 3 | |
| 22 | 22 | # ^-- %hi(__start) w/o addend |
| 23 | 23 | # CHECK-NEXT 20004: 21 08 00 08 addi $8, $8, 8 |
| 24 | 24 | # ^-- %lo(_label) |
deps/lld/test/ELF/mips-micro-got.s created+46| ... | ... | @@ -0,0 +1,46 @@ |
| 1 | # Check microMIPS GOT relocations for O32 ABI. | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -mattr=micromips \ | |
| 4 | # RUN: %s -o %t1.o | |
| 5 | # RUN: llvm-mc -filetype=obj -triple=mips-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: -32744 | |
| 17 | # CHECK-NEXT: Initial: 0x30000 | |
| 18 | # CHECK-NEXT: } | |
| 19 | # CHECK-NEXT: Entry { | |
| 20 | # CHECK-NEXT: Address: | |
| 21 | # CHECK-NEXT: Access: -32740 | |
| 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: -32736 | |
| 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 | lw $4, %got(data)($28) | |
| 41 | addiu $4, $4, %lo(data) | |
| 42 | lw $25, %call16(foo0)($28) | |
| 43 | ||
| 44 | .data | |
| 45 | data: | |
| 46 | .word 0 |
deps/lld/test/ELF/mips-micro-got64.s created+48| ... | ... | @@ -0,0 +1,48 @@ |
| 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 created+155| ... | ... | @@ -0,0 +1,155 @@ |
| 1 | # Check PLT creation for microMIPS to microMIPS calls. | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | |
| 4 | # RUN: -mattr=micromips %S/Inputs/mips-micro.s -o %t1eb.o | |
| 5 | # RUN: ld.lld -shared -o %teb.so %t1eb.o | |
| 6 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | |
| 7 | # RUN: -mattr=micromips %s -o %t2eb.o | |
| 8 | # RUN: ld.lld -o %teb.exe %t2eb.o %teb.so | |
| 9 | # RUN: llvm-objdump -d -mattr=micromips %teb.exe | FileCheck --check-prefix=EB %s | |
| 10 | # RUN: llvm-readobj -mips-plt-got %teb.exe | FileCheck --check-prefix=PLT %s | |
| 11 | ||
| 12 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ | |
| 13 | # RUN: -mattr=micromips %S/Inputs/mips-micro.s -o %t1el.o | |
| 14 | # RUN: ld.lld -shared -o %tel.so %t1el.o | |
| 15 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ | |
| 16 | # RUN: -mattr=micromips %s -o %t2el.o | |
| 17 | # RUN: ld.lld -o %tel.exe %t2el.o %tel.so | |
| 18 | # RUN: llvm-objdump -d -mattr=micromips %tel.exe | FileCheck --check-prefix=EL %s | |
| 19 | # RUN: llvm-readobj -mips-plt-got %tel.exe | FileCheck --check-prefix=PLT %s | |
| 20 | ||
| 21 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | |
| 22 | # RUN: -mattr=micromips -mcpu=mips32r6 %S/Inputs/mips-micro.s -o %t1eb.o | |
| 23 | # RUN: ld.lld -shared -o %teb.so %t1eb.o | |
| 24 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | |
| 25 | # RUN: -mattr=micromips -mcpu=mips32r6 %s -o %t2eb.o | |
| 26 | # RUN: ld.lld -o %teb.exe %t2eb.o %teb.so | |
| 27 | # RUN: llvm-objdump -d -mattr=micromips %teb.exe | FileCheck --check-prefix=EBR6 %s | |
| 28 | ||
| 29 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ | |
| 30 | # RUN: -mattr=micromips -mcpu=mips32r6 %S/Inputs/mips-micro.s -o %t1el.o | |
| 31 | # RUN: ld.lld -shared -o %tel.so %t1el.o | |
| 32 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ | |
| 33 | # RUN: -mattr=micromips -mcpu=mips32r6 %s -o %t2el.o | |
| 34 | # RUN: ld.lld -o %tel.exe %t2el.o %tel.so | |
| 35 | # RUN: llvm-objdump -d -mattr=micromips %tel.exe | FileCheck --check-prefix=ELR6 %s | |
| 36 | ||
| 37 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | |
| 38 | # RUN: -mattr=micromips %S/Inputs/mips-micro.s -o %t1eb.o | |
| 39 | # RUN: ld.lld -shared -o %teb.so %t1eb.o | |
| 40 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | |
| 41 | # RUN: %S/Inputs/mips-fpic.s -o %t-reg.o | |
| 42 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | |
| 43 | # RUN: -mattr=micromips %s -o %t2eb.o | |
| 44 | # RUN: ld.lld --no-threads -o %teb.exe %t-reg.o %t2eb.o %teb.so | |
| 45 | # RUN: llvm-objdump -d -mattr=micromips %teb.exe \ | |
| 46 | # RUN: | FileCheck --check-prefix=MIXED %s | |
| 47 | ||
| 48 | # REQUIRES: mips | |
| 49 | ||
| 50 | # EB: Disassembly of section .plt: | |
| 51 | # EB-NEXT: .plt: | |
| 52 | # EB-NEXT: 20010: 79 80 3f fd addiupc $3, 65524 | |
| 53 | # EB-NEXT: 20014: ff 23 00 00 lw $25, 0($3) | |
| 54 | # EB-NEXT: 20018: 05 35 subu16 $2, $2, $3 | |
| 55 | # EB-NEXT: 2001a: 25 25 srl16 $2, $2, 2 | |
| 56 | # EB-NEXT: 2001c: 33 02 ff fe addiu $24, $2, -2 | |
| 57 | # EB-NEXT: 20020: 0d ff move $15, $ra | |
| 58 | # EB-NEXT: 20022: 45 f9 jalrs16 $25 | |
| 59 | # EB-NEXT: 20024: 0f 83 move $gp, $3 | |
| 60 | # EB-NEXT: 20026: 0c 00 nop | |
| 61 | # EB-NEXT: 20028: 00 00 00 00 nop | |
| 62 | # EB-NEXT: 2002c: 00 00 00 00 nop | |
| 63 | ||
| 64 | # EB-NEXT: 20030: 79 00 3f f7 addiupc $2, 65500 | |
| 65 | # EB-NEXT: 20034: ff 22 00 00 lw $25, 0($2) | |
| 66 | # EB-NEXT: 20038: 45 99 jr16 $25 | |
| 67 | # EB-NEXT: 2003a: 0f 02 move $24, $2 | |
| 68 | ||
| 69 | # EL: Disassembly of section .plt: | |
| 70 | # EL-NEXT: .plt: | |
| 71 | # EL-NEXT: 20010: 80 79 fd 3f addiupc $3, 65524 | |
| 72 | # EL-NEXT: 20014: 23 ff 00 00 lw $25, 0($3) | |
| 73 | # EL-NEXT: 20018: 35 05 subu16 $2, $2, $3 | |
| 74 | # EL-NEXT: 2001a: 25 25 srl16 $2, $2, 2 | |
| 75 | # EL-NEXT: 2001c: 02 33 fe ff addiu $24, $2, -2 | |
| 76 | # EL-NEXT: 20020: ff 0d move $15, $ra | |
| 77 | # EL-NEXT: 20022: f9 45 jalrs16 $25 | |
| 78 | # EL-NEXT: 20024: 83 0f move $gp, $3 | |
| 79 | # EL-NEXT: 20026: 00 0c nop | |
| 80 | # EL-NEXT: 20028: 00 00 00 00 nop | |
| 81 | # EL-NEXT: 2002c: 00 00 00 00 nop | |
| 82 | ||
| 83 | # EL-NEXT: 20030: 00 79 f7 3f addiupc $2, 65500 | |
| 84 | # EL-NEXT: 20034: 22 ff 00 00 lw $25, 0($2) | |
| 85 | # EL-NEXT: 20038: 99 45 jr16 $25 | |
| 86 | # EL-NEXT: 2003a: 02 0f move $24, $2 | |
| 87 | ||
| 88 | # EBR6: Disassembly of section .plt: | |
| 89 | # EBR6-NEXT: .plt: | |
| 90 | # EBR6-NEXT: 20010: 78 60 3f fd lapc $3, 65524 | |
| 91 | # EBR6-NEXT: 20014: ff 23 00 00 lw $25, 0($3) | |
| 92 | # EBR6-NEXT: 20018: 05 35 subu16 $2, $2, $3 | |
| 93 | # EBR6-NEXT: 2001a: 25 25 srl16 $2, $2, 2 | |
| 94 | # EBR6-NEXT: 2001c: 33 02 ff fe addiu $24, $2, -2 | |
| 95 | # EBR6-NEXT: 20020: 0d ff move16 $15, $ra | |
| 96 | # EBR6-NEXT: 20022: 0f 83 move16 $gp, $3 | |
| 97 | # EBR6-NEXT: 20024: 47 2b jalr $25 | |
| 98 | ||
| 99 | # EBR6: 20030: 78 40 3f f7 lapc $2, 65500 | |
| 100 | # EBR6-NEXT: 20034: ff 22 00 00 lw $25, 0($2) | |
| 101 | # EBR6-NEXT: 20038: 0f 02 move16 $24, $2 | |
| 102 | # EBR6-NEXT: 2003a: 47 23 jrc16 $25 | |
| 103 | ||
| 104 | # ELR6: Disassembly of section .plt: | |
| 105 | # ELR6-NEXT: .plt: | |
| 106 | # ELR6-NEXT: 20010: 60 78 fd 3f lapc $3, 65524 | |
| 107 | # ELR6-NEXT: 20014: 23 ff 00 00 lw $25, 0($3) | |
| 108 | # ELR6-NEXT: 20018: 35 05 subu16 $2, $2, $3 | |
| 109 | # ELR6-NEXT: 2001a: 25 25 srl16 $2, $2, 2 | |
| 110 | # ELR6-NEXT: 2001c: 02 33 fe ff addiu $24, $2, -2 | |
| 111 | # ELR6-NEXT: 20020: ff 0d move16 $15, $ra | |
| 112 | # ELR6-NEXT: 20022: 83 0f move16 $gp, $3 | |
| 113 | # ELR6-NEXT: 20024: 2b 47 jalr $25 | |
| 114 | ||
| 115 | # ELR6: 20030: 40 78 f7 3f lapc $2, 65500 | |
| 116 | # ELR6-NEXT: 20034: 22 ff 00 00 lw $25, 0($2) | |
| 117 | # ELR6-NEXT: 20038: 02 0f move16 $24, $2 | |
| 118 | # ELR6-NEXT: 2003a: 23 47 jrc16 $25 | |
| 119 | ||
| 120 | # MIXED: Disassembly of section .plt: | |
| 121 | # MIXED-NEXT: .plt: | |
| 122 | # MIXED-NEXT: 20020: 79 80 3f f9 addiupc $3, 65508 | |
| 123 | # MIXED-NEXT: 20024: ff 23 00 00 lw $25, 0($3) | |
| 124 | # MIXED-NEXT: 20028: 05 35 subu16 $2, $2, $3 | |
| 125 | # MIXED-NEXT: 2002a: 25 25 srl16 $2, $2, 2 | |
| 126 | # MIXED-NEXT: 2002c: 33 02 ff fe addiu $24, $2, -2 | |
| 127 | # MIXED-NEXT: 20030: 0d ff move $15, $ra | |
| 128 | # MIXED-NEXT: 20032: 45 f9 jalrs16 $25 | |
| 129 | # MIXED-NEXT: 20034: 0f 83 move $gp, $3 | |
| 130 | # MIXED-NEXT: 20036: 0c 00 nop | |
| 131 | # MIXED-NEXT: 20038: 00 00 00 00 nop | |
| 132 | # MIXED-NEXT: 2003c: 00 00 00 00 nop | |
| 133 | ||
| 134 | # MIXED-NEXT: 20040: 79 00 3f f3 addiupc $2, 65484 | |
| 135 | # MIXED-NEXT: 20044: ff 22 00 00 lw $25, 0($2) | |
| 136 | # MIXED-NEXT: 20048: 45 99 jr16 $25 | |
| 137 | # MIXED-NEXT: 2004a: 0f 02 move $24, $2 | |
| 138 | ||
| 139 | # PLT: Entries [ | |
| 140 | # PLT-NEXT: Entry { | |
| 141 | # PLT-NEXT: Address: 0x3000C | |
| 142 | # ^ 0x20030 + 65500 | |
| 143 | # PLT-NEXT: Initial: | |
| 144 | # PLT-NEXT: Value: 0x0 | |
| 145 | # PLT-NEXT: Type: Function | |
| 146 | # PLT-NEXT: Section: Undefined | |
| 147 | # PLT-NEXT: Name: foo | |
| 148 | # PLT-NEXT: } | |
| 149 | # PLT-NEXT: ] | |
| 150 | ||
| 151 | .text | |
| 152 | .set micromips | |
| 153 | .global __start | |
| 154 | __start: | |
| 155 | jal foo |
deps/lld/test/ELF/mips-micro-plt.s created+91| ... | ... | @@ -0,0 +1,91 @@ |
| 1 | # Check less-significant bit setup for microMIPS PLT. | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | |
| 4 | # RUN: -mattr=micromips %S/Inputs/mips-dynamic.s -o %t-dso.o | |
| 5 | # RUN: ld.lld %t-dso.o -shared -o %t.so | |
| 6 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | |
| 7 | # RUN: -mattr=micromips %s -o %t-exe.o | |
| 8 | # 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 | ||
| 11 | # REQUIRES: mips | |
| 12 | ||
| 13 | # CHECK: Symbols [ | |
| 14 | # CHECK: Symbol { | |
| 15 | # CHECK: Name: foo | |
| 16 | # CHECK-NEXT: Value: 0x20008 | |
| 17 | # CHECK-NEXT: Size: | |
| 18 | # CHECK-NEXT: Binding: Local | |
| 19 | # CHECK-NEXT: Type: None | |
| 20 | # CHECK-NEXT: Other [ | |
| 21 | # CHECK-NEXT: STO_MIPS_MICROMIPS | |
| 22 | # CHECK-NEXT: STV_HIDDEN | |
| 23 | # CHECK-NEXT: ] | |
| 24 | # CHECK-NEXT: Section: .text | |
| 25 | # CHECK-NEXT: } | |
| 26 | # CHECK: Symbol { | |
| 27 | # CHECK: Name: __start | |
| 28 | # CHECK-NEXT: Value: 0x20000 | |
| 29 | # CHECK-NEXT: Size: | |
| 30 | # CHECK-NEXT: Binding: Global | |
| 31 | # CHECK-NEXT: Type: None | |
| 32 | # CHECK-NEXT: Other [ | |
| 33 | # CHECK-NEXT: STO_MIPS_MICROMIPS | |
| 34 | # CHECK-NEXT: ] | |
| 35 | # CHECK-NEXT: Section: .text | |
| 36 | # CHECK-NEXT: } | |
| 37 | # CHECK: Symbol { | |
| 38 | # CHECK: Name: foo0 | |
| 39 | # CHECK-NEXT: Value: 0x0 | |
| 40 | # CHECK-NEXT: Size: | |
| 41 | # CHECK-NEXT: Binding: Global | |
| 42 | # CHECK-NEXT: Type: Function | |
| 43 | # CHECK-NEXT: Other: 0 | |
| 44 | # CHECK-NEXT: Section: Undefined | |
| 45 | # CHECK-NEXT: } | |
| 46 | # CHECK-NEXT: ] | |
| 47 | # CHECK: DynamicSymbols [ | |
| 48 | # CHECK: Symbol { | |
| 49 | # CHECK: Name: foo0 | |
| 50 | # CHECK-NEXT: Value: 0x0 | |
| 51 | # CHECK-NEXT: Size: | |
| 52 | # CHECK-NEXT: Binding: Global | |
| 53 | # CHECK-NEXT: Type: Function | |
| 54 | # CHECK-NEXT: Other: 0 | |
| 55 | # CHECK-NEXT: Section: Undefined | |
| 56 | # CHECK-NEXT: } | |
| 57 | # CHECK-NEXT: ] | |
| 58 | ||
| 59 | # CHECK: Primary GOT { | |
| 60 | # CHECK: Local entries [ | |
| 61 | # CHECK-NEXT: Entry { | |
| 62 | # CHECK-NEXT: Address: | |
| 63 | # CHECK-NEXT: Access: | |
| 64 | # CHECK-NEXT: Initial: 0x20009 | |
| 65 | # CHECK-NEXT: } | |
| 66 | # CHECK: ] | |
| 67 | # CHECK: } | |
| 68 | ||
| 69 | # CHECK: PLT GOT { | |
| 70 | # CHECK: Entries [ | |
| 71 | # CHECK-NEXT: Entry { | |
| 72 | # CHECK-NEXT: Address: | |
| 73 | # CHECK-NEXT: Initial: 0x20011 | |
| 74 | # CHECK-NEXT: Value: 0x0 | |
| 75 | # CHECK-NEXT: Type: Function | |
| 76 | # CHECK-NEXT: Section: Undefined | |
| 77 | # CHECK-NEXT: Name: foo0@ | |
| 78 | # CHECK-NEXT: } | |
| 79 | # CHECK-NEXT: ] | |
| 80 | # CHECK-NEXT: } | |
| 81 | ||
| 82 | .text | |
| 83 | .set micromips | |
| 84 | .global foo | |
| 85 | .hidden foo | |
| 86 | .global __start | |
| 87 | __start: | |
| 88 | lw $t0,%got(foo)($gp) | |
| 89 | addi $t0,$t0,%lo(foo) | |
| 90 | foo: | |
| 91 | jal foo0 |
deps/lld/test/ELF/mips-micro-relocs.s created+59| ... | ... | @@ -0,0 +1,59 @@ |
| 1 | # Check handling of microMIPS relocations. | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | |
| 4 | # RUN: -mattr=micromips %S/Inputs/mips-micro.s -o %t1eb.o | |
| 5 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | |
| 6 | # RUN: -mattr=micromips %s -o %t2eb.o | |
| 7 | # RUN: ld.lld -o %teb.exe %t1eb.o %t2eb.o | |
| 8 | # RUN: llvm-objdump -d -t -mattr=micromips %teb.exe \ | |
| 9 | # RUN: | FileCheck --check-prefixes=EB,SYM %s | |
| 10 | ||
| 11 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ | |
| 12 | # RUN: -mattr=micromips %S/Inputs/mips-micro.s -o %t1el.o | |
| 13 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ | |
| 14 | # RUN: -mattr=micromips %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 | # REQUIRES: mips | |
| 20 | ||
| 21 | # EB: __start: | |
| 22 | # EB-NEXT: 20010: 41 a3 00 01 lui $3, 1 | |
| 23 | # EB-NEXT: 20014: 30 63 7f df addiu $3, $3, 32735 | |
| 24 | # EB-NEXT: 20018: fc 7c 80 18 lw $3, -32744($gp) | |
| 25 | # EB-NEXT: 2001c: fc 63 80 18 lw $3, -32744($3) | |
| 26 | # EB-NEXT: 20020: 8f 70 beqz16 $6, -32 | |
| 27 | # EB-NEXT: 20022: 00 7e 00 00 sll $3, $fp, 0 | |
| 28 | # EB-NEXT: 20026: cf ec b16 -40 | |
| 29 | # EB-NEXT: 20028: 00 00 00 00 nop | |
| 30 | # EB-NEXT: 2002c: 94 00 ff e8 b -44 | |
| 31 | ||
| 32 | # EL: __start: | |
| 33 | # EL-NEXT: 20010: a3 41 01 00 lui $3, 1 | |
| 34 | # EL-NEXT: 20014: 63 30 df 7f addiu $3, $3, 32735 | |
| 35 | # EL-NEXT: 20018: 7c fc 18 80 lw $3, -32744($gp) | |
| 36 | # EL-NEXT: 2001c: 63 fc 18 80 lw $3, -32744($3) | |
| 37 | # EL-NEXT: 20020: 70 8f beqz16 $6, -32 | |
| 38 | # EL-NEXT: 20022: 7e 00 00 00 sll $3, $fp, 0 | |
| 39 | # EL-NEXT: 20026: ec cf b16 -40 | |
| 40 | # EL-NEXT: 20028: 00 00 00 00 nop | |
| 41 | # EL-NEXT: 2002c: 00 94 e8 ff b -44 | |
| 42 | ||
| 43 | # SYM: 00037ff0 .got 00000000 .hidden _gp | |
| 44 | # SYM: 00020000 g F .text 00000000 foo | |
| 45 | # SYM: 00020010 .text 00000000 __start | |
| 46 | ||
| 47 | .text | |
| 48 | .set micromips | |
| 49 | .global __start | |
| 50 | __start: | |
| 51 | lui $3, %hi(_gp_disp) # R_MICROMIPS_HI16 | |
| 52 | addiu $3, $3, %lo(_gp_disp) # R_MICROMIPS_LO16 | |
| 53 | ||
| 54 | lw $3, %call16(foo)($gp) # R_MICROMIPS_CALL16 | |
| 55 | lw $3, %got(foo)($3) # R_MICROMIPS_GOT16 | |
| 56 | ||
| 57 | beqz16 $6, foo # R_MICROMIPS_PC7_S1 | |
| 58 | b16 foo # R_MICROMIPS_PC10_S1 | |
| 59 | b foo # R_MICROMIPS_PC16_S1 |
deps/lld/test/ELF/mips-micro-thunks.s created+47| ... | ... | @@ -0,0 +1,47 @@ |
| 1 | # Check microMIPS thunk generation. | |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | |
| 4 | # RUN: -mattr=micromips %s -o %t-eb.o | |
| 5 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | |
| 6 | # RUN: -position-independent -mattr=micromips \ | |
| 7 | # 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: llvm-objdump -d -mattr=+micromips %t-eb.exe \ | |
| 10 | # RUN: | FileCheck --check-prefix=EB %s | |
| 11 | ||
| 12 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ | |
| 13 | # RUN: -mattr=micromips %s -o %t-el.o | |
| 14 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ | |
| 15 | # RUN: -position-independent -mattr=micromips \ | |
| 16 | # 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: llvm-objdump -d -mattr=+micromips %t-el.exe \ | |
| 19 | # RUN: | FileCheck --check-prefix=EL %s | |
| 20 | ||
| 21 | # REQUIRES: mips | |
| 22 | ||
| 23 | # EB: __start: | |
| 24 | # EB-NEXT: 20000: f4 01 00 04 jal 131080 <__microLA25Thunk_foo> | |
| 25 | # EB-NEXT: 20004: 00 00 00 00 nop | |
| 26 | ||
| 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 | ||
| 43 | .text | |
| 44 | .set micromips | |
| 45 | .global __start | |
| 46 | __start: | |
| 47 | jal foo |
deps/lld/test/ELF/mips-n32-rels.s+3-3| ... | ... | @@ -38,11 +38,11 @@ |
| 38 | 38 | # ^-- %lo(0x17ff0) |
| 39 | 39 | |
| 40 | 40 | # CHECK: Contents of section .rodata: |
| 41 | # CHECK-NEXT: 100d4 00020004 | |
| 42 | # ^-- loc | |
| 41 | # CHECK-NEXT: {{[0-9a-f]+}} 00020004 | |
| 42 | # ^-- loc | |
| 43 | 43 | |
| 44 | 44 | # CHECK: 00020004 .text 00000000 loc |
| 45 | # CHECK: 00037ff0 *ABS* 00000000 .hidden _gp | |
| 45 | # CHECK: 00037ff0 .got 00000000 .hidden _gp | |
| 46 | 46 | # CHECK: 00020000 g F .text 00000000 __start |
| 47 | 47 | |
| 48 | 48 | # ELF: Format: ELF32-mips |
deps/lld/test/ELF/mips-out-of-bounds-call16-reloc.s created+29| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | # Check that we create an error on an out-of-bounds R_MIPS_CALL_16 | |
| 2 | ||
| 3 | # REQUIRES: mips | |
| 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 | |
| 6 | ||
| 7 | # CHECK: relocation R_MIPS_CALL16 out of range: 32768 is not in [-32768, 32767] | |
| 8 | ||
| 9 | .macro generate_values | |
| 10 | .irp i, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, | |
| 11 | .irp j, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, | |
| 12 | .irp k, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, | |
| 13 | .irp l, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, | |
| 14 | .text | |
| 15 | .globl sym_\i\j\k\l | |
| 16 | sym_\i\j\k\l: | |
| 17 | nop | |
| 18 | lw $25,%call16(sym_\i\j\k\l)($28) | |
| 19 | .endr | |
| 20 | .endr | |
| 21 | .endr | |
| 22 | .endr | |
| 23 | .endm | |
| 24 | ||
| 25 | generate_values | |
| 26 | ||
| 27 | .globl __start | |
| 28 | __start: | |
| 29 | nop |
deps/lld/test/ELF/no-inhibit-exec.s+4| ... | ... | @@ -2,12 +2,16 @@ |
| 2 | 2 | # RUN: not ld.lld %t -o %t2 |
| 3 | 3 | # RUN: ld.lld %t --noinhibit-exec -o %t2 |
| 4 | 4 | # RUN: llvm-objdump -d %t2 | FileCheck %s |
| 5 | # RUN: llvm-readobj -r %t2 | FileCheck %s --check-prefix=RELOC | |
| 5 | 6 | # REQUIRES: x86 |
| 6 | 7 | |
| 7 | 8 | # CHECK: Disassembly of section .text: |
| 8 | 9 | # CHECK-NEXT: _start |
| 9 | 10 | # CHECK-NEXT: 201000: {{.*}} callq -2101253 |
| 10 | 11 | |
| 12 | # RELOC: Relocations [ | |
| 13 | # RELOC-NEXT: ] | |
| 14 | ||
| 11 | 15 | # next code will not link without noinhibit-exec flag |
| 12 | 16 | # because of undefined symbol _bar |
| 13 | 17 | .globl _start |
deps/lld/test/ELF/non-abs-reloc.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | // RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s |
| 4 | // CHECK: {{.*}}:(.dummy+0x0): has non-ABS reloc | |
| 4 | // CHECK: {{.*}}:(.dummy+0x0): has non-ABS relocation R_X86_64_GOTPCREL against symbol 'foo' | |
| 5 | 5 | |
| 6 | 6 | .globl _start |
| 7 | 7 | _start: |
deps/lld/test/ELF/noplt-pie.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 4 | 4 | # RUN: ld.lld -shared %t2.o -o %t2.so |
| 5 | # RUN: ld.lld %t1.o %t2.so -o %t.out | |
| 5 | # RUN: ld.lld --hash-style=sysv %t1.o %t2.so -o %t.out | |
| 6 | 6 | # RUN: llvm-readobj -s -r %t.out | FileCheck %s |
| 7 | 7 | |
| 8 | 8 | # CHECK: Section { |
deps/lld/test/ELF/pack-dyn-relocs.s created+210| ... | ... | @@ -0,0 +1,210 @@ |
| 1 | // REQUIRES: arm, aarch64 | |
| 2 | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-shared.s -o %t.a32.so.o | |
| 4 | // RUN: ld.lld -shared %t.a32.so.o -o %t.a32.so | |
| 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 | |
| 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 | ||
| 12 | // Unpacked should have the relative relocations in their natural order. | |
| 13 | // UNPACKED32: 0x1000 R_ARM_RELATIVE - 0x0 | |
| 14 | // UNPACKED32-NEXT: 0x1004 R_ARM_RELATIVE - 0x0 | |
| 15 | // UNPACKED32-NEXT: 0x1008 R_ARM_RELATIVE - 0x0 | |
| 16 | // UNPACKED32-NEXT: 0x100C R_ARM_RELATIVE - 0x0 | |
| 17 | // UNPACKED32-NEXT: 0x1010 R_ARM_RELATIVE - 0x0 | |
| 18 | // UNPACKED32-NEXT: 0x1014 R_ARM_RELATIVE - 0x0 | |
| 19 | // UNPACKED32-NEXT: 0x1018 R_ARM_RELATIVE - 0x0 | |
| 20 | // UNPACKED32-NEXT: 0x101C R_ARM_RELATIVE - 0x0 | |
| 21 | ||
| 22 | // UNPACKED32-NEXT: 0x1024 R_ARM_RELATIVE - 0x0 | |
| 23 | // UNPACKED32-NEXT: 0x1028 R_ARM_RELATIVE - 0x0 | |
| 24 | // UNPACKED32-NEXT: 0x102C R_ARM_RELATIVE - 0x0 | |
| 25 | // UNPACKED32-NEXT: 0x1030 R_ARM_RELATIVE - 0x0 | |
| 26 | // UNPACKED32-NEXT: 0x1034 R_ARM_RELATIVE - 0x0 | |
| 27 | // UNPACKED32-NEXT: 0x1038 R_ARM_RELATIVE - 0x0 | |
| 28 | // UNPACKED32-NEXT: 0x103C R_ARM_RELATIVE - 0x0 | |
| 29 | ||
| 30 | // UNPACKED32-NEXT: 0x1044 R_ARM_RELATIVE - 0x0 | |
| 31 | // UNPACKED32-NEXT: 0x1048 R_ARM_RELATIVE - 0x0 | |
| 32 | // UNPACKED32-NEXT: 0x104C R_ARM_RELATIVE - 0x0 | |
| 33 | // UNPACKED32-NEXT: 0x1050 R_ARM_RELATIVE - 0x0 | |
| 34 | // UNPACKED32-NEXT: 0x1054 R_ARM_RELATIVE - 0x0 | |
| 35 | // UNPACKED32-NEXT: 0x1058 R_ARM_RELATIVE - 0x0 | |
| 36 | // UNPACKED32-NEXT: 0x105C R_ARM_RELATIVE - 0x0 | |
| 37 | // UNPACKED32-NEXT: 0x1060 R_ARM_RELATIVE - 0x0 | |
| 38 | // UNPACKED32-NEXT: 0x1064 R_ARM_RELATIVE - 0x0 | |
| 39 | ||
| 40 | // UNPACKED32-NEXT: 0x1020 R_ARM_ABS32 bar2 0x0 | |
| 41 | // UNPACKED32-NEXT: 0x1040 R_ARM_ABS32 zed2 0x0 | |
| 42 | ||
| 43 | // PACKED32-HEADERS: Index: 1 | |
| 44 | // PACKED32-HEADERS-NEXT: Name: .dynsym | |
| 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 | ||
| 62 | // Packed should have the larger groups of relative relocations first, | |
| 63 | // i.e. the 8 and 9 followed by the 7. | |
| 64 | // PACKED32: 0x1000 R_ARM_RELATIVE - 0x0 | |
| 65 | // PACKED32-NEXT: 0x1004 R_ARM_RELATIVE - 0x0 | |
| 66 | // PACKED32-NEXT: 0x1008 R_ARM_RELATIVE - 0x0 | |
| 67 | // PACKED32-NEXT: 0x100C R_ARM_RELATIVE - 0x0 | |
| 68 | // PACKED32-NEXT: 0x1010 R_ARM_RELATIVE - 0x0 | |
| 69 | // PACKED32-NEXT: 0x1014 R_ARM_RELATIVE - 0x0 | |
| 70 | // PACKED32-NEXT: 0x1018 R_ARM_RELATIVE - 0x0 | |
| 71 | // PACKED32-NEXT: 0x101C R_ARM_RELATIVE - 0x0 | |
| 72 | ||
| 73 | // PACKED32-NEXT: 0x1044 R_ARM_RELATIVE - 0x0 | |
| 74 | // PACKED32-NEXT: 0x1048 R_ARM_RELATIVE - 0x0 | |
| 75 | // PACKED32-NEXT: 0x104C R_ARM_RELATIVE - 0x0 | |
| 76 | // PACKED32-NEXT: 0x1050 R_ARM_RELATIVE - 0x0 | |
| 77 | // PACKED32-NEXT: 0x1054 R_ARM_RELATIVE - 0x0 | |
| 78 | // PACKED32-NEXT: 0x1058 R_ARM_RELATIVE - 0x0 | |
| 79 | // PACKED32-NEXT: 0x105C R_ARM_RELATIVE - 0x0 | |
| 80 | // PACKED32-NEXT: 0x1060 R_ARM_RELATIVE - 0x0 | |
| 81 | // PACKED32-NEXT: 0x1064 R_ARM_RELATIVE - 0x0 | |
| 82 | ||
| 83 | // PACKED32-NEXT: 0x1024 R_ARM_RELATIVE - 0x0 | |
| 84 | // PACKED32-NEXT: 0x1028 R_ARM_RELATIVE - 0x0 | |
| 85 | // PACKED32-NEXT: 0x102C R_ARM_RELATIVE - 0x0 | |
| 86 | // PACKED32-NEXT: 0x1030 R_ARM_RELATIVE - 0x0 | |
| 87 | // PACKED32-NEXT: 0x1034 R_ARM_RELATIVE - 0x0 | |
| 88 | // PACKED32-NEXT: 0x1038 R_ARM_RELATIVE - 0x0 | |
| 89 | // PACKED32-NEXT: 0x103C R_ARM_RELATIVE - 0x0 | |
| 90 | ||
| 91 | // PACKED32-NEXT: 0x1020 R_ARM_ABS32 bar2 0x0 | |
| 92 | // PACKED32-NEXT: 0x1040 R_ARM_ABS32 zed2 0x0 | |
| 93 | ||
| 94 | // 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 | |
| 96 | // 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 | |
| 98 | // 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 | ||
| 103 | // UNPACKED64: 0x10000 R_AARCH64_RELATIVE - 0x1 | |
| 104 | // UNPACKED64-NEXT: 0x10008 R_AARCH64_RELATIVE - 0x2 | |
| 105 | // UNPACKED64-NEXT: 0x10010 R_AARCH64_RELATIVE - 0x3 | |
| 106 | // UNPACKED64-NEXT: 0x10018 R_AARCH64_RELATIVE - 0x4 | |
| 107 | // UNPACKED64-NEXT: 0x10020 R_AARCH64_RELATIVE - 0x5 | |
| 108 | // UNPACKED64-NEXT: 0x10028 R_AARCH64_RELATIVE - 0x6 | |
| 109 | // UNPACKED64-NEXT: 0x10030 R_AARCH64_RELATIVE - 0x7 | |
| 110 | // UNPACKED64-NEXT: 0x10038 R_AARCH64_RELATIVE - 0x8 | |
| 111 | ||
| 112 | // UNPACKED64-NEXT: 0x10048 R_AARCH64_RELATIVE - 0x1 | |
| 113 | // UNPACKED64-NEXT: 0x10050 R_AARCH64_RELATIVE - 0x2 | |
| 114 | // UNPACKED64-NEXT: 0x10058 R_AARCH64_RELATIVE - 0x3 | |
| 115 | // UNPACKED64-NEXT: 0x10060 R_AARCH64_RELATIVE - 0x4 | |
| 116 | // UNPACKED64-NEXT: 0x10068 R_AARCH64_RELATIVE - 0x5 | |
| 117 | // UNPACKED64-NEXT: 0x10070 R_AARCH64_RELATIVE - 0x6 | |
| 118 | // UNPACKED64-NEXT: 0x10078 R_AARCH64_RELATIVE - 0x7 | |
| 119 | ||
| 120 | // UNPACKED64-NEXT: 0x10088 R_AARCH64_RELATIVE - 0x1 | |
| 121 | // UNPACKED64-NEXT: 0x10090 R_AARCH64_RELATIVE - 0x2 | |
| 122 | // UNPACKED64-NEXT: 0x10098 R_AARCH64_RELATIVE - 0x3 | |
| 123 | // UNPACKED64-NEXT: 0x100A0 R_AARCH64_RELATIVE - 0x4 | |
| 124 | // UNPACKED64-NEXT: 0x100A8 R_AARCH64_RELATIVE - 0x5 | |
| 125 | // UNPACKED64-NEXT: 0x100B0 R_AARCH64_RELATIVE - 0x6 | |
| 126 | // UNPACKED64-NEXT: 0x100B8 R_AARCH64_RELATIVE - 0x7 | |
| 127 | // UNPACKED64-NEXT: 0x100C0 R_AARCH64_RELATIVE - 0x8 | |
| 128 | // UNPACKED64-NEXT: 0x100C8 R_AARCH64_RELATIVE - 0x9 | |
| 129 | ||
| 130 | // UNPACKED64-NEXT: 0x10040 R_AARCH64_ABS64 bar2 0x1 | |
| 131 | // UNPACKED64-NEXT: 0x10080 R_AARCH64_ABS64 zed2 0x0 | |
| 132 | ||
| 133 | // PACKED64: 0x10000 R_AARCH64_RELATIVE - 0x1 | |
| 134 | // PACKED64-NEXT: 0x10008 R_AARCH64_RELATIVE - 0x2 | |
| 135 | // PACKED64-NEXT: 0x10010 R_AARCH64_RELATIVE - 0x3 | |
| 136 | // PACKED64-NEXT: 0x10018 R_AARCH64_RELATIVE - 0x4 | |
| 137 | // PACKED64-NEXT: 0x10020 R_AARCH64_RELATIVE - 0x5 | |
| 138 | // PACKED64-NEXT: 0x10028 R_AARCH64_RELATIVE - 0x6 | |
| 139 | // PACKED64-NEXT: 0x10030 R_AARCH64_RELATIVE - 0x7 | |
| 140 | // PACKED64-NEXT: 0x10038 R_AARCH64_RELATIVE - 0x8 | |
| 141 | ||
| 142 | // PACKED64-NEXT: 0x10088 R_AARCH64_RELATIVE - 0x1 | |
| 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 | ||
| 182 | .data | |
| 183 | .dc.a __ehdr_start + 1 | |
| 184 | .dc.a __ehdr_start + 2 | |
| 185 | .dc.a __ehdr_start + 3 | |
| 186 | .dc.a __ehdr_start + 4 | |
| 187 | .dc.a __ehdr_start + 5 | |
| 188 | .dc.a __ehdr_start + 6 | |
| 189 | .dc.a __ehdr_start + 7 | |
| 190 | .dc.a __ehdr_start + 8 | |
| 191 | .dc.a bar2 + 1 | |
| 192 | ||
| 193 | .dc.a __ehdr_start + 1 | |
| 194 | .dc.a __ehdr_start + 2 | |
| 195 | .dc.a __ehdr_start + 3 | |
| 196 | .dc.a __ehdr_start + 4 | |
| 197 | .dc.a __ehdr_start + 5 | |
| 198 | .dc.a __ehdr_start + 6 | |
| 199 | .dc.a __ehdr_start + 7 | |
| 200 | .dc.a zed2 | |
| 201 | ||
| 202 | .dc.a __ehdr_start + 1 | |
| 203 | .dc.a __ehdr_start + 2 | |
| 204 | .dc.a __ehdr_start + 3 | |
| 205 | .dc.a __ehdr_start + 4 | |
| 206 | .dc.a __ehdr_start + 5 | |
| 207 | .dc.a __ehdr_start + 6 | |
| 208 | .dc.a __ehdr_start + 7 | |
| 209 | .dc.a __ehdr_start + 8 | |
| 210 | .dc.a __ehdr_start + 9 |
deps/lld/test/ELF/pie-weak.s+5-2| ... | ... | @@ -1,10 +1,13 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -relax-relocations=false -triple=x86_64-unknown-linux %s -o %t.o |
| 3 | # RUN: ld.lld -pie %t.o -o %t | |
| 3 | # RUN: ld.lld --hash-style=sysv -pie %t.o -o %t | |
| 4 | 4 | # RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOCS %s |
| 5 | 5 | # RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s |
| 6 | 6 | |
| 7 | 7 | # RELOCS: Relocations [ |
| 8 | # RELOCS-NEXT: Section ({{.*}}) .rela.dyn { | |
| 9 | # RELOCS-NEXT: R_X86_64_GLOB_DAT foo 0x0 | |
| 10 | # RELOCS-NEXT: } | |
| 8 | 11 | # RELOCS-NEXT: ] |
| 9 | 12 | |
| 10 | 13 | .weak foo |
| ... | ... | @@ -12,6 +15,6 @@ |
| 12 | 15 | .globl _start |
| 13 | 16 | _start: |
| 14 | 17 | # DISASM: _start: |
| 15 | # DISASM-NEXT: 1000: 48 8b 05 69 10 00 00 movq 4201(%rip), %rax | |
| 18 | # DISASM-NEXT: 1000: 48 8b 05 99 10 00 00 movq 4249(%rip), %rax | |
| 16 | 19 | # ^ .got - (.text + 7) |
| 17 | 20 | mov foo@gotpcrel(%rip), %rax |
deps/lld/test/ELF/ppc-relocs.s+31-5| ... | ... | @@ -17,6 +17,20 @@ msg: |
| 17 | 17 | # CHECK: msg: |
| 18 | 18 | # CHECK: 11004: 66 6f 6f 00 oris 15, 19, 28416 |
| 19 | 19 | |
| 20 | .section .R_PPC_ADDR16_HI,"ax",@progbits | |
| 21 | .globl _starti | |
| 22 | _starti: | |
| 23 | lis 4,msgi@h | |
| 24 | msgi: | |
| 25 | .string "foo" | |
| 26 | leni = . - msgi | |
| 27 | ||
| 28 | # CHECK: Disassembly of section .R_PPC_ADDR16_HI: | |
| 29 | # CHECK: _starti: | |
| 30 | # CHECK: 11008: 3c 80 00 01 lis 4, 1 | |
| 31 | # CHECK: msgi: | |
| 32 | # CHECK: 1100c: 66 6f 6f 00 oris 15, 19, 28416 | |
| 33 | ||
| 20 | 34 | .section .R_PPC_ADDR16_LO,"ax",@progbits |
| 21 | 35 | addi 4, 4, msg@l |
| 22 | 36 | mystr: |
| ... | ... | @@ -25,9 +39,9 @@ mystr: |
| 25 | 39 | |
| 26 | 40 | # CHECK: Disassembly of section .R_PPC_ADDR16_LO: |
| 27 | 41 | # CHECK: .R_PPC_ADDR16_LO: |
| 28 | # CHECK: 11008: 38 84 10 04 addi 4, 4, 4100 | |
| 42 | # CHECK: 11010: 38 84 10 04 addi 4, 4, 4100 | |
| 29 | 43 | # CHECK: mystr: |
| 30 | # CHECK: 1100c: 62 6c 61 68 ori 12, 19, 24936 | |
| 44 | # CHECK: 11014: 62 6c 61 68 ori 12, 19, 24936 | |
| 31 | 45 | |
| 32 | 46 | .align 2 |
| 33 | 47 | .section .R_PPC_REL24,"ax",@progbits |
| ... | ... | @@ -39,7 +53,7 @@ mystr: |
| 39 | 53 | |
| 40 | 54 | # CHECK: Disassembly of section .R_PPC_REL24: |
| 41 | 55 | # CHECK: .FR_PPC_REL24: |
| 42 | # CHECK: 11014: 48 00 00 04 b .+4 | |
| 56 | # CHECK: 1101c: 48 00 00 04 b .+4 | |
| 43 | 57 | |
| 44 | 58 | .section .R_PPC_REL32,"ax",@progbits |
| 45 | 59 | .globl .FR_PPC_REL32 |
| ... | ... | @@ -50,7 +64,7 @@ mystr: |
| 50 | 64 | |
| 51 | 65 | # CHECK: Disassembly of section .R_PPC_REL32: |
| 52 | 66 | # CHECK: .FR_PPC_REL32: |
| 53 | # CHECK: 11018: 00 00 00 04 | |
| 67 | # CHECK: 11020: 00 00 00 04 | |
| 54 | 68 | |
| 55 | 69 | .section .R_PPC_ADDR32,"ax",@progbits |
| 56 | 70 | .globl .FR_PPC_ADDR32 |
| ... | ... | @@ -61,4 +75,16 @@ mystr: |
| 61 | 75 | |
| 62 | 76 | # CHECK: Disassembly of section .R_PPC_ADDR32: |
| 63 | 77 | # CHECK: .FR_PPC_ADDR32: |
| 64 | # CHECK: 1101c: 00 01 10 20 | |
| 78 | # CHECK: 11024: 00 01 10 28 | |
| 79 | ||
| 80 | .align 2 | |
| 81 | .section .R_PPC_PLTREL24,"ax",@progbits | |
| 82 | .globl .R_PPC_PLTREL24 | |
| 83 | .FR_PPC_PLTREL24: | |
| 84 | b .Lfoox4@PLT | |
| 85 | .section .R_PPC_PLTREL24_2,"ax",@progbits | |
| 86 | .Lfoox4: | |
| 87 | ||
| 88 | # CHECK: Disassembly of section .R_PPC_PLTREL24: | |
| 89 | # CHECK: .R_PPC_PLTREL24: | |
| 90 | # CHECK: 11028: 48 00 00 04 b .+4 |
deps/lld/test/ELF/ppc64-addr16-error.s+1-1| ... | ... | @@ -5,4 +5,4 @@ |
| 5 | 5 | |
| 6 | 6 | .short sym+65539 |
| 7 | 7 | |
| 8 | // CHECK: relocation R_PPC64_ADDR16 out of range | |
| 8 | // CHECK: relocation R_PPC64_ADDR16 out of range: 65539 is not in [-32768, 32767] |
deps/lld/test/ELF/pr34660.s created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | # REQUIRES: aarch64 | |
| 2 | ||
| 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 | |
| 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 | |
| 7 | ||
| 8 | # It would be much easier to understand/read this test if llvm-objdump would print | |
| 9 | # the immediates in hex. | |
| 10 | # IMM = hex(65540) = 0x10004 | |
| 11 | # PC = 0x10000 | |
| 12 | # As the relocation is PC-relative, IMM + PC = 0x20004 which is the VA of the | |
| 13 | # correct symbol. | |
| 14 | ||
| 15 | # DISASM: Disassembly of section .text: | |
| 16 | # DISASM-NEXT: $x.0: | |
| 17 | # DISASM-NEXT: 10000: 28 00 08 58 ldr x8, #65540 | |
| 18 | ||
| 19 | # SYM: Symbol table '.symtab' | |
| 20 | # SYM: 0000000000020004 0 NOTYPE LOCAL DEFAULT 5 patatino | |
| 21 | ||
| 22 | ldr x8, patatino | |
| 23 | .data | |
| 24 | .zero 4 | |
| 25 | patatino: |
deps/lld/test/ELF/pr34872.s created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | # 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: -triple=x86_64-pc-linux -o %t2.o | |
| 4 | # RUN: ld.lld -shared %t2.o -o %t2.so | |
| 5 | # RUN: not ld.lld %t2.so %t.o 2>&1 | FileCheck %s | |
| 6 | ||
| 7 | # CHECK: undefined symbol: fmod | |
| 8 | # Check we're not emitting other diagnostics for this symbol. | |
| 9 | # CHECK-NOT: fmod | |
| 10 | ||
| 11 | .global main | |
| 12 | ||
| 13 | main: | |
| 14 | callq fmod |
deps/lld/test/ELF/progname.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: echo .global __progname > %t2.s | |
| 3 | // RUN: echo ".global __progname; .data; .dc.a __progname" > %t2.s | |
| 4 | 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2.o |
| 5 | 5 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| 6 | 6 | // RUN: ld.lld -o %t %t.o %t2.so |
deps/lld/test/ELF/relocatable-comdat2.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: ld.lld -r %t.o -o %t | |
| 4 | # RUN: llvm-readobj -elf-section-groups -s %t | FileCheck %s | |
| 5 | ||
| 6 | ## Check .foo was not merged. | |
| 7 | # CHECK: Sections [ | |
| 8 | # CHECK: Name: .foo | |
| 9 | # CHECK: Name: .foo | |
| 10 | # CHECK: Name: .foo | |
| 11 | ||
| 12 | # CHECK: Groups { | |
| 13 | # CHECK-NEXT: Group { | |
| 14 | # CHECK-NEXT: Name: .group | |
| 15 | # CHECK-NEXT: Index: 2 | |
| 16 | # CHECK-NEXT: Type: COMDAT | |
| 17 | # CHECK-NEXT: Signature: bar | |
| 18 | # CHECK-NEXT: Section(s) in group [ | |
| 19 | # CHECK-NEXT: .foo (3) | |
| 20 | # CHECK-NEXT: ] | |
| 21 | # CHECK-NEXT: } | |
| 22 | # CHECK-NEXT: Group { | |
| 23 | # CHECK-NEXT: Name: .group | |
| 24 | # CHECK-NEXT: Index: 4 | |
| 25 | # CHECK-NEXT: Type: COMDAT | |
| 26 | # CHECK-NEXT: Signature: zed | |
| 27 | # CHECK-NEXT: Section(s) in group [ | |
| 28 | # CHECK-NEXT: .foo (5) | |
| 29 | # CHECK-NEXT: ] | |
| 30 | # CHECK-NEXT: } | |
| 31 | # CHECK-NEXT: } | |
| 32 | ||
| 33 | .section .foo,"axG",@progbits,bar,comdat | |
| 34 | .section .foo,"axG",@progbits,zed,comdat | |
| 35 | .section .foo,"ax",@progbits |
deps/lld/test/ELF/relocatable-common.s+4-1| ... | ... | @@ -30,7 +30,10 @@ |
| 30 | 30 | # DEFCOMM-NEXT: Binding: Global |
| 31 | 31 | # DEFCOMM-NEXT: Type: Object |
| 32 | 32 | # DEFCOMM-NEXT: Other: 0 |
| 33 | # DEFCOMM-NEXT: Section: COMMON (0x2) | |
| 33 | # DEFCOMM-NEXT: Section: COMMON | |
| 34 | 34 | # DEFCOMM-NEXT: } |
| 35 | 35 | |
| 36 | # RUN: not ld.lld -shared --no-define-common %t1.o -o %t 2>&1 | FileCheck --check-prefix=ERROR %s | |
| 37 | # ERROR: error: -no-define-common not supported in non relocatable output | |
| 38 | ||
| 36 | 39 | .comm common,4,4 |
deps/lld/test/ELF/relocatable-compressed-input.s+5-5| ... | ... | @@ -24,11 +24,11 @@ |
| 24 | 24 | # CHECK-NEXT: AddressAlignment: 1 |
| 25 | 25 | # CHECK-NEXT: EntrySize: 1 |
| 26 | 26 | # CHECK-NEXT: SectionData ( |
| 27 | # CHECK-NEXT: 0000: {{.*}} |short unsigned i| | |
| 28 | # CHECK-NEXT: 0010: {{.*}} |nt.unsigned int.| | |
| 29 | # CHECK-NEXT: 0020: {{.*}} |long unsigned in| | |
| 30 | # CHECK-NEXT: 0030: {{.*}} |t.char.unsigned | | |
| 31 | # CHECK-NEXT: 0040: {{.*}} |char.| | |
| 27 | # CHECK-NEXT: 0000: {{.*}} |long unsigned in| | |
| 28 | # CHECK-NEXT: 0010: {{.*}} |t.unsigned char.| | |
| 29 | # CHECK-NEXT: 0020: {{.*}} |unsigned int.cha| | |
| 30 | # CHECK-NEXT: 0030: {{.*}} |r.short unsigned| | |
| 31 | # CHECK-NEXT: 0040: {{.*}} | int.| | |
| 32 | 32 | # CHECK-NEXT: ) |
| 33 | 33 | # CHECK-NEXT: } |
| 34 | 34 |
deps/lld/test/ELF/relocatable-versioned.s created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o | |
| 3 | # RUN: ld.lld -o %t2.o -r %t1.o | |
| 4 | # RUN: llvm-nm %t2.o | FileCheck %s | |
| 5 | # CHECK: foo@VERSION | |
| 6 | ||
| 7 | .global "foo@VERSION" | |
| 8 | "foo@VERSION": | |
| 9 | ret |
deps/lld/test/ELF/relocatable.s+1-1| ... | ... | @@ -81,7 +81,7 @@ |
| 81 | 81 | # CHECKEXE-NEXT: Version: 1 |
| 82 | 82 | # CHECKEXE-NEXT: Entry: 0x201000 |
| 83 | 83 | # CHECKEXE-NEXT: ProgramHeaderOffset: 0x40 |
| 84 | # CHECKEXE-NEXT: SectionHeaderOffset: 0x11F8 | |
| 84 | # CHECKEXE-NEXT: SectionHeaderOffset: 0x21A0 | |
| 85 | 85 | # CHECKEXE-NEXT: Flags [ |
| 86 | 86 | # CHECKEXE-NEXT: ] |
| 87 | 87 | # CHECKEXE-NEXT: HeaderSize: 64 |
deps/lld/test/ELF/relocation-b-aarch64.test created+48| ... | ... | @@ -0,0 +1,48 @@ |
| 1 | # REQUIRES: aarch64 | |
| 2 | ||
| 3 | # RUN: yaml2obj %s -o %t.o | |
| 4 | # RUN: ld.lld %t.o -o %t.out | |
| 5 | # RUN: llvm-objdump -d -triple=aarch64-none-linux %t.out | FileCheck %s | |
| 6 | ||
| 7 | # Check that the R_AARCH64_JUMP26 writes the branch opcode as well as the | |
| 8 | # immediate. We use this property to overwrite instructions with a branch. | |
| 9 | ||
| 10 | # CHECK: Disassembly of section .text: | |
| 11 | # CHECK-NEXT: foo: | |
| 12 | # CHECK-NEXT: 20000: 01 00 00 14 b #4 | |
| 13 | # CHECK: bar: | |
| 14 | # CHECK-NEXT: 20004: ff ff ff 17 b #-4 | |
| 15 | ||
| 16 | !ELF | |
| 17 | FileHeader: | |
| 18 | Class: ELFCLASS64 | |
| 19 | Data: ELFDATA2LSB | |
| 20 | Type: ET_REL | |
| 21 | Machine: EM_AARCH64 | |
| 22 | Sections: | |
| 23 | - Type: SHT_PROGBITS | |
| 24 | Name: .text | |
| 25 | Flags: [ SHF_ALLOC, SHF_EXECINSTR ] | |
| 26 | Content: "0000000000000000" | |
| 27 | - Type: SHT_RELA | |
| 28 | Name: .rela.text | |
| 29 | Link: .symtab | |
| 30 | Info: .text | |
| 31 | Relocations: | |
| 32 | - Offset: 0 | |
| 33 | Symbol: bar | |
| 34 | Type: R_AARCH64_JUMP26 | |
| 35 | - Offset: 4 | |
| 36 | Symbol: foo | |
| 37 | Type: R_AARCH64_JUMP26 | |
| 38 | ||
| 39 | Symbols: | |
| 40 | Local: | |
| 41 | - Type: STT_FUNC | |
| 42 | Section: .text | |
| 43 | Name: foo | |
| 44 | Value: 0 | |
| 45 | - Type: STT_FUNC | |
| 46 | Section: .text | |
| 47 | Name: bar | |
| 48 | Value: 4 |
deps/lld/test/ELF/relocation-copy-alias.s+5-3| ... | ... | @@ -1,8 +1,10 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy-alias.s -o %t2.o |
| 4 | // RUN: ld.lld -shared %t2.o -o %t.so | |
| 5 | // RUN: ld.lld %t.o %t.so -o %t3 | |
| 4 | // RUN: ld.lld --hash-style=sysv -shared %t2.o -o %t.so | |
| 5 | // RUN: ld.lld --hash-style=sysv %t.o %t.so -o %t3 | |
| 6 | // RUN: llvm-readobj --dyn-symbols -r --expand-relocs %t3 | FileCheck %s | |
| 7 | // RUN: ld.lld --hash-style=sysv --gc-sections %t.o %t.so -o %t3 | |
| 6 | 8 | // RUN: llvm-readobj --dyn-symbols -r --expand-relocs %t3 | FileCheck %s |
| 7 | 9 | |
| 8 | 10 | .global _start |
| ... | ... | @@ -61,7 +63,7 @@ movl $5, b2 |
| 61 | 63 | // CHECK: Name: b3 |
| 62 | 64 | // CHECK-NEXT: Value: [[B]] |
| 63 | 65 | // CHECK-NEXT: Size: 1 |
| 64 | // CHECK-NEXT: Binding: Weak | |
| 66 | // CHECK-NEXT: Binding: Global | |
| 65 | 67 | // CHECK-NEXT: Type: Object (0x1) |
| 66 | 68 | // CHECK-NEXT: Other: 0 |
| 67 | 69 | // CHECK-NEXT: Section: .bss |
deps/lld/test/ELF/relocation-copy-align-common.s+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \ |
| 4 | 4 | # RUN: %p/Inputs/relocation-copy-align-common.s -o %t2.o |
| 5 | 5 | # RUN: ld.lld -shared %t2.o -o %t.so |
| 6 | # RUN: ld.lld %t.o %t.so -o %t3 | |
| 6 | # RUN: ld.lld --hash-style=sysv %t.o %t.so -o %t3 | |
| 7 | 7 | # RUN: llvm-readobj -s -r --expand-relocs %t3 | FileCheck %s |
| 8 | 8 | |
| 9 | 9 | # CHECK: Section { |
deps/lld/test/ELF/relocation-copy-flags.s+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 4 | 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy.s -o %t2.o |
| 5 | 5 | // RUN: ld.lld %t2.o -o %t2.so -shared |
| 6 | // RUN: ld.lld %t.o %t2.so -o %t.exe | |
| 6 | // RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t.exe | |
| 7 | 7 | // RUN: llvm-readobj -s -section-data -r %t.exe | FileCheck %s |
| 8 | 8 | |
| 9 | 9 | .global _start |
deps/lld/test/ELF/relocation-copy-relro.s+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy-relro.s -o %t2.o |
| 4 | 4 | // RUN: ld.lld -shared %t2.o -o %t.so |
| 5 | // RUN: ld.lld %t.o %t.so -o %t3 | |
| 5 | // RUN: ld.lld --hash-style=sysv %t.o %t.so -o %t3 | |
| 6 | 6 | // RUN: llvm-readobj -program-headers -s -r %t3 | FileCheck %s |
| 7 | 7 | |
| 8 | 8 | // CHECK: Name: .bss.rel.ro (48) |
deps/lld/test/ELF/relocation-i686.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | 3 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| 4 | // RUN: ld.lld %t %t2.so -o %t2 | |
| 4 | // RUN: ld.lld --hash-style=sysv %t %t2.so -o %t2 | |
| 5 | 5 | // RUN: llvm-readobj -s %t2 | FileCheck --check-prefix=ADDR %s |
| 6 | 6 | // RUN: llvm-objdump -d %t2 | FileCheck %s |
| 7 | 7 | // REQUIRES: x86 |
deps/lld/test/ELF/relocation-relative-weak.s+1| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | # RUN: llvm-readobj -dyn-relocations %t | FileCheck %s |
| 5 | 5 | |
| 6 | 6 | # CHECK: Dynamic Relocations { |
| 7 | # CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT w 0x0 | |
| 7 | 8 | # CHECK-NEXT: } |
| 8 | 9 | |
| 9 | 10 | .globl _start |
deps/lld/test/ELF/relocation-size-err.s created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | // REQUIRES: x86 | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 3 | // RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s | |
| 4 | ||
| 5 | // CHECK: error: can't create dynamic relocation R_X86_64_SIZE64 against symbol: foo in readonly segment; recompile object files with -fPIC | |
| 6 | ||
| 7 | .global foo | |
| 8 | foo: | |
| 9 | .quad 42 | |
| 10 | .size foo, 8 | |
| 11 | ||
| 12 | .quad foo@SIZE |
deps/lld/test/ELF/relocation.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2 |
| 3 | 3 | // RUN: ld.lld %t2 -o %t2.so -shared |
| 4 | // RUN: ld.lld %t %t2.so -o %t3 | |
| 4 | // RUN: ld.lld --hash-style=sysv %t %t2.so -o %t3 | |
| 5 | 5 | // RUN: llvm-readobj -s %t3 | FileCheck --check-prefix=SEC %s |
| 6 | 6 | // RUN: llvm-objdump -s -d %t3 | FileCheck %s |
| 7 | 7 | // REQUIRES: x86 |
deps/lld/test/ELF/relro-copyrel-bss-script.s created+40| ... | ... | @@ -0,0 +1,40 @@ |
| 1 | // REQUIRES: x86 | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t.o | |
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/copy-in-shared.s -o %t2.o | |
| 4 | // RUN: ld.lld -shared %t.o %t2.o -o %t.so | |
| 5 | ||
| 6 | // A linker script that will map .bss.rel.ro into .bss. | |
| 7 | // RUN: echo "SECTIONS { \ | |
| 8 | // RUN: .bss : { *(.bss) *(.bss.*) } \ | |
| 9 | // RUN: } " > %t.script | |
| 10 | ||
| 11 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t3.o | |
| 12 | // RUN: ld.lld %t3.o %t.so -z relro -o %t --script=%t.script 2>&1 | |
| 13 | // RUN: llvm-readobj --program-headers %t | FileCheck %s | |
| 14 | .section .text, "ax", @progbits | |
| 15 | .global bar | |
| 16 | .global foo | |
| 17 | .global _start | |
| 18 | _start: | |
| 19 | callq bar | |
| 20 | // Will produce .bss.rel.ro that will match in .bss, this will lose | |
| 21 | // the relro property of the copy relocation. | |
| 22 | .quad foo | |
| 23 | ||
| 24 | // Non relro bss | |
| 25 | .bss | |
| 26 | // make large enough to affect PT_GNU_RELRO MemSize if this was marked | |
| 27 | // as relro. | |
| 28 | .space 0x2000 | |
| 29 | ||
| 30 | // CHECK: Type: PT_GNU_RELRO (0x6474E552) | |
| 31 | // CHECK-NEXT: Offset: | |
| 32 | // CHECK-NEXT: VirtualAddress: | |
| 33 | // CHECK-NEXT: PhysicalAddress: | |
| 34 | // CHECK-NEXT: FileSize: | |
| 35 | // CHECK-NEXT: MemSize: 4096 | |
| 36 | // CHECK-NEXT: Flags [ (0x4) | |
| 37 | // CHECK-NEXT: PF_R (0x4) | |
| 38 | // CHECK-NEXT: ] | |
| 39 | // CHECK-NEXT: Alignment: 1 | |
| 40 | // CHECK-NEXT: } |
deps/lld/test/ELF/relro-non-contiguous-script-data.s created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | // REQUIRES: x86 | |
| 2 | ||
| 3 | // RUN: echo "SECTIONS { \ | |
| 4 | // RUN: .dynamic : { *(.dynamic) } \ | |
| 5 | // RUN: .non_ro : { . += 1; } \ | |
| 6 | // RUN: .jcr : { *(.jcr) } \ | |
| 7 | // RUN: } " > %t.script | |
| 8 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 9 | // RUN: not ld.lld --export-dynamic %t.o -o %t --script=%t.script 2>&1 | FileCheck %s | |
| 10 | ||
| 11 | // RUN: echo "SECTIONS { \ | |
| 12 | // RUN: .dynamic : { *(.dynamic) } \ | |
| 13 | // RUN: .non_ro : { BYTE(1); } \ | |
| 14 | // RUN: .jcr : { *(.jcr) } \ | |
| 15 | // RUN: } " > %t2.script | |
| 16 | // RUN: not ld.lld --export-dynamic %t.o -o %t --script=%t2.script 2>&1 | FileCheck %s | |
| 17 | ||
| 18 | // CHECK: error: section: .jcr is not contiguous with other relro sections | |
| 19 | ||
| 20 | .global _start | |
| 21 | _start: | |
| 22 | ||
| 23 | // non-empty relro section | |
| 24 | .section .jcr, "aw", @progbits | |
| 25 | .quad 0 |
deps/lld/test/ELF/relro-non-contiguous.s created+28| ... | ... | @@ -0,0 +1,28 @@ |
| 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/copy-in-shared.s -o %t2.o | |
| 3 | // RUN: ld.lld -shared %t.o %t2.o -o %t.so | |
| 4 | ||
| 5 | // Place the .got.plt (non relro) immediately after .dynamic. This is the | |
| 6 | // reverse order of the non-linker script case. The linker created .bss.rel.ro | |
| 7 | // section will be placed after .got.plt causing the relro to be non-contiguous. | |
| 8 | // RUN: echo "SECTIONS { \ | |
| 9 | // RUN: .dynamic : { *(.dynamic) } \ | |
| 10 | // RUN: .got.plt : { *(.got.plt) } \ | |
| 11 | // RUN: } " > %t.script | |
| 12 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t3.o | |
| 13 | ||
| 14 | // Expect error for non-contiguous relro | |
| 15 | // 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 | // RUN: ld.lld %t3.o %t.so -z norelro -o %t --script=%t.script | |
| 18 | // REQUIRES: x86 | |
| 19 | ||
| 20 | // CHECK: error: section: .bss.rel.ro is not contiguous with other relro sections | |
| 21 | .section .text, "ax", @progbits | |
| 22 | .global _start | |
| 23 | .global bar | |
| 24 | .global foo | |
| 25 | _start: | |
| 26 | .quad bar | |
| 27 | .quad foo | |
| 28 |
deps/lld/test/ELF/relro-omagic.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | 3 | # RUN: ld.lld -shared %t2.o -o %t2.so -soname relro-omagic.s.tmp2.so |
| 4 | # RUN: ld.lld -N %t.o %t2.so -o %t | |
| 4 | # RUN: ld.lld --hash-style=sysv -N %t.o %t2.so -o %t | |
| 5 | 5 | # RUN: llvm-objdump -section-headers %t | FileCheck --check-prefix=NORELRO %s |
| 6 | 6 | # RUN: llvm-readobj --program-headers %t | FileCheck --check-prefix=NOPHDRS %s |
| 7 | 7 |
deps/lld/test/ELF/relro-script.s created+29| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | // REQUIRES: x86 | |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t.o | |
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/copy-in-shared.s -o %t2.o | |
| 4 | // RUN: ld.lld -shared %t.o %t2.o -o %t.so | |
| 5 | ||
| 6 | // ld.bfd and gold use .data.rel.ro rather than .bss.rel.ro. When a linker | |
| 7 | // script, such as ld.bfd's internal linker script has a .data.rel.ro | |
| 8 | // OutputSection we rename .bss.rel.ro to .data.rel.ro.bss in order to match in | |
| 9 | // .data.rel.ro. This keeps the relro sections contiguous. | |
| 10 | ||
| 11 | // Use the same sections and ordering as the ld.bfd internal linker script. | |
| 12 | // RUN: echo "SECTIONS { \ | |
| 13 | // RUN: .data.rel.ro : { *(.data.rel.ro .data.rel.ro.*) } \ | |
| 14 | // RUN: .dynamic : { *(.dynamic) } \ | |
| 15 | // RUN: .got : { *(.got) } \ | |
| 16 | // RUN: .got.plt : { *(.got.plt) } \ | |
| 17 | // RUN: } " > %t.script | |
| 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 | |
| 20 | ||
| 21 | // CHECK: .data.rel.ro | |
| 22 | // CHECK-NEXT: <internal>:(.bss.rel.ro) | |
| 23 | .section .text, "ax", @progbits | |
| 24 | .global _start | |
| 25 | .global bar | |
| 26 | .global foo | |
| 27 | _start: | |
| 28 | .quad bar | |
| 29 | .quad foo |
deps/lld/test/ELF/reproduce-thin-archive.s+6| ... | ... | @@ -5,11 +5,17 @@ |
| 5 | 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.dir/foo.o |
| 6 | 6 | # RUN: cd %t.dir |
| 7 | 7 | # RUN: llvm-ar --format=gnu rcT foo.a foo.o |
| 8 | ||
| 8 | 9 | # RUN: ld.lld -m elf_x86_64 foo.a -o bar --reproduce repro.tar |
| 9 | 10 | # RUN: tar xf repro.tar |
| 10 | 11 | # RUN: diff foo.a repro/%:t.dir/foo.a |
| 11 | 12 | # RUN: diff foo.o repro/%:t.dir/foo.o |
| 12 | 13 | |
| 14 | # RUN: ld.lld -m elf_x86_64 --whole-archive foo.a -o bar --reproduce repro2.tar | |
| 15 | # RUN: tar xf repro2.tar | |
| 16 | # RUN: diff foo.a repro2/%:t.dir/foo.a | |
| 17 | # RUN: diff foo.o repro2/%:t.dir/foo.o | |
| 18 | ||
| 13 | 19 | .globl _start |
| 14 | 20 | _start: |
| 15 | 21 | nop |
deps/lld/test/ELF/reproduce.s+20-11| ... | ... | @@ -33,27 +33,36 @@ |
| 33 | 33 | # RUN: echo "{};" > dyn |
| 34 | 34 | # RUN: echo > file |
| 35 | 35 | # RUN: echo > file2 |
| 36 | # RUN: echo "_start" > order | |
| 37 | # RUN: mkdir "sysroot with spaces" | |
| 36 | 38 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o 'foo bar' |
| 37 | 39 | # RUN: ld.lld --reproduce repro2.tar 'foo bar' -L"foo bar" -Lfile -Tfile2 \ |
| 38 | # RUN: --dynamic-list dyn -rpath file --script=file --version-script ver \ | |
| 39 | # RUN: --dynamic-linker "some unusual/path" -soname 'foo bar' -soname='foo bar' | |
| 40 | # RUN: --dynamic-list dyn -rpath file --script=file --symbol-ordering-file order \ | |
| 41 | # RUN: --sysroot "sysroot with spaces" --sysroot="sysroot with spaces" \ | |
| 42 | # RUN: --version-script ver --dynamic-linker "some unusual/path" -soname 'foo bar' \ | |
| 43 | # RUN: -soname='foo bar' | |
| 40 | 44 | # RUN: tar xf repro2.tar |
| 41 | 45 | # RUN: FileCheck %s --check-prefix=RSP2 < repro2/response.txt |
| 46 | # RSP2: --chroot . | |
| 42 | 47 | # RSP2: "{{.*}}foo bar" |
| 43 | # RSP2-NEXT: -L "{{.*}}foo bar" | |
| 44 | # RSP2-NEXT: -L {{.+}}file | |
| 45 | # RSP2-NEXT: --script {{.+}}file2 | |
| 46 | # RSP2-NEXT: --dynamic-list {{.+}}dyn | |
| 47 | # RSP2-NEXT: -rpath {{.+}}file | |
| 48 | # RSP2-NEXT: --script {{.+}}file | |
| 49 | # RSP2-NEXT: --version-script [[PATH:.*]]ver | |
| 48 | # RSP2-NEXT: --library-path "[[BASEDIR:.+]]/foo bar" | |
| 49 | # RSP2-NEXT: --library-path [[BASEDIR]]/file | |
| 50 | # RSP2-NEXT: --script [[BASEDIR]]/file2 | |
| 51 | # RSP2-NEXT: --dynamic-list [[BASEDIR]]/dyn | |
| 52 | # RSP2-NEXT: -rpath [[BASEDIR]]/file | |
| 53 | # RSP2-NEXT: --script [[BASEDIR]]/file | |
| 54 | # RSP2-NEXT: --symbol-ordering-file [[BASEDIR]]/order | |
| 55 | # RSP2-NEXT: --sysroot "[[BASEDIR]]/sysroot with spaces" | |
| 56 | # RSP2-NEXT: --sysroot "[[BASEDIR]]/sysroot with spaces" | |
| 57 | # RSP2-NEXT: --version-script [[BASEDIR]]/ver | |
| 50 | 58 | # RSP2-NEXT: --dynamic-linker "some unusual/path" |
| 51 | # RSP2-NEXT: -soname="foo bar" | |
| 52 | # RSP2-NEXT: -soname="foo bar" | |
| 59 | # RSP2-NEXT: -soname "foo bar" | |
| 60 | # RSP2-NEXT: -soname "foo bar" | |
| 53 | 61 | |
| 54 | 62 | # RUN: tar tf repro2.tar | FileCheck %s |
| 55 | 63 | # CHECK: repro2/response.txt |
| 56 | 64 | # CHECK-NEXT: repro2/version.txt |
| 65 | # CHECK-NEXT: repro2/{{.*}}/order | |
| 57 | 66 | # CHECK-NEXT: repro2/{{.*}}/dyn |
| 58 | 67 | # CHECK-NEXT: repro2/{{.*}}/ver |
| 59 | 68 | # CHECK-NEXT: repro2/{{.*}}/foo bar |
deps/lld/test/ELF/resolution-end.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution-end.s -o %t2.o |
| 3 | 3 | # RUN: ld.lld -shared -o %t2.so %t2.o |
| 4 | # RUN: ld.lld %t1.o %t2.so -o %t | |
| 4 | # RUN: ld.lld --hash-style=sysv %t1.o %t2.so -o %t | |
| 5 | 5 | # RUN: llvm-readobj -t -s -section-data %t | FileCheck %s |
| 6 | 6 | # REQUIRES: x86 |
| 7 | 7 |
deps/lld/test/ELF/retain-symbols-file.s+2-2| ... | ... | @@ -2,11 +2,11 @@ |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 3 | 3 | # RUN: echo "bar" > %t_retain.txt |
| 4 | 4 | # RUN: echo "foo" >> %t_retain.txt |
| 5 | # RUN: ld.lld -shared --retain-symbols-file=%t_retain.txt %t -o %t2 | |
| 5 | # RUN: ld.lld --hash-style=sysv -shared --retain-symbols-file=%t_retain.txt %t -o %t2 | |
| 6 | 6 | # RUN: llvm-readobj --dyn-symbols %t2 | FileCheck %s |
| 7 | 7 | |
| 8 | 8 | ## Check separate form. |
| 9 | # RUN: ld.lld -shared --retain-symbols-file %t_retain.txt %t -o %t2 | |
| 9 | # RUN: ld.lld --hash-style=sysv -shared --retain-symbols-file %t_retain.txt %t -o %t2 | |
| 10 | 10 | # RUN: llvm-readobj --dyn-symbols %t2 | FileCheck %s |
| 11 | 11 | |
| 12 | 12 | # CHECK: DynamicSymbols [ |
deps/lld/test/ELF/section-metadata-err.s+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 4 | 4 | # RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s |
| 5 | 5 | |
| 6 | # CHECK: error: Merge and .eh_frame sections are not supported with SHF_LINK_ORDER {{.*}}section-metadata-err.s.tmp.o:(.foo) | |
| 6 | # CHECK: error: a section with SHF_LINK_ORDER should not refer a non-regular section: {{.*}}section-metadata-err.s.tmp.o:(.foo) | |
| 7 | 7 | |
| 8 | 8 | .global _start |
| 9 | 9 | _start: |
deps/lld/test/ELF/segments.s+5| ... | ... | @@ -1,7 +1,10 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | ||
| 3 | 4 | # RUN: ld.lld %t -o %t1 |
| 4 | 5 | # RUN: llvm-readobj --program-headers %t1 | FileCheck --check-prefix=ROSEGMENT %s |
| 6 | # RUN: ld.lld --omagic --no-omagic %t -o %t1 | |
| 7 | # RUN: llvm-readobj --program-headers %t1 | FileCheck --check-prefix=ROSEGMENT %s | |
| 5 | 8 | |
| 6 | 9 | # ROSEGMENT: ProgramHeader { |
| 7 | 10 | # ROSEGMENT: Type: PT_LOAD |
| ... | ... | @@ -76,6 +79,8 @@ |
| 76 | 79 | |
| 77 | 80 | # RUN: ld.lld -N %t -o %t3 |
| 78 | 81 | # RUN: llvm-readobj --program-headers %t3 | FileCheck --check-prefix=OMAGIC %s |
| 82 | # RUN: ld.lld --omagic %t -o %t3 | |
| 83 | # RUN: llvm-readobj --program-headers %t3 | FileCheck --check-prefix=OMAGIC %s | |
| 79 | 84 | |
| 80 | 85 | # OMAGIC: ProgramHeader { |
| 81 | 86 | # OMAGIC: Type: PT_LOAD |
deps/lld/test/ELF/shared-lazy.s created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | |
| 2 | // RUN: rm -f %t1.a | |
| 3 | // RUN: llvm-ar rc %t1.a %t1.o | |
| 4 | // RUN: ld.lld %t1.o -o %t1.so -shared | |
| 5 | // RUN: echo ".global foo" > %t2.s | |
| 6 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2.o | |
| 7 | // RUN: ld.lld %t1.a %t1.so %t2.o -o %t.so -shared | |
| 8 | // RUN: llvm-readelf --dyn-symbols %t.so | FileCheck %s | |
| 9 | ||
| 10 | // Test that 'foo' from %t1.so is used and we don't fetch a member | |
| 11 | // from the archive. | |
| 12 | ||
| 13 | // CHECK: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND foo | |
| 14 | ||
| 15 | .global foo | |
| 16 | foo: |
deps/lld/test/ELF/shared.s+3-3| ... | ... | @@ -1,10 +1,10 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o |
| 2 | 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 | |
| 3 | // RUN: ld.lld --hash-style=sysv -shared %t2.o -o %t2.so | |
| 4 | 4 | // RUN: llvm-readobj -s %t2.so | FileCheck --check-prefix=SO %s |
| 5 | // RUN: ld.lld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t | |
| 5 | // RUN: ld.lld --hash-style=sysv -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t | |
| 6 | 6 | // RUN: llvm-readobj --program-headers --dynamic-table -t -s -dyn-symbols -section-data -hash-table %t | FileCheck %s |
| 7 | // RUN: ld.lld %t.o %t2.so %t2.so -o %t2 | |
| 7 | // RUN: ld.lld --hash-style=sysv %t.o %t2.so %t2.so -o %t2 | |
| 8 | 8 | // RUN: llvm-readobj -dyn-symbols %t2 | FileCheck --check-prefix=DONT_EXPORT %s |
| 9 | 9 | // REQUIRES: x86 |
| 10 | 10 |
deps/lld/test/ELF/shlib-undefined-shared.s created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 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 %t1.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 -shared -version-script %t.script -o %t2.so %t2.o %t1.so | |
| 9 | # RUN: llvm-nm -g %t2.so | 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 |
deps/lld/test/ELF/silent-ignore.test created+20| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | RUN: ld.lld --version \ | |
| 2 | RUN: -allow-shlib-undefined \ | |
| 3 | RUN: -cref \ | |
| 4 | RUN: -g \ | |
| 5 | RUN: -no-add-needed \ | |
| 6 | RUN: -no-allow-shlib-undefined \ | |
| 7 | RUN: -no-copy-dt-needed-entries \ | |
| 8 | RUN: -no-ctors-in-init-array \ | |
| 9 | RUN: -no-keep-memory \ | |
| 10 | RUN: -no-warn-common \ | |
| 11 | RUN: -no-warn-mismatch \ | |
| 12 | RUN: -sort-common \ | |
| 13 | RUN: -stats \ | |
| 14 | RUN: -warn-execstack \ | |
| 15 | RUN: -warn-once \ | |
| 16 | RUN: -warn-shared-textrel \ | |
| 17 | RUN: -EB \ | |
| 18 | RUN: -EL \ | |
| 19 | RUN: -Qy | |
| 20 | RUN: not ld.lld --version --not-an-ignored-argument |
deps/lld/test/ELF/sort-norosegment.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 3 | 3 | |
| 4 | # RUN: ld.lld -no-rosegment -o %t1 %t -shared | |
| 4 | # RUN: ld.lld --hash-style=sysv -no-rosegment -o %t1 %t -shared | |
| 5 | 5 | # RUN: llvm-readobj -elf-output-style=GNU -s %t1 | FileCheck %s |
| 6 | 6 | |
| 7 | 7 | # CHECK: .text {{.*}} AX |
deps/lld/test/ELF/startstop-gccollect.s+9-3| ... | ... | @@ -11,21 +11,27 @@ |
| 11 | 11 | # RUN: ld.lld %t --gc-sections -o %tout |
| 12 | 12 | # RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s |
| 13 | 13 | |
| 14 | # RUN: echo ".global __start_foo; __start_foo:" > %t2.s | |
| 15 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t2.s -o %t2.o | |
| 16 | # RUN: ld.lld -shared %t2.o -o %t2.so | |
| 17 | # RUN: ld.lld %t --gc-sections -o %tout %t2.so | |
| 18 | # RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s | |
| 19 | ||
| 14 | 20 | # DISASM: _start: |
| 15 | 21 | # DISASM-NEXT: 201000: e8 05 00 00 00 callq 5 <__start_foo> |
| 16 | # DISASM-NEXT: 201005: e8 01 00 00 00 callq 1 <__start_bar> | |
| 22 | # DISASM-NEXT: 201005: e8 02 00 00 00 callq 2 <__stop_bar> | |
| 17 | 23 | # DISASM-NEXT: Disassembly of section foo: |
| 18 | 24 | # DISASM-NEXT: __start_foo: |
| 19 | 25 | # DISASM-NEXT: 20100a: 90 nop |
| 20 | 26 | # DISASM-NEXT: Disassembly of section bar: |
| 21 | # DISASM-NEXT: __start_bar: | |
| 27 | # DISASM-NEXT: bar: | |
| 22 | 28 | # DISASM-NEXT: 20100b: 90 nop |
| 23 | 29 | |
| 24 | 30 | .global _start |
| 25 | 31 | .text |
| 26 | 32 | _start: |
| 27 | 33 | callq __start_foo |
| 28 | callq __start_bar | |
| 34 | callq __stop_bar | |
| 29 | 35 | |
| 30 | 36 | .section foo,"ax" |
| 31 | 37 | nop |
deps/lld/test/ELF/startstop.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | // RUN: ld.lld %t -o %tout -shared | |
| 3 | // RUN: ld.lld --hash-style=sysv %t -o %tout -shared | |
| 4 | 4 | // RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s |
| 5 | 5 | // RUN: llvm-readobj -symbols -r %tout | FileCheck -check-prefix=SYMBOL %s |
| 6 | 6 |
deps/lld/test/ELF/string-gc.s+2-2| ... | ... | @@ -14,7 +14,7 @@ |
| 14 | 14 | // CHECK-NEXT: } |
| 15 | 15 | // CHECK-NEXT: Symbol { |
| 16 | 16 | // CHECK-NEXT: Name: s3 |
| 17 | // CHECK-NEXT: Value: 0x200125 | |
| 17 | // CHECK-NEXT: Value: 0x200120 | |
| 18 | 18 | // CHECK-NEXT: Size: 0 |
| 19 | 19 | // CHECK-NEXT: Binding: Local (0x0) |
| 20 | 20 | // CHECK-NEXT: Type: Object (0x1) |
| ... | ... | @@ -23,7 +23,7 @@ |
| 23 | 23 | // CHECK-NEXT: } |
| 24 | 24 | // CHECK-NEXT: Symbol { |
| 25 | 25 | // CHECK-NEXT: Name: s1 |
| 26 | // CHECK-NEXT: Value: 0x200120 | |
| 26 | // CHECK-NEXT: Value: 0x200125 | |
| 27 | 27 | // CHECK-NEXT: Size: 0 |
| 28 | 28 | // CHECK-NEXT: Binding: Local (0x0) |
| 29 | 29 | // CHECK-NEXT: Type: Object (0x1) |
deps/lld/test/ELF/strip-debug.s+8-19| ... | ... | @@ -1,25 +1,14 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -g %s -o %t | |
| 4 | # RUN: ld.lld %t -o %t2 | |
| 5 | # RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=DEFAULT %s | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | |
| 6 | 3 | # RUN: ld.lld %t -o %t2 --strip-debug |
| 7 | # RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=STRIP %s | |
| 4 | # RUN: llvm-readobj -sections %t2 | FileCheck %s | |
| 8 | 5 | # RUN: ld.lld %t -o %t2 -S |
| 9 | # RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=STRIP %s | |
| 6 | # RUN: llvm-readobj -sections %t2 | FileCheck %s | |
| 10 | 7 | # RUN: ld.lld %t -o %t2 --strip-all |
| 11 | # RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=STRIP %s | |
| 12 | ||
| 13 | # DEFAULT: Name: .debug_info | |
| 14 | # DEFAULT: Name: .debug_abbrev | |
| 15 | # DEFAULT: Name: .debug_aranges | |
| 16 | # DEFAULT: Name: .debug_line | |
| 8 | # RUN: llvm-readobj -sections %t2 | FileCheck %s | |
| 17 | 9 | |
| 18 | # STRIP-NOT: Name: .debug_info | |
| 19 | # STRIP-NOT: Name: .debug_abbrev | |
| 20 | # STRIP-NOT: Name: .debug_aranges | |
| 21 | # STRIP-NOT: Name: .debug_line | |
| 10 | # CHECK-NOT: Foo | |
| 11 | # CHECK-NOT: Bar | |
| 22 | 12 | |
| 23 | .globl _start | |
| 24 | _start: | |
| 25 | ret | |
| 13 | .section .debug_Foo,"",@progbits | |
| 14 | .section .zdebug_Bar,"",@progbits |
deps/lld/test/ELF/symbol-ordering-file2.s created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 3 | # RUN: echo "bar" > %t.order | |
| 4 | # RUN: ld.lld --symbol-ordering-file %t.order -shared %t.o -o %t.so | |
| 5 | # RUN: llvm-nm %t.so | FileCheck %s | |
| 6 | ||
| 7 | # CHECK: 0000000000002000 d _DYNAMIC | |
| 8 | # CHECK-NEXT: 0000000000001000 T bar | |
| 9 | # CHECK-NEXT: 0000000000001004 T foo | |
| 10 | ||
| 11 | .section .text.foo,"ax",@progbits | |
| 12 | .align 4 | |
| 13 | .global foo | |
| 14 | foo: | |
| 15 | retq | |
| 16 | ||
| 17 | .section .text.bar,"ax",@progbits | |
| 18 | .align 4 | |
| 19 | .global bar | |
| 20 | bar: | |
| 21 | retq |
deps/lld/test/ELF/synthetic-got.s+2-2| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 3 | 3 | # RUN: echo "SECTIONS { }" > %t0.script |
| 4 | # RUN: ld.lld -shared %t.o -o %t0.out --script %t0.script | |
| 4 | # RUN: ld.lld --hash-style=sysv -shared %t.o -o %t0.out --script %t0.script | |
| 5 | 5 | # RUN: llvm-objdump -section-headers %t0.out | FileCheck %s --check-prefix=GOT |
| 6 | 6 | # RUN: llvm-objdump -s -section=.got -section=.got.plt %t0.out \ |
| 7 | 7 | # RUN: | FileCheck %s --check-prefix=GOTDATA |
| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | # GOTDATA-NEXT: 01d0 00000000 00000000 |
| 17 | 17 | |
| 18 | 18 | # RUN: echo "SECTIONS { .mygot : { *(.got) *(.got.plt) } }" > %t1.script |
| 19 | # RUN: ld.lld -shared %t.o -o %t1.out --script %t1.script | |
| 19 | # RUN: ld.lld --hash-style=sysv -shared %t.o -o %t1.out --script %t1.script | |
| 20 | 20 | # RUN: llvm-objdump -section-headers %t1.out | FileCheck %s --check-prefix=MYGOT |
| 21 | 21 | # RUN: llvm-objdump -s -section=.mygot %t1.out | FileCheck %s --check-prefix=MYGOTDATA |
| 22 | 22 |
deps/lld/test/ELF/sysroot.s+2| ... | ... | @@ -28,6 +28,8 @@ |
| 28 | 28 | // Should substitute SysRoot if specified |
| 29 | 29 | // RUN: ld.lld -o %t/r %t/m.o --sysroot=%t -L=lib -l:libls.a |
| 30 | 30 | // RUN: ld.lld -o %t/r %t/m.o --sysroot=%t -L=/lib -l:libls.a |
| 31 | // Check alias. | |
| 32 | // RUN: ld.lld -o %t/r %t/m.o --sysroot %t -L=lib -l:libls.a | |
| 31 | 33 | |
| 32 | 34 | // Should not substitute SysRoot if the directory name does not start with '=' |
| 33 | 35 | // RUN: not ld.lld -o %t/r %r/m.o --sysroot=%t -Llib -l:libls.a |
deps/lld/test/ELF/sysv-hash-no-rosegment.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: ld.lld -shared --no-rosegment -o %t %t.o | |
| 4 | # RUN: llvm-readobj -hash-table %t | FileCheck %s | |
| 5 | ||
| 6 | # CHECK: HashTable { | |
| 7 | # CHECK-NEXT: Num Buckets: 2 | |
| 8 | # CHECK-NEXT: Num Chains: 2 | |
| 9 | # CHECK-NEXT: Buckets: [1, 0] | |
| 10 | # CHECK-NEXT: Chains: [0, 0] | |
| 11 | # CHECK-NEXT: } | |
| 12 | ||
| 13 | callq undef@PLT |
deps/lld/test/ELF/tls-dynamic-i686.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t |
| 3 | // RUN: ld.lld -shared %t -o %tout | |
| 3 | // RUN: ld.lld --hash-style=sysv -shared %t -o %tout | |
| 4 | 4 | // RUN: llvm-readobj -sections -relocations %tout | FileCheck %s |
| 5 | 5 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS |
| 6 | 6 |
deps/lld/test/ELF/tls-dynamic.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | // RUN: ld.lld -shared %t -o %tout | |
| 3 | // RUN: ld.lld --hash-style=sysv -shared %t -o %tout | |
| 4 | 4 | // RUN: llvm-readobj -sections -relocations %tout | FileCheck %s |
| 5 | 5 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS |
| 6 | 6 |
deps/lld/test/ELF/tls-got.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-got.s -o %t2.o |
| 3 | 3 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| 4 | // RUN: ld.lld -e main %t1.o %t2.so -o %t3 | |
| 4 | // RUN: ld.lld --hash-style=sysv -e main %t1.o %t2.so -o %t3 | |
| 5 | 5 | // RUN: llvm-readobj -s -r %t3 | FileCheck %s |
| 6 | 6 | // RUN: llvm-objdump -d %t3 | FileCheck --check-prefix=DISASM %s |
| 7 | 7 |
deps/lld/test/ELF/tls-i686.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t |
| 3 | 3 | // RUN: ld.lld %t -o %tout |
| 4 | // RUN: ld.lld %t -shared -o %tsharedout | |
| 4 | // RUN: ld.lld --hash-style=sysv %t -shared -o %tsharedout | |
| 5 | 5 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS |
| 6 | 6 | // RUN: llvm-readobj -r %tout | FileCheck %s --check-prefix=RELOC |
| 7 | 7 | // RUN: llvm-objdump -d %tsharedout | FileCheck %s --check-prefix=DISSHARED |
deps/lld/test/ELF/tls-initial-exec-local.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: ld.lld -shared %t.o -o %t | |
| 3 | // RUN: ld.lld --hash-style=sysv -shared %t.o -o %t | |
| 4 | 4 | // RUN: llvm-readobj -r -s %t | FileCheck %s |
| 5 | 5 | // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s |
| 6 | 6 |
deps/lld/test/ELF/tls-opt-gdie.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-opt-gdie.s -o %tso.o |
| 3 | 3 | // RUN: ld.lld -shared %tso.o -o %t.so |
| 4 | // RUN: ld.lld %t.o %t.so -o %t1 | |
| 4 | // RUN: ld.lld --hash-style=sysv %t.o %t.so -o %t1 | |
| 5 | 5 | // RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=RELOC %s |
| 6 | 6 | // RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s |
| 7 | 7 |
deps/lld/test/ELF/tls-opt-gdiele-i686.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-gdiele-i686.s -o %tso.o |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| 3 | 3 | // RUN: ld.lld -shared %tso.o -o %tso |
| 4 | // RUN: ld.lld %t.o %tso -o %tout | |
| 4 | // RUN: ld.lld --hash-style=sysv %t.o %tso -o %tout | |
| 5 | 5 | // RUN: llvm-readobj -r %tout | FileCheck --check-prefix=NORELOC %s |
| 6 | 6 | // RUN: llvm-objdump -d %tout | FileCheck --check-prefix=DISASM %s |
| 7 | 7 |
deps/lld/test/ELF/tls-opt-iele-i686-nopic.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o %tso.o |
| 3 | 3 | // RUN: ld.lld -shared %tso.o -o %tso |
| 4 | // RUN: ld.lld %t.o %tso -o %t1 | |
| 4 | // RUN: ld.lld --hash-style=sysv %t.o %tso -o %t1 | |
| 5 | 5 | // RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=GOTREL %s |
| 6 | 6 | // RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s |
| 7 | 7 |
deps/lld/test/ELF/tls-static.s+12-4| ... | ... | @@ -3,12 +3,20 @@ |
| 3 | 3 | // RUN: ld.lld -static %t -o %tout |
| 4 | 4 | // RUN: ld.lld %t -o %tout |
| 5 | 5 | // RUN: ld.lld -shared %tso -o %tshared |
| 6 | // RUN: not ld.lld -static %t %tshared -o %tout 2>&1 | FileCheck %s | |
| 6 | // RUN: ld.lld -static %t %tshared -o %tout | |
| 7 | 7 | // REQUIRES: x86 |
| 8 | 8 | |
| 9 | 9 | .global _start |
| 10 | 10 | _start: |
| 11 | call __tls_get_addr | |
| 11 | data16 | |
| 12 | leaq foobar@TLSGD(%rip), %rdi | |
| 13 | data16 | |
| 14 | data16 | |
| 15 | rex64 | |
| 16 | callq __tls_get_addr@PLT | |
| 12 | 17 | |
| 13 | // CHECK: error: undefined symbol: __tls_get_addr | |
| 14 | // CHECK: >>> referenced by {{.*}}:(.text+0x1) | |
| 18 | ||
| 19 | .section .tdata,"awT",@progbits | |
| 20 | .global foobar | |
| 21 | foobar: | |
| 22 | .long 42 |
deps/lld/test/ELF/tls-two-relocs.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | // RUN: ld.lld %t -o %tout -shared | |
| 3 | // RUN: ld.lld --hash-style=sysv %t -o %tout -shared | |
| 4 | 4 | // RUN: llvm-readobj -r %tout | FileCheck %s |
| 5 | 5 | |
| 6 | 6 | data16 |
deps/lld/test/ELF/trace-symbols.s+9-5| ... | ... | @@ -31,19 +31,23 @@ |
| 31 | 31 | # RUN: %t %t2 %t1 -o %t4 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s |
| 32 | 32 | # RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \ |
| 33 | 33 | # RUN: FileCheck -check-prefix=OBJECTD2FOO %s |
| 34 | # RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 2>&1 | \ | |
| 35 | # RUN: FileCheck -check-prefix=OBJECTD2FOO %s | |
| 36 | 34 | # OBJECTD2FOO: trace-symbols.s.tmp2: definition of foo |
| 37 | 35 | |
| 36 | # RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 2>&1 | \ | |
| 37 | # RUN: FileCheck -check-prefix=FOO_AND_COMMON %s | |
| 38 | # FOO_AND_COMMON: trace-symbols.s.tmp: reference to foo | |
| 39 | # FOO_AND_COMMON: trace-symbols.s.tmp2: definition of foo | |
| 40 | # FOO_AND_COMMON: trace-symbols.s.tmp1.a: lazy definition of common | |
| 41 | ||
| 38 | 42 | # RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \ |
| 39 | 43 | # RUN: FileCheck -check-prefix=SHLIBDCOMMON %s |
| 40 | # SHLIBDCOMMON: trace-symbols.s.tmp1.so: definition of common | |
| 44 | # SHLIBDCOMMON: trace-symbols.s.tmp1.so: shared definition of common | |
| 41 | 45 | |
| 42 | 46 | # RUN: ld.lld -y foo -y common %t %t2.so %t1.so -o %t3 2>&1 | \ |
| 43 | 47 | # RUN: FileCheck -check-prefix=SHLIBD2FOO %s |
| 44 | 48 | # RUN: ld.lld -y foo %t %t1.a %t2.so -o %t3 | \ |
| 45 | 49 | # RUN: FileCheck -check-prefix=NO-SHLIBD2FOO %s |
| 46 | # SHLIBD2FOO: trace-symbols.s.tmp2.so: definition of foo | |
| 50 | # SHLIBD2FOO: trace-symbols.s.tmp2.so: shared definition of foo | |
| 47 | 51 | # NO-SHLIBD2FOO-NOT: trace-symbols.s.tmp2.so: definition of foo |
| 48 | 52 | |
| 49 | 53 | # RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 2>&1 | \ |
| ... | ... | @@ -61,7 +65,7 @@ |
| 61 | 65 | |
| 62 | 66 | # RUN: ld.lld -y bar %t %t1.so %t2.so -o %t3 | \ |
| 63 | 67 | # RUN: FileCheck -check-prefix=SHLIBDBAR %s |
| 64 | # SHLIBDBAR: trace-symbols.s.tmp2.so: definition of bar | |
| 68 | # SHLIBDBAR: trace-symbols.s.tmp2.so: shared definition of bar | |
| 65 | 69 | |
| 66 | 70 | # RUN: ld.lld -y foo -y bar %t %t1.so %t2.so -o %t3 | \ |
| 67 | 71 | # RUN: FileCheck -check-prefix=SHLIBRBAR %s |
deps/lld/test/ELF/typed-undef.s created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # We used to crash on this, check that we don't | |
| 4 | ||
| 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 | |
| 7 | ||
| 8 | .global _start | |
| 9 | _start: | |
| 10 | .quad foo - . | |
| 11 | .type foo, @object |
deps/lld/test/ELF/undef-broken-debug.test created+47| ... | ... | @@ -0,0 +1,47 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: yaml2obj %s -o %t.o | |
| 3 | # RUN: not ld.lld %t.o -o %t.exe 2>&1 | FileCheck %s | |
| 4 | ||
| 5 | # The debug info has a broken relocation. Check that we don't crash | |
| 6 | # and still report the undefined symbol. | |
| 7 | ||
| 8 | # CHECK: error: unsupported relocation target while parsing debug info | |
| 9 | # CHECK: error: undefined symbol: bar | |
| 10 | ||
| 11 | --- !ELF | |
| 12 | FileHeader: | |
| 13 | Class: ELFCLASS64 | |
| 14 | Data: ELFDATA2LSB | |
| 15 | Type: ET_REL | |
| 16 | Machine: EM_X86_64 | |
| 17 | Sections: | |
| 18 | - Name: .text | |
| 19 | Type: SHT_PROGBITS | |
| 20 | Flags: [ SHF_ALLOC, SHF_EXECINSTR ] | |
| 21 | Content: '0000000000000000' | |
| 22 | - Name: .rela.text | |
| 23 | Type: SHT_RELA | |
| 24 | AddressAlign: 8 | |
| 25 | Link: .symtab | |
| 26 | Info: .text | |
| 27 | Relocations: | |
| 28 | - Offset: 0x0000000000000000 | |
| 29 | Symbol: bar | |
| 30 | Type: R_X86_64_64 | |
| 31 | - Name: .debug_line | |
| 32 | Type: SHT_PROGBITS | |
| 33 | Content: 3300000002001C0000000101FB0E0D000101010100000001000001006162632E7300000000000009020000000000000000140208000101 | |
| 34 | - Name: .rela.debug_line | |
| 35 | AddressAlign: 8 | |
| 36 | Type: SHT_RELA | |
| 37 | Link: .symtab | |
| 38 | Info: .debug_line | |
| 39 | Relocations: | |
| 40 | - Offset: 0x0000000000000029 | |
| 41 | Symbol: bar | |
| 42 | Type: R_X86_64_64 | |
| 43 | Symbols: | |
| 44 | Global: | |
| 45 | - Name: _start | |
| 46 | Section: .text | |
| 47 | - Name: bar |
deps/lld/test/ELF/undef-version-script.s+3-3| ... | ... | @@ -3,9 +3,6 @@ |
| 3 | 3 | # RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so |
| 4 | 4 | # RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s |
| 5 | 5 | |
| 6 | # This does not match gold's behavior because gold does not create undefined | |
| 7 | # symbols in dynsym without an appropriate (e.g. PLT) relocation in the input. | |
| 8 | ||
| 9 | 6 | # CHECK: DynamicSymbols [ |
| 10 | 7 | # CHECK-NEXT: Symbol { |
| 11 | 8 | # CHECK-NEXT: Name: @ |
| ... | ... | @@ -38,3 +35,6 @@ |
| 38 | 35 | |
| 39 | 36 | .global foo |
| 40 | 37 | .weak bar |
| 38 | .data | |
| 39 | .dc.a foo | |
| 40 | .dc.a bar |
deps/lld/test/ELF/unresolved-symbols.s+3| ... | ... | @@ -13,6 +13,9 @@ |
| 13 | 13 | # RUN: not ld.lld %t1.o %t2.o -o %t --unresolved-symbols=xxx 2>&1 | \ |
| 14 | 14 | # RUN: FileCheck -check-prefix=ERR1 %s |
| 15 | 15 | # ERR1: unknown --unresolved-symbols value: xxx |
| 16 | ## Check alias. | |
| 17 | # RUN: not ld.lld %t1.o %t2.o -o %t --unresolved-symbols xxx 2>&1 | \ | |
| 18 | # RUN: FileCheck -check-prefix=ERR1 %s | |
| 16 | 19 | |
| 17 | 20 | ## Ignore all should not produce error for symbols from object except |
| 18 | 21 | ## case when --no-undefined specified. |
deps/lld/test/ELF/verdef-defaultver.s+2-2| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/verdef-defaultver.s -o %t1 |
| 4 | 4 | # RUN: echo "V1 { global: a; local: *; };" > %t.script |
| 5 | 5 | # RUN: echo "V2 { global: b; c; } V1;" >> %t.script |
| 6 | # RUN: ld.lld -shared -soname shared %t1 --version-script %t.script -o %t.so | |
| 6 | # RUN: ld.lld --hash-style=sysv -shared -soname shared %t1 --version-script %t.script -o %t.so | |
| 7 | 7 | # RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s |
| 8 | 8 | |
| 9 | 9 | # DSO: DynamicSymbols [ |
| ... | ... | @@ -107,7 +107,7 @@ |
| 107 | 107 | |
| 108 | 108 | ## Check that we can link against DSO produced. |
| 109 | 109 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2 |
| 110 | # RUN: ld.lld %t2 %t.so -o %t3 | |
| 110 | # RUN: ld.lld --hash-style=sysv %t2 %t.so -o %t3 | |
| 111 | 111 | # RUN: llvm-readobj -V -dyn-symbols %t3 | FileCheck --check-prefix=EXE %s |
| 112 | 112 | |
| 113 | 113 | # EXE: DynamicSymbols [ |
deps/lld/test/ELF/verdef.s+3-3| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | # RUN: echo "LIBSAMPLE_1.0 { global: a; local: *; };" > %t.script |
| 4 | 4 | # RUN: echo "LIBSAMPLE_2.0 { global: b; local: *; };" >> %t.script |
| 5 | 5 | # RUN: echo "LIBSAMPLE_3.0 { global: c; local: *; };" >> %t.script |
| 6 | # RUN: ld.lld --version-script %t.script -shared -soname shared %t.o -o %t.so | |
| 6 | # RUN: ld.lld --hash-style=sysv --version-script %t.script -shared -soname shared %t.o -o %t.so | |
| 7 | 7 | # RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s |
| 8 | 8 | |
| 9 | 9 | # DSO: Version symbols { |
| ... | ... | @@ -65,7 +65,7 @@ |
| 65 | 65 | |
| 66 | 66 | ## Check that we can link agains DSO we produced. |
| 67 | 67 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/verdef.s -o %tmain.o |
| 68 | # RUN: ld.lld %tmain.o %t.so -o %tout | |
| 68 | # RUN: ld.lld --hash-style=sysv %tmain.o %t.so -o %tout | |
| 69 | 69 | # RUN: llvm-readobj -V %tout | FileCheck --check-prefix=MAIN %s |
| 70 | 70 | |
| 71 | 71 | # MAIN: Version symbols { |
| ... | ... | @@ -100,7 +100,7 @@ |
| 100 | 100 | # RUN: echo "LIBSAMPLE_2.0 { global: b; local: *; };" >> %t.script |
| 101 | 101 | # RUN: echo "LIBSAMPLE_3.0 { global: c; local: *; };" >> %t.script |
| 102 | 102 | # RUN: echo "}" >> %t.script |
| 103 | # RUN: ld.lld --script %t.script -shared -soname shared %t.o -o %t2.so | |
| 103 | # RUN: ld.lld --hash-style=sysv --script %t.script -shared -soname shared %t.o -o %t2.so | |
| 104 | 104 | # RUN: llvm-readobj -V -dyn-symbols %t2.so | FileCheck --check-prefix=DSO %s |
| 105 | 105 | |
| 106 | 106 | .globl a |
deps/lld/test/ELF/verneed-as-needed-weak.s+5-1| ... | ... | @@ -1,6 +1,10 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/verneed1.s -o %t1.o | |
| 3 | # RUN: echo "v1 {}; v2 {}; v3 { local: *; };" > %t.script | |
| 4 | # RUN: ld.lld -shared %t1.o --version-script %t.script -o %t.so | |
| 5 | ||
| 2 | 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: ld.lld %t.o --as-needed %S/Inputs/verneed1.so -o %t | |
| 7 | # RUN: ld.lld %t.o --as-needed %t.so -o %t | |
| 4 | 8 | # RUN: llvm-readobj -V %t | FileCheck %s |
| 5 | 9 | |
| 6 | 10 | # CHECK: SHT_GNU_verneed { |
deps/lld/test/ELF/verneed-local.s+5-1| ... | ... | @@ -1,6 +1,10 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/verneed1.s -o %t1.o | |
| 3 | # RUN: echo "v1 {}; v2 {}; v3 { local: *; };" > %t.script | |
| 4 | # RUN: ld.lld -shared %t1.o --version-script %t.script -o %t.so | |
| 5 | ||
| 2 | 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: not ld.lld %t.o %S/Inputs/verneed1.so -o %t 2>&1 | FileCheck %s | |
| 7 | # RUN: not ld.lld %t.o %t.so -o %t 2>&1 | FileCheck %s | |
| 4 | 8 | |
| 5 | 9 | # CHECK: error: undefined symbol: f3 |
| 6 | 10 | # CHECK: >>> referenced by {{.*}}:(.text+0x1) |
deps/lld/test/ELF/verneed.s+7-1| ... | ... | @@ -1,6 +1,12 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/verneed1.s -o %t1.o | |
| 3 | # RUN: echo "v1 {}; v2 {}; v3 { local: *; };" > %t.script | |
| 4 | # RUN: ld.lld -shared %t1.o --version-script %t.script -o %t1.so -soname verneed1.so.0 | |
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/verneed2.s -o %t2.o | |
| 6 | # RUN: ld.lld -shared %t2.o --version-script %t.script -o %t2.so -soname verneed2.so.0 | |
| 7 | ||
| 2 | 8 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: ld.lld %t.o %S/Inputs/verneed1.so %S/Inputs/verneed2.so -o %t | |
| 9 | # RUN: ld.lld --hash-style=sysv %t.o %t1.so %t2.so -o %t | |
| 4 | 10 | # RUN: llvm-readobj -V -sections -section-data -dyn-symbols -dynamic-table %t | FileCheck %s |
| 5 | 11 | |
| 6 | 12 | # CHECK: Section { |
deps/lld/test/ELF/version-script-err.s-1| ... | ... | @@ -8,4 +8,3 @@ |
| 8 | 8 | // RUN: not ld.lld --version-script %terr1.script -shared %t.o -o %t.so 2>&1 | \ |
| 9 | 9 | // RUN: FileCheck -check-prefix=ERR1 %s |
| 10 | 10 | // ERR1: {{.*}}:1: unclosed quote |
| 11 | // ERR1-NEXT: {{.*}}: unexpected EOF |
deps/lld/test/ELF/version-script-extern.s+1-1| ... | ... | @@ -7,7 +7,7 @@ |
| 7 | 7 | # RUN: echo "LIBSAMPLE_2.0 { global:" >> %t.script |
| 8 | 8 | # RUN: echo ' extern "C" { _Z3bari; };' >> %t.script |
| 9 | 9 | # RUN: echo "};" >> %t.script |
| 10 | # RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so | |
| 10 | # RUN: ld.lld --hash-style=sysv --version-script %t.script -shared %t.o -o %t.so | |
| 11 | 11 | # RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s |
| 12 | 12 | |
| 13 | 13 | # DSO: DynamicSymbols [ |
deps/lld/test/ELF/version-script-twice.s+4| ... | ... | @@ -7,7 +7,11 @@ |
| 7 | 7 | |
| 8 | 8 | .weak	openat |
| 9 | 9 | openat: |
| 10 | ||
| 11 | .global openat@FBSD_1.1 | |
| 10 | 12 | openat@FBSD_1.1 = openat |
| 13 | ||
| 14 | .global openat@@FBSD_1.2 | |
| 11 | 15 | openat@@FBSD_1.2 = openat |
| 12 | 16 | |
| 13 | 17 | # CHECK-DAG: openat@FBSD_1.1 |
deps/lld/test/ELF/version-script.s+8-2| ... | ... | @@ -42,6 +42,12 @@ |
| 42 | 42 | # RUN: ld.lld --version-script %t.script --dynamic-list %t.list %t.o %t2.so -o %t2 |
| 43 | 43 | # RUN: llvm-readobj %t2 > /dev/null |
| 44 | 44 | |
| 45 | ## Check that we can handle multiple "--version-script" options. | |
| 46 | # RUN: echo "VERSION_1.0 { global : foo1; local : *; };" > %t7a.script | |
| 47 | # RUN: echo "VERSION_2.0 { global: foo3; local: *; };" > %t7b.script | |
| 48 | # RUN: ld.lld --version-script %t7a.script --version-script %t7b.script -shared %t.o %t2.so -o %t7.so | |
| 49 | # RUN: llvm-readobj -dyn-symbols %t7.so | FileCheck --check-prefix=VERDSO %s | |
| 50 | ||
| 45 | 51 | # DSO: DynamicSymbols [ |
| 46 | 52 | # DSO-NEXT: Symbol { |
| 47 | 53 | # DSO-NEXT: Name: @ |
| ... | ... | @@ -142,12 +148,12 @@ |
| 142 | 148 | # VERDSO-NEXT: ] |
| 143 | 149 | |
| 144 | 150 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 145 | # RUN: ld.lld -shared %t.o %t2.so -o %t.so | |
| 151 | # RUN: ld.lld --hash-style=sysv -shared %t.o %t2.so -o %t.so | |
| 146 | 152 | # RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=ALL %s |
| 147 | 153 | |
| 148 | 154 | # RUN: echo "{ global: foo1; foo3; };" > %t2.script |
| 149 | 155 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 150 | # RUN: ld.lld --version-script %t2.script -shared %t.o %t2.so -o %t.so | |
| 156 | # RUN: ld.lld --hash-style=sysv --version-script %t2.script -shared %t.o %t2.so -o %t.so | |
| 151 | 157 | # RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=ALL %s |
| 152 | 158 | |
| 153 | 159 | # ALL: DynamicSymbols [ |
deps/lld/test/ELF/weak-entry.s created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | |
| 3 | # RUN: ld.lld %t -o %tout | |
| 4 | # RUN: llvm-nm %tout | FileCheck %s | |
| 5 | ||
| 6 | # CHECK: w _start | |
| 7 | # CHECK-NEXT: T foo | |
| 8 | ||
| 9 | .global foo | |
| 10 | .weak _start | |
| 11 | .text | |
| 12 | foo: | |
| 13 | 	.dc.a _start |
deps/lld/test/ELF/weak-undef-export.s created+31| ... | ... | @@ -0,0 +1,31 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # Test that we don't fail with foo being undefined. | |
| 4 | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 6 | # RUN: ld.lld --export-dynamic %t.o -o %t | |
| 7 | # RUN: llvm-readobj -dyn-symbols %t | FileCheck %s | |
| 8 | ||
| 9 | # CHECK: DynamicSymbols [ | |
| 10 | # CHECK-NEXT: Symbol { | |
| 11 | # CHECK-NEXT: Name: @ (0) | |
| 12 | # CHECK-NEXT: Value: 0x0 | |
| 13 | # CHECK-NEXT: Size: 0 | |
| 14 | # CHECK-NEXT: Binding: Local (0x0) | |
| 15 | # CHECK-NEXT: Type: None (0x0) | |
| 16 | # CHECK-NEXT: Other: 0 | |
| 17 | # CHECK-NEXT: Section: Undefined (0x0) | |
| 18 | # CHECK-NEXT: } | |
| 19 | # CHECK-NEXT: Symbol { | |
| 20 | # CHECK-NEXT: Name: foo@ (1) | |
| 21 | # CHECK-NEXT: Value: 0x0 | |
| 22 | # CHECK-NEXT: Size: 0 | |
| 23 | # CHECK-NEXT: Binding: Weak (0x2) | |
| 24 | # CHECK-NEXT: Type: None (0x0) | |
| 25 | # CHECK-NEXT: Other: 0 | |
| 26 | # CHECK-NEXT: Section: Undefined (0x0) | |
| 27 | # CHECK-NEXT: } | |
| 28 | # CHECK-NEXT: ] | |
| 29 | ||
| 30 | .weak foo | |
| 31 | .quad foo |
deps/lld/test/ELF/weak-undef-lazy.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 %S/Inputs/weak-undef-lazy.s -o %t2.o | |
| 4 | # RUN: rm -f %t2.a | |
| 5 | # RUN: llvm-ar rc %t2.a %t2.o | |
| 6 | # RUN: ld.lld %t.o %t2.a -o %t --export-dynamic | |
| 7 | ||
| 8 | .global _start | |
| 9 | _start: | |
| 10 | .weak foobar | |
| 11 | .quad foobar |
deps/lld/test/ELF/weak-undef-rw.s created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | |
| 3 | # RUN: ld.lld %t.o -o %t --export-dynamic | |
| 4 | # RUN: llvm-readobj -r %t | FileCheck %s | |
| 5 | ||
| 6 | # CHECK: R_X86_64_64 foobar 0x0 | |
| 7 | ||
| 8 | .global _start | |
| 9 | _start: | |
| 10 | .data | |
| 11 | .weak foobar | |
| 12 | .quad foobar |
deps/lld/test/ELF/weak-undef-val.s created+26| ... | ... | @@ -0,0 +1,26 @@ |
| 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 --export-dynamic | |
| 4 | # RUN: llvm-readobj -s -section-data %t | FileCheck %s | |
| 5 | ||
| 6 | # CHECK: Name: .text | |
| 7 | # CHECK-NEXT: Type: SHT_PROGBITS | |
| 8 | # CHECK-NEXT: Flags [ | |
| 9 | # CHECK-NEXT: SHF_ALLOC | |
| 10 | # CHECK-NEXT: SHF_EXECINSTR | |
| 11 | # CHECK-NEXT: ] | |
| 12 | # CHECK-NEXT: Address: 0x201000 | |
| 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: 00F0DFFF | | |
| 21 | # CHECK-NEXT: ) | |
| 22 | ||
| 23 | .global _start | |
| 24 | _start: | |
| 25 | .weak foobar | |
| 26 | .long foobar - . |
deps/lld/test/ELF/weak-undef.s+12| ... | ... | @@ -13,9 +13,21 @@ |
| 13 | 13 | # CHECK-NEXT: Other: 0 |
| 14 | 14 | # CHECK-NEXT: Section: Undefined (0x0) |
| 15 | 15 | # CHECK-NEXT: } |
| 16 | # CHECK-NEXT: Symbol { | |
| 17 | # CHECK-NEXT: Name: foo@ | |
| 18 | # CHECK-NEXT: Value: 0x0 | |
| 19 | # CHECK-NEXT: Size: 0 | |
| 20 | # CHECK-NEXT: Binding: Weak | |
| 21 | # CHECK-NEXT: Type: None | |
| 22 | # CHECK-NEXT: Other: 0 | |
| 23 | # CHECK-NEXT: Section: Undefined | |
| 24 | # CHECK-NEXT: } | |
| 16 | 25 | # CHECK-NEXT: ] |
| 17 | 26 | |
| 18 | 27 | .weak foo |
| 19 | 28 | |
| 20 | 29 | .globl _start |
| 21 | 30 | _start: |
| 31 | ||
| 32 | .data | |
| 33 | .dc.a foo |
deps/lld/test/ELF/wrap-no-real.s created+77| ... | ... | @@ -0,0 +1,77 @@ |
| 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/wrap-no-real.s -o %t2.o | |
| 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/wrap-no-real2.s -o %t3.o | |
| 5 | // RUN: ld.lld -o %t3.so -shared %t3.o | |
| 6 | ||
| 7 | // RUN: ld.lld -o %t %t1.o %t2.o -wrap foo | |
| 8 | // RUN: llvm-objdump -d -print-imm-hex %t | FileCheck %s | |
| 9 | ||
| 10 | // RUN: ld.lld -o %t %t1.o %t2.o %t3.so -wrap foo | |
| 11 | // RUN: llvm-objdump -d -print-imm-hex %t | FileCheck %s | |
| 12 | ||
| 13 | // CHECK: _start: | |
| 14 | // CHECK-NEXT: movl $0x11010, %edx | |
| 15 | // CHECK-NEXT: movl $0x11010, %edx | |
| 16 | // CHECK-NEXT: movl $0x11000, %edx | |
| 17 | ||
| 18 | // RUN: llvm-readobj -t %t | FileCheck -check-prefix=SYM %s | |
| 19 | ||
| 20 | // Test the full symbol table. It is verbose, but lld at times | |
| 21 | // produced duplicated symbols which are hard to test otherwise. | |
| 22 | ||
| 23 | // SYM: Symbols [ | |
| 24 | // SYM-NEXT: Symbol { | |
| 25 | // SYM-NEXT: Name: (0) | |
| 26 | // SYM-NEXT: Value: | |
| 27 | // SYM-NEXT: Size: | |
| 28 | // SYM-NEXT: Binding: | |
| 29 | // SYM-NEXT: Type | |
| 30 | // SYM-NEXT: Other: | |
| 31 | // SYM-NEXT: Section: | |
| 32 | // SYM-NEXT: } | |
| 33 | // SYM-NEXT: Symbol { | |
| 34 | // SYM-NEXT: Name: _DYNAMIC | |
| 35 | // SYM-NEXT: Value: | |
| 36 | // SYM-NEXT: Size: | |
| 37 | // SYM-NEXT: Binding: | |
| 38 | // SYM-NEXT: Type: | |
| 39 | // SYM-NEXT: Other [ | |
| 40 | // SYM-NEXT: STV_HIDDEN | |
| 41 | // SYM-NEXT: ] | |
| 42 | // SYM-NEXT: Section: .dynamic | |
| 43 | // SYM-NEXT: } | |
| 44 | // SYM-NEXT: Symbol { | |
| 45 | // SYM-NEXT: Name: foo | |
| 46 | // SYM-NEXT: Value: 0x11000 | |
| 47 | // SYM-NEXT: Size: | |
| 48 | // SYM-NEXT: Binding: | |
| 49 | // SYM-NEXT: Type: | |
| 50 | // SYM-NEXT: Other: | |
| 51 | // SYM-NEXT: Section: | |
| 52 | // SYM-NEXT: } | |
| 53 | // SYM-NEXT: Symbol { | |
| 54 | // SYM-NEXT: Name: _start | |
| 55 | // SYM-NEXT: Value: | |
| 56 | // SYM-NEXT: Size: | |
| 57 | // SYM-NEXT: Binding: | |
| 58 | // SYM-NEXT: Type | |
| 59 | // SYM-NEXT: Other: | |
| 60 | // SYM-NEXT: Section: | |
| 61 | // SYM-NEXT: } | |
| 62 | // SYM-NEXT: Symbol { | |
| 63 | // SYM-NEXT: Name: __wrap_foo | |
| 64 | // SYM-NEXT: Value: 0x11010 | |
| 65 | // SYM-NEXT: Size: | |
| 66 | // SYM-NEXT: Binding: | |
| 67 | // SYM-NEXT: Type: | |
| 68 | // SYM-NEXT: Other: | |
| 69 | // SYM-NEXT: Section: | |
| 70 | // SYM-NEXT: } | |
| 71 | // SYM-NEXT: ] | |
| 72 | ||
| 73 | .global _start | |
| 74 | _start: | |
| 75 | movl $foo, %edx | |
| 76 | movl $__wrap_foo, %edx | |
| 77 | movl $__real_foo, %edx |
deps/lld/test/ELF/wrap.s+24-10| ... | ... | @@ -12,17 +12,31 @@ |
| 12 | 12 | // CHECK-NEXT: movl $0x11010, %edx |
| 13 | 13 | // CHECK-NEXT: movl $0x11000, %edx |
| 14 | 14 | |
| 15 | // This shows an oddity of our implementation. The symbol foo gets | |
| 16 | // mapped to __wrap_foo, but stays in the symbol table. This results | |
| 17 | // in it showing up twice in the output. | |
| 15 | // RUN: llvm-readobj -t %t3 > %t4.dump | |
| 16 | // RUN: FileCheck --check-prefix=SYM1 %s < %t4.dump | |
| 17 | // RUN: FileCheck --check-prefix=SYM2 %s < %t4.dump | |
| 18 | // RUN: FileCheck --check-prefix=SYM3 %s < %t4.dump | |
| 18 | 19 | |
| 19 | // RUN: llvm-readobj -t -s %t3 | FileCheck -check-prefix=SYM %s | |
| 20 | // SYM: Name: foo | |
| 21 | // SYM-NEXT: Value: 0x11000 | |
| 22 | // SYM: Name: __wrap_foo | |
| 23 | // SYM-NEXT: Value: 0x11010 | |
| 24 | // SYM: Name: __wrap_foo | |
| 25 | // SYM-NEXT: Value: 0x11010 | |
| 20 | // SYM1: Name: foo | |
| 21 | // SYM1-NEXT: Value: 0x11000 | |
| 22 | // SYM1-NEXT: Size: | |
| 23 | // SYM1-NEXT: Binding: Global | |
| 24 | // SYM1-NEXT: Type: None | |
| 25 | // SYM1-NEXT: Other: 0 | |
| 26 | // SYM2: Name: __wrap_foo | |
| 27 | // SYM2-NEXT: Value: 0x11010 | |
| 28 | // SYM2-NEXT: Size: | |
| 29 | // SYM2-NEXT: Binding: Weak | |
| 30 | // SYM2-NEXT: Type: None | |
| 31 | // SYM2-NEXT: Other [ | |
| 32 | // SYM2-NEXT: STV_PROTECTED | |
| 33 | // SYM2-NEXT: ] | |
| 34 | // SYM3: Name: __real_foo | |
| 35 | // SYM3-NEXT: Value: 0x11020 | |
| 36 | // SYM3-NEXT: Size: | |
| 37 | // SYM3-NEXT: Binding: Global | |
| 38 | // SYM3-NEXT: Type: None | |
| 39 | // SYM3-NEXT: Other: 0 | |
| 26 | 40 | |
| 27 | 41 | .global _start |
| 28 | 42 | _start: |
deps/lld/test/ELF/writable-sec-plt-reloc.s created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | |
| 3 | # RUN: llvm-mc %p/Inputs/writable-sec-plt-reloc.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux | |
| 4 | # RUN: ld.lld %t2.o -o %t2.so -shared | |
| 5 | # RUN: ld.lld %t.o %t2.so -o %t | |
| 6 | # RUN: llvm-readelf --symbols -r %t | FileCheck %s | |
| 7 | ||
| 8 | # CHECK: R_X86_64_JUMP_SLOT {{.*}} foo + 0 | |
| 9 | # CHECK: 0000000000201010 0 FUNC GLOBAL DEFAULT UND foo | |
| 10 | ||
| 11 | .section .bar,"awx" | |
| 12 | .global _start | |
| 13 | _start: | |
| 14 | call foo |
deps/lld/test/ELF/x86-64-dyn-rel-error.s+4-2| ... | ... | @@ -2,11 +2,13 @@ |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o |
| 4 | 4 | // RUN: ld.lld %t2.o -shared -o %t2.so |
| 5 | // RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s | |
| 5 | // RUN: not ld.lld -shared %t.o %t2.so -o %t 2>&1 | FileCheck %s | |
| 6 | 6 | |
| 7 | 7 | .global _start |
| 8 | 8 | _start: |
| 9 | 9 | .data |
| 10 | .long bar | |
| 10 | .long zed | |
| 11 | 11 | |
| 12 | 12 | // CHECK: relocation R_X86_64_32 cannot be used against shared object; recompile with -fPIC |
| 13 | ||
| 14 | // RUN: ld.lld --noinhibit-exec %t.o %t2.so -o %t 2>&1 | FileCheck %s |
deps/lld/test/ELF/x86-64-dyn-rel-error2.s+2-2| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o |
| 4 | 4 | // RUN: ld.lld %t2.o -shared -o %t2.so |
| 5 | // RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s | |
| 5 | // RUN: not ld.lld -shared %t.o %t2.so -o %t 2>&1 | FileCheck %s | |
| 6 | 6 | |
| 7 | 7 | // CHECK: relocation R_X86_64_PC32 cannot be used against shared object; recompile with -fPIC |
| 8 | 8 | // CHECK: >>> defined in {{.*}}.so |
| ... | ... | @@ -11,4 +11,4 @@ |
| 11 | 11 | .global _start |
| 12 | 12 | _start: |
| 13 | 13 | .data |
| 14 | .long bar - . | |
| 14 | .long zed - . |
deps/lld/test/ELF/x86-64-relax-got-abs.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 2 | // RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux %s \ |
| 3 | 3 | // RUN: -o %t.o |
| 4 | // RUN: ld.lld %t.o -o %t.so -shared | |
| 4 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | |
| 5 | 5 | // RUN: llvm-objdump -d %t.so | FileCheck %s |
| 6 | 6 | |
| 7 | 7 | // We used to fail trying to relax this into a pc relocation to an absolute |
deps/lld/test/ELF/x86-64-reloc-16.s+1-1| ... | ... | @@ -9,6 +9,6 @@ |
| 9 | 9 | // CHECK-NEXT: 200000 42 |
| 10 | 10 | |
| 11 | 11 | // RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s |
| 12 | // ERROR: relocation R_X86_64_16 out of range | |
| 12 | // ERROR: relocation R_X86_64_16 out of range: 65536 is not in [0, 65535] | |
| 13 | 13 | |
| 14 | 14 | .short foo |
deps/lld/test/ELF/x86-64-reloc-8.s+1-1| ... | ... | @@ -9,6 +9,6 @@ |
| 9 | 9 | // CHECK-NEXT: 200000 42 |
| 10 | 10 | |
| 11 | 11 | // RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s |
| 12 | // ERROR: relocation R_X86_64_8 out of range | |
| 12 | // ERROR: relocation R_X86_64_8 out of range: 256 is not in [0, 255] | |
| 13 | 13 | |
| 14 | 14 | .byte foo |
deps/lld/test/ELF/x86-64-reloc-error.s+2-2| ... | ... | @@ -6,5 +6,5 @@ |
| 6 | 6 | movl $big, %edx |
| 7 | 7 | movq $foo - 0x1000000000000, %rdx |
| 8 | 8 | |
| 9 | # CHECK: {{.*}}:(.text+0x1): relocation R_X86_64_32 out of range | |
| 10 | # CHECK: {{.*}}:(.text+0x8): relocation R_X86_64_32S out of range | |
| 9 | # CHECK: {{.*}}:(.text+0x1): relocation R_X86_64_32 out of range: 68719476736 is not in [0, 4294967295] | |
| 10 | # CHECK: {{.*}}:(.text+0x8): relocation R_X86_64_32S out of range: -281474976710656 is not in [-2147483648, 2147483647] |
deps/lld/test/ELF/x86-64-reloc-range.s+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // RUN: llvm-mc %s -o %t.o -triple x86_64-pc-linux -filetype=obj |
| 2 | 2 | // RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s |
| 3 | 3 | |
| 4 | // CHECK: {{.*}}:(.text+0x3): relocation R_X86_64_PC32 out of range | |
| 4 | // CHECK: {{.*}}:(.text+0x3): relocation R_X86_64_PC32 out of range: 2147483648 is not in [-2147483648, 2147483647] | |
| 5 | 5 | // CHECK-NOT: relocation |
| 6 | 6 | |
| 7 | 7 | lea foo(%rip), %rax |
deps/lld/test/ELF/x86-64-retpoline-znow.s created+53| ... | ... | @@ -0,0 +1,53 @@ |
| 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: ld.lld -shared %t1.o %t2.so -o %t.exe -z retpolineplt -z now | |
| 7 | // RUN: llvm-objdump -d -s %t.exe | FileCheck %s | |
| 8 | ||
| 9 | // CHECK: Disassembly of section .plt: | |
| 10 | // CHECK-NEXT: .plt: | |
| 11 | // CHECK-NEXT: 1010:	e8 0b 00 00 00 	callq	11 <.plt+0x10> | |
| 12 | // CHECK-NEXT: 1015:	f3 90 	pause | |
| 13 | // CHECK-NEXT: 1017:	0f ae e8 	lfence | |
| 14 | // CHECK-NEXT: 101a:	eb f9 	jmp	-7 <.plt+0x5> | |
| 15 | // CHECK-NEXT: 101c:	cc 	int3 | |
| 16 | // CHECK-NEXT: 101d:	cc 	int3 | |
| 17 | // CHECK-NEXT: 101e:	cc 	int3 | |
| 18 | // CHECK-NEXT: 101f:	cc 	int3 | |
| 19 | // CHECK-NEXT: 1020:	4c 89 1c 24 	movq	%r11, (%rsp) | |
| 20 | // CHECK-NEXT: 1024:	c3 	retq | |
| 21 | // CHECK-NEXT: 1025:	cc 	int3 | |
| 22 | // CHECK-NEXT: 1026:	cc 	int3 | |
| 23 | // CHECK-NEXT: 1027:	cc 	int3 | |
| 24 | // CHECK-NEXT: 1028:	cc 	int3 | |
| 25 | // CHECK-NEXT: 1029:	cc 	int3 | |
| 26 | // CHECK-NEXT: 102a:	cc 	int3 | |
| 27 | // CHECK-NEXT: 102b:	cc 	int3 | |
| 28 | // CHECK-NEXT: 102c:	cc 	int3 | |
| 29 | // CHECK-NEXT: 102d:	cc 	int3 | |
| 30 | // CHECK-NEXT: 102e:	cc 	int3 | |
| 31 | // CHECK-NEXT: 102f:	cc 	int3 | |
| 32 | // CHECK-NEXT: 1030:	4c 8b 1d c1 10 00 00 	movq	4289(%rip), %r11 | |
| 33 | // CHECK-NEXT: 1037:	e9 d4 ff ff ff 	jmp	-44 <.plt> | |
| 34 | // CHECK-NEXT: 103c:	cc 	int3 | |
| 35 | // CHECK-NEXT: 103d:	cc 	int3 | |
| 36 | // CHECK-NEXT: 103e:	cc 	int3 | |
| 37 | // CHECK-NEXT: 103f:	cc 	int3 | |
| 38 | // CHECK-NEXT: 1040:	4c 8b 1d b9 10 00 00 	movq	4281(%rip), %r11 | |
| 39 | // CHECK-NEXT: 1047:	e9 c4 ff ff ff 	jmp	-60 <.plt> | |
| 40 | // CHECK-NEXT: 104c:	cc 	int3 | |
| 41 | // CHECK-NEXT: 104d:	cc 	int3 | |
| 42 | // CHECK-NEXT: 104e:	cc 	int3 | |
| 43 | // CHECK-NEXT: 104f:	cc 	int3 | |
| 44 | ||
| 45 | // CHECK: Contents of section .got.plt: | |
| 46 | // CHECK-NEXT: 20e0 00200000 00000000 00000000 00000000 | |
| 47 | // CHECK-NEXT: 20f0 00000000 00000000 00000000 00000000 | |
| 48 | // CHECK-NEXT: 2100 00000000 00000000 | |
| 49 | ||
| 50 | .global _start | |
| 51 | _start: | |
| 52 | jmp bar@PLT | |
| 53 | jmp zed@PLT |
deps/lld/test/ELF/x86-64-retpoline.s created+66| ... | ... | @@ -0,0 +1,66 @@ |
| 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: ld.lld -shared %t1.o %t2.so -o %t.exe -z retpolineplt | |
| 7 | // RUN: llvm-objdump -d -s %t.exe | FileCheck %s | |
| 8 | ||
| 9 | // CHECK: Disassembly of section .plt: | |
| 10 | // CHECK-NEXT: .plt: | |
| 11 | // CHECK-NEXT: 1010: ff 35 f2 0f 00 00 pushq 4082(%rip) | |
| 12 | // CHECK-NEXT: 1016: 4c 8b 1d f3 0f 00 00 movq 4083(%rip), %r11 | |
| 13 | // CHECK-NEXT: 101d: e8 0e 00 00 00 callq 14 <.plt+0x20> | |
| 14 | // CHECK-NEXT: 1022: f3 90 pause | |
| 15 | // CHECK-NEXT: 1024: 0f ae e8 lfence | |
| 16 | // CHECK-NEXT: 1027: eb f9 jmp -7 <.plt+0x12> | |
| 17 | // CHECK-NEXT: 1029: cc int3 | |
| 18 | // CHECK-NEXT: 102a: cc int3 | |
| 19 | // CHECK-NEXT: 102b: cc int3 | |
| 20 | // CHECK-NEXT: 102c: cc int3 | |
| 21 | // CHECK-NEXT: 102d: cc int3 | |
| 22 | // CHECK-NEXT: 102e: cc int3 | |
| 23 | // CHECK-NEXT: 102f: cc int3 | |
| 24 | // CHECK-NEXT: 1030: 4c 89 1c 24 movq %r11, (%rsp) | |
| 25 | // CHECK-NEXT: 1034: c3 retq | |
| 26 | // CHECK-NEXT: 1035: cc int3 | |
| 27 | // CHECK-NEXT: 1036: cc int3 | |
| 28 | // CHECK-NEXT: 1037: cc int3 | |
| 29 | // CHECK-NEXT: 1038: cc int3 | |
| 30 | // CHECK-NEXT: 1039: cc int3 | |
| 31 | // CHECK-NEXT: 103a: cc int3 | |
| 32 | // CHECK-NEXT: 103b: cc int3 | |
| 33 | // CHECK-NEXT: 103c: cc int3 | |
| 34 | // CHECK-NEXT: 103d: cc int3 | |
| 35 | // CHECK-NEXT: 103e: cc int3 | |
| 36 | // CHECK-NEXT: 103f: cc int3 | |
| 37 | // CHECK-NEXT: 1040: 4c 8b 1d d1 0f 00 00 movq 4049(%rip), %r11 | |
| 38 | // CHECK-NEXT: 1047: e8 e4 ff ff ff callq -28 <.plt+0x20> | |
| 39 | // CHECK-NEXT: 104c: e9 d1 ff ff ff jmp -47 <.plt+0x12> | |
| 40 | // CHECK-NEXT: 1051: 68 00 00 00 00 pushq $0 | |
| 41 | // CHECK-NEXT: 1056: e9 b5 ff ff ff jmp -75 <.plt> | |
| 42 | // CHECK-NEXT: 105b: cc int3 | |
| 43 | // CHECK-NEXT: 105c: cc int3 | |
| 44 | // CHECK-NEXT: 105d: cc int3 | |
| 45 | // CHECK-NEXT: 105e: cc int3 | |
| 46 | // CHECK-NEXT: 105f: cc int3 | |
| 47 | // CHECK-NEXT: 1060: 4c 8b 1d b9 0f 00 00 movq 4025(%rip), %r11 | |
| 48 | // CHECK-NEXT: 1067: e8 c4 ff ff ff callq -60 <.plt+0x20> | |
| 49 | // CHECK-NEXT: 106c: e9 b1 ff ff ff jmp -79 <.plt+0x12> | |
| 50 | // CHECK-NEXT: 1071: 68 01 00 00 00 pushq $1 | |
| 51 | // CHECK-NEXT: 1076: e9 95 ff ff ff jmp -107 <.plt> | |
| 52 | // CHECK-NEXT: 107b: cc int3 | |
| 53 | // CHECK-NEXT: 107c: cc int3 | |
| 54 | // CHECK-NEXT: 107d: cc int3 | |
| 55 | // CHECK-NEXT: 107e: cc int3 | |
| 56 | // CHECK-NEXT: 107f: cc int3 | |
| 57 | ||
| 58 | // CHECK: Contents of section .got.plt: | |
| 59 | // CHECK-NEXT: 2000 00300000 00000000 00000000 00000000 | |
| 60 | // CHECK-NEXT: 2010 00000000 00000000 51100000 00000000 | |
| 61 | // CHECK-NEXT: 2020 71100000 00000000 | |
| 62 | ||
| 63 | .global _start | |
| 64 | _start: | |
| 65 | jmp bar@PLT | |
| 66 | jmp zed@PLT |
deps/lld/test/ELF/x86-64-tls-gd-local.s+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // REQUIRES: x86 |
| 2 | 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 | |
| 3 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | |
| 4 | 4 | // RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s |
| 5 | 5 | |
| 6 | 6 | .byte 0x66 |
deps/lld/test/ELF/znotext-copy-relocation.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: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/znotext-copy-relocations.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 | |
| 6 | # RUN: llvm-readobj -r %t | FileCheck %s | |
| 7 | ||
| 8 | # CHECK: Relocations [ | |
| 9 | # CHECK-NEXT: Section ({{.*}}) .rela.dyn { | |
| 10 | # CHECK-NEXT: R_X86_64_COPY foo 0x0 | |
| 11 | # CHECK-NEXT: } | |
| 12 | # CHECK-NEXT: ] | |
| 13 | ||
| 14 | .global _start | |
| 15 | _start: | |
| 16 | .long foo |
deps/lld/test/ELF/znotext-plt-relocations-protected.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/znotext-plt-relocations-protected.s -o %t2.o | |
| 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 | |
| 6 | ||
| 7 | # CHECK: error: cannot preempt symbol: foo | |
| 8 | ||
| 9 | .global _start | |
| 10 | _start: | |
| 11 | callq foo |
deps/lld/test/ELF/znotext-plt-relocations.s created+20| ... | ... | @@ -0,0 +1,20 @@ |
| 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/znotext-plt-relocations.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 | |
| 6 | # RUN: llvm-readobj -r %t | FileCheck %s | |
| 7 | ||
| 8 | # CHECK: Relocations [ | |
| 9 | # CHECK-NEXT: Section {{.*}} .rela.dyn { | |
| 10 | # CHECK-NEXT: R_X86_64_64 foo 0x0 | |
| 11 | # CHECK-NEXT: } | |
| 12 | # CHECK-NEXT: Section {{.*}} .rela.plt { | |
| 13 | # CHECK-NEXT: R_X86_64_JUMP_SLOT atexit 0x0 | |
| 14 | # CHECK-NEXT: } | |
| 15 | # CHECK-NEXT: ] | |
| 16 | ||
| 17 | .text | |
| 18 | _start: | |
| 19 | callq atexit | |
| 20 | .quad foo |
deps/lld/test/ELF/znotext-weak-undef.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 -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 | |
| 5 | ||
| 6 | # RUN: ld.lld -z notext %t.o -o %t | |
| 7 | # RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=EXE | |
| 8 | # EXE: Relocations [ | |
| 9 | # EXE-NEXT: ] | |
| 10 | ||
| 11 | .text | |
| 12 | .global foo | |
| 13 | .weak foo | |
| 14 | ||
| 15 | _start: | |
| 16 | mov $foo,%eax |
deps/lld/test/MinGW/driver.test created+126| ... | ... | @@ -0,0 +1,126 @@ |
| 1 | RUN: ld.lld -### foo.o -m i386pe | FileCheck -check-prefix=X86 %s | |
| 2 | X86: -out:a.exe | |
| 3 | X86-SAME: -machine:x86 | |
| 4 | X86-SAME: -alternatename:__image_base__=___ImageBase | |
| 5 | X86-SAME: foo.o | |
| 6 | ||
| 7 | RUN: ld.lld -### foo.o -m i386pep | FileCheck -check-prefix=X64 %s | |
| 8 | X64: -out:a.exe | |
| 9 | X64-SAME: -machine:x64 | |
| 10 | X64-SAME: -alternatename:__image_base__=__ImageBase | |
| 11 | X64-SAME: foo.o | |
| 12 | ||
| 13 | RUN: ld.lld -### foo.o -m thumb2pe | FileCheck -check-prefix=ARM %s | |
| 14 | ARM: -out:a.exe | |
| 15 | ARM-SAME: -machine:arm | |
| 16 | ARM-SAME: -alternatename:__image_base__=__ImageBase | |
| 17 | ARM-SAME: foo.o | |
| 18 | ||
| 19 | RUN: ld.lld -### foo.o -m arm64pe | FileCheck -check-prefix=ARM64 %s | |
| 20 | ARM64: -out:a.exe | |
| 21 | ARM64-SAME: -machine:arm64 | |
| 22 | ARM64-SAME: -alternatename:__image_base__=__ImageBase | |
| 23 | ARM64-SAME: foo.o | |
| 24 | ||
| 25 | RUN: ld.lld -### foo.o -m i386pep -shared | FileCheck -check-prefix=SHARED %s | |
| 26 | RUN: ld.lld -### foo.o -m i386pep --shared | FileCheck -check-prefix=SHARED %s | |
| 27 | SHARED: -out:a.dll | |
| 28 | SHARED-SAME: -dll | |
| 29 | ||
| 30 | RUN: ld.lld -### foo.o -m i386pep -shared foo.def | FileCheck -check-prefix=DEF1 %s | |
| 31 | DEF1: -def:foo.def | |
| 32 | ||
| 33 | RUN: ld.lld -### foo.o -m i386pep -shared FOO.DEF | FileCheck -check-prefix=DEF2 %s | |
| 34 | DEF2: -def:FOO.DEF | |
| 35 | ||
| 36 | RUN: ld.lld -### foo.o -m i386pep -obar.exe | FileCheck -check-prefix=OUT %s | |
| 37 | RUN: ld.lld -### foo.o -m i386pep -o bar.exe | FileCheck -check-prefix=OUT %s | |
| 38 | OUT: -out:bar.exe | |
| 39 | ||
| 40 | RUN: ld.lld -### foo.o -m i386pep --out-implib bar | FileCheck -check-prefix=IMPLIB %s | |
| 41 | RUN: ld.lld -### foo.o -m i386pep --out-implib=bar | FileCheck -check-prefix=IMPLIB %s | |
| 42 | IMPLIB: -implib:bar | |
| 43 | ||
| 44 | RUN: ld.lld -### foo.o -m i386pep -out-implib bar | FileCheck -check-prefix=NOIMPLIB %s | |
| 45 | NOIMPLIB: -out:ut-implib | |
| 46 | ||
| 47 | RUN: ld.lld -### foo.o -m i386pep -e bar | FileCheck -check-prefix=ENTRY %s | |
| 48 | RUN: ld.lld -### foo.o -m i386pep -entry bar | FileCheck -check-prefix=ENTRY %s | |
| 49 | RUN: ld.lld -### foo.o -m i386pep --entry bar | FileCheck -check-prefix=ENTRY %s | |
| 50 | ENTRY: -entry:bar | |
| 51 | ||
| 52 | RUN: ld.lld -### foo.o -m i386pep -mllvm bar -mllvm baz | FileCheck -check-prefix=MLLVM %s | |
| 53 | MLLVM: -mllvm:bar -mllvm:baz | |
| 54 | ||
| 55 | RUN: ld.lld -### foo.o -m i386pep -subsystem console | FileCheck -check-prefix=SUBSYSTEM %s | |
| 56 | RUN: ld.lld -### foo.o -m i386pep --subsystem console | FileCheck -check-prefix=SUBSYSTEM %s | |
| 57 | SUBSYSTEM: -subsystem:console | |
| 58 | ||
| 59 | RUN: ld.lld -### foo.o -m i386pep -stack 4194304,8192 | FileCheck -check-prefix=STACK %s | |
| 60 | RUN: ld.lld -### foo.o -m i386pep --stack 4194304,8192 | FileCheck -check-prefix=STACK %s | |
| 61 | STACK: -stack:4194304,8192 | |
| 62 | ||
| 63 | RUN: ld.lld -### foo.o -m i386pep -verbose | FileCheck -check-prefix=VERBOSE %s | |
| 64 | RUN: ld.lld -### foo.o -m i386pep --verbose | FileCheck -check-prefix=VERBOSE %s | |
| 65 | VERBOSE: -verbose | |
| 66 | ||
| 67 | RUN: ld.lld -### -shared -m i386pe -e _DllMainCRTStartup@12 foo.o | FileCheck -check-prefix I386-ENTRY %s | |
| 68 | I386-ENTRY: -entry:DllMainCRTStartup@12 | |
| 69 | ||
| 70 | RUN: ld.lld -### -m i386pep foo.o --whole-archive bar.a --no-whole-archive baz.a | FileCheck -check-prefix WHOLE-ARCHIVE %s | |
| 71 | RUN: ld.lld -### -m i386pep foo.o -whole-archive bar.a -no-whole-archive baz.a | FileCheck -check-prefix WHOLE-ARCHIVE %s | |
| 72 | WHOLE-ARCHIVE: foo.o -wholearchive:bar.a baz.a | |
| 73 | ||
| 74 | RUN: ld.lld -### -m i386pep foo.o | FileCheck -check-prefix MINGW-FLAG %s | |
| 75 | MINGW-FLAG: -lldmingw | |
| 76 | ||
| 77 | RUN: ld.lld -### -m i386pep foo.o --export-all-symbols | FileCheck -check-prefix EXPORT-ALL %s | |
| 78 | EXPORT-ALL: -export-all-symbols | |
| 79 | ||
| 80 | RUN: ld.lld -### -m i386pep foo.o --output-def out.def | FileCheck -check-prefix OUTPUT-DEF %s | |
| 81 | OUTPUT-DEF: -output-def:out.def | |
| 82 | ||
| 83 | RUN: ld.lld -### -m i386pep foo.o -Xlink=-lldmap | FileCheck -check-prefix XLINK %s | |
| 84 | XLINK: -lldmap | |
| 85 | ||
| 86 | RUN: ld.lld -### -m i386pep foo.o | FileCheck -check-prefix DEBUG %s | |
| 87 | DEBUG: -debug:dwarf | |
| 88 | ||
| 89 | 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 | |
| 91 | STRIP-NOT: -debug:dwarf | |
| 92 | ||
| 93 | RUN: ld.lld -### -m i386pep foo.o --large-address-aware | FileCheck -check-prefix LARGE-ADDRESS-AWARE %s | |
| 94 | LARGE-ADDRESS-AWARE: -largeaddressaware | |
| 95 | ||
| 96 | RUN: ld.lld -### -m i386pe foo.o | FileCheck -check-prefix DEFAULT-DISABLE-FLAGS %s | |
| 97 | RUN: ld.lld -### -m i386pep foo.o | FileCheck -check-prefix DEFAULT-DISABLE-FLAGS %s | |
| 98 | DEFAULT-DISABLE-FLAGS: -dynamicbase:no | |
| 99 | RUN: ld.lld -### -m i386pe --dynamicbase foo.o | FileCheck -check-prefix NO-DEFAULT-DISABLE-FLAGS %s | |
| 100 | RUN: ld.lld -### -m i386pep -dynamicbase foo.o | FileCheck -check-prefix NO-DEFAULT-DISABLE-FLAGS %s | |
| 101 | RUN: ld.lld -### -m thumb2pe foo.o | FileCheck -check-prefix NO-DEFAULT-DISABLE-FLAGS %s | |
| 102 | RUN: ld.lld -### -m arm64pe foo.o | FileCheck -check-prefix NO-DEFAULT-DISABLE-FLAGS %s | |
| 103 | NO-DEFAULT-DISABLE-FLAGS-NOT: -dynamicbase:no | |
| 104 | ||
| 105 | RUN: ld.lld -### -m i386pep foo.o --image-base 0x1230000 | FileCheck -check-prefix IMAGE-BASE %s | |
| 106 | RUN: ld.lld -### -m i386pep foo.o -image-base 0x1230000 | FileCheck -check-prefix IMAGE-BASE %s | |
| 107 | IMAGE-BASE: -base:0x1230000 | |
| 108 | ||
| 109 | RUN: ld.lld -### -m i386pep foo.o | FileCheck -check-prefix NO-GC-SECTIONS %s | |
| 110 | RUN: ld.lld -### -m i386pep foo.o --gc-sections --no-gc-sections | FileCheck -check-prefix NO-GC-SECTIONS %s | |
| 111 | NO-GC-SECTIONS: -opt:noref | |
| 112 | ||
| 113 | RUN: ld.lld -### -m i386pep foo.o --gc-sections | FileCheck -check-prefix GC-SECTIONS %s | |
| 114 | RUN: ld.lld -### -m i386pep foo.o -gc-sections | FileCheck -check-prefix GC-SECTIONS %s | |
| 115 | GC-SECTIONS: -opt:ref | |
| 116 | ||
| 117 | RUN: ld.lld -### -m i386pep foo.o | FileCheck -check-prefix ICF-NONE %s | |
| 118 | RUN: ld.lld -### -m i386pep foo.o --icf=none | FileCheck -check-prefix ICF-NONE %s | |
| 119 | RUN: ld.lld -### -m i386pep foo.o -icf=none | FileCheck -check-prefix ICF-NONE %s | |
| 120 | RUN: ld.lld -### -m i386pep foo.o --icf=safe | FileCheck -check-prefix ICF-NONE %s | |
| 121 | RUN: ld.lld -### -m i386pep foo.o -icf=safe | FileCheck -check-prefix ICF-NONE %s | |
| 122 | ICF-NONE: -opt:noicf | |
| 123 | ||
| 124 | 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 | |
| 126 | ICF: -opt:icf |
deps/lld/test/MinGW/lib.test created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | RUN: rm -rf %t/lib | |
| 2 | RUN: mkdir -p %t/lib | |
| 3 | RUN: not ld.lld -### -m i386pep -lfoo -L%t/lib 2>&1 | FileCheck -check-prefix=LIB1 %s | |
| 4 | LIB1: unable to find library -lfoo | |
| 5 | ||
| 6 | RUN: echo > %t/lib/libfoo.dll.a | |
| 7 | RUN: ld.lld -### -m i386pep -lfoo -L%t/lib | FileCheck -check-prefix=LIB2 %s | |
| 8 | LIB2: libfoo.dll.a | |
| 9 | ||
| 10 | RUN: not ld.lld -### -m i386pep -Bstatic -lfoo -L%t/lib 2>&1 | FileCheck -check-prefix=LIB3 %s | |
| 11 | LIB3: unable to find library -lfoo | |
| 12 | ||
| 13 | RUN: echo > %t/lib/libfoo.a | |
| 14 | RUN: ld.lld -### -m i386pep -Bstatic -lfoo -L%t/lib | FileCheck -check-prefix=LIB4 %s | |
| 15 | LIB4: libfoo.a | |
| 16 | ||
| 17 | RUN: echo > %t/lib/libbar.dll.a | |
| 18 | RUN: echo > %t/lib/libbar.a | |
| 19 | RUN: ld.lld -### -m i386pep -Bstatic -lfoo -Bdynamic -lbar -L%t/lib | FileCheck -check-prefix=LIB5 %s | |
| 20 | LIB5: libfoo.a | |
| 21 | LIB5-SAME: libbar.dll.a |
deps/lld/test/Unit/lit.cfg deleted-23| ... | ... | @@ -1,23 +0,0 @@ |
| 1 | # -*- Python -*- | |
| 2 | ||
| 3 | # Configuration file for the 'lit' test runner. | |
| 4 | ||
| 5 | import os | |
| 6 | ||
| 7 | import lit.formats | |
| 8 | ||
| 9 | # name: The name of this test suite. | |
| 10 | config.name = 'lld-Unit' | |
| 11 | ||
| 12 | # suffixes: A list of file extensions to treat as test files. | |
| 13 | config.suffixes = [] | |
| 14 | ||
| 15 | # test_source_root: The root path where unit test binaries are located. | |
| 16 | # test_exec_root: The root path where tests should be run. | |
| 17 | config.test_source_root = os.path.join(config.lld_obj_root, 'unittests') | |
| 18 | config.test_exec_root = config.test_source_root | |
| 19 | ||
| 20 | # testFormat: The test format to use to interpret tests. | |
| 21 | if not hasattr(config, 'llvm_build_mode'): | |
| 22 | lit_config.fatal("unable to find llvm_build_mode value on config") | |
| 23 | config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, 'Tests') |
deps/lld/test/Unit/lit.cfg.py created+37| ... | ... | @@ -0,0 +1,37 @@ |
| 1 | # -*- Python -*- | |
| 2 | ||
| 3 | # Configuration file for the 'lit' test runner. | |
| 4 | ||
| 5 | import os | |
| 6 | ||
| 7 | import lit.formats | |
| 8 | ||
| 9 | # name: The name of this test suite. | |
| 10 | config.name = 'lld-Unit' | |
| 11 | ||
| 12 | # suffixes: A list of file extensions to treat as test files. | |
| 13 | config.suffixes = [] | |
| 14 | ||
| 15 | # test_source_root: The root path where unit test binaries are located. | |
| 16 | # test_exec_root: The root path where tests should be run. | |
| 17 | config.test_source_root = os.path.join(config.lld_obj_root, 'unittests') | |
| 18 | config.test_exec_root = config.test_source_root | |
| 19 | ||
| 20 | ||
| 21 | # Tweak the PATH to include the tools dir. | |
| 22 | path = os.path.pathsep.join((config.lld_tools_dir, config.llvm_tools_dir, config.environment['PATH'])) | |
| 23 | config.environment['PATH'] = path | |
| 24 | ||
| 25 | path = os.path.pathsep.join((config.lld_libs_dir, config.llvm_libs_dir, | |
| 26 | config.environment.get('LD_LIBRARY_PATH',''))) | |
| 27 | config.environment['LD_LIBRARY_PATH'] = path | |
| 28 | ||
| 29 | # Propagate LLVM_SRC_ROOT into the environment. | |
| 30 | config.environment['LLVM_SRC_ROOT'] = config.llvm_src_root | |
| 31 | ||
| 32 | # Propagate PYTHON_EXECUTABLE into the environment | |
| 33 | config.environment['PYTHON_EXECUTABLE'] = sys.executable | |
| 34 | ||
| 35 | ||
| 36 | # testFormat: The test format to use to interpret tests. | |
| 37 | config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, 'Tests') |
deps/lld/test/Unit/lit.site.cfg.in deleted-25| ... | ... | @@ -1,25 +0,0 @@ |
| 1 | @LIT_SITE_CFG_IN_HEADER@ | |
| 2 | ||
| 3 | config.llvm_src_root = "@LLVM_SOURCE_DIR@" | |
| 4 | config.llvm_obj_root = "@LLVM_BINARY_DIR@" | |
| 5 | config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" | |
| 6 | config.llvm_libs_dir = "@LLVM_LIBS_DIR@" | |
| 7 | config.llvm_build_mode = "@LLVM_BUILD_MODE@" | |
| 8 | config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" | |
| 9 | config.lld_obj_root = "@LLD_BINARY_DIR@" | |
| 10 | config.lld_src_root = "@LLD_SOURCE_DIR@" | |
| 11 | config.target_triple = "@TARGET_TRIPLE@" | |
| 12 | config.python_executable = "@PYTHON_EXECUTABLE@" | |
| 13 | ||
| 14 | # Support substitution of the tools and libs dirs with user parameters. This is | |
| 15 | # used when we can't determine the tool dir at configuration time. | |
| 16 | try: | |
| 17 | config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params | |
| 18 | config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params | |
| 19 | config.llvm_build_mode = config.llvm_build_mode % lit_config.params | |
| 20 | except KeyError as e: | |
| 21 | key, = e.args | |
| 22 | lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) | |
| 23 | ||
| 24 | # Let the main config do the real work. | |
| 25 | lit_config.load_config(config, "@LLD_SOURCE_DIR@/test/Unit/lit.cfg") |
deps/lld/test/Unit/lit.site.cfg.py.in created+27| ... | ... | @@ -0,0 +1,27 @@ |
| 1 | @LIT_SITE_CFG_IN_HEADER@ | |
| 2 | ||
| 3 | config.llvm_src_root = "@LLVM_SOURCE_DIR@" | |
| 4 | config.llvm_obj_root = "@LLVM_BINARY_DIR@" | |
| 5 | config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" | |
| 6 | config.llvm_libs_dir = "@LLVM_LIBS_DIR@" | |
| 7 | config.llvm_build_mode = "@LLVM_BUILD_MODE@" | |
| 8 | config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" | |
| 9 | config.lld_obj_root = "@LLD_BINARY_DIR@" | |
| 10 | config.lld_src_root = "@LLD_SOURCE_DIR@" | |
| 11 | config.lld_libs_dir = "@LLVM_LIBRARY_OUTPUT_INTDIR@" | |
| 12 | config.lld_tools_dir = "@LLVM_RUNTIME_OUTPUT_INTDIR@" | |
| 13 | config.target_triple = "@TARGET_TRIPLE@" | |
| 14 | config.python_executable = "@PYTHON_EXECUTABLE@" | |
| 15 | ||
| 16 | # Support substitution of the tools and libs dirs with user parameters. This is | |
| 17 | # used when we can't determine the tool dir at configuration time. | |
| 18 | try: | |
| 19 | config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params | |
| 20 | config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params | |
| 21 | config.llvm_build_mode = config.llvm_build_mode % lit_config.params | |
| 22 | except KeyError as e: | |
| 23 | key, = e.args | |
| 24 | lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) | |
| 25 | ||
| 26 | # Let the main config do the real work. | |
| 27 | lit_config.load_config(config, "@LLD_SOURCE_DIR@/test/Unit/lit.cfg.py") |
deps/lld/test/lit.cfg deleted-270| ... | ... | @@ -1,270 +0,0 @@ |
| 1 | # -*- Python -*- | |
| 2 | ||
| 3 | import os | |
| 4 | import platform | |
| 5 | import re | |
| 6 | import subprocess | |
| 7 | import locale | |
| 8 | ||
| 9 | import lit.formats | |
| 10 | import lit.util | |
| 11 | ||
| 12 | # Configuration file for the 'lit' test runner. | |
| 13 | ||
| 14 | # name: The name of this test suite. | |
| 15 | config.name = 'lld' | |
| 16 | ||
| 17 | # Tweak PATH for Win32 | |
| 18 | if sys.platform in ['win32']: | |
| 19 | # Seek sane tools in directories and set to $PATH. | |
| 20 | path = getattr(config, 'lit_tools_dir', None) | |
| 21 | path = lit_config.getToolsPath(path, | |
| 22 | config.environment['PATH'], | |
| 23 | ['cmp.exe', 'grep.exe', 'sed.exe']) | |
| 24 | if path is not None: | |
| 25 | path = os.path.pathsep.join((path, | |
| 26 | config.environment['PATH'])) | |
| 27 | config.environment['PATH'] = path | |
| 28 | ||
| 29 | # Choose between lit's internal shell pipeline runner and a real shell. If | |
| 30 | # LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override. | |
| 31 | use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") | |
| 32 | if use_lit_shell: | |
| 33 | # 0 is external, "" is default, and everything else is internal. | |
| 34 | execute_external = (use_lit_shell == "0") | |
| 35 | else: | |
| 36 | # Otherwise we default to internal on Windows and external elsewhere, as | |
| 37 | # bash on Windows is usually very slow. | |
| 38 | execute_external = (not sys.platform in ['win32']) | |
| 39 | ||
| 40 | ||
| 41 | # testFormat: The test format to use to interpret tests. | |
| 42 | # | |
| 43 | # For now we require '&&' between commands, until they get globally killed and | |
| 44 | # the test runner updated. | |
| 45 | config.test_format = lit.formats.ShTest(execute_external) | |
| 46 | ||
| 47 | # suffixes: A list of file extensions to treat as test files. | |
| 48 | config.suffixes = ['.ll', '.s', '.test', '.yaml', '.objtxt'] | |
| 49 | ||
| 50 | # excludes: A list of directories to exclude from the testsuite. The 'Inputs' | |
| 51 | # subdirectories contain auxiliary inputs for various tests in their parent | |
| 52 | # directories. | |
| 53 | config.excludes = ['Inputs'] | |
| 54 | ||
| 55 | # test_source_root: The root path where tests are located. | |
| 56 | config.test_source_root = os.path.dirname(__file__) | |
| 57 | ||
| 58 | # test_exec_root: The root path where tests should be run. | |
| 59 | lld_obj_root = getattr(config, 'lld_obj_root', None) | |
| 60 | if lld_obj_root is not None: | |
| 61 | config.test_exec_root = os.path.join(lld_obj_root, 'test') | |
| 62 | ||
| 63 | # Set llvm_{src,obj}_root for use by others. | |
| 64 | config.llvm_src_root = getattr(config, 'llvm_src_root', None) | |
| 65 | config.llvm_obj_root = getattr(config, 'llvm_obj_root', None) | |
| 66 | ||
| 67 | # Tweak the PATH to include the tools dir and the scripts dir. | |
| 68 | if lld_obj_root is not None: | |
| 69 | lld_tools_dir = getattr(config, 'lld_tools_dir', None) | |
| 70 | if not lld_tools_dir: | |
| 71 | lit_config.fatal('No LLD tools dir set!') | |
| 72 | llvm_tools_dir = getattr(config, 'llvm_tools_dir', None) | |
| 73 | if not llvm_tools_dir: | |
| 74 | lit_config.fatal('No LLVM tools dir set!') | |
| 75 | path = os.path.pathsep.join((lld_tools_dir, llvm_tools_dir, config.environment['PATH'])) | |
| 76 | path = os.path.pathsep.join((os.path.join(getattr(config, 'llvm_src_root', None),'test','Scripts'),path)) | |
| 77 | ||
| 78 | config.environment['PATH'] = path | |
| 79 | ||
| 80 | lld_libs_dir = getattr(config, 'lld_libs_dir', None) | |
| 81 | if not lld_libs_dir: | |
| 82 | lit_config.fatal('No LLD libs dir set!') | |
| 83 | llvm_libs_dir = getattr(config, 'llvm_libs_dir', None) | |
| 84 | if not llvm_libs_dir: | |
| 85 | lit_config.fatal('No LLVM libs dir set!') | |
| 86 | path = os.path.pathsep.join((lld_libs_dir, llvm_libs_dir, | |
| 87 | config.environment.get('LD_LIBRARY_PATH',''))) | |
| 88 | config.environment['LD_LIBRARY_PATH'] = path | |
| 89 | ||
| 90 | # Propagate LLVM_SRC_ROOT into the environment. | |
| 91 | config.environment['LLVM_SRC_ROOT'] = getattr(config, 'llvm_src_root', '') | |
| 92 | ||
| 93 | # Propagate PYTHON_EXECUTABLE into the environment | |
| 94 | config.environment['PYTHON_EXECUTABLE'] = getattr(config, 'python_executable', | |
| 95 | '') | |
| 96 | ### | |
| 97 | ||
| 98 | # Check that the object root is known. | |
| 99 | if config.test_exec_root is None: | |
| 100 | # Otherwise, we haven't loaded the site specific configuration (the user is | |
| 101 | # probably trying to run on a test file directly, and either the site | |
| 102 | # configuration hasn't been created by the build system, or we are in an | |
| 103 | # out-of-tree build situation). | |
| 104 | ||
| 105 | # Check for 'lld_site_config' user parameter, and use that if available. | |
| 106 | site_cfg = lit_config.params.get('lld_site_config', None) | |
| 107 | if site_cfg and os.path.exists(site_cfg): | |
| 108 | lit_config.load_config(config, site_cfg) | |
| 109 | raise SystemExit | |
| 110 | ||
| 111 | # Try to detect the situation where we are using an out-of-tree build by | |
| 112 | # looking for 'llvm-config'. | |
| 113 | # | |
| 114 | # FIXME: I debated (i.e., wrote and threw away) adding logic to | |
| 115 | # automagically generate the lit.site.cfg if we are in some kind of fresh | |
| 116 | # build situation. This means knowing how to invoke the build system though, | |
| 117 | # and I decided it was too much magic. We should solve this by just having | |
| 118 | # the .cfg files generated during the configuration step. | |
| 119 | ||
| 120 | llvm_config = lit.util.which('llvm-config', config.environment['PATH']) | |
| 121 | if not llvm_config: | |
| 122 | lit_config.fatal('No site specific configuration available!') | |
| 123 | ||
| 124 | # Get the source and object roots. | |
| 125 | llvm_src_root = subprocess.check_output(['llvm-config', '--src-root']).strip() | |
| 126 | llvm_obj_root = subprocess.check_output(['llvm-config', '--obj-root']).strip() | |
| 127 | lld_src_root = os.path.join(llvm_src_root, "tools", "lld") | |
| 128 | lld_obj_root = os.path.join(llvm_obj_root, "tools", "lld") | |
| 129 | ||
| 130 | # Validate that we got a tree which points to here, using the standard | |
| 131 | # tools/lld layout. | |
| 132 | this_src_root = os.path.dirname(config.test_source_root) | |
| 133 | if os.path.realpath(lld_src_root) != os.path.realpath(this_src_root): | |
| 134 | lit_config.fatal('No site specific configuration available!') | |
| 135 | ||
| 136 | # Check that the site specific configuration exists. | |
| 137 | site_cfg = os.path.join(lld_obj_root, 'test', 'lit.site.cfg') | |
| 138 | if not os.path.exists(site_cfg): | |
| 139 | lit_config.fatal( | |
| 140 | 'No site specific configuration available! You may need to ' | |
| 141 | 'run "make test" in your lld build directory.') | |
| 142 | ||
| 143 | # Okay, that worked. Notify the user of the automagic, and reconfigure. | |
| 144 | lit_config.note('using out-of-tree build at %r' % lld_obj_root) | |
| 145 | lit_config.load_config(config, site_cfg) | |
| 146 | raise SystemExit | |
| 147 | ||
| 148 | # For each occurrence of a lld tool name as its own word, replace it | |
| 149 | # with the full path to the build directory holding that tool. This | |
| 150 | # ensures that we are testing the tools just built and not some random | |
| 151 | # tools that might happen to be in the user's PATH. | |
| 152 | ||
| 153 | # Regex assertions to reject neighbor hyphens/dots (seen in some tests). | |
| 154 | # For example, we want to prefix 'lld' and 'ld.lld' but not the 'lld' inside | |
| 155 | # of 'ld.lld'. | |
| 156 | NoPreJunk = r"(?<!(-|\.|/))" | |
| 157 | NoPostJunk = r"(?!(-|\.))" | |
| 158 | ||
| 159 | config.substitutions.append( (r"\bld.lld\b", 'ld.lld --full-shutdown') ) | |
| 160 | ||
| 161 | tool_patterns = [r"\bFileCheck\b", | |
| 162 | r"\bnot\b", | |
| 163 | NoPreJunk + r"\blld\b" + NoPostJunk, | |
| 164 | r"\bld.lld\b", | |
| 165 | r"\blld-link\b", | |
| 166 | r"\bllvm-as\b", | |
| 167 | r"\bllvm-mc\b", | |
| 168 | r"\bllvm-nm\b", | |
| 169 | r"\bllvm-objdump\b", | |
| 170 | r"\bllvm-pdbutil\b", | |
| 171 | r"\bllvm-readobj\b", | |
| 172 | r"\bobj2yaml\b", | |
| 173 | r"\byaml2obj\b"] | |
| 174 | ||
| 175 | for pattern in tool_patterns: | |
| 176 | # Extract the tool name from the pattern. This relies on the tool | |
| 177 | # name being surrounded by \b word match operators. If the | |
| 178 | # pattern starts with "| ", include it in the string to be | |
| 179 | # substituted. | |
| 180 | tool_match = re.match(r"^(\\)?((\| )?)\W+b([0-9A-Za-z-_\.]+)\\b\W*$", | |
| 181 | pattern) | |
| 182 | tool_pipe = tool_match.group(2) | |
| 183 | tool_name = tool_match.group(4) | |
| 184 | tool_path = lit.util.which(tool_name, config.environment['PATH']) | |
| 185 | if not tool_path: | |
| 186 | # Warn, but still provide a substitution. | |
| 187 | lit_config.note('Did not find ' + tool_name + ' in ' + path) | |
| 188 | tool_path = llvm_tools_dir + '/' + tool_name | |
| 189 | config.substitutions.append((pattern, tool_pipe + tool_path)) | |
| 190 | ||
| 191 | # Add site-specific substitutions. | |
| 192 | config.substitutions.append( ('%python', config.python_executable) ) | |
| 193 | ||
| 194 | ### | |
| 195 | ||
| 196 | # When running under valgrind, we mangle '-vg' onto the end of the triple so we | |
| 197 | # can check it with XFAIL and XTARGET. | |
| 198 | if lit_config.useValgrind: | |
| 199 | config.target_triple += '-vg' | |
| 200 | ||
| 201 | # Shell execution | |
| 202 | if execute_external: | |
| 203 | config.available_features.add('shell') | |
| 204 | ||
| 205 | # zlib compression library | |
| 206 | if config.have_zlib: | |
| 207 | config.available_features.add("zlib") | |
| 208 | ||
| 209 | # Running on Darwin OS | |
| 210 | if platform.system() in ['Darwin']: | |
| 211 | config.available_features.add('system-linker-mach-o') | |
| 212 | ||
| 213 | # Running on ELF based *nix | |
| 214 | if platform.system() in ['FreeBSD', 'Linux']: | |
| 215 | config.available_features.add('system-linker-elf') | |
| 216 | ||
| 217 | # Running on Windows | |
| 218 | if platform.system() in ['Windows']: | |
| 219 | config.available_features.add('system-windows') | |
| 220 | ||
| 221 | # Set if host-cxxabi's demangler can handle target's symbols. | |
| 222 | if platform.system() not in ['Windows']: | |
| 223 | config.available_features.add('demangler') | |
| 224 | ||
| 225 | # llvm-config knows whether it is compiled with asserts (and) | |
| 226 | # whether we are operating in release/debug mode. | |
| 227 | import subprocess | |
| 228 | try: | |
| 229 | llvm_config_cmd = \ | |
| 230 | subprocess.Popen([os.path.join(llvm_tools_dir, 'llvm-config'), | |
| 231 | '--build-mode', '--assertion-mode', '--targets-built'], | |
| 232 | stdout = subprocess.PIPE) | |
| 233 | except OSError as why: | |
| 234 | print("Could not find llvm-config in " + llvm_tools_dir) | |
| 235 | exit(42) | |
| 236 | ||
| 237 | llvm_config_output = llvm_config_cmd.stdout.read().decode('utf_8') | |
| 238 | llvm_config_output_list = llvm_config_output.split("\n") | |
| 239 | ||
| 240 | if re.search(r'DEBUG', llvm_config_output_list[0]): | |
| 241 | config.available_features.add('debug') | |
| 242 | if re.search(r'ON', llvm_config_output_list[1]): | |
| 243 | config.available_features.add('asserts') | |
| 244 | ||
| 245 | archs = llvm_config_output_list[2] | |
| 246 | if re.search(r'AArch64', archs): | |
| 247 | config.available_features.add('aarch64') | |
| 248 | if re.search(r'AMDGPU', archs): | |
| 249 | config.available_features.add('amdgpu') | |
| 250 | if re.search(r'ARM', archs): | |
| 251 | config.available_features.add('arm') | |
| 252 | if re.search(r'AVR', archs): | |
| 253 | config.available_features.add('avr') | |
| 254 | if re.search(r'Mips', archs): | |
| 255 | config.available_features.add('mips') | |
| 256 | if re.search(r'PowerPC', archs): | |
| 257 | config.available_features.add('ppc') | |
| 258 | if re.search(r'Sparc', archs): | |
| 259 | config.available_features.add('sparc') | |
| 260 | if re.search(r'X86', archs): | |
| 261 | config.available_features.add('x86') | |
| 262 | llvm_config_cmd.wait() | |
| 263 | ||
| 264 | # Set a fake constant version so that we get consitent output. | |
| 265 | config.environment['LLD_VERSION'] = 'LLD 1.0' | |
| 266 | ||
| 267 | # Indirectly check if the mt.exe Microsoft utility exists by searching for | |
| 268 | # cvtres, which always accompanies it. | |
| 269 | if lit.util.which('cvtres', config.environment['PATH']): | |
| 270 | config.available_features.add('win_mt') |
deps/lld/test/lit.cfg.py created+93| ... | ... | @@ -0,0 +1,93 @@ |
| 1 | # -*- Python -*- | |
| 2 | ||
| 3 | import os | |
| 4 | import platform | |
| 5 | import re | |
| 6 | import subprocess | |
| 7 | import locale | |
| 8 | ||
| 9 | import lit.formats | |
| 10 | import lit.util | |
| 11 | ||
| 12 | from lit.llvm import llvm_config | |
| 13 | ||
| 14 | # Configuration file for the 'lit' test runner. | |
| 15 | ||
| 16 | # name: The name of this test suite. | |
| 17 | config.name = 'lld' | |
| 18 | ||
| 19 | # testFormat: The test format to use to interpret tests. | |
| 20 | # | |
| 21 | # For now we require '&&' between commands, until they get globally killed and | |
| 22 | # the test runner updated. | |
| 23 | config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell) | |
| 24 | ||
| 25 | # suffixes: A list of file extensions to treat as test files. | |
| 26 | config.suffixes = ['.ll', '.s', '.test', '.yaml', '.objtxt'] | |
| 27 | ||
| 28 | # excludes: A list of directories to exclude from the testsuite. The 'Inputs' | |
| 29 | # subdirectories contain auxiliary inputs for various tests in their parent | |
| 30 | # directories. | |
| 31 | config.excludes = ['Inputs'] | |
| 32 | ||
| 33 | # test_source_root: The root path where tests are located. | |
| 34 | config.test_source_root = os.path.dirname(__file__) | |
| 35 | ||
| 36 | config.test_exec_root = os.path.join(config.lld_obj_root, 'test') | |
| 37 | ||
| 38 | llvm_config.use_default_substitutions() | |
| 39 | llvm_config.use_lld() | |
| 40 | ||
| 41 | tool_patterns = [ | |
| 42 | 'llc', 'llvm-as', 'llvm-mc', 'llvm-nm', | |
| 43 | 'llvm-objdump', 'llvm-pdbutil', 'llvm-readobj', 'obj2yaml', 'yaml2obj'] | |
| 44 | ||
| 45 | llvm_config.add_tool_substitutions(tool_patterns) | |
| 46 | ||
| 47 | # When running under valgrind, we mangle '-vg' onto the end of the triple so we | |
| 48 | # can check it with XFAIL and XTARGET. | |
| 49 | if lit_config.useValgrind: | |
| 50 | config.target_triple += '-vg' | |
| 51 | ||
| 52 | # Running on ELF based *nix | |
| 53 | if platform.system() in ['FreeBSD', 'Linux']: | |
| 54 | config.available_features.add('system-linker-elf') | |
| 55 | ||
| 56 | # Set if host-cxxabi's demangler can handle target's symbols. | |
| 57 | if platform.system() not in ['Windows']: | |
| 58 | config.available_features.add('demangler') | |
| 59 | ||
| 60 | llvm_config.feature_config( | |
| 61 | [('--build-mode', {'DEBUG': 'debug'}), | |
| 62 | ('--assertion-mode', {'ON': 'asserts'}), | |
| 63 | ('--targets-built', {'AArch64': 'aarch64', | |
| 64 | 'AMDGPU': 'amdgpu', | |
| 65 | 'ARM': 'arm', | |
| 66 | 'AVR': 'avr', | |
| 67 | 'Mips': 'mips', | |
| 68 | 'PowerPC': 'ppc', | |
| 69 | 'Sparc': 'sparc', | |
| 70 | 'WebAssembly': 'wasm', | |
| 71 | 'X86': 'x86'}) | |
| 72 | ]) | |
| 73 | ||
| 74 | # Set a fake constant version so that we get consitent output. | |
| 75 | config.environment['LLD_VERSION'] = 'LLD 1.0' | |
| 76 | ||
| 77 | # Indirectly check if the mt.exe Microsoft utility exists by searching for | |
| 78 | # cvtres, which always accompanies it. Alternatively, check if we can use | |
| 79 | # libxml2 to merge manifests. | |
| 80 | if (lit.util.which('cvtres', config.environment['PATH'])) or \ | |
| 81 | (config.llvm_libxml2_enabled == '1'): | |
| 82 | config.available_features.add('manifest_tool') | |
| 83 | ||
| 84 | if (config.llvm_libxml2_enabled == '1'): | |
| 85 | config.available_features.add('libxml2') | |
| 86 | ||
| 87 | tar_executable = lit.util.which('tar', config.environment['PATH']) | |
| 88 | if tar_executable: | |
| 89 | tar_version = subprocess.Popen( | |
| 90 | [tar_executable, '--version'], stdout=subprocess.PIPE, env={'LANG': 'C'}) | |
| 91 | if 'GNU tar' in tar_version.stdout.read().decode(): | |
| 92 | config.available_features.add('gnutar') | |
| 93 | tar_version.wait() |
deps/lld/test/lit.site.cfg.in deleted-25| ... | ... | @@ -1,25 +0,0 @@ |
| 1 | @LIT_SITE_CFG_IN_HEADER@ | |
| 2 | ||
| 3 | config.llvm_src_root = "@LLVM_SOURCE_DIR@" | |
| 4 | config.llvm_obj_root = "@LLVM_BINARY_DIR@" | |
| 5 | config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" | |
| 6 | config.llvm_libs_dir = "@LLVM_LIBS_DIR@" | |
| 7 | config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" | |
| 8 | config.lld_obj_root = "@LLD_BINARY_DIR@" | |
| 9 | config.lld_libs_dir = "@LLVM_LIBRARY_OUTPUT_INTDIR@" | |
| 10 | config.lld_tools_dir = "@LLVM_RUNTIME_OUTPUT_INTDIR@" | |
| 11 | config.target_triple = "@TARGET_TRIPLE@" | |
| 12 | config.python_executable = "@PYTHON_EXECUTABLE@" | |
| 13 | config.have_zlib = @HAVE_LIBZ@ | |
| 14 | ||
| 15 | # Support substitution of the tools and libs dirs with user parameters. This is | |
| 16 | # used when we can't determine the tool dir at configuration time. | |
| 17 | try: | |
| 18 | config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params | |
| 19 | config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params | |
| 20 | except KeyError as e: | |
| 21 | key, = e.args | |
| 22 | lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) | |
| 23 | ||
| 24 | # Let the main config do the real work. | |
| 25 | lit_config.load_config(config, "@LLD_SOURCE_DIR@/test/lit.cfg") |
deps/lld/test/lit.site.cfg.py.in created+28| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | @LIT_SITE_CFG_IN_HEADER@ | |
| 2 | ||
| 3 | config.llvm_src_root = "@LLVM_SOURCE_DIR@" | |
| 4 | config.llvm_obj_root = "@LLVM_BINARY_DIR@" | |
| 5 | config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" | |
| 6 | config.llvm_libs_dir = "@LLVM_LIBS_DIR@" | |
| 7 | config.llvm_libxml2_enabled = "@LLVM_LIBXML2_ENABLED@" | |
| 8 | config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" | |
| 9 | config.lld_obj_root = "@LLD_BINARY_DIR@" | |
| 10 | config.lld_libs_dir = "@LLVM_LIBRARY_OUTPUT_INTDIR@" | |
| 11 | config.lld_tools_dir = "@LLVM_RUNTIME_OUTPUT_INTDIR@" | |
| 12 | config.target_triple = "@TARGET_TRIPLE@" | |
| 13 | config.python_executable = "@PYTHON_EXECUTABLE@" | |
| 14 | config.have_zlib = @HAVE_LIBZ@ | |
| 15 | ||
| 16 | # Support substitution of the tools and libs dirs with user parameters. This is | |
| 17 | # used when we can't determine the tool dir at configuration time. | |
| 18 | try: | |
| 19 | config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params | |
| 20 | config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params | |
| 21 | except KeyError as e: | |
| 22 | key, = e.args | |
| 23 | lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) | |
| 24 | ||
| 25 | @LIT_SITE_CFG_IN_FOOTER@ | |
| 26 | ||
| 27 | # Let the main config do the real work. | |
| 28 | lit_config.load_config(config, "@LLD_SOURCE_DIR@/test/lit.cfg.py") |
deps/lld/test/wasm/Inputs/archive1.ll created+7| ... | ... | @@ -0,0 +1,7 @@ |
| 1 | declare i32 @bar() local_unnamed_addr #1 | |
| 2 | ||
| 3 | define i32 @foo() local_unnamed_addr #0 { | |
| 4 | entry: | |
| 5 | %call = tail call i32 @bar() #2 | |
| 6 | ret i32 %call | |
| 7 | } |
deps/lld/test/wasm/Inputs/archive2.ll created+7| ... | ... | @@ -0,0 +1,7 @@ |
| 1 | declare i32 @foo() local_unnamed_addr #1 | |
| 2 | ||
| 3 | define i32 @bar() local_unnamed_addr #0 { | |
| 4 | entry: | |
| 5 | %call = tail call i32 @foo() #2 | |
| 6 | ret i32 %call | |
| 7 | } |
deps/lld/test/wasm/Inputs/call-indirect.ll created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | @indirect_bar = internal local_unnamed_addr global i32 ()* @bar, align 4 | |
| 2 | @indirect_foo = internal local_unnamed_addr global i32 ()* @foo, align 4 | |
| 3 | ||
| 4 | declare i32 @foo() local_unnamed_addr | |
| 5 | ||
| 6 | define i32 @bar() { | |
| 7 | entry: | |
| 8 | ret i32 1 | |
| 9 | } | |
| 10 | ||
| 11 | define void @call_bar_indirect() local_unnamed_addr #1 { | |
| 12 | entry: | |
| 13 | %0 = load i32 ()*, i32 ()** @indirect_bar, align 4 | |
| 14 | %1 = load i32 ()*, i32 ()** @indirect_foo, align 4 | |
| 15 | %call = tail call i32 %0() #2 | |
| 16 | ret void | |
| 17 | } |
deps/lld/test/wasm/Inputs/global-ctor-dtor.ll created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | define hidden void @myctor() { | |
| 2 | entry: | |
| 3 | ret void | |
| 4 | } | |
| 5 | ||
| 6 | define hidden void @mydtor() { | |
| 7 | entry: | |
| 8 | %ptr = alloca i32 | |
| 9 | ret void | |
| 10 | } | |
| 11 | ||
| 12 | @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @myctor, i8* null }] | |
| 13 | ||
| 14 | @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @mydtor, i8* null }] |
deps/lld/test/wasm/Inputs/hello.ll created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | ; Wasm module generated from the following C code: | |
| 2 | ; void puts(const char*); | |
| 3 | ; void hello() { puts("hello\n"); } | |
| 4 | ||
| 5 | @hello_str = unnamed_addr constant [7 x i8] c"hello\0A\00", align 1 | |
| 6 | ||
| 7 | ; Function Attrs: nounwind | |
| 8 | define hidden void @hello() local_unnamed_addr #0 { | |
| 9 | entry: | |
| 10 | tail call void @puts(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @hello_str, i32 0, i32 0)) | |
| 11 | ret void | |
| 12 | } | |
| 13 | ||
| 14 | ; Function Attrs: nounwind | |
| 15 | declare void @puts(i8* nocapture readonly) local_unnamed_addr #1 |
deps/lld/test/wasm/Inputs/hidden.ll created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | ; Function Attrs: norecurse nounwind readnone | |
| 2 | define hidden i32 @archiveHidden() #0 { | |
| 3 | entry: | |
| 4 | ret i32 0 | |
| 5 | } | |
| 6 | ||
| 7 | ; Function Attrs: norecurse nounwind readnone | |
| 8 | define i32 @archiveDefault() #1 { | |
| 9 | entry: | |
| 10 | ret i32 0 | |
| 11 | } |
deps/lld/test/wasm/Inputs/many-funcs.ll created+776| ... | ... | @@ -0,0 +1,776 @@ |
| 1 | @g0 = global i32 1, align 4 | |
| 2 | @foo = global i32 1, align 4 | |
| 3 | ||
| 4 | define i32 @f1() { | |
| 5 | entry: | |
| 6 | %0 = load i32, i32* @foo, align 4 | |
| 7 | ret i32 %0 | |
| 8 | } | |
| 9 | ||
| 10 | define i32 @f2() { | |
| 11 | entry: | |
| 12 | %0 = load i32, i32* @foo, align 4 | |
| 13 | ret i32 %0 | |
| 14 | } | |
| 15 | ||
| 16 | define i32 @f3() { | |
| 17 | entry: | |
| 18 | %0 = load i32, i32* @foo, align 4 | |
| 19 | ret i32 %0 | |
| 20 | } | |
| 21 | ||
| 22 | define i32 @f4() { | |
| 23 | entry: | |
| 24 | %0 = load i32, i32* @foo, align 4 | |
| 25 | ret i32 %0 | |
| 26 | } | |
| 27 | ||
| 28 | define i32 @f5() { | |
| 29 | entry: | |
| 30 | %0 = load i32, i32* @foo, align 4 | |
| 31 | ret i32 %0 | |
| 32 | } | |
| 33 | ||
| 34 | define i32 @f6() { | |
| 35 | entry: | |
| 36 | %0 = load i32, i32* @foo, align 4 | |
| 37 | ret i32 %0 | |
| 38 | } | |
| 39 | ||
| 40 | define i32 @f7() { | |
| 41 | entry: | |
| 42 | %0 = load i32, i32* @foo, align 4 | |
| 43 | ret i32 %0 | |
| 44 | } | |
| 45 | ||
| 46 | define i32 @f8() { | |
| 47 | entry: | |
| 48 | %0 = load i32, i32* @foo, align 4 | |
| 49 | ret i32 %0 | |
| 50 | } | |
| 51 | ||
| 52 | define i32 @f9() { | |
| 53 | entry: | |
| 54 | %0 = load i32, i32* @foo, align 4 | |
| 55 | ret i32 %0 | |
| 56 | } | |
| 57 | ||
| 58 | define i32 @f10() { | |
| 59 | entry: | |
| 60 | %0 = load i32, i32* @foo, align 4 | |
| 61 | ret i32 %0 | |
| 62 | } | |
| 63 | ||
| 64 | define i32 @f11() { | |
| 65 | entry: | |
| 66 | %0 = load i32, i32* @foo, align 4 | |
| 67 | ret i32 %0 | |
| 68 | } | |
| 69 | ||
| 70 | define i32 @f12() { | |
| 71 | entry: | |
| 72 | %0 = load i32, i32* @foo, align 4 | |
| 73 | ret i32 %0 | |
| 74 | } | |
| 75 | ||
| 76 | define i32 @f13() { | |
| 77 | entry: | |
| 78 | %0 = load i32, i32* @foo, align 4 | |
| 79 | ret i32 %0 | |
| 80 | } | |
| 81 | ||
| 82 | define i32 @f14() { | |
| 83 | entry: | |
| 84 | %0 = load i32, i32* @foo, align 4 | |
| 85 | ret i32 %0 | |
| 86 | } | |
| 87 | ||
| 88 | define i32 @f15() { | |
| 89 | entry: | |
| 90 | %0 = load i32, i32* @foo, align 4 | |
| 91 | ret i32 %0 | |
| 92 | } | |
| 93 | ||
| 94 | define i32 @f16() { | |
| 95 | entry: | |
| 96 | %0 = load i32, i32* @foo, align 4 | |
| 97 | ret i32 %0 | |
| 98 | } | |
| 99 | ||
| 100 | define i32 @f17() { | |
| 101 | entry: | |
| 102 | %0 = load i32, i32* @foo, align 4 | |
| 103 | ret i32 %0 | |
| 104 | } | |
| 105 | ||
| 106 | define i32 @f18() { | |
| 107 | entry: | |
| 108 | %0 = load i32, i32* @foo, align 4 | |
| 109 | ret i32 %0 | |
| 110 | } | |
| 111 | ||
| 112 | define i32 @f19() { | |
| 113 | entry: | |
| 114 | %0 = load i32, i32* @foo, align 4 | |
| 115 | ret i32 %0 | |
| 116 | } | |
| 117 | ||
| 118 | define i32 @f20() { | |
| 119 | entry: | |
| 120 | %0 = load i32, i32* @foo, align 4 | |
| 121 | ret i32 %0 | |
| 122 | } | |
| 123 | ||
| 124 | define i32 @f21() { | |
| 125 | entry: | |
| 126 | %0 = load i32, i32* @foo, align 4 | |
| 127 | ret i32 %0 | |
| 128 | } | |
| 129 | ||
| 130 | define i32 @f22() { | |
| 131 | entry: | |
| 132 | %0 = load i32, i32* @foo, align 4 | |
| 133 | ret i32 %0 | |
| 134 | } | |
| 135 | ||
| 136 | define i32 @f23() { | |
| 137 | entry: | |
| 138 | %0 = load i32, i32* @foo, align 4 | |
| 139 | ret i32 %0 | |
| 140 | } | |
| 141 | ||
| 142 | define i32 @f24() { | |
| 143 | entry: | |
| 144 | %0 = load i32, i32* @foo, align 4 | |
| 145 | ret i32 %0 | |
| 146 | } | |
| 147 | ||
| 148 | define i32 @f25() { | |
| 149 | entry: | |
| 150 | %0 = load i32, i32* @foo, align 4 | |
| 151 | ret i32 %0 | |
| 152 | } | |
| 153 | ||
| 154 | define i32 @f26() { | |
| 155 | entry: | |
| 156 | %0 = load i32, i32* @foo, align 4 | |
| 157 | ret i32 %0 | |
| 158 | } | |
| 159 | ||
| 160 | define i32 @f27() { | |
| 161 | entry: | |
| 162 | %0 = load i32, i32* @foo, align 4 | |
| 163 | ret i32 %0 | |
| 164 | } | |
| 165 | ||
| 166 | define i32 @f28() { | |
| 167 | entry: | |
| 168 | %0 = load i32, i32* @foo, align 4 | |
| 169 | ret i32 %0 | |
| 170 | } | |
| 171 | ||
| 172 | define i32 @f29() { | |
| 173 | entry: | |
| 174 | %0 = load i32, i32* @foo, align 4 | |
| 175 | ret i32 %0 | |
| 176 | } | |
| 177 | ||
| 178 | define i32 @f30() { | |
| 179 | entry: | |
| 180 | %0 = load i32, i32* @foo, align 4 | |
| 181 | ret i32 %0 | |
| 182 | } | |
| 183 | ||
| 184 | define i32 @f31() { | |
| 185 | entry: | |
| 186 | %0 = load i32, i32* @foo, align 4 | |
| 187 | ret i32 %0 | |
| 188 | } | |
| 189 | ||
| 190 | define i32 @f32() { | |
| 191 | entry: | |
| 192 | %0 = load i32, i32* @foo, align 4 | |
| 193 | ret i32 %0 | |
| 194 | } | |
| 195 | ||
| 196 | define i32 @f33() { | |
| 197 | entry: | |
| 198 | %0 = load i32, i32* @foo, align 4 | |
| 199 | ret i32 %0 | |
| 200 | } | |
| 201 | ||
| 202 | define i32 @f34() { | |
| 203 | entry: | |
| 204 | %0 = load i32, i32* @foo, align 4 | |
| 205 | ret i32 %0 | |
| 206 | } | |
| 207 | ||
| 208 | define i32 @f35() { | |
| 209 | entry: | |
| 210 | %0 = load i32, i32* @foo, align 4 | |
| 211 | ret i32 %0 | |
| 212 | } | |
| 213 | ||
| 214 | define i32 @f36() { | |
| 215 | entry: | |
| 216 | %0 = load i32, i32* @foo, align 4 | |
| 217 | ret i32 %0 | |
| 218 | } | |
| 219 | ||
| 220 | define i32 @f37() { | |
| 221 | entry: | |
| 222 | %0 = load i32, i32* @foo, align 4 | |
| 223 | ret i32 %0 | |
| 224 | } | |
| 225 | ||
| 226 | define i32 @f38() { | |
| 227 | entry: | |
| 228 | %0 = load i32, i32* @foo, align 4 | |
| 229 | ret i32 %0 | |
| 230 | } | |
| 231 | ||
| 232 | define i32 @f39() { | |
| 233 | entry: | |
| 234 | %0 = load i32, i32* @foo, align 4 | |
| 235 | ret i32 %0 | |
| 236 | } | |
| 237 | ||
| 238 | define i32 @f40() { | |
| 239 | entry: | |
| 240 | %0 = load i32, i32* @foo, align 4 | |
| 241 | ret i32 %0 | |
| 242 | } | |
| 243 | ||
| 244 | define i32 @f41() { | |
| 245 | entry: | |
| 246 | %0 = load i32, i32* @foo, align 4 | |
| 247 | ret i32 %0 | |
| 248 | } | |
| 249 | ||
| 250 | define i32 @f42() { | |
| 251 | entry: | |
| 252 | %0 = load i32, i32* @foo, align 4 | |
| 253 | ret i32 %0 | |
| 254 | } | |
| 255 | ||
| 256 | define i32 @f43() { | |
| 257 | entry: | |
| 258 | %0 = load i32, i32* @foo, align 4 | |
| 259 | ret i32 %0 | |
| 260 | } | |
| 261 | ||
| 262 | define i32 @f44() { | |
| 263 | entry: | |
| 264 | %0 = load i32, i32* @foo, align 4 | |
| 265 | ret i32 %0 | |
| 266 | } | |
| 267 | ||
| 268 | define i32 @f45() { | |
| 269 | entry: | |
| 270 | %0 = load i32, i32* @foo, align 4 | |
| 271 | ret i32 %0 | |
| 272 | } | |
| 273 | ||
| 274 | define i32 @f46() { | |
| 275 | entry: | |
| 276 | %0 = load i32, i32* @foo, align 4 | |
| 277 | ret i32 %0 | |
| 278 | } | |
| 279 | ||
| 280 | define i32 @f47() { | |
| 281 | entry: | |
| 282 | %0 = load i32, i32* @foo, align 4 | |
| 283 | ret i32 %0 | |
| 284 | } | |
| 285 | ||
| 286 | define i32 @f48() { | |
| 287 | entry: | |
| 288 | %0 = load i32, i32* @foo, align 4 | |
| 289 | ret i32 %0 | |
| 290 | } | |
| 291 | ||
| 292 | define i32 @f49() { | |
| 293 | entry: | |
| 294 | %0 = load i32, i32* @foo, align 4 | |
| 295 | ret i32 %0 | |
| 296 | } | |
| 297 | ||
| 298 | define i32 @f50() { | |
| 299 | entry: | |
| 300 | %0 = load i32, i32* @foo, align 4 | |
| 301 | ret i32 %0 | |
| 302 | } | |
| 303 | ||
| 304 | define i32 @f51() { | |
| 305 | entry: | |
| 306 | %0 = load i32, i32* @foo, align 4 | |
| 307 | ret i32 %0 | |
| 308 | } | |
| 309 | ||
| 310 | define i32 @f52() { | |
| 311 | entry: | |
| 312 | %0 = load i32, i32* @foo, align 4 | |
| 313 | ret i32 %0 | |
| 314 | } | |
| 315 | ||
| 316 | define i32 @f53() { | |
| 317 | entry: | |
| 318 | %0 = load i32, i32* @foo, align 4 | |
| 319 | ret i32 %0 | |
| 320 | } | |
| 321 | ||
| 322 | define i32 @f54() { | |
| 323 | entry: | |
| 324 | %0 = load i32, i32* @foo, align 4 | |
| 325 | ret i32 %0 | |
| 326 | } | |
| 327 | ||
| 328 | define i32 @f55() { | |
| 329 | entry: | |
| 330 | %0 = load i32, i32* @foo, align 4 | |
| 331 | ret i32 %0 | |
| 332 | } | |
| 333 | ||
| 334 | define i32 @f56() { | |
| 335 | entry: | |
| 336 | %0 = load i32, i32* @foo, align 4 | |
| 337 | ret i32 %0 | |
| 338 | } | |
| 339 | ||
| 340 | define i32 @f57() { | |
| 341 | entry: | |
| 342 | %0 = load i32, i32* @foo, align 4 | |
| 343 | ret i32 %0 | |
| 344 | } | |
| 345 | ||
| 346 | define i32 @f58() { | |
| 347 | entry: | |
| 348 | %0 = load i32, i32* @foo, align 4 | |
| 349 | ret i32 %0 | |
| 350 | } | |
| 351 | ||
| 352 | define i32 @f59() { | |
| 353 | entry: | |
| 354 | %0 = load i32, i32* @foo, align 4 | |
| 355 | ret i32 %0 | |
| 356 | } | |
| 357 | ||
| 358 | define i32 @f60() { | |
| 359 | entry: | |
| 360 | %0 = load i32, i32* @foo, align 4 | |
| 361 | ret i32 %0 | |
| 362 | } | |
| 363 | ||
| 364 | define i32 @f61() { | |
| 365 | entry: | |
| 366 | %0 = load i32, i32* @foo, align 4 | |
| 367 | ret i32 %0 | |
| 368 | } | |
| 369 | ||
| 370 | define i32 @f62() { | |
| 371 | entry: | |
| 372 | %0 = load i32, i32* @foo, align 4 | |
| 373 | ret i32 %0 | |
| 374 | } | |
| 375 | ||
| 376 | define i32 @f63() { | |
| 377 | entry: | |
| 378 | %0 = load i32, i32* @foo, align 4 | |
| 379 | ret i32 %0 | |
| 380 | } | |
| 381 | ||
| 382 | define i32 @f64() { | |
| 383 | entry: | |
| 384 | %0 = load i32, i32* @foo, align 4 | |
| 385 | ret i32 %0 | |
| 386 | } | |
| 387 | ||
| 388 | define i32 @f65() { | |
| 389 | entry: | |
| 390 | %0 = load i32, i32* @foo, align 4 | |
| 391 | ret i32 %0 | |
| 392 | } | |
| 393 | ||
| 394 | define i32 @f66() { | |
| 395 | entry: | |
| 396 | %0 = load i32, i32* @foo, align 4 | |
| 397 | ret i32 %0 | |
| 398 | } | |
| 399 | ||
| 400 | define i32 @f67() { | |
| 401 | entry: | |
| 402 | %0 = load i32, i32* @foo, align 4 | |
| 403 | ret i32 %0 | |
| 404 | } | |
| 405 | ||
| 406 | define i32 @f68() { | |
| 407 | entry: | |
| 408 | %0 = load i32, i32* @foo, align 4 | |
| 409 | ret i32 %0 | |
| 410 | } | |
| 411 | ||
| 412 | define i32 @f69() { | |
| 413 | entry: | |
| 414 | %0 = load i32, i32* @foo, align 4 | |
| 415 | ret i32 %0 | |
| 416 | } | |
| 417 | ||
| 418 | define i32 @f70() { | |
| 419 | entry: | |
| 420 | %0 = load i32, i32* @foo, align 4 | |
| 421 | ret i32 %0 | |
| 422 | } | |
| 423 | ||
| 424 | define i32 @f71() { | |
| 425 | entry: | |
| 426 | %0 = load i32, i32* @foo, align 4 | |
| 427 | ret i32 %0 | |
| 428 | } | |
| 429 | ||
| 430 | define i32 @f72() { | |
| 431 | entry: | |
| 432 | %0 = load i32, i32* @foo, align 4 | |
| 433 | ret i32 %0 | |
| 434 | } | |
| 435 | ||
| 436 | define i32 @f73() { | |
| 437 | entry: | |
| 438 | %0 = load i32, i32* @foo, align 4 | |
| 439 | ret i32 %0 | |
| 440 | } | |
| 441 | ||
| 442 | define i32 @f74() { | |
| 443 | entry: | |
| 444 | %0 = load i32, i32* @foo, align 4 | |
| 445 | ret i32 %0 | |
| 446 | } | |
| 447 | ||
| 448 | define i32 @f75() { | |
| 449 | entry: | |
| 450 | %0 = load i32, i32* @foo, align 4 | |
| 451 | ret i32 %0 | |
| 452 | } | |
| 453 | ||
| 454 | define i32 @f76() { | |
| 455 | entry: | |
| 456 | %0 = load i32, i32* @foo, align 4 | |
| 457 | ret i32 %0 | |
| 458 | } | |
| 459 | ||
| 460 | define i32 @f77() { | |
| 461 | entry: | |
| 462 | %0 = load i32, i32* @foo, align 4 | |
| 463 | ret i32 %0 | |
| 464 | } | |
| 465 | ||
| 466 | define i32 @f78() { | |
| 467 | entry: | |
| 468 | %0 = load i32, i32* @foo, align 4 | |
| 469 | ret i32 %0 | |
| 470 | } | |
| 471 | ||
| 472 | define i32 @f79() { | |
| 473 | entry: | |
| 474 | %0 = load i32, i32* @foo, align 4 | |
| 475 | ret i32 %0 | |
| 476 | } | |
| 477 | ||
| 478 | define i32 @f80() { | |
| 479 | entry: | |
| 480 | %0 = load i32, i32* @foo, align 4 | |
| 481 | ret i32 %0 | |
| 482 | } | |
| 483 | ||
| 484 | define i32 @f81() { | |
| 485 | entry: | |
| 486 | %0 = load i32, i32* @foo, align 4 | |
| 487 | ret i32 %0 | |
| 488 | } | |
| 489 | ||
| 490 | define i32 @f82() { | |
| 491 | entry: | |
| 492 | %0 = load i32, i32* @foo, align 4 | |
| 493 | ret i32 %0 | |
| 494 | } | |
| 495 | ||
| 496 | define i32 @f83() { | |
| 497 | entry: | |
| 498 | %0 = load i32, i32* @foo, align 4 | |
| 499 | ret i32 %0 | |
| 500 | } | |
| 501 | ||
| 502 | define i32 @f84() { | |
| 503 | entry: | |
| 504 | %0 = load i32, i32* @foo, align 4 | |
| 505 | ret i32 %0 | |
| 506 | } | |
| 507 | ||
| 508 | define i32 @f85() { | |
| 509 | entry: | |
| 510 | %0 = load i32, i32* @foo, align 4 | |
| 511 | ret i32 %0 | |
| 512 | } | |
| 513 | ||
| 514 | define i32 @f86() { | |
| 515 | entry: | |
| 516 | %0 = load i32, i32* @foo, align 4 | |
| 517 | ret i32 %0 | |
| 518 | } | |
| 519 | ||
| 520 | define i32 @f87() { | |
| 521 | entry: | |
| 522 | %0 = load i32, i32* @foo, align 4 | |
| 523 | ret i32 %0 | |
| 524 | } | |
| 525 | ||
| 526 | define i32 @f88() { | |
| 527 | entry: | |
| 528 | %0 = load i32, i32* @foo, align 4 | |
| 529 | ret i32 %0 | |
| 530 | } | |
| 531 | ||
| 532 | define i32 @f89() { | |
| 533 | entry: | |
| 534 | %0 = load i32, i32* @foo, align 4 | |
| 535 | ret i32 %0 | |
| 536 | } | |
| 537 | ||
| 538 | define i32 @f90() { | |
| 539 | entry: | |
| 540 | %0 = load i32, i32* @foo, align 4 | |
| 541 | ret i32 %0 | |
| 542 | } | |
| 543 | ||
| 544 | define i32 @f91() { | |
| 545 | entry: | |
| 546 | %0 = load i32, i32* @foo, align 4 | |
| 547 | ret i32 %0 | |
| 548 | } | |
| 549 | ||
| 550 | define i32 @f92() { | |
| 551 | entry: | |
| 552 | %0 = load i32, i32* @foo, align 4 | |
| 553 | ret i32 %0 | |
| 554 | } | |
| 555 | ||
| 556 | define i32 @f93() { | |
| 557 | entry: | |
| 558 | %0 = load i32, i32* @foo, align 4 | |
| 559 | ret i32 %0 | |
| 560 | } | |
| 561 | ||
| 562 | define i32 @f94() { | |
| 563 | entry: | |
| 564 | %0 = load i32, i32* @foo, align 4 | |
| 565 | ret i32 %0 | |
| 566 | } | |
| 567 | ||
| 568 | define i32 @f95() { | |
| 569 | entry: | |
| 570 | %0 = load i32, i32* @foo, align 4 | |
| 571 | ret i32 %0 | |
| 572 | } | |
| 573 | ||
| 574 | define i32 @f96() { | |
| 575 | entry: | |
| 576 | %0 = load i32, i32* @foo, align 4 | |
| 577 | ret i32 %0 | |
| 578 | } | |
| 579 | ||
| 580 | define i32 @f97() { | |
| 581 | entry: | |
| 582 | %0 = load i32, i32* @foo, align 4 | |
| 583 | ret i32 %0 | |
| 584 | } | |
| 585 | ||
| 586 | define i32 @f98() { | |
| 587 | entry: | |
| 588 | %0 = load i32, i32* @foo, align 4 | |
| 589 | ret i32 %0 | |
| 590 | } | |
| 591 | ||
| 592 | define i32 @f99() { | |
| 593 | entry: | |
| 594 | %0 = load i32, i32* @foo, align 4 | |
| 595 | ret i32 %0 | |
| 596 | } | |
| 597 | ||
| 598 | define i32 @f100() { | |
| 599 | entry: | |
| 600 | %0 = load i32, i32* @foo, align 4 | |
| 601 | ret i32 %0 | |
| 602 | } | |
| 603 | ||
| 604 | define i32 @f101() { | |
| 605 | entry: | |
| 606 | %0 = load i32, i32* @foo, align 4 | |
| 607 | ret i32 %0 | |
| 608 | } | |
| 609 | ||
| 610 | define i32 @f102() { | |
| 611 | entry: | |
| 612 | %0 = load i32, i32* @foo, align 4 | |
| 613 | ret i32 %0 | |
| 614 | } | |
| 615 | ||
| 616 | define i32 @f103() { | |
| 617 | entry: | |
| 618 | %0 = load i32, i32* @foo, align 4 | |
| 619 | ret i32 %0 | |
| 620 | } | |
| 621 | ||
| 622 | define i32 @f104() { | |
| 623 | entry: | |
| 624 | %0 = load i32, i32* @foo, align 4 | |
| 625 | ret i32 %0 | |
| 626 | } | |
| 627 | ||
| 628 | define i32 @f105() { | |
| 629 | entry: | |
| 630 | %0 = load i32, i32* @foo, align 4 | |
| 631 | ret i32 %0 | |
| 632 | } | |
| 633 | ||
| 634 | define i32 @f106() { | |
| 635 | entry: | |
| 636 | %0 = load i32, i32* @foo, align 4 | |
| 637 | ret i32 %0 | |
| 638 | } | |
| 639 | ||
| 640 | define i32 @f107() { | |
| 641 | entry: | |
| 642 | %0 = load i32, i32* @foo, align 4 | |
| 643 | ret i32 %0 | |
| 644 | } | |
| 645 | ||
| 646 | define i32 @f108() { | |
| 647 | entry: | |
| 648 | %0 = load i32, i32* @foo, align 4 | |
| 649 | ret i32 %0 | |
| 650 | } | |
| 651 | ||
| 652 | define i32 @f109() { | |
| 653 | entry: | |
| 654 | %0 = load i32, i32* @foo, align 4 | |
| 655 | ret i32 %0 | |
| 656 | } | |
| 657 | ||
| 658 | define i32 @f110() { | |
| 659 | entry: | |
| 660 | %0 = load i32, i32* @foo, align 4 | |
| 661 | ret i32 %0 | |
| 662 | } | |
| 663 | ||
| 664 | define i32 @f111() { | |
| 665 | entry: | |
| 666 | %0 = load i32, i32* @foo, align 4 | |
| 667 | ret i32 %0 | |
| 668 | } | |
| 669 | ||
| 670 | define i32 @f112() { | |
| 671 | entry: | |
| 672 | %0 = load i32, i32* @foo, align 4 | |
| 673 | ret i32 %0 | |
| 674 | } | |
| 675 | ||
| 676 | define i32 @f113() { | |
| 677 | entry: | |
| 678 | %0 = load i32, i32* @foo, align 4 | |
| 679 | ret i32 %0 | |
| 680 | } | |
| 681 | ||
| 682 | define i32 @f114() { | |
| 683 | entry: | |
| 684 | %0 = load i32, i32* @foo, align 4 | |
| 685 | ret i32 %0 | |
| 686 | } | |
| 687 | ||
| 688 | define i32 @f115() { | |
| 689 | entry: | |
| 690 | %0 = load i32, i32* @foo, align 4 | |
| 691 | ret i32 %0 | |
| 692 | } | |
| 693 | ||
| 694 | define i32 @f116() { | |
| 695 | entry: | |
| 696 | %0 = load i32, i32* @foo, align 4 | |
| 697 | ret i32 %0 | |
| 698 | } | |
| 699 | ||
| 700 | define i32 @f117() { | |
| 701 | entry: | |
| 702 | %0 = load i32, i32* @foo, align 4 | |
| 703 | ret i32 %0 | |
| 704 | } | |
| 705 | ||
| 706 | define i32 @f118() { | |
| 707 | entry: | |
| 708 | %0 = load i32, i32* @foo, align 4 | |
| 709 | ret i32 %0 | |
| 710 | } | |
| 711 | ||
| 712 | define i32 @f119() { | |
| 713 | entry: | |
| 714 | %0 = load i32, i32* @foo, align 4 | |
| 715 | ret i32 %0 | |
| 716 | } | |
| 717 | ||
| 718 | define i32 @f120() { | |
| 719 | entry: | |
| 720 | %0 = load i32, i32* @foo, align 4 | |
| 721 | ret i32 %0 | |
| 722 | } | |
| 723 | ||
| 724 | define i32 @f121() { | |
| 725 | entry: | |
| 726 | %0 = load i32, i32* @foo, align 4 | |
| 727 | ret i32 %0 | |
| 728 | } | |
| 729 | ||
| 730 | define i32 @f122() { | |
| 731 | entry: | |
| 732 | %0 = load i32, i32* @foo, align 4 | |
| 733 | ret i32 %0 | |
| 734 | } | |
| 735 | ||
| 736 | define i32 @f123() { | |
| 737 | entry: | |
| 738 | %0 = load i32, i32* @foo, align 4 | |
| 739 | ret i32 %0 | |
| 740 | } | |
| 741 | ||
| 742 | define i32 @f124() { | |
| 743 | entry: | |
| 744 | %0 = load i32, i32* @foo, align 4 | |
| 745 | ret i32 %0 | |
| 746 | } | |
| 747 | ||
| 748 | define i32 @f125() { | |
| 749 | entry: | |
| 750 | %0 = load i32, i32* @foo, align 4 | |
| 751 | ret i32 %0 | |
| 752 | } | |
| 753 | ||
| 754 | define i32 @f126() { | |
| 755 | entry: | |
| 756 | %0 = load i32, i32* @foo, align 4 | |
| 757 | ret i32 %0 | |
| 758 | } | |
| 759 | ||
| 760 | define i32 @f127() { | |
| 761 | entry: | |
| 762 | %0 = load i32, i32* @foo, align 4 | |
| 763 | ret i32 %0 | |
| 764 | } | |
| 765 | ||
| 766 | define i32 @f128() { | |
| 767 | entry: | |
| 768 | %0 = load i32, i32* @g0, align 4 | |
| 769 | ret i32 %0 | |
| 770 | } | |
| 771 | ||
| 772 | define i32 @f129() { | |
| 773 | entry: | |
| 774 | %0 = load i32, i32* @g0, align 4 | |
| 775 | ret i32 %0 | |
| 776 | } |
deps/lld/test/wasm/Inputs/ret32.ll created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | ; Function Attrs: norecurse nounwind readnone | |
| 2 | define i32 @ret32(float %arg) #0 { | |
| 3 | entry: | |
| 4 | ret i32 0 | |
| 5 | ; ptrtoint (i32 (float)* @ret32 to i32) | |
| 6 | } |
deps/lld/test/wasm/Inputs/ret64.ll created+4| ... | ... | @@ -0,0 +1,4 @@ |
| 1 | define i64 @ret64(double %arg) local_unnamed_addr #0 { | |
| 2 | entry: | |
| 3 | ret i64 1 | |
| 4 | } |
deps/lld/test/wasm/Inputs/weak-alias.ll created+37| ... | ... | @@ -0,0 +1,37 @@ |
| 1 | ; Function Attrs: norecurse nounwind readnone | |
| 2 | define i32 @direct_fn() #0 { | |
| 3 | entry: | |
| 4 | ret i32 0 | |
| 5 | } | |
| 6 | ||
| 7 | @alias_fn = weak alias i32 (), i32 ()* @direct_fn | |
| 8 | ||
| 9 | define i32 @call_direct() #0 { | |
| 10 | entry: | |
| 11 | %call = call i32 @direct_fn() | |
| 12 | ret i32 %call | |
| 13 | } | |
| 14 | ||
| 15 | define i32 @call_alias() #0 { | |
| 16 | entry: | |
| 17 | %call = call i32 @alias_fn() | |
| 18 | ret i32 %call | |
| 19 | } | |
| 20 | ||
| 21 | define i32 @call_alias_ptr() #0 { | |
| 22 | entry: | |
| 23 | %fnptr = alloca i32 ()*, align 8 | |
| 24 | store i32 ()* @alias_fn, i32 ()** %fnptr, align 8 | |
| 25 | %0 = load i32 ()*, i32 ()** %fnptr, align 8 | |
| 26 | %call = call i32 %0() | |
| 27 | ret i32 %call | |
| 28 | } | |
| 29 | ||
| 30 | define i32 @call_direct_ptr() #0 { | |
| 31 | entry: | |
| 32 | %fnptr = alloca i32 ()*, align 8 | |
| 33 | store i32 ()* @direct_fn, i32 ()** %fnptr, align 8 | |
| 34 | %0 = load i32 ()*, i32 ()** %fnptr, align 8 | |
| 35 | %call = call i32 %0() | |
| 36 | ret i32 %call | |
| 37 | } |
deps/lld/test/wasm/Inputs/weak-symbol1.ll created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | define weak i32 @weakFn() #0 { | |
| 2 | entry: | |
| 3 | ret i32 1 | |
| 4 | } | |
| 5 | ||
| 6 | define i32 @exportWeak1() { | |
| 7 | entry: | |
| 8 | ret i32 ptrtoint (i32 ()* @weakFn to i32) | |
| 9 | } | |
| 10 | ||
| 11 | @weakGlobal = weak global i32 1 |
deps/lld/test/wasm/Inputs/weak-symbol2.ll created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | define weak i32 @weakFn() #0 { | |
| 2 | entry: | |
| 3 | ret i32 2 | |
| 4 | } | |
| 5 | ||
| 6 | define i32 @exportWeak2() { | |
| 7 | entry: | |
| 8 | ret i32 ptrtoint (i32 ()* @weakFn to i32) | |
| 9 | } | |
| 10 | ||
| 11 | @weakGlobal = weak global i32 2 |
deps/lld/test/wasm/archive.ll created+31| ... | ... | @@ -0,0 +1,31 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %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 | |
| 4 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %S/Inputs/hello.ll -o %t.a3.o | |
| 5 | ; RUN: llvm-ar rcs %t.a %t.a1.o %t.a2.o %t.a3.o | |
| 6 | ; RUN: lld -flavor wasm %t.a %t.o -o %t.wasm | |
| 7 | ; RUN: llvm-nm -a %t.wasm | FileCheck %s | |
| 8 | ||
| 9 | declare i32 @foo() local_unnamed_addr #1 | |
| 10 | ||
| 11 | define i32 @_start() local_unnamed_addr #0 { | |
| 12 | entry: | |
| 13 | %call = tail call i32 @foo() #2 | |
| 14 | ret i32 %call | |
| 15 | } | |
| 16 | ||
| 17 | ; Verify that multually dependant object files in an archive is handled | |
| 18 | ; correctly. | |
| 19 | ||
| 20 | ; CHECK: 00000002 T _start | |
| 21 | ; CHECK-NEXT: 00000002 T _start | |
| 22 | ; CHECK-NEXT: 00000000 T bar | |
| 23 | ; CHECK-NEXT: 00000000 T bar | |
| 24 | ; CHECK-NEXT: 00000001 T foo | |
| 25 | ; CHECK-NEXT: 00000001 T foo | |
| 26 | ||
| 27 | ; Verify that symbols from unused objects don't appear in the symbol table | |
| 28 | ; CHECK-NOT: hello | |
| 29 | ||
| 30 | ; Specifying the same archive twice is allowed. | |
| 31 | ; RUN: lld -flavor wasm %t.a %t.a %t.o -o %t.wasm |
deps/lld/test/wasm/call-indirect.ll created+132| ... | ... | @@ -0,0 +1,132 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/call-indirect.ll -o %t2.o | |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | |
| 3 | ; RUN: lld -flavor wasm -o %t.wasm %t2.o %t.o | |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | |
| 5 | ||
| 6 | ; bitcode generated from the following C code: | |
| 7 | ; int foo(void) { return 1; } | |
| 8 | ; int (*indirect_func)(void) = &foo; | |
| 9 | ; void _start(void) { indirect_func(); } | |
| 10 | ||
| 11 | @indirect_func = local_unnamed_addr global i32 ()* @foo, align 4 | |
| 12 | ||
| 13 | ; Function Attrs: norecurse nounwind readnone | |
| 14 | define i32 @foo() #0 { | |
| 15 | entry: | |
| 16 | ret i32 2 | |
| 17 | } | |
| 18 | ||
| 19 | ; Function Attrs: nounwind | |
| 20 | define i32 @_start() local_unnamed_addr #1 { | |
| 21 | entry: | |
| 22 | %0 = load i32 ()*, i32 ()** @indirect_func, align 4 | |
| 23 | %call = call i32 %0() #2 | |
| 24 | ret i32 0 | |
| 25 | } | |
| 26 | ||
| 27 | ; Indirect function call where no function actually has this type. | |
| 28 | ; Ensures that the type entry is still created in this case. | |
| 29 | define void @call_ptr(i64 (i64)* %arg) { | |
| 30 | %1 = call i64 %arg(i64 1) | |
| 31 | ret void | |
| 32 | } | |
| 33 | ||
| 34 | ; CHECK: !WASM | |
| 35 | ; CHECK-NEXT: FileHeader: | |
| 36 | ; CHECK-NEXT: Version: 0x00000001 | |
| 37 | ; CHECK-NEXT: Sections: | |
| 38 | ; CHECK-NEXT: - Type: TYPE | |
| 39 | ; CHECK-NEXT: Signatures: | |
| 40 | ; CHECK-NEXT: - Index: 0 | |
| 41 | ; CHECK-NEXT: ReturnType: I32 | |
| 42 | ; CHECK-NEXT: ParamTypes: | |
| 43 | ; CHECK-NEXT: - Index: 1 | |
| 44 | ; CHECK-NEXT: ReturnType: NORESULT | |
| 45 | ; CHECK-NEXT: ParamTypes: | |
| 46 | ; 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 | |
| 52 | ; CHECK-NEXT: ParamTypes: | |
| 53 | ; CHECK-NEXT: - I64 | |
| 54 | ; CHECK-NEXT: - Type: FUNCTION | |
| 55 | ; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 0, 2 ] | |
| 56 | ; CHECK-NEXT: - Type: TABLE | |
| 57 | ; CHECK-NEXT: Tables: | |
| 58 | ; CHECK-NEXT: - ElemType: ANYFUNC | |
| 59 | ; CHECK-NEXT: Limits: | |
| 60 | ; CHECK-NEXT: Flags: [ HAS_MAX ] | |
| 61 | ; CHECK-NEXT: Initial: 0x00000003 | |
| 62 | ; CHECK-NEXT: Maximum: 0x00000003 | |
| 63 | ; CHECK-NEXT: - Type: MEMORY | |
| 64 | ; CHECK-NEXT: Memories: | |
| 65 | ; CHECK-NEXT: - Initial: 0x00000002 | |
| 66 | ; CHECK-NEXT: - Type: GLOBAL | |
| 67 | ; CHECK-NEXT: Globals: | |
| 68 | ; CHECK-NEXT: - Type: I32 | |
| 69 | ; CHECK-NEXT: Mutable: true | |
| 70 | ; CHECK-NEXT: InitExpr: | |
| 71 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 72 | ; CHECK-NEXT: Value: 66576 | |
| 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: _start | |
| 79 | ; CHECK-NEXT: Kind: FUNCTION | |
| 80 | ; CHECK-NEXT: Index: 3 | |
| 81 | ; CHECK-NEXT: - Name: foo | |
| 82 | ; CHECK-NEXT: Kind: FUNCTION | |
| 83 | ; CHECK-NEXT: Index: 2 | |
| 84 | ; CHECK-NEXT: - Name: bar | |
| 85 | ; CHECK-NEXT: Kind: FUNCTION | |
| 86 | ; CHECK-NEXT: Index: 0 | |
| 87 | ; CHECK-NEXT: - Name: call_bar_indirect | |
| 88 | ; CHECK-NEXT: Kind: FUNCTION | |
| 89 | ; CHECK-NEXT: Index: 1 | |
| 90 | ; CHECK-NEXT: - Name: call_ptr | |
| 91 | ; CHECK-NEXT: Kind: FUNCTION | |
| 92 | ; CHECK-NEXT: Index: 4 | |
| 93 | ; CHECK-NEXT: - Type: ELEM | |
| 94 | ; CHECK-NEXT: Segments: | |
| 95 | ; CHECK-NEXT: - Offset: | |
| 96 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 97 | ; CHECK-NEXT: Value: 1 | |
| 98 | ; CHECK-NEXT: Functions: [ 0, 2 ] | |
| 99 | ; CHECK-NEXT: - Type: CODE | |
| 100 | ; CHECK-NEXT: Functions: | |
| 101 | ; CHECK-NEXT: - Locals: | |
| 102 | ; CHECK-NEXT: Body: 41010B | |
| 103 | ; CHECK-NEXT: - Locals: | |
| 104 | ; CHECK-NEXT: Body: 410028028088808000118080808000001A0B | |
| 105 | ; CHECK-NEXT: - Locals: | |
| 106 | ; CHECK-NEXT: Body: 41020B | |
| 107 | ; CHECK-NEXT: - Locals: | |
| 108 | ; CHECK-NEXT: Body: 410028028888808000118080808000001A41000B | |
| 109 | ; CHECK-NEXT: - Locals: | |
| 110 | ; CHECK-NEXT: Body: 42012000118380808000001A0B | |
| 111 | ; CHECK-NEXT: - Type: DATA | |
| 112 | ; CHECK-NEXT: Segments: | |
| 113 | ; CHECK-NEXT: - SectionOffset: 7 | |
| 114 | ; CHECK-NEXT: MemoryIndex: 0 | |
| 115 | ; CHECK-NEXT: Offset: | |
| 116 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 117 | ; CHECK-NEXT: Value: 1024 | |
| 118 | ; CHECK-NEXT: Content: '010000000200000002000000' | |
| 119 | ; CHECK-NEXT: - Type: CUSTOM | |
| 120 | ; CHECK-NEXT: Name: linking | |
| 121 | ; CHECK-NEXT: DataSize: 12 | |
| 122 | ; CHECK-NEXT: - Type: CUSTOM | |
| 123 | ; CHECK-NEXT: Name: name | |
| 124 | ; CHECK-NEXT: FunctionNames: | |
| 125 | ; CHECK-NEXT: - Index: 0 | |
| 126 | ; CHECK-NEXT: Name: bar | |
| 127 | ; CHECK-NEXT: - Index: 1 | |
| 128 | ; CHECK-NEXT: Name: call_bar_indirect | |
| 129 | ; CHECK-NEXT: - Index: 2 | |
| 130 | ; CHECK-NEXT: Name: foo | |
| 131 | ; CHECK-NEXT: - Index: 3 | |
| 132 | ; CHECK-NEXT: Name: _start |
deps/lld/test/wasm/conflict.test created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | # RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %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 | |
| 3 | ||
| 4 | # CHECK: duplicate symbol: ret32 | |
| 5 | # CHECK-NEXT: >>> defined in {{.*}}conflict.test.tmp.ret32.o | |
| 6 | # CHECK-NEXT: >>> defined in {{.*}}conflict.test.tmp.ret32.o |
deps/lld/test/wasm/data-layout.ll created+61| ... | ... | @@ -0,0 +1,61 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/hello.ll -o %t.hello.o | |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | |
| 3 | ; RUN: lld -flavor wasm --emit-relocs --allow-undefined --no-entry -o %t.wasm %t.o %t.hello.o | |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | |
| 5 | ||
| 6 | @foo = hidden global i32 1, align 4 | |
| 7 | @aligned_bar = hidden global i32 3, align 16 | |
| 8 | ||
| 9 | @hello_str = external global i8* | |
| 10 | @external_ref = global i8** @hello_str, align 8 | |
| 11 | ||
| 12 | ; CHECK: - Type: GLOBAL | |
| 13 | ; CHECK-NEXT: Globals: | |
| 14 | ; CHECK-NEXT: - Type: I32 | |
| 15 | ; CHECK-NEXT: Mutable: true | |
| 16 | ; CHECK-NEXT: InitExpr: | |
| 17 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 18 | ; CHECK-NEXT: Value: 66608 | |
| 19 | ; CHECK-NEXT: - Type: I32 | |
| 20 | ; CHECK-NEXT: Mutable: false | |
| 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 | |
| 31 | ; CHECK-NEXT: InitExpr: | |
| 32 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 33 | ; CHECK-NEXT: Value: 1048 | |
| 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 | ||
| 40 | ; 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: | |
| 46 | ; CHECK-NEXT: - SectionOffset: 7 | |
| 47 | ; CHECK-NEXT: MemoryIndex: 0 | |
| 48 | ; CHECK-NEXT: Offset: | |
| 49 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 50 | ; CHECK-NEXT: Value: 1024 | |
| 51 | ; CHECK-NEXT: Content: 0100000000000000000000000000000003000000000000001C040000 | |
| 52 | ; CHECK-NEXT: - SectionOffset: 41 | |
| 53 | ; CHECK-NEXT: MemoryIndex: 0 | |
| 54 | ; CHECK-NEXT: Offset: | |
| 55 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 56 | ; CHECK-NEXT: Value: 1052 | |
| 57 | ; CHECK-NEXT: Content: 68656C6C6F0A00 | |
| 58 | ||
| 59 | ; CHECK: - Type: CUSTOM | |
| 60 | ; CHECK-NEXT: Name: linking | |
| 61 | ; CHECK-NEXT: DataSize: 35 |
deps/lld/test/wasm/entry.ll created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %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 | ||
| 7 | define void @entry() local_unnamed_addr #0 { | |
| 8 | entry: | |
| 9 | ret void | |
| 10 | } | |
| 11 | ||
| 12 | ; CHECK: - Type: EXPORT | |
| 13 | ; CHECK: Exports: | |
| 14 | ; CHECK: - Name: memory | |
| 15 | ; CHECK: Kind: MEMORY | |
| 16 | ; CHECK: Index: 0 | |
| 17 | ; CHECK: - Name: entry | |
| 18 | ; CHECK: Kind: FUNCTION | |
| 19 | ; CHECK: Index: 0 |
deps/lld/test/wasm/function-imports-first.ll created+42| ... | ... | @@ -0,0 +1,42 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | |
| 3 | ; RUN: lld -flavor wasm -o %t.wasm %t.o %t.ret32.o | |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | |
| 5 | ||
| 6 | ; Function Attrs: nounwind | |
| 7 | define hidden void @_start() local_unnamed_addr #0 { | |
| 8 | entry: | |
| 9 | %call = tail call i32 @ret32(float 0.000000e+00) #2 | |
| 10 | ret void | |
| 11 | } | |
| 12 | ||
| 13 | declare i32 @ret32(float) local_unnamed_addr #1 | |
| 14 | ||
| 15 | ; CHECK: - Type: TYPE | |
| 16 | ; CHECK: Signatures: | |
| 17 | ; CHECK-NEXT: - Index: 0 | |
| 18 | ; CHECK-NEXT: ReturnType: NORESULT | |
| 19 | ; CHECK-NEXT: ParamTypes: | |
| 20 | ; CHECK-NEXT: - Index: 1 | |
| 21 | ; CHECK-NEXT: ReturnType: I32 | |
| 22 | ; CHECK-NEXT: ParamTypes: | |
| 23 | ; CHECK-NEXT: - F32 | |
| 24 | ; CHECK: - Type: FUNCTION | |
| 25 | ; CHECK-NEXT: FunctionTypes: [ 0, 1 ] | |
| 26 | ; CHECK: - Type: CODE | |
| 27 | ; CHECK-NEXT: Functions: | |
| 28 | ; CHECK-NEXT: - Locals: | |
| 29 | ; CHECK-NEXT: Body: 43000000001081808080001A0B | |
| 30 | ; CHECK-NEXT: - Locals: | |
| 31 | ; CHECK-NEXT: Body: 41000B | |
| 32 | ; CHECK-NEXT: - Type: CUSTOM | |
| 33 | ; CHECK-NEXT: Name: linking | |
| 34 | ; CHECK-NEXT: DataSize: 0 | |
| 35 | ; CHECK-NEXT: - Type: CUSTOM | |
| 36 | ; CHECK-NEXT: Name: name | |
| 37 | ; CHECK-NEXT: FunctionNames: | |
| 38 | ; CHECK-NEXT: - Index: 0 | |
| 39 | ; CHECK-NEXT: Name: _start | |
| 40 | ; CHECK-NEXT: - Index: 1 | |
| 41 | ; CHECK-NEXT: Name: ret32 | |
| 42 | ; CHECK-NEXT: ... |
deps/lld/test/wasm/function-imports.ll created+37| ... | ... | @@ -0,0 +1,37 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | |
| 3 | ; RUN: lld -flavor wasm -o %t.wasm %t.ret32.o %t.o | |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | |
| 5 | ||
| 6 | ; Function Attrs: nounwind | |
| 7 | define hidden void @_start() local_unnamed_addr #0 { | |
| 8 | entry: | |
| 9 | %call = tail call i32 @ret32(float 0.000000e+00) #2 | |
| 10 | ret void | |
| 11 | } | |
| 12 | ||
| 13 | declare i32 @ret32(float) local_unnamed_addr #1 | |
| 14 | ||
| 15 | ; CHECK: Sections: | |
| 16 | ; CHECK: - Type: TYPE | |
| 17 | ; CHECK-NEXT: Signatures: | |
| 18 | ; CHECK-NEXT: - Index: 0 | |
| 19 | ; CHECK-NEXT: ReturnType: I32 | |
| 20 | ; CHECK-NEXT: ParamTypes: | |
| 21 | ; CHECK-NEXT: - F32 | |
| 22 | ; CHECK-NEXT: - Index: 1 | |
| 23 | ; CHECK-NEXT: ReturnType: NORESULT | |
| 24 | ; CHECK-NEXT: ParamTypes: | |
| 25 | ; CHECK-NEXT: - Type: FUNCTION | |
| 26 | ; CHECK-NEXT: FunctionTypes: [ 0, 1 ] | |
| 27 | ; CHECK: - Type: CODE | |
| 28 | ; CHECK-NEXT: Functions: | |
| 29 | ; CHECK: - Locals: | |
| 30 | ; CHECK: - Locals: | |
| 31 | ; CHECK: Name: name | |
| 32 | ; CHECK-NEXT: FunctionNames: | |
| 33 | ; CHECK-NEXT: - Index: 0 | |
| 34 | ; CHECK-NEXT: Name: ret32 | |
| 35 | ; CHECK-NEXT: - Index: 1 | |
| 36 | ; CHECK-NEXT: Name: _start | |
| 37 | ; CHECK-NEXT: ... |
deps/lld/test/wasm/function-index.test created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | # RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %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 | |
| 3 | # RUN: lld -flavor wasm -r -o %t.wasm %t.ret32.o %t.ret64.o | |
| 4 | # RUN: obj2yaml %t.wasm | FileCheck %s | |
| 5 | ||
| 6 | CHECK: Sections: | |
| 7 | CHECK: - Type: TYPE | |
| 8 | CHECK: Signatures: | |
| 9 | CHECK: - Index: 0 | |
| 10 | CHECK: ReturnType: I32 | |
| 11 | CHECK: ParamTypes: | |
| 12 | CHECK: - F32 | |
| 13 | CHECK: - Index: 1 | |
| 14 | CHECK: ReturnType: I64 | |
| 15 | CHECK: ParamTypes: | |
| 16 | CHECK: - F64 | |
| 17 | CHECK: - Type: FUNCTION | |
| 18 | CHECK: FunctionTypes: [ 0, 1 ] |
deps/lld/test/wasm/import-memory.test created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | # RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | |
| 2 | # RUN: lld -flavor wasm -entry ret32 --import-memory -o %t.wasm %t.ret32.o | |
| 3 | # RUN: obj2yaml %t.wasm | FileCheck %s | |
| 4 | ||
| 5 | # Verify the --import-memory flag creates a memory import | |
| 6 | ||
| 7 | # CHECK: - Type: IMPORT | |
| 8 | # CHECK-NEXT: Imports: | |
| 9 | # CHECK-NEXT: - Module: env | |
| 10 | # CHECK-NEXT: Field: memory | |
| 11 | # CHECK-NEXT: Kind: MEMORY | |
| 12 | # CHECK-NEXT: Memory: | |
| 13 | # CHECK-NEXT: Initial: 0x00000002 |
deps/lld/test/wasm/init-fini.ll created+99| ... | ... | @@ -0,0 +1,99 @@ |
| 1 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -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 | |
| 3 | ||
| 4 | define hidden void @func1() { | |
| 5 | entry: | |
| 6 | ret void | |
| 7 | } | |
| 8 | ||
| 9 | define hidden void @func2() { | |
| 10 | entry: | |
| 11 | ret void | |
| 12 | } | |
| 13 | ||
| 14 | define void @__cxa_atexit() { | |
| 15 | ret void | |
| 16 | } | |
| 17 | ||
| 18 | define hidden void @_start() { | |
| 19 | entry: | |
| 20 | ret void | |
| 21 | } | |
| 22 | ||
| 23 | @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @func1, i8* null }] | |
| 24 | ||
| 25 | @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @func2, i8* null }] | |
| 26 | ||
| 27 | ; RUN: lld -flavor wasm %t.o %t.global-ctor-dtor.o -o %t.wasm | |
| 28 | ; RUN: obj2yaml %t.wasm | FileCheck %s | |
| 29 | ||
| 30 | ; CHECK: Name: linking | |
| 31 | ; CHECK-NEXT: DataSize: 0 | |
| 32 | ; CHECK-NEXT: - Type: CUSTOM | |
| 33 | ; CHECK-NEXT: Name: name | |
| 34 | ; CHECK-NEXT: FunctionNames: | |
| 35 | ; CHECK-NEXT: - Index: 0 | |
| 36 | ; CHECK-NEXT: Name: func1 | |
| 37 | ; CHECK-NEXT: - Index: 1 | |
| 38 | ; CHECK-NEXT: Name: func2 | |
| 39 | ; CHECK-NEXT: - Index: 2 | |
| 40 | ; CHECK-NEXT: Name: __cxa_atexit | |
| 41 | ; CHECK-NEXT: - Index: 3 | |
| 42 | ; CHECK-NEXT: Name: _start | |
| 43 | ; CHECK-NEXT: - Index: 4 | |
| 44 | ; CHECK-NEXT: Name: .Lcall_dtors | |
| 45 | ; CHECK-NEXT: - Index: 5 | |
| 46 | ; CHECK-NEXT: Name: .Lregister_call_dtors | |
| 47 | ; CHECK-NEXT: - Index: 6 | |
| 48 | ; CHECK-NEXT: Name: .Lbitcast | |
| 49 | ; CHECK-NEXT: - Index: 7 | |
| 50 | ; CHECK-NEXT: Name: myctor | |
| 51 | ; CHECK-NEXT: - Index: 8 | |
| 52 | ; CHECK-NEXT: Name: mydtor | |
| 53 | ; CHECK-NEXT: - Index: 9 | |
| 54 | ; CHECK-NEXT: Name: .Lcall_dtors | |
| 55 | ; CHECK-NEXT: - Index: 10 | |
| 56 | ; CHECK-NEXT: Name: .Lregister_call_dtors | |
| 57 | ; CHECK-NEXT: ... | |
| 58 | ||
| 59 | ||
| 60 | ; RUN: lld -flavor wasm -r %t.o %t.global-ctor-dtor.o -o %t.reloc.wasm | |
| 61 | ; RUN: obj2yaml %t.reloc.wasm | FileCheck -check-prefix=RELOC %s | |
| 62 | ||
| 63 | ; RELOC: Name: linking | |
| 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 | |
| 78 | ; RELOC-NEXT: Name: func1 | |
| 79 | ; RELOC-NEXT: - Index: 1 | |
| 80 | ; RELOC-NEXT: Name: func2 | |
| 81 | ; RELOC-NEXT: - Index: 2 | |
| 82 | ; RELOC-NEXT: Name: __cxa_atexit | |
| 83 | ; RELOC-NEXT: - Index: 3 | |
| 84 | ; RELOC-NEXT: Name: _start | |
| 85 | ; RELOC-NEXT: - Index: 4 | |
| 86 | ; RELOC-NEXT: Name: .Lcall_dtors | |
| 87 | ; RELOC-NEXT: - Index: 5 | |
| 88 | ; RELOC-NEXT: Name: .Lregister_call_dtors | |
| 89 | ; RELOC-NEXT: - Index: 6 | |
| 90 | ; RELOC-NEXT: Name: .Lbitcast | |
| 91 | ; RELOC-NEXT: - Index: 7 | |
| 92 | ; RELOC-NEXT: Name: myctor | |
| 93 | ; RELOC-NEXT: - Index: 8 | |
| 94 | ; RELOC-NEXT: Name: mydtor | |
| 95 | ; RELOC-NEXT: - Index: 9 | |
| 96 | ; RELOC-NEXT: Name: .Lcall_dtors | |
| 97 | ; RELOC-NEXT: - Index: 10 | |
| 98 | ; RELOC-NEXT: Name: .Lregister_call_dtors | |
| 99 | ; RELOC-NEXT: ... |
deps/lld/test/wasm/invalid-stack-size.test created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj %s -o %t.o | |
| 2 | ; RUN: not lld -flavor wasm -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 | ||
| 9 | ; CHECK: error: stack size must be 16-byte aligned |
deps/lld/test/wasm/lit.local.cfg created+4| ... | ... | @@ -0,0 +1,4 @@ |
| 1 | if 'wasm' not in config.available_features: | |
| 2 | config.unsupported = True | |
| 3 | ||
| 4 | config.suffixes = ['.test', '.yaml', '.ll'] |
deps/lld/test/wasm/load-undefined.ll created+38| ... | ... | @@ -0,0 +1,38 @@ |
| 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/local-symbols.ll created+78| ... | ... | @@ -0,0 +1,78 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | |
| 2 | ; RUN: lld -flavor wasm -o %t.wasm %t.o | |
| 3 | ; RUN: obj2yaml %t.wasm | FileCheck %s | |
| 4 | ||
| 5 | @foo = default global i32 1, align 4 | |
| 6 | @bar = internal default global i32 3, align 4 | |
| 7 | ||
| 8 | define internal i32 @baz() local_unnamed_addr { | |
| 9 | entry: | |
| 10 | ret i32 2 | |
| 11 | } | |
| 12 | ||
| 13 | define i32 @_start() local_unnamed_addr { | |
| 14 | entry: | |
| 15 | ret i32 1 | |
| 16 | } | |
| 17 | ||
| 18 | ; CHECK: --- !WASM | |
| 19 | ; CHECK-NEXT: FileHeader: | |
| 20 | ; CHECK-NEXT: Version: 0x00000001 | |
| 21 | ; CHECK-NEXT: Sections: | |
| 22 | ; CHECK-NEXT: - Type: TYPE | |
| 23 | ; CHECK-NEXT: Signatures: | |
| 24 | ; CHECK-NEXT: - Index: 0 | |
| 25 | ; CHECK-NEXT: ReturnType: I32 | |
| 26 | ; CHECK-NEXT: ParamTypes: | |
| 27 | ; CHECK-NEXT: - Type: FUNCTION | |
| 28 | ; CHECK-NEXT: FunctionTypes: [ 0, 0 ] | |
| 29 | ; CHECK-NEXT: - Type: TABLE | |
| 30 | ; CHECK-NEXT: Tables: | |
| 31 | ; CHECK-NEXT: - ElemType: ANYFUNC | |
| 32 | ; CHECK-NEXT: Limits: | |
| 33 | ; CHECK-NEXT: Flags: [ HAS_MAX ] | |
| 34 | ; CHECK-NEXT: Initial: 0x00000001 | |
| 35 | ; CHECK-NEXT: Maximum: 0x00000001 | |
| 36 | ; CHECK-NEXT: - Type: MEMORY | |
| 37 | ; CHECK-NEXT: Memories: | |
| 38 | ; CHECK-NEXT: - Initial: 0x00000002 | |
| 39 | ; CHECK-NEXT: - Type: GLOBAL | |
| 40 | ; CHECK-NEXT: Globals: | |
| 41 | ; CHECK-NEXT: - Type: I32 | |
| 42 | ; CHECK-NEXT: Mutable: true | |
| 43 | ; CHECK-NEXT: InitExpr: | |
| 44 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 45 | ; CHECK-NEXT: Value: 66576 | |
| 46 | ; CHECK-NEXT: - Type: EXPORT | |
| 47 | ; CHECK-NEXT: Exports: | |
| 48 | ; CHECK-NEXT: - Name: memory | |
| 49 | ; CHECK-NEXT: Kind: MEMORY | |
| 50 | ; CHECK-NEXT: Index: 0 | |
| 51 | ; CHECK-NEXT: - Name: _start | |
| 52 | ; CHECK-NEXT: Kind: FUNCTION | |
| 53 | ; CHECK-NEXT: Index: 1 | |
| 54 | ; CHECK-NEXT: - Type: CODE | |
| 55 | ; CHECK-NEXT: Functions: | |
| 56 | ; CHECK-NEXT: - Locals: | |
| 57 | ; CHECK-NEXT: Body: 41020B | |
| 58 | ; CHECK-NEXT: - Locals: | |
| 59 | ; CHECK-NEXT: Body: 41010B | |
| 60 | ; CHECK-NEXT: - Type: DATA | |
| 61 | ; CHECK-NEXT: Segments: | |
| 62 | ; CHECK-NEXT: - SectionOffset: 7 | |
| 63 | ; CHECK-NEXT: MemoryIndex: 0 | |
| 64 | ; CHECK-NEXT: Offset: | |
| 65 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 66 | ; CHECK-NEXT: Value: 1024 | |
| 67 | ; CHECK-NEXT: Content: '0100000003000000' | |
| 68 | ; CHECK-NEXT: - Type: CUSTOM | |
| 69 | ; CHECK-NEXT: Name: linking | |
| 70 | ; CHECK-NEXT: DataSize: 8 | |
| 71 | ; CHECK-NEXT: - Type: CUSTOM | |
| 72 | ; CHECK-NEXT: Name: name | |
| 73 | ; CHECK-NEXT: FunctionNames: | |
| 74 | ; CHECK-NEXT: - Index: 0 | |
| 75 | ; CHECK-NEXT: Name: baz | |
| 76 | ; CHECK-NEXT: - Index: 1 | |
| 77 | ; CHECK-NEXT: Name: _start | |
| 78 | ; CHECK-NEXT: ... |
deps/lld/test/wasm/many-functions.ll created+695| ... | ... | @@ -0,0 +1,695 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/many-funcs.ll -o %t.many.o | |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | |
| 3 | ; RUN: lld -flavor wasm -r -o %t.wasm %t.many.o %t.o | |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | |
| 5 | ||
| 6 | ; Test that relocations within the CODE section correctly handle | |
| 7 | ; linking object with different header sizes. many-funcs.ll has | |
| 8 | ; 128 function and so the final output requires a 2-byte LEB in | |
| 9 | ; the CODE section header to store the function count. | |
| 10 | ||
| 11 | define i32 @func() { | |
| 12 | entry: | |
| 13 | %call = tail call i32 @func() | |
| 14 | ret i32 %call | |
| 15 | } | |
| 16 | ||
| 17 | ; CHECK: - Type: CODE | |
| 18 | ; CHECK-NEXT: Relocations: | |
| 19 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 20 | ; CHECK-NEXT: Index: 0 | |
| 21 | ; CHECK-NEXT: Offset: 0x00000008 | |
| 22 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 23 | ; CHECK-NEXT: Index: 0 | |
| 24 | ; CHECK-NEXT: Offset: 0x00000014 | |
| 25 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 26 | ; CHECK-NEXT: Index: 0 | |
| 27 | ; CHECK-NEXT: Offset: 0x00000020 | |
| 28 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 29 | ; CHECK-NEXT: Index: 0 | |
| 30 | ; CHECK-NEXT: Offset: 0x0000002C | |
| 31 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 32 | ; CHECK-NEXT: Index: 0 | |
| 33 | ; CHECK-NEXT: Offset: 0x00000038 | |
| 34 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 35 | ; CHECK-NEXT: Index: 0 | |
| 36 | ; CHECK-NEXT: Offset: 0x00000044 | |
| 37 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 38 | ; CHECK-NEXT: Index: 0 | |
| 39 | ; CHECK-NEXT: Offset: 0x00000050 | |
| 40 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 41 | ; CHECK-NEXT: Index: 0 | |
| 42 | ; CHECK-NEXT: Offset: 0x0000005C | |
| 43 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 44 | ; CHECK-NEXT: Index: 0 | |
| 45 | ; CHECK-NEXT: Offset: 0x00000068 | |
| 46 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 47 | ; CHECK-NEXT: Index: 0 | |
| 48 | ; CHECK-NEXT: Offset: 0x00000074 | |
| 49 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 50 | ; CHECK-NEXT: Index: 0 | |
| 51 | ; CHECK-NEXT: Offset: 0x00000080 | |
| 52 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 53 | ; CHECK-NEXT: Index: 0 | |
| 54 | ; CHECK-NEXT: Offset: 0x0000008C | |
| 55 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 56 | ; CHECK-NEXT: Index: 0 | |
| 57 | ; CHECK-NEXT: Offset: 0x00000098 | |
| 58 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 59 | ; CHECK-NEXT: Index: 0 | |
| 60 | ; CHECK-NEXT: Offset: 0x000000A4 | |
| 61 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 62 | ; CHECK-NEXT: Index: 0 | |
| 63 | ; CHECK-NEXT: Offset: 0x000000B0 | |
| 64 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 65 | ; CHECK-NEXT: Index: 0 | |
| 66 | ; CHECK-NEXT: Offset: 0x000000BC | |
| 67 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 68 | ; CHECK-NEXT: Index: 0 | |
| 69 | ; CHECK-NEXT: Offset: 0x000000C8 | |
| 70 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 71 | ; CHECK-NEXT: Index: 0 | |
| 72 | ; CHECK-NEXT: Offset: 0x000000D4 | |
| 73 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 74 | ; CHECK-NEXT: Index: 0 | |
| 75 | ; CHECK-NEXT: Offset: 0x000000E0 | |
| 76 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 77 | ; CHECK-NEXT: Index: 0 | |
| 78 | ; CHECK-NEXT: Offset: 0x000000EC | |
| 79 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 80 | ; CHECK-NEXT: Index: 0 | |
| 81 | ; CHECK-NEXT: Offset: 0x000000F8 | |
| 82 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 83 | ; CHECK-NEXT: Index: 0 | |
| 84 | ; CHECK-NEXT: Offset: 0x00000104 | |
| 85 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 86 | ; CHECK-NEXT: Index: 0 | |
| 87 | ; CHECK-NEXT: Offset: 0x00000110 | |
| 88 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 89 | ; CHECK-NEXT: Index: 0 | |
| 90 | ; CHECK-NEXT: Offset: 0x0000011C | |
| 91 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 92 | ; CHECK-NEXT: Index: 0 | |
| 93 | ; CHECK-NEXT: Offset: 0x00000128 | |
| 94 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 95 | ; CHECK-NEXT: Index: 0 | |
| 96 | ; CHECK-NEXT: Offset: 0x00000134 | |
| 97 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 98 | ; CHECK-NEXT: Index: 0 | |
| 99 | ; CHECK-NEXT: Offset: 0x00000140 | |
| 100 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 101 | ; CHECK-NEXT: Index: 0 | |
| 102 | ; CHECK-NEXT: Offset: 0x0000014C | |
| 103 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 104 | ; CHECK-NEXT: Index: 0 | |
| 105 | ; CHECK-NEXT: Offset: 0x00000158 | |
| 106 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 107 | ; CHECK-NEXT: Index: 0 | |
| 108 | ; CHECK-NEXT: Offset: 0x00000164 | |
| 109 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 110 | ; CHECK-NEXT: Index: 0 | |
| 111 | ; CHECK-NEXT: Offset: 0x00000170 | |
| 112 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 113 | ; CHECK-NEXT: Index: 0 | |
| 114 | ; CHECK-NEXT: Offset: 0x0000017C | |
| 115 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 116 | ; CHECK-NEXT: Index: 0 | |
| 117 | ; CHECK-NEXT: Offset: 0x00000188 | |
| 118 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 119 | ; CHECK-NEXT: Index: 0 | |
| 120 | ; CHECK-NEXT: Offset: 0x00000194 | |
| 121 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 122 | ; CHECK-NEXT: Index: 0 | |
| 123 | ; CHECK-NEXT: Offset: 0x000001A0 | |
| 124 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 125 | ; CHECK-NEXT: Index: 0 | |
| 126 | ; CHECK-NEXT: Offset: 0x000001AC | |
| 127 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 128 | ; CHECK-NEXT: Index: 0 | |
| 129 | ; CHECK-NEXT: Offset: 0x000001B8 | |
| 130 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 131 | ; CHECK-NEXT: Index: 0 | |
| 132 | ; CHECK-NEXT: Offset: 0x000001C4 | |
| 133 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 134 | ; CHECK-NEXT: Index: 0 | |
| 135 | ; CHECK-NEXT: Offset: 0x000001D0 | |
| 136 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 137 | ; CHECK-NEXT: Index: 0 | |
| 138 | ; CHECK-NEXT: Offset: 0x000001DC | |
| 139 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 140 | ; CHECK-NEXT: Index: 0 | |
| 141 | ; CHECK-NEXT: Offset: 0x000001E8 | |
| 142 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 143 | ; CHECK-NEXT: Index: 0 | |
| 144 | ; CHECK-NEXT: Offset: 0x000001F4 | |
| 145 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 146 | ; CHECK-NEXT: Index: 0 | |
| 147 | ; CHECK-NEXT: Offset: 0x00000200 | |
| 148 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 149 | ; CHECK-NEXT: Index: 0 | |
| 150 | ; CHECK-NEXT: Offset: 0x0000020C | |
| 151 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 152 | ; CHECK-NEXT: Index: 0 | |
| 153 | ; CHECK-NEXT: Offset: 0x00000218 | |
| 154 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 155 | ; CHECK-NEXT: Index: 0 | |
| 156 | ; CHECK-NEXT: Offset: 0x00000224 | |
| 157 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 158 | ; CHECK-NEXT: Index: 0 | |
| 159 | ; CHECK-NEXT: Offset: 0x00000230 | |
| 160 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 161 | ; CHECK-NEXT: Index: 0 | |
| 162 | ; CHECK-NEXT: Offset: 0x0000023C | |
| 163 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 164 | ; CHECK-NEXT: Index: 0 | |
| 165 | ; CHECK-NEXT: Offset: 0x00000248 | |
| 166 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 167 | ; CHECK-NEXT: Index: 0 | |
| 168 | ; CHECK-NEXT: Offset: 0x00000254 | |
| 169 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 170 | ; CHECK-NEXT: Index: 0 | |
| 171 | ; CHECK-NEXT: Offset: 0x00000260 | |
| 172 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 173 | ; CHECK-NEXT: Index: 0 | |
| 174 | ; CHECK-NEXT: Offset: 0x0000026C | |
| 175 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 176 | ; CHECK-NEXT: Index: 0 | |
| 177 | ; CHECK-NEXT: Offset: 0x00000278 | |
| 178 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 179 | ; CHECK-NEXT: Index: 0 | |
| 180 | ; CHECK-NEXT: Offset: 0x00000284 | |
| 181 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 182 | ; CHECK-NEXT: Index: 0 | |
| 183 | ; CHECK-NEXT: Offset: 0x00000290 | |
| 184 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 185 | ; CHECK-NEXT: Index: 0 | |
| 186 | ; CHECK-NEXT: Offset: 0x0000029C | |
| 187 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 188 | ; CHECK-NEXT: Index: 0 | |
| 189 | ; CHECK-NEXT: Offset: 0x000002A8 | |
| 190 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 191 | ; CHECK-NEXT: Index: 0 | |
| 192 | ; CHECK-NEXT: Offset: 0x000002B4 | |
| 193 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 194 | ; CHECK-NEXT: Index: 0 | |
| 195 | ; CHECK-NEXT: Offset: 0x000002C0 | |
| 196 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 197 | ; CHECK-NEXT: Index: 0 | |
| 198 | ; CHECK-NEXT: Offset: 0x000002CC | |
| 199 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 200 | ; CHECK-NEXT: Index: 0 | |
| 201 | ; CHECK-NEXT: Offset: 0x000002D8 | |
| 202 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 203 | ; CHECK-NEXT: Index: 0 | |
| 204 | ; CHECK-NEXT: Offset: 0x000002E4 | |
| 205 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 206 | ; CHECK-NEXT: Index: 0 | |
| 207 | ; CHECK-NEXT: Offset: 0x000002F0 | |
| 208 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 209 | ; CHECK-NEXT: Index: 0 | |
| 210 | ; CHECK-NEXT: Offset: 0x000002FC | |
| 211 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 212 | ; CHECK-NEXT: Index: 0 | |
| 213 | ; CHECK-NEXT: Offset: 0x00000308 | |
| 214 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 215 | ; CHECK-NEXT: Index: 0 | |
| 216 | ; CHECK-NEXT: Offset: 0x00000314 | |
| 217 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 218 | ; CHECK-NEXT: Index: 0 | |
| 219 | ; CHECK-NEXT: Offset: 0x00000320 | |
| 220 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 221 | ; CHECK-NEXT: Index: 0 | |
| 222 | ; CHECK-NEXT: Offset: 0x0000032C | |
| 223 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 224 | ; CHECK-NEXT: Index: 0 | |
| 225 | ; CHECK-NEXT: Offset: 0x00000338 | |
| 226 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 227 | ; CHECK-NEXT: Index: 0 | |
| 228 | ; CHECK-NEXT: Offset: 0x00000344 | |
| 229 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 230 | ; CHECK-NEXT: Index: 0 | |
| 231 | ; CHECK-NEXT: Offset: 0x00000350 | |
| 232 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 233 | ; CHECK-NEXT: Index: 0 | |
| 234 | ; CHECK-NEXT: Offset: 0x0000035C | |
| 235 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 236 | ; CHECK-NEXT: Index: 0 | |
| 237 | ; CHECK-NEXT: Offset: 0x00000368 | |
| 238 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 239 | ; CHECK-NEXT: Index: 0 | |
| 240 | ; CHECK-NEXT: Offset: 0x00000374 | |
| 241 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 242 | ; CHECK-NEXT: Index: 0 | |
| 243 | ; CHECK-NEXT: Offset: 0x00000380 | |
| 244 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 245 | ; CHECK-NEXT: Index: 0 | |
| 246 | ; CHECK-NEXT: Offset: 0x0000038C | |
| 247 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 248 | ; CHECK-NEXT: Index: 0 | |
| 249 | ; CHECK-NEXT: Offset: 0x00000398 | |
| 250 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 251 | ; CHECK-NEXT: Index: 0 | |
| 252 | ; CHECK-NEXT: Offset: 0x000003A4 | |
| 253 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 254 | ; CHECK-NEXT: Index: 0 | |
| 255 | ; CHECK-NEXT: Offset: 0x000003B0 | |
| 256 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 257 | ; CHECK-NEXT: Index: 0 | |
| 258 | ; CHECK-NEXT: Offset: 0x000003BC | |
| 259 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 260 | ; CHECK-NEXT: Index: 0 | |
| 261 | ; CHECK-NEXT: Offset: 0x000003C8 | |
| 262 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 263 | ; CHECK-NEXT: Index: 0 | |
| 264 | ; CHECK-NEXT: Offset: 0x000003D4 | |
| 265 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 266 | ; CHECK-NEXT: Index: 0 | |
| 267 | ; CHECK-NEXT: Offset: 0x000003E0 | |
| 268 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 269 | ; CHECK-NEXT: Index: 0 | |
| 270 | ; CHECK-NEXT: Offset: 0x000003EC | |
| 271 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 272 | ; CHECK-NEXT: Index: 0 | |
| 273 | ; CHECK-NEXT: Offset: 0x000003F8 | |
| 274 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 275 | ; CHECK-NEXT: Index: 0 | |
| 276 | ; CHECK-NEXT: Offset: 0x00000404 | |
| 277 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 278 | ; CHECK-NEXT: Index: 0 | |
| 279 | ; CHECK-NEXT: Offset: 0x00000410 | |
| 280 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 281 | ; CHECK-NEXT: Index: 0 | |
| 282 | ; CHECK-NEXT: Offset: 0x0000041C | |
| 283 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 284 | ; CHECK-NEXT: Index: 0 | |
| 285 | ; CHECK-NEXT: Offset: 0x00000428 | |
| 286 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 287 | ; CHECK-NEXT: Index: 0 | |
| 288 | ; CHECK-NEXT: Offset: 0x00000434 | |
| 289 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 290 | ; CHECK-NEXT: Index: 0 | |
| 291 | ; CHECK-NEXT: Offset: 0x00000440 | |
| 292 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 293 | ; CHECK-NEXT: Index: 0 | |
| 294 | ; CHECK-NEXT: Offset: 0x0000044C | |
| 295 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 296 | ; CHECK-NEXT: Index: 0 | |
| 297 | ; CHECK-NEXT: Offset: 0x00000458 | |
| 298 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 299 | ; CHECK-NEXT: Index: 0 | |
| 300 | ; CHECK-NEXT: Offset: 0x00000464 | |
| 301 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 302 | ; CHECK-NEXT: Index: 0 | |
| 303 | ; CHECK-NEXT: Offset: 0x00000470 | |
| 304 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 305 | ; CHECK-NEXT: Index: 0 | |
| 306 | ; CHECK-NEXT: Offset: 0x0000047C | |
| 307 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 308 | ; CHECK-NEXT: Index: 0 | |
| 309 | ; CHECK-NEXT: Offset: 0x00000488 | |
| 310 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 311 | ; CHECK-NEXT: Index: 0 | |
| 312 | ; CHECK-NEXT: Offset: 0x00000494 | |
| 313 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 314 | ; CHECK-NEXT: Index: 0 | |
| 315 | ; CHECK-NEXT: Offset: 0x000004A0 | |
| 316 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 317 | ; CHECK-NEXT: Index: 0 | |
| 318 | ; CHECK-NEXT: Offset: 0x000004AC | |
| 319 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 320 | ; CHECK-NEXT: Index: 0 | |
| 321 | ; CHECK-NEXT: Offset: 0x000004B8 | |
| 322 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 323 | ; CHECK-NEXT: Index: 0 | |
| 324 | ; CHECK-NEXT: Offset: 0x000004C4 | |
| 325 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 326 | ; CHECK-NEXT: Index: 0 | |
| 327 | ; CHECK-NEXT: Offset: 0x000004D0 | |
| 328 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 329 | ; CHECK-NEXT: Index: 0 | |
| 330 | ; CHECK-NEXT: Offset: 0x000004DC | |
| 331 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 332 | ; CHECK-NEXT: Index: 0 | |
| 333 | ; CHECK-NEXT: Offset: 0x000004E8 | |
| 334 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 335 | ; CHECK-NEXT: Index: 0 | |
| 336 | ; CHECK-NEXT: Offset: 0x000004F4 | |
| 337 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 338 | ; CHECK-NEXT: Index: 0 | |
| 339 | ; CHECK-NEXT: Offset: 0x00000500 | |
| 340 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 341 | ; CHECK-NEXT: Index: 0 | |
| 342 | ; CHECK-NEXT: Offset: 0x0000050C | |
| 343 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 344 | ; CHECK-NEXT: Index: 0 | |
| 345 | ; CHECK-NEXT: Offset: 0x00000518 | |
| 346 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 347 | ; CHECK-NEXT: Index: 0 | |
| 348 | ; CHECK-NEXT: Offset: 0x00000524 | |
| 349 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 350 | ; CHECK-NEXT: Index: 0 | |
| 351 | ; CHECK-NEXT: Offset: 0x00000530 | |
| 352 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 353 | ; CHECK-NEXT: Index: 0 | |
| 354 | ; CHECK-NEXT: Offset: 0x0000053C | |
| 355 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 356 | ; CHECK-NEXT: Index: 0 | |
| 357 | ; CHECK-NEXT: Offset: 0x00000548 | |
| 358 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 359 | ; CHECK-NEXT: Index: 0 | |
| 360 | ; CHECK-NEXT: Offset: 0x00000554 | |
| 361 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 362 | ; CHECK-NEXT: Index: 0 | |
| 363 | ; CHECK-NEXT: Offset: 0x00000560 | |
| 364 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 365 | ; CHECK-NEXT: Index: 0 | |
| 366 | ; CHECK-NEXT: Offset: 0x0000056C | |
| 367 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 368 | ; CHECK-NEXT: Index: 0 | |
| 369 | ; CHECK-NEXT: Offset: 0x00000578 | |
| 370 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 371 | ; CHECK-NEXT: Index: 0 | |
| 372 | ; CHECK-NEXT: Offset: 0x00000584 | |
| 373 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 374 | ; CHECK-NEXT: Index: 0 | |
| 375 | ; CHECK-NEXT: Offset: 0x00000590 | |
| 376 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 377 | ; CHECK-NEXT: Index: 0 | |
| 378 | ; CHECK-NEXT: Offset: 0x0000059C | |
| 379 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 380 | ; CHECK-NEXT: Index: 0 | |
| 381 | ; CHECK-NEXT: Offset: 0x000005A8 | |
| 382 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 383 | ; CHECK-NEXT: Index: 0 | |
| 384 | ; CHECK-NEXT: Offset: 0x000005B4 | |
| 385 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 386 | ; CHECK-NEXT: Index: 0 | |
| 387 | ; CHECK-NEXT: Offset: 0x000005C0 | |
| 388 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 389 | ; CHECK-NEXT: Index: 0 | |
| 390 | ; CHECK-NEXT: Offset: 0x000005CC | |
| 391 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 392 | ; CHECK-NEXT: Index: 0 | |
| 393 | ; CHECK-NEXT: Offset: 0x000005D8 | |
| 394 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 395 | ; CHECK-NEXT: Index: 0 | |
| 396 | ; CHECK-NEXT: Offset: 0x000005E4 | |
| 397 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 398 | ; CHECK-NEXT: Index: 0 | |
| 399 | ; CHECK-NEXT: Offset: 0x000005F0 | |
| 400 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 401 | ; CHECK-NEXT: Index: 1 | |
| 402 | ; CHECK-NEXT: Offset: 0x000005FC | |
| 403 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | |
| 404 | ; CHECK-NEXT: Index: 1 | |
| 405 | ; CHECK-NEXT: Offset: 0x00000608 | |
| 406 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB | |
| 407 | ; CHECK-NEXT: Index: 129 | |
| 408 | ; CHECK-NEXT: Offset: 0x00000611 | |
| 409 | ; CHECK-NEXT: Functions: | |
| 410 | ; CHECK-NEXT: - Locals: | |
| 411 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 412 | ; CHECK-NEXT: - Locals: | |
| 413 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 414 | ; CHECK-NEXT: - Locals: | |
| 415 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 416 | ; CHECK-NEXT: - Locals: | |
| 417 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 418 | ; CHECK-NEXT: - Locals: | |
| 419 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 420 | ; CHECK-NEXT: - Locals: | |
| 421 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 422 | ; CHECK-NEXT: - Locals: | |
| 423 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 424 | ; CHECK-NEXT: - Locals: | |
| 425 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 426 | ; CHECK-NEXT: - Locals: | |
| 427 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 428 | ; CHECK-NEXT: - Locals: | |
| 429 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 430 | ; CHECK-NEXT: - Locals: | |
| 431 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 432 | ; CHECK-NEXT: - Locals: | |
| 433 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 434 | ; CHECK-NEXT: - Locals: | |
| 435 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 436 | ; CHECK-NEXT: - Locals: | |
| 437 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 438 | ; CHECK-NEXT: - Locals: | |
| 439 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 440 | ; CHECK-NEXT: - Locals: | |
| 441 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 442 | ; CHECK-NEXT: - Locals: | |
| 443 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 444 | ; CHECK-NEXT: - Locals: | |
| 445 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 446 | ; CHECK-NEXT: - Locals: | |
| 447 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 448 | ; CHECK-NEXT: - Locals: | |
| 449 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 450 | ; CHECK-NEXT: - Locals: | |
| 451 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 452 | ; CHECK-NEXT: - Locals: | |
| 453 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 454 | ; CHECK-NEXT: - Locals: | |
| 455 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 456 | ; CHECK-NEXT: - Locals: | |
| 457 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 458 | ; CHECK-NEXT: - Locals: | |
| 459 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 460 | ; CHECK-NEXT: - Locals: | |
| 461 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 462 | ; CHECK-NEXT: - Locals: | |
| 463 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 464 | ; CHECK-NEXT: - Locals: | |
| 465 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 466 | ; CHECK-NEXT: - Locals: | |
| 467 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 468 | ; CHECK-NEXT: - Locals: | |
| 469 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 470 | ; CHECK-NEXT: - Locals: | |
| 471 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 472 | ; CHECK-NEXT: - Locals: | |
| 473 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 474 | ; CHECK-NEXT: - Locals: | |
| 475 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 476 | ; CHECK-NEXT: - Locals: | |
| 477 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 478 | ; CHECK-NEXT: - Locals: | |
| 479 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 480 | ; CHECK-NEXT: - Locals: | |
| 481 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 482 | ; CHECK-NEXT: - Locals: | |
| 483 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 484 | ; CHECK-NEXT: - Locals: | |
| 485 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 486 | ; CHECK-NEXT: - Locals: | |
| 487 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 488 | ; CHECK-NEXT: - Locals: | |
| 489 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 490 | ; CHECK-NEXT: - Locals: | |
| 491 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 492 | ; CHECK-NEXT: - Locals: | |
| 493 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 494 | ; CHECK-NEXT: - Locals: | |
| 495 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 496 | ; CHECK-NEXT: - Locals: | |
| 497 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 498 | ; CHECK-NEXT: - Locals: | |
| 499 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 500 | ; CHECK-NEXT: - Locals: | |
| 501 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 502 | ; CHECK-NEXT: - Locals: | |
| 503 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 504 | ; CHECK-NEXT: - Locals: | |
| 505 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 506 | ; CHECK-NEXT: - Locals: | |
| 507 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 508 | ; CHECK-NEXT: - Locals: | |
| 509 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 510 | ; CHECK-NEXT: - Locals: | |
| 511 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 512 | ; CHECK-NEXT: - Locals: | |
| 513 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 514 | ; CHECK-NEXT: - Locals: | |
| 515 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 516 | ; CHECK-NEXT: - Locals: | |
| 517 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 518 | ; CHECK-NEXT: - Locals: | |
| 519 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 520 | ; CHECK-NEXT: - Locals: | |
| 521 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 522 | ; CHECK-NEXT: - Locals: | |
| 523 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 524 | ; CHECK-NEXT: - Locals: | |
| 525 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 526 | ; CHECK-NEXT: - Locals: | |
| 527 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 528 | ; CHECK-NEXT: - Locals: | |
| 529 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 530 | ; CHECK-NEXT: - Locals: | |
| 531 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 532 | ; CHECK-NEXT: - Locals: | |
| 533 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 534 | ; CHECK-NEXT: - Locals: | |
| 535 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 536 | ; CHECK-NEXT: - Locals: | |
| 537 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 538 | ; CHECK-NEXT: - Locals: | |
| 539 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 540 | ; CHECK-NEXT: - Locals: | |
| 541 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 542 | ; CHECK-NEXT: - Locals: | |
| 543 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 544 | ; CHECK-NEXT: - Locals: | |
| 545 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 546 | ; CHECK-NEXT: - Locals: | |
| 547 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 548 | ; CHECK-NEXT: - Locals: | |
| 549 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 550 | ; CHECK-NEXT: - Locals: | |
| 551 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 552 | ; CHECK-NEXT: - Locals: | |
| 553 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 554 | ; CHECK-NEXT: - Locals: | |
| 555 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 556 | ; CHECK-NEXT: - Locals: | |
| 557 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 558 | ; CHECK-NEXT: - Locals: | |
| 559 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 560 | ; CHECK-NEXT: - Locals: | |
| 561 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 562 | ; CHECK-NEXT: - Locals: | |
| 563 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 564 | ; CHECK-NEXT: - Locals: | |
| 565 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 566 | ; CHECK-NEXT: - Locals: | |
| 567 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 568 | ; CHECK-NEXT: - Locals: | |
| 569 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 570 | ; CHECK-NEXT: - Locals: | |
| 571 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 572 | ; CHECK-NEXT: - Locals: | |
| 573 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 574 | ; CHECK-NEXT: - Locals: | |
| 575 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 576 | ; CHECK-NEXT: - Locals: | |
| 577 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 578 | ; CHECK-NEXT: - Locals: | |
| 579 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 580 | ; CHECK-NEXT: - Locals: | |
| 581 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 582 | ; CHECK-NEXT: - Locals: | |
| 583 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 584 | ; CHECK-NEXT: - Locals: | |
| 585 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 586 | ; CHECK-NEXT: - Locals: | |
| 587 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 588 | ; CHECK-NEXT: - Locals: | |
| 589 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 590 | ; CHECK-NEXT: - Locals: | |
| 591 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 592 | ; CHECK-NEXT: - Locals: | |
| 593 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 594 | ; CHECK-NEXT: - Locals: | |
| 595 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 596 | ; CHECK-NEXT: - Locals: | |
| 597 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 598 | ; CHECK-NEXT: - Locals: | |
| 599 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 600 | ; CHECK-NEXT: - Locals: | |
| 601 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 602 | ; CHECK-NEXT: - Locals: | |
| 603 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 604 | ; CHECK-NEXT: - Locals: | |
| 605 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 606 | ; CHECK-NEXT: - Locals: | |
| 607 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 608 | ; CHECK-NEXT: - Locals: | |
| 609 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 610 | ; CHECK-NEXT: - Locals: | |
| 611 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 612 | ; CHECK-NEXT: - Locals: | |
| 613 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 614 | ; CHECK-NEXT: - Locals: | |
| 615 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 616 | ; CHECK-NEXT: - Locals: | |
| 617 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 618 | ; CHECK-NEXT: - Locals: | |
| 619 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 620 | ; CHECK-NEXT: - Locals: | |
| 621 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 622 | ; CHECK-NEXT: - Locals: | |
| 623 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 624 | ; CHECK-NEXT: - Locals: | |
| 625 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 626 | ; CHECK-NEXT: - Locals: | |
| 627 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 628 | ; CHECK-NEXT: - Locals: | |
| 629 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 630 | ; CHECK-NEXT: - Locals: | |
| 631 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 632 | ; CHECK-NEXT: - Locals: | |
| 633 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 634 | ; CHECK-NEXT: - Locals: | |
| 635 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 636 | ; CHECK-NEXT: - Locals: | |
| 637 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 638 | ; CHECK-NEXT: - Locals: | |
| 639 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 640 | ; CHECK-NEXT: - Locals: | |
| 641 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 642 | ; CHECK-NEXT: - Locals: | |
| 643 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 644 | ; CHECK-NEXT: - Locals: | |
| 645 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 646 | ; CHECK-NEXT: - Locals: | |
| 647 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 648 | ; CHECK-NEXT: - Locals: | |
| 649 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 650 | ; CHECK-NEXT: - Locals: | |
| 651 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 652 | ; CHECK-NEXT: - Locals: | |
| 653 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 654 | ; CHECK-NEXT: - Locals: | |
| 655 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 656 | ; CHECK-NEXT: - Locals: | |
| 657 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 658 | ; CHECK-NEXT: - Locals: | |
| 659 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 660 | ; CHECK-NEXT: - Locals: | |
| 661 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 662 | ; CHECK-NEXT: - Locals: | |
| 663 | ; CHECK-NEXT: Body: 4100280284808080000B | |
| 664 | ; CHECK-NEXT: - Locals: | |
| 665 | ; CHECK-NEXT: Body: 4100280280808080000B | |
| 666 | ; CHECK-NEXT: - Locals: | |
| 667 | ; CHECK-NEXT: Body: 4100280280808080000B | |
| 668 | ; CHECK-NEXT: - Locals: | |
| 669 | ; CHECK-NEXT: Body: 1081818080000B | |
| 670 | ; CHECK-NEXT: - Type: DATA | |
| 671 | ; CHECK-NEXT: Segments: | |
| 672 | ; CHECK-NEXT: - SectionOffset: 6 | |
| 673 | ; CHECK-NEXT: MemoryIndex: 0 | |
| 674 | ; CHECK-NEXT: Offset: | |
| 675 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 676 | ; CHECK-NEXT: Value: 0 | |
| 677 | ; CHECK-NEXT: Content: '01000000' | |
| 678 | ; CHECK-NEXT: - SectionOffset: 15 | |
| 679 | ; CHECK-NEXT: MemoryIndex: 0 | |
| 680 | ; CHECK-NEXT: Offset: | |
| 681 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 682 | ; CHECK-NEXT: Value: 4 | |
| 683 | ; CHECK-NEXT: Content: '01000000' | |
| 684 | ; CHECK-NEXT: - Type: CUSTOM | |
| 685 | ; CHECK-NEXT: Name: linking | |
| 686 | ; CHECK-NEXT: DataSize: 8 | |
| 687 | ; CHECK-NEXT: SegmentInfo: | |
| 688 | ; CHECK-NEXT: - Index: 0 | |
| 689 | ; CHECK-NEXT: Name: .data.g0 | |
| 690 | ; CHECK-NEXT: Alignment: 4 | |
| 691 | ; CHECK-NEXT: Flags: [ ] | |
| 692 | ; CHECK-NEXT: - Index: 1 | |
| 693 | ; CHECK-NEXT: Name: .data.foo | |
| 694 | ; CHECK-NEXT: Alignment: 4 | |
| 695 | ; CHECK-NEXT: Flags: [ ] |
deps/lld/test/wasm/relocatable.ll created+194| ... | ... | @@ -0,0 +1,194 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/hello.ll -o %t.hello.o | |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | |
| 3 | ; RUN: lld -flavor wasm -r -o %t.wasm %t.hello.o %t.o | |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | |
| 5 | ||
| 6 | ; Function Attrs: nounwind | |
| 7 | define hidden i32 @my_func() local_unnamed_addr { | |
| 8 | entry: | |
| 9 | %call = tail call i32 @foo_import() | |
| 10 | ret i32 1 | |
| 11 | } | |
| 12 | ||
| 13 | declare i32 @foo_import() local_unnamed_addr | |
| 14 | @data_import = external global i64 | |
| 15 | ||
| 16 | @func_addr1 = hidden global i32()* @my_func, align 4 | |
| 17 | @func_addr2 = hidden global i32()* @foo_import, align 4 | |
| 18 | @data_addr1 = hidden global i64* @data_import, align 8 | |
| 19 | ||
| 20 | ; CHECK: --- !WASM | |
| 21 | ; CHECK-NEXT: FileHeader: | |
| 22 | ; CHECK-NEXT: Version: 0x00000001 | |
| 23 | ; CHECK-NEXT: Sections: | |
| 24 | ; CHECK-NEXT: - Type: TYPE | |
| 25 | ; CHECK-NEXT: Signatures: | |
| 26 | ; CHECK-NEXT: - Index: 0 | |
| 27 | ; CHECK-NEXT: ReturnType: NORESULT | |
| 28 | ; CHECK-NEXT: ParamTypes: | |
| 29 | ; CHECK-NEXT: - Index: 1 | |
| 30 | ; CHECK-NEXT: ReturnType: NORESULT | |
| 31 | ; CHECK-NEXT: ParamTypes: | |
| 32 | ; CHECK-NEXT: - I32 | |
| 33 | ; CHECK-NEXT: - Index: 2 | |
| 34 | ; CHECK-NEXT: ReturnType: I32 | |
| 35 | ; CHECK-NEXT: ParamTypes: | |
| 36 | ; CHECK-NEXT: - Type: IMPORT | |
| 37 | ; CHECK-NEXT: Imports: | |
| 38 | ; CHECK-NEXT: - Module: env | |
| 39 | ; CHECK-NEXT: Field: puts | |
| 40 | ; CHECK-NEXT: Kind: FUNCTION | |
| 41 | ; CHECK-NEXT: SigIndex: 1 | |
| 42 | ; CHECK-NEXT: - Module: env | |
| 43 | ; CHECK-NEXT: Field: foo_import | |
| 44 | ; CHECK-NEXT: Kind: FUNCTION | |
| 45 | ; CHECK-NEXT: SigIndex: 2 | |
| 46 | ; CHECK-NEXT: - Module: env | |
| 47 | ; CHECK-NEXT: Field: data_import | |
| 48 | ; CHECK-NEXT: Kind: GLOBAL | |
| 49 | ; CHECK-NEXT: GlobalType: I32 | |
| 50 | ; CHECK-NEXT: GlobalMutable: false | |
| 51 | ; CHECK-NEXT: - Type: FUNCTION | |
| 52 | ; CHECK-NEXT: FunctionTypes: [ 0, 2 ] | |
| 53 | ; CHECK-NEXT: - Type: TABLE | |
| 54 | ; CHECK-NEXT: Tables: | |
| 55 | ; CHECK-NEXT: - ElemType: ANYFUNC | |
| 56 | ; CHECK-NEXT: Limits: | |
| 57 | ; CHECK-NEXT: Flags: [ HAS_MAX ] | |
| 58 | ; CHECK-NEXT: Initial: 0x00000002 | |
| 59 | ; CHECK-NEXT: Maximum: 0x00000002 | |
| 60 | ; CHECK-NEXT: - Type: MEMORY | |
| 61 | ; CHECK-NEXT: Memories: | |
| 62 | ; 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 | |
| 106 | ; CHECK-NEXT: Segments: | |
| 107 | ; CHECK-NEXT: - Offset: | |
| 108 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 109 | ; CHECK-NEXT: Value: 0 | |
| 110 | ; CHECK-NEXT: Functions: [ 3, 1 ] | |
| 111 | ; CHECK-NEXT: - Type: CODE | |
| 112 | ; CHECK-NEXT: Relocations: | |
| 113 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB | |
| 114 | ; CHECK-NEXT: Index: 1 | |
| 115 | ; CHECK-NEXT: Offset: 0x00000004 | |
| 116 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB | |
| 117 | ; CHECK-NEXT: Index: 0 | |
| 118 | ; CHECK-NEXT: Offset: 0x0000000A | |
| 119 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB | |
| 120 | ; CHECK-NEXT: Index: 1 | |
| 121 | ; CHECK-NEXT: Offset: 0x00000013 | |
| 122 | ; CHECK-NEXT: Functions: | |
| 123 | ; CHECK-NEXT: - Locals: | |
| 124 | ; CHECK-NEXT: Body: 4180808080001080808080000B | |
| 125 | ; CHECK-NEXT: - Locals: | |
| 126 | ; CHECK-NEXT: Body: 1081808080001A41010B | |
| 127 | ; CHECK-NEXT: - Type: DATA | |
| 128 | ; CHECK-NEXT: Relocations: | |
| 129 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 | |
| 130 | ; CHECK-NEXT: Index: 0 | |
| 131 | ; CHECK-NEXT: Offset: 0x00000012 | |
| 132 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 | |
| 133 | ; CHECK-NEXT: Index: 1 | |
| 134 | ; CHECK-NEXT: Offset: 0x0000001B | |
| 135 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 | |
| 136 | ; CHECK-NEXT: Index: 0 | |
| 137 | ; CHECK-NEXT: Offset: 0x00000024 | |
| 138 | ; CHECK-NEXT: Segments: | |
| 139 | ; CHECK-NEXT: - SectionOffset: 6 | |
| 140 | ; CHECK-NEXT: MemoryIndex: 0 | |
| 141 | ; CHECK-NEXT: Offset: | |
| 142 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 143 | ; CHECK-NEXT: Value: 0 | |
| 144 | ; CHECK-NEXT: Content: 68656C6C6F0A00 | |
| 145 | ; CHECK-NEXT: - SectionOffset: 18 | |
| 146 | ; CHECK-NEXT: MemoryIndex: 0 | |
| 147 | ; CHECK-NEXT: Offset: | |
| 148 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 149 | ; CHECK-NEXT: Value: 8 | |
| 150 | ; CHECK-NEXT: Content: '00000000' | |
| 151 | ; CHECK-NEXT: - SectionOffset: 27 | |
| 152 | ; CHECK-NEXT: MemoryIndex: 0 | |
| 153 | ; CHECK-NEXT: Offset: | |
| 154 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 155 | ; CHECK-NEXT: Value: 12 | |
| 156 | ; CHECK-NEXT: Content: '01000000' | |
| 157 | ; CHECK-NEXT: - SectionOffset: 36 | |
| 158 | ; CHECK-NEXT: MemoryIndex: 0 | |
| 159 | ; CHECK-NEXT: Offset: | |
| 160 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 161 | ; CHECK-NEXT: Value: 16 | |
| 162 | ; CHECK-NEXT: Content: FFFFFFFF | |
| 163 | ; CHECK-NEXT: - Type: CUSTOM | |
| 164 | ; CHECK-NEXT: Name: linking | |
| 165 | ; CHECK-NEXT: DataSize: 20 | |
| 166 | ; CHECK-NEXT: SegmentInfo: | |
| 167 | ; CHECK-NEXT: - Index: 0 | |
| 168 | ; CHECK-NEXT: Name: .rodata.hello_str | |
| 169 | ; CHECK-NEXT: Alignment: 1 | |
| 170 | ; CHECK-NEXT: Flags: [ ] | |
| 171 | ; CHECK-NEXT: - Index: 1 | |
| 172 | ; CHECK-NEXT: Name: .data.func_addr1 | |
| 173 | ; CHECK-NEXT: Alignment: 4 | |
| 174 | ; CHECK-NEXT: Flags: [ ] | |
| 175 | ; CHECK-NEXT: - Index: 2 | |
| 176 | ; CHECK-NEXT: Name: .data.func_addr2 | |
| 177 | ; CHECK-NEXT: Alignment: 4 | |
| 178 | ; CHECK-NEXT: Flags: [ ] | |
| 179 | ; CHECK-NEXT: - Index: 3 | |
| 180 | ; CHECK-NEXT: Name: .data.data_addr1 | |
| 181 | ; CHECK-NEXT: Alignment: 8 | |
| 182 | ; CHECK-NEXT: Flags: [ ] | |
| 183 | ; CHECK-NEXT: - Type: CUSTOM | |
| 184 | ; CHECK-NEXT: Name: name | |
| 185 | ; CHECK-NEXT: FunctionNames: | |
| 186 | ; CHECK-NEXT: - Index: 0 | |
| 187 | ; CHECK-NEXT: Name: puts | |
| 188 | ; CHECK-NEXT: - Index: 1 | |
| 189 | ; CHECK-NEXT: Name: foo_import | |
| 190 | ; CHECK-NEXT: - Index: 2 | |
| 191 | ; CHECK-NEXT: Name: hello | |
| 192 | ; CHECK-NEXT: - Index: 3 | |
| 193 | ; CHECK-NEXT: Name: my_func | |
| 194 | ; CHECK-NEXT: ... |
deps/lld/test/wasm/signature-mismatch.ll created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %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 | |
| 4 | ||
| 5 | ; Function Attrs: nounwind | |
| 6 | define hidden void @_start() local_unnamed_addr #0 { | |
| 7 | entry: | |
| 8 | %call = tail call i32 @ret32(i32 1, i64 2, i32 3) #2 | |
| 9 | ret void | |
| 10 | } | |
| 11 | ||
| 12 | declare i32 @ret32(i32, i64, i32) local_unnamed_addr #1 | |
| 13 | ||
| 14 | ; CHECK: error: function signature mismatch: ret32 | |
| 15 | ; CHECK-NEXT: >>> defined as (I32, I64, I32) -> I32 in {{.*}}.main.o | |
| 16 | ; CHECK-NEXT: >>> defined as (F32) -> I32 in {{.*}}.ret32.o |
deps/lld/test/wasm/stack-pointer.ll created+64| ... | ... | @@ -0,0 +1,64 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | |
| 2 | ; RUN: lld -flavor wasm --emit-relocs -o %t.wasm %t.o | |
| 3 | ; RUN: obj2yaml %t.wasm | FileCheck %s | |
| 4 | ||
| 5 | ; Function Attrs: nounwind | |
| 6 | define hidden i32 @_start() local_unnamed_addr { | |
| 7 | entry: | |
| 8 | %retval = alloca i32, align 4 | |
| 9 | ret i32 0 | |
| 10 | } | |
| 11 | ||
| 12 | ; CHECK: --- !WASM | |
| 13 | ; CHECK-NEXT: FileHeader: | |
| 14 | ; CHECK-NEXT: Version: 0x00000001 | |
| 15 | ; CHECK-NEXT: Sections: | |
| 16 | ; CHECK-NEXT: - Type: TYPE | |
| 17 | ; CHECK-NEXT: Signatures: | |
| 18 | ; CHECK-NEXT: - Index: 0 | |
| 19 | ; CHECK-NEXT: ReturnType: I32 | |
| 20 | ; CHECK-NEXT: ParamTypes: | |
| 21 | ; CHECK-NEXT: - Type: FUNCTION | |
| 22 | ; CHECK-NEXT: FunctionTypes: [ 0 ] | |
| 23 | ; CHECK-NEXT: - Type: TABLE | |
| 24 | ; CHECK-NEXT: Tables: | |
| 25 | ; CHECK-NEXT: - ElemType: ANYFUNC | |
| 26 | ; CHECK-NEXT: Limits: | |
| 27 | ; CHECK-NEXT: Flags: [ HAS_MAX ] | |
| 28 | ; CHECK-NEXT: Initial: 0x00000001 | |
| 29 | ; CHECK-NEXT: Maximum: 0x00000001 | |
| 30 | ; CHECK-NEXT: - Type: MEMORY | |
| 31 | ; CHECK-NEXT: Memories: | |
| 32 | ; CHECK-NEXT: - Initial: 0x00000002 | |
| 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 | |
| 49 | ; CHECK-NEXT: Relocations: | |
| 50 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB | |
| 51 | ; CHECK-NEXT: Index: 0 | |
| 52 | ; CHECK-NEXT: Offset: 0x00000004 | |
| 53 | ; CHECK-NEXT: Functions: | |
| 54 | ; CHECK-NEXT: - Locals: | |
| 55 | ; CHECK-NEXT: Body: 23808080800041106B1A41000B | |
| 56 | ; CHECK-NEXT: - Type: CUSTOM | |
| 57 | ; CHECK-NEXT: Name: linking | |
| 58 | ; CHECK-NEXT: DataSize: 0 | |
| 59 | ; CHECK-NEXT: - Type: CUSTOM | |
| 60 | ; CHECK-NEXT: Name: name | |
| 61 | ; CHECK-NEXT: FunctionNames: | |
| 62 | ; CHECK-NEXT: - Index: 0 | |
| 63 | ; CHECK-NEXT: Name: _start | |
| 64 | ; CHECK-NEXT: ... |
deps/lld/test/wasm/strip-debug.test created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | |
| 2 | RUN: lld -flavor wasm --strip-debug --entry=ret32 -o %t.wasm %t.ret32.o | |
| 3 | RUN: obj2yaml %t.wasm | FileCheck %s | |
| 4 | ||
| 5 | # Check that there is no name section | |
| 6 | CHECK-NOT: Name: name |
deps/lld/test/wasm/symbol-type-mismatch.ll created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %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 | |
| 4 | ||
| 5 | @ret32 = extern_weak global i32, align 4 | |
| 6 | ||
| 7 | ; CHECK: error: symbol type mismatch: ret32 | |
| 8 | ; CHECK: >>> defined as Global in {{.*}}symbol-type-mismatch.ll.tmp.o | |
| 9 | ; CHECK: >>> defined as Function in {{.*}}.ret32.o |
deps/lld/test/wasm/undefined-entry.test created+4| ... | ... | @@ -0,0 +1,4 @@ |
| 1 | RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | |
| 2 | RUN: not lld -flavor wasm -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s | |
| 3 | ||
| 4 | CHECK: error: undefined symbol: _start |
deps/lld/test/wasm/undefined.ll created+20| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | |
| 2 | ; RUN: lld -flavor wasm --allow-undefined -o %t.wasm %t.o | |
| 3 | ||
| 4 | ; Fails due to undefined 'foo' | |
| 5 | ; RUN: not lld -flavor wasm -o %t.wasm %t.o 2>&1 | FileCheck %s | |
| 6 | ; CHECK: error: {{.*}}.o: undefined symbol: foo | |
| 7 | ||
| 8 | ; But succeeds if we pass a file containing 'foo' as --allow-undefined-file. | |
| 9 | ; RUN: echo 'foo' > %t.txt | |
| 10 | ; RUN: lld -flavor wasm --allow-undefined-file=%t.txt -o %t.wasm %t.o | |
| 11 | ||
| 12 | ; 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 | |
| 14 | ||
| 15 | declare i32 @foo() #0 | |
| 16 | ||
| 17 | define hidden void @_start() local_unnamed_addr #0 { | |
| 18 | entry: | |
| 19 | ret void | |
| 20 | } |
deps/lld/test/wasm/version.ll created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | |
| 2 | ; RUN: lld -flavor wasm -o %t.wasm %t.o | |
| 3 | ; RUN: llvm-readobj -file-headers %t.wasm | FileCheck %s | |
| 4 | ||
| 5 | define hidden void @_start() local_unnamed_addr #0 { | |
| 6 | entry: | |
| 7 | ret void | |
| 8 | } | |
| 9 | ||
| 10 | ; CHECK: Format: WASM | |
| 11 | ; CHECK: Arch: wasm32 | |
| 12 | ; CHECK: AddressSize: 32bit | |
| 13 | ; CHECK: Version: 0x1 |
deps/lld/test/wasm/visibility-hidden.ll created+46| ... | ... | @@ -0,0 +1,46 @@ |
| 1 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s | |
| 2 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj %S/Inputs/hidden.ll -o %t2.o | |
| 3 | ; RUN: llvm-ar rcs %t2.a %t2.o | |
| 4 | ; RUN: lld -flavor wasm %t.o %t2.a -o %t.wasm | |
| 5 | ; RUN: obj2yaml %t.wasm | FileCheck %s | |
| 6 | ||
| 7 | ; Test that hidden symbols are not exported, whether pulled in from an archive | |
| 8 | ; or directly. | |
| 9 | ||
| 10 | define hidden i32 @objectHidden() { | |
| 11 | entry: | |
| 12 | ret i32 0 | |
| 13 | } | |
| 14 | ||
| 15 | define i32 @objectDefault() { | |
| 16 | entry: | |
| 17 | ret i32 0 | |
| 18 | } | |
| 19 | ||
| 20 | declare i32 @archiveHidden() | |
| 21 | declare i32 @archiveDefault() | |
| 22 | ||
| 23 | define i32 @_start() { | |
| 24 | entry: | |
| 25 | %call1 = call i32 @objectHidden() | |
| 26 | %call2 = call i32 @objectDefault() | |
| 27 | %call3 = call i32 @archiveHidden() | |
| 28 | %call4 = call i32 @archiveDefault() | |
| 29 | ret i32 0 | |
| 30 | } | |
| 31 | ||
| 32 | ; CHECK: - Type: EXPORT | |
| 33 | ; CHECK-NEXT: Exports: | |
| 34 | ; CHECK-NEXT: - Name: memory | |
| 35 | ; CHECK-NEXT: Kind: MEMORY | |
| 36 | ; CHECK-NEXT: Index: 0 | |
| 37 | ; CHECK-NEXT: - Name: _start | |
| 38 | ; CHECK-NEXT: Kind: FUNCTION | |
| 39 | ; CHECK-NEXT: Index: 2 | |
| 40 | ; CHECK-NEXT: - Name: archiveDefault | |
| 41 | ; CHECK-NEXT: Kind: FUNCTION | |
| 42 | ; CHECK-NEXT: Index: 4 | |
| 43 | ; CHECK-NEXT: - Name: objectDefault | |
| 44 | ; CHECK-NEXT: Kind: FUNCTION | |
| 45 | ; CHECK-NEXT: Index: 1 | |
| 46 | ; CHECK-NEXT: - Type: |
deps/lld/test/wasm/weak-alias-overide.ll created+123| ... | ... | @@ -0,0 +1,123 @@ |
| 1 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s | |
| 2 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o | |
| 3 | ; RUN: lld -flavor wasm %t.o %t2.o -o %t.wasm | |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | |
| 5 | ||
| 6 | ; Test that the strongly defined alias_fn from this file is used both here | |
| 7 | ; and in call_alias. | |
| 8 | ||
| 9 | define i32 @alias_fn() local_unnamed_addr #1 { | |
| 10 | ret i32 1 | |
| 11 | } | |
| 12 | ||
| 13 | ; Function Attrs: nounwind uwtable | |
| 14 | define void @_start() local_unnamed_addr #1 { | |
| 15 | entry: | |
| 16 | %call = tail call i32 @alias_fn() #2 | |
| 17 | ret void | |
| 18 | } | |
| 19 | ||
| 20 | ; CHECK: --- !WASM | |
| 21 | ; CHECK-NEXT: FileHeader: | |
| 22 | ; CHECK-NEXT: Version: 0x00000001 | |
| 23 | ; CHECK-NEXT: Sections: | |
| 24 | ; CHECK-NEXT: - Type: TYPE | |
| 25 | ; CHECK-NEXT: Signatures: | |
| 26 | ; CHECK-NEXT: - Index: 0 | |
| 27 | ; CHECK-NEXT: ReturnType: I32 | |
| 28 | ; CHECK-NEXT: ParamTypes: | |
| 29 | ; CHECK-NEXT: - Index: 1 | |
| 30 | ; CHECK-NEXT: ReturnType: NORESULT | |
| 31 | ; CHECK-NEXT: ParamTypes: | |
| 32 | ; CHECK-NEXT: - Type: FUNCTION | |
| 33 | ; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 0, 0, 0, 0 ] | |
| 34 | ; CHECK-NEXT: - Type: TABLE | |
| 35 | ; CHECK-NEXT: Tables: | |
| 36 | ; CHECK-NEXT: - ElemType: ANYFUNC | |
| 37 | ; CHECK-NEXT: Limits: | |
| 38 | ; CHECK-NEXT: Flags: [ HAS_MAX ] | |
| 39 | ; CHECK-NEXT: Initial: 0x00000003 | |
| 40 | ; CHECK-NEXT: Maximum: 0x00000003 | |
| 41 | ; CHECK-NEXT: - Type: MEMORY | |
| 42 | ; CHECK-NEXT: Memories: | |
| 43 | ; CHECK-NEXT: - Initial: 0x00000002 | |
| 44 | ; CHECK-NEXT: - Type: GLOBAL | |
| 45 | ; CHECK-NEXT: Globals: | |
| 46 | ; CHECK-NEXT: - Type: I32 | |
| 47 | ; CHECK-NEXT: Mutable: true | |
| 48 | ; CHECK-NEXT: InitExpr: | |
| 49 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 50 | ; CHECK-NEXT: Value: 66560 | |
| 51 | ; CHECK-NEXT: - Type: EXPORT | |
| 52 | ; CHECK-NEXT: Exports: | |
| 53 | ; CHECK-NEXT: - Name: memory | |
| 54 | ; CHECK-NEXT: Kind: MEMORY | |
| 55 | ; CHECK-NEXT: Index: 0 | |
| 56 | ; CHECK-NEXT: - Name: _start | |
| 57 | ; CHECK-NEXT: Kind: FUNCTION | |
| 58 | ; CHECK-NEXT: Index: 1 | |
| 59 | ; CHECK-NEXT: - Name: alias_fn | |
| 60 | ; CHECK-NEXT: Kind: FUNCTION | |
| 61 | ; CHECK-NEXT: Index: 0 | |
| 62 | ; CHECK-NEXT: - Name: direct_fn | |
| 63 | ; CHECK-NEXT: Kind: FUNCTION | |
| 64 | ; CHECK-NEXT: Index: 2 | |
| 65 | ; CHECK-NEXT: - Name: call_direct | |
| 66 | ; CHECK-NEXT: Kind: FUNCTION | |
| 67 | ; CHECK-NEXT: Index: 3 | |
| 68 | ; CHECK-NEXT: - Name: call_alias | |
| 69 | ; CHECK-NEXT: Kind: FUNCTION | |
| 70 | ; CHECK-NEXT: Index: 4 | |
| 71 | ; CHECK-NEXT: - Name: call_alias_ptr | |
| 72 | ; CHECK-NEXT: Kind: FUNCTION | |
| 73 | ; CHECK-NEXT: Index: 5 | |
| 74 | ; CHECK-NEXT: - Name: call_direct_ptr | |
| 75 | ; CHECK-NEXT: Kind: FUNCTION | |
| 76 | ; CHECK-NEXT: Index: 6 | |
| 77 | ; CHECK-NEXT: - Type: ELEM | |
| 78 | ; CHECK-NEXT: Segments: | |
| 79 | ; CHECK-NEXT: - Offset: | |
| 80 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 81 | ; CHECK-NEXT: Value: 1 | |
| 82 | ; CHECK-NEXT: Functions: [ 0, 2 ] | |
| 83 | ; CHECK-NEXT: - Type: CODE | |
| 84 | ; CHECK-NEXT: Functions: | |
| 85 | ; CHECK-NEXT: - Locals: | |
| 86 | ; CHECK-NEXT: Body: 41010B | |
| 87 | ; CHECK-NEXT: - Locals: | |
| 88 | ; CHECK-NEXT: Body: 1080808080001A0B | |
| 89 | ; CHECK-NEXT: - Locals: | |
| 90 | ; CHECK-NEXT: Body: 41000B | |
| 91 | ; CHECK-NEXT: - Locals: | |
| 92 | ; CHECK-NEXT: Body: 1082808080000B | |
| 93 | ; CHECK-NEXT: - Locals: | |
| 94 | ; CHECK-NEXT: Body: 1080808080000B | |
| 95 | ; CHECK-NEXT: - Locals: | |
| 96 | ; CHECK-NEXT: - Type: I32 | |
| 97 | ; CHECK-NEXT: Count: 2 | |
| 98 | ; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081080808080002101200041106A24808080800020010B | |
| 99 | ; CHECK-NEXT: - Locals: | |
| 100 | ; CHECK-NEXT: - Type: I32 | |
| 101 | ; CHECK-NEXT: Count: 2 | |
| 102 | ; CHECK-NEXT: Body: 23808080800041106B220024808080800020004182808080003602081082808080002101200041106A24808080800020010B | |
| 103 | ; CHECK-NEXT: - Type: CUSTOM | |
| 104 | ; CHECK-NEXT: Name: linking | |
| 105 | ; CHECK-NEXT: DataSize: 0 | |
| 106 | ; CHECK-NEXT: - Type: CUSTOM | |
| 107 | ; CHECK-NEXT: Name: name | |
| 108 | ; CHECK-NEXT: FunctionNames: | |
| 109 | ; CHECK-NEXT: - Index: 0 | |
| 110 | ; CHECK-NEXT: Name: alias_fn | |
| 111 | ; CHECK-NEXT: - Index: 1 | |
| 112 | ; CHECK-NEXT: Name: _start | |
| 113 | ; CHECK-NEXT: - Index: 2 | |
| 114 | ; CHECK-NEXT: Name: direct_fn | |
| 115 | ; CHECK-NEXT: - Index: 3 | |
| 116 | ; CHECK-NEXT: Name: call_direct | |
| 117 | ; CHECK-NEXT: - Index: 4 | |
| 118 | ; CHECK-NEXT: Name: call_alias | |
| 119 | ; CHECK-NEXT: - Index: 5 | |
| 120 | ; CHECK-NEXT: Name: call_alias_ptr | |
| 121 | ; CHECK-NEXT: - Index: 6 | |
| 122 | ; CHECK-NEXT: Name: call_direct_ptr | |
| 123 | ; CHECK-NEXT: ... |
deps/lld/test/wasm/weak-alias.ll created+113| ... | ... | @@ -0,0 +1,113 @@ |
| 1 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s | |
| 2 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o | |
| 3 | ; RUN: lld -flavor wasm %t.o %t2.o -o %t.wasm | |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | |
| 5 | ||
| 6 | ; Test that weak aliases (alias_fn is a weak alias of direct_fn) are linked correctly | |
| 7 | ||
| 8 | declare i32 @alias_fn() local_unnamed_addr #1 | |
| 9 | ||
| 10 | ; Function Attrs: nounwind uwtable | |
| 11 | define i32 @_start() local_unnamed_addr #1 { | |
| 12 | entry: | |
| 13 | %call = tail call i32 @alias_fn() #2 | |
| 14 | ret i32 %call | |
| 15 | } | |
| 16 | ||
| 17 | ; CHECK: --- !WASM | |
| 18 | ; CHECK-NEXT: FileHeader: | |
| 19 | ; CHECK-NEXT: Version: 0x00000001 | |
| 20 | ; CHECK-NEXT: Sections: | |
| 21 | ; CHECK-NEXT: - Type: TYPE | |
| 22 | ; CHECK-NEXT: Signatures: | |
| 23 | ; CHECK-NEXT: - Index: 0 | |
| 24 | ; CHECK-NEXT: ReturnType: I32 | |
| 25 | ; CHECK-NEXT: ParamTypes: | |
| 26 | ; CHECK-NEXT: - Type: FUNCTION | |
| 27 | ; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0, 0 ] | |
| 28 | ; CHECK-NEXT: - Type: TABLE | |
| 29 | ; CHECK-NEXT: Tables: | |
| 30 | ; CHECK-NEXT: - ElemType: ANYFUNC | |
| 31 | ; CHECK-NEXT: Limits: | |
| 32 | ; CHECK-NEXT: Flags: [ HAS_MAX ] | |
| 33 | ; CHECK-NEXT: Initial: 0x00000003 | |
| 34 | ; CHECK-NEXT: Maximum: 0x00000003 | |
| 35 | ; CHECK-NEXT: - Type: MEMORY | |
| 36 | ; CHECK-NEXT: Memories: | |
| 37 | ; CHECK-NEXT: - Initial: 0x00000002 | |
| 38 | ; CHECK-NEXT: - Type: GLOBAL | |
| 39 | ; CHECK-NEXT: Globals: | |
| 40 | ; CHECK-NEXT: - Type: I32 | |
| 41 | ; CHECK-NEXT: Mutable: true | |
| 42 | ; CHECK-NEXT: InitExpr: | |
| 43 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 44 | ; CHECK-NEXT: Value: 66560 | |
| 45 | ; CHECK-NEXT: - Type: EXPORT | |
| 46 | ; CHECK-NEXT: Exports: | |
| 47 | ; CHECK-NEXT: - Name: memory | |
| 48 | ; CHECK-NEXT: Kind: MEMORY | |
| 49 | ; CHECK-NEXT: Index: 0 | |
| 50 | ; CHECK-NEXT: - Name: _start | |
| 51 | ; CHECK-NEXT: Kind: FUNCTION | |
| 52 | ; CHECK-NEXT: Index: 0 | |
| 53 | ; CHECK-NEXT: - Name: alias_fn | |
| 54 | ; CHECK-NEXT: Kind: FUNCTION | |
| 55 | ; CHECK-NEXT: Index: 1 | |
| 56 | ; CHECK-NEXT: - Name: direct_fn | |
| 57 | ; CHECK-NEXT: Kind: FUNCTION | |
| 58 | ; CHECK-NEXT: Index: 1 | |
| 59 | ; CHECK-NEXT: - Name: call_direct | |
| 60 | ; CHECK-NEXT: Kind: FUNCTION | |
| 61 | ; CHECK-NEXT: Index: 2 | |
| 62 | ; CHECK-NEXT: - Name: call_alias | |
| 63 | ; CHECK-NEXT: Kind: FUNCTION | |
| 64 | ; CHECK-NEXT: Index: 3 | |
| 65 | ; CHECK-NEXT: - Name: call_alias_ptr | |
| 66 | ; CHECK-NEXT: Kind: FUNCTION | |
| 67 | ; CHECK-NEXT: Index: 4 | |
| 68 | ; CHECK-NEXT: - Name: call_direct_ptr | |
| 69 | ; CHECK-NEXT: Kind: FUNCTION | |
| 70 | ; CHECK-NEXT: Index: 5 | |
| 71 | ; CHECK-NEXT: - Type: ELEM | |
| 72 | ; CHECK-NEXT: Segments: | |
| 73 | ; CHECK-NEXT: - Offset: | |
| 74 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 75 | ; CHECK-NEXT: Value: 1 | |
| 76 | ; CHECK-NEXT: Functions: [ 1, 1 ] | |
| 77 | ; CHECK-NEXT: - Type: CODE | |
| 78 | ; CHECK-NEXT: Functions: | |
| 79 | ; CHECK-NEXT: - Locals: | |
| 80 | ; CHECK-NEXT: Body: 1081808080000B | |
| 81 | ; CHECK-NEXT: - Locals: | |
| 82 | ; CHECK-NEXT: Body: 41000B | |
| 83 | ; CHECK-NEXT: - Locals: | |
| 84 | ; CHECK-NEXT: Body: 1081808080000B | |
| 85 | ; CHECK-NEXT: - Locals: | |
| 86 | ; CHECK-NEXT: Body: 1081808080000B | |
| 87 | ; CHECK-NEXT: - Locals: | |
| 88 | ; CHECK-NEXT: - Type: I32 | |
| 89 | ; CHECK-NEXT: Count: 2 | |
| 90 | ; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B | |
| 91 | ; CHECK-NEXT: - Locals: | |
| 92 | ; CHECK-NEXT: - Type: I32 | |
| 93 | ; CHECK-NEXT: Count: 2 | |
| 94 | ; CHECK-NEXT: Body: 23808080800041106B220024808080800020004182808080003602081081808080002101200041106A24808080800020010B | |
| 95 | ; CHECK-NEXT: - Type: CUSTOM | |
| 96 | ; CHECK-NEXT: Name: linking | |
| 97 | ; CHECK-NEXT: DataSize: 0 | |
| 98 | ; CHECK-NEXT: - Type: CUSTOM | |
| 99 | ; CHECK-NEXT: Name: name | |
| 100 | ; CHECK-NEXT: FunctionNames: | |
| 101 | ; CHECK-NEXT: - Index: 0 | |
| 102 | ; CHECK-NEXT: Name: _start | |
| 103 | ; CHECK-NEXT: - Index: 1 | |
| 104 | ; CHECK-NEXT: Name: direct_fn | |
| 105 | ; CHECK-NEXT: - Index: 2 | |
| 106 | ; CHECK-NEXT: Name: call_direct | |
| 107 | ; CHECK-NEXT: - Index: 3 | |
| 108 | ; CHECK-NEXT: Name: call_alias | |
| 109 | ; CHECK-NEXT: - Index: 4 | |
| 110 | ; CHECK-NEXT: Name: call_alias_ptr | |
| 111 | ; CHECK-NEXT: - Index: 5 | |
| 112 | ; CHECK-NEXT: Name: call_direct_ptr | |
| 113 | ; CHECK-NEXT: ... |
deps/lld/test/wasm/weak-external.ll created+86| ... | ... | @@ -0,0 +1,86 @@ |
| 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 created+100| ... | ... | @@ -0,0 +1,100 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %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 | |
| 3 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | |
| 4 | ; RUN: lld -flavor wasm -o %t.wasm %t.o %t1.o %t2.o | |
| 5 | ; RUN: obj2yaml %t.wasm | FileCheck %s | |
| 6 | ||
| 7 | declare i32 @weakFn() local_unnamed_addr | |
| 8 | @weakGlobal = external global i32 | |
| 9 | ||
| 10 | define i32 @_start() local_unnamed_addr { | |
| 11 | entry: | |
| 12 | %call = call i32 @weakFn() | |
| 13 | %val = load i32, i32* @weakGlobal, align 4 | |
| 14 | ret i32 %val | |
| 15 | } | |
| 16 | ||
| 17 | ; CHECK: --- !WASM | |
| 18 | ; CHECK-NEXT: FileHeader: | |
| 19 | ; CHECK-NEXT: Version: 0x00000001 | |
| 20 | ; CHECK-NEXT: Sections: | |
| 21 | ; CHECK-NEXT: - Type: TYPE | |
| 22 | ; CHECK-NEXT: Signatures: | |
| 23 | ; CHECK-NEXT: - Index: 0 | |
| 24 | ; CHECK-NEXT: ReturnType: I32 | |
| 25 | ; CHECK-NEXT: ParamTypes: | |
| 26 | ; CHECK-NEXT: - Type: FUNCTION | |
| 27 | ; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ] | |
| 28 | ; CHECK-NEXT: - Type: TABLE | |
| 29 | ; CHECK-NEXT: Tables: | |
| 30 | ; CHECK-NEXT: - ElemType: ANYFUNC | |
| 31 | ; CHECK-NEXT: Limits: | |
| 32 | ; CHECK-NEXT: Flags: [ HAS_MAX ] | |
| 33 | ; CHECK-NEXT: Initial: 0x00000002 | |
| 34 | ; CHECK-NEXT: Maximum: 0x00000002 | |
| 35 | ; CHECK-NEXT: - Type: MEMORY | |
| 36 | ; CHECK-NEXT: Memories: | |
| 37 | ; CHECK-NEXT: - Initial: 0x00000002 | |
| 38 | ; CHECK-NEXT: - Type: GLOBAL | |
| 39 | ; CHECK-NEXT: Globals: | |
| 40 | ; CHECK-NEXT: - Type: I32 | |
| 41 | ; CHECK-NEXT: Mutable: true | |
| 42 | ; CHECK-NEXT: InitExpr: | |
| 43 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 44 | ; CHECK-NEXT: Value: 66576 | |
| 45 | ; CHECK-NEXT: - Type: EXPORT | |
| 46 | ; CHECK-NEXT: Exports: | |
| 47 | ; CHECK-NEXT: - Name: memory | |
| 48 | ; CHECK-NEXT: Kind: MEMORY | |
| 49 | ; CHECK-NEXT: Index: 0 | |
| 50 | ; CHECK-NEXT: - Name: _start | |
| 51 | ; CHECK-NEXT: Kind: FUNCTION | |
| 52 | ; CHECK-NEXT: Index: 0 | |
| 53 | ; CHECK-NEXT: - Name: weakFn | |
| 54 | ; CHECK-NEXT: Kind: FUNCTION | |
| 55 | ; CHECK-NEXT: Index: 1 | |
| 56 | ; CHECK-NEXT: - Name: exportWeak1 | |
| 57 | ; CHECK-NEXT: Kind: FUNCTION | |
| 58 | ; CHECK-NEXT: Index: 2 | |
| 59 | ; CHECK-NEXT: - Name: exportWeak2 | |
| 60 | ; CHECK-NEXT: Kind: FUNCTION | |
| 61 | ; CHECK-NEXT: Index: 4 | |
| 62 | ; CHECK-NEXT: - Type: ELEM | |
| 63 | ; CHECK-NEXT: Segments: | |
| 64 | ; CHECK-NEXT: - Offset: | |
| 65 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 66 | ; CHECK-NEXT: Value: 1 | |
| 67 | ; CHECK-NEXT: Functions: [ 1 ] | |
| 68 | ; CHECK-NEXT: - Type: CODE | |
| 69 | ; CHECK-NEXT: Functions: | |
| 70 | ; CHECK-NEXT: - Locals: | |
| 71 | ; CHECK-NEXT: Body: 1081808080001A4100280280888080000B | |
| 72 | ; CHECK-NEXT: - Locals: | |
| 73 | ; CHECK-NEXT: Body: 41010B | |
| 74 | ; CHECK-NEXT: - Locals: | |
| 75 | ; CHECK-NEXT: Body: 4181808080000B | |
| 76 | ; CHECK-NEXT: - Locals: | |
| 77 | ; CHECK-NEXT: Body: 41020B | |
| 78 | ; CHECK-NEXT: - Locals: | |
| 79 | ; CHECK-NEXT: Body: 4181808080000B | |
| 80 | ; CHECK-NEXT: - Type: DATA | |
| 81 | ; CHECK-NEXT: Segments: | |
| 82 | ; CHECK-NEXT: - SectionOffset: 7 | |
| 83 | ; CHECK-NEXT: MemoryIndex: 0 | |
| 84 | ; CHECK-NEXT: Offset: | |
| 85 | ; CHECK-NEXT: Opcode: I32_CONST | |
| 86 | ; CHECK-NEXT: Value: 1024 | |
| 87 | ; CHECK-NEXT: Content: '0100000002000000' | |
| 88 | ; CHECK-NEXT: - Type: CUSTOM | |
| 89 | ; CHECK-NEXT: Name: linking | |
| 90 | ; CHECK-NEXT: DataSize: 8 | |
| 91 | ; CHECK-NEXT: - Type: CUSTOM | |
| 92 | ; CHECK-NEXT: Name: name | |
| 93 | ; CHECK-NEXT: FunctionNames: | |
| 94 | ; CHECK-NEXT: - Index: 0 | |
| 95 | ; CHECK-NEXT: Name: _start | |
| 96 | ; CHECK-NEXT: - Index: 2 | |
| 97 | ; CHECK-NEXT: Name: exportWeak1 | |
| 98 | ; CHECK-NEXT: - Index: 4 | |
| 99 | ; CHECK-NEXT: Name: exportWeak2 | |
| 100 | ; CHECK-NEXT: ... |
deps/lld/tools/lld/CMakeLists.txt+5-2| ... | ... | @@ -7,16 +7,19 @@ add_lld_tool(lld |
| 7 | 7 | ) |
| 8 | 8 | |
| 9 | 9 | target_link_libraries(lld |
| 10 | lldDriver | |
| 10 | PRIVATE | |
| 11 | 11 | lldCOFF |
| 12 | lldDriver | |
| 12 | 13 | lldELF |
| 14 | lldMinGW | |
| 15 | lldWasm | |
| 13 | 16 | ) |
| 14 | 17 | |
| 15 | 18 | install(TARGETS lld |
| 16 | 19 | RUNTIME DESTINATION bin) |
| 17 | 20 | |
| 18 | 21 | if(NOT LLD_SYMLINKS_TO_CREATE) |
| 19 | set(LLD_SYMLINKS_TO_CREATE lld-link ld.lld) | |
| 22 | set(LLD_SYMLINKS_TO_CREATE lld-link ld.lld ld64.lld wasm-ld) | |
| 20 | 23 | endif() |
| 21 | 24 | |
| 22 | 25 | foreach(link ${LLD_SYMLINKS_TO_CREATE}) |
deps/lld/tools/lld/lld.cpp+18-2| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | // |
| 17 | 17 | //===----------------------------------------------------------------------===// |
| 18 | 18 | |
| 19 | #include "lld/Driver/Driver.h" | |
| 19 | #include "lld/Common/Driver.h" | |
| 20 | 20 | #include "llvm/ADT/STLExtras.h" |
| 21 | 21 | #include "llvm/ADT/StringSwitch.h" |
| 22 | 22 | #include "llvm/ADT/Twine.h" |
| ... | ... | @@ -34,6 +34,7 @@ enum Flavor { |
| 34 | 34 | Gnu, // -flavor gnu |
| 35 | 35 | WinLink, // -flavor link |
| 36 | 36 | Darwin, // -flavor darwin |
| 37 | Wasm, // -flavor wasm | |
| 37 | 38 | }; |
| 38 | 39 | |
| 39 | 40 | LLVM_ATTRIBUTE_NORETURN static void die(const Twine &S) { |
| ... | ... | @@ -44,11 +45,22 @@ LLVM_ATTRIBUTE_NORETURN static void die(const Twine &S) { |
| 44 | 45 | static Flavor getFlavor(StringRef S) { |
| 45 | 46 | return StringSwitch<Flavor>(S) |
| 46 | 47 | .CasesLower("ld", "ld.lld", "gnu", Gnu) |
| 48 | .CasesLower("wasm", "ld-wasm", Wasm) | |
| 47 | 49 | .CaseLower("link", WinLink) |
| 48 | .CaseLower("darwin", Darwin) | |
| 50 | .CasesLower("ld64", "ld64.lld", "darwin", Darwin) | |
| 49 | 51 | .Default(Invalid); |
| 50 | 52 | } |
| 51 | 53 | |
| 54 | static bool isPETarget(const std::vector<const char *> &V) { | |
| 55 | for (auto It = V.begin(); It + 1 != V.end(); ++It) { | |
| 56 | if (StringRef(*It) != "-m") | |
| 57 | continue; | |
| 58 | StringRef S = *(It + 1); | |
| 59 | return S == "i386pe" || S == "i386pep" || S == "thumb2pe" || S == "arm64pe"; | |
| 60 | } | |
| 61 | return false; | |
| 62 | } | |
| 63 | ||
| 52 | 64 | static Flavor parseProgname(StringRef Progname) { |
| 53 | 65 | #if __APPLE__ |
| 54 | 66 | // Use Darwin driver for "ld" on Darwin. |
| ... | ... | @@ -101,11 +113,15 @@ int main(int Argc, const char **Argv) { |
| 101 | 113 | std::vector<const char *> Args(Argv, Argv + Argc); |
| 102 | 114 | switch (parseFlavor(Args)) { |
| 103 | 115 | case Gnu: |
| 116 | if (isPETarget(Args)) | |
| 117 | return !mingw::link(Args); | |
| 104 | 118 | return !elf::link(Args, true); |
| 105 | 119 | case WinLink: |
| 106 | 120 | return !coff::link(Args, true); |
| 107 | 121 | case Darwin: |
| 108 | 122 | return !mach_o::link(Args); |
| 123 | case Wasm: | |
| 124 | return !wasm::link(Args, true); | |
| 109 | 125 | default: |
| 110 | 126 | die("lld is a generic driver.\n" |
| 111 | 127 | "Invoke ld.lld (Unix), ld (macOS) or lld-link (Windows) instead."); |
deps/lld/unittests/DriverTests/CMakeLists.txt+1| ... | ... | @@ -3,6 +3,7 @@ add_lld_unittest(DriverTests |
| 3 | 3 | ) |
| 4 | 4 | |
| 5 | 5 | target_link_libraries(DriverTests |
| 6 | PRIVATE | |
| 6 | 7 | lldDriver |
| 7 | 8 | lldMachO |
| 8 | 9 | ) |
deps/lld/unittests/DriverTests/DarwinLdDriverTest.cpp+1-1| ... | ... | @@ -12,7 +12,7 @@ |
| 12 | 12 | /// |
| 13 | 13 | //===----------------------------------------------------------------------===// |
| 14 | 14 | |
| 15 | #include "lld/Driver/Driver.h" | |
| 15 | #include "lld/Common/Driver.h" | |
| 16 | 16 | #include "lld/ReaderWriter/MachOLinkingContext.h" |
| 17 | 17 | #include "llvm/BinaryFormat/MachO.h" |
| 18 | 18 | #include "llvm/Support/raw_ostream.h" |
deps/lld/unittests/MachOTests/CMakeLists.txt+1| ... | ... | @@ -7,6 +7,7 @@ add_lld_unittest(lldMachOTests |
| 7 | 7 | ) |
| 8 | 8 | |
| 9 | 9 | target_link_libraries(lldMachOTests |
| 10 | PRIVATE | |
| 10 | 11 | lldDriver |
| 11 | 12 | lldMachO |
| 12 | 13 | lldYAML |
deps/lld/utils/benchmark.py created+135| ... | ... | @@ -0,0 +1,135 @@ |
| 1 | #!/usr/bin/env python | |
| 2 | # | |
| 3 | # The LLVM Compiler Infrastructure | |
| 4 | # | |
| 5 | # This file is distributed under the University of Illinois Open Source | |
| 6 | # License. See LICENSE.TXT for details. | |
| 7 | # | |
| 8 | # ==------------------------------------------------------------------------==# | |
| 9 | ||
| 10 | import os | |
| 11 | import glob | |
| 12 | import re | |
| 13 | import subprocess | |
| 14 | import json | |
| 15 | import datetime | |
| 16 | import argparse | |
| 17 | import urllib | |
| 18 | import urllib2 | |
| 19 | ||
| 20 | parser = argparse.ArgumentParser() | |
| 21 | parser.add_argument('benchmark_directory') | |
| 22 | parser.add_argument('--runs', type=int, default=10) | |
| 23 | parser.add_argument('--wrapper', default='') | |
| 24 | parser.add_argument('--machine', required=True) | |
| 25 | parser.add_argument('--revision', required=True) | |
| 26 | parser.add_argument('--threads', action='store_true') | |
| 27 | parser.add_argument('--url', help='The lnt server url to send the results to', | |
| 28 | default='http://localhost:8000/db_default/v4/link/submitRun') | |
| 29 | args = parser.parse_args() | |
| 30 | ||
| 31 | class Bench: | |
| 32 | def __init__(self, directory, variant): | |
| 33 | self.directory = directory | |
| 34 | self.variant = variant | |
| 35 | def __str__(self): | |
| 36 | if not self.variant: | |
| 37 | return self.directory | |
| 38 | return '%s-%s' % (self.directory, self.variant) | |
| 39 | ||
| 40 | def getBenchmarks(): | |
| 41 | ret = [] | |
| 42 | for i in glob.glob('*/response*.txt'): | |
| 43 | m = re.match('response-(.*)\.txt', os.path.basename(i)) | |
| 44 | variant = m.groups()[0] if m else None | |
| 45 | ret.append(Bench(os.path.dirname(i), variant)) | |
| 46 | return ret | |
| 47 | ||
| 48 | def parsePerfNum(num): | |
| 49 | num = num.replace(b',',b'') | |
| 50 | try: | |
| 51 | return int(num) | |
| 52 | except ValueError: | |
| 53 | return float(num) | |
| 54 | ||
| 55 | def parsePerfLine(line): | |
| 56 | ret = {} | |
| 57 | line = line.split(b'#')[0].strip() | |
| 58 | if len(line) != 0: | |
| 59 | p = line.split() | |
| 60 | ret[p[1].strip().decode('ascii')] = parsePerfNum(p[0]) | |
| 61 | return ret | |
| 62 | ||
| 63 | def parsePerf(output): | |
| 64 | ret = {} | |
| 65 | lines = [x.strip() for x in output.split(b'\n')] | |
| 66 | ||
| 67 | seconds = [x for x in lines if b'seconds time elapsed' in x][0] | |
| 68 | seconds = seconds.strip().split()[0].strip() | |
| 69 | ret['seconds-elapsed'] = parsePerfNum(seconds) | |
| 70 | ||
| 71 | measurement_lines = [x for x in lines if b'#' in x] | |
| 72 | for l in measurement_lines: | |
| 73 | ret.update(parsePerfLine(l)) | |
| 74 | return ret | |
| 75 | ||
| 76 | def run(cmd): | |
| 77 | try: | |
| 78 | return subprocess.check_output(cmd, stderr=subprocess.STDOUT) | |
| 79 | except subprocess.CalledProcessError as e: | |
| 80 | print(e.output) | |
| 81 | raise e | |
| 82 | ||
| 83 | def combinePerfRun(acc, d): | |
| 84 | for k,v in d.items(): | |
| 85 | a = acc.get(k, []) | |
| 86 | a.append(v) | |
| 87 | acc[k] = a | |
| 88 | ||
| 89 | def perf(cmd): | |
| 90 | # Discard the first run to warm up any system cache. | |
| 91 | run(cmd) | |
| 92 | ||
| 93 | ret = {} | |
| 94 | wrapper_args = [x for x in args.wrapper.split(',') if x] | |
| 95 | for i in range(args.runs): | |
| 96 | os.unlink('t') | |
| 97 | out = run(wrapper_args + ['perf', 'stat'] + cmd) | |
| 98 | r = parsePerf(out) | |
| 99 | combinePerfRun(ret, r) | |
| 100 | os.unlink('t') | |
| 101 | return ret | |
| 102 | ||
| 103 | def runBench(bench): | |
| 104 | thread_arg = [] if args.threads else ['--no-threads'] | |
| 105 | os.chdir(bench.directory) | |
| 106 | suffix = '-%s' % bench.variant if bench.variant else '' | |
| 107 | response = 'response' + suffix + '.txt' | |
| 108 | ret = perf(['../ld.lld', '@' + response, '-o', 't'] + thread_arg) | |
| 109 | ret['name'] = str(bench) | |
| 110 | os.chdir('..') | |
| 111 | return ret | |
| 112 | ||
| 113 | def buildLntJson(benchmarks): | |
| 114 | start = datetime.datetime.utcnow().isoformat() | |
| 115 | tests = [runBench(b) for b in benchmarks] | |
| 116 | end = datetime.datetime.utcnow().isoformat() | |
| 117 | ret = { | |
| 118 | 'format_version' : 2, | |
| 119 | 'machine' : { 'name' : args.machine }, | |
| 120 | 'run' : { | |
| 121 | 'end_time' : start, | |
| 122 | 'start_time' : end, | |
| 123 | 'llvm_project_revision': args.revision | |
| 124 | }, | |
| 125 | 'tests' : tests | |
| 126 | } | |
| 127 | return json.dumps(ret, sort_keys=True, indent=4) | |
| 128 | ||
| 129 | def submitToServer(data): | |
| 130 | data2 = urllib.urlencode({ 'input_data' : data }).encode('ascii') | |
| 131 | urllib2.urlopen(urllib2.Request(args.url, data2)) | |
| 132 | ||
| 133 | os.chdir(args.benchmark_directory) | |
| 134 | data = buildLntJson(getBenchmarks()) | |
| 135 | submitToServer(data) |
deps/lld/utils/link.yaml created+39| ... | ... | @@ -0,0 +1,39 @@ |
| 1 | format_version: '2' | |
| 2 | name: link | |
| 3 | run_fields: | |
| 4 | - name: llvm_project_revision | |
| 5 | order: true | |
| 6 | machine_fields: | |
| 7 | - name: hardware | |
| 8 | - name: os | |
| 9 | metrics: | |
| 10 | - name: branch-misses | |
| 11 | bigger_is_better: false | |
| 12 | type: Real | |
| 13 | - name: stalled-cycles-frontend | |
| 14 | bigger_is_better: false | |
| 15 | type: Real | |
| 16 | - name: branches | |
| 17 | bigger_is_better: false | |
| 18 | type: Real | |
| 19 | - name: context-switches | |
| 20 | bigger_is_better: false | |
| 21 | type: Real | |
| 22 | - name: cpu-migrations | |
| 23 | bigger_is_better: false | |
| 24 | type: Real | |
| 25 | - name: cycles | |
| 26 | bigger_is_better: false | |
| 27 | type: Real | |
| 28 | - name: instructions | |
| 29 | bigger_is_better: false | |
| 30 | type: Real | |
| 31 | - name: seconds-elapsed | |
| 32 | bigger_is_better: false | |
| 33 | type: Real | |
| 34 | - name: page-faults | |
| 35 | bigger_is_better: false | |
| 36 | type: Real | |
| 37 | - name: task-clock | |
| 38 | bigger_is_better: false | |
| 39 | type: Real |
deps/lld/wasm/CMakeLists.txt created+26| ... | ... | @@ -0,0 +1,26 @@ |
| 1 | set(LLVM_TARGET_DEFINITIONS Options.td) | |
| 2 | tablegen(LLVM Options.inc -gen-opt-parser-defs) | |
| 3 | add_public_tablegen_target(WasmOptionsTableGen) | |
| 4 | ||
| 5 | add_lld_library(lldWasm | |
| 6 | Driver.cpp | |
| 7 | InputFiles.cpp | |
| 8 | InputSegment.cpp | |
| 9 | OutputSections.cpp | |
| 10 | SymbolTable.cpp | |
| 11 | Symbols.cpp | |
| 12 | Writer.cpp | |
| 13 | WriterUtils.cpp | |
| 14 | ||
| 15 | LINK_COMPONENTS | |
| 16 | ${LLVM_TARGETS_TO_BUILD} | |
| 17 | BinaryFormat | |
| 18 | Core | |
| 19 | Demangle | |
| 20 | Object | |
| 21 | Option | |
| 22 | Support | |
| 23 | ||
| 24 | LINK_LIBS | |
| 25 | lldCommon | |
| 26 | ) |
deps/lld/wasm/Config.h created+51| ... | ... | @@ -0,0 +1,51 @@ |
| 1 | //===- Config.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_CONFIG_H | |
| 11 | #define LLD_WASM_CONFIG_H | |
| 12 | ||
| 13 | #include "llvm/ADT/StringRef.h" | |
| 14 | #include "llvm/ADT/StringSet.h" | |
| 15 | #include "llvm/BinaryFormat/Wasm.h" | |
| 16 | ||
| 17 | #include "Symbols.h" | |
| 18 | ||
| 19 | using llvm::wasm::WasmGlobal; | |
| 20 | ||
| 21 | namespace lld { | |
| 22 | namespace wasm { | |
| 23 | ||
| 24 | struct Configuration { | |
| 25 | bool AllowUndefined; | |
| 26 | bool CheckSignatures; | |
| 27 | bool Demangle; | |
| 28 | bool EmitRelocs; | |
| 29 | bool ImportMemory; | |
| 30 | bool Relocatable; | |
| 31 | bool StripAll; | |
| 32 | bool StripDebug; | |
| 33 | uint32_t GlobalBase; | |
| 34 | uint32_t InitialMemory; | |
| 35 | uint32_t MaxMemory; | |
| 36 | uint32_t ZStackSize; | |
| 37 | llvm::StringRef Entry; | |
| 38 | llvm::StringRef OutputFile; | |
| 39 | ||
| 40 | llvm::StringSet<> AllowUndefinedSymbols; | |
| 41 | std::vector<llvm::StringRef> SearchPaths; | |
| 42 | Symbol *StackPointerSymbol = nullptr; | |
| 43 | }; | |
| 44 | ||
| 45 | // The only instance of Configuration struct. | |
| 46 | extern Configuration *Config; | |
| 47 | ||
| 48 | } // namespace wasm | |
| 49 | } // namespace lld | |
| 50 | ||
| 51 | #endif |
deps/lld/wasm/Driver.cpp created+321| ... | ... | @@ -0,0 +1,321 @@ |
| 1 | //===- Driver.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/Driver.h" | |
| 11 | #include "Config.h" | |
| 12 | #include "SymbolTable.h" | |
| 13 | #include "Writer.h" | |
| 14 | #include "lld/Common/Args.h" | |
| 15 | #include "lld/Common/ErrorHandler.h" | |
| 16 | #include "lld/Common/Memory.h" | |
| 17 | #include "lld/Common/Threads.h" | |
| 18 | #include "lld/Common/Version.h" | |
| 19 | #include "llvm/ADT/Twine.h" | |
| 20 | #include "llvm/Object/Wasm.h" | |
| 21 | #include "llvm/Option/ArgList.h" | |
| 22 | #include "llvm/Support/CommandLine.h" | |
| 23 | #include "llvm/Support/Path.h" | |
| 24 | #include "llvm/Support/Process.h" | |
| 25 | ||
| 26 | using namespace llvm; | |
| 27 | using namespace llvm::sys; | |
| 28 | using namespace llvm::wasm; | |
| 29 | ||
| 30 | using namespace lld; | |
| 31 | using namespace lld::wasm; | |
| 32 | ||
| 33 | namespace { | |
| 34 | ||
| 35 | // Parses command line options. | |
| 36 | class WasmOptTable : public llvm::opt::OptTable { | |
| 37 | public: | |
| 38 | WasmOptTable(); | |
| 39 | llvm::opt::InputArgList parse(ArrayRef<const char *> Argv); | |
| 40 | }; | |
| 41 | ||
| 42 | // Create enum with OPT_xxx values for each option in Options.td | |
| 43 | enum { | |
| 44 | OPT_INVALID = 0, | |
| 45 | #define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID, | |
| 46 | #include "Options.inc" | |
| 47 | #undef OPTION | |
| 48 | }; | |
| 49 | ||
| 50 | class LinkerDriver { | |
| 51 | public: | |
| 52 | void link(ArrayRef<const char *> ArgsArr); | |
| 53 | ||
| 54 | private: | |
| 55 | void createFiles(llvm::opt::InputArgList &Args); | |
| 56 | void addFile(StringRef Path); | |
| 57 | void addLibrary(StringRef Name); | |
| 58 | std::vector<InputFile *> Files; | |
| 59 | }; | |
| 60 | ||
| 61 | } // anonymous namespace | |
| 62 | ||
| 63 | Configuration *lld::wasm::Config; | |
| 64 | ||
| 65 | bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly, | |
| 66 | raw_ostream &Error) { | |
| 67 | errorHandler().LogName = Args[0]; | |
| 68 | errorHandler().ErrorOS = &Error; | |
| 69 | errorHandler().ColorDiagnostics = Error.has_colors(); | |
| 70 | errorHandler().ErrorLimitExceededMsg = | |
| 71 | "too many errors emitted, stopping now (use " | |
| 72 | "-error-limit=0 to see all errors)"; | |
| 73 | ||
| 74 | Config = make<Configuration>(); | |
| 75 | Symtab = make<SymbolTable>(); | |
| 76 | ||
| 77 | LinkerDriver().link(Args); | |
| 78 | ||
| 79 | // Exit immediately if we don't need to return to the caller. | |
| 80 | // This saves time because the overhead of calling destructors | |
| 81 | // for all globally-allocated objects is not negligible. | |
| 82 | if (CanExitEarly) | |
| 83 | exitLld(errorCount() ? 1 : 0); | |
| 84 | ||
| 85 | freeArena(); | |
| 86 | return !errorCount(); | |
| 87 | } | |
| 88 | ||
| 89 | // Create OptTable | |
| 90 | ||
| 91 | // Create prefix string literals used in Options.td | |
| 92 | #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; | |
| 93 | #include "Options.inc" | |
| 94 | #undef PREFIX | |
| 95 | ||
| 96 | // Create table mapping all options defined in Options.td | |
| 97 | static const opt::OptTable::Info OptInfo[] = { | |
| 98 | #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ | |
| 99 | {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \ | |
| 100 | X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12}, | |
| 101 | #include "Options.inc" | |
| 102 | #undef OPTION | |
| 103 | }; | |
| 104 | ||
| 105 | // Set color diagnostics according to -color-diagnostics={auto,always,never} | |
| 106 | // or -no-color-diagnostics flags. | |
| 107 | static void handleColorDiagnostics(opt::InputArgList &Args) { | |
| 108 | auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq, | |
| 109 | OPT_no_color_diagnostics); | |
| 110 | if (!Arg) | |
| 111 | return; | |
| 112 | ||
| 113 | if (Arg->getOption().getID() == OPT_color_diagnostics) | |
| 114 | errorHandler().ColorDiagnostics = true; | |
| 115 | else if (Arg->getOption().getID() == OPT_no_color_diagnostics) | |
| 116 | errorHandler().ColorDiagnostics = false; | |
| 117 | else { | |
| 118 | StringRef S = Arg->getValue(); | |
| 119 | if (S == "always") | |
| 120 | errorHandler().ColorDiagnostics = true; | |
| 121 | if (S == "never") | |
| 122 | errorHandler().ColorDiagnostics = false; | |
| 123 | if (S != "auto") | |
| 124 | error("unknown option: -color-diagnostics=" + S); | |
| 125 | } | |
| 126 | } | |
| 127 | ||
| 128 | // Find a file by concatenating given paths. | |
| 129 | static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) { | |
| 130 | SmallString<128> S; | |
| 131 | path::append(S, Path1, Path2); | |
| 132 | if (fs::exists(S)) | |
| 133 | return S.str().str(); | |
| 134 | return None; | |
| 135 | } | |
| 136 | ||
| 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) { | |
| 152 | SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size()); | |
| 153 | ||
| 154 | unsigned MissingIndex; | |
| 155 | unsigned MissingCount; | |
| 156 | opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount); | |
| 157 | ||
| 158 | handleColorDiagnostics(Args); | |
| 159 | for (auto *Arg : Args.filtered(OPT_UNKNOWN)) | |
| 160 | error("unknown argument: " + Arg->getSpelling()); | |
| 161 | return Args; | |
| 162 | } | |
| 163 | ||
| 164 | void LinkerDriver::addFile(StringRef Path) { | |
| 165 | Optional<MemoryBufferRef> Buffer = readFile(Path); | |
| 166 | if (!Buffer.hasValue()) | |
| 167 | return; | |
| 168 | MemoryBufferRef MBRef = *Buffer; | |
| 169 | ||
| 170 | if (identify_magic(MBRef.getBuffer()) == file_magic::archive) | |
| 171 | Files.push_back(make<ArchiveFile>(MBRef)); | |
| 172 | else | |
| 173 | Files.push_back(make<ObjFile>(MBRef)); | |
| 174 | } | |
| 175 | ||
| 176 | // Add a given library by searching it from input search paths. | |
| 177 | void LinkerDriver::addLibrary(StringRef Name) { | |
| 178 | for (StringRef Dir : Config->SearchPaths) { | |
| 179 | if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".a")) { | |
| 180 | addFile(*S); | |
| 181 | return; | |
| 182 | } | |
| 183 | } | |
| 184 | ||
| 185 | error("unable to find library -l" + Name); | |
| 186 | } | |
| 187 | ||
| 188 | void LinkerDriver::createFiles(opt::InputArgList &Args) { | |
| 189 | for (auto *Arg : Args) { | |
| 190 | switch (Arg->getOption().getUnaliasedOption().getID()) { | |
| 191 | case OPT_l: | |
| 192 | addLibrary(Arg->getValue()); | |
| 193 | break; | |
| 194 | case OPT_INPUT: | |
| 195 | addFile(Arg->getValue()); | |
| 196 | break; | |
| 197 | } | |
| 198 | } | |
| 199 | ||
| 200 | if (Files.empty()) | |
| 201 | error("no input files"); | |
| 202 | } | |
| 203 | ||
| 204 | static StringRef getEntry(opt::InputArgList &Args, StringRef Default) { | |
| 205 | auto *Arg = Args.getLastArg(OPT_entry, OPT_no_entry); | |
| 206 | if (!Arg) | |
| 207 | return Default; | |
| 208 | if (Arg->getOption().getID() == OPT_no_entry) | |
| 209 | return ""; | |
| 210 | return Arg->getValue(); | |
| 211 | } | |
| 212 | ||
| 213 | void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | |
| 214 | WasmOptTable Parser; | |
| 215 | opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); | |
| 216 | ||
| 217 | // Handle --help | |
| 218 | if (Args.hasArg(OPT_help)) { | |
| 219 | printHelp(ArgsArr[0]); | |
| 220 | return; | |
| 221 | } | |
| 222 | ||
| 223 | // Parse and evaluate -mllvm options. | |
| 224 | std::vector<const char *> V; | |
| 225 | V.push_back("wasm-ld (LLVM option parsing)"); | |
| 226 | for (auto *Arg : Args.filtered(OPT_mllvm)) | |
| 227 | V.push_back(Arg->getValue()); | |
| 228 | cl::ParseCommandLineOptions(V.size(), V.data()); | |
| 229 | ||
| 230 | errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20); | |
| 231 | ||
| 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); | |
| 238 | Config->CheckSignatures = | |
| 239 | Args.hasFlag(OPT_check_signatures, OPT_no_check_signatures, false); | |
| 240 | Config->EmitRelocs = Args.hasArg(OPT_emit_relocs); | |
| 241 | Config->Entry = getEntry(Args, Args.hasArg(OPT_relocatable) ? "" : "_start"); | |
| 242 | Config->ImportMemory = Args.hasArg(OPT_import_memory); | |
| 243 | Config->OutputFile = Args.getLastArgValue(OPT_o); | |
| 244 | Config->Relocatable = Args.hasArg(OPT_relocatable); | |
| 245 | Config->SearchPaths = args::getStrings(Args, OPT_L); | |
| 246 | Config->StripAll = Args.hasArg(OPT_strip_all); | |
| 247 | Config->StripDebug = Args.hasArg(OPT_strip_debug); | |
| 248 | errorHandler().Verbose = Args.hasArg(OPT_verbose); | |
| 249 | ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true); | |
| 250 | if (Config->Relocatable) | |
| 251 | Config->EmitRelocs = true; | |
| 252 | ||
| 253 | Config->InitialMemory = args::getInteger(Args, OPT_initial_memory, 0); | |
| 254 | Config->GlobalBase = args::getInteger(Args, OPT_global_base, 1024); | |
| 255 | Config->MaxMemory = args::getInteger(Args, OPT_max_memory, 0); | |
| 256 | Config->ZStackSize = | |
| 257 | args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize); | |
| 258 | ||
| 259 | if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file)) | |
| 260 | if (Optional<MemoryBufferRef> Buf = readFile(Arg->getValue())) | |
| 261 | for (StringRef Sym : args::getLines(*Buf)) | |
| 262 | Config->AllowUndefinedSymbols.insert(Sym); | |
| 263 | ||
| 264 | if (Config->OutputFile.empty()) | |
| 265 | error("no output file specified"); | |
| 266 | ||
| 267 | if (!Args.hasArg(OPT_INPUT)) | |
| 268 | error("no input files"); | |
| 269 | ||
| 270 | if (Config->Relocatable && !Config->Entry.empty()) | |
| 271 | error("entry point specified for relocatable output file"); | |
| 272 | if (Config->Relocatable && Args.hasArg(OPT_undefined)) | |
| 273 | error("undefined symbols specified for relocatable output file"); | |
| 274 | ||
| 275 | if (!Config->Relocatable) { | |
| 276 | if (!Config->Entry.empty()) { | |
| 277 | static WasmSignature Signature = {{}, WASM_TYPE_NORESULT}; | |
| 278 | addSyntheticUndefinedFunction(Config->Entry, &Signature); | |
| 279 | } | |
| 280 | ||
| 281 | // Handle the `--undefined <sym>` options. | |
| 282 | for (StringRef S : args::getStrings(Args, OPT_undefined)) | |
| 283 | addSyntheticUndefinedFunction(S, nullptr); | |
| 284 | ||
| 285 | Config->StackPointerSymbol = Symtab->addDefinedGlobal("__stack_pointer"); | |
| 286 | } | |
| 287 | ||
| 288 | createFiles(Args); | |
| 289 | if (errorCount()) | |
| 290 | return; | |
| 291 | ||
| 292 | // Add all files to the symbol table. This will add almost all | |
| 293 | // symbols that we need to the symbol table. | |
| 294 | for (InputFile *F : Files) | |
| 295 | Symtab->addFile(F); | |
| 296 | ||
| 297 | // Make sure we have resolved all symbols. | |
| 298 | if (!Config->Relocatable && !Config->AllowUndefined) { | |
| 299 | Symtab->reportRemainingUndefines(); | |
| 300 | } else { | |
| 301 | // When we allow undefined symbols we cannot include those defined in | |
| 302 | // -u/--undefined since these undefined symbols have only names and no | |
| 303 | // function signature, which means they cannot be written to the final | |
| 304 | // output. | |
| 305 | for (StringRef S : args::getStrings(Args, OPT_undefined)) { | |
| 306 | Symbol *Sym = Symtab->find(S); | |
| 307 | if (!Sym->isDefined()) | |
| 308 | error("function forced with --undefined not found: " + Sym->getName()); | |
| 309 | } | |
| 310 | } | |
| 311 | if (errorCount()) | |
| 312 | return; | |
| 313 | ||
| 314 | if (!Config->Entry.empty() && !Symtab->find(Config->Entry)->isDefined()) | |
| 315 | error("entry point not found: " + Config->Entry); | |
| 316 | if (errorCount()) | |
| 317 | return; | |
| 318 | ||
| 319 | // Write the result to the file. | |
| 320 | writeResult(); | |
| 321 | } |
deps/lld/wasm/InputFiles.cpp created+312| ... | ... | @@ -0,0 +1,312 @@ |
| 1 | //===- InputFiles.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 | ||
| 12 | #include "Config.h" | |
| 13 | #include "InputSegment.h" | |
| 14 | #include "SymbolTable.h" | |
| 15 | #include "lld/Common/ErrorHandler.h" | |
| 16 | #include "lld/Common/Memory.h" | |
| 17 | #include "llvm/Object/Binary.h" | |
| 18 | #include "llvm/Object/Wasm.h" | |
| 19 | #include "llvm/Support/raw_ostream.h" | |
| 20 | ||
| 21 | #define DEBUG_TYPE "lld" | |
| 22 | ||
| 23 | using namespace lld; | |
| 24 | using namespace lld::wasm; | |
| 25 | ||
| 26 | using namespace llvm; | |
| 27 | using namespace llvm::object; | |
| 28 | using namespace llvm::wasm; | |
| 29 | ||
| 30 | Optional<MemoryBufferRef> lld::wasm::readFile(StringRef Path) { | |
| 31 | log("Loading: " + Path); | |
| 32 | ||
| 33 | auto MBOrErr = MemoryBuffer::getFile(Path); | |
| 34 | if (auto EC = MBOrErr.getError()) { | |
| 35 | error("cannot open " + Path + ": " + EC.message()); | |
| 36 | return None; | |
| 37 | } | |
| 38 | std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; | |
| 39 | MemoryBufferRef MBRef = MB->getMemBufferRef(); | |
| 40 | make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take MB ownership | |
| 41 | ||
| 42 | return MBRef; | |
| 43 | } | |
| 44 | ||
| 45 | void ObjFile::dumpInfo() const { | |
| 46 | log("reloc info for: " + getName() + "\n" + | |
| 47 | " FunctionIndexOffset : " + Twine(FunctionIndexOffset) + "\n" + | |
| 48 | " NumFunctionImports : " + Twine(NumFunctionImports()) + "\n" + | |
| 49 | " NumGlobalImports : " + Twine(NumGlobalImports()) + "\n"); | |
| 50 | } | |
| 51 | ||
| 52 | bool ObjFile::isImportedFunction(uint32_t Index) const { | |
| 53 | return Index < NumFunctionImports(); | |
| 54 | } | |
| 55 | ||
| 56 | Symbol *ObjFile::getFunctionSymbol(uint32_t Index) const { | |
| 57 | return FunctionSymbols[Index]; | |
| 58 | } | |
| 59 | ||
| 60 | Symbol *ObjFile::getTableSymbol(uint32_t Index) const { | |
| 61 | return TableSymbols[Index]; | |
| 62 | } | |
| 63 | ||
| 64 | Symbol *ObjFile::getGlobalSymbol(uint32_t Index) const { | |
| 65 | return GlobalSymbols[Index]; | |
| 66 | } | |
| 67 | ||
| 68 | uint32_t ObjFile::getRelocatedAddress(uint32_t Index) const { | |
| 69 | return getGlobalSymbol(Index)->getVirtualAddress(); | |
| 70 | } | |
| 71 | ||
| 72 | uint32_t ObjFile::relocateFunctionIndex(uint32_t Original) const { | |
| 73 | Symbol *Sym = getFunctionSymbol(Original); | |
| 74 | uint32_t Index = Sym->getOutputIndex(); | |
| 75 | DEBUG(dbgs() << "relocateFunctionIndex: " << toString(*Sym) << ": " | |
| 76 | << Original << " -> " << Index << "\n"); | |
| 77 | return Index; | |
| 78 | } | |
| 79 | ||
| 80 | uint32_t ObjFile::relocateTypeIndex(uint32_t Original) const { | |
| 81 | return TypeMap[Original]; | |
| 82 | } | |
| 83 | ||
| 84 | uint32_t ObjFile::relocateTableIndex(uint32_t Original) const { | |
| 85 | Symbol *Sym = getTableSymbol(Original); | |
| 86 | uint32_t Index = Sym->getTableIndex(); | |
| 87 | DEBUG(dbgs() << "relocateTableIndex: " << toString(*Sym) << ": " << Original | |
| 88 | << " -> " << Index << "\n"); | |
| 89 | return Index; | |
| 90 | } | |
| 91 | ||
| 92 | uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const { | |
| 93 | Symbol *Sym = getGlobalSymbol(Original); | |
| 94 | uint32_t Index = Sym->getOutputIndex(); | |
| 95 | DEBUG(dbgs() << "relocateGlobalIndex: " << toString(*Sym) << ": " << Original | |
| 96 | << " -> " << Index << "\n"); | |
| 97 | return Index; | |
| 98 | } | |
| 99 | ||
| 100 | void ObjFile::parse() { | |
| 101 | // Parse a memory buffer as a wasm file. | |
| 102 | DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n"); | |
| 103 | std::unique_ptr<Binary> Bin = CHECK(createBinary(MB), toString(this)); | |
| 104 | ||
| 105 | auto *Obj = dyn_cast<WasmObjectFile>(Bin.get()); | |
| 106 | if (!Obj) | |
| 107 | fatal(toString(this) + ": not a wasm file"); | |
| 108 | if (!Obj->isRelocatableObject()) | |
| 109 | fatal(toString(this) + ": not a relocatable wasm file"); | |
| 110 | ||
| 111 | Bin.release(); | |
| 112 | WasmObj.reset(Obj); | |
| 113 | ||
| 114 | // Find the code and data sections. Wasm objects can have at most one code | |
| 115 | // and one data section. | |
| 116 | for (const SectionRef &Sec : WasmObj->sections()) { | |
| 117 | const WasmSection &Section = WasmObj->getWasmSection(Sec); | |
| 118 | if (Section.Type == WASM_SEC_CODE) | |
| 119 | CodeSection = &Section; | |
| 120 | else if (Section.Type == WASM_SEC_DATA) | |
| 121 | DataSection = &Section; | |
| 122 | } | |
| 123 | ||
| 124 | initializeSymbols(); | |
| 125 | } | |
| 126 | ||
| 127 | // Return the InputSegment in which a given symbol is defined. | |
| 128 | InputSegment *ObjFile::getSegment(const WasmSymbol &WasmSym) { | |
| 129 | uint32_t Address = WasmObj->getWasmSymbolValue(WasmSym); | |
| 130 | for (InputSegment *Segment : Segments) { | |
| 131 | if (Address >= Segment->startVA() && Address < Segment->endVA()) { | |
| 132 | DEBUG(dbgs() << "Found symbol in segment: " << WasmSym.Name << " -> " | |
| 133 | << Segment->getName() << "\n"); | |
| 134 | ||
| 135 | return Segment; | |
| 136 | } | |
| 137 | } | |
| 138 | error("symbol not found in any segment: " + WasmSym.Name); | |
| 139 | return nullptr; | |
| 140 | } | |
| 141 | ||
| 142 | static void copyRelocationsRange(std::vector<WasmRelocation> &To, | |
| 143 | ArrayRef<WasmRelocation> From, size_t Start, | |
| 144 | size_t End) { | |
| 145 | for (const WasmRelocation &R : From) | |
| 146 | if (R.Offset >= Start && R.Offset < End) | |
| 147 | To.push_back(R); | |
| 148 | } | |
| 149 | ||
| 150 | void ObjFile::initializeSymbols() { | |
| 151 | Symbols.reserve(WasmObj->getNumberOfSymbols()); | |
| 152 | ||
| 153 | for (const WasmImport &Import : WasmObj->imports()) { | |
| 154 | switch (Import.Kind) { | |
| 155 | case WASM_EXTERNAL_FUNCTION: | |
| 156 | ++FunctionImports; | |
| 157 | break; | |
| 158 | case WASM_EXTERNAL_GLOBAL: | |
| 159 | ++GlobalImports; | |
| 160 | break; | |
| 161 | } | |
| 162 | } | |
| 163 | ||
| 164 | FunctionSymbols.resize(FunctionImports + WasmObj->functions().size()); | |
| 165 | GlobalSymbols.resize(GlobalImports + WasmObj->globals().size()); | |
| 166 | ||
| 167 | for (const WasmSegment &S : WasmObj->dataSegments()) { | |
| 168 | InputSegment *Seg = make<InputSegment>(&S, this); | |
| 169 | copyRelocationsRange(Seg->Relocations, DataSection->Relocations, | |
| 170 | Seg->getInputSectionOffset(), | |
| 171 | Seg->getInputSectionOffset() + Seg->getSize()); | |
| 172 | Segments.emplace_back(Seg); | |
| 173 | } | |
| 174 | ||
| 175 | // Populate `FunctionSymbols` and `GlobalSymbols` based on the WasmSymbols | |
| 176 | // in the object | |
| 177 | for (const SymbolRef &Sym : WasmObj->symbols()) { | |
| 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 | ||
| 196 | Symbols.push_back(S); | |
| 197 | if (WasmSym.isFunction()) { | |
| 198 | DEBUG(dbgs() << "Function: " << WasmSym.ElementIndex << " -> " | |
| 199 | << toString(*S) << "\n"); | |
| 200 | FunctionSymbols[WasmSym.ElementIndex] = S; | |
| 201 | if (WasmSym.HasAltIndex) | |
| 202 | FunctionSymbols[WasmSym.AltIndex] = S; | |
| 203 | } else { | |
| 204 | DEBUG(dbgs() << "Global: " << WasmSym.ElementIndex << " -> " | |
| 205 | << toString(*S) << "\n"); | |
| 206 | GlobalSymbols[WasmSym.ElementIndex] = S; | |
| 207 | if (WasmSym.HasAltIndex) | |
| 208 | GlobalSymbols[WasmSym.AltIndex] = S; | |
| 209 | } | |
| 210 | } | |
| 211 | ||
| 212 | DEBUG(for (size_t I = 0; I < FunctionSymbols.size(); ++I) | |
| 213 | assert(FunctionSymbols[I] != nullptr); | |
| 214 | for (size_t I = 0; I < GlobalSymbols.size(); ++I) | |
| 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 | } | |
| 233 | ||
| 234 | DEBUG(dbgs() << "TableSymbols: " << TableSymbols.size() << "\n"); | |
| 235 | DEBUG(dbgs() << "Functions : " << FunctionSymbols.size() << "\n"); | |
| 236 | DEBUG(dbgs() << "Globals : " << GlobalSymbols.size() << "\n"); | |
| 237 | } | |
| 238 | ||
| 239 | Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) { | |
| 240 | return Symtab->addUndefined(this, &Sym); | |
| 241 | } | |
| 242 | ||
| 243 | Symbol *ObjFile::createDefined(const WasmSymbol &Sym, | |
| 244 | const InputSegment *Segment) { | |
| 245 | Symbol *S; | |
| 246 | if (Sym.isLocal()) { | |
| 247 | S = make<Symbol>(Sym.Name, true); | |
| 248 | Symbol::Kind Kind; | |
| 249 | if (Sym.Type == WasmSymbol::SymbolType::FUNCTION_EXPORT) | |
| 250 | Kind = Symbol::Kind::DefinedFunctionKind; | |
| 251 | else if (Sym.Type == WasmSymbol::SymbolType::GLOBAL_EXPORT) | |
| 252 | Kind = Symbol::Kind::DefinedGlobalKind; | |
| 253 | else | |
| 254 | llvm_unreachable("invalid local symbol type"); | |
| 255 | S->update(Kind, this, &Sym, Segment); | |
| 256 | return S; | |
| 257 | } | |
| 258 | return Symtab->addDefined(this, &Sym, Segment); | |
| 259 | } | |
| 260 | ||
| 261 | void ArchiveFile::parse() { | |
| 262 | // Parse a MemoryBufferRef as an archive file. | |
| 263 | DEBUG(dbgs() << "Parsing library: " << toString(this) << "\n"); | |
| 264 | File = CHECK(Archive::create(MB), toString(this)); | |
| 265 | ||
| 266 | // Read the symbol table to construct Lazy symbols. | |
| 267 | int Count = 0; | |
| 268 | for (const Archive::Symbol &Sym : File->symbols()) { | |
| 269 | Symtab->addLazy(this, &Sym); | |
| 270 | ++Count; | |
| 271 | } | |
| 272 | DEBUG(dbgs() << "Read " << Count << " symbols\n"); | |
| 273 | } | |
| 274 | ||
| 275 | void ArchiveFile::addMember(const Archive::Symbol *Sym) { | |
| 276 | const Archive::Child &C = | |
| 277 | CHECK(Sym->getMember(), | |
| 278 | "could not get the member for symbol " + Sym->getName()); | |
| 279 | ||
| 280 | // Don't try to load the same member twice (this can happen when members | |
| 281 | // mutually reference each other). | |
| 282 | if (!Seen.insert(C.getChildOffset()).second) | |
| 283 | return; | |
| 284 | ||
| 285 | DEBUG(dbgs() << "loading lazy: " << Sym->getName() << "\n"); | |
| 286 | DEBUG(dbgs() << "from archive: " << toString(this) << "\n"); | |
| 287 | ||
| 288 | MemoryBufferRef MB = | |
| 289 | CHECK(C.getMemoryBufferRef(), | |
| 290 | "could not get the buffer for the member defining symbol " + | |
| 291 | Sym->getName()); | |
| 292 | ||
| 293 | if (identify_magic(MB.getBuffer()) != file_magic::wasm_object) { | |
| 294 | error("unknown file type: " + MB.getBufferIdentifier()); | |
| 295 | return; | |
| 296 | } | |
| 297 | ||
| 298 | InputFile *Obj = make<ObjFile>(MB); | |
| 299 | Obj->ParentName = ParentName; | |
| 300 | Symtab->addFile(Obj); | |
| 301 | } | |
| 302 | ||
| 303 | // Returns a string in the format of "foo.o" or "foo.a(bar.o)". | |
| 304 | std::string lld::toString(const wasm::InputFile *File) { | |
| 305 | if (!File) | |
| 306 | return "<internal>"; | |
| 307 | ||
| 308 | if (File->ParentName.empty()) | |
| 309 | return File->getName(); | |
| 310 | ||
| 311 | return (File->ParentName + "(" + File->getName() + ")").str(); | |
| 312 | } |
deps/lld/wasm/InputFiles.h created+153| ... | ... | @@ -0,0 +1,153 @@ |
| 1 | //===- InputFiles.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_FILES_H | |
| 11 | #define LLD_WASM_INPUT_FILES_H | |
| 12 | ||
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | #include "llvm/ADT/DenseMap.h" | |
| 15 | #include "llvm/ADT/DenseSet.h" | |
| 16 | #include "llvm/Object/Archive.h" | |
| 17 | #include "llvm/Object/Wasm.h" | |
| 18 | #include "llvm/Support/MemoryBuffer.h" | |
| 19 | ||
| 20 | #include "WriterUtils.h" | |
| 21 | ||
| 22 | #include <vector> | |
| 23 | ||
| 24 | using llvm::object::Archive; | |
| 25 | using llvm::object::WasmObjectFile; | |
| 26 | using llvm::object::WasmSection; | |
| 27 | using llvm::object::WasmSymbol; | |
| 28 | using llvm::wasm::WasmImport; | |
| 29 | ||
| 30 | namespace lld { | |
| 31 | namespace wasm { | |
| 32 | ||
| 33 | class Symbol; | |
| 34 | class InputSegment; | |
| 35 | ||
| 36 | class InputFile { | |
| 37 | public: | |
| 38 | enum Kind { | |
| 39 | ObjectKind, | |
| 40 | ArchiveKind, | |
| 41 | }; | |
| 42 | ||
| 43 | virtual ~InputFile() {} | |
| 44 | ||
| 45 | // Returns the filename. | |
| 46 | StringRef getName() const { return MB.getBufferIdentifier(); } | |
| 47 | ||
| 48 | // Reads a file (the constructor doesn't do that). | |
| 49 | virtual void parse() = 0; | |
| 50 | ||
| 51 | Kind kind() const { return FileKind; } | |
| 52 | ||
| 53 | // An archive file name if this file is created from an archive. | |
| 54 | StringRef ParentName; | |
| 55 | ||
| 56 | protected: | |
| 57 | InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} | |
| 58 | MemoryBufferRef MB; | |
| 59 | ||
| 60 | private: | |
| 61 | const Kind FileKind; | |
| 62 | }; | |
| 63 | ||
| 64 | // .a file (ar archive) | |
| 65 | class ArchiveFile : public InputFile { | |
| 66 | public: | |
| 67 | explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {} | |
| 68 | static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; } | |
| 69 | ||
| 70 | void addMember(const Archive::Symbol *Sym); | |
| 71 | ||
| 72 | void parse() override; | |
| 73 | ||
| 74 | private: | |
| 75 | std::unique_ptr<Archive> File; | |
| 76 | llvm::DenseSet<uint64_t> Seen; | |
| 77 | }; | |
| 78 | ||
| 79 | // .o file (wasm object file) | |
| 80 | class ObjFile : public InputFile { | |
| 81 | public: | |
| 82 | explicit ObjFile(MemoryBufferRef M) : InputFile(ObjectKind, M) {} | |
| 83 | static bool classof(const InputFile *F) { return F->kind() == ObjectKind; } | |
| 84 | ||
| 85 | void parse() override; | |
| 86 | ||
| 87 | // Returns the underlying wasm file. | |
| 88 | const WasmObjectFile *getWasmObj() const { return WasmObj.get(); } | |
| 89 | ||
| 90 | void dumpInfo() const; | |
| 91 | ||
| 92 | uint32_t relocateTypeIndex(uint32_t Original) const; | |
| 93 | uint32_t relocateFunctionIndex(uint32_t Original) const; | |
| 94 | uint32_t relocateGlobalIndex(uint32_t Original) const; | |
| 95 | uint32_t relocateTableIndex(uint32_t Original) 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 | ||
| 105 | int32_t FunctionIndexOffset = 0; | |
| 106 | const WasmSection *CodeSection = nullptr; | |
| 107 | std::vector<OutputRelocation> CodeRelocations; | |
| 108 | int32_t CodeOffset = 0; | |
| 109 | const WasmSection *DataSection = nullptr; | |
| 110 | ||
| 111 | std::vector<uint32_t> TypeMap; | |
| 112 | std::vector<InputSegment *> Segments; | |
| 113 | ||
| 114 | ArrayRef<Symbol *> getSymbols() { return Symbols; } | |
| 115 | ArrayRef<Symbol *> getTableSymbols() { return TableSymbols; } | |
| 116 | ||
| 117 | private: | |
| 118 | Symbol *createDefined(const WasmSymbol &Sym, | |
| 119 | const InputSegment *Segment = nullptr); | |
| 120 | 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 | ||
| 127 | // List of all symbols referenced or defined by this file. | |
| 128 | std::vector<Symbol *> Symbols; | |
| 129 | ||
| 130 | // List of all function symbols indexed by the function index space | |
| 131 | std::vector<Symbol *> FunctionSymbols; | |
| 132 | ||
| 133 | // List of all global symbols indexed by the global index space | |
| 134 | std::vector<Symbol *> GlobalSymbols; | |
| 135 | ||
| 136 | // List of all indirect symbols indexed by table index space. | |
| 137 | std::vector<Symbol *> TableSymbols; | |
| 138 | ||
| 139 | uint32_t GlobalImports = 0; | |
| 140 | uint32_t FunctionImports = 0; | |
| 141 | std::unique_ptr<WasmObjectFile> WasmObj; | |
| 142 | }; | |
| 143 | ||
| 144 | // Opens a given file. | |
| 145 | llvm::Optional<MemoryBufferRef> readFile(StringRef Path); | |
| 146 | ||
| 147 | } // namespace wasm | |
| 148 | ||
| 149 | std::string toString(const wasm::InputFile *File); | |
| 150 | ||
| 151 | } // namespace lld | |
| 152 | ||
| 153 | #endif |
deps/lld/wasm/InputSegment.cpp created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 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 created+76| ... | ... | @@ -0,0 +1,76 @@ |
| 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/Options.td created+103| ... | ... | @@ -0,0 +1,103 @@ |
| 1 | include "llvm/Option/OptParser.td" | |
| 2 | ||
| 3 | // For options whose names are multiple letters, either one dash or | |
| 4 | // two can precede the option name except those that start with 'o'. | |
| 5 | class F<string name>: Flag<["--", "-"], name>; | |
| 6 | class J<string name>: Joined<["--", "-"], name>; | |
| 7 | class S<string name>: Separate<["--", "-"], name>; | |
| 8 | ||
| 9 | multiclass Eq<string name> { | |
| 10 | def "": Separate<["--", "-"], name>; | |
| 11 | def _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>; | |
| 12 | } | |
| 13 | ||
| 14 | def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">, | |
| 15 | HelpText<"Add a directory to the library search path">; | |
| 16 | ||
| 17 | def color_diagnostics: F<"color-diagnostics">, | |
| 18 | HelpText<"Use colors in diagnostics">; | |
| 19 | ||
| 20 | def color_diagnostics_eq: J<"color-diagnostics=">, | |
| 21 | HelpText<"Use colors in diagnostics">; | |
| 22 | ||
| 23 | // The follow flags are shared with the ELF linker | |
| 24 | def help: F<"help">, HelpText<"Print option help">; | |
| 25 | ||
| 26 | def l: JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">, | |
| 27 | HelpText<"Root name of library to use">; | |
| 28 | ||
| 29 | def mllvm: S<"mllvm">, HelpText<"Options to pass to LLVM">; | |
| 30 | ||
| 31 | def no_threads: F<"no-threads">, | |
| 32 | HelpText<"Do not run the linker multi-threaded">; | |
| 33 | ||
| 34 | def no_color_diagnostics: F<"no-color-diagnostics">, | |
| 35 | HelpText<"Do not use colors in diagnostics">; | |
| 36 | ||
| 37 | def no_check_signatures: F<"no-check-signatures">, HelpText<"Don't check function signatures">; | |
| 38 | ||
| 39 | def o: JoinedOrSeparate<["-"], "o">, MetaVarName<"<path>">, | |
| 40 | HelpText<"Path to file to write output">; | |
| 41 | ||
| 42 | def threads: F<"threads">, HelpText<"Run the linker multi-threaded">; | |
| 43 | ||
| 44 | def check_signatures: F<"check-signatures">, HelpText<"Check function signatures">; | |
| 45 | ||
| 46 | def v: Flag<["-"], "v">, HelpText<"Display the version number">; | |
| 47 | ||
| 48 | def version: F<"version">, HelpText<"Display the version number and exit">; | |
| 49 | ||
| 50 | def verbose: F<"verbose">, HelpText<"Verbose mode">; | |
| 51 | ||
| 52 | def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">; | |
| 53 | ||
| 54 | def emit_relocs: F<"emit-relocs">, HelpText<"Generate relocations in output">; | |
| 55 | ||
| 56 | def strip_all: F<"strip-all">, HelpText<"Strip all symbols">; | |
| 57 | ||
| 58 | def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">; | |
| 59 | ||
| 60 | defm undefined: Eq<"undefined">, | |
| 61 | HelpText<"Force undefined symbol during linking">; | |
| 62 | ||
| 63 | def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">, | |
| 64 | HelpText<"Linker option extensions">; | |
| 65 | ||
| 66 | def entry: S<"entry">, MetaVarName<"<entry>">, | |
| 67 | HelpText<"Name of entry point symbol">; | |
| 68 | ||
| 69 | def no_entry: F<"no-entry">, | |
| 70 | HelpText<"Do not output any entry point">; | |
| 71 | ||
| 72 | def error_limit: J<"error-limit=">, | |
| 73 | HelpText<"Maximum number of errors to emit before stopping (0 = no limit)">; | |
| 74 | ||
| 75 | // The follow flags are unique to wasm | |
| 76 | ||
| 77 | def global_base: J<"global-base=">, | |
| 78 | HelpText<"Where to start to place global data">; | |
| 79 | ||
| 80 | def initial_memory: J<"initial-memory=">, | |
| 81 | HelpText<"Initial size of the linear memory">; | |
| 82 | ||
| 83 | def max_memory: J<"max-memory=">, | |
| 84 | HelpText<"Maximum size of the linear memory">; | |
| 85 | ||
| 86 | def import_memory: F<"import-memory">, | |
| 87 | HelpText<"Import memory from the environment">; | |
| 88 | ||
| 89 | def allow_undefined: F<"allow-undefined">, | |
| 90 | HelpText<"Allow undefined symbols in linked binary">; | |
| 91 | ||
| 92 | def allow_undefined_file: J<"allow-undefined-file=">, | |
| 93 | HelpText<"Allow symbols listed in <file> to be undefined in linked binary">; | |
| 94 | ||
| 95 | def allow_undefined_file_s: Separate<["-"], "allow-undefined-file">, Alias<allow_undefined_file>; | |
| 96 | ||
| 97 | // Aliases | |
| 98 | def alias_initial_memory_i: Flag<["-"], "i">, Alias<initial_memory>; | |
| 99 | def alias_max_memory_m: Flag<["-"], "m">, Alias<max_memory>; | |
| 100 | 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>; |
deps/lld/wasm/OutputSections.cpp created+348| ... | ... | @@ -0,0 +1,348 @@ |
| 1 | //===- OutputSections.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 "OutputSections.h" | |
| 11 | ||
| 12 | #include "Config.h" | |
| 13 | #include "InputFiles.h" | |
| 14 | #include "OutputSegment.h" | |
| 15 | #include "SymbolTable.h" | |
| 16 | #include "lld/Common/ErrorHandler.h" | |
| 17 | #include "lld/Common/Memory.h" | |
| 18 | #include "lld/Common/Threads.h" | |
| 19 | #include "llvm/ADT/Twine.h" | |
| 20 | #include "llvm/Support/LEB128.h" | |
| 21 | ||
| 22 | #define DEBUG_TYPE "lld" | |
| 23 | ||
| 24 | using namespace llvm; | |
| 25 | using namespace llvm::wasm; | |
| 26 | using namespace lld; | |
| 27 | using namespace lld::wasm; | |
| 28 | ||
| 29 | enum class RelocEncoding { | |
| 30 | Uleb128, | |
| 31 | Sleb128, | |
| 32 | I32, | |
| 33 | }; | |
| 34 | ||
| 35 | static StringRef sectionTypeToString(uint32_t SectionType) { | |
| 36 | switch (SectionType) { | |
| 37 | case WASM_SEC_CUSTOM: | |
| 38 | return "CUSTOM"; | |
| 39 | case WASM_SEC_TYPE: | |
| 40 | return "TYPE"; | |
| 41 | case WASM_SEC_IMPORT: | |
| 42 | return "IMPORT"; | |
| 43 | case WASM_SEC_FUNCTION: | |
| 44 | return "FUNCTION"; | |
| 45 | case WASM_SEC_TABLE: | |
| 46 | return "TABLE"; | |
| 47 | case WASM_SEC_MEMORY: | |
| 48 | return "MEMORY"; | |
| 49 | case WASM_SEC_GLOBAL: | |
| 50 | return "GLOBAL"; | |
| 51 | case WASM_SEC_EXPORT: | |
| 52 | return "EXPORT"; | |
| 53 | case WASM_SEC_START: | |
| 54 | return "START"; | |
| 55 | case WASM_SEC_ELEM: | |
| 56 | return "ELEM"; | |
| 57 | case WASM_SEC_CODE: | |
| 58 | return "CODE"; | |
| 59 | case WASM_SEC_DATA: | |
| 60 | return "DATA"; | |
| 61 | default: | |
| 62 | fatal("invalid section type"); | |
| 63 | } | |
| 64 | } | |
| 65 | ||
| 66 | std::string lld::toString(const OutputSection &Section) { | |
| 67 | std::string rtn = Section.getSectionName(); | |
| 68 | if (!Section.Name.empty()) | |
| 69 | rtn += "(" + Section.Name + ")"; | |
| 70 | return rtn; | |
| 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 | } | |
| 179 | ||
| 180 | std::string OutputSection::getSectionName() const { | |
| 181 | return sectionTypeToString(Type); | |
| 182 | } | |
| 183 | ||
| 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) { | |
| 189 | raw_string_ostream OS(Header); | |
| 190 | debugWrite(OS.tell(), "section type [" + Twine(getSectionName()) + "]"); | |
| 191 | writeUleb128(OS, Type, nullptr); | |
| 192 | writeUleb128(OS, BodySize, "section size"); | |
| 193 | OS.flush(); | |
| 194 | log("createHeader: " + toString(*this) + " body=" + Twine(BodySize) + | |
| 195 | " total=" + Twine(getSize())); | |
| 196 | } | |
| 197 | ||
| 198 | CodeSection::CodeSection(uint32_t NumFunctions, ArrayRef<ObjFile *> Objs) | |
| 199 | : OutputSection(WASM_SEC_CODE), InputObjects(Objs) { | |
| 200 | raw_string_ostream OS(CodeSectionHeader); | |
| 201 | writeUleb128(OS, NumFunctions, "function count"); | |
| 202 | OS.flush(); | |
| 203 | BodySize = CodeSectionHeader.size(); | |
| 204 | ||
| 205 | for (ObjFile *File : InputObjects) { | |
| 206 | if (!File->CodeSection) | |
| 207 | continue; | |
| 208 | ||
| 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 | } | |
| 220 | ||
| 221 | createHeader(BodySize); | |
| 222 | } | |
| 223 | ||
| 224 | void CodeSection::writeTo(uint8_t *Buf) { | |
| 225 | log("writing " + toString(*this)); | |
| 226 | log(" size=" + Twine(getSize())); | |
| 227 | Buf += Offset; | |
| 228 | ||
| 229 | // Write section header | |
| 230 | memcpy(Buf, Header.data(), Header.size()); | |
| 231 | Buf += Header.size(); | |
| 232 | ||
| 233 | uint8_t *ContentsStart = Buf; | |
| 234 | ||
| 235 | // Write code section headers | |
| 236 | memcpy(Buf, CodeSectionHeader.data(), CodeSectionHeader.size()); | |
| 237 | Buf += CodeSectionHeader.size(); | |
| 238 | ||
| 239 | // Write code section bodies | |
| 240 | parallelForEach(InputObjects, [ContentsStart](ObjFile *File) { | |
| 241 | if (!File->CodeSection) | |
| 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 | } | |
| 258 | ||
| 259 | uint32_t CodeSection::numRelocations() const { | |
| 260 | uint32_t Count = 0; | |
| 261 | for (ObjFile *File : InputObjects) | |
| 262 | Count += File->CodeRelocations.size(); | |
| 263 | return Count; | |
| 264 | } | |
| 265 | ||
| 266 | void CodeSection::writeRelocations(raw_ostream &OS) const { | |
| 267 | for (ObjFile *File : InputObjects) | |
| 268 | for (const OutputRelocation &Reloc : File->CodeRelocations) | |
| 269 | writeReloc(OS, Reloc); | |
| 270 | } | |
| 271 | ||
| 272 | DataSection::DataSection(ArrayRef<OutputSegment *> Segments) | |
| 273 | : OutputSection(WASM_SEC_DATA), Segments(Segments) { | |
| 274 | raw_string_ostream OS(DataSectionHeader); | |
| 275 | ||
| 276 | writeUleb128(OS, Segments.size(), "data segment count"); | |
| 277 | OS.flush(); | |
| 278 | BodySize = DataSectionHeader.size(); | |
| 279 | ||
| 280 | for (OutputSegment *Segment : Segments) { | |
| 281 | raw_string_ostream OS(Segment->Header); | |
| 282 | writeUleb128(OS, 0, "memory index"); | |
| 283 | writeUleb128(OS, WASM_OPCODE_I32_CONST, "opcode:i32const"); | |
| 284 | writeSleb128(OS, Segment->StartVA, "memory offset"); | |
| 285 | writeUleb128(OS, WASM_OPCODE_END, "opcode:end"); | |
| 286 | writeUleb128(OS, Segment->Size, "segment size"); | |
| 287 | OS.flush(); | |
| 288 | Segment->setSectionOffset(BodySize); | |
| 289 | BodySize += Segment->Header.size(); | |
| 290 | log("Data segment: size=" + Twine(Segment->Size)); | |
| 291 | for (InputSegment *InputSeg : Segment->InputSegments) { | |
| 292 | uint32_t InputOffset = InputSeg->getInputSectionOffset(); | |
| 293 | uint32_t OutputOffset = Segment->getSectionOffset() + | |
| 294 | Segment->Header.size() + | |
| 295 | InputSeg->getOutputSegmentOffset(); | |
| 296 | calcRelocations(*InputSeg->File, InputSeg->Relocations, | |
| 297 | InputSeg->OutRelocations, OutputOffset - InputOffset); | |
| 298 | } | |
| 299 | BodySize += Segment->Size; | |
| 300 | } | |
| 301 | ||
| 302 | createHeader(BodySize); | |
| 303 | } | |
| 304 | ||
| 305 | void DataSection::writeTo(uint8_t *Buf) { | |
| 306 | log("writing " + toString(*this) + " size=" + Twine(getSize()) + | |
| 307 | " body=" + Twine(BodySize)); | |
| 308 | Buf += Offset; | |
| 309 | ||
| 310 | // Write section header | |
| 311 | memcpy(Buf, Header.data(), Header.size()); | |
| 312 | Buf += Header.size(); | |
| 313 | ||
| 314 | uint8_t *ContentsStart = Buf; | |
| 315 | ||
| 316 | // Write data section headers | |
| 317 | memcpy(Buf, DataSectionHeader.data(), DataSectionHeader.size()); | |
| 318 | ||
| 319 | parallelForEach(Segments, [ContentsStart](const OutputSegment *Segment) { | |
| 320 | // Write data segment header | |
| 321 | uint8_t *SegStart = ContentsStart + Segment->getSectionOffset(); | |
| 322 | memcpy(SegStart, Segment->Header.data(), Segment->Header.size()); | |
| 323 | ||
| 324 | // Write segment data payload | |
| 325 | for (const InputSegment *Input : Segment->InputSegments) { | |
| 326 | ArrayRef<uint8_t> Content(Input->Segment->Data.Content); | |
| 327 | memcpy(SegStart + Segment->Header.size() + | |
| 328 | Input->getOutputSegmentOffset(), | |
| 329 | Content.data(), Content.size()); | |
| 330 | applyRelocations(ContentsStart, Input->OutRelocations); | |
| 331 | } | |
| 332 | }); | |
| 333 | } | |
| 334 | ||
| 335 | uint32_t DataSection::numRelocations() const { | |
| 336 | uint32_t Count = 0; | |
| 337 | for (const OutputSegment *Seg : Segments) | |
| 338 | for (const InputSegment *InputSeg : Seg->InputSegments) | |
| 339 | Count += InputSeg->OutRelocations.size(); | |
| 340 | return Count; | |
| 341 | } | |
| 342 | ||
| 343 | void DataSection::writeRelocations(raw_ostream &OS) const { | |
| 344 | for (const OutputSegment *Seg : Segments) | |
| 345 | for (const InputSegment *InputSeg : Seg->InputSegments) | |
| 346 | for (const OutputRelocation &Reloc : InputSeg->OutRelocations) | |
| 347 | writeReloc(OS, Reloc); | |
| 348 | } |
deps/lld/wasm/OutputSections.h created+136| ... | ... | @@ -0,0 +1,136 @@ |
| 1 | //===- OutputSections.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_OUTPUT_SECTIONS_H | |
| 11 | #define LLD_WASM_OUTPUT_SECTIONS_H | |
| 12 | ||
| 13 | #include "InputSegment.h" | |
| 14 | #include "WriterUtils.h" | |
| 15 | #include "lld/Common/ErrorHandler.h" | |
| 16 | #include "llvm/ADT/DenseMap.h" | |
| 17 | ||
| 18 | using llvm::raw_ostream; | |
| 19 | using llvm::raw_string_ostream; | |
| 20 | ||
| 21 | namespace lld { | |
| 22 | ||
| 23 | namespace wasm { | |
| 24 | class OutputSection; | |
| 25 | } | |
| 26 | std::string toString(const wasm::OutputSection &Section); | |
| 27 | ||
| 28 | namespace wasm { | |
| 29 | ||
| 30 | class OutputSegment; | |
| 31 | class ObjFile; | |
| 32 | ||
| 33 | class OutputSection { | |
| 34 | public: | |
| 35 | OutputSection(uint32_t Type, std::string Name = "") | |
| 36 | : Type(Type), Name(Name) {} | |
| 37 | virtual ~OutputSection() = default; | |
| 38 | ||
| 39 | std::string getSectionName() const; | |
| 40 | void setOffset(size_t NewOffset) { | |
| 41 | log("setOffset: " + toString(*this) + ": " + Twine(NewOffset)); | |
| 42 | Offset = NewOffset; | |
| 43 | } | |
| 44 | void createHeader(size_t BodySize); | |
| 45 | virtual size_t getSize() const = 0; | |
| 46 | virtual void writeTo(uint8_t *Buf) = 0; | |
| 47 | virtual void finalizeContents() {} | |
| 48 | virtual uint32_t numRelocations() const { return 0; } | |
| 49 | virtual void writeRelocations(raw_ostream &OS) const {} | |
| 50 | ||
| 51 | std::string Header; | |
| 52 | uint32_t Type; | |
| 53 | std::string Name; | |
| 54 | ||
| 55 | protected: | |
| 56 | size_t Offset = 0; | |
| 57 | }; | |
| 58 | ||
| 59 | class SyntheticSection : public OutputSection { | |
| 60 | public: | |
| 61 | SyntheticSection(uint32_t Type, std::string Name = "") | |
| 62 | : OutputSection(Type, Name), BodyOutputStream(Body) { | |
| 63 | if (!Name.empty()) | |
| 64 | writeStr(BodyOutputStream, Name); | |
| 65 | } | |
| 66 | ||
| 67 | void writeTo(uint8_t *Buf) override { | |
| 68 | assert(Offset); | |
| 69 | log("writing " + toString(*this)); | |
| 70 | memcpy(Buf + Offset, Header.data(), Header.size()); | |
| 71 | memcpy(Buf + Offset + Header.size(), Body.data(), Body.size()); | |
| 72 | } | |
| 73 | ||
| 74 | size_t getSize() const override { return Header.size() + Body.size(); } | |
| 75 | ||
| 76 | void finalizeContents() override { | |
| 77 | BodyOutputStream.flush(); | |
| 78 | createHeader(Body.size()); | |
| 79 | } | |
| 80 | ||
| 81 | raw_ostream &getStream() { return BodyOutputStream; } | |
| 82 | ||
| 83 | std::string Body; | |
| 84 | ||
| 85 | protected: | |
| 86 | raw_string_ostream BodyOutputStream; | |
| 87 | }; | |
| 88 | ||
| 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 { | |
| 106 | public: | |
| 107 | explicit CodeSection(uint32_t NumFunctions, ArrayRef<ObjFile *> Objs); | |
| 108 | size_t getSize() const override { return Header.size() + BodySize; } | |
| 109 | void writeTo(uint8_t *Buf) override; | |
| 110 | uint32_t numRelocations() const override; | |
| 111 | void writeRelocations(raw_ostream &OS) const override; | |
| 112 | ||
| 113 | protected: | |
| 114 | ArrayRef<ObjFile *> InputObjects; | |
| 115 | std::string CodeSectionHeader; | |
| 116 | size_t BodySize = 0; | |
| 117 | }; | |
| 118 | ||
| 119 | class DataSection : public OutputSection { | |
| 120 | public: | |
| 121 | explicit DataSection(ArrayRef<OutputSegment *> Segments); | |
| 122 | size_t getSize() const override { return Header.size() + BodySize; } | |
| 123 | void writeTo(uint8_t *Buf) override; | |
| 124 | uint32_t numRelocations() const override; | |
| 125 | void writeRelocations(raw_ostream &OS) const override; | |
| 126 | ||
| 127 | protected: | |
| 128 | ArrayRef<OutputSegment *> Segments; | |
| 129 | std::string DataSectionHeader; | |
| 130 | size_t BodySize = 0; | |
| 131 | }; | |
| 132 | ||
| 133 | } // namespace wasm | |
| 134 | } // namespace lld | |
| 135 | ||
| 136 | #endif // LLD_WASM_OUTPUT_SECTIONS_H |
deps/lld/wasm/OutputSegment.h created+56| ... | ... | @@ -0,0 +1,56 @@ |
| 1 | //===- OutputSegment.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_OUTPUT_SEGMENT_H | |
| 11 | #define LLD_WASM_OUTPUT_SEGMENT_H | |
| 12 | ||
| 13 | #include "InputSegment.h" | |
| 14 | #include "lld/Common/ErrorHandler.h" | |
| 15 | #include "llvm/Object/Wasm.h" | |
| 16 | ||
| 17 | namespace lld { | |
| 18 | namespace wasm { | |
| 19 | ||
| 20 | class InputSegment; | |
| 21 | ||
| 22 | class OutputSegment { | |
| 23 | public: | |
| 24 | OutputSegment(StringRef N) : Name(N) {} | |
| 25 | ||
| 26 | void addInputSegment(InputSegment *Segment) { | |
| 27 | Alignment = std::max(Alignment, Segment->getAlignment()); | |
| 28 | InputSegments.push_back(Segment); | |
| 29 | Size = llvm::alignTo(Size, Segment->getAlignment()); | |
| 30 | Segment->setOutputSegment(this, Size); | |
| 31 | Size += Segment->getSize(); | |
| 32 | } | |
| 33 | ||
| 34 | uint32_t getSectionOffset() const { return SectionOffset; } | |
| 35 | ||
| 36 | void setSectionOffset(uint32_t Offset) { SectionOffset = Offset; } | |
| 37 | ||
| 38 | StringRef Name; | |
| 39 | uint32_t Alignment = 0; | |
| 40 | uint32_t StartVA = 0; | |
| 41 | std::vector<InputSegment *> InputSegments; | |
| 42 | ||
| 43 | // Sum of the size of the all the input segments | |
| 44 | uint32_t Size = 0; | |
| 45 | ||
| 46 | // Segment header | |
| 47 | std::string Header; | |
| 48 | ||
| 49 | private: | |
| 50 | uint32_t SectionOffset = 0; | |
| 51 | }; | |
| 52 | ||
| 53 | } // namespace wasm | |
| 54 | } // namespace lld | |
| 55 | ||
| 56 | #endif // LLD_WASM_OUTPUT_SEGMENT_H |
deps/lld/wasm/SymbolTable.cpp created+237| ... | ... | @@ -0,0 +1,237 @@ |
| 1 | //===- SymbolTable.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 "SymbolTable.h" | |
| 11 | ||
| 12 | #include "Config.h" | |
| 13 | #include "WriterUtils.h" | |
| 14 | #include "lld/Common/ErrorHandler.h" | |
| 15 | #include "lld/Common/Memory.h" | |
| 16 | ||
| 17 | #include <unordered_set> | |
| 18 | ||
| 19 | #define DEBUG_TYPE "lld" | |
| 20 | ||
| 21 | using namespace llvm; | |
| 22 | using namespace lld; | |
| 23 | using namespace lld::wasm; | |
| 24 | ||
| 25 | SymbolTable *lld::wasm::Symtab; | |
| 26 | ||
| 27 | void SymbolTable::addFile(InputFile *File) { | |
| 28 | log("Processing: " + toString(File)); | |
| 29 | File->parse(); | |
| 30 | ||
| 31 | if (auto *F = dyn_cast<ObjFile>(File)) | |
| 32 | ObjectFiles.push_back(F); | |
| 33 | } | |
| 34 | ||
| 35 | void SymbolTable::reportRemainingUndefines() { | |
| 36 | std::unordered_set<Symbol *> Undefs; | |
| 37 | for (Symbol *Sym : SymVector) { | |
| 38 | if (Sym->isUndefined() && !Sym->isWeak() && | |
| 39 | Config->AllowUndefinedSymbols.count(Sym->getName()) == 0) { | |
| 40 | Undefs.insert(Sym); | |
| 41 | } | |
| 42 | } | |
| 43 | ||
| 44 | if (Undefs.empty()) | |
| 45 | return; | |
| 46 | ||
| 47 | for (ObjFile *File : ObjectFiles) | |
| 48 | for (Symbol *Sym : File->getSymbols()) | |
| 49 | if (Undefs.count(Sym)) | |
| 50 | error(toString(File) + ": undefined symbol: " + toString(*Sym)); | |
| 51 | ||
| 52 | for (Symbol *Sym : Undefs) | |
| 53 | if (!Sym->getFile()) | |
| 54 | error("undefined symbol: " + toString(*Sym)); | |
| 55 | } | |
| 56 | ||
| 57 | Symbol *SymbolTable::find(StringRef Name) { | |
| 58 | auto It = SymMap.find(CachedHashStringRef(Name)); | |
| 59 | if (It == SymMap.end()) | |
| 60 | return nullptr; | |
| 61 | return It->second; | |
| 62 | } | |
| 63 | ||
| 64 | std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { | |
| 65 | Symbol *&Sym = SymMap[CachedHashStringRef(Name)]; | |
| 66 | if (Sym) | |
| 67 | return {Sym, false}; | |
| 68 | Sym = make<Symbol>(Name, false); | |
| 69 | SymVector.emplace_back(Sym); | |
| 70 | return {Sym, true}; | |
| 71 | } | |
| 72 | ||
| 73 | void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) { | |
| 74 | error("duplicate symbol: " + toString(*Existing) + "\n>>> defined in " + | |
| 75 | toString(Existing->getFile()) + "\n>>> defined in " + | |
| 76 | toString(NewFile)); | |
| 77 | } | |
| 78 | ||
| 79 | // Get the signature for a given function symbol, either by looking | |
| 80 | // it up in function sections (for defined functions), of the imports section | |
| 81 | // (for imported functions). | |
| 82 | static const WasmSignature *getFunctionSig(const ObjFile &Obj, | |
| 83 | const WasmSymbol &Sym) { | |
| 84 | DEBUG(dbgs() << "getFunctionSig: " << Sym.Name << "\n"); | |
| 85 | const WasmObjectFile *WasmObj = Obj.getWasmObj(); | |
| 86 | return &WasmObj->types()[Sym.FunctionType]; | |
| 87 | } | |
| 88 | ||
| 89 | // 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. | |
| 91 | static void checkSymbolTypes(const Symbol &Existing, const InputFile &F, | |
| 92 | const WasmSymbol &New, | |
| 93 | const WasmSignature *NewSig) { | |
| 94 | if (Existing.isLazy()) | |
| 95 | return; | |
| 96 | ||
| 97 | bool NewIsFunction = New.Type == WasmSymbol::SymbolType::FUNCTION_EXPORT || | |
| 98 | New.Type == WasmSymbol::SymbolType::FUNCTION_IMPORT; | |
| 99 | ||
| 100 | // First check the symbol types match (i.e. either both are function | |
| 101 | // symbols or both are data symbols). | |
| 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 | } | |
| 109 | ||
| 110 | // For function symbols, optionally check the function signature matches too. | |
| 111 | if (!NewIsFunction || !Config->CheckSignatures) | |
| 112 | return; | |
| 113 | // Skip the signature check if the existing function has no signature (e.g. | |
| 114 | // if it is an undefined symbol generated by --undefined command line flag). | |
| 115 | if (!Existing.hasFunctionType()) | |
| 116 | return; | |
| 117 | ||
| 118 | DEBUG(dbgs() << "checkSymbolTypes: " << New.Name << "\n"); | |
| 119 | assert(NewSig); | |
| 120 | ||
| 121 | const WasmSignature &OldSig = Existing.getFunctionType(); | |
| 122 | if (*NewSig == OldSig) | |
| 123 | return; | |
| 124 | ||
| 125 | error("function signature mismatch: " + New.Name + "\n>>> defined as " + | |
| 126 | toString(OldSig) + " in " + toString(Existing.getFile()) + | |
| 127 | "\n>>> defined as " + toString(*NewSig) + " in " + F.getName()); | |
| 128 | } | |
| 129 | ||
| 130 | Symbol *SymbolTable::addDefinedGlobal(StringRef Name) { | |
| 131 | DEBUG(dbgs() << "addDefinedGlobal: " << Name << "\n"); | |
| 132 | Symbol *S; | |
| 133 | bool WasInserted; | |
| 134 | std::tie(S, WasInserted) = insert(Name); | |
| 135 | if (WasInserted) | |
| 136 | S->update(Symbol::DefinedGlobalKind); | |
| 137 | else if (!S->isGlobal()) | |
| 138 | error("symbol type mismatch: " + Name); | |
| 139 | return S; | |
| 140 | } | |
| 141 | ||
| 142 | Symbol *SymbolTable::addDefined(InputFile *F, const WasmSymbol *Sym, | |
| 143 | const InputSegment *Segment) { | |
| 144 | DEBUG(dbgs() << "addDefined: " << Sym->Name << "\n"); | |
| 145 | Symbol *S; | |
| 146 | bool WasInserted; | |
| 147 | Symbol::Kind Kind = Symbol::DefinedFunctionKind; | |
| 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 | ||
| 154 | std::tie(S, WasInserted) = insert(Sym->Name); | |
| 155 | if (WasInserted) { | |
| 156 | S->update(Kind, F, Sym, Segment, NewSig); | |
| 157 | } else if (S->isLazy()) { | |
| 158 | // The existing symbol is lazy. Replace it without checking types since | |
| 159 | // lazy symbols don't have any type information. | |
| 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 | } | |
| 182 | return S; | |
| 183 | } | |
| 184 | ||
| 185 | Symbol *SymbolTable::addUndefinedFunction(StringRef Name, | |
| 186 | const WasmSignature *Type) { | |
| 187 | Symbol *S; | |
| 188 | bool WasInserted; | |
| 189 | std::tie(S, WasInserted) = insert(Name); | |
| 190 | if (WasInserted) { | |
| 191 | S->update(Symbol::UndefinedFunctionKind, nullptr, nullptr, nullptr, Type); | |
| 192 | } else if (!S->isFunction()) { | |
| 193 | error("symbol type mismatch: " + Name); | |
| 194 | } | |
| 195 | return S; | |
| 196 | } | |
| 197 | ||
| 198 | Symbol *SymbolTable::addUndefined(InputFile *F, const WasmSymbol *Sym) { | |
| 199 | DEBUG(dbgs() << "addUndefined: " << Sym->Name << "\n"); | |
| 200 | Symbol *S; | |
| 201 | bool WasInserted; | |
| 202 | Symbol::Kind Kind = Symbol::UndefinedFunctionKind; | |
| 203 | const WasmSignature *NewSig = nullptr; | |
| 204 | if (Sym->Type == WasmSymbol::SymbolType::GLOBAL_IMPORT) | |
| 205 | Kind = Symbol::UndefinedGlobalKind; | |
| 206 | else | |
| 207 | NewSig = getFunctionSig(*cast<ObjFile>(F), *Sym); | |
| 208 | std::tie(S, WasInserted) = insert(Sym->Name); | |
| 209 | if (WasInserted) { | |
| 210 | S->update(Kind, F, Sym, nullptr, NewSig); | |
| 211 | } else if (S->isLazy()) { | |
| 212 | DEBUG(dbgs() << "resolved by existing lazy\n"); | |
| 213 | auto *AF = cast<ArchiveFile>(S->getFile()); | |
| 214 | AF->addMember(&S->getArchiveSymbol()); | |
| 215 | } else if (S->isDefined()) { | |
| 216 | DEBUG(dbgs() << "resolved by existing\n"); | |
| 217 | checkSymbolTypes(*S, *F, *Sym, NewSig); | |
| 218 | } | |
| 219 | return S; | |
| 220 | } | |
| 221 | ||
| 222 | void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol *Sym) { | |
| 223 | DEBUG(dbgs() << "addLazy: " << Sym->getName() << "\n"); | |
| 224 | StringRef Name = Sym->getName(); | |
| 225 | Symbol *S; | |
| 226 | bool WasInserted; | |
| 227 | std::tie(S, WasInserted) = insert(Name); | |
| 228 | if (WasInserted) { | |
| 229 | S->update(Symbol::LazyKind, F); | |
| 230 | S->setArchiveSymbol(*Sym); | |
| 231 | } else if (S->isUndefined()) { | |
| 232 | // There is an existing undefined symbol. The can load from the | |
| 233 | // archive. | |
| 234 | DEBUG(dbgs() << "replacing existing undefined\n"); | |
| 235 | F->addMember(Sym); | |
| 236 | } | |
| 237 | } |
deps/lld/wasm/SymbolTable.h created+71| ... | ... | @@ -0,0 +1,71 @@ |
| 1 | //===- SymbolTable.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_SYMBOL_TABLE_H | |
| 11 | #define LLD_WASM_SYMBOL_TABLE_H | |
| 12 | ||
| 13 | #include "InputFiles.h" | |
| 14 | #include "Symbols.h" | |
| 15 | ||
| 16 | #include "llvm/ADT/CachedHashString.h" | |
| 17 | #include "llvm/ADT/DenseMap.h" | |
| 18 | #include "llvm/Support/raw_ostream.h" | |
| 19 | ||
| 20 | using llvm::object::WasmSymbol; | |
| 21 | using llvm::wasm::WasmSignature; | |
| 22 | ||
| 23 | namespace lld { | |
| 24 | namespace wasm { | |
| 25 | ||
| 26 | class InputSegment; | |
| 27 | ||
| 28 | // SymbolTable is a bucket of all known symbols, including defined, | |
| 29 | // undefined, or lazy symbols (the last one is symbols in archive | |
| 30 | // files whose archive members are not yet loaded). | |
| 31 | // | |
| 32 | // We put all symbols of all files to a SymbolTable, and the | |
| 33 | // SymbolTable selects the "best" symbols if there are name | |
| 34 | // conflicts. For example, obviously, a defined symbol is better than | |
| 35 | // an undefined symbol. Or, if there's a conflict between a lazy and a | |
| 36 | // undefined, it'll read an archive member to read a real definition | |
| 37 | // to replace the lazy symbol. The logic is implemented in the | |
| 38 | // add*() functions, which are called by input files as they are parsed. | |
| 39 | // There is one add* function per symbol type. | |
| 40 | class SymbolTable { | |
| 41 | public: | |
| 42 | void addFile(InputFile *File); | |
| 43 | ||
| 44 | std::vector<ObjFile *> ObjectFiles; | |
| 45 | ||
| 46 | void reportDuplicate(Symbol *Existing, InputFile *NewFile); | |
| 47 | void reportRemainingUndefines(); | |
| 48 | ||
| 49 | ArrayRef<Symbol *> getSymbols() const { return SymVector; } | |
| 50 | Symbol *find(StringRef Name); | |
| 51 | ||
| 52 | Symbol *addDefined(InputFile *F, const WasmSymbol *Sym, | |
| 53 | const InputSegment *Segment = nullptr); | |
| 54 | Symbol *addUndefined(InputFile *F, const WasmSymbol *Sym); | |
| 55 | Symbol *addUndefinedFunction(StringRef Name, const WasmSignature *Type); | |
| 56 | Symbol *addDefinedGlobal(StringRef Name); | |
| 57 | void addLazy(ArchiveFile *F, const Archive::Symbol *Sym); | |
| 58 | ||
| 59 | private: | |
| 60 | std::pair<Symbol *, bool> insert(StringRef Name); | |
| 61 | ||
| 62 | llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap; | |
| 63 | std::vector<Symbol *> SymVector; | |
| 64 | }; | |
| 65 | ||
| 66 | extern SymbolTable *Symtab; | |
| 67 | ||
| 68 | } // namespace wasm | |
| 69 | } // namespace lld | |
| 70 | ||
| 71 | #endif |
deps/lld/wasm/Symbols.cpp created+114| ... | ... | @@ -0,0 +1,114 @@ |
| 1 | //===- Symbols.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 "Symbols.h" | |
| 11 | ||
| 12 | #include "Config.h" | |
| 13 | #include "InputFiles.h" | |
| 14 | #include "InputSegment.h" | |
| 15 | #include "lld/Common/ErrorHandler.h" | |
| 16 | #include "lld/Common/Strings.h" | |
| 17 | ||
| 18 | #define DEBUG_TYPE "lld" | |
| 19 | ||
| 20 | using namespace llvm; | |
| 21 | using namespace lld; | |
| 22 | using namespace lld::wasm; | |
| 23 | ||
| 24 | uint32_t Symbol::getGlobalIndex() const { | |
| 25 | assert(!Sym->isFunction()); | |
| 26 | return Sym->ElementIndex; | |
| 27 | } | |
| 28 | ||
| 29 | uint32_t Symbol::getFunctionIndex() const { | |
| 30 | assert(Sym->isFunction()); | |
| 31 | return Sym->ElementIndex; | |
| 32 | } | |
| 33 | ||
| 34 | const WasmSignature &Symbol::getFunctionType() const { | |
| 35 | assert(FunctionType != nullptr); | |
| 36 | return *FunctionType; | |
| 37 | } | |
| 38 | ||
| 39 | uint32_t Symbol::getVirtualAddress() const { | |
| 40 | assert(isGlobal()); | |
| 41 | DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n"); | |
| 42 | if (isUndefined()) | |
| 43 | return UINT32_MAX; | |
| 44 | if (VirtualAddress.hasValue()) | |
| 45 | return VirtualAddress.getValue(); | |
| 46 | ||
| 47 | assert(Sym != nullptr); | |
| 48 | ObjFile *Obj = cast<ObjFile>(File); | |
| 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 | } | |
| 55 | ||
| 56 | uint32_t Symbol::getOutputIndex() const { | |
| 57 | if (isUndefined() && isWeak()) | |
| 58 | return 0; | |
| 59 | return OutputIndex.getValue(); | |
| 60 | } | |
| 61 | ||
| 62 | void Symbol::setVirtualAddress(uint32_t Value) { | |
| 63 | DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n"); | |
| 64 | assert(!VirtualAddress.hasValue()); | |
| 65 | VirtualAddress = Value; | |
| 66 | } | |
| 67 | ||
| 68 | void Symbol::setOutputIndex(uint32_t Index) { | |
| 69 | DEBUG(dbgs() << "setOutputIndex " << Name << " -> " << Index << "\n"); | |
| 70 | assert(!OutputIndex.hasValue()); | |
| 71 | OutputIndex = Index; | |
| 72 | } | |
| 73 | ||
| 74 | void Symbol::setTableIndex(uint32_t Index) { | |
| 75 | DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n"); | |
| 76 | assert(!TableIndex.hasValue()); | |
| 77 | TableIndex = Index; | |
| 78 | } | |
| 79 | ||
| 80 | void Symbol::update(Kind K, InputFile *F, const WasmSymbol *WasmSym, | |
| 81 | const InputSegment *Seg, const WasmSignature *Sig) { | |
| 82 | SymbolKind = K; | |
| 83 | File = F; | |
| 84 | Sym = WasmSym; | |
| 85 | Segment = Seg; | |
| 86 | FunctionType = Sig; | |
| 87 | } | |
| 88 | ||
| 89 | bool Symbol::isWeak() const { return Sym && Sym->isWeak(); } | |
| 90 | ||
| 91 | bool Symbol::isHidden() const { return Sym && Sym->isHidden(); } | |
| 92 | ||
| 93 | std::string lld::toString(const wasm::Symbol &Sym) { | |
| 94 | if (Config->Demangle) | |
| 95 | if (Optional<std::string> S = demangleItanium(Sym.getName())) | |
| 96 | return "`" + *S + "'"; | |
| 97 | return Sym.getName(); | |
| 98 | } | |
| 99 | ||
| 100 | std::string lld::toString(wasm::Symbol::Kind Kind) { | |
| 101 | switch (Kind) { | |
| 102 | case wasm::Symbol::DefinedFunctionKind: | |
| 103 | return "DefinedFunction"; | |
| 104 | case wasm::Symbol::DefinedGlobalKind: | |
| 105 | return "DefinedGlobal"; | |
| 106 | case wasm::Symbol::UndefinedFunctionKind: | |
| 107 | return "UndefinedFunction"; | |
| 108 | case wasm::Symbol::UndefinedGlobalKind: | |
| 109 | return "UndefinedGlobal"; | |
| 110 | case wasm::Symbol::LazyKind: | |
| 111 | return "LazyKind"; | |
| 112 | } | |
| 113 | llvm_unreachable("Invalid symbol kind!"); | |
| 114 | } |
deps/lld/wasm/Symbols.h created+128| ... | ... | @@ -0,0 +1,128 @@ |
| 1 | //===- Symbols.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_SYMBOLS_H | |
| 11 | #define LLD_WASM_SYMBOLS_H | |
| 12 | ||
| 13 | #include "lld/Common/LLVM.h" | |
| 14 | #include "llvm/Object/Archive.h" | |
| 15 | #include "llvm/Object/Wasm.h" | |
| 16 | ||
| 17 | using llvm::object::Archive; | |
| 18 | using llvm::object::WasmSymbol; | |
| 19 | using llvm::wasm::WasmExport; | |
| 20 | using llvm::wasm::WasmImport; | |
| 21 | using llvm::wasm::WasmSignature; | |
| 22 | ||
| 23 | namespace lld { | |
| 24 | namespace wasm { | |
| 25 | ||
| 26 | class InputFile; | |
| 27 | class InputSegment; | |
| 28 | ||
| 29 | class Symbol { | |
| 30 | public: | |
| 31 | enum Kind { | |
| 32 | DefinedFunctionKind, | |
| 33 | DefinedGlobalKind, | |
| 34 | ||
| 35 | LazyKind, | |
| 36 | UndefinedFunctionKind, | |
| 37 | UndefinedGlobalKind, | |
| 38 | ||
| 39 | LastDefinedKind = DefinedGlobalKind, | |
| 40 | InvalidKind, | |
| 41 | }; | |
| 42 | ||
| 43 | Symbol(StringRef Name, bool IsLocal) | |
| 44 | : WrittenToSymtab(0), WrittenToNameSec(0), IsLocal(IsLocal), Name(Name) {} | |
| 45 | ||
| 46 | Kind getKind() const { return SymbolKind; } | |
| 47 | ||
| 48 | bool isLazy() const { return SymbolKind == LazyKind; } | |
| 49 | bool isDefined() const { return SymbolKind <= LastDefinedKind; } | |
| 50 | bool isUndefined() const { | |
| 51 | return SymbolKind == UndefinedGlobalKind || | |
| 52 | SymbolKind == UndefinedFunctionKind; | |
| 53 | } | |
| 54 | bool isFunction() const { | |
| 55 | return SymbolKind == DefinedFunctionKind || | |
| 56 | SymbolKind == UndefinedFunctionKind; | |
| 57 | } | |
| 58 | bool isGlobal() const { return !isFunction(); } | |
| 59 | bool isLocal() const { return IsLocal; } | |
| 60 | bool isWeak() const; | |
| 61 | bool isHidden() const; | |
| 62 | ||
| 63 | // Returns the symbol name. | |
| 64 | StringRef getName() const { return Name; } | |
| 65 | ||
| 66 | // Returns the file from which this symbol was created. | |
| 67 | InputFile *getFile() const { return File; } | |
| 68 | ||
| 69 | uint32_t getGlobalIndex() const; | |
| 70 | uint32_t getFunctionIndex() const; | |
| 71 | ||
| 72 | bool hasFunctionType() const { return FunctionType != nullptr; } | |
| 73 | const WasmSignature &getFunctionType() const; | |
| 74 | uint32_t getOutputIndex() const; | |
| 75 | uint32_t getTableIndex() const { return TableIndex.getValue(); } | |
| 76 | ||
| 77 | // Returns the virtual address of a defined global. | |
| 78 | // Only works for globals, not functions. | |
| 79 | uint32_t getVirtualAddress() const; | |
| 80 | ||
| 81 | // Set the output index of the symbol (in the function or global index | |
| 82 | // space of the output object. | |
| 83 | void setOutputIndex(uint32_t Index); | |
| 84 | ||
| 85 | // Returns true if a table index has been set for this symbol | |
| 86 | bool hasTableIndex() const { return TableIndex.hasValue(); } | |
| 87 | ||
| 88 | // Set the table index of the symbol | |
| 89 | void setTableIndex(uint32_t Index); | |
| 90 | ||
| 91 | void setVirtualAddress(uint32_t VA); | |
| 92 | ||
| 93 | void update(Kind K, InputFile *F = nullptr, const WasmSymbol *Sym = nullptr, | |
| 94 | const InputSegment *Segment = nullptr, | |
| 95 | const WasmSignature *Sig = nullptr); | |
| 96 | ||
| 97 | void setArchiveSymbol(const Archive::Symbol &Sym) { ArchiveSymbol = Sym; } | |
| 98 | const Archive::Symbol &getArchiveSymbol() { return ArchiveSymbol; } | |
| 99 | ||
| 100 | // This bit is used by Writer::writeNameSection() to prevent | |
| 101 | // symbols from being written to the symbol table more than once. | |
| 102 | unsigned WrittenToSymtab : 1; | |
| 103 | unsigned WrittenToNameSec : 1; | |
| 104 | ||
| 105 | protected: | |
| 106 | unsigned IsLocal : 1; | |
| 107 | ||
| 108 | StringRef Name; | |
| 109 | Archive::Symbol ArchiveSymbol = {nullptr, 0, 0}; | |
| 110 | Kind SymbolKind = InvalidKind; | |
| 111 | InputFile *File = nullptr; | |
| 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 | }; | |
| 119 | ||
| 120 | } // namespace wasm | |
| 121 | ||
| 122 | // Returns a symbol name for an error message. | |
| 123 | std::string toString(const wasm::Symbol &Sym); | |
| 124 | std::string toString(wasm::Symbol::Kind Kind); | |
| 125 | ||
| 126 | } // namespace lld | |
| 127 | ||
| 128 | #endif |
deps/lld/wasm/Writer.cpp created+745| ... | ... | @@ -0,0 +1,745 @@ |
| 1 | //===- Writer.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 "Writer.h" | |
| 11 | ||
| 12 | #include "Config.h" | |
| 13 | #include "OutputSections.h" | |
| 14 | #include "OutputSegment.h" | |
| 15 | #include "SymbolTable.h" | |
| 16 | #include "WriterUtils.h" | |
| 17 | #include "lld/Common/ErrorHandler.h" | |
| 18 | #include "lld/Common/Memory.h" | |
| 19 | #include "lld/Common/Threads.h" | |
| 20 | #include "llvm/Support/FileOutputBuffer.h" | |
| 21 | #include "llvm/Support/Format.h" | |
| 22 | #include "llvm/Support/FormatVariadic.h" | |
| 23 | #include "llvm/Support/LEB128.h" | |
| 24 | ||
| 25 | #include <cstdarg> | |
| 26 | ||
| 27 | #define DEBUG_TYPE "lld" | |
| 28 | ||
| 29 | using namespace llvm; | |
| 30 | using namespace llvm::wasm; | |
| 31 | using namespace lld; | |
| 32 | using namespace lld::wasm; | |
| 33 | ||
| 34 | static constexpr int kStackAlignment = 16; | |
| 35 | ||
| 36 | namespace { | |
| 37 | ||
| 38 | // Traits for using WasmSignature in a DenseMap. | |
| 39 | struct WasmSignatureDenseMapInfo { | |
| 40 | static WasmSignature getEmptyKey() { | |
| 41 | WasmSignature Sig; | |
| 42 | Sig.ReturnType = 1; | |
| 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 | }; | |
| 61 | ||
| 62 | // The writer writes a SymbolTable result to a file. | |
| 63 | class Writer { | |
| 64 | public: | |
| 65 | void run(); | |
| 66 | ||
| 67 | private: | |
| 68 | void openFile(); | |
| 69 | ||
| 70 | uint32_t getTypeIndex(const WasmSignature &Sig); | |
| 71 | void assignSymbolIndexes(); | |
| 72 | void calculateImports(); | |
| 73 | void calculateOffsets(); | |
| 74 | void calculateTypes(); | |
| 75 | void createOutputSegments(); | |
| 76 | void layoutMemory(); | |
| 77 | void createHeader(); | |
| 78 | void createSections(); | |
| 79 | SyntheticSection *createSyntheticSection(uint32_t Type, | |
| 80 | std::string Name = ""); | |
| 81 | ||
| 82 | // Builtin sections | |
| 83 | void createTypeSection(); | |
| 84 | void createFunctionSection(); | |
| 85 | void createTableSection(); | |
| 86 | void createGlobalSection(); | |
| 87 | void createExportSection(); | |
| 88 | void createImportSection(); | |
| 89 | void createMemorySection(); | |
| 90 | void createElemSection(); | |
| 91 | void createStartSection(); | |
| 92 | void createCodeSection(); | |
| 93 | void createDataSection(); | |
| 94 | ||
| 95 | // Custom sections | |
| 96 | void createRelocSections(); | |
| 97 | void createLinkingSection(); | |
| 98 | void createNameSection(); | |
| 99 | ||
| 100 | void writeHeader(); | |
| 101 | void writeSections(); | |
| 102 | ||
| 103 | uint64_t FileSize = 0; | |
| 104 | uint32_t DataSize = 0; | |
| 105 | uint32_t NumFunctions = 0; | |
| 106 | uint32_t NumMemoryPages = 0; | |
| 107 | uint32_t InitialTableOffset = 0; | |
| 108 | ||
| 109 | std::vector<const WasmSignature *> Types; | |
| 110 | DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo> TypeIndices; | |
| 111 | std::vector<const Symbol *> FunctionImports; | |
| 112 | std::vector<const Symbol *> GlobalImports; | |
| 113 | std::vector<const Symbol *> DefinedGlobals; | |
| 114 | std::vector<const Symbol *> IndirectFunctions; | |
| 115 | ||
| 116 | // Elements that are used to construct the final output | |
| 117 | std::string Header; | |
| 118 | std::vector<OutputSection *> OutputSections; | |
| 119 | ||
| 120 | std::unique_ptr<FileOutputBuffer> Buffer; | |
| 121 | ||
| 122 | std::vector<OutputSegment *> Segments; | |
| 123 | llvm::SmallDenseMap<StringRef, OutputSegment *> SegmentMap; | |
| 124 | }; | |
| 125 | ||
| 126 | } // anonymous namespace | |
| 127 | ||
| 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() { | |
| 139 | uint32_t NumImports = FunctionImports.size() + GlobalImports.size(); | |
| 140 | if (Config->ImportMemory) | |
| 141 | ++NumImports; | |
| 142 | ||
| 143 | if (NumImports == 0) | |
| 144 | return; | |
| 145 | ||
| 146 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_IMPORT); | |
| 147 | raw_ostream &OS = Section->getStream(); | |
| 148 | ||
| 149 | writeUleb128(OS, NumImports, "import count"); | |
| 150 | ||
| 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) { | |
| 162 | WasmImport Import; | |
| 163 | Import.Module = "env"; | |
| 164 | Import.Field = "memory"; | |
| 165 | Import.Kind = WASM_EXTERNAL_MEMORY; | |
| 166 | Import.Memory.Flags = 0; | |
| 167 | Import.Memory.Initial = NumMemoryPages; | |
| 168 | writeImport(OS, Import); | |
| 169 | } | |
| 170 | ||
| 171 | for (const Symbol *Sym : GlobalImports) { | |
| 172 | WasmImport Import; | |
| 173 | Import.Module = "env"; | |
| 174 | Import.Field = Sym->getName(); | |
| 175 | Import.Kind = WASM_EXTERNAL_GLOBAL; | |
| 176 | Import.Global.Mutable = false; | |
| 177 | Import.Global.Type = WASM_TYPE_I32; | |
| 178 | writeImport(OS, Import); | |
| 179 | } | |
| 180 | } | |
| 181 | ||
| 182 | void Writer::createTypeSection() { | |
| 183 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_TYPE); | |
| 184 | raw_ostream &OS = Section->getStream(); | |
| 185 | writeUleb128(OS, Types.size(), "type count"); | |
| 186 | for (const WasmSignature *Sig : Types) | |
| 187 | writeSig(OS, *Sig); | |
| 188 | } | |
| 189 | ||
| 190 | void Writer::createFunctionSection() { | |
| 191 | if (!NumFunctions) | |
| 192 | return; | |
| 193 | ||
| 194 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_FUNCTION); | |
| 195 | raw_ostream &OS = Section->getStream(); | |
| 196 | ||
| 197 | writeUleb128(OS, NumFunctions, "function count"); | |
| 198 | for (ObjFile *File : Symtab->ObjectFiles) | |
| 199 | for (uint32_t Sig : File->getWasmObj()->functionTypes()) | |
| 200 | writeUleb128(OS, File->relocateTypeIndex(Sig), "sig index"); | |
| 201 | } | |
| 202 | ||
| 203 | void Writer::createMemorySection() { | |
| 204 | if (Config->ImportMemory) | |
| 205 | return; | |
| 206 | ||
| 207 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_MEMORY); | |
| 208 | raw_ostream &OS = Section->getStream(); | |
| 209 | ||
| 210 | writeUleb128(OS, 1, "memory count"); | |
| 211 | writeUleb128(OS, 0, "memory limits flags"); | |
| 212 | writeUleb128(OS, NumMemoryPages, "initial pages"); | |
| 213 | } | |
| 214 | ||
| 215 | void Writer::createGlobalSection() { | |
| 216 | if (DefinedGlobals.empty()) | |
| 217 | return; | |
| 218 | ||
| 219 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL); | |
| 220 | raw_ostream &OS = Section->getStream(); | |
| 221 | ||
| 222 | writeUleb128(OS, DefinedGlobals.size(), "global count"); | |
| 223 | for (const Symbol *Sym : DefinedGlobals) { | |
| 224 | WasmGlobal Global; | |
| 225 | Global.Type = WASM_TYPE_I32; | |
| 226 | Global.Mutable = Sym == Config->StackPointerSymbol; | |
| 227 | Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; | |
| 228 | Global.InitExpr.Value.Int32 = Sym->getVirtualAddress(); | |
| 229 | writeGlobal(OS, Global); | |
| 230 | } | |
| 231 | } | |
| 232 | ||
| 233 | void Writer::createTableSection() { | |
| 234 | // Always output a table section, even if there are no indirect calls. | |
| 235 | // There are two reasons for this: | |
| 236 | // 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. | |
| 238 | // 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 | |
| 240 | // a validation error to include a call_indirect instruction if there | |
| 241 | // is not table. | |
| 242 | uint32_t TableSize = InitialTableOffset + IndirectFunctions.size(); | |
| 243 | ||
| 244 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_TABLE); | |
| 245 | raw_ostream &OS = Section->getStream(); | |
| 246 | ||
| 247 | writeUleb128(OS, 1, "table count"); | |
| 248 | writeSleb128(OS, WASM_TYPE_ANYFUNC, "table type"); | |
| 249 | writeUleb128(OS, WASM_LIMITS_FLAG_HAS_MAX, "table flags"); | |
| 250 | writeUleb128(OS, TableSize, "table initial size"); | |
| 251 | writeUleb128(OS, TableSize, "table max size"); | |
| 252 | } | |
| 253 | ||
| 254 | void Writer::createExportSection() { | |
| 255 | bool ExportMemory = !Config->Relocatable && !Config->ImportMemory; | |
| 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; | |
| 287 | ||
| 288 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_EXPORT); | |
| 289 | raw_ostream &OS = Section->getStream(); | |
| 290 | ||
| 291 | writeUleb128(OS, NumExports, "export count"); | |
| 292 | ||
| 293 | if (ExportMemory) { | |
| 294 | WasmExport MemoryExport; | |
| 295 | MemoryExport.Name = "memory"; | |
| 296 | MemoryExport.Kind = WASM_EXTERNAL_MEMORY; | |
| 297 | MemoryExport.Index = 0; | |
| 298 | writeExport(OS, MemoryExport); | |
| 299 | } | |
| 300 | ||
| 301 | for (const Symbol *Sym : SymbolExports) { | |
| 302 | log("Export: " + Sym->getName()); | |
| 303 | WasmExport Export; | |
| 304 | Export.Name = Sym->getName(); | |
| 305 | Export.Index = Sym->getOutputIndex(); | |
| 306 | if (Sym->isFunction()) | |
| 307 | Export.Kind = WASM_EXTERNAL_FUNCTION; | |
| 308 | else | |
| 309 | Export.Kind = WASM_EXTERNAL_GLOBAL; | |
| 310 | writeExport(OS, Export); | |
| 311 | } | |
| 312 | } | |
| 313 | ||
| 314 | void Writer::createStartSection() {} | |
| 315 | ||
| 316 | void Writer::createElemSection() { | |
| 317 | if (IndirectFunctions.empty()) | |
| 318 | return; | |
| 319 | ||
| 320 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_ELEM); | |
| 321 | raw_ostream &OS = Section->getStream(); | |
| 322 | ||
| 323 | writeUleb128(OS, 1, "segment count"); | |
| 324 | writeUleb128(OS, 0, "table index"); | |
| 325 | WasmInitExpr InitExpr; | |
| 326 | InitExpr.Opcode = WASM_OPCODE_I32_CONST; | |
| 327 | InitExpr.Value.Int32 = InitialTableOffset; | |
| 328 | writeInitExpr(OS, InitExpr); | |
| 329 | writeUleb128(OS, IndirectFunctions.size(), "elem count"); | |
| 330 | ||
| 331 | uint32_t TableIndex = InitialTableOffset; | |
| 332 | for (const Symbol *Sym : IndirectFunctions) { | |
| 333 | assert(Sym->getTableIndex() == TableIndex); | |
| 334 | writeUleb128(OS, Sym->getOutputIndex(), "function index"); | |
| 335 | ++TableIndex; | |
| 336 | } | |
| 337 | } | |
| 338 | ||
| 339 | void Writer::createCodeSection() { | |
| 340 | if (!NumFunctions) | |
| 341 | return; | |
| 342 | ||
| 343 | log("createCodeSection"); | |
| 344 | ||
| 345 | auto Section = make<CodeSection>(NumFunctions, Symtab->ObjectFiles); | |
| 346 | OutputSections.push_back(Section); | |
| 347 | } | |
| 348 | ||
| 349 | void Writer::createDataSection() { | |
| 350 | if (!Segments.size()) | |
| 351 | return; | |
| 352 | ||
| 353 | log("createDataSection"); | |
| 354 | auto Section = make<DataSection>(Segments); | |
| 355 | OutputSections.push_back(Section); | |
| 356 | } | |
| 357 | ||
| 358 | // Create relocations sections in the final output. | |
| 359 | // These are only created when relocatable output is requested. | |
| 360 | void Writer::createRelocSections() { | |
| 361 | log("createRelocSections"); | |
| 362 | // Don't use iterator here since we are adding to OutputSection | |
| 363 | size_t OrigSize = OutputSections.size(); | |
| 364 | for (size_t i = 0; i < OrigSize; i++) { | |
| 365 | OutputSection *S = OutputSections[i]; | |
| 366 | const char *name; | |
| 367 | uint32_t Count = S->numRelocations(); | |
| 368 | if (!Count) | |
| 369 | continue; | |
| 370 | ||
| 371 | if (S->Type == WASM_SEC_DATA) | |
| 372 | name = "reloc.DATA"; | |
| 373 | else if (S->Type == WASM_SEC_CODE) | |
| 374 | name = "reloc.CODE"; | |
| 375 | else | |
| 376 | llvm_unreachable("relocations only supported for code and data"); | |
| 377 | ||
| 378 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, name); | |
| 379 | raw_ostream &OS = Section->getStream(); | |
| 380 | writeUleb128(OS, S->Type, "reloc section"); | |
| 381 | writeUleb128(OS, Count, "reloc count"); | |
| 382 | S->writeRelocations(OS); | |
| 383 | } | |
| 384 | } | |
| 385 | ||
| 386 | // Create the custom "linking" section containing linker metadata. | |
| 387 | // This is only created when relocatable output is requested. | |
| 388 | void Writer::createLinkingSection() { | |
| 389 | SyntheticSection *Section = | |
| 390 | createSyntheticSection(WASM_SEC_CUSTOM, "linking"); | |
| 391 | raw_ostream &OS = Section->getStream(); | |
| 392 | ||
| 393 | SubSection DataSizeSubSection(WASM_DATA_SIZE); | |
| 394 | writeUleb128(DataSizeSubSection.getStream(), DataSize, "data size"); | |
| 395 | DataSizeSubSection.finalizeContents(); | |
| 396 | DataSizeSubSection.writeToStream(OS); | |
| 397 | ||
| 398 | if (!Config->Relocatable) | |
| 399 | return; | |
| 400 | ||
| 401 | if (Segments.size()) { | |
| 402 | SubSection SubSection(WASM_SEGMENT_INFO); | |
| 403 | writeUleb128(SubSection.getStream(), Segments.size(), "num data segments"); | |
| 404 | for (const OutputSegment *S : Segments) { | |
| 405 | writeStr(SubSection.getStream(), S->Name, "segment name"); | |
| 406 | writeUleb128(SubSection.getStream(), S->Alignment, "alignment"); | |
| 407 | writeUleb128(SubSection.getStream(), 0, "flags"); | |
| 408 | } | |
| 409 | SubSection.finalizeContents(); | |
| 410 | SubSection.writeToStream(OS); | |
| 411 | } | |
| 412 | ||
| 413 | std::vector<WasmInitFunc> InitFunctions; | |
| 414 | for (ObjFile *File : Symtab->ObjectFiles) { | |
| 415 | const WasmLinkingData &L = File->getWasmObj()->linkingData(); | |
| 416 | InitFunctions.reserve(InitFunctions.size() + L.InitFunctions.size()); | |
| 417 | for (const WasmInitFunc &F : L.InitFunctions) | |
| 418 | InitFunctions.emplace_back(WasmInitFunc{ | |
| 419 | F.Priority, File->relocateFunctionIndex(F.FunctionIndex)}); | |
| 420 | } | |
| 421 | ||
| 422 | if (!InitFunctions.empty()) { | |
| 423 | SubSection SubSection(WASM_INIT_FUNCS); | |
| 424 | writeUleb128(SubSection.getStream(), InitFunctions.size(), | |
| 425 | "num init functionsw"); | |
| 426 | for (const WasmInitFunc &F : InitFunctions) { | |
| 427 | writeUleb128(SubSection.getStream(), F.Priority, "priority"); | |
| 428 | writeUleb128(SubSection.getStream(), F.FunctionIndex, "function index"); | |
| 429 | } | |
| 430 | SubSection.finalizeContents(); | |
| 431 | SubSection.writeToStream(OS); | |
| 432 | } | |
| 433 | } | |
| 434 | ||
| 435 | // Create the custom "name" section containing debug symbol names. | |
| 436 | void Writer::createNameSection() { | |
| 437 | // Create an array of all function sorted by function index space | |
| 438 | std::vector<const Symbol *> Names; | |
| 439 | ||
| 440 | for (ObjFile *File : Symtab->ObjectFiles) { | |
| 441 | Names.reserve(Names.size() + File->getSymbols().size()); | |
| 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 | ||
| 450 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "name"); | |
| 451 | ||
| 452 | std::sort(Names.begin(), Names.end(), [](const Symbol *A, const Symbol *B) { | |
| 453 | return A->getOutputIndex() < B->getOutputIndex(); | |
| 454 | }); | |
| 455 | ||
| 456 | SubSection FunctionSubsection(WASM_NAMES_FUNCTION); | |
| 457 | raw_ostream &OS = FunctionSubsection.getStream(); | |
| 458 | writeUleb128(OS, Names.size(), "name count"); | |
| 459 | ||
| 460 | // We have to iterate through the inputs twice so that all the imports | |
| 461 | // appear first before any of the local function names. | |
| 462 | for (const Symbol *S : Names) { | |
| 463 | writeUleb128(OS, S->getOutputIndex(), "func index"); | |
| 464 | writeStr(OS, S->getName(), "symbol name"); | |
| 465 | } | |
| 466 | ||
| 467 | FunctionSubsection.finalizeContents(); | |
| 468 | FunctionSubsection.writeToStream(Section->getStream()); | |
| 469 | } | |
| 470 | ||
| 471 | void Writer::writeHeader() { | |
| 472 | memcpy(Buffer->getBufferStart(), Header.data(), Header.size()); | |
| 473 | } | |
| 474 | ||
| 475 | void Writer::writeSections() { | |
| 476 | uint8_t *Buf = Buffer->getBufferStart(); | |
| 477 | parallelForEach(OutputSections, [Buf](OutputSection *S) { S->writeTo(Buf); }); | |
| 478 | } | |
| 479 | ||
| 480 | // 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. | |
| 482 | void Writer::layoutMemory() { | |
| 483 | uint32_t MemoryPtr = 0; | |
| 484 | if (!Config->Relocatable) { | |
| 485 | MemoryPtr = Config->GlobalBase; | |
| 486 | debugPrint("mem: global base = %d\n", Config->GlobalBase); | |
| 487 | } | |
| 488 | ||
| 489 | createOutputSegments(); | |
| 490 | ||
| 491 | // Static data comes first | |
| 492 | for (OutputSegment *Seg : Segments) { | |
| 493 | MemoryPtr = alignTo(MemoryPtr, Seg->Alignment); | |
| 494 | Seg->StartVA = MemoryPtr; | |
| 495 | debugPrint("mem: %-10s offset=%-8d size=%-4d align=%d\n", | |
| 496 | Seg->Name.str().c_str(), MemoryPtr, Seg->Size, Seg->Alignment); | |
| 497 | MemoryPtr += Seg->Size; | |
| 498 | } | |
| 499 | ||
| 500 | DataSize = MemoryPtr; | |
| 501 | if (!Config->Relocatable) | |
| 502 | DataSize -= Config->GlobalBase; | |
| 503 | debugPrint("mem: static data = %d\n", DataSize); | |
| 504 | ||
| 505 | // Stack comes after static data | |
| 506 | if (!Config->Relocatable) { | |
| 507 | MemoryPtr = alignTo(MemoryPtr, kStackAlignment); | |
| 508 | if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment)) | |
| 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 | } | |
| 516 | ||
| 517 | uint32_t MemSize = alignTo(MemoryPtr, WasmPageSize); | |
| 518 | NumMemoryPages = MemSize / WasmPageSize; | |
| 519 | debugPrint("mem: total pages = %d\n", NumMemoryPages); | |
| 520 | } | |
| 521 | ||
| 522 | SyntheticSection *Writer::createSyntheticSection(uint32_t Type, | |
| 523 | std::string Name) { | |
| 524 | auto Sec = make<SyntheticSection>(Type, Name); | |
| 525 | log("createSection: " + toString(*Sec)); | |
| 526 | OutputSections.push_back(Sec); | |
| 527 | return Sec; | |
| 528 | } | |
| 529 | ||
| 530 | void Writer::createSections() { | |
| 531 | // Known sections | |
| 532 | createTypeSection(); | |
| 533 | createImportSection(); | |
| 534 | createFunctionSection(); | |
| 535 | createTableSection(); | |
| 536 | createMemorySection(); | |
| 537 | createGlobalSection(); | |
| 538 | createExportSection(); | |
| 539 | createStartSection(); | |
| 540 | createElemSection(); | |
| 541 | createCodeSection(); | |
| 542 | createDataSection(); | |
| 543 | ||
| 544 | // Custom sections | |
| 545 | if (Config->EmitRelocs) | |
| 546 | createRelocSections(); | |
| 547 | createLinkingSection(); | |
| 548 | if (!Config->StripDebug && !Config->StripAll) | |
| 549 | createNameSection(); | |
| 550 | ||
| 551 | for (OutputSection *S : OutputSections) { | |
| 552 | S->setOffset(FileSize); | |
| 553 | S->finalizeContents(); | |
| 554 | FileSize += S->getSize(); | |
| 555 | } | |
| 556 | } | |
| 557 | ||
| 558 | void Writer::calculateOffsets() { | |
| 559 | for (ObjFile *File : Symtab->ObjectFiles) { | |
| 560 | const WasmObjectFile *WasmFile = File->getWasmObj(); | |
| 561 | ||
| 562 | // Function Index | |
| 563 | File->FunctionIndexOffset = | |
| 564 | FunctionImports.size() - File->NumFunctionImports() + NumFunctions; | |
| 565 | NumFunctions += WasmFile->functions().size(); | |
| 566 | ||
| 567 | // Memory | |
| 568 | if (WasmFile->memories().size() > 1) | |
| 569 | fatal(File->getName() + ": contains more than one memory"); | |
| 570 | } | |
| 571 | } | |
| 572 | ||
| 573 | void Writer::calculateImports() { | |
| 574 | for (Symbol *Sym : Symtab->getSymbols()) { | |
| 575 | if (!Sym->isUndefined() || Sym->isWeak()) | |
| 576 | continue; | |
| 577 | ||
| 578 | if (Sym->isFunction()) { | |
| 579 | Sym->setOutputIndex(FunctionImports.size()); | |
| 580 | FunctionImports.push_back(Sym); | |
| 581 | } else { | |
| 582 | Sym->setOutputIndex(GlobalImports.size()); | |
| 583 | GlobalImports.push_back(Sym); | |
| 584 | } | |
| 585 | } | |
| 586 | } | |
| 587 | ||
| 588 | uint32_t Writer::getTypeIndex(const WasmSignature &Sig) { | |
| 589 | auto Pair = TypeIndices.insert(std::make_pair(Sig, Types.size())); | |
| 590 | if (Pair.second) | |
| 591 | Types.push_back(&Sig); | |
| 592 | return Pair.first->second; | |
| 593 | } | |
| 594 | ||
| 595 | void Writer::calculateTypes() { | |
| 596 | for (ObjFile *File : Symtab->ObjectFiles) { | |
| 597 | File->TypeMap.reserve(File->getWasmObj()->types().size()); | |
| 598 | for (const WasmSignature &Sig : File->getWasmObj()->types()) | |
| 599 | File->TypeMap.push_back(getTypeIndex(Sig)); | |
| 600 | } | |
| 601 | } | |
| 602 | ||
| 603 | void Writer::assignSymbolIndexes() { | |
| 604 | uint32_t GlobalIndex = GlobalImports.size(); | |
| 605 | ||
| 606 | if (Config->StackPointerSymbol) { | |
| 607 | DefinedGlobals.emplace_back(Config->StackPointerSymbol); | |
| 608 | Config->StackPointerSymbol->setOutputIndex(GlobalIndex++); | |
| 609 | } | |
| 610 | ||
| 611 | if (Config->EmitRelocs) | |
| 612 | DefinedGlobals.reserve(Symtab->getSymbols().size()); | |
| 613 | ||
| 614 | uint32_t TableIndex = InitialTableOffset; | |
| 615 | ||
| 616 | for (ObjFile *File : Symtab->ObjectFiles) { | |
| 617 | DEBUG(dbgs() << "assignSymbolIndexes: " << File->getName() << "\n"); | |
| 618 | ||
| 619 | for (Symbol *Sym : File->getSymbols()) { | |
| 620 | // Assign indexes for symbols defined with this file. | |
| 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 | ||
| 633 | for (Symbol *Sym : File->getTableSymbols()) { | |
| 634 | if (!Sym->hasTableIndex()) { | |
| 635 | Sym->setTableIndex(TableIndex++); | |
| 636 | IndirectFunctions.emplace_back(Sym); | |
| 637 | } | |
| 638 | } | |
| 639 | } | |
| 640 | } | |
| 641 | ||
| 642 | static StringRef getOutputDataSegmentName(StringRef Name) { | |
| 643 | if (Config->Relocatable) | |
| 644 | return Name; | |
| 645 | ||
| 646 | for (StringRef V : | |
| 647 | {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.", | |
| 648 | ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.", | |
| 649 | ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."}) { | |
| 650 | StringRef Prefix = V.drop_back(); | |
| 651 | if (Name.startswith(V) || Name == Prefix) | |
| 652 | return Prefix; | |
| 653 | } | |
| 654 | ||
| 655 | return Name; | |
| 656 | } | |
| 657 | ||
| 658 | void Writer::createOutputSegments() { | |
| 659 | for (ObjFile *File : Symtab->ObjectFiles) { | |
| 660 | for (InputSegment *Segment : File->Segments) { | |
| 661 | StringRef Name = getOutputDataSegmentName(Segment->getName()); | |
| 662 | OutputSegment *&S = SegmentMap[Name]; | |
| 663 | if (S == nullptr) { | |
| 664 | DEBUG(dbgs() << "new segment: " << Name << "\n"); | |
| 665 | S = make<OutputSegment>(Name); | |
| 666 | Segments.push_back(S); | |
| 667 | } | |
| 668 | S->addInputSegment(Segment); | |
| 669 | DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n"); | |
| 670 | } | |
| 671 | } | |
| 672 | } | |
| 673 | ||
| 674 | void Writer::run() { | |
| 675 | if (!Config->Relocatable) | |
| 676 | InitialTableOffset = 1; | |
| 677 | ||
| 678 | log("-- calculateTypes"); | |
| 679 | calculateTypes(); | |
| 680 | log("-- calculateImports"); | |
| 681 | calculateImports(); | |
| 682 | log("-- calculateOffsets"); | |
| 683 | calculateOffsets(); | |
| 684 | ||
| 685 | if (errorHandler().Verbose) { | |
| 686 | log("Defined Functions: " + Twine(NumFunctions)); | |
| 687 | log("Defined Globals : " + Twine(DefinedGlobals.size())); | |
| 688 | log("Function Imports : " + Twine(FunctionImports.size())); | |
| 689 | log("Global Imports : " + Twine(GlobalImports.size())); | |
| 690 | log("Total Imports : " + | |
| 691 | Twine(FunctionImports.size() + GlobalImports.size())); | |
| 692 | for (ObjFile *File : Symtab->ObjectFiles) | |
| 693 | File->dumpInfo(); | |
| 694 | } | |
| 695 | ||
| 696 | log("-- assignSymbolIndexes"); | |
| 697 | assignSymbolIndexes(); | |
| 698 | log("-- layoutMemory"); | |
| 699 | layoutMemory(); | |
| 700 | ||
| 701 | createHeader(); | |
| 702 | log("-- createSections"); | |
| 703 | createSections(); | |
| 704 | ||
| 705 | log("-- openFile"); | |
| 706 | openFile(); | |
| 707 | if (errorCount()) | |
| 708 | return; | |
| 709 | ||
| 710 | writeHeader(); | |
| 711 | ||
| 712 | log("-- writeSections"); | |
| 713 | writeSections(); | |
| 714 | if (errorCount()) | |
| 715 | return; | |
| 716 | ||
| 717 | if (Error E = Buffer->commit()) | |
| 718 | fatal("failed to write the output file: " + toString(std::move(E))); | |
| 719 | } | |
| 720 | ||
| 721 | // Open a result file. | |
| 722 | void Writer::openFile() { | |
| 723 | log("writing: " + Config->OutputFile); | |
| 724 | ::remove(Config->OutputFile.str().c_str()); | |
| 725 | ||
| 726 | Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = | |
| 727 | FileOutputBuffer::create(Config->OutputFile, FileSize, | |
| 728 | FileOutputBuffer::F_executable); | |
| 729 | ||
| 730 | if (!BufferOrErr) | |
| 731 | error("failed to open " + Config->OutputFile + ": " + | |
| 732 | toString(BufferOrErr.takeError())); | |
| 733 | else | |
| 734 | Buffer = std::move(*BufferOrErr); | |
| 735 | } | |
| 736 | ||
| 737 | void Writer::createHeader() { | |
| 738 | raw_string_ostream OS(Header); | |
| 739 | writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic"); | |
| 740 | writeU32(OS, WasmVersion, "wasm version"); | |
| 741 | OS.flush(); | |
| 742 | FileSize += Header.size(); | |
| 743 | } | |
| 744 | ||
| 745 | void lld::wasm::writeResult() { Writer().run(); } |
deps/lld/wasm/Writer.h created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | //===- Writer.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_WRITER_H | |
| 11 | #define LLD_WASM_WRITER_H | |
| 12 | ||
| 13 | namespace lld { | |
| 14 | namespace wasm { | |
| 15 | ||
| 16 | void writeResult(); | |
| 17 | ||
| 18 | } // namespace wasm | |
| 19 | } // namespace lld | |
| 20 | ||
| 21 | #endif |
deps/lld/wasm/WriterUtils.cpp created+215| ... | ... | @@ -0,0 +1,215 @@ |
| 1 | //===- WriterUtils.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 "WriterUtils.h" | |
| 11 | ||
| 12 | #include "lld/Common/ErrorHandler.h" | |
| 13 | ||
| 14 | #include "llvm/Support/Debug.h" | |
| 15 | #include "llvm/Support/EndianStream.h" | |
| 16 | #include "llvm/Support/FormatVariadic.h" | |
| 17 | #include "llvm/Support/LEB128.h" | |
| 18 | ||
| 19 | #define DEBUG_TYPE "lld" | |
| 20 | ||
| 21 | using namespace llvm; | |
| 22 | using namespace llvm::wasm; | |
| 23 | using namespace lld::wasm; | |
| 24 | ||
| 25 | static const char *valueTypeToString(int32_t Type) { | |
| 26 | switch (Type) { | |
| 27 | case WASM_TYPE_I32: | |
| 28 | return "i32"; | |
| 29 | case WASM_TYPE_I64: | |
| 30 | return "i64"; | |
| 31 | case WASM_TYPE_F32: | |
| 32 | return "f32"; | |
| 33 | case WASM_TYPE_F64: | |
| 34 | return "f64"; | |
| 35 | default: | |
| 36 | llvm_unreachable("invalid value type"); | |
| 37 | } | |
| 38 | } | |
| 39 | ||
| 40 | namespace lld { | |
| 41 | ||
| 42 | void wasm::debugWrite(uint64_t offset, Twine msg) { | |
| 43 | DEBUG(dbgs() << format(" | %08" PRIx64 ": ", offset) << msg << "\n"); | |
| 44 | } | |
| 45 | ||
| 46 | void wasm::writeUleb128(raw_ostream &OS, uint32_t Number, const char *msg) { | |
| 47 | if (msg) | |
| 48 | debugWrite(OS.tell(), msg + formatv(" [{0:x}]", Number)); | |
| 49 | encodeULEB128(Number, OS); | |
| 50 | } | |
| 51 | ||
| 52 | void wasm::writeSleb128(raw_ostream &OS, int32_t Number, const char *msg) { | |
| 53 | if (msg) | |
| 54 | debugWrite(OS.tell(), msg + formatv(" [{0:x}]", Number)); | |
| 55 | encodeSLEB128(Number, OS); | |
| 56 | } | |
| 57 | ||
| 58 | void wasm::writeBytes(raw_ostream &OS, const char *bytes, size_t count, | |
| 59 | const char *msg) { | |
| 60 | if (msg) | |
| 61 | debugWrite(OS.tell(), msg + formatv(" [data[{0}]]", count)); | |
| 62 | OS.write(bytes, count); | |
| 63 | } | |
| 64 | ||
| 65 | void wasm::writeStr(raw_ostream &OS, const StringRef String, const char *msg) { | |
| 66 | if (msg) | |
| 67 | debugWrite(OS.tell(), | |
| 68 | msg + formatv(" [str[{0}]: {1}]", String.size(), String)); | |
| 69 | writeUleb128(OS, String.size(), nullptr); | |
| 70 | writeBytes(OS, String.data(), String.size()); | |
| 71 | } | |
| 72 | ||
| 73 | void wasm::writeU8(raw_ostream &OS, uint8_t byte, const char *msg) { | |
| 74 | OS << byte; | |
| 75 | } | |
| 76 | ||
| 77 | void wasm::writeU32(raw_ostream &OS, uint32_t Number, const char *msg) { | |
| 78 | debugWrite(OS.tell(), msg + formatv("[{0:x}]", Number)); | |
| 79 | support::endian::Writer<support::little>(OS).write(Number); | |
| 80 | } | |
| 81 | ||
| 82 | void wasm::writeValueType(raw_ostream &OS, int32_t Type, const char *msg) { | |
| 83 | debugWrite(OS.tell(), msg + formatv("[type: {0}]", valueTypeToString(Type))); | |
| 84 | writeSleb128(OS, Type, nullptr); | |
| 85 | } | |
| 86 | ||
| 87 | void wasm::writeSig(raw_ostream &OS, const WasmSignature &Sig) { | |
| 88 | writeSleb128(OS, WASM_TYPE_FUNC, "signature type"); | |
| 89 | writeUleb128(OS, Sig.ParamTypes.size(), "param count"); | |
| 90 | for (int32_t ParamType : Sig.ParamTypes) { | |
| 91 | writeValueType(OS, ParamType, "param type"); | |
| 92 | } | |
| 93 | if (Sig.ReturnType == WASM_TYPE_NORESULT) { | |
| 94 | writeUleb128(OS, 0, "result count"); | |
| 95 | } else { | |
| 96 | writeUleb128(OS, 1, "result count"); | |
| 97 | writeValueType(OS, Sig.ReturnType, "result type"); | |
| 98 | } | |
| 99 | } | |
| 100 | ||
| 101 | void wasm::writeInitExpr(raw_ostream &OS, const WasmInitExpr &InitExpr) { | |
| 102 | writeU8(OS, InitExpr.Opcode, "opcode"); | |
| 103 | switch (InitExpr.Opcode) { | |
| 104 | case WASM_OPCODE_I32_CONST: | |
| 105 | writeSleb128(OS, InitExpr.Value.Int32, "literal (i32)"); | |
| 106 | break; | |
| 107 | case WASM_OPCODE_I64_CONST: | |
| 108 | writeSleb128(OS, InitExpr.Value.Int64, "literal (i64)"); | |
| 109 | break; | |
| 110 | case WASM_OPCODE_GET_GLOBAL: | |
| 111 | writeUleb128(OS, InitExpr.Value.Global, "literal (global index)"); | |
| 112 | break; | |
| 113 | default: | |
| 114 | fatal("unknown opcode in init expr: " + Twine(InitExpr.Opcode)); | |
| 115 | } | |
| 116 | writeU8(OS, WASM_OPCODE_END, "opcode:end"); | |
| 117 | } | |
| 118 | ||
| 119 | void wasm::writeLimits(raw_ostream &OS, const WasmLimits &Limits) { | |
| 120 | writeUleb128(OS, Limits.Flags, "limits flags"); | |
| 121 | writeUleb128(OS, Limits.Initial, "limits initial"); | |
| 122 | if (Limits.Flags & WASM_LIMITS_FLAG_HAS_MAX) | |
| 123 | writeUleb128(OS, Limits.Maximum, "limits max"); | |
| 124 | } | |
| 125 | ||
| 126 | void wasm::writeGlobal(raw_ostream &OS, const WasmGlobal &Global) { | |
| 127 | writeValueType(OS, Global.Type, "global type"); | |
| 128 | writeUleb128(OS, Global.Mutable, "global mutable"); | |
| 129 | writeInitExpr(OS, Global.InitExpr); | |
| 130 | } | |
| 131 | ||
| 132 | void wasm::writeImport(raw_ostream &OS, const WasmImport &Import) { | |
| 133 | writeStr(OS, Import.Module, "import module name"); | |
| 134 | writeStr(OS, Import.Field, "import field name"); | |
| 135 | writeU8(OS, Import.Kind, "import kind"); | |
| 136 | switch (Import.Kind) { | |
| 137 | case WASM_EXTERNAL_FUNCTION: | |
| 138 | writeUleb128(OS, Import.SigIndex, "import sig index"); | |
| 139 | break; | |
| 140 | case WASM_EXTERNAL_GLOBAL: | |
| 141 | writeValueType(OS, Import.Global.Type, "import global type"); | |
| 142 | writeUleb128(OS, Import.Global.Mutable, "import global mutable"); | |
| 143 | break; | |
| 144 | case WASM_EXTERNAL_MEMORY: | |
| 145 | writeLimits(OS, Import.Memory); | |
| 146 | break; | |
| 147 | default: | |
| 148 | fatal("unsupported import type: " + Twine(Import.Kind)); | |
| 149 | } | |
| 150 | } | |
| 151 | ||
| 152 | void wasm::writeExport(raw_ostream &OS, const WasmExport &Export) { | |
| 153 | writeStr(OS, Export.Name, "export name"); | |
| 154 | writeU8(OS, Export.Kind, "export kind"); | |
| 155 | switch (Export.Kind) { | |
| 156 | case WASM_EXTERNAL_FUNCTION: | |
| 157 | writeUleb128(OS, Export.Index, "function index"); | |
| 158 | break; | |
| 159 | case WASM_EXTERNAL_GLOBAL: | |
| 160 | writeUleb128(OS, Export.Index, "global index"); | |
| 161 | break; | |
| 162 | case WASM_EXTERNAL_MEMORY: | |
| 163 | writeUleb128(OS, Export.Index, "memory index"); | |
| 164 | break; | |
| 165 | default: | |
| 166 | fatal("unsupported export type: " + Twine(Export.Kind)); | |
| 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; | |
| 181 | default: | |
| 182 | break; | |
| 183 | } | |
| 184 | } | |
| 185 | ||
| 186 | } // namespace lld | |
| 187 | ||
| 188 | std::string lld::toString(ValType Type) { | |
| 189 | switch (Type) { | |
| 190 | case ValType::I32: | |
| 191 | return "I32"; | |
| 192 | case ValType::I64: | |
| 193 | return "I64"; | |
| 194 | case ValType::F32: | |
| 195 | return "F32"; | |
| 196 | case ValType::F64: | |
| 197 | return "F64"; | |
| 198 | } | |
| 199 | llvm_unreachable("Invalid wasm::ValType"); | |
| 200 | } | |
| 201 | ||
| 202 | std::string lld::toString(const WasmSignature &Sig) { | |
| 203 | SmallString<128> S("("); | |
| 204 | for (uint32_t Type : Sig.ParamTypes) { | |
| 205 | if (S.size() != 1) | |
| 206 | S += ", "; | |
| 207 | S += toString(static_cast<ValType>(Type)); | |
| 208 | } | |
| 209 | S += ") -> "; | |
| 210 | if (Sig.ReturnType == WASM_TYPE_NORESULT) | |
| 211 | S += "void"; | |
| 212 | else | |
| 213 | S += toString(static_cast<ValType>(Sig.ReturnType)); | |
| 214 | return S.str(); | |
| 215 | } |
deps/lld/wasm/WriterUtils.h created+78| ... | ... | @@ -0,0 +1,78 @@ |
| 1 | //===- WriterUtils.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_WRITERUTILS_H | |
| 11 | #define LLD_WASM_WRITERUTILS_H | |
| 12 | ||
| 13 | #include "llvm/ADT/Twine.h" | |
| 14 | #include "llvm/Object/Wasm.h" | |
| 15 | #include "llvm/Support/raw_ostream.h" | |
| 16 | ||
| 17 | using llvm::raw_ostream; | |
| 18 | ||
| 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 { | |
| 31 | namespace wasm { | |
| 32 | ||
| 33 | struct OutputRelocation { | |
| 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 | ||
| 41 | void writeUleb128(raw_ostream &OS, uint32_t Number, const char *msg); | |
| 42 | ||
| 43 | void writeSleb128(raw_ostream &OS, int32_t Number, const char *msg); | |
| 44 | ||
| 45 | void writeBytes(raw_ostream &OS, const char *bytes, size_t count, | |
| 46 | const char *msg = nullptr); | |
| 47 | ||
| 48 | void writeStr(raw_ostream &OS, const llvm::StringRef String, | |
| 49 | const char *msg = nullptr); | |
| 50 | ||
| 51 | void writeU8(raw_ostream &OS, uint8_t byte, const char *msg); | |
| 52 | ||
| 53 | void writeU32(raw_ostream &OS, uint32_t Number, const char *msg); | |
| 54 | ||
| 55 | void writeValueType(raw_ostream &OS, int32_t Type, const char *msg); | |
| 56 | ||
| 57 | void writeSig(raw_ostream &OS, const llvm::wasm::WasmSignature &Sig); | |
| 58 | ||
| 59 | void writeInitExpr(raw_ostream &OS, const llvm::wasm::WasmInitExpr &InitExpr); | |
| 60 | ||
| 61 | void writeLimits(raw_ostream &OS, const llvm::wasm::WasmLimits &Limits); | |
| 62 | ||
| 63 | void writeGlobal(raw_ostream &OS, const llvm::wasm::WasmGlobal &Global); | |
| 64 | ||
| 65 | void writeImport(raw_ostream &OS, const llvm::wasm::WasmImport &Import); | |
| 66 | ||
| 67 | void writeExport(raw_ostream &OS, const llvm::wasm::WasmExport &Export); | |
| 68 | ||
| 69 | void writeReloc(raw_ostream &OS, const OutputRelocation &Reloc); | |
| 70 | ||
| 71 | } // namespace wasm | |
| 72 | ||
| 73 | std::string toString(const llvm::wasm::ValType Type); | |
| 74 | std::string toString(const llvm::wasm::WasmSignature &Sig); | |
| 75 | ||
| 76 | } // namespace lld | |
| 77 | ||
| 78 | #endif // LLD_WASM_WRITERUTILS_H |
src/target.cpp+27-1| ... | ... | @@ -13,6 +13,7 @@ |
| 13 | 13 | #include <stdio.h> |
| 14 | 14 | |
| 15 | 15 | static const ArchType arch_list[] = { |
| 16 | {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8_3a}, | |
| 16 | 17 | {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8_2a}, |
| 17 | 18 | {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8_1a}, |
| 18 | 19 | {ZigLLVM_arm, ZigLLVM_ARMSubArch_v8}, |
| ... | ... | @@ -33,9 +34,30 @@ static const ArchType arch_list[] = { |
| 33 | 34 | {ZigLLVM_arm, ZigLLVM_ARMSubArch_v5te}, |
| 34 | 35 | {ZigLLVM_arm, ZigLLVM_ARMSubArch_v4t}, |
| 35 | 36 | |
| 36 | {ZigLLVM_armeb, ZigLLVM_NoSubArch}, | |
| 37 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8_3a}, | |
| 38 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8_2a}, | |
| 39 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8_1a}, | |
| 40 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8}, | |
| 41 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8r}, | |
| 42 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8m_baseline}, | |
| 43 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v8m_mainline}, | |
| 44 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7}, | |
| 45 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7em}, | |
| 46 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7m}, | |
| 47 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7s}, | |
| 48 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7k}, | |
| 49 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v7ve}, | |
| 50 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6}, | |
| 51 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6m}, | |
| 52 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6k}, | |
| 53 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v6t2}, | |
| 54 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v5}, | |
| 55 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v5te}, | |
| 56 | {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v4t}, | |
| 57 | ||
| 37 | 58 | {ZigLLVM_aarch64, ZigLLVM_NoSubArch}, |
| 38 | 59 | {ZigLLVM_aarch64_be, ZigLLVM_NoSubArch}, |
| 60 | {ZigLLVM_arc, ZigLLVM_NoSubArch}, | |
| 39 | 61 | {ZigLLVM_avr, ZigLLVM_NoSubArch}, |
| 40 | 62 | {ZigLLVM_bpfel, ZigLLVM_NoSubArch}, |
| 41 | 63 | {ZigLLVM_bpfeb, ZigLLVM_NoSubArch}, |
| ... | ... | @@ -144,6 +166,7 @@ static const ZigLLVM_EnvironmentType environ_list[] = { |
| 144 | 166 | ZigLLVM_UnknownEnvironment, |
| 145 | 167 | |
| 146 | 168 | ZigLLVM_GNU, |
| 169 | ZigLLVM_GNUABIN32, | |
| 147 | 170 | ZigLLVM_GNUABI64, |
| 148 | 171 | ZigLLVM_GNUEABI, |
| 149 | 172 | ZigLLVM_GNUEABIHF, |
| ... | ... | @@ -161,6 +184,7 @@ static const ZigLLVM_EnvironmentType environ_list[] = { |
| 161 | 184 | ZigLLVM_AMDOpenCL, |
| 162 | 185 | ZigLLVM_CoreCLR, |
| 163 | 186 | ZigLLVM_OpenCL, |
| 187 | ZigLLVM_Simulator, | |
| 164 | 188 | }; |
| 165 | 189 | |
| 166 | 190 | static const ZigLLVM_ObjectFormatType oformat_list[] = { |
| ... | ... | @@ -521,6 +545,7 @@ void resolve_target_object_format(ZigTarget *target) { |
| 521 | 545 | case ZigLLVM_amdil: |
| 522 | 546 | case ZigLLVM_amdil64: |
| 523 | 547 | case ZigLLVM_armeb: |
| 548 | case ZigLLVM_arc: | |
| 524 | 549 | case ZigLLVM_avr: |
| 525 | 550 | case ZigLLVM_bpfeb: |
| 526 | 551 | case ZigLLVM_bpfel: |
| ... | ... | @@ -583,6 +608,7 @@ static int get_arch_pointer_bit_width(ZigLLVM_ArchType arch) { |
| 583 | 608 | case ZigLLVM_msp430: |
| 584 | 609 | return 16; |
| 585 | 610 | |
| 611 | case ZigLLVM_arc: | |
| 586 | 612 | case ZigLLVM_arm: |
| 587 | 613 | case ZigLLVM_armeb: |
| 588 | 614 | case ZigLLVM_hexagon: |
src/translate_c.cpp+9| ... | ... | @@ -760,6 +760,8 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou |
| 760 | 760 | return trans_create_node_symbol_str(c, "f64"); |
| 761 | 761 | case BuiltinType::Float128: |
| 762 | 762 | return trans_create_node_symbol_str(c, "f128"); |
| 763 | case BuiltinType::Float16: | |
| 764 | return trans_create_node_symbol_str(c, "f16"); | |
| 763 | 765 | case BuiltinType::LongDouble: |
| 764 | 766 | return trans_create_node_symbol_str(c, "c_longdouble"); |
| 765 | 767 | case BuiltinType::WChar_U: |
| ... | ... | @@ -1062,6 +1064,7 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou |
| 1062 | 1064 | case Type::Pipe: |
| 1063 | 1065 | case Type::ObjCTypeParam: |
| 1064 | 1066 | case Type::DeducedTemplateSpecialization: |
| 1067 | case Type::DependentAddressSpace: | |
| 1065 | 1068 | emit_warning(c, source_loc, "unsupported type: '%s'", ty->getTypeClassName()); |
| 1066 | 1069 | return nullptr; |
| 1067 | 1070 | } |
| ... | ... | @@ -1252,6 +1255,9 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS |
| 1252 | 1255 | case BO_PtrMemI: |
| 1253 | 1256 | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_PtrMemI"); |
| 1254 | 1257 | return nullptr; |
| 1258 | case BO_Cmp: | |
| 1259 | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Cmp"); | |
| 1260 | return nullptr; | |
| 1255 | 1261 | case BO_Mul: |
| 1256 | 1262 | return trans_create_bin_op(c, scope, stmt->getLHS(), |
| 1257 | 1263 | qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeMultWrap : BinOpTypeMult, |
| ... | ... | @@ -1513,6 +1519,9 @@ static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_use |
| 1513 | 1519 | case BO_RemAssign: |
| 1514 | 1520 | emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_RemAssign"); |
| 1515 | 1521 | return nullptr; |
| 1522 | case BO_Cmp: | |
| 1523 | emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_Cmp"); | |
| 1524 | return nullptr; | |
| 1516 | 1525 | case BO_AddAssign: |
| 1517 | 1526 | if (qual_type_has_wrapping_overflow(c, stmt->getType())) |
| 1518 | 1527 | return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap, BinOpTypeAddWrap); |
src/zig_llvm.cpp+6-2| ... | ... | @@ -38,7 +38,7 @@ |
| 38 | 38 | #include <llvm/Transforms/IPO/AlwaysInliner.h> |
| 39 | 39 | #include <llvm/Transforms/Scalar.h> |
| 40 | 40 | |
| 41 | #include <lld/Driver/Driver.h> | |
| 41 | #include <lld/Common/Driver.h> | |
| 42 | 42 | |
| 43 | 43 | #include <new> |
| 44 | 44 | |
| ... | ... | @@ -609,7 +609,7 @@ ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScop |
| 609 | 609 | void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) { |
| 610 | 610 | if (on_state) { |
| 611 | 611 | FastMathFlags fmf; |
| 612 | fmf.setUnsafeAlgebra(); | |
| 612 | fmf.setFast(); | |
| 613 | 613 | unwrap(builder_wrapped)->setFastMathFlags(fmf); |
| 614 | 614 | } else { |
| 615 | 615 | unwrap(builder_wrapped)->clearFastMathFlags(); |
| ... | ... | @@ -647,11 +647,13 @@ static_assert((Triple::ArchType)ZigLLVM_LastArchType == Triple::LastArchType, "" |
| 647 | 647 | static_assert((Triple::VendorType)ZigLLVM_LastVendorType == Triple::LastVendorType, ""); |
| 648 | 648 | static_assert((Triple::OSType)ZigLLVM_LastOSType == Triple::LastOSType, ""); |
| 649 | 649 | static_assert((Triple::EnvironmentType)ZigLLVM_LastEnvironmentType == Triple::LastEnvironmentType, ""); |
| 650 | static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v5 == Triple::KalimbaSubArch_v5, ""); | |
| 650 | 651 | |
| 651 | 652 | static_assert((Triple::ObjectFormatType)ZigLLVM_UnknownObjectFormat == Triple::UnknownObjectFormat, ""); |
| 652 | 653 | static_assert((Triple::ObjectFormatType)ZigLLVM_COFF == Triple::COFF, ""); |
| 653 | 654 | static_assert((Triple::ObjectFormatType)ZigLLVM_ELF == Triple::ELF, ""); |
| 654 | 655 | static_assert((Triple::ObjectFormatType)ZigLLVM_MachO == Triple::MachO, ""); |
| 656 | static_assert((Triple::ObjectFormatType)ZigLLVM_Wasm == Triple::Wasm, ""); | |
| 655 | 657 | |
| 656 | 658 | const char *ZigLLVMGetArchTypeName(ZigLLVM_ArchType arch) { |
| 657 | 659 | return (const char*)Triple::getArchTypeName((Triple::ArchType)arch).bytes_begin(); |
| ... | ... | @@ -690,6 +692,8 @@ const char *ZigLLVMGetSubArchTypeName(ZigLLVM_SubArchType sub_arch) { |
| 690 | 692 | switch (sub_arch) { |
| 691 | 693 | case ZigLLVM_NoSubArch: |
| 692 | 694 | return "(none)"; |
| 695 | case ZigLLVM_ARMSubArch_v8_3a: | |
| 696 | return "v8_3a"; | |
| 693 | 697 | case ZigLLVM_ARMSubArch_v8_2a: |
| 694 | 698 | return "v8_2a"; |
| 695 | 699 | case ZigLLVM_ARMSubArch_v8_1a: |
src/zig_llvm.h+5-1| ... | ... | @@ -209,6 +209,7 @@ enum ZigLLVM_ArchType { |
| 209 | 209 | ZigLLVM_armeb, // ARM (big endian): armeb |
| 210 | 210 | ZigLLVM_aarch64, // AArch64 (little endian): aarch64 |
| 211 | 211 | ZigLLVM_aarch64_be, // AArch64 (big endian): aarch64_be |
| 212 | ZigLLVM_arc, // ARC: Synopsys ARC | |
| 212 | 213 | ZigLLVM_avr, // AVR: Atmel AVR microcontroller |
| 213 | 214 | ZigLLVM_bpfel, // eBPF or extended BPF or 64-bit BPF (little endian) |
| 214 | 215 | ZigLLVM_bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian) |
| ... | ... | @@ -261,6 +262,7 @@ enum ZigLLVM_ArchType { |
| 261 | 262 | enum ZigLLVM_SubArchType { |
| 262 | 263 | ZigLLVM_NoSubArch, |
| 263 | 264 | |
| 265 | ZigLLVM_ARMSubArch_v8_3a, | |
| 264 | 266 | ZigLLVM_ARMSubArch_v8_2a, |
| 265 | 267 | ZigLLVM_ARMSubArch_v8_1a, |
| 266 | 268 | ZigLLVM_ARMSubArch_v8, |
| ... | ... | @@ -350,6 +352,7 @@ enum ZigLLVM_EnvironmentType { |
| 350 | 352 | ZigLLVM_UnknownEnvironment, |
| 351 | 353 | |
| 352 | 354 | ZigLLVM_GNU, |
| 355 | ZigLLVM_GNUABIN32, | |
| 353 | 356 | ZigLLVM_GNUABI64, |
| 354 | 357 | ZigLLVM_GNUEABI, |
| 355 | 358 | ZigLLVM_GNUEABIHF, |
| ... | ... | @@ -368,8 +371,9 @@ enum ZigLLVM_EnvironmentType { |
| 368 | 371 | ZigLLVM_AMDOpenCL, |
| 369 | 372 | ZigLLVM_CoreCLR, |
| 370 | 373 | ZigLLVM_OpenCL, |
| 374 | ZigLLVM_Simulator, | |
| 371 | 375 | |
| 372 | ZigLLVM_LastEnvironmentType = ZigLLVM_OpenCL | |
| 376 | ZigLLVM_LastEnvironmentType = ZigLLVM_Simulator | |
| 373 | 377 | }; |
| 374 | 378 | |
| 375 | 379 | enum ZigLLVM_ObjectFormatType { |
std/debug/index.zig+9-2| ... | ... | @@ -791,14 +791,21 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 791 | 791 | } |
| 792 | 792 | |
| 793 | 793 | const version = try in_stream.readInt(st.elf.endian, u16); |
| 794 | if (version != 2) return error.InvalidDebugInfo; | |
| 794 | // TODO support 3 and 5 | |
| 795 | if (version != 2 and version != 4) return error.InvalidDebugInfo; | |
| 795 | 796 | |
| 796 | const prologue_length = try in_stream.readInt(st.elf.endian, u32); | |
| 797 | const prologue_length = if (is_64) try in_stream.readInt(st.elf.endian, u64) | |
| 798 | else try in_stream.readInt(st.elf.endian, u32); | |
| 797 | 799 | const prog_start_offset = (try in_file.getPos()) + prologue_length; |
| 798 | 800 | |
| 799 | 801 | const minimum_instruction_length = try in_stream.readByte(); |
| 800 | 802 | if (minimum_instruction_length == 0) return error.InvalidDebugInfo; |
| 801 | 803 | |
| 804 | if (version >= 4) { | |
| 805 | // maximum_operations_per_instruction | |
| 806 | _ = try in_stream.readByte(); | |
| 807 | } | |
| 808 | ||
| 802 | 809 | const default_is_stmt = (try in_stream.readByte()) != 0; |
| 803 | 810 | const line_base = try in_stream.readByteSigned(); |
| 804 | 811 |
std/special/compiler_rt/index.zig+18-1| ... | ... | @@ -127,7 +127,24 @@ fn isArmArch() bool { |
| 127 | 127 | builtin.Arch.armv5, |
| 128 | 128 | builtin.Arch.armv5te, |
| 129 | 129 | builtin.Arch.armv4t, |
| 130 | builtin.Arch.armeb => true, | |
| 130 | builtin.Arch.armebv8_2a, | |
| 131 | builtin.Arch.armebv8_1a, | |
| 132 | builtin.Arch.armebv8, | |
| 133 | builtin.Arch.armebv8r, | |
| 134 | builtin.Arch.armebv8m_baseline, | |
| 135 | builtin.Arch.armebv8m_mainline, | |
| 136 | builtin.Arch.armebv7, | |
| 137 | builtin.Arch.armebv7em, | |
| 138 | builtin.Arch.armebv7m, | |
| 139 | builtin.Arch.armebv7s, | |
| 140 | builtin.Arch.armebv7k, | |
| 141 | builtin.Arch.armebv6, | |
| 142 | builtin.Arch.armebv6m, | |
| 143 | builtin.Arch.armebv6k, | |
| 144 | builtin.Arch.armebv6t2, | |
| 145 | builtin.Arch.armebv5, | |
| 146 | builtin.Arch.armebv5te, | |
| 147 | builtin.Arch.armebv4t => true, | |
| 131 | 148 | else => false, |
| 132 | 149 | }; |
| 133 | 150 | } |