Index: llvm/test/tools/llvm-objcopy/ELF/binary-paddr.test =================================================================== --- llvm/test/tools/llvm-objcopy/ELF/binary-paddr.test +++ llvm/test/tools/llvm-objcopy/ELF/binary-paddr.test @@ -129,3 +129,47 @@ VAddr: 0x3000 Sections: - Section: .data + +## Check that the LMA is correctly calculated for sections not contained in a +## PT_LOAD segment. + +# RUN: yaml2obj --docnum=4 %s -o %t4 +# RUN: llvm-objcopy -O binary %t4 %t4.out +# RUN: od -A x -t x2 %t4.out | FileCheck %s --check-prefix=CHECK4 --ignore-case +# RUN: wc -c %t4.out | FileCheck %s --check-prefix=SIZE4 + +# CHECK4: 9090 9090 9090 90c3 +# SIZE4: 8 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x8000 + AddressAlign: 0x8 + Content: 90909090909090C3 + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_ALLOC, SHF_WRITE ] + Address: 0x8008 + AddressAlign: 0x1 + Size: 0x4 +ProgramHeaders: + - Type: PT_LOAD + Flags: [ PF_R, PF_X ] + VAddr: 0x8000 + Sections: + - Section: .text + - Type: PT_GNU_STACK + Flags: [ PF_R, PF_W ] + VAddr: 0x0000 + FileSize: 0x0000 + Align: 0x0000 + # The huge size makes this phdr a parent of .bss + MemSize: 0x1000000 Index: llvm/tools/llvm-objcopy/ELF/Object.cpp =================================================================== --- llvm/tools/llvm-objcopy/ELF/Object.cpp +++ llvm/tools/llvm-objcopy/ELF/Object.cpp @@ -2258,9 +2258,14 @@ // skipped. uint64_t MinAddr = UINT64_MAX; for (SectionBase &Sec : Obj.allocSections()) { - if (Sec.ParentSegment != nullptr) - Sec.Addr = - Sec.Offset - Sec.ParentSegment->Offset + Sec.ParentSegment->PAddr; + if (Sec.ParentSegment != nullptr) { + if (Sec.ParentSegment->Type == PT_LOAD) + Sec.Addr = + Sec.Offset - Sec.ParentSegment->Offset + Sec.ParentSegment->PAddr; + else + Sec.Addr = + Sec.Addr - Sec.ParentSegment->PAddr + Sec.ParentSegment->VAddr; + } MinAddr = std::min(MinAddr, Sec.Addr); }