From 4c3b2976216b197fd62d21663e6b81706dd698cb Mon Sep 17 00:00:00 2001 From: George Rimar Date: Mon, 28 Jan 2019 10:44:01 +0000 Subject: [PATCH] [llvm-objdump] - Implement the --adjust-vma option. GNU objdump's help says: "--adjust-vma: Add OFFSET to all displayed section addresses" In real life what it does is a bit more complicated (and IMO not always reasonable. For example, GNU objdump prints not only VMA, but also LMA for sections. And with --adjust-vma it adjusts LMA, but only when a section has relocations. llvm-objsump does not seem to support printing LMAs yet, but GNU's logic anyways does not make sense for me here). This patch tries to adjust VMA. I tried to implement a reasonable approach. I am not adjusting sections that are not allocatable. As, for example, adjusting debug sections VA's and rel[a] sections VA's should not make sense. This behavior seems to be GNU compatible. Differential revision: https://reviews.llvm.org/D57051 llvm-svn: 352347 --- llvm/test/tools/llvm-objdump/X86/adjust-vma.test | 131 +++++++++++++++++++++++ llvm/tools/llvm-objdump/llvm-objdump.cpp | 42 +++++++- 2 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 llvm/test/tools/llvm-objdump/X86/adjust-vma.test diff --git a/llvm/test/tools/llvm-objdump/X86/adjust-vma.test b/llvm/test/tools/llvm-objdump/X86/adjust-vma.test new file mode 100644 index 0000000..c3317d9 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/X86/adjust-vma.test @@ -0,0 +1,131 @@ +# RUN: yaml2obj %s > %t +# RUN: llvm-objdump --all-headers -D -z %t | FileCheck %s --check-prefixes=COMMON,NOADJUST +# RUN: llvm-objdump --all-headers -D -z --adjust-vma=0x0 %t | FileCheck %s --check-prefixes=COMMON,NOADJUST +# RUN: llvm-objdump --all-headers -D -z --adjust-vma=0x123000 %t | FileCheck %s --check-prefixes=COMMON,ADJUST + +# NOADJUST: Disassembly of section .text: +# NOADJUST-NEXT: 0000000000000000 sym: +# NOADJUST-NEXT: 0: {{.*}} nop +# NOADJUST: 0000000000000001 func: +# NOADJUST-NEXT: 1: {{.*}} retq + +# ADJUST: Disassembly of section .text: +# ADJUST-NEXT: 0000000000123000 sym: +# ADJUST-NEXT: 123000: {{.*}} nop +# ADJUST: 0000000000123001 func: +# ADJUST-NEXT: 123001: {{.*}} retq + +# NOADJUST: Disassembly of section .debug_str: +# NOADJUST-NEXT: 0000000000000000 .debug_str: +# NOADJUST-NEXT: 0: {{.*}} %al, (%rax) +# NOADJUST-NEXT: 0000000000000001: R_X86_64_32 .text +# NOADJUST-NEXT: 2: {{.*}} addb %al, (%rax) + +# ADJUST: Disassembly of section .debug_str: +# ADJUST-NEXT: 0000000000000000 .debug_str: +# ADJUST-NEXT: 0: {{.*}} %al, (%rax) +# ADJUST-NEXT: 0000000000123001: R_X86_64_32 .text +# ADJUST-NEXT: 2: {{.*}} addb %al, (%rax) + +# COMMON: Disassembly of section .rela.debug_str: +# COMMON-NEXT: 0000000000000000 .rela.debug_str: +# COMMON-NEXT: 0: {{.*}} addl %eax, (%rax) +## ... There are more lines here. We do not care. + +# NOADJUST: Disassembly of section .data: +# NOADJUST-NEXT: 0000000000000000 .data: +# NOADJUST-NEXT: 0: {{.*}} addb %al, (%rax) +# NOADJUST-NEXT: 0000000000000000: R_X86_64_32 .text +# NOADJUST-NEXT: 2: {{.*}} addb %al, (%rax) + +# ADJUST: Disassembly of section .data: +# ADJUST-NEXT: 0000000000123000 .data: +# ADJUST-NEXT: 123000: {{.*}} addb %al, (%rax) +# ADJUST-NEXT: 0000000000123000: R_X86_64_32 .text +# ADJUST-NEXT: 123002: {{.*}} addb %al, (%rax) + +# COMMON: Disassembly of section .rela.data: +# COMMON-NEXT: 0000000000000000 .rela.data: +# COMMON-NEXT: 0: {{.*}} addb %al, (%rax) +## ... There are more lines here. We do not care. + +# NOADJUST: Sections: +# NOADJUST-NEXT: Idx Name Size Address Type +# NOADJUST-NEXT: 0 00000000 0000000000000000 +# NOADJUST-NEXT: 1 .text 00000002 0000000000000000 TEXT +# NOADJUST-NEXT: 2 .debug_str 00000004 0000000000000000 +# NOADJUST-NEXT: 3 .rela.debug_str 00000018 0000000000000000 +# NOADJUST-NEXT: 4 .data 00000004 0000000000000000 DATA +# NOADJUST-NEXT: 5 .rela.data 00000018 0000000000000000 +# NOADJUST-NEXT: 6 .symtab 00000060 0000000000000000 +# NOADJUST-NEXT: 7 .strtab 00000010 0000000000000000 +# NOADJUST-NEXT: 8 .shstrtab 0000003c 0000000000000000 + +# ADJUST: Sections: +# ADJUST-NEXT: Idx Name Size Address Type +# ADJUST-NEXT: 0 00000000 0000000000000000 +# ADJUST-NEXT: 1 .text 00000002 0000000000123000 TEXT +# ADJUST-NEXT: 2 .debug_str 00000004 0000000000000000 +# ADJUST-NEXT: 3 .rela.debug_str 00000018 0000000000000000 +# ADJUST-NEXT: 4 .data 00000004 0000000000123000 DATA +# ADJUST-NEXT: 5 .rela.data 00000018 0000000000000000 +# ADJUST-NEXT: 6 .symtab 00000060 0000000000000000 +# ADJUST-NEXT: 7 .strtab 00000010 0000000000000000 +# ADJUST-NEXT: 8 .shstrtab 0000003c 0000000000000000 + +# COMMON: SYMBOL TABLE: +# COMMON-NEXT: 0000000000000001 l F .text 00000000 func +# COMMON-NEXT: 0000000000000000 .text 00000000 sym +# COMMON-NEXT: 0000000000000000 l d .text 00000000 .text + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000004 + Content: 90C3 + - Name: .debug_str + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: '00000000' + - Name: .rela.debug_str + Type: SHT_RELA + Link: .symtab + AddressAlign: 0x0000000000000008 + Info: .debug_str + Relocations: + - Offset: 0x0000000000000001 + Symbol: .text + Type: R_X86_64_32 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000001 + Content: '00000000' + - Name: .rela.data + Type: SHT_RELA + Link: .symtab + AddressAlign: 0x0000000000000008 + Info: .data + Relocations: + - Offset: 0x0000000000000000 + Symbol: .text + Type: R_X86_64_32 +Symbols: + Local: + - Name: func + Type: STT_FUNC + Section: .text + Value: 0x0000000000000001 + - Name: sym + Section: .text + - Name: .text + Type: STT_SECTION + Section: .text diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 9ac5266..8241765 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -70,6 +70,11 @@ using namespace llvm; using namespace object; +cl::opt AdjustVMA( + "adjust-vma", + cl::desc("Increase the displayed address by the specified offset"), + cl::value_desc("offset"), cl::init(0)); + cl::opt llvm::AllHeaders("all-headers", cl::desc("Display all available header information")); @@ -890,6 +895,18 @@ getRelocsMap(llvm::object::ObjectFile const &Obj) { return Ret; } +// Used for --adjust-vma to check if address should be adjusted by the +// specified value for a given section. +// For ELF we do not adjust non-allocatable sections like debug ones, +// because they are not loadable. +// TODO: implement for other file formats. +static bool shouldAdjustVA(const SectionRef &Section) { + const ObjectFile *Obj = Section.getObject(); + if (isa(Obj)) + return ELFSectionRef(Section).getFlags() & ELF::SHF_ALLOC; + return false; +} + static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj, MCContext &Ctx, MCDisassembler *DisAsm, const MCInstrAnalysis *MIA, MCInstPrinter *IP, @@ -1046,6 +1063,10 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj, ArrayRef Bytes(reinterpret_cast(BytesStr.data()), BytesStr.size()); + uint64_t VMAAdjustment = 0; + if (shouldAdjustVA(Section)) + VMAAdjustment = AdjustVMA; + uint64_t Size; uint64_t Index; bool PrintedSection = false; @@ -1110,7 +1131,8 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj, outs() << '\n'; if (!NoLeadingAddr) - outs() << format("%016" PRIx64 " ", SectionAddr + Start); + outs() << format("%016" PRIx64 " ", + SectionAddr + Start + VMAAdjustment); StringRef SymbolName = std::get<1>(Symbols[SI]); if (Demangle) @@ -1271,9 +1293,9 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj, if (Size == 0) Size = 1; - PIP.printInst(*IP, Disassembled ? &Inst : nullptr, - Bytes.slice(Index, Size), SectionAddr + Index, outs(), "", - *STI, &SP, &Rels); + PIP.printInst( + *IP, Disassembled ? &Inst : nullptr, Bytes.slice(Index, Size), + SectionAddr + Index + VMAAdjustment, outs(), "", *STI, &SP, &Rels); outs() << CommentStream.str(); Comments.clear(); @@ -1353,6 +1375,15 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj, if (Offset >= Index + Size) break; + // When --adjust-vma is used, update the address printed. + if (RelCur->getSymbol() != Obj->symbol_end()) { + Expected SymSI = + RelCur->getSymbol()->getSection(); + if (SymSI && *SymSI != Obj->section_end() && + (shouldAdjustVA(**SymSI))) + Offset += AdjustVMA; + } + printRelocation(*RelCur, SectionAddr + Offset, Obj->getBytesInAddress()); ++RelCur; @@ -1493,6 +1524,9 @@ void llvm::printSectionHeaders(const ObjectFile *Obj) { StringRef Name; error(Section.getName(Name)); uint64_t Address = Section.getAddress(); + if (shouldAdjustVA(Section)) + Address += AdjustVMA; + uint64_t Size = Section.getSize(); bool Text = Section.isText(); bool Data = Section.isData(); -- 2.7.4