From bf3fd7c9a0f359758fc929cfb33708693c4f2aeb Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 9 Oct 2015 15:31:49 +0000 Subject: [PATCH] ELF2: Emit a PT_PHDR header as the first entry of the program header. PT_PHDR entry points to the program header itself. llvm-svn: 249839 --- lld/ELF/Writer.cpp | 12 ++++++++++++ lld/test/elf2/basic-aarch64.s | 18 +++++++++++++++--- lld/test/elf2/basic-mips.s | 14 +++++++++++++- lld/test/elf2/basic.s | 18 +++++++++++++++--- lld/test/elf2/basic32.s | 18 +++++++++++++++--- lld/test/elf2/basic32be.s | 18 +++++++++++++++--- lld/test/elf2/basic64be.s | 18 +++++++++++++++--- lld/test/elf2/emulation.s | 8 ++++---- lld/test/elf2/program-header-layout.s | 12 ++++++++++++ lld/test/elf2/shared.s | 5 ++--- 10 files changed, 118 insertions(+), 23 deletions(-) diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 0688a5bf28b5..832357462cb4 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -103,6 +103,7 @@ private: llvm::BumpPtrAllocator PAlloc; SymbolTable &Symtab; std::vector *> PHDRs; + ProgramHeader PhdrPHDR{PT_PHDR, PF_R, 0, 0}; ProgramHeader FileHeaderPHDR{PT_LOAD, PF_R, 0, 0}; ProgramHeader InterpPHDR{PT_INTERP, 0, 0, 0}; ProgramHeader DynamicPHDR{PT_DYNAMIC, 0, 0, 0}; @@ -501,6 +502,13 @@ template void Writer::assignAddresses() { FileOff += sizeof(Elf_Ehdr); VA += sizeof(Elf_Ehdr); + // The first PHDR entry is PT_PHDR which describes the program header itself. + PHDRs.push_back(&PhdrPHDR); + PhdrPHDR.Header.p_align = 8; + PhdrPHDR.Header.p_offset = FileOff; + PhdrPHDR.Header.p_vaddr = VA; + PhdrPHDR.Header.p_paddr = VA; + // Reserve space for PHDRs. ProgramHeaderOff = FileOff; FileOff = RoundUpToAlignment(FileOff, Target->getPageSize()); @@ -558,6 +566,10 @@ template void Writer::assignAddresses() { FileOff += OffsetToAlignment(FileOff, ELFT::Is64Bits ? 8 : 4); + // Fix up the first entry's size. + PhdrPHDR.Header.p_filesz = sizeof(Elf_Phdr) * PHDRs.size(); + PhdrPHDR.Header.p_memsz = sizeof(Elf_Phdr) * PHDRs.size(); + // Add space for section headers. SectionHeaderOff = FileOff; FileOff += getNumSections() * sizeof(Elf_Shdr); diff --git a/lld/test/elf2/basic-aarch64.s b/lld/test/elf2/basic-aarch64.s index f82af4bcb88d..a401da80d6a4 100644 --- a/lld/test/elf2/basic-aarch64.s +++ b/lld/test/elf2/basic-aarch64.s @@ -31,7 +31,7 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 64 # CHECK-NEXT: ProgramHeaderEntrySize: 56 -# CHECK-NEXT: ProgramHeaderCount: 2 +# CHECK-NEXT: ProgramHeaderCount: 3 # CHECK-NEXT: SectionHeaderEntrySize: 64 # CHECK-NEXT: SectionHeaderCount: 6 # CHECK-NEXT: StringTableSectionIndex: 5 @@ -159,12 +159,24 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: ProgramHeaders [ # CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_PHDR (0x6) +# CHECK-NEXT: Offset: 0x40 +# CHECK-NEXT: VirtualAddress: 0x400040 +# CHECK-NEXT: PhysicalAddress: 0x400040 +# CHECK-NEXT: FileSize: 168 +# CHECK-NEXT: MemSize: 168 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD (0x1) # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x400000 # CHECK-NEXT: PhysicalAddress: 0x400000 -# CHECK-NEXT: FileSize: 176 -# CHECK-NEXT: MemSize: 176 +# CHECK-NEXT: FileSize: 232 +# CHECK-NEXT: MemSize: 232 # CHECK-NEXT: Flags [ # CHECK-NEXT: PF_R # CHECK-NEXT: ] diff --git a/lld/test/elf2/basic-mips.s b/lld/test/elf2/basic-mips.s index 33a2bddc176a..5e2a157a1605 100644 --- a/lld/test/elf2/basic-mips.s +++ b/lld/test/elf2/basic-mips.s @@ -32,7 +32,7 @@ __start: # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 52 # CHECK-NEXT: ProgramHeaderEntrySize: 32 -# CHECK-NEXT: ProgramHeaderCount: 2 +# CHECK-NEXT: ProgramHeaderCount: 3 # CHECK-NEXT: SectionHeaderEntrySize: 40 # CHECK-NEXT: SectionHeaderCount: 8 # CHECK-NEXT: StringTableSectionIndex: 7 @@ -181,6 +181,18 @@ __start: # CHECK-NEXT: ] # CHECK-NEXT: ProgramHeaders [ # CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_PHDR (0x6) +# CHECK-NEXT: Offset: 0x34 +# CHECK-NEXT: VirtualAddress: 0x400034 +# CHECK-NEXT: PhysicalAddress: 0x400034 +# CHECK-NEXT: FileSize: 96 +# CHECK-NEXT: MemSize: 96 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD (0x1) # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x400000 diff --git a/lld/test/elf2/basic.s b/lld/test/elf2/basic.s index 4dc64b2cdeb1..e1bc067b5248 100644 --- a/lld/test/elf2/basic.s +++ b/lld/test/elf2/basic.s @@ -32,7 +32,7 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 64 # CHECK-NEXT: ProgramHeaderEntrySize: 56 -# CHECK-NEXT: ProgramHeaderCount: 2 +# CHECK-NEXT: ProgramHeaderCount: 3 # CHECK-NEXT: SectionHeaderEntrySize: 64 # CHECK-NEXT: SectionHeaderCount: 6 # CHECK-NEXT: StringTableSectionIndex: 5 @@ -151,12 +151,24 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: ProgramHeaders [ # CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_PHDR (0x6) +# CHECK-NEXT: Offset: 0x40 +# CHECK-NEXT: VirtualAddress: 0x10040 +# CHECK-NEXT: PhysicalAddress: 0x10040 +# CHECK-NEXT: FileSize: 168 +# CHECK-NEXT: MemSize: 168 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD (0x1) # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x10000 # CHECK-NEXT: PhysicalAddress: 0x10000 -# CHECK-NEXT: FileSize: 176 -# CHECK-NEXT: MemSize: 176 +# CHECK-NEXT: FileSize: 232 +# CHECK-NEXT: MemSize: 232 # CHECK-NEXT: Flags [ # CHECK-NEXT: PF_R # CHECK-NEXT: ] diff --git a/lld/test/elf2/basic32.s b/lld/test/elf2/basic32.s index 94ee394f21b0..28501e79f738 100644 --- a/lld/test/elf2/basic32.s +++ b/lld/test/elf2/basic32.s @@ -30,7 +30,7 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 52 # CHECK-NEXT: ProgramHeaderEntrySize: 32 -# CHECK-NEXT: ProgramHeaderCount: 2 +# CHECK-NEXT: ProgramHeaderCount: 3 # CHECK-NEXT: SectionHeaderEntrySize: 40 # CHECK-NEXT: SectionHeaderCount: 6 # CHECK-NEXT: StringTableSectionIndex: 5 @@ -129,12 +129,24 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: ProgramHeaders [ # CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_PHDR (0x6) +# CHECK-NEXT: Offset: 0x34 +# CHECK-NEXT: VirtualAddress: 0x10034 +# CHECK-NEXT: PhysicalAddress: 0x10034 +# CHECK-NEXT: FileSize: 96 +# CHECK-NEXT: MemSize: 96 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD (0x1) # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x10000 # CHECK-NEXT: PhysicalAddress: 0x10000 -# CHECK-NEXT: FileSize: 116 -# CHECK-NEXT: MemSize: 116 +# CHECK-NEXT: FileSize: 148 +# CHECK-NEXT: MemSize: 148 # CHECK-NEXT: Flags [ # CHECK-NEXT: PF_R # CHECK-NEXT: ] diff --git a/lld/test/elf2/basic32be.s b/lld/test/elf2/basic32be.s index cc433d74f82e..b0fd12b23927 100644 --- a/lld/test/elf2/basic32be.s +++ b/lld/test/elf2/basic32be.s @@ -30,7 +30,7 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 52 # CHECK-NEXT: ProgramHeaderEntrySize: 32 -# CHECK-NEXT: ProgramHeaderCount: 2 +# CHECK-NEXT: ProgramHeaderCount: 3 # CHECK-NEXT: SectionHeaderEntrySize: 40 # CHECK-NEXT: SectionHeaderCount: 6 # CHECK-NEXT: StringTableSectionIndex: 5 @@ -129,12 +129,24 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: ProgramHeaders [ # CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_PHDR (0x6) +# CHECK-NEXT: Offset: 0x34 +# CHECK-NEXT: VirtualAddress: 0x10000034 +# CHECK-NEXT: PhysicalAddress: 0x10000034 +# CHECK-NEXT: FileSize: 96 +# CHECK-NEXT: MemSize: 96 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD (0x1) # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x10000000 # CHECK-NEXT: PhysicalAddress: 0x10000000 -# CHECK-NEXT: FileSize: 116 -# CHECK-NEXT: MemSize: 116 +# CHECK-NEXT: FileSize: 148 +# CHECK-NEXT: MemSize: 148 # CHECK-NEXT: Flags [ # CHECK-NEXT: PF_R # CHECK-NEXT: ] diff --git a/lld/test/elf2/basic64be.s b/lld/test/elf2/basic64be.s index 9c41baf993e4..392ed5dd1aa3 100644 --- a/lld/test/elf2/basic64be.s +++ b/lld/test/elf2/basic64be.s @@ -35,7 +35,7 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 64 # CHECK-NEXT: ProgramHeaderEntrySize: 56 -# CHECK-NEXT: ProgramHeaderCount: 3 +# CHECK-NEXT: ProgramHeaderCount: 4 # CHECK-NEXT: SectionHeaderEntrySize: 64 # CHECK-NEXT: SectionHeaderCount: 7 # CHECK-NEXT: StringTableSectionIndex: 6 @@ -163,13 +163,25 @@ _start: # CHECK-NEXT: } # CHECK-NEXT: ] # CHECK-NEXT: ProgramHeaders [ +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_PHDR (0x6) +# CHECK-NEXT: Offset: 0x40 +# CHECK-NEXT: VirtualAddress: 0x10000040 +# CHECK-NEXT: PhysicalAddress: 0x10000040 +# CHECK-NEXT: FileSize: 224 +# CHECK-NEXT: MemSize: 224 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } # CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD (0x1) # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x10000000 # CHECK-NEXT: PhysicalAddress: 0x10000000 -# CHECK-NEXT: FileSize: 232 -# CHECK-NEXT: MemSize: 232 +# CHECK-NEXT: FileSize: 288 +# CHECK-NEXT: MemSize: 288 # CHECK-NEXT: Flags [ # CHECK-NEXT: PF_R # CHECK-NEXT: ] diff --git a/lld/test/elf2/emulation.s b/lld/test/elf2/emulation.s index 38e9d5e06a0c..ea61cf920e69 100644 --- a/lld/test/elf2/emulation.s +++ b/lld/test/elf2/emulation.s @@ -23,7 +23,7 @@ # X86-64-NEXT: ] # X86-64-NEXT: HeaderSize: 64 # X86-64-NEXT: ProgramHeaderEntrySize: 56 -# X86-64-NEXT: ProgramHeaderCount: 1 +# X86-64-NEXT: ProgramHeaderCount: 2 # X86-64-NEXT: SectionHeaderEntrySize: 64 # X86-64-NEXT: SectionHeaderCount: 6 # X86-64-NEXT: StringTableSectionIndex: 5 @@ -54,7 +54,7 @@ # X86-NEXT: ] # X86-NEXT: HeaderSize: 52 # X86-NEXT: ProgramHeaderEntrySize: 32 -# X86-NEXT: ProgramHeaderCount: 1 +# X86-NEXT: ProgramHeaderCount: 2 # X86-NEXT: SectionHeaderEntrySize: 40 # X86-NEXT: SectionHeaderCount: 6 # X86-NEXT: StringTableSectionIndex: 5 @@ -85,7 +85,7 @@ # PPC64-NEXT: ] # PPC64-NEXT: HeaderSize: 64 # PPC64-NEXT: ProgramHeaderEntrySize: 56 -# PPC64-NEXT: ProgramHeaderCount: 1 +# PPC64-NEXT: ProgramHeaderCount: 2 # PPC64-NEXT: SectionHeaderEntrySize: 64 # PPC64-NEXT: SectionHeaderCount: 6 # PPC64-NEXT: StringTableSectionIndex: 5 @@ -116,7 +116,7 @@ # PPC-NEXT: ] # PPC-NEXT: HeaderSize: 52 # PPC-NEXT: ProgramHeaderEntrySize: 32 -# PPC-NEXT: ProgramHeaderCount: 1 +# PPC-NEXT: ProgramHeaderCount: 2 # PPC-NEXT: SectionHeaderEntrySize: 40 # PPC-NEXT: SectionHeaderCount: 6 # PPC-NEXT: StringTableSectionIndex: 5 diff --git a/lld/test/elf2/program-header-layout.s b/lld/test/elf2/program-header-layout.s index 42472c292689..3ae68951700d 100644 --- a/lld/test/elf2/program-header-layout.s +++ b/lld/test/elf2/program-header-layout.s @@ -33,6 +33,18 @@ _start: # CHECK: ProgramHeaders [ # CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_PHDR (0x6) +# CHECK-NEXT: Offset: 0x40 +# CHECK-NEXT: VirtualAddress: 0x10040 +# CHECK-NEXT: PhysicalAddress: 0x10040 +# CHECK-NEXT: FileSize: 168 +# CHECK-NEXT: MemSize: 168 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: diff --git a/lld/test/elf2/shared.s b/lld/test/elf2/shared.s index 4dac06de1237..57cc0d4a4811 100644 --- a/lld/test/elf2/shared.s +++ b/lld/test/elf2/shared.s @@ -256,9 +256,8 @@ // CHECK-NEXT: 0x00000000 NULL 0x0 // CHECK-NEXT: ] -// CHECK: ProgramHeaders [ -// CHECK-NEXT: ProgramHeader { -// CHECK-NEXT: Type: PT_INTERP +// CHECK: ProgramHeaders [ +// CHECK: Type: PT_INTERP // CHECK-NEXT: Offset: [[INTERPOFFSET]] // CHECK-NEXT: VirtualAddress: [[INTERPADDR]] // CHECK-NEXT: PhysicalAddress: [[INTERPADDR]]