diff --git a/llvm/test/tools/llvm-objdump/X86/elf-disassemble-relocs-exec.test b/llvm/test/tools/llvm-objdump/X86/elf-disassemble-relocs-exec.test new file mode 100644 index 00000000000000..16216c68e1b2c2 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/X86/elf-disassemble-relocs-exec.test @@ -0,0 +1,59 @@ +## Check that 'llvm-objdump -dr' correctly prints relocations in executables. + +# RUN: yaml2obj --docnum=1 %s -o %t +# RUN: llvm-objdump -dr %t | FileCheck %s + +# CHECK: 400000: 90 nop +# CHECK-NEXT: 400001: bf 10 00 40 00 movl $4194320, %edi +# CHECK-NEXT: 0000000000400002: R_X86_64_32 .rodata +# CHECK-NEXT: 400006: e8 fc fe ff ff callq 0x3fff07 +# CHECK-NEXT: 0000000000400007: R_X86_64_PLT32 puts-0x4 +# CHECK-NEXT: 40000b: 90 nop + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +ProgramHeaders: + - Type: PT_LOAD + Flags: [ PF_X, PF_R ] + FirstSec: .text + LastSec: .rodata + VAddr: 0x400000 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x400000 + AddressAlign: 0x10 + Content: 90BF10004000E8FCFEFFFF90 + - Name: .rodata + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + AddressAlign: 0x8 + Content: 00 + - Name: .rela.text + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + AddressAlign: 0x8 + Info: .text + Relocations: + - Offset: 0x400002 + Symbol: .rodata + Type: R_X86_64_32 + Addend: 0 + - Offset: 0x400007 + Symbol: puts + Type: R_X86_64_PLT32 + Addend: -4 +Symbols: + - Name: .rodata + Type: STT_SECTION + Section: .rodata + Value: 0x400628 + - Name: puts + Type: STT_FUNC + Binding: STB_GLOBAL +... diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 48ae92f734c74d..9d461b08f3f88a 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -1286,6 +1286,10 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj, if (shouldAdjustVA(Section)) VMAAdjustment = AdjustVMA; + // In executable and shared objects, r_offset holds a virtual address. + // Subtract SectionAddr from the r_offset field of a relocation to get + // the section offset. + uint64_t RelAdjustment = Obj->isRelocatableObject() ? 0 : SectionAddr; uint64_t Size; uint64_t Index; bool PrintedSection = false; @@ -1432,7 +1436,8 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj, // For --reloc: print zero blocks patched by relocations, so that // relocations can be shown in the dump. if (RelCur != RelEnd) - MaxOffset = RelCur->getOffset() - Index; + MaxOffset = std::min(RelCur->getOffset() - RelAdjustment - Index, + MaxOffset); if (size_t N = countSkippableZeroBytes(Bytes.slice(Index, MaxOffset))) { @@ -1581,7 +1586,7 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj, if (Obj->getArch() != Triple::hexagon) { // Print relocation for instruction and data. while (RelCur != RelEnd) { - uint64_t Offset = RelCur->getOffset(); + uint64_t Offset = RelCur->getOffset() - RelAdjustment; // If this relocation is hidden, skip it. if (getHidden(*RelCur) || SectionAddr + Offset < StartAddress) { ++RelCur;