mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-14 19:49:36 +00:00
[BOLT][DWARF] Fix abbrev offsets for type units
Summary: When rewriting .debug_abbrev section, update abbrev offsets for type units in addition to compile units. Reuse abbreviation entries if they were shared by multiple compile/type units. (cherry picked from FBD31262326)
This commit is contained in:
parent
47455e98b3
commit
e3b901aaee
@ -164,7 +164,6 @@ static bool isHighPcFormEightBytes(dwarf::Form DwarfForm) {
|
||||
|
||||
void DWARFRewriter::updateDebugInfo() {
|
||||
ErrorOr<BinarySection &> DebugInfo = BC.getUniqueSectionByName(".debug_info");
|
||||
|
||||
if (!DebugInfo)
|
||||
return;
|
||||
|
||||
@ -841,9 +840,9 @@ void DWARFRewriter::finalizeDebugSections(
|
||||
AbbrevSectionContents->size());
|
||||
|
||||
// Update abbreviation offsets if they were changed.
|
||||
for (auto &CU : BC.DwCtx->compile_units()) {
|
||||
if (CU->isDWOUnit())
|
||||
continue;
|
||||
SimpleBinaryPatcher *DebugTypesPatcher = nullptr;
|
||||
for (auto &CU : BC.DwCtx->normal_units()) {
|
||||
assert(!CU->isDWOUnit());
|
||||
|
||||
const uint64_t NewAbbrevOffset =
|
||||
AbbrevWriter->getAbbreviationsOffsetForUnit(*CU);
|
||||
@ -854,8 +853,22 @@ void DWARFRewriter::finalizeDebugSections(
|
||||
// unit_length - 4 bytes
|
||||
// version - 2 bytes
|
||||
// So + 6 to patch debug_abbrev_offset
|
||||
DebugInfoPatcher.addLE32Patch(CU->getOffset() + 6,
|
||||
static_cast<uint32_t>(NewAbbrevOffset));
|
||||
constexpr uint64_t AbbrevFieldOffset = 6;
|
||||
if (!CU->isTypeUnit()) {
|
||||
DebugInfoPatcher.addLE32Patch(CU->getOffset() + AbbrevFieldOffset,
|
||||
static_cast<uint32_t>(NewAbbrevOffset));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!DebugTypesPatcher) {
|
||||
ErrorOr<BinarySection &> DebugTypes =
|
||||
BC.getUniqueSectionByName(".debug_types");
|
||||
DebugTypes->registerPatcher(std::make_unique<SimpleBinaryPatcher>());
|
||||
DebugTypesPatcher =
|
||||
static_cast<SimpleBinaryPatcher *>(DebugTypes->getPatcher());
|
||||
}
|
||||
DebugTypesPatcher->addLE32Patch(CU->getOffset() + AbbrevFieldOffset,
|
||||
static_cast<uint32_t>(NewAbbrevOffset));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -409,19 +409,20 @@ void DebugAbbrevWriter::addUnitAbbreviations(DWARFUnit &Unit) {
|
||||
if (!Abbrevs)
|
||||
return;
|
||||
|
||||
uint64_t CUIndex = Unit.getOffset();
|
||||
|
||||
if (CUAbbrevData.find(CUIndex) == CUAbbrevData.end()) {
|
||||
std::lock_guard<std::mutex> Lock(WriterMutex);
|
||||
AbbrevData &Data = CUAbbrevData[CUIndex];
|
||||
Data.Buffer = std::make_unique<DebugBufferVector>();
|
||||
Data.Stream = std::make_unique<raw_svector_ostream>(*Data.Buffer);
|
||||
}
|
||||
// Multiple units may share the same abbreviations. Only add abbreviations
|
||||
// for the first unit and reuse them.
|
||||
const uint64_t AbbrevOffset = Unit.getAbbreviationsOffset();
|
||||
if (CUAbbrevData.find(AbbrevOffset) != CUAbbrevData.end())
|
||||
return;
|
||||
|
||||
std::lock_guard<std::mutex> Lock(WriterMutex);
|
||||
AbbrevData &UnitData = CUAbbrevData[AbbrevOffset];
|
||||
UnitData.Buffer = std::make_unique<DebugBufferVector>();
|
||||
UnitData.Stream = std::make_unique<raw_svector_ostream>(*UnitData.Buffer);
|
||||
|
||||
const auto &UnitPatches = Patches[&Unit];
|
||||
|
||||
raw_svector_ostream &OS = *CUAbbrevData[CUIndex].Stream.get();
|
||||
raw_svector_ostream &OS = *UnitData.Stream.get();
|
||||
|
||||
// Take a fast path if there are no patches to apply. Simply copy the original
|
||||
// contents.
|
||||
@ -502,20 +503,20 @@ std::unique_ptr<DebugBufferVector> DebugAbbrevWriter::finalize() {
|
||||
// Pre-calculate the total size of abbrev section.
|
||||
uint64_t Size = 0;
|
||||
for (const auto &KV : CUAbbrevData) {
|
||||
const AbbrevData &Data = KV.second;
|
||||
Size += Data.Buffer->size();
|
||||
const AbbrevData &UnitData = KV.second;
|
||||
Size += UnitData.Buffer->size();
|
||||
}
|
||||
ReturnBuffer.reserve(Size);
|
||||
|
||||
uint64_t Pos = 0;
|
||||
for (auto &KV : CUAbbrevData) {
|
||||
AbbrevData &Data = KV.second;
|
||||
ReturnBuffer.append(*Data.Buffer);
|
||||
Data.Offset = Pos;
|
||||
Pos += Data.Buffer->size();
|
||||
AbbrevData &UnitData = KV.second;
|
||||
ReturnBuffer.append(*UnitData.Buffer);
|
||||
UnitData.Offset = Pos;
|
||||
Pos += UnitData.Buffer->size();
|
||||
|
||||
Data.Buffer.reset();
|
||||
Data.Stream.reset();
|
||||
UnitData.Buffer.reset();
|
||||
UnitData.Stream.reset();
|
||||
}
|
||||
|
||||
return std::make_unique<DebugBufferVector>(ReturnBuffer);
|
||||
|
@ -443,7 +443,7 @@ class DebugAbbrevWriter {
|
||||
std::unique_ptr<DebugBufferVector> Buffer;
|
||||
std::unique_ptr<raw_svector_ostream> Stream;
|
||||
};
|
||||
/// Map CU offset to abbreviations data.
|
||||
/// Map original CU abbrev offset to abbreviations data.
|
||||
std::map<uint64_t, AbbrevData> CUAbbrevData;
|
||||
|
||||
/// Attributes Substitution information.
|
||||
@ -490,9 +490,10 @@ public:
|
||||
|
||||
/// Return an offset in the finalized section corresponding to CU \p Unit.
|
||||
uint64_t getAbbreviationsOffsetForUnit(const DWARFUnit &Unit) {
|
||||
assert(CUAbbrevData.find(Unit.getOffset()) != CUAbbrevData.end() &&
|
||||
assert(CUAbbrevData.find(Unit.getAbbreviationsOffset()) !=
|
||||
CUAbbrevData.end() &&
|
||||
"no abbrev data found for unit");
|
||||
return CUAbbrevData[Unit.getOffset()].Offset;
|
||||
return CUAbbrevData[Unit.getAbbreviationsOffset()].Offset;
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user