Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -21,6 +21,7 @@ #include "Strings.h" #include "SymbolTable.h" #include "Symbols.h" +#include "SyntheticSections.h" #include "Target.h" #include "Writer.h" #include "llvm/ADT/STLExtras.h" @@ -489,6 +490,14 @@ // updates the output section size. auto &ICmd = cast(Base); for (InputSectionData *ID : ICmd.Sections) { + // We tentatively added all synthetic sections at the beginning and removed + // empty ones afterwards (because there is no way to know whether they were + // going be empty or not other than actually running linker scripts.) + // We need to ignore remains of empty sections. + if (auto *Sec = dyn_cast>(ID)) + if (Sec->empty()) + continue; + auto *IB = static_cast *>(ID); switchTo(IB->OutSec); if (auto *I = dyn_cast>(IB)) Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -446,6 +446,7 @@ void finalize() override; void writeTo(uint8_t *Buf) override; size_t getSize() const override { return CuTypesOffset; } + bool empty() const override; // Pairs of [CU Offset, CU length]. std::vector> CompilationUnits; Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -1448,6 +1448,10 @@ } } +template bool GdbIndexSection::empty() const { + return !Out::DebugInfo; +} + template EhFrameHeader::EhFrameHeader() : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 1, ".eh_frame_hdr") {} Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -239,7 +239,6 @@ In::DynStrTab = make>(".dynstr", true); In::Dynamic = make>(); Out::EhFrame = make>(); - In::Plt = make>(); In::RelaDyn = make>( Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc); In::ShStrTab = make>(".shstrtab", false); @@ -256,23 +255,14 @@ In::Interp = nullptr; } - if (Config->EhFrameHdr) - In::EhFrameHdr = make>(); - - if (Config->GdbIndex) - In::GdbIndex = make>(); + if (!Config->Relocatable) + Symtab::X->Sections.push_back(createCommentSection()); - In::RelaPlt = make>( - Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/); if (Config->Strip != StripPolicy::All) { In::StrTab = make>(".strtab", false); In::SymTab = make>(*In::StrTab); } - // Initialize linker generated sections - if (!Config->Relocatable) - Symtab::X->Sections.push_back(createCommentSection()); - if (Config->BuildId != BuildIdKind::None) { In::BuildId = make>(); Symtab::X->Sections.push_back(In::BuildId); @@ -341,6 +331,25 @@ In::GotPlt = make>(); Symtab::X->Sections.push_back(In::GotPlt); + + if (Config->GdbIndex) { + In::GdbIndex = make>(); + Symtab::X->Sections.push_back(In::GdbIndex); + } + + // We always need to add rel[a].plt to output if it has entries. + // Even for static linking it can contain R_[*]_IRELATIVE relocations. + In::RelaPlt = make>( + Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/); + Symtab::X->Sections.push_back(In::RelaPlt); + + In::Plt = make>(); + Symtab::X->Sections.push_back(In::Plt); + + if (Config->EhFrameHdr) { + In::EhFrameHdr = make>(); + Symtab::X->Sections.push_back(In::EhFrameHdr); + } } template @@ -886,7 +895,7 @@ static void finalizeSynthetic(const std::vector *> &Sections) { for (SyntheticSection *SS : Sections) - if (SS && SS->OutSec) { + if (SS && SS->OutSec && !SS->empty()) { SS->finalize(); SS->OutSec->Size = 0; SS->OutSec->assignOffsets(); @@ -1004,36 +1013,17 @@ In::VerNeed, In::Dynamic}); } -// This function add Out::* sections to OutputSections. template void Writer::addPredefinedSections() { - auto Add = [&](OutputSectionBase *OS) { - if (OS) - OutputSections.push_back(OS); - }; - - // This order is not the same as the final output order - // because we sort the sections using their attributes below. - if (In::GdbIndex && Out::DebugInfo) - addInputSec(In::GdbIndex); - addInputSec(In::SymTab); - addInputSec(In::ShStrTab); - addInputSec(In::StrTab); - - // We always need to add rel[a].plt to output if it has entries. - // Even during static linking it can contain R_[*]_IRELATIVE relocations. - if (!In::RelaPlt->empty()) - addInputSec(In::RelaPlt); - - if (!In::Plt->empty()) - addInputSec(In::Plt); - if (!Out::EhFrame->empty()) - addInputSec(In::EhFrameHdr); if (Out::Bss->Size > 0) - Add(Out::Bss); + OutputSections.push_back(Out::Bss); auto OS = dyn_cast_or_null>(findSection(".ARM.exidx")); if (OS && !OS->Sections.empty() && !Config->Relocatable) OS->addSection(make>()); + + addInputSec(In::SymTab); + addInputSec(In::ShStrTab); + addInputSec(In::StrTab); } // The linker is expected to define SECNAME_start and SECNAME_end Index: lld/trunk/test/ELF/eh-frame-hdr-abs-fde.s =================================================================== --- lld/trunk/test/ELF/eh-frame-hdr-abs-fde.s +++ lld/trunk/test/ELF/eh-frame-hdr-abs-fde.s @@ -9,11 +9,11 @@ # REQUIRES: mips # CHECK: Contents of section .eh_frame_hdr: -# CHECK-NEXT: 10178 011b033b ffffffcc 00000001 0000fe88 -# ^-- 0x20000 - 0x10178 +# CHECK-NEXT: 10148 011b033b 00000010 00000001 0000feb8 +# ^-- 0x20000 - 0x10148 # .text - .eh_frame_hdr -# CHECK-NEXT: 10188 ffffffe8 -# CHECK-NEXT: Contents of section .text: +# CHECK-NEXT: 10158 0000002c +# CHECK: Contents of section .text: # CHECK-NEXT: 20000 00000000 # CHECK: Augmentation: "zLR" Index: lld/trunk/test/ELF/eh-frame-hdr-augmentation.s =================================================================== --- lld/trunk/test/ELF/eh-frame-hdr-augmentation.s +++ lld/trunk/test/ELF/eh-frame-hdr-augmentation.s @@ -18,7 +18,7 @@ // CHECK-NEXT: DW_CFA_nop: // CHECK-NEXT: DW_CFA_nop: -// CHECK: 00000020 00000014 00000024 FDE cie=00000024 pc=00000da8...00000da8 +// CHECK: 00000020 00000014 00000024 FDE cie=00000024 pc=00000d98...00000d98 // CHECK-NEXT: DW_CFA_nop: // CHECK-NEXT: DW_CFA_nop: // CHECK-NEXT: DW_CFA_nop: Index: lld/trunk/test/ELF/eh-frame-hdr-icf.s =================================================================== --- lld/trunk/test/ELF/eh-frame-hdr-icf.s +++ lld/trunk/test/ELF/eh-frame-hdr-icf.s @@ -5,9 +5,9 @@ # RUN: llvm-objdump -s %t2 | FileCheck %s # CHECK: Contents of section .eh_frame_hdr: -# CHECK-NEXT: 2001a0 011b033b b4ffffff 01000000 600e0000 +# CHECK-NEXT: 200158 011b033b 1c000000 01000000 a80e0000 # ^ FDE count -# CHECK-NEXT: 2001b0 d0ffffff 00000000 00000000 +# CHECK-NEXT: 200168 38000000 00000000 00000000 # ^ FDE for f2 .globl _start, f1, f2 Index: lld/trunk/test/ELF/eh-frame-hdr.s =================================================================== --- lld/trunk/test/ELF/eh-frame-hdr.s +++ lld/trunk/test/ELF/eh-frame-hdr.s @@ -40,84 +40,83 @@ //HDRDISASM-NEXT: dah: //HDRDISASM-NEXT: 201002: 90 nop -// HDR: Sections [ -// HDR: Section { -// HDR: Index: 1 -// HDR-NEXT: Name: .eh_frame +// HDR: Section { +// HDR: Index: +// HDR: Name: .eh_frame_hdr // HDR-NEXT: Type: SHT_PROGBITS // HDR-NEXT: Flags [ // HDR-NEXT: SHF_ALLOC // HDR-NEXT: ] // HDR-NEXT: Address: 0x200158 // HDR-NEXT: Offset: 0x158 -// HDR-NEXT: Size: 96 +// HDR-NEXT: Size: 36 // HDR-NEXT: Link: 0 // HDR-NEXT: Info: 0 -// HDR-NEXT: AddressAlignment: 8 +// HDR-NEXT: AddressAlignment: 1 // HDR-NEXT: EntrySize: 0 // HDR-NEXT: SectionData ( -// HDR-NEXT: 0000: 14000000 00000000 017A5200 01781001 | -// HDR-NEXT: 0010: 1B0C0708 90010000 14000000 1C000000 | -// HDR-NEXT: 0020: 880E0000 01000000 00000000 00000000 | -// HDR-NEXT: 0030: 14000000 34000000 710E0000 01000000 | -// HDR-NEXT: 0040: 00000000 00000000 14000000 4C000000 | -// HDR-NEXT: 0050: 5A0E0000 01000000 00000000 00000000 | -// CIE: 14000000 00000000 017A5200 01781001 1B0C0708 90010000 -// FDE(1): 14000000 1C000000 880E0000 01000000 00000000 00000000 -// address of data (starts with 0x880E0000) = 0x200158 + 0x0020 = 0x200178 -// The starting address to which this FDE applies = 0xE88 + 0x200178 = 0x201000 -// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1 -// FDE(2): 14000000 34000000 710E0000 01000000 00000000 00000000 -// address of data (starts with 0x710E0000) = 0x200158 + 0x0038 = 0x200190 -// The starting address to which this FDE applies = 0xE71 + 0x200190 = 0x201001 -// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1 -// FDE(3): 14000000 4C000000 5A0E0000 01000000 00000000 00000000 -// address of data (starts with 0x5A0E0000) = 0x200158 + 0x0050 = 0x2001A8 -// The starting address to which this FDE applies = 0xE5A + 0x2001A8 = 0x201002 -// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1 +// HDR-NEXT: 0000: 011B033B 24000000 03000000 A80E0000 +// HDR-NEXT: 0010: 40000000 A90E0000 58000000 AA0E0000 +// HDR-NEXT: 0020: 70000000 // HDR-NEXT: ) +// Header (always 4 bytes): 0x011B033B +// 24000000 = .eh_frame(0x200180) - .eh_frame_hdr(0x200158) - 4 +// 03000000 = 3 = the number of FDE pointers in the table. +// Entry(1): A80E0000 40000000 +// 480E0000 = 0x201000 - .eh_frame_hdr(0x200158) = 0xEA8 +// 40000000 = address of FDE(1) - .eh_frame_hdr(0x200158) = +// = .eh_frame(0x200180) + 24 - 0x200158 = 0x40 +// Entry(2): A90E0000 58000000 +// A90E0000 = 0x201001 - .eh_frame_hdr(0x200158) = 0xEA9 +// 58000000 = address of FDE(2) - .eh_frame_hdr(0x200158) = +// = .eh_frame(0x200180) + 24 + 24 - 0x200158 = 0x58 +// Entry(3): AA0E0000 70000000 +// AA0E0000 = 0x201002 - .eh_frame_hdr(0x200158) = 0xEAA +// 70000000 = address of FDE(3) - .eh_frame_hdr(0x200158) = +// = .eh_frame(0x200180) + 24 + 24 + 24 - 0x200158 = 0x70 // HDR-NEXT: } // HDR-NEXT: Section { -// HDR-NEXT: Index: 2 -// HDR-NEXT: Name: .eh_frame_hdr +// HDR-NEXT: Index: +// HDR-NEXT: Name: .eh_frame // HDR-NEXT: Type: SHT_PROGBITS // HDR-NEXT: Flags [ // HDR-NEXT: SHF_ALLOC // HDR-NEXT: ] -// HDR-NEXT: Address: 0x2001B8 -// HDR-NEXT: Offset: 0x1B8 -// HDR-NEXT: Size: 36 +// HDR-NEXT: Address: 0x200180 +// HDR-NEXT: Offset: 0x180 +// HDR-NEXT: Size: 96 // HDR-NEXT: Link: 0 // HDR-NEXT: Info: 0 -// HDR-NEXT: AddressAlignment: 1 +// HDR-NEXT: AddressAlignment: 8 // HDR-NEXT: EntrySize: 0 // HDR-NEXT: SectionData ( -// HDR-NEXT: 0000: 011B033B 9CFFFFFF 03000000 480E0000 | -// HDR-NEXT: 0010: B8FFFFFF 490E0000 D0FFFFFF 4A0E0000 | -// HDR-NEXT: 0020: E8FFFFFF | -// Header (always 4 bytes): 0x011B033B -// 9CFFFFFF = .eh_frame(0x200158) - .eh_frame_hdr(0x2001B8) - 4 -// 03000000 = 3 = the number of FDE pointers in the table. -// Entry(1): 480E0000 B8FFFFFF -// 480E0000 = 0x201000 - .eh_frame_hdr(0x2001B8) = 0xE48 -// B8FFFFFF = address of FDE(1) - .eh_frame_hdr(0x2001B8) = -// = .eh_frame(0x200158) + 24 - 0x2001B8 = 0xFFFFFFB8 -// Entry(2): 490E0000 D0FFFFFF -// 490E0000 = 0x201001 - .eh_frame_hdr(0x2001B8) = 0xE49 -// D0FFFFFF = address of FDE(2) - .eh_frame_hdr(0x2001B8) = -// = .eh_frame(0x200158) + 24 + 24 - 0x2001B8 = 0xFFFFFFD0 -// Entry(3): 4A0E0000 E8FFFFFF -// 4A0E0000 = 0x201002 - .eh_frame_hdr(0x2001B8) = 0xE4A -// E8FFFFFF = address of FDE(2) - .eh_frame_hdr(0x2001B8) = -// = .eh_frame(0x200158) + 24 + 24 - 0x2001B8 = 0xFFFFFFE8 +// HDR-NEXT: 0000: 14000000 00000000 017A5200 01781001 +// HDR-NEXT: 0010: 1B0C0708 90010000 14000000 1C000000 +// HDR-NEXT: 0020: 600E0000 01000000 00000000 00000000 +// HDR-NEXT: 0030: 14000000 34000000 490E0000 01000000 +// HDR-NEXT: 0040: 00000000 00000000 14000000 4C000000 +// HDR-NEXT: 0050: 320E0000 01000000 00000000 00000000 // HDR-NEXT: ) +// CIE: 14000000 00000000 017A5200 01781001 1B0C0708 90010000 +// FDE(1): 14000000 1C000000 600E0000 01000000 00000000 00000000 +// address of data (starts with 0x600E0000) = 0x200180 + 0x0020 = 0x2001A0 +// The starting address to which this FDE applies = 0xE60 + 0x2001A0 = 0x201000 +// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1 +// FDE(2): 14000000 34000000 490E0000 01000000 00000000 00000000 +// address of data (starts with 0x490E0000) = 0x200180 + 0x0038 = 0x2001B8 +// The starting address to which this FDE applies = 0xE49 + 0x2001B8 = 0x201001 +// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1 +// FDE(3): 14000000 4C000000 320E0000 01000000 00000000 00000000 +// address of data (starts with 0x320E0000) = 0x200180 + 0x0050 = 0x2001D0 +// The starting address to which this FDE applies = 0xE5A + 0x2001D0 = 0x201002 +// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1 // HDR-NEXT: } // HDR: ProgramHeaders [ // HDR: ProgramHeader { // HDR: Type: PT_GNU_EH_FRAME -// HDR-NEXT: Offset: 0x1B8 -// HDR-NEXT: VirtualAddress: 0x2001B8 -// HDR-NEXT: PhysicalAddress: 0x2001B8 +// HDR-NEXT: Offset: 0x158 +// HDR-NEXT: VirtualAddress: 0x200158 +// HDR-NEXT: PhysicalAddress: 0x200158 // HDR-NEXT: FileSize: 36 // HDR-NEXT: MemSize: 36 // HDR-NEXT: Flags [ Index: lld/trunk/test/ELF/eh-frame-marker.s =================================================================== --- lld/trunk/test/ELF/eh-frame-marker.s +++ lld/trunk/test/ELF/eh-frame-marker.s @@ -3,15 +3,16 @@ // RUN: llvm-readobj -t -s %t.so | FileCheck %s // We used to crash on this. +// CHECK: Name: .eh_frame_hdr // CHECK: Name: .eh_frame // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x229 +// CHECK-NEXT: Address: [[ADDR:.*]] // CHECK: Name: foo -// CHECK-NEXT: Value: 0x229 +// CHECK-NEXT: Value: [[ADDR]] .section .eh_frame foo: Index: lld/trunk/test/ELF/linkerscript/phdrs.s =================================================================== --- lld/trunk/test/ELF/linkerscript/phdrs.s +++ lld/trunk/test/ELF/linkerscript/phdrs.s @@ -95,8 +95,8 @@ # INT-PHDRS-NEXT: Offset: 0xB0 # INT-PHDRS-NEXT: VirtualAddress: 0xB0 # INT-PHDRS-NEXT: PhysicalAddress: 0xB0 -# INT-PHDRS-NEXT: FileSize: 9 -# INT-PHDRS-NEXT: MemSize: 9 +# INT-PHDRS-NEXT: FileSize: +# INT-PHDRS-NEXT: MemSize: # INT-PHDRS-NEXT: Flags [ # INT-PHDRS-NEXT: PF_R # INT-PHDRS-NEXT: PF_W