From c965ffa1ed9346f058280f8444b1d2792491bd30 Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Mon, 5 Sep 2022 17:33:22 +0300 Subject: [PATCH] [llvm-dwarfutil][DWARFv5] fix reading of DW_FORM_addrx attribute. llvm::dwarfutil::ObjFileAddressMap::relocateIndexedAddr() does not read address value. The relocateIndexedAddr() should not relocate the address as the linked binary has already resolved relocations. But it should read the value. This patch adds the reading value of the address. Differential Revision: https://reviews.llvm.org/D133324 --- .../tools/llvm-dwarfutil/ELF/X86/dwarf5-addrx.test | 120 +++++++++++++++++++++ llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp | 29 ++++- 2 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-addrx.test diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-addrx.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-addrx.test new file mode 100644 index 0000000..20964f9 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-addrx.test @@ -0,0 +1,120 @@ +## Test that DWARF5 DW_FORM_addrx is correctly recognized +## and converted into the DW_FORM_addr + +# RUN: yaml2obj %s -o %t.o + +# RUN: llvm-dwarfutil %t.o %t1 +# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s +# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix DWARF-CHECK + +#CHECK: No errors. + +#DWARF-CHECK: DW_TAG_compile_unit +#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "CU1" +#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001130) +#DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000030) +#DWARF-CHECK: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) +#DWARF-CHECK: DW_TAG_subprogram +#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo1" +#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001130) +#DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010) +#DWARF-CHECK: DW_TAG_subprogram +#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo2" +#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001140) +#DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010) +#DWARF-CHECK: DW_TAG_subprogram +#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo3" +#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001150) +#DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1130 + Size: 0x30 +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addrx + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + - Attribute: DW_AT_addr_base + Form: DW_FORM_sec_offset + - Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addrx + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Tag: DW_TAG_base_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + debug_info: + - Version: 5 + UnitType: DW_UT_compile + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: CU1 + - Value: 0x0 + - Value: 0x30 + - Value: 0x8 + - AbbrCode: 2 + Values: + - CStr: foo1 + - Value: 0x0 + - Value: 0x10 + - Value: 0x64 + - AbbrCode: 0 + - AbbrCode: 2 + Values: + - CStr: foo2 + - Value: 0x01 + - Value: 0x10 + - Value: 0x64 + - AbbrCode: 0 + - AbbrCode: 2 + Values: + - CStr: foo3 + - Value: 0x02 + - Value: 0x10 + - Value: 0x64 + - AbbrCode: 0 + - AbbrCode: 3 + Values: + - CStr: int + - AbbrCode: 0 + debug_addr: + - Version: 5 + AddressSize: 0x08 + Entries: + - Address: 0x1130 + - Address: 0x1140 + - Address: 0x1150 +... diff --git a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp index df17b01..5b1ded8 100644 --- a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp +++ b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp @@ -14,6 +14,7 @@ #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/DWARF/DWARFExpression.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Support/Endian.h" #include #include @@ -40,7 +41,7 @@ class ObjFileAddressMap : public AddressesMap { public: ObjFileAddressMap(DWARFContext &Context, const Options &Options, object::ObjectFile &ObjFile) - : Opts(Options) { + : Opts(Options), Context(Context) { // Remember addresses of existing text sections. for (const object::SectionRef &Sect : ObjFile.sections()) { if (!Sect.isText()) @@ -137,9 +138,28 @@ public: void clear() override { DWARFAddressRanges.clear(); } - llvm::Expected relocateIndexedAddr(uint64_t, uint64_t) override { - // should not be called. - return object::createError("no relocations in linked binary"); + llvm::Expected relocateIndexedAddr(uint64_t StartOffset, + uint64_t EndOffset) override { + // No relocations in linked binary. Return just address value. + + const char *AddrPtr = + Context.getDWARFObj().getAddrSection().Data.data() + StartOffset; + support::endianness Endianess = + Context.getDWARFObj().isLittleEndian() ? support::little : support::big; + + assert(EndOffset > StartOffset); + switch (EndOffset - StartOffset) { + case 1: + return *AddrPtr; + case 2: + return support::endian::read16(AddrPtr, Endianess); + case 4: + return support::endian::read32(AddrPtr, Endianess); + case 8: + return support::endian::read64(AddrPtr, Endianess); + } + + llvm_unreachable("relocateIndexedAddr unhandled case!"); } protected: @@ -209,6 +229,7 @@ private: RangesTy DWARFAddressRanges; AddressRanges TextAddressRanges; const Options &Opts; + DWARFContext &Context; }; static bool knownByDWARFUtil(StringRef SecName) { -- 2.7.4