Create a dynamic segment.

It is still empty. I will add content next.

llvm-svn: 247097
This commit is contained in:
Rafael Espindola 2015-09-08 22:55:28 +00:00
parent ac5f048e09
commit e438e07856
2 changed files with 56 additions and 9 deletions

View File

@ -558,6 +558,17 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() {
FileSize = SizeOfHeaders + RoundUpToAlignment(FileOff - SizeOfHeaders, 8);
}
static uint32_t convertSectionFlagsToSegmentFlags(uint64_t Flags) {
uint32_t Ret = PF_R;
if (Flags & SHF_WRITE)
Ret |= PF_W;
if (Flags & SHF_EXECINSTR)
Ret |= PF_X;
return Ret;
}
template <class ELFT> void Writer<ELFT>::writeHeader() {
uint8_t *Buf = Buffer->getBufferStart();
auto *EHdr = reinterpret_cast<Elf_Ehdr *>(Buf);
@ -572,8 +583,17 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
EHdr->e_ident[EI_VERSION] = EV_CURRENT;
EHdr->e_ident[EI_OSABI] = ELFOSABI_NONE;
EHdr->e_type = ET_EXEC;
// FIXME: Generalize the segment construction similar to how we create
// output sections.
unsigned NumSegments = 1;
const SymbolTable &Symtab = SymTable.getSymTable();
const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles =
Symtab.getSharedFiles();
bool HasDynamicSegment = !SharedFiles.empty();
if (HasDynamicSegment)
NumSegments++;
EHdr->e_type = ET_EXEC;
auto &FirstObj = cast<ObjectFile<ELFT>>(*Symtab.getFirstELF());
EHdr->e_machine = FirstObj.getEMachine();
EHdr->e_version = EV_CURRENT;
@ -582,7 +602,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
EHdr->e_shoff = SectionHeaderOff;
EHdr->e_ehsize = sizeof(Elf_Ehdr);
EHdr->e_phentsize = sizeof(Elf_Phdr);
EHdr->e_phnum = 1;
EHdr->e_phnum = NumSegments;
EHdr->e_shentsize = sizeof(Elf_Shdr);
EHdr->e_shnum = getNumSections();
EHdr->e_shstrndx = StringTable.getSectionIndex();
@ -597,6 +617,18 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
PHdrs->p_memsz = FileSize;
PHdrs->p_align = 0x4000;
if (HasDynamicSegment) {
PHdrs++;
PHdrs->p_type = PT_DYNAMIC;
PHdrs->p_flags = convertSectionFlagsToSegmentFlags(DynamicSec.getFlags());
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_align = DynamicSec.getAlign();
}
auto SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff);
// First entry is null.
++SHdrs;

View File

@ -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 -t -s %t | FileCheck %s
// RUN: llvm-readobj --program-headers -t -s %t | FileCheck %s
// REQUIRES: x86
// CHECK: Name: .dynamic
@ -9,16 +9,16 @@
// CHECK-NEXT: SHF_ALLOC
// CHECK-NEXT: SHF_WRITE
// CHECK-NEXT: ]
// CHECK-NEXT: Address:
// CHECK-NEXT: Offset:
// CHECK-NEXT: Size:
// CHECK-NEXT: Link: 6
// CHECK-NEXT: Address: [[ADDR:.*]]
// CHECK-NEXT: Offset: [[OFFSET:.*]]
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Link: [[STRTAB:.*]]
// CHECK-NEXT: Info: 0
// CHECK-NEXT: AddressAlignment: 4
// CHECK-NEXT: AddressAlignment: [[ALIGN:.*]]
// CHECK-NEXT: EntrySize: 8
// CHECK-NEXT: }
// CHECK: Index: 6
// CHECK: Index: [[STRTAB]]
// CHECK-NEXT: Name: .strtab
// CHECK-NEXT: Type: SHT_STRTAB
// CHECK-NEXT: Flags [
@ -63,6 +63,21 @@
// CHECK-NEXT: }
// 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: Flags [
// CHECK-NEXT: PF_R
// CHECK-NEXT: PF_W
// CHECK-NEXT: ]
// CHECK-NEXT: Alignment: [[ALIGN]]
// CHECK-NEXT: }
.global _start
_start:
.long bar