| author | |
| committer | |
| log | 95dbba046d84b3e95c63f97d8e6a819b3e1b4cd5 |
| tree | 8ac7dfecb977ce70ec9ebb3b02392f88a74f6833 |
| parent | 7109035b78ee05302bbdaadc52013b430a030b69 |
22 files changed, 371 insertions(+), 31 deletions(-)
deps/lld/COFF/Driver.cpp+3-3| ... | ... | @@ -1551,11 +1551,11 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1551 | 1551 | continue; |
| 1552 | 1552 | } |
| 1553 | 1553 | |
| 1554 | // If the symbol isn't common, it must have been replaced with a regular | |
| 1555 | // symbol, which will carry its own alignment. | |
| 1554 | 1556 | auto *DC = dyn_cast<DefinedCommon>(Sym); |
| 1555 | if (!DC) { | |
| 1556 | warn("/aligncomm symbol " + Name + " of wrong kind"); | |
| 1557 | if (!DC) | |
| 1557 | 1558 | continue; |
| 1558 | } | |
| 1559 | 1559 | |
| 1560 | 1560 | CommonChunk *C = DC->getChunk(); |
| 1561 | 1561 | C->Alignment = std::max(C->Alignment, Alignment); |
deps/lld/COFF/InputFiles.cpp+49-5| ... | ... | @@ -205,7 +205,13 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber, |
| 205 | 205 | |
| 206 | 206 | void ObjFile::readAssociativeDefinition( |
| 207 | 207 | COFFSymbolRef Sym, const coff_aux_section_definition *Def) { |
| 208 | SectionChunk *Parent = SparseChunks[Def->getNumber(Sym.isBigObj())]; | |
| 208 | readAssociativeDefinition(Sym, Def, Def->getNumber(Sym.isBigObj())); | |
| 209 | } | |
| 210 | ||
| 211 | void ObjFile::readAssociativeDefinition(COFFSymbolRef Sym, | |
| 212 | const coff_aux_section_definition *Def, | |
| 213 | uint32_t ParentSection) { | |
| 214 | SectionChunk *Parent = SparseChunks[ParentSection]; | |
| 209 | 215 | |
| 210 | 216 | // If the parent is pending, it probably means that its section definition |
| 211 | 217 | // appears after us in the symbol table. Leave the associated section as |
| ... | ... | @@ -225,6 +231,35 @@ void ObjFile::readAssociativeDefinition( |
| 225 | 231 | } |
| 226 | 232 | } |
| 227 | 233 | |
| 234 | void ObjFile::recordPrevailingSymbolForMingw( | |
| 235 | COFFSymbolRef Sym, DenseMap<StringRef, uint32_t> &PrevailingSectionMap) { | |
| 236 | // For comdat symbols in executable sections, where this is the copy | |
| 237 | // of the section chunk we actually include instead of discarding it, | |
| 238 | // add the symbol to a map to allow using it for implicitly | |
| 239 | // associating .[px]data$<func> sections to it. | |
| 240 | int32_t SectionNumber = Sym.getSectionNumber(); | |
| 241 | SectionChunk *SC = SparseChunks[SectionNumber]; | |
| 242 | if (SC && SC->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) { | |
| 243 | StringRef Name; | |
| 244 | COFFObj->getSymbolName(Sym, Name); | |
| 245 | PrevailingSectionMap[Name] = SectionNumber; | |
| 246 | } | |
| 247 | } | |
| 248 | ||
| 249 | void ObjFile::maybeAssociateSEHForMingw( | |
| 250 | COFFSymbolRef Sym, const coff_aux_section_definition *Def, | |
| 251 | const DenseMap<StringRef, uint32_t> &PrevailingSectionMap) { | |
| 252 | StringRef Name; | |
| 253 | COFFObj->getSymbolName(Sym, Name); | |
| 254 | if (Name.consume_front(".pdata$") || Name.consume_front(".xdata$")) { | |
| 255 | // For MinGW, treat .[px]data$<func> as implicitly associative to | |
| 256 | // the symbol <func>. | |
| 257 | auto ParentSym = PrevailingSectionMap.find(Name); | |
| 258 | if (ParentSym != PrevailingSectionMap.end()) | |
| 259 | readAssociativeDefinition(Sym, Def, ParentSym->second); | |
| 260 | } | |
| 261 | } | |
| 262 | ||
| 228 | 263 | Symbol *ObjFile::createRegular(COFFSymbolRef Sym) { |
| 229 | 264 | SectionChunk *SC = SparseChunks[Sym.getSectionNumber()]; |
| 230 | 265 | if (Sym.isExternal()) { |
| ... | ... | @@ -248,19 +283,24 @@ void ObjFile::initializeSymbols() { |
| 248 | 283 | std::vector<uint32_t> PendingIndexes; |
| 249 | 284 | PendingIndexes.reserve(NumSymbols); |
| 250 | 285 | |
| 286 | DenseMap<StringRef, uint32_t> PrevailingSectionMap; | |
| 251 | 287 | std::vector<const coff_aux_section_definition *> ComdatDefs( |
| 252 | 288 | COFFObj->getNumberOfSections() + 1); |
| 253 | 289 | |
| 254 | 290 | for (uint32_t I = 0; I < NumSymbols; ++I) { |
| 255 | 291 | COFFSymbolRef COFFSym = check(COFFObj->getSymbol(I)); |
| 292 | bool PrevailingComdat; | |
| 256 | 293 | if (COFFSym.isUndefined()) { |
| 257 | 294 | Symbols[I] = createUndefined(COFFSym); |
| 258 | 295 | } else if (COFFSym.isWeakExternal()) { |
| 259 | 296 | Symbols[I] = createUndefined(COFFSym); |
| 260 | 297 | uint32_t TagIndex = COFFSym.getAux<coff_aux_weak_external>()->TagIndex; |
| 261 | 298 | WeakAliases.emplace_back(Symbols[I], TagIndex); |
| 262 | } else if (Optional<Symbol *> OptSym = createDefined(COFFSym, ComdatDefs)) { | |
| 299 | } else if (Optional<Symbol *> OptSym = | |
| 300 | createDefined(COFFSym, ComdatDefs, PrevailingComdat)) { | |
| 263 | 301 | Symbols[I] = *OptSym; |
| 302 | if (Config->MinGW && PrevailingComdat) | |
| 303 | recordPrevailingSymbolForMingw(COFFSym, PrevailingSectionMap); | |
| 264 | 304 | } else { |
| 265 | 305 | // createDefined() returns None if a symbol belongs to a section that |
| 266 | 306 | // was pending at the point when the symbol was read. This can happen in |
| ... | ... | @@ -278,9 +318,12 @@ void ObjFile::initializeSymbols() { |
| 278 | 318 | |
| 279 | 319 | for (uint32_t I : PendingIndexes) { |
| 280 | 320 | COFFSymbolRef Sym = check(COFFObj->getSymbol(I)); |
| 281 | if (auto *Def = Sym.getSectionDefinition()) | |
| 321 | if (auto *Def = Sym.getSectionDefinition()) { | |
| 282 | 322 | if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) |
| 283 | 323 | readAssociativeDefinition(Sym, Def); |
| 324 | else if (Config->MinGW) | |
| 325 | maybeAssociateSEHForMingw(Sym, Def, PrevailingSectionMap); | |
| 326 | } | |
| 284 | 327 | if (SparseChunks[Sym.getSectionNumber()] == PendingComdat) { |
| 285 | 328 | StringRef Name; |
| 286 | 329 | COFFObj->getSymbolName(Sym, Name); |
| ... | ... | @@ -306,7 +349,9 @@ Symbol *ObjFile::createUndefined(COFFSymbolRef Sym) { |
| 306 | 349 | |
| 307 | 350 | Optional<Symbol *> ObjFile::createDefined( |
| 308 | 351 | COFFSymbolRef Sym, |
| 309 | std::vector<const coff_aux_section_definition *> &ComdatDefs) { | |
| 352 | std::vector<const coff_aux_section_definition *> &ComdatDefs, | |
| 353 | bool &Prevailing) { | |
| 354 | Prevailing = false; | |
| 310 | 355 | auto GetName = [&]() { |
| 311 | 356 | StringRef S; |
| 312 | 357 | COFFObj->getSymbolName(Sym, S); |
| ... | ... | @@ -352,7 +397,6 @@ Optional<Symbol *> ObjFile::createDefined( |
| 352 | 397 | if (const coff_aux_section_definition *Def = ComdatDefs[SectionNumber]) { |
| 353 | 398 | ComdatDefs[SectionNumber] = nullptr; |
| 354 | 399 | Symbol *Leader; |
| 355 | bool Prevailing; | |
| 356 | 400 | if (Sym.isExternal()) { |
| 357 | 401 | std::tie(Leader, Prevailing) = |
| 358 | 402 | Symtab->addComdat(this, GetName(), Sym.getGeneric()); |
deps/lld/COFF/InputFiles.h+16-1| ... | ... | @@ -13,6 +13,7 @@ |
| 13 | 13 | #include "Config.h" |
| 14 | 14 | #include "lld/Common/LLVM.h" |
| 15 | 15 | #include "llvm/ADT/ArrayRef.h" |
| 16 | #include "llvm/ADT/DenseMap.h" | |
| 16 | 17 | #include "llvm/ADT/DenseSet.h" |
| 17 | 18 | #include "llvm/LTO/LTO.h" |
| 18 | 19 | #include "llvm/Object/Archive.h" |
| ... | ... | @@ -157,10 +158,24 @@ private: |
| 157 | 158 | COFFSymbolRef COFFSym, |
| 158 | 159 | const llvm::object::coff_aux_section_definition *Def); |
| 159 | 160 | |
| 161 | void readAssociativeDefinition( | |
| 162 | COFFSymbolRef COFFSym, | |
| 163 | const llvm::object::coff_aux_section_definition *Def, | |
| 164 | uint32_t ParentSection); | |
| 165 | ||
| 166 | void recordPrevailingSymbolForMingw( | |
| 167 | COFFSymbolRef COFFSym, | |
| 168 | llvm::DenseMap<StringRef, uint32_t> &PrevailingSectionMap); | |
| 169 | ||
| 170 | void maybeAssociateSEHForMingw( | |
| 171 | COFFSymbolRef Sym, const llvm::object::coff_aux_section_definition *Def, | |
| 172 | const llvm::DenseMap<StringRef, uint32_t> &PrevailingSectionMap); | |
| 173 | ||
| 160 | 174 | llvm::Optional<Symbol *> |
| 161 | 175 | createDefined(COFFSymbolRef Sym, |
| 162 | 176 | std::vector<const llvm::object::coff_aux_section_definition *> |
| 163 | &ComdatDefs); | |
| 177 | &ComdatDefs, | |
| 178 | bool &PrevailingComdat); | |
| 164 | 179 | Symbol *createRegular(COFFSymbolRef Sym); |
| 165 | 180 | Symbol *createUndefined(COFFSymbolRef Sym); |
| 166 | 181 |
deps/lld/ELF/LinkerScript.cpp+13-9| ... | ... | @@ -116,7 +116,8 @@ void LinkerScript::expandMemoryRegions(uint64_t Size) { |
| 116 | 116 | if (Ctx->MemRegion) |
| 117 | 117 | expandMemoryRegion(Ctx->MemRegion, Size, Ctx->MemRegion->Name, |
| 118 | 118 | Ctx->OutSec->Name); |
| 119 | if (Ctx->LMARegion) | |
| 119 | // Only expand the LMARegion if it is different from MemRegion. | |
| 120 | if (Ctx->LMARegion && Ctx->MemRegion != Ctx->LMARegion) | |
| 120 | 121 | expandMemoryRegion(Ctx->LMARegion, Size, Ctx->LMARegion->Name, |
| 121 | 122 | Ctx->OutSec->Name); |
| 122 | 123 | } |
| ... | ... | @@ -750,6 +751,13 @@ MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *Sec) { |
| 750 | 751 | return nullptr; |
| 751 | 752 | } |
| 752 | 753 | |
| 754 | static OutputSection *findFirstSection(PhdrEntry *Load) { | |
| 755 | for (OutputSection *Sec : OutputSections) | |
| 756 | if (Sec->PtLoad == Load) | |
| 757 | return Sec; | |
| 758 | return nullptr; | |
| 759 | } | |
| 760 | ||
| 753 | 761 | // This function assigns offsets to input sections and an output section |
| 754 | 762 | // for a single sections command (e.g. ".text { *(.text); }"). |
| 755 | 763 | void LinkerScript::assignOffsets(OutputSection *Sec) { |
| ... | ... | @@ -775,8 +783,11 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { |
| 775 | 783 | // will set the LMA such that the difference between VMA and LMA for the |
| 776 | 784 | // section is the same as the preceding output section in the same region |
| 777 | 785 | // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html |
| 786 | // This, however, should only be done by the first "non-header" section | |
| 787 | // in the segment. | |
| 778 | 788 | if (PhdrEntry *L = Ctx->OutSec->PtLoad) |
| 779 | L->LMAOffset = Ctx->LMAOffset; | |
| 789 | if (Sec == findFirstSection(L)) | |
| 790 | L->LMAOffset = Ctx->LMAOffset; | |
| 780 | 791 | |
| 781 | 792 | // We can call this method multiple times during the creation of |
| 782 | 793 | // thunks and want to start over calculation each time. |
| ... | ... | @@ -953,13 +964,6 @@ void LinkerScript::adjustSectionsAfterSorting() { |
| 953 | 964 | } |
| 954 | 965 | } |
| 955 | 966 | |
| 956 | static OutputSection *findFirstSection(PhdrEntry *Load) { | |
| 957 | for (OutputSection *Sec : OutputSections) | |
| 958 | if (Sec->PtLoad == Load) | |
| 959 | return Sec; | |
| 960 | return nullptr; | |
| 961 | } | |
| 962 | ||
| 963 | 967 | static uint64_t computeBase(uint64_t Min, bool AllocateHeaders) { |
| 964 | 968 | // If there is no SECTIONS or if the linkerscript is explicit about program |
| 965 | 969 | // headers, do our best to allocate them. |
deps/lld/ELF/SyntheticSections.cpp+3-1| ... | ... | @@ -2929,8 +2929,10 @@ void elf::mergeSections() { |
| 2929 | 2929 | |
| 2930 | 2930 | // We do not want to handle sections that are not alive, so just remove |
| 2931 | 2931 | // them instead of trying to merge. |
| 2932 | if (!MS->Live) | |
| 2932 | if (!MS->Live) { | |
| 2933 | S = nullptr; | |
| 2933 | 2934 | continue; |
| 2935 | } | |
| 2934 | 2936 | |
| 2935 | 2937 | StringRef OutsecName = getOutputSectionName(MS); |
| 2936 | 2938 | uint32_t Alignment = std::max<uint32_t>(MS->Alignment, MS->Entsize); |
deps/lld/ELF/Writer.cpp+7-5| ... | ... | @@ -1815,12 +1815,14 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() { |
| 1815 | 1815 | // Segments are contiguous memory regions that has the same attributes |
| 1816 | 1816 | // (e.g. executable or writable). There is one phdr for each segment. |
| 1817 | 1817 | // Therefore, we need to create a new phdr when the next section has |
| 1818 | // different flags or is loaded at a discontiguous address using AT linker | |
| 1819 | // script command. At the same time, we don't want to create a separate | |
| 1820 | // load segment for the headers, even if the first output section has | |
| 1821 | // an AT attribute. | |
| 1818 | // different flags or is loaded at a discontiguous address or memory | |
| 1819 | // region using AT or AT> linker script command, respectively. At the same | |
| 1820 | // time, we don't want to create a separate load segment for the headers, | |
| 1821 | // even if the first output section has an AT or AT> attribute. | |
| 1822 | 1822 | uint64_t NewFlags = computeFlags(Sec->getPhdrFlags()); |
| 1823 | if ((Sec->LMAExpr && Load->LastSec != Out::ProgramHeaders) || | |
| 1823 | if (((Sec->LMAExpr || | |
| 1824 | (Sec->LMARegion && (Sec->LMARegion != Load->FirstSec->LMARegion))) && | |
| 1825 | Load->LastSec != Out::ProgramHeaders) || | |
| 1824 | 1826 | Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) { |
| 1825 | 1827 | |
| 1826 | 1828 | Load = AddHdr(PT_LOAD, NewFlags); |
deps/lld/docs/ReleaseNotes.rst+7-1| ... | ... | @@ -29,7 +29,13 @@ ELF Improvements |
| 29 | 29 | COFF Improvements |
| 30 | 30 | ----------------- |
| 31 | 31 | |
| 32 | * Item 1. | |
| 32 | * Improved correctness of exporting mangled stdcall symbols. | |
| 33 | ||
| 34 | * Completed support for ARM64 relocations. | |
| 35 | ||
| 36 | * Added support for outputting PDB debug info for MinGW targets. | |
| 37 | ||
| 38 | * Improved compatibility of output binaries with GNU binutils objcopy/strip. | |
| 33 | 39 | |
| 34 | 40 | MachO Improvements |
| 35 | 41 | ------------------ |
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp+1| ... | ... | @@ -621,6 +621,7 @@ void ArchHandler_x86_64::applyFixupFinal( |
| 621 | 621 | // Fall into llvm_unreachable(). |
| 622 | 622 | break; |
| 623 | 623 | } |
| 624 | llvm_unreachable("invalid x86_64 Reference Kind"); | |
| 624 | 625 | } |
| 625 | 626 | |
| 626 | 627 | void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, |
deps/lld/test/COFF/Inputs/associative-comdat-mingw-2.s created+34| ... | ... | @@ -0,0 +1,34 @@ |
| 1 | .section .xdata$foo,"dr" | |
| 2 | .linkonce discard | |
| 3 | .p2align 3 | |
| 4 | .long 42 | |
| 5 | ||
| 6 | .section .xdata$bar,"dr" | |
| 7 | .linkonce discard | |
| 8 | .p2align 3 | |
| 9 | .long 43 | |
| 10 | ||
| 11 | .section .xdata$baz,"dr" | |
| 12 | .linkonce discard | |
| 13 | .p2align 3 | |
| 14 | .long 44 | |
| 15 | ||
| 16 | .def foo; | |
| 17 | .scl 2; | |
| 18 | .type 32; | |
| 19 | .endef | |
| 20 | .section .text$foo,"xr",discard,foo | |
| 21 | .globl foo | |
| 22 | .p2align 4 | |
| 23 | foo: | |
| 24 | ret | |
| 25 | ||
| 26 | .def bar; | |
| 27 | .scl 2; | |
| 28 | .type 32; | |
| 29 | .endef | |
| 30 | .section .text$bar,"xr",discard,bar | |
| 31 | .globl bar | |
| 32 | .p2align 4 | |
| 33 | bar: | |
| 34 | ret |
deps/lld/test/COFF/Inputs/common-replacement.s created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | .globl foo | |
| 2 | .data | |
| 3 | .p2align 2, 0 | |
| 4 | foo: | |
| 5 | .long 42 |
deps/lld/test/COFF/associative-comdat-mingw.s created+73| ... | ... | @@ -0,0 +1,73 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t1.obj | |
| 4 | # RUN: llvm-mc -triple=x86_64-windows-gnu %S/Inputs/associative-comdat-mingw-2.s -filetype=obj -o %t2.obj | |
| 5 | ||
| 6 | # RUN: lld-link -lldmingw -entry:main %t1.obj %t2.obj -out:%t.gc.exe -verbose | |
| 7 | # RUN: llvm-readobj -sections %t.gc.exe | FileCheck %s | |
| 8 | ||
| 9 | # CHECK: Sections [ | |
| 10 | # CHECK: Section { | |
| 11 | # CHECK: Number: 2 | |
| 12 | # CHECK-LABEL: Name: .rdata (2E 72 64 61 74 61 00 00) | |
| 13 | # This is the critical check to show that only *one* definition of | |
| 14 | # .xdata$foo was retained. This *must* be 4. | |
| 15 | # Make sure that no other .xdata sections get included, which would | |
| 16 | # increase the size here. | |
| 17 | # CHECK-NEXT: VirtualSize: 0x4 | |
| 18 | ||
| 19 | .text | |
| 20 | .def main; | |
| 21 | .scl 2; | |
| 22 | .type 32; | |
| 23 | .endef | |
| 24 | .globl main | |
| 25 | .p2align 4, 0x90 | |
| 26 | main: | |
| 27 | call foo | |
| 28 | retq | |
| 29 | ||
| 30 | # Defines .text$foo (which has a leader symbol and is referenced like | |
| 31 | # normally), and .xdata$foo (which lacks a leader symbol, which normally | |
| 32 | # would be declared associative to the symbol foo). | |
| 33 | # .xdata$foo should be implicitly treated as associative to foo and brought | |
| 34 | # in, while .xdata$bar, implicitly associative to bar, not included, and | |
| 35 | # .xdata$baz not included since there's no symbol baz. | |
| 36 | ||
| 37 | # GNU binutils ld doesn't do this at all, but always includes all .xdata/.pdata | |
| 38 | # comdat sections, even if --gc-sections is used. | |
| 39 | ||
| 40 | .section .xdata$foo,"dr" | |
| 41 | .linkonce discard | |
| 42 | .p2align 3 | |
| 43 | .long 42 | |
| 44 | ||
| 45 | .section .xdata$bar,"dr" | |
| 46 | .linkonce discard | |
| 47 | .p2align 3 | |
| 48 | .long 43 | |
| 49 | ||
| 50 | .section .xdata$baz,"dr" | |
| 51 | .linkonce discard | |
| 52 | .p2align 3 | |
| 53 | .long 44 | |
| 54 | ||
| 55 | .def foo; | |
| 56 | .scl 2; | |
| 57 | .type 32; | |
| 58 | .endef | |
| 59 | .section .text$foo,"xr",discard,foo | |
| 60 | .globl foo | |
| 61 | .p2align 4 | |
| 62 | foo: | |
| 63 | ret | |
| 64 | ||
| 65 | .def bar; | |
| 66 | .scl 2; | |
| 67 | .type 32; | |
| 68 | .endef | |
| 69 | .section .text$bar,"xr",discard,bar | |
| 70 | .globl bar | |
| 71 | .p2align 4 | |
| 72 | bar: | |
| 73 | ret |
deps/lld/test/COFF/common-replacement.s created+35| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | ||
| 3 | # RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t1.obj | |
| 4 | # RUN: llvm-mc -triple=x86_64-windows-gnu %S/Inputs/common-replacement.s -filetype=obj -o %t2.obj | |
| 5 | ||
| 6 | # RUN: lld-link -lldmingw -entry:main %t1.obj %t2.obj -out:%t.exe -verbose 2>&1 \ | |
| 7 | # RUN: | FileCheck -check-prefix VERBOSE %s | |
| 8 | # RUN: llvm-readobj -s %t.exe | FileCheck -check-prefix SECTIONS %s | |
| 9 | ||
| 10 | # VERBOSE: -aligncomm:"foo",2 | |
| 11 | ||
| 12 | # As long as the .comm symbol is replaced with actual data, RawDataSize | |
| 13 | # below should be nonzero. | |
| 14 | ||
| 15 | # SECTIONS: Name: .data (2E 64 61 74 61 00 00 00) | |
| 16 | # SECTIONS-NEXT: VirtualSize: 0x8 | |
| 17 | # SECTIONS-NEXT: VirtualAddress: 0x2000 | |
| 18 | # SECTIONS-NEXT: RawDataSize: 512 | |
| 19 | ||
| 20 | ||
| 21 | .text | |
| 22 | .def main; | |
| 23 | .scl 2; | |
| 24 | .type 32; | |
| 25 | .endef | |
| 26 | .globl main | |
| 27 | .p2align 4, 0x90 | |
| 28 | main: | |
| 29 | movl foo(%rip), %eax | |
| 30 | retq | |
| 31 | ||
| 32 | # This produces an aligncomm directive, but when linking in | |
| 33 | # Inputs/common-replacement.s, this symbol is replaced by a normal defined | |
| 34 | # symbol instead. | |
| 35 | .comm foo, 4, 2 |
deps/lld/test/ELF/linkerscript/Inputs/at6.s created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | .global _start | |
| 2 | .text | |
| 3 | _start: | |
| 4 | nop | |
| 5 | ||
| 6 | .section .sec1,"aw",@progbits | |
| 7 | .long 1 | |
| 8 | ||
| 9 | .section .sec2,"aw",@progbits | |
| 10 | .long 2 | |
| 11 |
deps/lld/test/ELF/linkerscript/Inputs/at7.s created+7| ... | ... | @@ -0,0 +1,7 @@ |
| 1 | .global _start | |
| 2 | .text | |
| 3 | _start: | |
| 4 | nop | |
| 5 | ||
| 6 | .section .sec, "aw" | |
| 7 | .word 4 |
deps/lld/test/ELF/linkerscript/Inputs/at8.s created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | .section .sec1,"aw",@progbits | |
| 2 | .quad 1 | |
| 3 | ||
| 4 | .section .sec2,"aw",@progbits | |
| 5 | .quad 2 | |
| 6 | ||
| 7 | .section .sec3,"aw",@progbits | |
| 8 | .quad 3 |
deps/lld/test/ELF/linkerscript/at6.test created+30| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/at6.s -o %t.o | |
| 3 | # RUN: ld.lld %t.o --script %s -o %t | |
| 4 | # RUN: llvm-readelf -sections -program-headers %t | FileCheck %s | |
| 5 | ||
| 6 | MEMORY { | |
| 7 | FLASH : ORIGIN = 0x08000000, LENGTH = 0x100 | |
| 8 | RAM : ORIGIN = 0x20000000, LENGTH = 0x200 | |
| 9 | } | |
| 10 | ||
| 11 | SECTIONS { | |
| 12 | .text : { *(.text) } > FLASH | |
| 13 | .sec1 : { *(.sec1) } > RAM | |
| 14 | .sec2 : { *(.sec2) } > RAM AT > FLASH | |
| 15 | } | |
| 16 | ||
| 17 | # Make sure we create a separate PT_LOAD entry for .sec2. Previously, | |
| 18 | # it was added to the PT_LOAD entry of .sec1 | |
| 19 | ||
| 20 | # CHECK: Name Type Address Off | |
| 21 | # CHECK: .text PROGBITS 0000000008000000 001000 | |
| 22 | # CHECK: .sec1 PROGBITS 0000000020000000 002000 | |
| 23 | # CHECK: .sec2 PROGBITS 0000000020000004 002004 | |
| 24 | ||
| 25 | # CHECK: Program Headers: | |
| 26 | # CHECK: Type Offset VirtAddr PhysAddr | |
| 27 | # CHECK-NEXT: LOAD 0x001000 0x0000000008000000 0x0000000008000000 | |
| 28 | # CHECK-NEXT: LOAD 0x002000 0x0000000020000000 0x0000000020000000 | |
| 29 | # CHECK-NEXT: LOAD 0x002004 0x0000000020000004 0x0000000008000001 | |
| 30 | # CHECK-NOT: LOAD |
deps/lld/test/ELF/linkerscript/at7.test created+28| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/at7.s -o %t.o | |
| 3 | # RUN: ld.lld %t.o --script %s -o %t | |
| 4 | # RUN: llvm-readelf -sections -program-headers %t | FileCheck %s | |
| 5 | ||
| 6 | MEMORY { | |
| 7 | RAM : ORIGIN = 0x20000000, LENGTH = 0x200 | |
| 8 | } | |
| 9 | ||
| 10 | SECTIONS { | |
| 11 | .text : { *(.text) } > RAM AT> RAM | |
| 12 | .sec : { *(.sec) } > RAM | |
| 13 | } | |
| 14 | ||
| 15 | # Make sure the memory for the .text section is only reserved once. | |
| 16 | # Previously, the location counter for both MemRegion and LMARegion | |
| 17 | # was increased unconditionally. | |
| 18 | ||
| 19 | ||
| 20 | # CHECK: Name Type Address Off | |
| 21 | # CHECK: .text PROGBITS 0000000020000000 001000 | |
| 22 | # CHECK: .sec PROGBITS 0000000020000001 001001 | |
| 23 | ||
| 24 | # CHECK: Program Headers: | |
| 25 | # CHECK: Type Offset VirtAddr PhysAddr | |
| 26 | # CHECK-NEXT: LOAD 0x001000 0x0000000020000000 0x0000000020000000 | |
| 27 | # CHECK-NEXT: LOAD 0x001001 0x0000000020000001 0x0000000020000001 | |
| 28 | # CHECK-NOT: LOAD |
deps/lld/test/ELF/linkerscript/at8.test created+31| ... | ... | @@ -0,0 +1,31 @@ |
| 1 | # REQUIRES: x86 | |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/at8.s -o %t.o | |
| 3 | # RUN: ld.lld %t.o --script %s -o %t | |
| 4 | # RUN: llvm-readelf -sections -program-headers %t | FileCheck %s | |
| 5 | ||
| 6 | MEMORY { | |
| 7 | FLASH : ORIGIN = 0x08000000, LENGTH = 0x100 | |
| 8 | RAM : ORIGIN = 0x20000000, LENGTH = 0x200 | |
| 9 | } | |
| 10 | ||
| 11 | SECTIONS { | |
| 12 | .text : { *(.text) } > FLASH | |
| 13 | .sec1 : { *(.sec1) } > RAM AT > FLASH | |
| 14 | .sec2 : { *(.sec2) } > RAM | |
| 15 | .sec3 : { *(.sec3) } > RAM AT > FLASH | |
| 16 | } | |
| 17 | ||
| 18 | # Make sure we do not issue a load-address overlap error | |
| 19 | # Previously, .sec3 would overwrite the LMAOffset in the | |
| 20 | # PT_LOAD header. | |
| 21 | ||
| 22 | # CHECK: Name Type Address Off | |
| 23 | # CHECK: .text PROGBITS 0000000008000000 001000 | |
| 24 | # CHECK: .sec1 PROGBITS 0000000020000000 001000 | |
| 25 | # CHECK: .sec2 PROGBITS 0000000020000008 001008 | |
| 26 | # CHECK: .sec3 PROGBITS 0000000020000010 001010 | |
| 27 | ||
| 28 | # CHECK: Program Headers: | |
| 29 | # CHECK: Type Offset VirtAddr PhysAddr | |
| 30 | # CHECK-NEXT: LOAD 0x001000 0x0000000020000000 0x0000000008000000 | |
| 31 | # CHECK-NOT: LOAD |
deps/lld/test/ELF/lto/cache.ll+1-1| ... | ... | @@ -13,7 +13,7 @@ |
| 13 | 13 | ; RUN: ls %t.cache | count 4 |
| 14 | 14 | |
| 15 | 15 | ; Create a file of size 64KB. |
| 16 | ; RUN: "%python" -c "print(' ' * 65536)" > %t.cache/llvmcache-foo | |
| 16 | ; RUN: %python -c "print(' ' * 65536)" > %t.cache/llvmcache-foo | |
| 17 | 17 | |
| 18 | 18 | ; This should leave the file in place. |
| 19 | 19 | ; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k:prune_interval=0s -o %t3 %t2.o %t.o |
deps/lld/test/ELF/x86-64-reloc-error2.s+7-3| ... | ... | @@ -1,14 +1,18 @@ |
| 1 | 1 | # REQUIRES: x86 |
| 2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s | |
| 3 | # RUN: not ld.lld --entry=func --gc-sections %t.o -o /dev/null 2>&1 | FileCheck %s | |
| 4 | 4 | |
| 5 | 5 | ## Check we are able to find a function symbol that encloses |
| 6 | 6 | ## a given location when reporting error messages. |
| 7 | 7 | # CHECK: {{.*}}.o:(function func): relocation R_X86_64_32S out of range: -281474974609408 is not in [-2147483648, 2147483647] |
| 8 | 8 | |
| 9 | # This mergeable section will be garbage collected. We had a crash issue in that case. Test it. | |
| 10 | .section .rodata.str1,"aMS",@progbits,1 | |
| 11 | .asciz "a" | |
| 12 | ||
| 9 | 13 | .section .text.func, "ax", %progbits |
| 10 | 14 | .globl func |
| 11 | 15 | .type func,@function |
| 12 | .size func, 0x10 | |
| 13 | 16 | func: |
| 14 | movq func - 0x1000000000000, %rdx | |
| 17 | movq $func - 0x1000000000000, %rdx | |
| 18 | .size func, .-func |
deps/lld/test/mach-o/dependency_info.yaml+1-1| ... | ... | @@ -9,7 +9,7 @@ |
| 9 | 9 | # RUN: -F/Custom/Frameworks \ |
| 10 | 10 | # RUN: -framework Bar \ |
| 11 | 11 | # RUN: -framework Foo |
| 12 | # RUN: '%python' %p/Inputs/DependencyDump.py %t.info | FileCheck %s | |
| 12 | # RUN: %python %p/Inputs/DependencyDump.py %t.info | FileCheck %s | |
| 13 | 13 | |
| 14 | 14 | |
| 15 | 15 | # CHECK: linker-vers: lld |
deps/lld/test/wasm/lto/cache.ll+1-1| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | ; RUN: ls %t.cache | count 4 |
| 12 | 12 | |
| 13 | 13 | ; Create a file of size 64KB. |
| 14 | ; RUN: "%python" -c "print(' ' * 65536)" > %t.cache/llvmcache-foo | |
| 14 | ; RUN: %python -c "print(' ' * 65536)" > %t.cache/llvmcache-foo | |
| 15 | 15 | |
| 16 | 16 | ; This should leave the file in place. |
| 17 | 17 | ; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k:prune_interval=0s -o %t.wasm %t2.o %t.o |