Index: test/Object/objdump-no-sectionheaders.test =================================================================== --- test/Object/objdump-no-sectionheaders.test +++ test/Object/objdump-no-sectionheaders.test @@ -2,5 +2,5 @@ ; RUN: | FileCheck %s ; CHECK: Sections: -; CHECK: Idx Name Size Address Type +; CHECK: Idx Name Size VMA LMA Type ; CHECK-NOT: {{.}} Index: test/Object/objdump-sectionheaders.test =================================================================== --- test/Object/objdump-sectionheaders.test +++ test/Object/objdump-sectionheaders.test @@ -5,12 +5,12 @@ ; results in a way that we don't emulate. ; CHECK: Sections: -; CHECK: Idx Name Size Address Type -; CHECK: 0 00000000 0000000000000000 -; CHECK: 1 .text 00000026 0000000000000000 TEXT -; CHECK: 2 .rodata.str1.1 0000000d 0000000000000026 DATA -; CHECK: 3 .note.GNU-stack 00000000 0000000000000033 -; CHECK: 4 .rela.text 00000048 0000000000000038 -; CHECK: 5 .symtab 000000c0 0000000000000080 -; CHECK: 6 .strtab 00000033 0000000000000140 -; CHECK: 7 .shstrtab 0000004b 0000000000000173 +; CHECK: Idx Name Size VMA LMA Type +; CHECK: 0 00000000 0000000000000000 0000000000000000 +; CHECK: 1 .text 00000026 0000000000000000 0000000000000000 TEXT +; CHECK: 2 .rodata.str1.1 0000000d 0000000000000026 0000000000000026 DATA +; CHECK: 3 .note.GNU-stack 00000000 0000000000000033 0000000000000033 +; CHECK: 4 .rela.text 00000048 0000000000000038 0000000000000038 +; CHECK: 5 .symtab 000000c0 0000000000000080 0000000000000080 +; CHECK: 6 .strtab 00000033 0000000000000140 0000000000000140 +; CHECK: 7 .shstrtab 0000004b 0000000000000173 0000000000000173 Index: test/tools/llvm-objdump/X86/phdrs-lma.test =================================================================== --- /dev/null +++ test/tools/llvm-objdump/X86/phdrs-lma.test @@ -0,0 +1,34 @@ +## phdrs-lma.elf-x86-64 was generated using LLD 8.0.0 (trunk 348589). +## llvm-mc -filetype=obj -triple=x86_64-unknown-linux test.s -o test.o +## ld.lld test.o -o phdrs-lma.elf-x86-64 -script test.script +## +## test.s: +## .section .aaa, "a" +## .quad 0 +## +## .section .bbb, "a" +## .quad 0 +## +## .section .text, "ax" +## nop +## +## test.script: +## SECTIONS { +## . = 0x1000; +## .aaa : { *(.aaa.*) } +## .bbb : AT(0x2000) { *(.bbb.*) } +## } + +## Check we print both VMA and LMA correctly when dumping section headers. +# RUN: llvm-objdump --section-headers %p/Inputs/phdrs-lma.elf-x86-64 | FileCheck %s + +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size VMA LMA Type +# CHECK-NEXT: 0 00000000 0000000000000000 0000000000000000 +# CHECK-NEXT: 1 .aaa 00000008 0000000000001000 0000000000001000 DATA +# CHECK-NEXT: 2 .bbb 00000008 0000000000001008 0000000000002000 DATA +# CHECK-NEXT: 3 .text 00000001 0000000000001010 0000000000002008 TEXT +# CHECK-NEXT: 4 .comment 00000021 0000000000000000 0000000000000000 +# CHECK-NEXT: 5 .symtab 00000018 0000000000000000 0000000000000000 +# CHECK-NEXT: 6 .shstrtab 00000034 0000000000000000 0000000000000000 +# CHECK-NEXT: 7 .strtab 00000001 0000000000000000 0000000000000000 Index: tools/llvm-objdump/ELFDump.cpp =================================================================== --- tools/llvm-objdump/ELFDump.cpp +++ tools/llvm-objdump/ELFDump.cpp @@ -132,6 +132,35 @@ return getRelocationValueString(ELF64BE, Rel, Result); } +template +static uint64_t getSectionLMA(const ELFFile *Obj, + const object::ELFSectionRef &Sec) { + auto PhdrOrErr = Obj->program_headers(); + if (!PhdrOrErr) + report_fatal_error(errorToErrorCode(PhdrOrErr.takeError()).message()); + + // We are going to search for PT_LOAD segment where the requested section + // lives. That will allow us to calculate it's LMA. + for (const typename ELFFile::Elf_Phdr &Phdr : *PhdrOrErr) + if ((Phdr.p_type == ELF::PT_LOAD) && (Phdr.p_vaddr <= Sec.getAddress()) && + (Phdr.p_vaddr + Phdr.p_memsz > Sec.getAddress())) + return Sec.getAddress() - Phdr.p_vaddr + Phdr.p_paddr; + + // Return section's VMA if we did not find its LMA. + return Sec.getAddress(); +} + +uint64_t llvm::getELFSectionLMA(const object::ELFSectionRef &Sec) { + if (const auto *ELFObj = dyn_cast(Sec.getObject())) + return getSectionLMA(ELFObj->getELFFile(), Sec); + else if (const auto *ELFObj = dyn_cast(Sec.getObject())) + return getSectionLMA(ELFObj->getELFFile(), Sec); + else if (const auto *ELFObj = dyn_cast(Sec.getObject())) + return getSectionLMA(ELFObj->getELFFile(), Sec); + const auto *ELFObj = cast(Sec.getObject()); + return getSectionLMA(ELFObj->getELFFile(), Sec); +} + template void printDynamicSection(const ELFFile *Elf, StringRef Filename) { auto ProgramHeaderOrError = Elf->program_headers(); Index: tools/llvm-objdump/llvm-objdump.h =================================================================== --- tools/llvm-objdump/llvm-objdump.h +++ tools/llvm-objdump/llvm-objdump.h @@ -21,6 +21,7 @@ class COFFObjectFile; class COFFImportFile; class ELFObjectFileBase; +class ELFSectionRef; class MachOObjectFile; class MachOUniversalBinary; class ObjectFile; @@ -137,6 +138,8 @@ const object::RelocationRef &RelRef, llvm::SmallVectorImpl &Result); +uint64_t getELFSectionLMA(const object::ELFSectionRef& Sec); + void error(std::error_code ec); bool isRelocAddressLess(object::RelocationRef A, object::RelocationRef B); void parseInputMachO(StringRef Filename); Index: tools/llvm-objdump/llvm-objdump.cpp =================================================================== --- tools/llvm-objdump/llvm-objdump.cpp +++ tools/llvm-objdump/llvm-objdump.cpp @@ -1487,21 +1487,35 @@ } void llvm::printSectionHeaders(const ObjectFile *Obj) { - outs() << "Sections:\n" - "Idx Name Size Address Type\n"; + // For ELF targets we print both virtual and load memory addresses. + if (Obj->isELF()) + outs() << "Sections:\n" + "Idx Name Size VMA LMA " + "Type\n"; + else + outs() << "Sections:\n" + "Idx Name Size Address Type\n"; + for (const SectionRef &Section : ToolSectionFilter(*Obj)) { StringRef Name; error(Section.getName(Name)); - uint64_t Address = Section.getAddress(); + uint64_t VMA = Section.getAddress(); uint64_t Size = Section.getSize(); bool Text = Section.isText(); bool Data = Section.isData(); bool BSS = Section.isBSS(); std::string Type = (std::string(Text ? "TEXT " : "") + (Data ? "DATA " : "") + (BSS ? "BSS" : "")); - outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n", - (unsigned)Section.getIndex(), Name.str().c_str(), Size, - Address, Type.c_str()); + + if (Obj->isELF()) + outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %016" PRIx64 + " %s\n", + (unsigned)Section.getIndex(), Name.str().c_str(), Size, + VMA, getELFSectionLMA(Section), Type.c_str()); + else + outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n", + (unsigned)Section.getIndex(), Name.str().c_str(), Size, + VMA, Type.c_str()); } outs() << "\n"; }