Index: test/tools/llvm-objcopy/marker-segment.test =================================================================== --- test/tools/llvm-objcopy/marker-segment.test +++ test/tools/llvm-objcopy/marker-segment.test @@ -0,0 +1,109 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-objcopy %t %t2 +# RUN: llvm-readobj -program-headers %t2 | FileCheck %s + +!ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_ARM +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x0000000000001000 + Content: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2000 + AddressAlign: 0x0000000000001000 + Content: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + - Name: .xdata + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + - Name: .after + Type: SHT_NOBITS + Flags: [ SHF_ALLOC ] + Size: 64 +ProgramHeaders: + - Type: PT_LOAD + Flags: [ PF_X, PF_R ] + VAddr: 0x1000 + PAddr: 0x1000 + Align: 0x1000 + Sections: + - Section: .text + - Type: PT_LOAD + Flags: [ PF_R, PF_W ] + VAddr: 0x2000 + PAddr: 0x2000 + Align: 0x1000 + Sections: + - Section: .data + - Type: 0x6474e551 # GNU_STACK + Flags: [ PF_R, PF_W ] + VAddr: 0x0000 + PAddr: 0x0000 + Align: 0x0000 + - Type: PT_LOAD + Flags: [ PF_R ] + Sections: + - Section: .xdata + - Section: .after + +#CHECK: ProgramHeaders [ +#CHECK-NEXT: ProgramHeader { +#CHECK-NEXT: Type: PT_LOAD +#CHECK-NEXT: Offset: 0x1000 +#CHECK-NEXT: VirtualAddress: 0x1000 +#CHECK-NEXT: PhysicalAddress: 0x1000 +#CHECK-NEXT: FileSize: 16 +#CHECK-NEXT: MemSize: 16 +#CHECK-NEXT: Flags [ +#CHECK-NEXT: PF_R +#CHECK-NEXT: PF_X +#CHECK-NEXT: ] +#CHECK-NEXT: Alignment: 4096 +#CHECK-NEXT: } +#CHECK-NEXT: ProgramHeader { +#CHECK-NEXT: Type: PT_LOAD +#CHECK-NEXT: Offset: 0x2000 +#CHECK-NEXT: VirtualAddress: 0x2000 +#CHECK-NEXT: PhysicalAddress: 0x2000 +#CHECK-NEXT: FileSize: 16 +#CHECK-NEXT: MemSize: 16 +#CHECK-NEXT: Flags [ +#CHECK-NEXT: PF_R +#CHECK-NEXT: PF_W +#CHECK-NEXT: ] +#CHECK-NEXT: Alignment: 4096 +#CHECK-NEXT: } +#CHECK-NEXT: ProgramHeader { +#CHECK-NEXT: Type: PT_GNU_STACK +#CHECK-NEXT: Offset: 0x0 +#CHECK-NEXT: VirtualAddress: 0x0 +#CHECK-NEXT: PhysicalAddress: 0x0 +#CHECK-NEXT: FileSize: 0 +#CHECK-NEXT: MemSize: 0 +#CHECK-NEXT: Flags [ +#CHECK-NEXT: PF_R +#CHECK-NEXT: PF_W +#CHECK-NEXT: ] +#CHECK-NEXT: Alignment: 0 +#CHECK-NEXT: } +#CHECK-NEXT: ProgramHeader { +#CHECK-NEXT: Type: PT_LOAD +#CHECK-NEXT: Offset: 0x2010 +#CHECK-NEXT: VirtualAddress: 0x0 +#CHECK-NEXT: PhysicalAddress: 0x0 +#CHECK-NEXT: FileSize: 0 +#CHECK-NEXT: MemSize: 64 +#CHECK-NEXT: Flags [ +#CHECK-NEXT: PF_R +#CHECK-NEXT: ] +#CHECK-NEXT: Alignment: 1 +#CHECK-NEXT: } +#CHECK-NEXT:] Index: tools/llvm-objcopy/Object.h =================================================================== --- tools/llvm-objcopy/Object.h +++ tools/llvm-objcopy/Object.h @@ -238,6 +238,7 @@ Segment *ParentSegment = nullptr; Segment(ArrayRef Data) : Contents(Data) {} + Segment() {} const SectionBase *firstSection() const { if (!Sections.empty()) @@ -512,6 +513,7 @@ template class ELFBuilder { private: using Elf_Shdr = typename ELFT::Shdr; + using Elf_Ehdr = typename ELFT::Ehdr; const ELFFile &ElfFile; Object &Obj; @@ -557,6 +559,9 @@ using ConstRange = iterator_range>::const_iterator>>; + Segment ElfHdrSegment; + Segment ProgramHdrSegment; + uint8_t Ident[16]; uint64_t Entry; uint64_t SHOffset; Index: tools/llvm-objcopy/Object.cpp =================================================================== --- tools/llvm-objcopy/Object.cpp +++ tools/llvm-objcopy/Object.cpp @@ -482,6 +482,27 @@ } } } + + auto &ElfHdr = Obj.ElfHdrSegment; + ElfHdr.Type = PT_PHDR; + ElfHdr.Flags = 0; + ElfHdr.OriginalOffset = ElfHdr.Offset = 0; + ElfHdr.VAddr = 0; + ElfHdr.PAddr = 0; + ElfHdr.FileSize = ElfHdr.MemSize = sizeof(Elf_Ehdr); + ElfHdr.Align = 0; + ElfHdr.Index = Index++; + + const auto &Ehdr = *ElfFile.getHeader(); + auto &PrHdr = Obj.ProgramHdrSegment; + PrHdr.Type = PT_PHDR; + PrHdr.Flags = 0; + PrHdr.OriginalOffset = PrHdr.Offset = PrHdr.VAddr = Ehdr.e_phoff; + PrHdr.PAddr = 0; + PrHdr.FileSize = PrHdr.MemSize = Ehdr.e_phentsize * Ehdr.e_phnum; + PrHdr.Align = 0; + PrHdr.Index = Index++; + // Now we do an O(n^2) loop through the segments in order to match up // segments. for (auto &Child : Obj.segments()) { @@ -913,6 +934,8 @@ std::vector OrderedSegments; for (auto &Segment : Obj.segments()) OrderedSegments.push_back(&Segment); + OrderedSegments.push_back(&Obj.ElfHdrSegment); + OrderedSegments.push_back(&Obj.ProgramHdrSegment); OrderSegments(OrderedSegments); // The size of ELF + program headers will not change so it is ok to assume // that the first offset of the first segment is a good place to start