18 using namespace dwarf;
23 : Abbrev(DA), InfoSection(IS), AbbrevSection(AS), RangeSection(RS),
24 StringSection(SS), StringOffsetSection(SOS), AddrOffsetSection(AOS),
25 RelocMap(M), isLittleEndian(LE) {
33 uint64_t &Result)
const {
34 uint32_t Offset = AddrOffsetSectionBase + Index * AddrSize;
35 if (AddrOffsetSection.
size() < Offset + AddrSize)
43 uint32_t &Result)
const {
45 const uint32_t ItemSize = 4;
46 uint32_t Offset = Index * ItemSize;
47 if (StringOffsetSection.
size() < Offset + ItemSize)
50 Result = DA.
getU32(&Offset);
55 Length = debug_info.
getU32(offset_ptr);
56 Version = debug_info.
getU16(offset_ptr);
57 uint64_t abbrOffset = debug_info.
getU32(offset_ptr);
58 AddrSize = debug_info.
getU8(offset_ptr);
62 bool abbrOffsetOK = AbbrevSection.
size() > abbrOffset;
63 bool addrSizeOK = AddrSize == 4 || AddrSize == 8;
65 if (!lengthOK || !versionOK || !addrSizeOK || !abbrOffsetOK)
91 assert(DieArray.size() > 0);
92 DataExtractor RangesData(RangeSection, isLittleEndian, AddrSize);
93 uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
94 return RangeList.
extract(RangesData, &ActualRangeListOffset);
104 RangeSectionBase = 0;
105 AddrOffsetSectionBase = 0;
111 extractDIEsIfNeeded(
true);
112 if (DieArray.empty())
114 return DieArray[0].getAttributeValueAsString(
this, DW_AT_comp_dir, 0);
118 extractDIEsIfNeeded(
true);
119 const uint64_t FailValue = -1ULL;
120 if (DieArray.empty())
123 .getAttributeValueAsUnsignedConstant(
this, DW_AT_GNU_dwo_id, FailValue);
126 void DWARFUnit::setDIERelations() {
127 if (DieArray.empty())
134 for (curr_die = die_array_begin; curr_die < die_array_end; ++curr_die) {
142 if (curr_die_abbrev) {
157 if (die_array_begin < die_array_end)
161 void DWARFUnit::extractDIEsToVector(
162 bool AppendCUDie,
bool AppendNonCUDies,
163 std::vector<DWARFDebugInfoEntryMinimal> &Dies)
const {
164 if (!AppendCUDie && !AppendNonCUDies)
175 while (Offset < NextCUOffset && DIE.
extractFast(
this, &Offset)) {
179 if (!AppendNonCUDies)
208 if (Offset > NextCUOffset)
209 fprintf(stderr,
"warning: DWARF compile unit extends beyond its "
210 "bounds cu 0x%8.8x at 0x%8.8x'\n",
getOffset(), Offset);
213 size_t DWARFUnit::extractDIEsIfNeeded(
bool CUDieOnly) {
214 if ((CUDieOnly && DieArray.size() > 0) ||
218 bool HasCUDie = DieArray.size() > 0;
219 extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
221 if (DieArray.empty())
227 DieArray[0].getAttributeValueAsAddress(
this, DW_AT_low_pc, -1ULL);
228 if (BaseAddr == -1ULL)
229 BaseAddr = DieArray[0].getAttributeValueAsAddress(
this, DW_AT_entry_pc, 0);
231 AddrOffsetSectionBase = DieArray[0].getAttributeValueAsSectionOffset(
232 this, DW_AT_GNU_addr_base, 0);
233 RangeSectionBase = DieArray[0].getAttributeValueAsSectionOffset(
234 this, DW_AT_GNU_ranges_base, 0);
238 return DieArray.size();
245 if (DWOContext->getNumDWOCompileUnits() > 0)
246 DWOU = DWOContext->getDWOCompileUnitAtIndex(0);
249 bool DWARFUnit::parseDWO() {
252 extractDIEsIfNeeded(
true);
253 if (DieArray.empty())
255 const char *DWOFileName =
256 DieArray[0].getAttributeValueAsString(
this, DW_AT_GNU_dwo_name, 0);
257 if (DWOFileName == 0)
259 const char *CompilationDir =
260 DieArray[0].getAttributeValueAsString(
this, DW_AT_comp_dir, 0);
271 DWO.
reset(
new DWOHolder(DWOFile));
284 void DWARFUnit::clearDIEs(
bool KeepCUDie) {
285 if (DieArray.size() > (
unsigned)KeepCUDie) {
293 std::vector<DWARFDebugInfoEntryMinimal> TmpArray;
294 DieArray.swap(TmpArray);
297 DieArray.push_back(TmpArray.front());
303 bool clear_dies_if_already_not_parsed,
304 uint32_t CUOffsetInAranges) {
311 const bool clear_dies = extractDIEsIfNeeded(
false) > 1 &&
312 clear_dies_if_already_not_parsed;
313 DieArray[0].buildAddressRangeTable(
this, debug_aranges, CUOffsetInAranges);
314 bool DWOCreated = parseDWO();
319 DWO->getUnit()->buildAddressRangeTable(
320 debug_aranges, clear_dies_if_already_not_parsed, CUOffsetInAranges);
322 if (DWOCreated && clear_dies_if_already_not_parsed)
332 DWARFUnit::getSubprogramForAddress(uint64_t Address) {
333 extractDIEsIfNeeded(
false);
334 for (
size_t i = 0, n = DieArray.size(); i != n; i++)
335 if (DieArray[i].isSubprogramDIE() &&
336 DieArray[i].addressRangeContainsAddress(
this, Address)) {
348 getSubprogramForAddress(Address);
355 SubprogramDIE = DWO->getUnit()->getSubprogramForAddress(Address);
357 ChainCU = DWO->getUnit();
size_t size() const
size - Get the string size.
void setBaseAddress(uint64_t base_addr)
bool is_relative(const Twine &path)
Is path relative?
DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(const DWARFUnit *U, const uint64_t Address) const
bool extractRangeList(uint32_t RangeListOffset, DWARFDebugRangeList &RangeList) const
uint32_t getNextUnitOffset() const
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type cast(const Y &Val)
bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
const char * getCompilationDir()
static ObjectFile * createObjectFile(StringRef ObjectPath)
Create ObjectFile from path.
uint32_t getFirstDIEOffset() const
const DWARFAbbreviationDeclarationSet * getAbbreviationDeclarationSet(uint64_t cu_abbr_offset) const
DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address)
void setSibling(DWARFDebugInfoEntryMinimal *sibling)
bool extract(DataExtractor data, uint32_t *offset_ptr)
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
DWARFDebugInfoEntryMinimal - A DIE with only the minimum required data.
void setRangesSection(StringRef RS, uint32_t Base)
void buildAddressRangeTable(DWARFDebugAranges *debug_aranges, bool clear_dies_if_already_not_parsed, uint32_t CUOffsetInAranges)
int fprintf(FILE *stream, const char *format, ...);
bool extract(DataExtractor debug_info, uint32_t *offset_ptr)
size_t getDebugInfoSize() const
Size in bytes of the .debug_info data associated with this compile unit.
bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const
void setParent(DWARFDebugInfoEntryMinimal *parent)
static bool isSupportedVersion(unsigned version)
virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr)
DWARFDebugInfoEntryMinimal * getParent()
uint32_t getOffset() const
DWARFUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS, StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, const RelocAddrMap *M, bool LE)
bool extractFast(const DWARFUnit *U, uint32_t *OffsetPtr)
void setAddrOffsetSection(StringRef AOS, uint32_t Base)