Alexander Yermolovich via llvm-dev
2021-Feb-13 02:07 UTC
[llvm-dev] Extracting LocList address ranges from DWO .debug_info
Hello
I am wondering if this is a bug, or more likely something I am doing wrong/using
wrong APIs.
I have binary A, and object file A.o, compiled with Clang debug fission single
mode. So .dwo sections are in the object file. Although with split mode it would
bre the same behavior.
Relevant parts of the code:
for (const auto &CU : DwCtx->compile_units()) {
auto *const DwarfUnit = CU.get();
if (llvm::Optional<uint64_t> DWOId = DwarfUnit->getDWOId()) {
auto *CUDWO =
static_cast<DWARFCompileUnit*>(DwarfUnit->getNonSkeletonUnitDIE(false).getDwarfUnit());
...
}
}
Later in the code I iterate over DIEs for .debug_info.dwo and call
DIE.getLocations(dwarf::DW_AT_location);
Alternatively can manually extract offset and call
CUnit->findLoclistFromOffset(Offset);
It fails because it tries to look up address using DWARFUnit in NormalUnits that
it extracts from A.o.
Under the hood vistAsoluteLocationList is called with getAddrOffsetSectionItem
passed in.
Since this DWARFUnit is DWO, it invokes Context.info_section_units(). Which uses
A.o to create DW_SECT_INFO and DW_SECT_EXT_TYPES.
Then calls itself, but from the newly constructed Debug DWARFUnit. The skeleton
CU that is in A.o.
Since the way it's constructed the AddrOffsetSectionBase is never set, so
getAddrOffsetSectionItem returns None. Eventually error is returned from high
level API call.
I ended up doing this to get address ranges:
DWARFLocationExpressionsVector LocEVector;
auto CallBack = [&](const DWARFLocationEntry &Entry) ->
bool {
auto StartAddress
BaseUnit->getAddrOffsetSectionItem(Entry.Value0);
if (!StartAddress) {
//TODO: Handle Error
return false;
}
LocEVector.emplace_back(DWARFLocationExpression{DWARFAddressRange{
(*StartAddress).Address, (*StartAddress).Address + Entry.Value1,
Entry.SectionIndex}, Entry.Loc});
return true;
};
if(Unit->getLocationTable().visitLocationList(&Offset,
CallBack))
...
But back to original API calls. Are they just not designed to work with DWO CUs,
or am I missing something?
Even if AddrOffsetSectionBase was set to 0, the address section it is accessing
is in A.o and is not relocated. One would still need to get base address from
the address from Skeleton CU to get fully resolved address ranges, or what I did
to use index to access binary .debug_addr section directly (with appropriate
AddrOffsetSectionBase).
Thank You
Alex
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20210213/15c3ccf2/attachment.html>
David Blaikie via llvm-dev
2021-Feb-16 06:09 UTC
[llvm-dev] Extracting LocList address ranges from DWO .debug_info
This stuff is a bit ad-hoc at best. I believe some of these APIs have been generalized enough to be usable for your use-case, but it might be at a lower level - specifically I think the loclist infrastructure is used by lldb when parsing DWARFv5. But it might be used without some of the LLVM DWARF Unit abstractions you're using. (those abstractions are used in llvm-dwarfdump - which often isn't dealing with both .o and .dwo, but only dumping one of the files & doing what it can (or sometimes dumping one file containing both sets of sections, in which case it can do some address lookup, etc, more conveniently)) On Fri, Feb 12, 2021 at 6:07 PM Alexander Yermolovich via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > Hello > > I am wondering if this is a bug, or more likely something I am doing wrong/using wrong APIs. > I have binary A, and object file A.o, compiled with Clang debug fission single mode. So .dwo sections are in the object file. Although with split mode it would bre the same behavior. > Relevant parts of the code: > for (const auto &CU : DwCtx->compile_units()) { > auto *const DwarfUnit = CU.get(); > if (llvm::Optional<uint64_t> DWOId = DwarfUnit->getDWOId()) { > auto *CUDWO = static_cast<DWARFCompileUnit*>(DwarfUnit->getNonSkeletonUnitDIE(false).getDwarfUnit()); > ... > } > } > > Later in the code I iterate over DIEs for .debug_info.dwo and call > DIE.getLocations(dwarf::DW_AT_location); > > Alternatively can manually extract offset and call > CUnit->findLoclistFromOffset(Offset); > > It fails because it tries to look up address using DWARFUnit in NormalUnits that it extracts from A.o. > Under the hood vistAsoluteLocationList is called with getAddrOffsetSectionItem passed in. > Since this DWARFUnit is DWO, it invokes Context.info_section_units(). Which uses A.o to create DW_SECT_INFO and DW_SECT_EXT_TYPES. > Then calls itself, but from the newly constructed Debug DWARFUnit. The skeleton CU that is in A.o. > > Since the way it's constructed the AddrOffsetSectionBase is never set, so getAddrOffsetSectionItem returns None. Eventually error is returned from high level API call. > > I ended up doing this to get address ranges: > DWARFLocationExpressionsVector LocEVector; > auto CallBack = [&](const DWARFLocationEntry &Entry) -> bool { > auto StartAddress > BaseUnit->getAddrOffsetSectionItem(Entry.Value0); > if (!StartAddress) { > //TODO: Handle Error > return false; > } > LocEVector.emplace_back(DWARFLocationExpression{DWARFAddressRange{ > (*StartAddress).Address, (*StartAddress).Address + Entry.Value1, > Entry.SectionIndex}, Entry.Loc}); > return true; > }; > > if(Unit->getLocationTable().visitLocationList(&Offset, CallBack)) > ... > > > But back to original API calls. Are they just not designed to work with DWO CUs, or am I missing something? > > Even if AddrOffsetSectionBase was set to 0, the address section it is accessing is in A.o and is not relocated. One would still need to get base address from the address from Skeleton CU to get fully resolved address ranges, or what I did to use index to access binary .debug_addr section directly (with appropriate AddrOffsetSectionBase). > > Thank You > Alex > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev