void WriteRelocations(MCAssembler &Asm, const MCAsmLayout &Layout);
+ void
+ createSectionHeaderStringTable(MCAssembler &Asm,
+ std::vector<const MCSectionELF *> &Sections);
void CreateMetadataSections(MCAssembler &Asm, const MCAsmLayout &Layout,
std::vector<const MCSectionELF *> &Sections);
Write16(NumberOfSections);
// e_shstrndx = Section # of '.shstrtab'
- if (ShstrtabIndex >= ELF::SHN_LORESERVE)
- Write16(ELF::SHN_XINDEX);
- else
- Write16(ShstrtabIndex);
+ assert(ShstrtabIndex < ELF::SHN_LORESERVE);
+ Write16(ShstrtabIndex);
}
uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data,
}
}
+void ELFObjectWriter::createSectionHeaderStringTable(
+ MCAssembler &Asm, std::vector<const MCSectionELF *> &Sections) {
+ const MCSectionELF *ShstrtabSection = Sections[ShstrtabIndex - 1];
+
+ Asm.getOrCreateSectionData(*ShstrtabSection);
+
+ for (MCSectionData &SD : Asm) {
+ const MCSectionELF &Section =
+ static_cast<const MCSectionELF &>(SD.getSection());
+ ShStrTabBuilder.add(Section.getSectionName());
+ }
+ ShStrTabBuilder.finalize(StringTableBuilder::ELF);
+ OS << ShStrTabBuilder.data();
+}
+
void ELFObjectWriter::CreateMetadataSections(
MCAssembler &Asm, const MCAsmLayout &Layout,
std::vector<const MCSectionELF *> &Sections) {
unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
- // We construct .shstrtab, .symtab and .strtab in this order to match gnu as.
- const MCSectionELF *ShstrtabSection =
- Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0);
- MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection);
- ShstrtabSD.setAlignment(1);
- ShstrtabIndex = Sections.size() + 1;
- Sections.push_back(ShstrtabSection);
-
const MCSectionELF *SymtabSection =
Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0,
EntrySize, "");
F = new MCDataFragment(&StrtabSD);
F->getContents().append(StrTabBuilder.data().begin(),
StrTabBuilder.data().end());
-
- F = new MCDataFragment(&ShstrtabSD);
-
- // Section header string table.
- for (auto it = Asm.begin(), ie = Asm.end(); it != ie; ++it) {
- const MCSectionELF &Section =
- static_cast<const MCSectionELF&>(it->getSection());
- ShStrTabBuilder.add(Section.getSectionName());
- }
- ShStrTabBuilder.finalize(StringTableBuilder::ELF);
- F->getContents().append(ShStrTabBuilder.data().begin(),
- ShStrTabBuilder.data().end());
}
void ELFObjectWriter::createIndexedSections(
SectionIndexMapTy &SectionIndexMap) {
MCContext &Ctx = Asm.getContext();
+ const MCSectionELF *ShstrtabSection =
+ Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0);
+ Sections.push_back(ShstrtabSection);
+ ShstrtabIndex = Sections.size();
+ assert(ShstrtabIndex == 1);
+
// Build the groups
for (const MCSectionData &SD : Asm) {
const MCSectionELF &Section =
// Null section first.
uint64_t FirstSectionSize =
(NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
- uint32_t FirstSectionLink =
- ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0;
- WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0);
+ WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, 0, 0);
for (unsigned i = 0; i < NumSections; ++i) {
const MCSectionELF &Section = *Sections[i];
CreateMetadataSections(Asm, Layout, Sections);
- unsigned NumSections = Asm.size();
+ unsigned NumSections = Asm.size() + 1;
SectionOffsetsTy SectionOffsets;
// Write out the ELF header ...
WriteHeader(Asm, NumSections + 1);
// ... then the sections ...
- for (const MCSectionELF *Section : Sections) {
- const MCSectionData &SD = Asm.getOrCreateSectionData(*Section);
+ SectionOffsets.push_back(std::make_pair(0, 0));
+ for (auto I = ++Sections.begin(), E = Sections.end(); I != E; ++I) {
+ const MCSectionData &SD = Asm.getOrCreateSectionData(**I);
uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment());
WriteZeros(Padding);
SectionOffsets.push_back(std::make_pair(SecStart, SecEnd));
}
+ {
+ uint64_t SecStart = OS.tell();
+ createSectionHeaderStringTable(Asm, Sections);
+ uint64_t SecEnd = OS.tell();
+ SectionOffsets[0] = std::make_pair(SecStart, SecEnd);
+ }
+
uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment);
WriteZeros(Padding);
@ The second, third, and fourth word should correspond to the section index
@ of .TEST1, .ARM.extab.TEST1, and .ARM.exidx.TEST1.
@-------------------------------------------------------------------------------
-@ CHECK: 0000: 01000000 05000000 06000000 07000000 |................|
+@ CHECK: 0000: 01000000 06000000 07000000 08000000 |................|
@ CHECK: )
@ CHECK: }
@ Check the .TEST1 section
@-------------------------------------------------------------------------------
@ CHECK: Section {
-@ CHECK: Index: 5
-@ CHECK: Name: .TEST1
+@ CHECK: Index: 6
+@ CHECK-NEXT: Name: .TEST1
@ CHECK: Type: SHT_PROGBITS (0x1)
@-------------------------------------------------------------------------------
@ The flags should contain SHF_GROUP.
@ Check the .ARM.extab.TEST1 section
@-------------------------------------------------------------------------------
@ CHECK: Section {
-@ CHECK: Index: 6
-@ CHECK: Name: .ARM.extab.TEST1
+@ CHECK: Index: 7
+@ CHECK-NEXT: Name: .ARM.extab.TEST1
@ CHECK: Type: SHT_PROGBITS (0x1)
@-------------------------------------------------------------------------------
@ The flags should contain SHF_GROUP.
@ Check the .ARM.exidx.TEST1 section
@-------------------------------------------------------------------------------
@ CHECK: Section {
-@ CHECK: Index: 7
-@ CHECK: Name: .ARM.exidx.TEST1
+@ CHECK: Index: 8
+@ CHECK-NEXT: Name: .ARM.exidx.TEST1
@ CHECK: Type: SHT_ARM_EXIDX (0x70000001)
@-------------------------------------------------------------------------------
@ The flags should contain SHF_GROUP.
@ CHECK: SHF_GROUP (0x200)
@ CHECK: SHF_LINK_ORDER (0x80)
@ CHECK: ]
-@ CHECK: Link: 5
+@ CHECK: Link: 6
@ CHECK: }
@ CHECK: ]
@ CHECK: Name: func1
@ CHECK: Binding: Weak (0x2)
@ CHECK: Type: Function (0x2)
-@ CHECK: Section: .TEST1 (0x5)
+@ CHECK: Section: .TEST1
@ CHECK: }
@ CHECK: ]
@ Check the .TEST1 section. There should be two "bx lr" instructions.
@-------------------------------------------------------------------------------
@ CHECK: Section {
-@ CHECK: Name: .TEST1
+@ CHECK: Index: 5
+@ CHECK-NEXT: Name: .TEST1
@ CHECK: SectionData (
@ CHECK: 0000: 1EFF2FE1 1EFF2FE1 |../.../.|
@ CHECK: )
@-------------------------------------------------------------------------------
@ CHECK: Section {
@ CHECK: Name: .ARM.exidx.TEST1
-@ CHECK: Link: 4
+@ CHECK: Link: 5
@-------------------------------------------------------------------------------
@ The first word should be the offset to .TEST1.
@ The second word should be the offset to .ARM.extab.TEST1
@ CHECK: Binding: Global (0x1)
@ CHECK: Type: Function (0x2)
@ CHECK: Other: 0
-@ CHECK: Section: .TEST1 (0x4)
+@ CHECK: Section: .TEST1
@ CHECK: }
@ CHECK: Symbol {
@ CHECK: Name: func2
@ CHECK: Binding: Global (0x1)
@ CHECK: Type: Function (0x2)
@ CHECK: Other: 0
-@ CHECK: Section: .TEST1 (0x4)
+@ CHECK: Section: .TEST1
@ CHECK: }
@ CHECK: ]
@-------------------------------------------------------------------------------
@ CHECK: Sections [
@ CHECK: Section {
-@ CHECK: Index: 4
-@ CHECK: Name: .TEST1
+@ CHECK: Index: 5
+@ CHECK-NEXT: Name: .TEST1
@ CHECK: SectionData (
@ CHECK: 0000: 1EFF2FE1 |../.|
@ CHECK: )
@-------------------------------------------------------------------------------
@ This section should linked with .TEST1 section.
@-------------------------------------------------------------------------------
-@ CHECK: Link: 4
+@ CHECK: Link: 5
@-------------------------------------------------------------------------------
@ The first word should be relocated to the code address in .TEST1 section.
@ Check the TEST2 section (without the dot in the beginning)
@-------------------------------------------------------------------------------
@ CHECK: Section {
-@ CHECK: Index: 7
-@ CHECK: Name: TEST2
+@ CHECK: Index: 8
+@ CHECK-NEXT: Name: TEST2
@ CHECK: SectionData (
@ CHECK: 0000: 1EFF2FE1 |../.|
@ CHECK: )
@-------------------------------------------------------------------------------
@ This section should linked with TEST2 section.
@-------------------------------------------------------------------------------
-@ CHECK: Link: 7
+@ CHECK: Link: 8
@-------------------------------------------------------------------------------
@ The first word should be relocated to the code address in TEST2 section.
@ CHECK: Symbols [
@ CHECK: Symbol {
@ CHECK: Name: func1
-@ CHECK: Section: .TEST1 (0x4)
+@ CHECK: Section: .TEST1
@ CHECK: }
@ CHECK: Symbol {
@ CHECK: Name: func2
-@ CHECK: Section: TEST2 (0x7)
+@ CHECK: Section: TEST2
@ CHECK: }
@ CHECK: ]
@-------------------------------------------------------------------------------
@ Check the index of .text section. This will be used in .ARM.exidx.
@-------------------------------------------------------------------------------
-@ CHECK: Index: 1
-@ CHECK: Name: .text
+@ CHECK: Index: 2
+@ CHECK-NEXT: Name: .text
@ CHECK: Type: SHT_PROGBITS (0x1)
@ CHECK: Flags [ (0x6)
@ CHECK: SHF_ALLOC (0x2)
@ Check the linked section of the EXIDX section. This should be the index
@ of the .text section.
@-------------------------------------------------------------------------------
-@ CHECK: Link: 1
+@ CHECK: Link: 2
@-------------------------------------------------------------------------------
@ The first word should be the offset to .text. The second word should be
@ name first we could use a FileCheck variable.
@ CHECK: Section {
-@ CHECK: Index: 6
+@ CHECK: Index: 7
@ CHECK-NEXT: Name: .text
@ CHECK-NEXT: Type: SHT_PROGBITS
@ CHECK-NEXT: Flags [
@ CHECK-NEXT: EntrySize: 0
@ CHECK-NEXT: }
@ CHECK-NEXT: Section {
-@ CHECK-NEXT: Index: 7
+@ CHECK-NEXT: Index: 8
@ CHECK-NEXT: Name: .ARM.exidx
@ CHECK-NEXT: Type: SHT_ARM_EXIDX
@ CHECK-NEXT: Flags [
@ CHECK-NEXT: Address: 0x0
@ CHECK-NEXT: Offset: 0x58
@ CHECK-NEXT: Size: 8
-@ CHECK-NEXT: Link: 6
+@ CHECK-NEXT: Link: 7
@ CHECK-NEXT: Info: 0
@ CHECK-NEXT: AddressAlignment: 4
@ CHECK-NEXT: EntrySize: 0
@ CHECK-NEXT: }
@ CHECK: Section {
-@ CHECK: Index: 8
+@ CHECK: Index: 9
@ CHECK-NEXT: Name: .text
@ CHECK-NEXT: Type: SHT_PROGBITS
@ CHECK-NEXT: Flags [
@ CHECK-NEXT: EntrySize: 0
@ CHECK-NEXT: }
@ CHECK-NEXT: Section {
-@ CHECK-NEXT: Index: 9
+@ CHECK-NEXT: Index: 10
@ CHECK-NEXT: Name: .ARM.exidx
@ CHECK-NEXT: Type: SHT_ARM_EXIDX
@ CHECK-NEXT: Flags [
@ CHECK-NEXT: Address: 0x0
@ CHECK-NEXT: Offset:
@ CHECK-NEXT: Size: 8
-@ CHECK-NEXT: Link: 8
+@ CHECK-NEXT: Link: 9
@ CHECK-NEXT: Info: 0
@ CHECK-NEXT: AddressAlignment: 4
@ CHECK-NEXT: EntrySize: 0
// Test that we produce two foo sections, each in separate groups
-// CHECK: Index: 1
+// CHECK: Index: 2
// CHECK-NEXT: Name: .group
-// CHECK: Index: 2
+// CHECK: Index: 3
// CHECK-NEXT: Name: .group
-// CHECK: Index: 6
+// CHECK: Index: 7
// CHECK-NEXT: Name: .foo
-// CHECK: Index: 7
+// CHECK: Index: 8
// CHECK-NEXT: Name: .foo
// CHECK: Symbols [
// CHECK: Name: f1
// CHECK-NOT: }
-// CHECK: Section: .group (0x1)
+// CHECK: Section: .group (0x2)
// CHECK: Name: f2
// CHECK-NOT: }
-// CHECK: Section: .group (0x2)
+// CHECK: Section: .group (0x3)
// CHECK: Name: .foo
// CHECK-NOT: }
-// CHECK: Section: .foo (0x6)
+// CHECK: Section: .foo (0x7)
// CHECK: Name: .foo
// CHECK-NOT: }
-// CHECK: Section: .foo (0x7)
+// CHECK: Section: .foo (0x8)
.section .foo,"axG",@progbits,f1,comdat
// CHECK: Name: .group
// CHECK-NOT: SectionData
// CHECK: SectionData
-// CHECK-NEXT: 0000: 01000000 05000000 07000000
+// CHECK-NEXT: 0000: 01000000 06000000 08000000
-// CHECK: Index: 5
+// CHECK: Index: 6
// CHECK-NEXT: Name: .text.world
// CHECK-NOT: Section {
// CHECK: SHF_GROUP
-// CHECK: Index: 7
+// CHECK: Index: 8
// CHECK-NEXT: Name: .rela.text.world
// CHECK-NOT: Section {
// CHECK: SHF_GROUP
// of the file.
// CHECK: Section {
-// CHECK: Index: 1
+// CHECK: Index: 2
// CHECK-NEXT: Name: .group
// CHECK-NEXT: Type: SHT_GROUP
// CHECK-NEXT: Flags [
// CHECK-NEXT: Address: 0x0
// CHECK-NEXT: Offset: 0x40
// CHECK-NEXT: Size: 12
-// CHECK-NEXT: Link: 13
+// CHECK-NEXT: Link:
// CHECK-NEXT: Info: 1
// CHECK-NEXT: AddressAlignment: 4
// CHECK-NEXT: EntrySize: 4
// CHECK-NEXT: }
// CHECK-NEXT: Section {
-// CHECK-NEXT: Index: 2
+// CHECK-NEXT: Index: 3
// CHECK-NEXT: Name: .group
// CHECK-NEXT: Type: SHT_GROUP
// CHECK-NEXT: Flags [
// CHECK-NEXT: Address: 0x0
// CHECK-NEXT: Offset: 0x4C
// CHECK-NEXT: Size: 8
-// CHECK-NEXT: Link: 13
+// CHECK-NEXT: Link:
// CHECK-NEXT: Info: 2
// CHECK-NEXT: AddressAlignment: 4
// CHECK-NEXT: EntrySize: 4
// CHECK-NEXT: }
// CHECK-NEXT: Section {
-// CHECK-NEXT: Index: 3
+// CHECK-NEXT: Index: 4
// CHECK-NEXT: Name: .group
// CHECK-NEXT: Type: SHT_GROUP
// CHECK-NEXT: Flags [
// CHECK-NEXT: Address: 0x0
// CHECK-NEXT: Offset: 0x54
// CHECK-NEXT: Size: 12
-// CHECK-NEXT: Link: 13
+// CHECK-NEXT: Link:
// CHECK-NEXT: Info: 10
// CHECK-NEXT: AddressAlignment: 4
// CHECK-NEXT: EntrySize: 4
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
// CHECK-NEXT: Other: 0
-// CHECK-NEXT: Section: .foo (0x7)
+// CHECK-NEXT: Section: .foo
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: g2
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
// CHECK-NEXT: Other: 0
-// CHECK-NEXT: Section: .group (0x2)
+// CHECK-NEXT: Section: .group (0x3)
// CHECK-NEXT: }
// CHECK: Symbol {
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -s | FileCheck %s
// Test that like gnu as we create text, data and bss by default. Also test
-// that shstrtab, symtab and strtab are listed in that order.
+// that shstrtab, symtab and strtab are listed.
+// CHECK: Section {
+// CHECK: Name: .shstrtab
+// CHECK-NEXT: Type: SHT_STRTAB
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x0
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 44
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 1
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: }
// CHECK: Section {
// CHECK: Name: .text
// CHECK-NEXT: Type: SHT_PROGBITS
// CHECK-NEXT: EntrySize: 0
// CHECK-NEXT: }
// CHECK: Section {
-// CHECK: Name: .shstrtab
-// CHECK-NEXT: Type: SHT_STRTAB
-// CHECK-NEXT: Flags [
-// CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x0
-// CHECK-NEXT: Offset: 0x40
-// CHECK-NEXT: Size: 44
-// CHECK-NEXT: Link: 0
-// CHECK-NEXT: Info: 0
-// CHECK-NEXT: AddressAlignment: 1
-// CHECK-NEXT: EntrySize: 0
-// CHECK-NEXT: }
-// CHECK: Section {
// CHECK: Name: .symtab
// CHECK-NEXT: Type: SHT_SYMTAB
// CHECK-NEXT: Flags [
// CHECK-NEXT: Address: 0x0
// CHECK-NEXT: Offset:
// CHECK-NEXT: Size: 96
-// CHECK-NEXT: Link: 6
+// CHECK-NEXT: Link:
// CHECK-NEXT: Info: 4
// CHECK-NEXT: AddressAlignment: 8
// CHECK-NEXT: EntrySize: 24
// SYMBOLS-NEXT: Binding: Local (0x0)
// SYMBOLS-NEXT: Type: None (0x0)
// SYMBOLS-NEXT: Other: 0
-// SYMBOLS-NEXT: Section: last (0xFF00)
+// SYMBOLS-NEXT: Section: dm (0xFF00)
// SYMBOLS-NEXT: }
// SYMBOLS-NEXT: Symbol {
// SYMBOLS-NEXT: Name: b
// SYMBOLS-NEXT: Binding: Local (0x0)
// SYMBOLS-NEXT: Type: None (0x0)
// SYMBOLS-NEXT: Other: 0
-// SYMBOLS-NEXT: Section: last (0xFF00)
+// SYMBOLS-NEXT: Section: dm (0xFF00)
// SYMBOLS-NEXT: }
// Test that this file has one section too many.
-// SYMBOLS: Name: last
+// SYMBOLS: Name: dm
// SYMBOLS-NEXT: Value: 0x0
// SYMBOLS-NEXT: Size: 0
// SYMBOLS-NEXT: Binding: Local (0x0)
// SYMBOLS-NEXT: Type: Section (0x3)
// SYMBOLS-NEXT: Other: 0
-// SYMBOLS-NEXT: Section: last (0xFF00)
+// SYMBOLS-NEXT: Section: dm (0xFF00)
// SYMBOLS-NEXT: }
// SYMBOLS-NEXT:]
gen_sections8 l
gen_sections4 m
-.section last
a:
b = a + 1
// Check the last referenced section.
-// SYMBOLS: Name: dm (0)
+// SYMBOLS: Name: zed
// SYMBOLS-NEXT: Value: 0x0
// SYMBOLS-NEXT: Size: 0
// SYMBOLS-NEXT: Binding: Local (0x0)
// SYMBOLS-NEXT: Type: Section (0x3)
// SYMBOLS-NEXT: Other: 0
-// SYMBOLS-NEXT: Section: dm (0xFEFF)
+// SYMBOLS-NEXT: Section: zed (0xFEFF)
// SYMBOLS-NEXT: }
// SYMBOLS-NEXT:]
gen_sections32 j
gen_sections16 k
gen_sections8 l
-gen_sections4 m
+ .section foo
+ .section bar
+ .section zed
// Test that the relocation points to the first section foo.
-// The first seciton foo has index 6
+// The first seciton foo has index 7
// CHECK: Section {
-// CHECK: Index: 6
+// CHECK: Index: 7
// CHECK-NEXT: Name: foo (28)
// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
// CHECK-NEXT: Flags [ (0x202)
// CHECK-NEXT: EntrySize: 0
// CHECK-NEXT: }
// CHECK-NEXT: Section {
-// CHECK-NEXT: Index: 7
+// CHECK-NEXT: Index: 8
// CHECK-NEXT: Name: foo (28)
// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
// CHECK-NEXT: Flags [ (0x200)
// The relocation points to symbol 6
// CHECK: Relocations [
-// CHECK-NEXT: Section (9) .relabar {
+// CHECK-NEXT: Section ({{.*}}) .relabar {
// CHECK-NEXT: Relocation {
// CHECK-NEXT: Offset: 0x0
// CHECK-NEXT: Type: R_X86_64_32 (10)
// symbol 6
// CHECK-NOT: Name
// CHECK: Name: foo
-// CHECK: Section: foo (0x6)
+// CHECK: Section: foo (0x7)
// symbol 7
// CHECK-NOT: Name
// CHECK: Name: foo
-// CHECK: Section: foo (0x7)
+// CHECK: Section: foo (0x8)
// OBJ: Binding: Global
// OBJ: Type: None
// OBJ: Other: 0
-// OBJ: Section: .text (0x4)
+// OBJ: Section: .text (0x5)
// OBJ: }
// OBJ: Symbol {
// OBJ: Name: g
// OBJ: Binding: Global
// OBJ: Type: None
// OBJ: Other: 0
-// OBJ: Section: .text (0x5)
+// OBJ: Section: .text (0x6)
// OBJ: }