From 3fb5a6dc9e0c30af868c85ac77c94ebec836b08a Mon Sep 17 00:00:00 2001 From: George Rimar Date: Tue, 29 Nov 2016 16:05:27 +0000 Subject: [PATCH] [ELF] - Add support of proccessing of the rest allocatable synthetic sections from linkerscript. This change continues what was started by D27040 Now all allocatable synthetics should be available from script side. Differential revision: https://reviews.llvm.org/D27131 llvm-svn: 288150 --- lld/ELF/LinkerScript.cpp | 9 ++ lld/ELF/SyntheticSections.cpp | 4 + lld/ELF/SyntheticSections.h | 1 + lld/ELF/Writer.cpp | 64 +++++------- lld/test/ELF/eh-frame-hdr-abs-fde.s | 8 +- lld/test/ELF/eh-frame-hdr-augmentation.s | 2 +- lld/test/ELF/eh-frame-hdr-icf.s | 4 +- lld/test/ELF/eh-frame-hdr.s | 121 +++++++++++------------ lld/test/ELF/eh-frame-marker.s | 5 +- lld/test/ELF/linkerscript/phdrs.s | 4 +- 10 files changed, 113 insertions(+), 109 deletions(-) diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 51689c2b011e..f87922c53e70 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/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 @@ template void LinkerScript::process(BaseCommand &Base) { // 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)) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index f54892dcd7a3..33515c2f89f0 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1448,6 +1448,10 @@ template void GdbIndexSection::writeTo(uint8_t *Buf) { } } +template bool GdbIndexSection::empty() const { + return !Out::DebugInfo; +} + template EhFrameHeader::EhFrameHeader() : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 1, ".eh_frame_hdr") {} diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 767767814c31..bafd4e99469f 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -446,6 +446,7 @@ public: 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; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 2fd2dc3e2827..8b8217b5b798 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -239,7 +239,6 @@ template void Writer::createSyntheticSections() { 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 @@ template void Writer::createSyntheticSections() { In::Interp = nullptr; } - if (Config->EhFrameHdr) - In::EhFrameHdr = make>(); + if (!Config->Relocatable) + Symtab::X->Sections.push_back(createCommentSection()); - if (Config->GdbIndex) - In::GdbIndex = make>(); - - 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 @@ template void Writer::createSyntheticSections() { 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 @@ template 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 @@ template void Writer::finalizeSections() { 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 diff --git a/lld/test/ELF/eh-frame-hdr-abs-fde.s b/lld/test/ELF/eh-frame-hdr-abs-fde.s index 37705d6ad818..dd0836a0ab72 100644 --- a/lld/test/ELF/eh-frame-hdr-abs-fde.s +++ b/lld/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" diff --git a/lld/test/ELF/eh-frame-hdr-augmentation.s b/lld/test/ELF/eh-frame-hdr-augmentation.s index 905c28e2fa6c..618f5e1a9d7d 100644 --- a/lld/test/ELF/eh-frame-hdr-augmentation.s +++ b/lld/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: diff --git a/lld/test/ELF/eh-frame-hdr-icf.s b/lld/test/ELF/eh-frame-hdr-icf.s index fcf9471ecedc..1b42285f5d32 100644 --- a/lld/test/ELF/eh-frame-hdr-icf.s +++ b/lld/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 diff --git a/lld/test/ELF/eh-frame-hdr.s b/lld/test/ELF/eh-frame-hdr.s index af39aba5f9c6..35c14a4b65dd 100644 --- a/lld/test/ELF/eh-frame-hdr.s +++ b/lld/test/ELF/eh-frame-hdr.s @@ -40,84 +40,83 @@ _start: //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: Link: 0 -// HDR-NEXT: Info: 0 -// HDR-NEXT: AddressAlignment: 8 -// 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: ) -// HDR-NEXT: } -// HDR-NEXT: Section { -// HDR-NEXT: Index: 2 -// HDR-NEXT: Name: .eh_frame_hdr -// 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: Link: 0 // HDR-NEXT: Info: 0 // HDR-NEXT: AddressAlignment: 1 // 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: 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: +// HDR-NEXT: Name: .eh_frame +// HDR-NEXT: Type: SHT_PROGBITS +// HDR-NEXT: Flags [ +// HDR-NEXT: SHF_ALLOC +// HDR-NEXT: ] +// HDR-NEXT: Address: 0x200180 +// HDR-NEXT: Offset: 0x180 +// HDR-NEXT: Size: 96 +// HDR-NEXT: Link: 0 +// HDR-NEXT: Info: 0 +// HDR-NEXT: AddressAlignment: 8 +// HDR-NEXT: EntrySize: 0 +// HDR-NEXT: SectionData ( +// 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 [ diff --git a/lld/test/ELF/eh-frame-marker.s b/lld/test/ELF/eh-frame-marker.s index 5951145c6a34..30bac460ae25 100644 --- a/lld/test/ELF/eh-frame-marker.s +++ b/lld/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: diff --git a/lld/test/ELF/linkerscript/phdrs.s b/lld/test/ELF/linkerscript/phdrs.s index 93456892b02c..e35fa010bfbc 100644 --- a/lld/test/ELF/linkerscript/phdrs.s +++ b/lld/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