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 --- /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 --- 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 @@ 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 @@ 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 @@ RangesTy DWARFAddressRanges; AddressRanges TextAddressRanges; const Options &Opts; + DWARFContext &Context; }; static bool knownByDWARFUtil(StringRef SecName) {