void DWARFUnit::updateAddressDieMap(DWARFDie Die) { if (Die.isSubroutineDIE()) { auto DIERangesOrError = Die.getAddressRanges(); if (DIERangesOrError) { for (const auto &R : DIERangesOrError.get()) { // Ignore 0-sized ranges. if (R.LowPC == R.HighPC) continue; auto B = AddrDieMap.upper_bound(R.LowPC); if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) { // The range is a sub-range of existing ranges, we need to split the // existing range. if (R.HighPC < B->second.first) AddrDieMap[R.HighPC] = B->second; if (R.LowPC > B->first) AddrDieMap[B->first].first = R.LowPC; } AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die); } } else llvm::consumeError(DIERangesOrError.takeError()); } // Parent DIEs are added to the AddrDieMap prior to the Children DIEs to // simplify the logic to update AddrDieMap. The child's range will always // be equal or smaller than the parent's range. With this assumption, when // adding one range into the map, it will at most split a range into 3 // sub-ranges. for (DWARFDie Child = Die.getFirstChild(); Child; Child = Child.getSibling()) updateAddressDieMap(Child); }
void DWARFUnit::getInlinedChainForAddress(uint64_t Address, SmallVectorImpl<DWARFDie> &InlinedChain) { assert(InlinedChain.empty()); // Try to look for subprogram DIEs in the DWO file. parseDWO(); // First, find the subroutine that contains the given address (the leaf // of inlined chain). DWARFDie SubroutineDIE = (DWO ? DWO.get() : this)->getSubroutineForAddress(Address); while (SubroutineDIE) { if (SubroutineDIE.isSubroutineDIE()) InlinedChain.push_back(SubroutineDIE); SubroutineDIE = SubroutineDIE.getParent(); } }