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 --- /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 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -1285,6 +1285,10 @@ 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; @@ -1431,7 +1435,8 @@ // 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))) { @@ -1580,7 +1585,7 @@ 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;