Index: llvm/test/tools/llvm-objcopy/binary-input-arch.test =================================================================== --- llvm/test/tools/llvm-objcopy/binary-input-arch.test +++ llvm/test/tools/llvm-objcopy/binary-input-arch.test @@ -65,8 +65,8 @@ # CHECK-NEXT: ] # 32-NEXT: HeaderSize: 52 # 64-NEXT: HeaderSize: 64 -# 32-NEXT: ProgramHeaderEntrySize: 32 -# 64-NEXT: ProgramHeaderEntrySize: 56 +# 32-NEXT: ProgramHeaderEntrySize: 0 +# 64-NEXT: ProgramHeaderEntrySize: 0 # CHECK-NEXT: ProgramHeaderCount: 0 # 32-NEXT: SectionHeaderEntrySize: 40 # 64-NEXT: SectionHeaderEntrySize: 64 Index: llvm/test/tools/llvm-objcopy/many-sections.test =================================================================== --- llvm/test/tools/llvm-objcopy/many-sections.test +++ llvm/test/tools/llvm-objcopy/many-sections.test @@ -22,12 +22,12 @@ EHDR-NEXT: Machine: EM_X86_64 (0x3E) EHDR-NEXT: Version: 1 EHDR-NEXT: Entry: 0x0 -EHDR-NEXT: ProgramHeaderOffset: 0x40 +EHDR-NEXT: ProgramHeaderOffset: 0x0 EHDR-NEXT: SectionHeaderOffset: EHDR-NEXT: Flags [ (0x0) EHDR-NEXT: ] EHDR-NEXT: HeaderSize: 64 -EHDR-NEXT: ProgramHeaderEntrySize: 56 +EHDR-NEXT: ProgramHeaderEntrySize: 0 EHDR-NEXT: ProgramHeaderCount: 0 EHDR-NEXT: SectionHeaderEntrySize: 64 EHDR-NEXT: SectionHeaderCount: 0 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-readobj -file-headers %t2 | FileCheck %s + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 + +# CHECK: ProgramHeaderOffset: 0x0 +# CHECK: ProgramHeaderEntrySize: 0 +# CHECK-NEXT: ProgramHeaderCount: 0 Index: llvm/test/tools/llvm-objcopy/strip-sections.test =================================================================== --- llvm/test/tools/llvm-objcopy/strip-sections.test +++ llvm/test/tools/llvm-objcopy/strip-sections.test @@ -44,7 +44,7 @@ #CHECK-NEXT: HeaderSize: 64 #CHECK-NEXT: ProgramHeaderEntrySize: 56 #CHECK-NEXT: ProgramHeaderCount: 1 -#CHECK-NEXT: SectionHeaderEntrySize: 64 +#CHECK-NEXT: SectionHeaderEntrySize: 0 #CHECK-NEXT: SectionHeaderCount: 0 #CHECK-NEXT: StringTableSectionIndex: 0 #CHECK-NEXT: } Index: llvm/tools/llvm-objcopy/Object.cpp =================================================================== --- llvm/tools/llvm-objcopy/Object.cpp +++ llvm/tools/llvm-objcopy/Object.cpp @@ -1049,15 +1049,13 @@ 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 = (Ehdr.e_phnum != 0) ? Obj.ProgramHdrSegment.Offset : 0; + Ehdr.e_phentsize = (Ehdr.e_phnum != 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) { + if (WriteSectionHeaders && size(Obj.sections()) != 0) { + Ehdr.e_shentsize = sizeof(Elf_Shdr); Ehdr.e_shoff = Obj.SHOffset; // """ // If the number of sections is greater than or equal to @@ -1081,6 +1079,7 @@ else Ehdr.e_shstrndx = Obj.SectionNames->Index; } else { + Ehdr.e_shentsize = 0; Ehdr.e_shoff = 0; Ehdr.e_shnum = 0; Ehdr.e_shstrndx = 0;