Skip to content

[llvm][dwarf][rfc][donotcommit] Enable print of ranges addresses from .debug_info.dwo #65516

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ class DWARFContext : public DIContext {
DWARFUnitVector &getDWOUnits(bool Lazy = false);

std::unique_ptr<const DWARFObject> DObj;
/// Can be optionally set by tools that work with .dwo/.dwp files to reference
/// main binary debug information. Usefull for accessing .debug_ranges and
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Useful

/// .debug_addr section.
std::unique_ptr<const DWARFObject> MainBinaryDObj = nullptr;
/// DWARFContext for main binary.
std::unique_ptr<DWARFContext> MainBinaryDICtx = nullptr;

// When set parses debug_info.dwo/debug_abbrev.dwo manually and populates CU
// Index, and TU Index for DWARF5.
Expand All @@ -145,6 +151,13 @@ class DWARFContext : public DIContext {

const DWARFObject &getDWARFObj() const { return *DObj; }

const DWARFObject *getMainBinaryDWARFObj() const {
return MainBinaryDObj.get();
}
const DWARFContext *getDWARFContextMainBinary() const {
return MainBinaryDICtx.get();
}

static bool classof(const DIContext *DICtx) {
return DICtx->getKind() == CK_DWARF;
}
Expand Down Expand Up @@ -478,6 +491,17 @@ class DWARFContext : public DIContext {
/// manually only for DWARF5.
void setParseCUTUIndexManually(bool PCUTU) { ParseCUTUIndexManually = PCUTU; }

/// Sets the object corresponding to the main binary to which the .dwo/.dwp
/// file belongs.
void setMainBinaryObjAndCreateContext(
const object::ObjectFile &Obj,
ProcessDebugRelocations RelocAction = ProcessDebugRelocations::Process,
const LoadedObjectInfo *L = nullptr,
std::function<void(Error)> RecoverableErrorHandler =
WithColor::defaultErrorHandler,
std::function<void(Error)> WarningHandler =
WithColor::defaultWarningHandler);

private:
void addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, DWARFDie Die,
std::vector<DILocal> &Result);
Expand Down
48 changes: 44 additions & 4 deletions llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,18 @@
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstdint>
#include <deque>
#include <map>
#include <optional>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

Expand Down Expand Up @@ -1004,21 +1006,47 @@ void DWARFContext::dump(
DObj->getAbbrevDWOSection()))
getDebugAbbrevDWO()->dump(OS);

std::unordered_map<uint64_t, DWARFUnit *> DwoIDToDUMap;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auto SetSections = [&](DWARFUnit &U) -> void {
std::optional<uint64_t> DWOID = U.getDWOId();
if (U.isDWOUnit() && DWOID) {
auto MapIter = DwoIDToDUMap.find(*DWOID);
if (MapIter != DwoIDToDUMap.end()) {
DWARFDie UnitDie = MapIter->second->getUnitDIE();
std::optional<uint64_t> RangeBase = UnitDie.getRangesBaseAttribute();
if (U.getVersion() < 5 && RangeBase)
U.setRangesSection(&MainBinaryDObj->getRangesSection(), *RangeBase);
if (std::optional<uint64_t> AddrBase =
MapIter->second->getAddrOffsetSectionBase())
U.setAddrOffsetSection(&MainBinaryDObj->getAddrSection(), *AddrBase);
}
}
};
auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) {
OS << '\n' << Name << " contents:\n";
if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
for (const auto &U : Units)
for (const auto &U : Units) {
SetSections(*U);
U->getDIEForOffset(*DumpOffset)
.dump(OS, 0, DumpOpts.noImplicitRecursion());
}
else
for (const auto &U : Units)
for (const auto &U : Units) {
SetSections(*U);
U->dump(OS, DumpOpts);
}
};
if ((DumpType & DIDT_DebugInfo)) {
if (Explicit || getNumCompileUnits())
dumpDebugInfo(".debug_info", info_section_units());
if (ExplicitDWO || getNumDWOCompileUnits())
if (ExplicitDWO || getNumDWOCompileUnits()) {
if (MainBinaryDObj) {
for (const auto &U : MainBinaryDICtx->compile_units())
if (std::optional<uint64_t> DWOID = U->getDWOId())
DwoIDToDUMap.insert({*DWOID, U.get()});
}
dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
}
}

auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) {
Expand Down Expand Up @@ -2428,3 +2456,15 @@ uint8_t DWARFContext::getCUAddrSize() {
auto CUs = compile_units();
return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize();
}

void DWARFContext::setMainBinaryObjAndCreateContext(
const object::ObjectFile &Obj, ProcessDebugRelocations RelocAction,
const LoadedObjectInfo *L,
std::function<void(Error)> RecoverableErrorHandler,
std::function<void(Error)> WarningHandler) {
MainBinaryDObj = std::make_unique<DWARFObjInMemory>(
Obj, L, RecoverableErrorHandler, WarningHandler, RelocAction);
MainBinaryDICtx =
DWARFContext::create(Obj, DWARFContext::ProcessDebugRelocations::Process,
nullptr, "", RecoverableErrorHandler);
}
7 changes: 5 additions & 2 deletions llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,8 +366,11 @@ Error DWARFUnit::extractRangeList(uint64_t RangeListOffset,
DWARFDebugRangeList &RangeList) const {
// Require that compile unit is extracted.
assert(!DieArray.empty());
DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
IsLittleEndian, getAddressByteSize());
DWARFDataExtractor RangesData(isDWOUnit() && Context.getMainBinaryDWARFObj()
? *Context.getMainBinaryDWARFObj()
: Context.getDWARFObj(),
*RangeSection, IsLittleEndian,
getAddressByteSize());
uint64_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
return RangeList.extract(RangesData, &ActualRangeListOffset);
}
Expand Down
21 changes: 21 additions & 0 deletions llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ static std::array<std::optional<uint64_t>, (unsigned)DIDT_ID_Count> DumpOffsets;
static alias DumpDebugFrameAlias("eh-frame", desc("Alias for --debug-frame"),
NotHidden, cat(SectionCategory),
aliasopt(DumpDebugFrame));
static cl::opt<std::string>
MainBinary("main-binary",
desc("Specifies the main binary for cases when .dwo/.dwp file "
"is processed."),
cl::init(""), cat(DwarfDumpCategory));
static list<std::string>
ArchFilters("arch",
desc("Dump debug information for the specified CPU "
Expand Down Expand Up @@ -714,6 +719,9 @@ static bool handleArchive(StringRef Filename, Archive &Arch,
static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
HandlerFn HandleObj, raw_ostream &OS) {
Expected<std::unique_ptr<Binary>> BinOrErr = object::createBinary(Buffer);
std::unique_ptr<MemoryBuffer> MainBuffer = nullptr;
ErrorOr<std::unique_ptr<MemoryBuffer>> MainBuffOrErr = nullptr;
std::unique_ptr<Binary> MainBin = nullptr;
error(Filename, BinOrErr.takeError());

bool Result = true;
Expand All @@ -727,6 +735,19 @@ static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
*Obj, DWARFContext::ProcessDebugRelocations::Process, nullptr, "",
RecoverableErrorHandler);
DICtx->setParseCUTUIndexManually(ManuallyGenerateUnitIndex);
if (!MainBinary.empty()) {
MainBuffOrErr = MemoryBuffer::getFileOrSTDIN(MainBinary);
error(MainBinary, MainBuffOrErr.getError());
MainBuffer = std::move(MainBuffOrErr.get());
Expected<std::unique_ptr<Binary>> MainBinOrErr =
object::createBinary(*MainBuffer);
error(MainBinary, MainBinOrErr.takeError());
MainBin = std::move(MainBinOrErr.get());
if (auto *Obj = dyn_cast<ObjectFile>(MainBin.get()))
DICtx->setMainBinaryObjAndCreateContext(
*Obj, DWARFContext::ProcessDebugRelocations::Process, nullptr,
RecoverableErrorHandler);
}
if (!HandleObj(*Obj, *DICtx, Filename, OS))
Result = false;
}
Expand Down