#include "Strings.h"
#include "SymbolTable.h"
#include "Symbols.h"
+#include "SyntheticSections.h"
#include "Target.h"
#include "Writer.h"
#include "llvm/ADT/STLExtras.h"
// updates the output section size.
auto &ICmd = cast<InputSectionDescription>(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<SyntheticSection<ELFT>>(ID))
+ if (Sec->empty())
+ continue;
+
auto *IB = static_cast<InputSectionBase<ELFT> *>(ID);
switchTo(IB->OutSec);
if (auto *I = dyn_cast<InputSection<ELFT>>(IB))
}
}
+template <class ELFT> bool GdbIndexSection<ELFT>::empty() const {
+ return !Out<ELFT>::DebugInfo;
+}
+
template <class ELFT>
EhFrameHeader<ELFT>::EhFrameHeader()
: SyntheticSection<ELFT>(SHF_ALLOC, SHT_PROGBITS, 1, ".eh_frame_hdr") {}
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<std::pair<uintX_t, uintX_t>> CompilationUnits;
In<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true);
In<ELFT>::Dynamic = make<DynamicSection<ELFT>>();
Out<ELFT>::EhFrame = make<EhOutputSection<ELFT>>();
- In<ELFT>::Plt = make<PltSection<ELFT>>();
In<ELFT>::RelaDyn = make<RelocationSection<ELFT>>(
Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
In<ELFT>::ShStrTab = make<StringTableSection<ELFT>>(".shstrtab", false);
In<ELFT>::Interp = nullptr;
}
- if (Config->EhFrameHdr)
- In<ELFT>::EhFrameHdr = make<EhFrameHeader<ELFT>>();
-
- if (Config->GdbIndex)
- In<ELFT>::GdbIndex = make<GdbIndexSection<ELFT>>();
+ if (!Config->Relocatable)
+ Symtab<ELFT>::X->Sections.push_back(createCommentSection<ELFT>());
- In<ELFT>::RelaPlt = make<RelocationSection<ELFT>>(
- Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
if (Config->Strip != StripPolicy::All) {
In<ELFT>::StrTab = make<StringTableSection<ELFT>>(".strtab", false);
In<ELFT>::SymTab = make<SymbolTableSection<ELFT>>(*In<ELFT>::StrTab);
}
- // Initialize linker generated sections
- if (!Config->Relocatable)
- Symtab<ELFT>::X->Sections.push_back(createCommentSection<ELFT>());
-
if (Config->BuildId != BuildIdKind::None) {
In<ELFT>::BuildId = make<BuildIdSection<ELFT>>();
Symtab<ELFT>::X->Sections.push_back(In<ELFT>::BuildId);
In<ELFT>::GotPlt = make<GotPltSection<ELFT>>();
Symtab<ELFT>::X->Sections.push_back(In<ELFT>::GotPlt);
+
+ if (Config->GdbIndex) {
+ In<ELFT>::GdbIndex = make<GdbIndexSection<ELFT>>();
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::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<ELFT>::RelaPlt = make<RelocationSection<ELFT>>(
+ Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::RelaPlt);
+
+ In<ELFT>::Plt = make<PltSection<ELFT>>();
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::Plt);
+
+ if (Config->EhFrameHdr) {
+ In<ELFT>::EhFrameHdr = make<EhFrameHeader<ELFT>>();
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::EhFrameHdr);
+ }
}
template <class ELFT>
static void
finalizeSynthetic(const std::vector<SyntheticSection<ELFT> *> &Sections) {
for (SyntheticSection<ELFT> *SS : Sections)
- if (SS && SS->OutSec) {
+ if (SS && SS->OutSec && !SS->empty()) {
SS->finalize();
SS->OutSec->Size = 0;
SS->OutSec->assignOffsets();
In<ELFT>::VerNeed, In<ELFT>::Dynamic});
}
-// This function add Out<ELFT>::* sections to OutputSections.
template <class ELFT> void Writer<ELFT>::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<ELFT>::GdbIndex && Out<ELFT>::DebugInfo)
- addInputSec(In<ELFT>::GdbIndex);
- addInputSec(In<ELFT>::SymTab);
- addInputSec(In<ELFT>::ShStrTab);
- addInputSec(In<ELFT>::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<ELFT>::RelaPlt->empty())
- addInputSec(In<ELFT>::RelaPlt);
-
- if (!In<ELFT>::Plt->empty())
- addInputSec(In<ELFT>::Plt);
- if (!Out<ELFT>::EhFrame->empty())
- addInputSec(In<ELFT>::EhFrameHdr);
if (Out<ELFT>::Bss->Size > 0)
- Add(Out<ELFT>::Bss);
+ OutputSections.push_back(Out<ELFT>::Bss);
auto OS = dyn_cast_or_null<OutputSection<ELFT>>(findSection(".ARM.exidx"));
if (OS && !OS->Sections.empty() && !Config->Relocatable)
OS->addSection(make<ARMExidxSentinelSection<ELFT>>());
+
+ addInputSec(In<ELFT>::SymTab);
+ addInputSec(In<ELFT>::ShStrTab);
+ addInputSec(In<ELFT>::StrTab);
}
// The linker is expected to define SECNAME_start and SECNAME_end
# 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"
// 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:
# 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
//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 [
// 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:
# 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