From 8e2d3f7c3066a5d04fb53d86598a02631bfa4dad Mon Sep 17 00:00:00 2001 From: Xin-Xin Wang Date: Wed, 23 Oct 2019 15:19:49 -0700 Subject: [PATCH] [BOLT] Fix invalid abbrev error when reading debug_info section with readelf Summary: This fixes a bug which causes the debug_info and debug_loc sections to be unreadable by readelf/objdump. Basically, we're using 12 bytes of a ULEB128 value to fill in space, but readelf can't read more than 9 bytes of ULEB128. Thus, we replace that value with a string of 'a' instead. (cherry picked from FBD18097728) --- bolt/src/DWARFRewriter.cpp | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/bolt/src/DWARFRewriter.cpp b/bolt/src/DWARFRewriter.cpp index b9d770ccec51..7e6f8894dea6 100644 --- a/bolt/src/DWARFRewriter.cpp +++ b/bolt/src/DWARFRewriter.cpp @@ -613,15 +613,28 @@ void DWARFRewriter::updateGdbIndexSection() { void DWARFRewriter::convertToRanges(const DWARFAbbreviationDeclaration *Abbrev) { + dwarf::Form HighPCForm = Abbrev->findAttribute(dwarf::DW_AT_high_pc)->Form; std::lock_guard Lock(AbbrevPatcherMutex); AbbrevPatcher->addAttributePatch(Abbrev, dwarf::DW_AT_low_pc, dwarf::DW_AT_ranges, dwarf::DW_FORM_sec_offset); - AbbrevPatcher->addAttributePatch(Abbrev, - dwarf::DW_AT_high_pc, - dwarf::DW_AT_low_pc, - dwarf::DW_FORM_udata); + if (HighPCForm == dwarf::DW_FORM_addr || + HighPCForm == dwarf::DW_FORM_data8) { + // LowPC must have 12 bytes, use indirect + AbbrevPatcher->addAttributePatch(Abbrev, + dwarf::DW_AT_high_pc, + dwarf::DW_AT_low_pc, + dwarf::DW_FORM_indirect); + } else if (HighPCForm == dwarf::DW_FORM_data4) { + // LowPC must have 8 bytes, use addr + AbbrevPatcher->addAttributePatch(Abbrev, + dwarf::DW_AT_high_pc, + dwarf::DW_AT_low_pc, + dwarf::DW_FORM_addr); + } else { + llvm_unreachable("unexpected form"); + } } void DWARFRewriter::convertToRanges(DWARFDie DIE, @@ -712,6 +725,7 @@ void DWARFRewriter::convertToRanges(DWARFDie DIE, DIE, LowPCOffset, HighPCOffset, LowPCFormValue, HighPCFormValue); unsigned LowPCSize = 0; + assert(DIE.getDwarfUnit()->getAddressByteSize() == 8); if (HighPCFormValue.getForm() == dwarf::DW_FORM_addr || HighPCFormValue.getForm() == dwarf::DW_FORM_data8) { LowPCSize = 12; @@ -723,6 +737,13 @@ void DWARFRewriter::convertToRanges(DWARFDie DIE, std::lock_guard Lock(DebugInfoPatcherMutex); DebugInfoPatcher->addLE32Patch(LowPCOffset, RangesSectionOffset); - DebugInfoPatcher->addUDataPatch(LowPCOffset + 4, 0, LowPCSize); + if (LowPCSize == 12) { + // Write an indirect 0 value for DW_AT_low_pc so that we can fill + // 12 bytes of space (see T56239836 for more details) + DebugInfoPatcher->addUDataPatch(LowPCOffset + 4, dwarf::DW_FORM_addr, 4); + DebugInfoPatcher->addLE64Patch(LowPCOffset + 8, 0); + } else { + DebugInfoPatcher->addLE64Patch(LowPCOffset + 4, 0); + } }