forked from OSchip/llvm-project
[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)
This commit is contained in:
parent
28f91871b3
commit
8e2d3f7c30
|
@ -613,15 +613,28 @@ void DWARFRewriter::updateGdbIndexSection() {
|
||||||
|
|
||||||
void
|
void
|
||||||
DWARFRewriter::convertToRanges(const DWARFAbbreviationDeclaration *Abbrev) {
|
DWARFRewriter::convertToRanges(const DWARFAbbreviationDeclaration *Abbrev) {
|
||||||
|
dwarf::Form HighPCForm = Abbrev->findAttribute(dwarf::DW_AT_high_pc)->Form;
|
||||||
std::lock_guard<std::mutex> Lock(AbbrevPatcherMutex);
|
std::lock_guard<std::mutex> Lock(AbbrevPatcherMutex);
|
||||||
AbbrevPatcher->addAttributePatch(Abbrev,
|
AbbrevPatcher->addAttributePatch(Abbrev,
|
||||||
dwarf::DW_AT_low_pc,
|
dwarf::DW_AT_low_pc,
|
||||||
dwarf::DW_AT_ranges,
|
dwarf::DW_AT_ranges,
|
||||||
dwarf::DW_FORM_sec_offset);
|
dwarf::DW_FORM_sec_offset);
|
||||||
AbbrevPatcher->addAttributePatch(Abbrev,
|
if (HighPCForm == dwarf::DW_FORM_addr ||
|
||||||
dwarf::DW_AT_high_pc,
|
HighPCForm == dwarf::DW_FORM_data8) {
|
||||||
dwarf::DW_AT_low_pc,
|
// LowPC must have 12 bytes, use indirect
|
||||||
dwarf::DW_FORM_udata);
|
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,
|
void DWARFRewriter::convertToRanges(DWARFDie DIE,
|
||||||
|
@ -712,6 +725,7 @@ void DWARFRewriter::convertToRanges(DWARFDie DIE,
|
||||||
DIE, LowPCOffset, HighPCOffset, LowPCFormValue, HighPCFormValue);
|
DIE, LowPCOffset, HighPCOffset, LowPCFormValue, HighPCFormValue);
|
||||||
|
|
||||||
unsigned LowPCSize = 0;
|
unsigned LowPCSize = 0;
|
||||||
|
assert(DIE.getDwarfUnit()->getAddressByteSize() == 8);
|
||||||
if (HighPCFormValue.getForm() == dwarf::DW_FORM_addr ||
|
if (HighPCFormValue.getForm() == dwarf::DW_FORM_addr ||
|
||||||
HighPCFormValue.getForm() == dwarf::DW_FORM_data8) {
|
HighPCFormValue.getForm() == dwarf::DW_FORM_data8) {
|
||||||
LowPCSize = 12;
|
LowPCSize = 12;
|
||||||
|
@ -723,6 +737,13 @@ void DWARFRewriter::convertToRanges(DWARFDie DIE,
|
||||||
|
|
||||||
std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
|
std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex);
|
||||||
DebugInfoPatcher->addLE32Patch(LowPCOffset, RangesSectionOffset);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue