forked from OSchip/llvm-project
libDebugInfo: Avoid independently parsing the same .dwo file for two separate CUs residing there
NFC, just an optimization. Will be building on this for DWP support shortly. llvm-svn: 303591
This commit is contained in:
parent
2db1369c1f
commit
f9803fb4bb
|
@ -71,6 +71,12 @@ class DWARFContext : public DIContext {
|
|||
std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
|
||||
std::unique_ptr<DWARFDebugLocDWO> LocDWO;
|
||||
|
||||
struct DWOFile {
|
||||
object::OwningBinary<object::ObjectFile> File;
|
||||
std::unique_ptr<DWARFContext> Context;
|
||||
};
|
||||
StringMap<std::weak_ptr<DWOFile>> DWOFiles;
|
||||
|
||||
/// Read compile units from the debug_info section (if necessary)
|
||||
/// and store them in CUs.
|
||||
void parseCompileUnits();
|
||||
|
@ -248,6 +254,8 @@ public:
|
|||
return version == 2 || version == 3 || version == 4 || version == 5;
|
||||
}
|
||||
|
||||
std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
|
||||
|
||||
private:
|
||||
/// Return the compile unit that includes an offset (relative to .debug_info).
|
||||
DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
|
||||
|
|
|
@ -143,17 +143,7 @@ class DWARFUnit {
|
|||
typedef iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>
|
||||
die_iterator_range;
|
||||
|
||||
class DWOHolder {
|
||||
object::OwningBinary<object::ObjectFile> DWOFile;
|
||||
std::unique_ptr<DWARFContext> DWOContext;
|
||||
DWARFUnit *DWOU = nullptr;
|
||||
|
||||
public:
|
||||
DWOHolder(StringRef DWOPath, uint64_t DWOId);
|
||||
|
||||
DWARFUnit *getUnit() const { return DWOU; }
|
||||
};
|
||||
std::unique_ptr<DWOHolder> DWO;
|
||||
std::shared_ptr<DWARFUnit> DWO;
|
||||
|
||||
const DWARFUnitIndex::Entry *IndexEntry;
|
||||
|
||||
|
|
|
@ -897,6 +897,28 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address,
|
|||
return InliningInfo;
|
||||
}
|
||||
|
||||
std::shared_ptr<DWARFContext>
|
||||
DWARFContext::getDWOContext(StringRef AbsolutePath) {
|
||||
auto &Entry = DWOFiles[AbsolutePath];
|
||||
if (auto S = Entry.lock()) {
|
||||
DWARFContext *Ctxt = S->Context.get();
|
||||
return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
|
||||
}
|
||||
|
||||
auto S = std::make_shared<DWOFile>();
|
||||
auto Obj = object::ObjectFile::createObjectFile(AbsolutePath);
|
||||
if (!Obj) {
|
||||
// TODO: Actually report errors helpfully.
|
||||
consumeError(Obj.takeError());
|
||||
return nullptr;
|
||||
}
|
||||
S->File = std::move(Obj.get());
|
||||
S->Context = llvm::make_unique<DWARFContextInMemory>(*S->File.getBinary());
|
||||
Entry = S;
|
||||
auto *Ctxt = S->Context.get();
|
||||
return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
|
||||
}
|
||||
|
||||
static Error createError(const Twine &Reason, llvm::Error E) {
|
||||
return make_error<StringError>(Reason + toString(std::move(E)),
|
||||
inconvertibleErrorCode());
|
||||
|
|
|
@ -249,23 +249,6 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
|
|||
return DieArray.size();
|
||||
}
|
||||
|
||||
DWARFUnit::DWOHolder::DWOHolder(StringRef DWOPath, uint64_t DWOId) {
|
||||
auto Obj = object::ObjectFile::createObjectFile(DWOPath);
|
||||
if (!Obj) {
|
||||
// TODO: Actually report errors helpfully.
|
||||
consumeError(Obj.takeError());
|
||||
return;
|
||||
}
|
||||
DWOFile = std::move(Obj.get());
|
||||
DWOContext.reset(
|
||||
cast<DWARFContext>(new DWARFContextInMemory(*DWOFile.getBinary())));
|
||||
for (const auto &DWOCU : DWOContext->dwo_compile_units())
|
||||
if (DWOCU->getDWOId() == DWOId) {
|
||||
DWOU = DWOCU.get();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool DWARFUnit::parseDWO() {
|
||||
if (isDWO)
|
||||
return false;
|
||||
|
@ -287,16 +270,21 @@ bool DWARFUnit::parseDWO() {
|
|||
auto DWOId = getDWOId();
|
||||
if (!DWOId)
|
||||
return false;
|
||||
DWO = llvm::make_unique<DWOHolder>(AbsolutePath, *DWOId);
|
||||
DWARFUnit *DWOCU = DWO->getUnit();
|
||||
if (!DWOCU) {
|
||||
DWO.reset();
|
||||
auto DWOContext = Context.getDWOContext(AbsolutePath);
|
||||
if (!DWOContext)
|
||||
return false;
|
||||
|
||||
for (const auto &DWOCU : DWOContext->dwo_compile_units())
|
||||
if (DWOCU->getDWOId() == DWOId) {
|
||||
DWO = std::shared_ptr<DWARFUnit>(std::move(DWOContext), DWOCU.get());
|
||||
break;
|
||||
}
|
||||
if (!DWO)
|
||||
return false;
|
||||
}
|
||||
// Share .debug_addr and .debug_ranges section with compile unit in .dwo
|
||||
DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
|
||||
DWO->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
|
||||
auto DWORangesBase = UnitDie.getRangesBaseAttribute();
|
||||
DWOCU->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);
|
||||
DWO->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -339,8 +327,9 @@ void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
|
|||
|
||||
// Collect address ranges from DIEs in .dwo if necessary.
|
||||
bool DWOCreated = parseDWO();
|
||||
if (DWO.get())
|
||||
DWO->getUnit()->collectAddressRanges(CURanges);
|
||||
assert(!DWOCreated);
|
||||
if (DWO)
|
||||
DWO->collectAddressRanges(CURanges);
|
||||
if (DWOCreated)
|
||||
DWO.reset();
|
||||
|
||||
|
@ -400,7 +389,7 @@ DWARFUnit::getInlinedChainForAddress(uint64_t Address,
|
|||
// First, find the subroutine that contains the given address (the leaf
|
||||
// of inlined chain).
|
||||
DWARFDie SubroutineDIE =
|
||||
(DWO ? DWO->getUnit() : this)->getSubroutineForAddress(Address);
|
||||
(DWO ? DWO.get() : this)->getSubroutineForAddress(Address);
|
||||
|
||||
while (SubroutineDIE) {
|
||||
if (SubroutineDIE.isSubroutineDIE())
|
||||
|
|
Loading…
Reference in New Issue