diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -689,22 +689,27 @@ } } + Optional LowPCAttrInfo = + findAttributeInfo(DIE, dwarf::DW_AT_low_pc); if (AbbreviationDecl->findAttributeIndex(dwarf::DW_AT_ranges)) { // Case 1: The object was already non-contiguous and had DW_AT_ranges. // In this case we simply need to update the value of DW_AT_ranges // and introduce DW_AT_GNU_ranges_base if required. Optional AttrVal = findAttributeInfo(DIE, dwarf::DW_AT_ranges); - std::lock_guard Lock(DebugInfoPatcherMutex); DebugInfoPatcher.addLE32Patch( AttrVal->Offset, DebugRangesOffset - DebugInfoPatcher.getRangeBase(), AttrVal->Size); - if (!RangesBase) + + if (!RangesBase) { + if (LowPCAttrInfo && + LowPCAttrInfo->V.getForm() != dwarf::DW_FORM_GNU_addr_index && + LowPCAttrInfo->V.getForm() != dwarf::DW_FORM_addrx) + DebugInfoPatcher.addLE64Patch(LowPCAttrInfo->Offset, 0); return; + } // Convert DW_AT_low_pc into DW_AT_GNU_ranges_base. - Optional LowPCAttrInfo = - findAttributeInfo(DIE, dwarf::DW_AT_low_pc); if (!LowPCAttrInfo) { errs() << "BOLT-ERROR: skeleton CU at 0x" << Twine::utohexstr(DIE.getOffset()) @@ -725,8 +730,9 @@ // Case 2: The object has both DW_AT_low_pc and DW_AT_high_pc emitted back // to back. Replace with new attributes and patch the DIE. - if (AbbreviationDecl->findAttributeIndex(dwarf::DW_AT_low_pc) && - AbbreviationDecl->findAttributeIndex(dwarf::DW_AT_high_pc)) { + Optional HighPCAttrInfo = + findAttributeInfo(DIE, dwarf::DW_AT_high_pc); + if (LowPCAttrInfo && HighPCAttrInfo) { convertToRangesPatchAbbrev(*DIE.getDwarfUnit(), AbbreviationDecl, AbbrevWriter, RangesBase); convertToRangesPatchDebugInfo(DIE, DebugRangesOffset, DebugInfoPatcher, diff --git a/bolt/test/AArch64/Inputs/go_dwarf.yaml b/bolt/test/AArch64/Inputs/go_dwarf.yaml new file mode 100644 --- /dev/null +++ b/bolt/test/AArch64/Inputs/go_dwarf.yaml @@ -0,0 +1,79 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_AARCH64 + Entry: 0x684 +ProgramHeaders: + - Type: PT_PHDR + Flags: [ PF_R ] + VAddr: 0x200 + Align: 0x8 + - Type: PT_INTERP + Flags: [ PF_R ] + FirstSec: .plt + LastSec: .plt + VAddr: 0x238 + - Type: PT_LOAD + Flags: [ PF_X, PF_R ] + FirstSec: .plt + LastSec: .text + Align: 0x10000 + VAddr: 0x5e8 +Sections: + - Name: .plt + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x5F0 + AddressAlign: 0x10 + EntSize: 0x10 + Content: F07BBFA99000009011CA47F910423E9120021FD61F2003D51F2003D51F2003D59000009011CE47F910623E9120021FD69000009011D247F910823E9120021FD69000009011D647F910A23E9120021FD69000009011DA47F910C23E9120021FD69000009011DE47F910E23E9120021FD6 + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x660 + AddressAlign: 0x8 + Content: FD7BBFA9A1D6811200000090FD03009100C02091F7FFFF9700008052FD7BC1A8C0035FD61D0080D21E0080D2E50300AAE10340F9E2230091E60300918000009000F847F98300009063F447F98400009084E447F9DBFFFF97E2FFFF978000009000F047F9400000B4DAFFFF17C0035FD6800000B000400091810000B0214000913F0000EBC00000548100009021E847F9610000B4F00301AA00021FD6C0035FD6800000B000400091810000B021400091210000CB22FC7FD3410C818BFF0781EB21FC4193C00000548200009042FC47F9620000B4F00302AA00021FD6C0035FD6FD7BBEA9FD030091F30B00F9930000B060424039400100358000009000EC47F9800000B4800000B0000440F9A9FFFF97D8FFFF972000805260420039F30B40F9FD7BC2A8C0035FD6DEFFFF171F2003D5FD7BBCA9FD030091F35301A99400009094223691F55B02A995000090B5023691940215CBF603002AF76303A9F70301AAF80302AA83FFFF97FF0F94EB6001005494FE4393130080D2A37A73F8E20318AA73060091E10317AAE003162A60003FD69F0213EB21FFFF54F35341A9F55B42A9F76343A9FD7BC4A8C0035FD61F2003D5C0035FD6 + - Name: .debug_info + Type: SHT_PROGBITS + AddressAlign: 0x1 + Content: B100000004000000000008011F0000000C000000000C00000000000000600600000000000000000000029E0000000101059000000060060000000000008406000000000000019C9000000003610001020990000000CA6204050000000200900000006D00000005970000000600077806000000000000A900000008015009033008000000000000080151030B4AF10000090405696E74000A08A40000000B0108A30000000C9D0000000D0500000005000000020000 + - Name: .debug_abbrev + Type: SHT_PROGBITS + AddressAlign: 0x1 + Content: 011101250E130B030E1B0E5517110110170000022E013F19030E3A0B3B0B390B49131101120140189742190113000003340003083A0B3B0B390B49131C0D0000042E013F19030E3A0B3B0B271949133C19011300000505004913000006180000000789820101110131130000088A820100021891421800000924000B0B3E0B030800000A0F000B0B491300000B24000B0B3E0B030E00000C2600491300000D2E003F193C196E0E030E3A0B3B0B000000 + - Name: .debug_line + Type: SHT_PROGBITS + AddressAlign: 0x1 + Content: 5C0000000300290000000401FB0E0D0001010101000000010000010065782E63010000003C6275696C742D696E3E0000000000050C00090260060000000000000105051313050C0610050522050C2C050522050C1E0505140501210203000101 +Symbols: + - Name: main + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x660 + Size: 0x24 +DWARF: + debug_str: + - te.c + - printf + - '/home/test/test/te' + - 'GNU C17 9.3.0 -mlittle-endian -mabi=lp64 -g -O3 -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection' + - main + - char + debug_aranges: + - Length: 0x2C + Version: 2 + CuOffset: 0x0 + AddressSize: 0x8 + Descriptors: + - Address: 0x660 + Length: 0x24 + debug_ranges: + - Offset: 0x0 + AddrSize: 0x8 + Entries: + - LowOffset: 0x0 + HighOffset: 0x24 +... diff --git a/bolt/test/AArch64/go_dwarf.test b/bolt/test/AArch64/go_dwarf.test new file mode 100644 --- /dev/null +++ b/bolt/test/AArch64/go_dwarf.test @@ -0,0 +1,53 @@ +# Check that the llvm-bolt update the dwarf information correctly in case: +# - DW_AT_low_pc is nullified in case the DW_AT_ranges tag already exists. +# - DW_AT_high_pc is in the form of DW_FORM_addr. + +RUN: yaml2obj %p/Inputs/go_dwarf.yaml &> %t.exe +RUN: llvm-bolt %t.exe -o %t.bolt -update-debug-sections + +# Check the original binary values. +RUN: llvm-dwarfdump -debug-info %t.exe |& \ +RUN: FileCheck %s -check-prefix=CHECKORIG + +CHECKORIG: DW_TAG_compile_unit +CHECKORIG-NEXT: DW_AT_producer +CHECKORIG-NEXT: DW_AT_language +CHECKORIG-NEXT: DW_AT_name +CHECKORIG-NEXT: DW_AT_comp_dir +CHECKORIG-NEXT: DW_AT_ranges (0x00000000 +CHECKORIG-NEXT: [0x0000000000000660, 0x0000000000000684)) +CHECKORIG-NEXT: DW_AT_low_pc (0x0000000000000660) + +CHECKORIG: DW_TAG_subprogram +CHECKORIG-NEXT: DW_AT_external (true) +CHECKORIG-NEXT: DW_AT_name ("main") +CHECKORIG-NEXT: DW_AT_decl_file +CHECKORIG-NEXT: DW_AT_decl_line (1) +CHECKORIG-NEXT: DW_AT_decl_column (0x05) +CHECKORIG-NEXT: DW_AT_type (0x00000090 "int") +CHECKORIG-NEXT: DW_AT_low_pc (0x0000000000000660) +CHECKORIG-NEXT: DW_AT_high_pc (0x0000000000000684) + + +# Check the bolted binary. +RUN: llvm-dwarfdump -debug-info %t.bolt |& FileCheck %s + +CHECK: DW_TAG_compile_unit +CHECK-NEXT: DW_AT_producer +CHECK-NEXT: DW_AT_language +CHECK-NEXT: DW_AT_name +CHECK-NEXT: DW_AT_comp_dir +CHECK-NEXT: DW_AT_ranges (0x00000010 +CHECK-NEXT: [0x0000000000000660, 0x0000000000000684)) +CHECK-NEXT: DW_AT_low_pc (0x0000000000000000) +CHECK-NEXT: DW_AT_stmt_list (0x00000000) + +CHECK: DW_TAG_subprogram +CHECK-NEXT: DW_AT_external (true) +CHECK-NEXT: DW_AT_name ("main") +CHECK-NEXT: DW_AT_decl_file +CHECK-NEXT: DW_AT_decl_line (1) +CHECK-NEXT: DW_AT_decl_column (0x05) +CHECK-NEXT: DW_AT_type (0x00000090 "int") +CHECK-NEXT: DW_AT_low_pc (0x0000000000000660) +CHECK-NEXT: DW_AT_high_pc (0x0000000000000684)