Index: llvm/test/tools/llvm-objcopy/relocatable-phdr.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-objcopy/relocatable-phdr.test @@ -0,0 +1,16 @@ +# This test ensures an object without a program header will retain zero values +# for offset and header size when copied with llvm-objcopy. +# RUN: yaml2obj %s > %t +# RUN: llvm-objcopy %t %t2 +# RUN: llvm-readelf -file-headers %t2 | FileCheck %s + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 + +# CHECK: Start of program headers: 0 (bytes into file) +# CHECK: Size of program headers: 0 (bytes) +# CHECK-NEXT:Number of program headers: 0 Index: llvm/tools/llvm-objcopy/Object.cpp =================================================================== --- llvm/tools/llvm-objcopy/Object.cpp +++ llvm/tools/llvm-objcopy/Object.cpp @@ -1049,13 +1049,11 @@ Ehdr.e_machine = Obj.Machine; Ehdr.e_version = Obj.Version; Ehdr.e_entry = Obj.Entry; - // TODO: Only set phoff when a program header exists, to avoid tools - // thinking this is corrupt data. - Ehdr.e_phoff = Obj.ProgramHdrSegment.Offset; + Ehdr.e_phnum = size(Obj.segments()); + Ehdr.e_phoff = (size(Obj.segments()) != 0) ? Obj.ProgramHdrSegment.Offset : 0; + Ehdr.e_phentsize = (size(Obj.segments()) != 0) ? sizeof(Elf_Phdr) : 0; Ehdr.e_flags = Obj.Flags; Ehdr.e_ehsize = sizeof(Elf_Ehdr); - Ehdr.e_phentsize = sizeof(Elf_Phdr); - Ehdr.e_phnum = size(Obj.segments()); Ehdr.e_shentsize = sizeof(Elf_Shdr); if (WriteSectionHeaders) { Ehdr.e_shoff = Obj.SHOffset;