[lld] r247155 - Start adding content to the dynamic section.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 9 08:33:08 PDT 2015
Author: rafael
Date: Wed Sep 9 10:33:08 2015
New Revision: 247155
URL: http://llvm.org/viewvc/llvm-project?rev=247155&view=rev
Log:
Start adding content to the dynamic section.
With this patch we create a dynamic string table (it is allocated, unlike
the regular one) and the dynamic section has a DT_STRTAB pointing to it.
Modified:
lld/trunk/ELF/Writer.cpp
lld/trunk/test/elf2/basic.s
lld/trunk/test/elf2/basic32.s
lld/trunk/test/elf2/basic32be.s
lld/trunk/test/elf2/basic64be.s
lld/trunk/test/elf2/shared.s
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=247155&r1=247154&r2=247155&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Sep 9 10:33:08 2015
@@ -37,6 +37,8 @@ namespace {
// non-overlapping file offsets and VAs.
template <bool Is64Bits> class OutputSectionBase {
public:
+ typedef
+ typename std::conditional<Is64Bits, Elf64_Dyn, Elf32_Dyn>::type Elf_Dyn;
typedef typename std::conditional<Is64Bits, uint64_t, uint32_t>::type uintX_t;
typedef
typename std::conditional<Is64Bits, Elf64_Shdr, Elf32_Shdr>::type HeaderT;
@@ -48,7 +50,7 @@ public:
Header.sh_flags = sh_flags;
}
void setVA(uintX_t VA) { Header.sh_addr = VA; }
- uintX_t getVA() { return Header.sh_addr; }
+ uintX_t getVA() const { return Header.sh_addr; }
void setFileOffset(uintX_t Off) { Header.sh_offset = Off; }
template <endianness E>
void writeHeaderTo(typename ELFFile<ELFType<E, Is64Bits>>::Elf_Shdr *SHdr);
@@ -105,7 +107,9 @@ public:
llvm::StringTableBuilder StrTabBuilder;
typedef typename OutputSectionBase<Is64Bits>::uintX_t uintX_t;
- StringTableSection() : OutputSectionBase<Is64Bits>(".strtab", SHT_STRTAB, 0) {
+ StringTableSection(bool Dynamic)
+ : OutputSectionBase<Is64Bits>(Dynamic ? ".dynstr" : ".strtab", SHT_STRTAB,
+ Dynamic ? SHF_ALLOC : 0) {
this->Header.sh_addralign = 1;
}
@@ -158,25 +162,44 @@ private:
template <bool Is64Bits>
class DynamicSection final : public OutputSectionBase<Is64Bits> {
+ typedef OutputSectionBase<Is64Bits> Base;
+ typedef typename Base::HeaderT HeaderT;
+ typedef typename Base::Elf_Dyn Elf_Dyn;
+
public:
- DynamicSection(const StringTableSection<Is64Bits> &StrTabSec)
+ DynamicSection(const StringTableSection<Is64Bits> &DynStrSec)
: OutputSectionBase<Is64Bits>(".dynamic", SHT_DYNAMIC,
SHF_ALLOC | SHF_WRITE),
- StrTabSec(StrTabSec) {
- typedef OutputSectionBase<Is64Bits> Base;
+ DynStrSec(DynStrSec) {
typename Base::HeaderT &Header = this->Header;
Header.sh_addralign = Is64Bits ? 8 : 4;
Header.sh_entsize = Is64Bits ? 16 : 8;
+
+ unsigned NumEntries = 0;
+
+ ++NumEntries; // DT_STRTAB
+ ++NumEntries; // DT_NULL
+
+ Header.sh_size = NumEntries * Header.sh_entsize;
}
void finalize() override {
- this->Header.sh_link = StrTabSec.getSectionIndex();
+ this->Header.sh_link = DynStrSec.getSectionIndex();
}
- void writeTo(uint8_t *Buf) override {}
+ void writeTo(uint8_t *Buf) override {
+ auto *P = reinterpret_cast<Elf_Dyn *>(Buf);
+
+ P->d_tag = DT_STRTAB;
+ P->d_un.d_ptr = DynStrSec.getVA();
+ ++P;
+
+ P->d_tag = DT_NULL;
+ P->d_un.d_val = 0;
+ }
private:
- const StringTableSection<Is64Bits> &StrTabSec;
+ const StringTableSection<Is64Bits> &DynStrSec;
};
// The writer writes a SymbolTable result to a file.
@@ -187,7 +210,9 @@ public:
typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
typedef typename ELFFile<ELFT>::Elf_Phdr Elf_Phdr;
typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
- Writer(SymbolTable *T) : SymTable(*T, StringTable), DynamicSec(StringTable) {}
+ Writer(SymbolTable *T)
+ : StrTabSec(false), DynStrSec(true), SymTable(*T, StrTabSec),
+ DynamicSec(DynStrSec) {}
void run();
private:
@@ -206,7 +231,8 @@ private:
uintX_t SizeOfHeaders;
uintX_t SectionHeaderOff;
- StringTableSection<ELFT::Is64Bits> StringTable;
+ StringTableSection<ELFT::Is64Bits> StrTabSec;
+ StringTableSection<ELFT::Is64Bits> DynStrSec;
SymbolTableSection<ELFT> SymTable;
@@ -488,7 +514,7 @@ template <class ELFT> void Writer<ELFT>:
OutputSection<ELFT> *BSSSec = SymTable.BSSSec;
// FIXME: Try to avoid the extra walk over all global symbols.
unsigned &NumVisible = SymTable.NumVisible;
- llvm::StringTableBuilder &Builder = StringTable.StrTabBuilder;
+ llvm::StringTableBuilder &Builder = StrTabSec.StrTabBuilder;
std::vector<DefinedCommon<ELFT> *> CommonSymbols;
for (auto &P : Symtab.getSymbols()) {
StringRef Name = P.first;
@@ -515,12 +541,14 @@ template <class ELFT> void Writer<ELFT>:
BSSSec->setSize(Off);
OutputSections.push_back(&SymTable);
- OutputSections.push_back(&StringTable);
+ OutputSections.push_back(&StrTabSec);
const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles =
Symtab.getSharedFiles();
- if (!SharedFiles.empty())
+ if (!SharedFiles.empty()) {
OutputSections.push_back(&DynamicSec);
+ OutputSections.push_back(&DynStrSec);
+ }
std::stable_sort(OutputSections.begin(), OutputSections.end(),
compSec<ELFT::Is64Bits>);
@@ -536,7 +564,7 @@ template <class ELFT> void Writer<ELFT>:
uintX_t FileOff = SizeOfHeaders;
for (OutputSectionBase<ELFT::Is64Bits> *Sec : OutputSections) {
- StringTable.add(Sec->getName());
+ StrTabSec.add(Sec->getName());
Sec->finalize();
uintX_t Align = Sec->getAlign();
@@ -605,13 +633,13 @@ template <class ELFT> void Writer<ELFT>:
EHdr->e_phnum = NumSegments;
EHdr->e_shentsize = sizeof(Elf_Shdr);
EHdr->e_shnum = getNumSections();
- EHdr->e_shstrndx = StringTable.getSectionIndex();
+ EHdr->e_shstrndx = StrTabSec.getSectionIndex();
auto PHdrs = reinterpret_cast<Elf_Phdr *>(Buf + EHdr->e_phoff);
PHdrs->p_type = PT_LOAD;
PHdrs->p_flags = PF_R | PF_X;
PHdrs->p_offset = 0x0000;
- PHdrs->p_vaddr = 0x400000;
+ PHdrs->p_vaddr = 0x1000;
PHdrs->p_paddr = PHdrs->p_vaddr;
PHdrs->p_filesz = FileSize;
PHdrs->p_memsz = FileSize;
@@ -624,8 +652,8 @@ template <class ELFT> void Writer<ELFT>:
PHdrs->p_offset = DynamicSec.getFileOff();
PHdrs->p_vaddr = DynamicSec.getVA();
PHdrs->p_paddr = PHdrs->p_vaddr;
- PHdrs->p_filesz = 0;
- PHdrs->p_memsz = 0;
+ PHdrs->p_filesz = DynamicSec.getSize();
+ PHdrs->p_memsz = DynamicSec.getSize();
PHdrs->p_align = DynamicSec.getAlign();
}
@@ -633,7 +661,7 @@ template <class ELFT> void Writer<ELFT>:
// First entry is null.
++SHdrs;
for (OutputSectionBase<ELFT::Is64Bits> *Sec : OutputSections) {
- Sec->setNameOffset(StringTable.getFileOff(Sec->getName()));
+ Sec->setNameOffset(StrTabSec.getFileOff(Sec->getName()));
Sec->template writeHeaderTo<ELFT::TargetEndianness>(SHdrs++);
}
}
Modified: lld/trunk/test/elf2/basic.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/basic.s?rev=247155&r1=247154&r2=247155&view=diff
==============================================================================
--- lld/trunk/test/elf2/basic.s (original)
+++ lld/trunk/test/elf2/basic.s Wed Sep 9 10:33:08 2015
@@ -152,8 +152,8 @@ _start:
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_LOAD (0x1)
# CHECK-NEXT: Offset: 0x0
-# CHECK-NEXT: VirtualAddress: 0x400000
-# CHECK-NEXT: PhysicalAddress: 0x400000
+# CHECK-NEXT: VirtualAddress: 0x1000
+# CHECK-NEXT: PhysicalAddress: 0x1000
# CHECK-NEXT: FileSize: 4592
# CHECK-NEXT: MemSize: 4592
# CHECK-NEXT: Flags [ (0x5)
Modified: lld/trunk/test/elf2/basic32.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/basic32.s?rev=247155&r1=247154&r2=247155&view=diff
==============================================================================
--- lld/trunk/test/elf2/basic32.s (original)
+++ lld/trunk/test/elf2/basic32.s Wed Sep 9 10:33:08 2015
@@ -131,8 +131,8 @@ _start:
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_LOAD (0x1)
# CHECK-NEXT: Offset: 0x0
-# CHECK-NEXT: VirtualAddress: 0x400000
-# CHECK-NEXT: PhysicalAddress: 0x400000
+# CHECK-NEXT: VirtualAddress: 0x1000
+# CHECK-NEXT: PhysicalAddress: 0x1000
# CHECK-NEXT: FileSize: 4424
# CHECK-NEXT: MemSize: 4424
# CHECK-NEXT: Flags [ (0x5)
Modified: lld/trunk/test/elf2/basic32be.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/basic32be.s?rev=247155&r1=247154&r2=247155&view=diff
==============================================================================
--- lld/trunk/test/elf2/basic32be.s (original)
+++ lld/trunk/test/elf2/basic32be.s Wed Sep 9 10:33:08 2015
@@ -131,8 +131,8 @@ _start:
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_LOAD (0x1)
# CHECK-NEXT: Offset: 0x0
-# CHECK-NEXT: VirtualAddress: 0x400000
-# CHECK-NEXT: PhysicalAddress: 0x400000
+# CHECK-NEXT: VirtualAddress: 0x1000
+# CHECK-NEXT: PhysicalAddress: 0x1000
# CHECK-NEXT: FileSize: 4424
# CHECK-NEXT: MemSize: 4424
# CHECK-NEXT: Flags [ (0x5)
Modified: lld/trunk/test/elf2/basic64be.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/basic64be.s?rev=247155&r1=247154&r2=247155&view=diff
==============================================================================
--- lld/trunk/test/elf2/basic64be.s (original)
+++ lld/trunk/test/elf2/basic64be.s Wed Sep 9 10:33:08 2015
@@ -152,8 +152,8 @@ _start:
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_LOAD (0x1)
# CHECK-NEXT: Offset: 0x0
-# CHECK-NEXT: VirtualAddress: 0x400000
-# CHECK-NEXT: PhysicalAddress: 0x400000
+# CHECK-NEXT: VirtualAddress: 0x1000
+# CHECK-NEXT: PhysicalAddress: 0x1000
# CHECK-NEXT: FileSize: 4680
# CHECK-NEXT: MemSize: 4680
# CHECK-NEXT: Flags [ (0x5)
Modified: lld/trunk/test/elf2/shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/shared.s?rev=247155&r1=247154&r2=247155&view=diff
==============================================================================
--- lld/trunk/test/elf2/shared.s (original)
+++ lld/trunk/test/elf2/shared.s Wed Sep 9 10:33:08 2015
@@ -1,6 +1,6 @@
// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
// RUN: lld -flavor gnu2 %t.o %p/Inputs/i686-simple-library.so -o %t
-// RUN: llvm-readobj --program-headers -t -s %t | FileCheck %s
+// RUN: llvm-readobj --program-headers --dynamic-table -t -s %t | FileCheck %s
// REQUIRES: x86
// CHECK: Name: .dynamic
@@ -11,19 +11,20 @@
// CHECK-NEXT: ]
// CHECK-NEXT: Address: [[ADDR:.*]]
// CHECK-NEXT: Offset: [[OFFSET:.*]]
-// CHECK-NEXT: Size: 0
-// CHECK-NEXT: Link: [[STRTAB:.*]]
+// CHECK-NEXT: Size: [[SIZE:.*]]
+// CHECK-NEXT: Link: [[DYNSTR:.*]]
// CHECK-NEXT: Info: 0
// CHECK-NEXT: AddressAlignment: [[ALIGN:.*]]
// CHECK-NEXT: EntrySize: 8
// CHECK-NEXT: }
-// CHECK: Index: [[STRTAB]]
-// CHECK-NEXT: Name: .strtab
+// CHECK: Index: [[DYNSTR]]
+// CHECK-NEXT: Name: .dynstr
// CHECK-NEXT: Type: SHT_STRTAB
// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
// CHECK-NEXT: ]
-// CHECK-NEXT: Address:
+// CHECK-NEXT: Address: [[DYNSTRADDR:.*]]
// CHECK-NEXT: Offset:
// CHECK-NEXT: Size:
// CHECK-NEXT: Link: 0
@@ -63,14 +64,19 @@
// CHECK-NEXT: }
// CHECK-NEXT: ]
+// CHECK: DynamicSection [
+// CHECK-NEXT: Tag Type Name/Value
+// CHECK-NEXT: 0x00000005 STRTAB [[DYNSTRADDR]]
+// CHECK-NEXT: 0x00000000 NULL 0x0
+// CHECK-NEXT: ]
// CHECK: ProgramHeader {
// CHECK: Type: PT_DYNAMIC
// CHECK-NEXT: Offset: [[OFFSET]]
// CHECK-NEXT: VirtualAddress: [[ADDR]]
// CHECK-NEXT: PhysicalAddress: [[ADDR]]
-// CHECK-NEXT: FileSize: 0
-// CHECK-NEXT: MemSize: 0
+// CHECK-NEXT: FileSize: [[SIZE]]
+// CHECK-NEXT: MemSize: [[SIZE]]
// CHECK-NEXT: Flags [
// CHECK-NEXT: PF_R
// CHECK-NEXT: PF_W
More information about the llvm-commits
mailing list