diff options
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 80 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/merge-sections.s | 28 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/phdrs.s | 3 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/repsection-va.s | 5 |
4 files changed, 45 insertions, 71 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 8e0016a2310..a6fbe64d5ee 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -242,14 +242,15 @@ void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) { if (V.empty()) continue; - OutputSectionBase<ELFT> *OutSec; - bool IsNew; - std::tie(OutSec, IsNew) = Factory.create(V.front(), Cmd->Name); - if (IsNew) - OutputSections->push_back(OutSec); - - uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0; for (InputSectionBase<ELFT> *Sec : V) { + OutputSectionBase<ELFT> *OutSec; + bool IsNew; + std::tie(OutSec, IsNew) = Factory.create(Sec, Cmd->Name); + if (IsNew) + OutputSections->push_back(OutSec); + + uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0; + if (Subalign) Sec->Alignment = Subalign; OutSec->addSection(Sec); @@ -368,16 +369,15 @@ void assignOffsets(OutputSectionCommand *Cmd, OutputSectionBase<ELFT> *Sec) { } template <class ELFT> -static OutputSectionBase<ELFT> * -findSection(OutputSectionCommand &Cmd, - ArrayRef<OutputSectionBase<ELFT> *> Sections) { - for (OutputSectionBase<ELFT> *Sec : Sections) { - if (Sec->getName() != Cmd.Name) - continue; - if (checkConstraint(Sec->getFlags(), Cmd.Constraint)) - return Sec; - } - return nullptr; +static std::vector<OutputSectionBase<ELFT> *> +findSections(OutputSectionCommand &Cmd, + ArrayRef<OutputSectionBase<ELFT> *> Sections) { + std::vector<OutputSectionBase<ELFT> *> Ret; + for (OutputSectionBase<ELFT> *Sec : Sections) + if (Sec->getName() == Cmd.Name && + checkConstraint(Sec->getFlags(), Cmd.Constraint)) + Ret.push_back(Sec); + return Ret; } template <class ELFT> void LinkerScript<ELFT>::assignAddresses() { @@ -413,35 +413,35 @@ template <class ELFT> void LinkerScript<ELFT>::assignAddresses() { } auto *Cmd = cast<OutputSectionCommand>(Base.get()); - OutputSectionBase<ELFT> *Sec = findSection<ELFT>(*Cmd, *OutputSections); - if (!Sec) - continue; + for (OutputSectionBase<ELFT> *Sec : + findSections<ELFT>(*Cmd, *OutputSections)) { - if (Cmd->AddrExpr) - Dot = Cmd->AddrExpr(Dot); + if (Cmd->AddrExpr) + Dot = Cmd->AddrExpr(Dot); - if (Cmd->AlignExpr) - Sec->updateAlignment(Cmd->AlignExpr(Dot)); + if (Cmd->AlignExpr) + Sec->updateAlignment(Cmd->AlignExpr(Dot)); - if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { - uintX_t TVA = Dot + ThreadBssOffset; - TVA = alignTo(TVA, Sec->getAlignment()); - Sec->setVA(TVA); - assignOffsets(Cmd, Sec); - ThreadBssOffset = TVA - Dot + Sec->getSize(); - continue; - } + if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { + uintX_t TVA = Dot + ThreadBssOffset; + TVA = alignTo(TVA, Sec->getAlignment()); + Sec->setVA(TVA); + assignOffsets(Cmd, Sec); + ThreadBssOffset = TVA - Dot + Sec->getSize(); + continue; + } - if (!(Sec->getFlags() & SHF_ALLOC)) { + if (!(Sec->getFlags() & SHF_ALLOC)) { + assignOffsets(Cmd, Sec); + continue; + } + + Dot = alignTo(Dot, Sec->getAlignment()); + Sec->setVA(Dot); assignOffsets(Cmd, Sec); - continue; + MinVA = std::min(MinVA, Dot); + Dot += Sec->getSize(); } - - Dot = alignTo(Dot, Sec->getAlignment()); - Sec->setVA(Dot); - assignOffsets(Cmd, Sec); - MinVA = std::min(MinVA, Dot); - Dot += Sec->getSize(); } // ELF and Program headers need to be right before the first section in diff --git a/lld/test/ELF/linkerscript/merge-sections.s b/lld/test/ELF/linkerscript/merge-sections.s deleted file mode 100644 index bb3849a861c..00000000000 --- a/lld/test/ELF/linkerscript/merge-sections.s +++ /dev/null @@ -1,28 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t - -# RUN: echo "SECTIONS { .foo : { *(.foo.*) } }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t -# RUN: llvm-objdump -s %t1 | FileCheck %s -# CHECK: Contents of section .foo: -# CHECK-NEXT: 0158 01000000 02000000 00000000 73686f72 ............shor -# CHECK-NEXT: 0168 7420756e 7369676e 65642069 6e7400 t unsigned int. - -.global _start -_start: - nop - -.section .foo.1, "aw" -writable: - .long 1 - -.section .foo.2, "aM",@progbits,1 -readable: - .long 2 - -.section .foo.3, "awx" - .long 0 - -.section .foo.4, "MS",@progbits,1 -.LASF2: - .string "short unsigned int" diff --git a/lld/test/ELF/linkerscript/phdrs.s b/lld/test/ELF/linkerscript/phdrs.s index 775e002506b..cd6bf82b55b 100644 --- a/lld/test/ELF/linkerscript/phdrs.s +++ b/lld/test/ELF/linkerscript/phdrs.s @@ -17,8 +17,9 @@ # CHECK-NEXT: PhysicalAddress: 0x10000000 # CHECK-NEXT: FileSize: 521 # CHECK-NEXT: MemSize: 521 -# CHECK-NEXT: Flags [ (0x5) +# CHECK-NEXT: Flags [ (0x7) # CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: PF_W (0x2) # CHECK-NEXT: PF_X (0x1) # CHECK-NEXT: ] diff --git a/lld/test/ELF/linkerscript/repsection-va.s b/lld/test/ELF/linkerscript/repsection-va.s index 29ecdf84a8b..4feeaa0e1c3 100644 --- a/lld/test/ELF/linkerscript/repsection-va.s +++ b/lld/test/ELF/linkerscript/repsection-va.s @@ -7,8 +7,9 @@ # CHECK: Sections: # CHECK-NEXT: Idx Name Size Address Type # CHECK-NEXT: 0 00000000 0000000000000000 -# CHECK-NEXT: 1 .foo 00000008 0000000000000120 DATA -# CHECK-NEXT: 2 .text 00000001 0000000000000128 TEXT DATA +# CHECK-NEXT: 1 .foo 00000004 0000000000000158 DATA +# CHECK-NEXT: 2 .foo 00000004 000000000000015c DATA +# CHECK-NEXT: 3 .text 00000001 0000000000000160 TEXT DATA .global _start _start: |

