From 95dbba046d84b3e95c63f97d8e6a819b3e1b4cd5 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 25 Aug 2018 22:10:32 -0400 Subject: [PATCH] update LLD fork to 7.0.0rc2 --- deps/lld/COFF/Driver.cpp | 6 +- deps/lld/COFF/InputFiles.cpp | 54 ++++++++++++-- deps/lld/COFF/InputFiles.h | 17 ++++- deps/lld/ELF/LinkerScript.cpp | 22 +++--- deps/lld/ELF/SyntheticSections.cpp | 4 +- deps/lld/ELF/Writer.cpp | 12 +-- deps/lld/docs/ReleaseNotes.rst | 8 +- .../ReaderWriter/MachO/ArchHandler_x86_64.cpp | 1 + .../COFF/Inputs/associative-comdat-mingw-2.s | 34 +++++++++ .../lld/test/COFF/Inputs/common-replacement.s | 5 ++ deps/lld/test/COFF/associative-comdat-mingw.s | 73 +++++++++++++++++++ deps/lld/test/COFF/common-replacement.s | 35 +++++++++ deps/lld/test/ELF/linkerscript/Inputs/at6.s | 11 +++ deps/lld/test/ELF/linkerscript/Inputs/at7.s | 7 ++ deps/lld/test/ELF/linkerscript/Inputs/at8.s | 8 ++ deps/lld/test/ELF/linkerscript/at6.test | 30 ++++++++ deps/lld/test/ELF/linkerscript/at7.test | 28 +++++++ deps/lld/test/ELF/linkerscript/at8.test | 31 ++++++++ deps/lld/test/ELF/lto/cache.ll | 2 +- deps/lld/test/ELF/x86-64-reloc-error2.s | 10 ++- deps/lld/test/mach-o/dependency_info.yaml | 2 +- deps/lld/test/wasm/lto/cache.ll | 2 +- 22 files changed, 371 insertions(+), 31 deletions(-) create mode 100644 deps/lld/test/COFF/Inputs/associative-comdat-mingw-2.s create mode 100644 deps/lld/test/COFF/Inputs/common-replacement.s create mode 100644 deps/lld/test/COFF/associative-comdat-mingw.s create mode 100644 deps/lld/test/COFF/common-replacement.s create mode 100644 deps/lld/test/ELF/linkerscript/Inputs/at6.s create mode 100644 deps/lld/test/ELF/linkerscript/Inputs/at7.s create mode 100644 deps/lld/test/ELF/linkerscript/Inputs/at8.s create mode 100644 deps/lld/test/ELF/linkerscript/at6.test create mode 100644 deps/lld/test/ELF/linkerscript/at7.test create mode 100644 deps/lld/test/ELF/linkerscript/at8.test diff --git a/deps/lld/COFF/Driver.cpp b/deps/lld/COFF/Driver.cpp index eefdb48bea..da7527607f 100644 --- a/deps/lld/COFF/Driver.cpp +++ b/deps/lld/COFF/Driver.cpp @@ -1551,11 +1551,11 @@ void LinkerDriver::link(ArrayRef ArgsArr) { continue; } + // If the symbol isn't common, it must have been replaced with a regular + // symbol, which will carry its own alignment. auto *DC = dyn_cast(Sym); - if (!DC) { - warn("/aligncomm symbol " + Name + " of wrong kind"); + if (!DC) continue; - } CommonChunk *C = DC->getChunk(); C->Alignment = std::max(C->Alignment, Alignment); diff --git a/deps/lld/COFF/InputFiles.cpp b/deps/lld/COFF/InputFiles.cpp index 2b3e65fae0..289cdb1f6c 100644 --- a/deps/lld/COFF/InputFiles.cpp +++ b/deps/lld/COFF/InputFiles.cpp @@ -205,7 +205,13 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber, void ObjFile::readAssociativeDefinition( COFFSymbolRef Sym, const coff_aux_section_definition *Def) { - SectionChunk *Parent = SparseChunks[Def->getNumber(Sym.isBigObj())]; + readAssociativeDefinition(Sym, Def, Def->getNumber(Sym.isBigObj())); +} + +void ObjFile::readAssociativeDefinition(COFFSymbolRef Sym, + const coff_aux_section_definition *Def, + uint32_t ParentSection) { + SectionChunk *Parent = SparseChunks[ParentSection]; // If the parent is pending, it probably means that its section definition // appears after us in the symbol table. Leave the associated section as @@ -225,6 +231,35 @@ void ObjFile::readAssociativeDefinition( } } +void ObjFile::recordPrevailingSymbolForMingw( + COFFSymbolRef Sym, DenseMap &PrevailingSectionMap) { + // For comdat symbols in executable sections, where this is the copy + // of the section chunk we actually include instead of discarding it, + // add the symbol to a map to allow using it for implicitly + // associating .[px]data$ sections to it. + int32_t SectionNumber = Sym.getSectionNumber(); + SectionChunk *SC = SparseChunks[SectionNumber]; + if (SC && SC->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) { + StringRef Name; + COFFObj->getSymbolName(Sym, Name); + PrevailingSectionMap[Name] = SectionNumber; + } +} + +void ObjFile::maybeAssociateSEHForMingw( + COFFSymbolRef Sym, const coff_aux_section_definition *Def, + const DenseMap &PrevailingSectionMap) { + StringRef Name; + COFFObj->getSymbolName(Sym, Name); + if (Name.consume_front(".pdata$") || Name.consume_front(".xdata$")) { + // For MinGW, treat .[px]data$ as implicitly associative to + // the symbol . + auto ParentSym = PrevailingSectionMap.find(Name); + if (ParentSym != PrevailingSectionMap.end()) + readAssociativeDefinition(Sym, Def, ParentSym->second); + } +} + Symbol *ObjFile::createRegular(COFFSymbolRef Sym) { SectionChunk *SC = SparseChunks[Sym.getSectionNumber()]; if (Sym.isExternal()) { @@ -248,19 +283,24 @@ void ObjFile::initializeSymbols() { std::vector PendingIndexes; PendingIndexes.reserve(NumSymbols); + DenseMap PrevailingSectionMap; std::vector ComdatDefs( COFFObj->getNumberOfSections() + 1); for (uint32_t I = 0; I < NumSymbols; ++I) { COFFSymbolRef COFFSym = check(COFFObj->getSymbol(I)); + bool PrevailingComdat; if (COFFSym.isUndefined()) { Symbols[I] = createUndefined(COFFSym); } else if (COFFSym.isWeakExternal()) { Symbols[I] = createUndefined(COFFSym); uint32_t TagIndex = COFFSym.getAux()->TagIndex; WeakAliases.emplace_back(Symbols[I], TagIndex); - } else if (Optional OptSym = createDefined(COFFSym, ComdatDefs)) { + } else if (Optional OptSym = + createDefined(COFFSym, ComdatDefs, PrevailingComdat)) { Symbols[I] = *OptSym; + if (Config->MinGW && PrevailingComdat) + recordPrevailingSymbolForMingw(COFFSym, PrevailingSectionMap); } else { // createDefined() returns None if a symbol belongs to a section that // was pending at the point when the symbol was read. This can happen in @@ -278,9 +318,12 @@ void ObjFile::initializeSymbols() { for (uint32_t I : PendingIndexes) { COFFSymbolRef Sym = check(COFFObj->getSymbol(I)); - if (auto *Def = Sym.getSectionDefinition()) + if (auto *Def = Sym.getSectionDefinition()) { if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) readAssociativeDefinition(Sym, Def); + else if (Config->MinGW) + maybeAssociateSEHForMingw(Sym, Def, PrevailingSectionMap); + } if (SparseChunks[Sym.getSectionNumber()] == PendingComdat) { StringRef Name; COFFObj->getSymbolName(Sym, Name); @@ -306,7 +349,9 @@ Symbol *ObjFile::createUndefined(COFFSymbolRef Sym) { Optional ObjFile::createDefined( COFFSymbolRef Sym, - std::vector &ComdatDefs) { + std::vector &ComdatDefs, + bool &Prevailing) { + Prevailing = false; auto GetName = [&]() { StringRef S; COFFObj->getSymbolName(Sym, S); @@ -352,7 +397,6 @@ Optional ObjFile::createDefined( if (const coff_aux_section_definition *Def = ComdatDefs[SectionNumber]) { ComdatDefs[SectionNumber] = nullptr; Symbol *Leader; - bool Prevailing; if (Sym.isExternal()) { std::tie(Leader, Prevailing) = Symtab->addComdat(this, GetName(), Sym.getGeneric()); diff --git a/deps/lld/COFF/InputFiles.h b/deps/lld/COFF/InputFiles.h index 4ee4b36388..2bfb9e4b00 100644 --- a/deps/lld/COFF/InputFiles.h +++ b/deps/lld/COFF/InputFiles.h @@ -13,6 +13,7 @@ #include "Config.h" #include "lld/Common/LLVM.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/LTO/LTO.h" #include "llvm/Object/Archive.h" @@ -157,10 +158,24 @@ private: COFFSymbolRef COFFSym, const llvm::object::coff_aux_section_definition *Def); + void readAssociativeDefinition( + COFFSymbolRef COFFSym, + const llvm::object::coff_aux_section_definition *Def, + uint32_t ParentSection); + + void recordPrevailingSymbolForMingw( + COFFSymbolRef COFFSym, + llvm::DenseMap &PrevailingSectionMap); + + void maybeAssociateSEHForMingw( + COFFSymbolRef Sym, const llvm::object::coff_aux_section_definition *Def, + const llvm::DenseMap &PrevailingSectionMap); + llvm::Optional createDefined(COFFSymbolRef Sym, std::vector - &ComdatDefs); + &ComdatDefs, + bool &PrevailingComdat); Symbol *createRegular(COFFSymbolRef Sym); Symbol *createUndefined(COFFSymbolRef Sym); diff --git a/deps/lld/ELF/LinkerScript.cpp b/deps/lld/ELF/LinkerScript.cpp index abdd899da4..d94970e484 100644 --- a/deps/lld/ELF/LinkerScript.cpp +++ b/deps/lld/ELF/LinkerScript.cpp @@ -116,7 +116,8 @@ void LinkerScript::expandMemoryRegions(uint64_t Size) { if (Ctx->MemRegion) expandMemoryRegion(Ctx->MemRegion, Size, Ctx->MemRegion->Name, Ctx->OutSec->Name); - if (Ctx->LMARegion) + // Only expand the LMARegion if it is different from MemRegion. + if (Ctx->LMARegion && Ctx->MemRegion != Ctx->LMARegion) expandMemoryRegion(Ctx->LMARegion, Size, Ctx->LMARegion->Name, Ctx->OutSec->Name); } @@ -750,6 +751,13 @@ MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *Sec) { return nullptr; } +static OutputSection *findFirstSection(PhdrEntry *Load) { + for (OutputSection *Sec : OutputSections) + if (Sec->PtLoad == Load) + return Sec; + return nullptr; +} + // This function assigns offsets to input sections and an output section // for a single sections command (e.g. ".text { *(.text); }"). void LinkerScript::assignOffsets(OutputSection *Sec) { @@ -775,8 +783,11 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { // will set the LMA such that the difference between VMA and LMA for the // section is the same as the preceding output section in the same region // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html + // This, however, should only be done by the first "non-header" section + // in the segment. if (PhdrEntry *L = Ctx->OutSec->PtLoad) - L->LMAOffset = Ctx->LMAOffset; + if (Sec == findFirstSection(L)) + L->LMAOffset = Ctx->LMAOffset; // We can call this method multiple times during the creation of // thunks and want to start over calculation each time. @@ -953,13 +964,6 @@ void LinkerScript::adjustSectionsAfterSorting() { } } -static OutputSection *findFirstSection(PhdrEntry *Load) { - for (OutputSection *Sec : OutputSections) - if (Sec->PtLoad == Load) - return Sec; - return nullptr; -} - static uint64_t computeBase(uint64_t Min, bool AllocateHeaders) { // If there is no SECTIONS or if the linkerscript is explicit about program // headers, do our best to allocate them. diff --git a/deps/lld/ELF/SyntheticSections.cpp b/deps/lld/ELF/SyntheticSections.cpp index ae02434572..8b02a14c93 100644 --- a/deps/lld/ELF/SyntheticSections.cpp +++ b/deps/lld/ELF/SyntheticSections.cpp @@ -2929,8 +2929,10 @@ void elf::mergeSections() { // We do not want to handle sections that are not alive, so just remove // them instead of trying to merge. - if (!MS->Live) + if (!MS->Live) { + S = nullptr; continue; + } StringRef OutsecName = getOutputSectionName(MS); uint32_t Alignment = std::max(MS->Alignment, MS->Entsize); diff --git a/deps/lld/ELF/Writer.cpp b/deps/lld/ELF/Writer.cpp index 73a97380b5..88a2d5c712 100644 --- a/deps/lld/ELF/Writer.cpp +++ b/deps/lld/ELF/Writer.cpp @@ -1815,12 +1815,14 @@ template std::vector Writer::createPhdrs() { // Segments are contiguous memory regions that has the same attributes // (e.g. executable or writable). There is one phdr for each segment. // Therefore, we need to create a new phdr when the next section has - // different flags or is loaded at a discontiguous address using AT linker - // script command. At the same time, we don't want to create a separate - // load segment for the headers, even if the first output section has - // an AT attribute. + // different flags or is loaded at a discontiguous address or memory + // region using AT or AT> linker script command, respectively. At the same + // time, we don't want to create a separate load segment for the headers, + // even if the first output section has an AT or AT> attribute. uint64_t NewFlags = computeFlags(Sec->getPhdrFlags()); - if ((Sec->LMAExpr && Load->LastSec != Out::ProgramHeaders) || + if (((Sec->LMAExpr || + (Sec->LMARegion && (Sec->LMARegion != Load->FirstSec->LMARegion))) && + Load->LastSec != Out::ProgramHeaders) || Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) { Load = AddHdr(PT_LOAD, NewFlags); diff --git a/deps/lld/docs/ReleaseNotes.rst b/deps/lld/docs/ReleaseNotes.rst index 7ac1f9ce56..58f4798089 100644 --- a/deps/lld/docs/ReleaseNotes.rst +++ b/deps/lld/docs/ReleaseNotes.rst @@ -29,7 +29,13 @@ ELF Improvements COFF Improvements ----------------- -* Item 1. +* Improved correctness of exporting mangled stdcall symbols. + +* Completed support for ARM64 relocations. + +* Added support for outputting PDB debug info for MinGW targets. + +* Improved compatibility of output binaries with GNU binutils objcopy/strip. MachO Improvements ------------------ diff --git a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp index 9b340b00bd..8cb6710857 100644 --- a/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp +++ b/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp @@ -621,6 +621,7 @@ void ArchHandler_x86_64::applyFixupFinal( // Fall into llvm_unreachable(). break; } + llvm_unreachable("invalid x86_64 Reference Kind"); } void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, diff --git a/deps/lld/test/COFF/Inputs/associative-comdat-mingw-2.s b/deps/lld/test/COFF/Inputs/associative-comdat-mingw-2.s new file mode 100644 index 0000000000..edb6a82da8 --- /dev/null +++ b/deps/lld/test/COFF/Inputs/associative-comdat-mingw-2.s @@ -0,0 +1,34 @@ + .section .xdata$foo,"dr" + .linkonce discard + .p2align 3 + .long 42 + + .section .xdata$bar,"dr" + .linkonce discard + .p2align 3 + .long 43 + + .section .xdata$baz,"dr" + .linkonce discard + .p2align 3 + .long 44 + + .def foo; + .scl 2; + .type 32; + .endef + .section .text$foo,"xr",discard,foo + .globl foo + .p2align 4 +foo: + ret + + .def bar; + .scl 2; + .type 32; + .endef + .section .text$bar,"xr",discard,bar + .globl bar + .p2align 4 +bar: + ret diff --git a/deps/lld/test/COFF/Inputs/common-replacement.s b/deps/lld/test/COFF/Inputs/common-replacement.s new file mode 100644 index 0000000000..eaaeee2a3d --- /dev/null +++ b/deps/lld/test/COFF/Inputs/common-replacement.s @@ -0,0 +1,5 @@ + .globl foo + .data + .p2align 2, 0 +foo: + .long 42 diff --git a/deps/lld/test/COFF/associative-comdat-mingw.s b/deps/lld/test/COFF/associative-comdat-mingw.s new file mode 100644 index 0000000000..09cba9c4c6 --- /dev/null +++ b/deps/lld/test/COFF/associative-comdat-mingw.s @@ -0,0 +1,73 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t1.obj +# RUN: llvm-mc -triple=x86_64-windows-gnu %S/Inputs/associative-comdat-mingw-2.s -filetype=obj -o %t2.obj + +# RUN: lld-link -lldmingw -entry:main %t1.obj %t2.obj -out:%t.gc.exe -verbose +# RUN: llvm-readobj -sections %t.gc.exe | FileCheck %s + +# CHECK: Sections [ +# CHECK: Section { +# CHECK: Number: 2 +# CHECK-LABEL: Name: .rdata (2E 72 64 61 74 61 00 00) +# This is the critical check to show that only *one* definition of +# .xdata$foo was retained. This *must* be 4. +# Make sure that no other .xdata sections get included, which would +# increase the size here. +# CHECK-NEXT: VirtualSize: 0x4 + + .text + .def main; + .scl 2; + .type 32; + .endef + .globl main + .p2align 4, 0x90 +main: + call foo + retq + +# Defines .text$foo (which has a leader symbol and is referenced like +# normally), and .xdata$foo (which lacks a leader symbol, which normally +# would be declared associative to the symbol foo). +# .xdata$foo should be implicitly treated as associative to foo and brought +# in, while .xdata$bar, implicitly associative to bar, not included, and +# .xdata$baz not included since there's no symbol baz. + +# GNU binutils ld doesn't do this at all, but always includes all .xdata/.pdata +# comdat sections, even if --gc-sections is used. + + .section .xdata$foo,"dr" + .linkonce discard + .p2align 3 + .long 42 + + .section .xdata$bar,"dr" + .linkonce discard + .p2align 3 + .long 43 + + .section .xdata$baz,"dr" + .linkonce discard + .p2align 3 + .long 44 + + .def foo; + .scl 2; + .type 32; + .endef + .section .text$foo,"xr",discard,foo + .globl foo + .p2align 4 +foo: + ret + + .def bar; + .scl 2; + .type 32; + .endef + .section .text$bar,"xr",discard,bar + .globl bar + .p2align 4 +bar: + ret diff --git a/deps/lld/test/COFF/common-replacement.s b/deps/lld/test/COFF/common-replacement.s new file mode 100644 index 0000000000..51e31fa167 --- /dev/null +++ b/deps/lld/test/COFF/common-replacement.s @@ -0,0 +1,35 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t1.obj +# RUN: llvm-mc -triple=x86_64-windows-gnu %S/Inputs/common-replacement.s -filetype=obj -o %t2.obj + +# RUN: lld-link -lldmingw -entry:main %t1.obj %t2.obj -out:%t.exe -verbose 2>&1 \ +# RUN: | FileCheck -check-prefix VERBOSE %s +# RUN: llvm-readobj -s %t.exe | FileCheck -check-prefix SECTIONS %s + +# VERBOSE: -aligncomm:"foo",2 + +# As long as the .comm symbol is replaced with actual data, RawDataSize +# below should be nonzero. + +# SECTIONS: Name: .data (2E 64 61 74 61 00 00 00) +# SECTIONS-NEXT: VirtualSize: 0x8 +# SECTIONS-NEXT: VirtualAddress: 0x2000 +# SECTIONS-NEXT: RawDataSize: 512 + + + .text + .def main; + .scl 2; + .type 32; + .endef + .globl main + .p2align 4, 0x90 +main: + movl foo(%rip), %eax + retq + +# This produces an aligncomm directive, but when linking in +# Inputs/common-replacement.s, this symbol is replaced by a normal defined +# symbol instead. + .comm foo, 4, 2 diff --git a/deps/lld/test/ELF/linkerscript/Inputs/at6.s b/deps/lld/test/ELF/linkerscript/Inputs/at6.s new file mode 100644 index 0000000000..2d22d4d342 --- /dev/null +++ b/deps/lld/test/ELF/linkerscript/Inputs/at6.s @@ -0,0 +1,11 @@ +.global _start +.text +_start: +nop + +.section .sec1,"aw",@progbits +.long 1 + +.section .sec2,"aw",@progbits +.long 2 + diff --git a/deps/lld/test/ELF/linkerscript/Inputs/at7.s b/deps/lld/test/ELF/linkerscript/Inputs/at7.s new file mode 100644 index 0000000000..29d2963596 --- /dev/null +++ b/deps/lld/test/ELF/linkerscript/Inputs/at7.s @@ -0,0 +1,7 @@ +.global _start +.text +_start: +nop + +.section .sec, "aw" +.word 4 diff --git a/deps/lld/test/ELF/linkerscript/Inputs/at8.s b/deps/lld/test/ELF/linkerscript/Inputs/at8.s new file mode 100644 index 0000000000..e15e4cd3b7 --- /dev/null +++ b/deps/lld/test/ELF/linkerscript/Inputs/at8.s @@ -0,0 +1,8 @@ +.section .sec1,"aw",@progbits +.quad 1 + +.section .sec2,"aw",@progbits +.quad 2 + +.section .sec3,"aw",@progbits +.quad 3 diff --git a/deps/lld/test/ELF/linkerscript/at6.test b/deps/lld/test/ELF/linkerscript/at6.test new file mode 100644 index 0000000000..498c0ef14f --- /dev/null +++ b/deps/lld/test/ELF/linkerscript/at6.test @@ -0,0 +1,30 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/at6.s -o %t.o +# RUN: ld.lld %t.o --script %s -o %t +# RUN: llvm-readelf -sections -program-headers %t | FileCheck %s + +MEMORY { + FLASH : ORIGIN = 0x08000000, LENGTH = 0x100 + RAM : ORIGIN = 0x20000000, LENGTH = 0x200 +} + +SECTIONS { + .text : { *(.text) } > FLASH + .sec1 : { *(.sec1) } > RAM + .sec2 : { *(.sec2) } > RAM AT > FLASH +} + +# Make sure we create a separate PT_LOAD entry for .sec2. Previously, +# it was added to the PT_LOAD entry of .sec1 + +# CHECK: Name Type Address Off +# CHECK: .text PROGBITS 0000000008000000 001000 +# CHECK: .sec1 PROGBITS 0000000020000000 002000 +# CHECK: .sec2 PROGBITS 0000000020000004 002004 + +# CHECK: Program Headers: +# CHECK: Type Offset VirtAddr PhysAddr +# CHECK-NEXT: LOAD 0x001000 0x0000000008000000 0x0000000008000000 +# CHECK-NEXT: LOAD 0x002000 0x0000000020000000 0x0000000020000000 +# CHECK-NEXT: LOAD 0x002004 0x0000000020000004 0x0000000008000001 +# CHECK-NOT: LOAD diff --git a/deps/lld/test/ELF/linkerscript/at7.test b/deps/lld/test/ELF/linkerscript/at7.test new file mode 100644 index 0000000000..1f67df29fd --- /dev/null +++ b/deps/lld/test/ELF/linkerscript/at7.test @@ -0,0 +1,28 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/at7.s -o %t.o +# RUN: ld.lld %t.o --script %s -o %t +# RUN: llvm-readelf -sections -program-headers %t | FileCheck %s + +MEMORY { + RAM : ORIGIN = 0x20000000, LENGTH = 0x200 +} + +SECTIONS { + .text : { *(.text) } > RAM AT> RAM + .sec : { *(.sec) } > RAM +} + +# Make sure the memory for the .text section is only reserved once. +# Previously, the location counter for both MemRegion and LMARegion +# was increased unconditionally. + + +# CHECK: Name Type Address Off +# CHECK: .text PROGBITS 0000000020000000 001000 +# CHECK: .sec PROGBITS 0000000020000001 001001 + +# CHECK: Program Headers: +# CHECK: Type Offset VirtAddr PhysAddr +# CHECK-NEXT: LOAD 0x001000 0x0000000020000000 0x0000000020000000 +# CHECK-NEXT: LOAD 0x001001 0x0000000020000001 0x0000000020000001 +# CHECK-NOT: LOAD diff --git a/deps/lld/test/ELF/linkerscript/at8.test b/deps/lld/test/ELF/linkerscript/at8.test new file mode 100644 index 0000000000..48c0d45814 --- /dev/null +++ b/deps/lld/test/ELF/linkerscript/at8.test @@ -0,0 +1,31 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/at8.s -o %t.o +# RUN: ld.lld %t.o --script %s -o %t +# RUN: llvm-readelf -sections -program-headers %t | FileCheck %s + +MEMORY { + FLASH : ORIGIN = 0x08000000, LENGTH = 0x100 + RAM : ORIGIN = 0x20000000, LENGTH = 0x200 +} + +SECTIONS { + .text : { *(.text) } > FLASH + .sec1 : { *(.sec1) } > RAM AT > FLASH + .sec2 : { *(.sec2) } > RAM + .sec3 : { *(.sec3) } > RAM AT > FLASH +} + +# Make sure we do not issue a load-address overlap error +# Previously, .sec3 would overwrite the LMAOffset in the +# PT_LOAD header. + +# CHECK: Name Type Address Off +# CHECK: .text PROGBITS 0000000008000000 001000 +# CHECK: .sec1 PROGBITS 0000000020000000 001000 +# CHECK: .sec2 PROGBITS 0000000020000008 001008 +# CHECK: .sec3 PROGBITS 0000000020000010 001010 + +# CHECK: Program Headers: +# CHECK: Type Offset VirtAddr PhysAddr +# CHECK-NEXT: LOAD 0x001000 0x0000000020000000 0x0000000008000000 +# CHECK-NOT: LOAD diff --git a/deps/lld/test/ELF/lto/cache.ll b/deps/lld/test/ELF/lto/cache.ll index 3f2bea9f2c..5ab74f5c54 100644 --- a/deps/lld/test/ELF/lto/cache.ll +++ b/deps/lld/test/ELF/lto/cache.ll @@ -13,7 +13,7 @@ ; RUN: ls %t.cache | count 4 ; Create a file of size 64KB. -; RUN: "%python" -c "print(' ' * 65536)" > %t.cache/llvmcache-foo +; RUN: %python -c "print(' ' * 65536)" > %t.cache/llvmcache-foo ; This should leave the file in place. ; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k:prune_interval=0s -o %t3 %t2.o %t.o diff --git a/deps/lld/test/ELF/x86-64-reloc-error2.s b/deps/lld/test/ELF/x86-64-reloc-error2.s index d49b675226..81f033f280 100644 --- a/deps/lld/test/ELF/x86-64-reloc-error2.s +++ b/deps/lld/test/ELF/x86-64-reloc-error2.s @@ -1,14 +1,18 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s +# RUN: not ld.lld --entry=func --gc-sections %t.o -o /dev/null 2>&1 | FileCheck %s ## Check we are able to find a function symbol that encloses ## a given location when reporting error messages. # CHECK: {{.*}}.o:(function func): relocation R_X86_64_32S out of range: -281474974609408 is not in [-2147483648, 2147483647] +# This mergeable section will be garbage collected. We had a crash issue in that case. Test it. +.section .rodata.str1,"aMS",@progbits,1 +.asciz "a" + .section .text.func, "ax", %progbits .globl func .type func,@function -.size func, 0x10 func: - movq func - 0x1000000000000, %rdx + movq $func - 0x1000000000000, %rdx +.size func, .-func diff --git a/deps/lld/test/mach-o/dependency_info.yaml b/deps/lld/test/mach-o/dependency_info.yaml index 34d688541b..06b269ae16 100644 --- a/deps/lld/test/mach-o/dependency_info.yaml +++ b/deps/lld/test/mach-o/dependency_info.yaml @@ -9,7 +9,7 @@ # RUN: -F/Custom/Frameworks \ # RUN: -framework Bar \ # RUN: -framework Foo -# RUN: '%python' %p/Inputs/DependencyDump.py %t.info | FileCheck %s +# RUN: %python %p/Inputs/DependencyDump.py %t.info | FileCheck %s # CHECK: linker-vers: lld diff --git a/deps/lld/test/wasm/lto/cache.ll b/deps/lld/test/wasm/lto/cache.ll index b0a7820c1e..9b4aa5d6e2 100644 --- a/deps/lld/test/wasm/lto/cache.ll +++ b/deps/lld/test/wasm/lto/cache.ll @@ -11,7 +11,7 @@ ; RUN: ls %t.cache | count 4 ; Create a file of size 64KB. -; RUN: "%python" -c "print(' ' * 65536)" > %t.cache/llvmcache-foo +; RUN: %python -c "print(' ' * 65536)" > %t.cache/llvmcache-foo ; This should leave the file in place. ; 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