1 //===-- DWARFUnit.cpp -----------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ADT/SmallString.h" 11 #include "llvm/ADT/STLExtras.h" 12 #include "llvm/ADT/StringRef.h" 13 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" 14 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 15 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" 16 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 17 #include "llvm/DebugInfo/DWARF/DWARFUnit.h" 18 #include "llvm/Object/ObjectFile.h" 19 #include "llvm/Support/Casting.h" 20 #include "llvm/Support/DataExtractor.h" 21 #include "llvm/Support/Path.h" 22 #include <algorithm> 23 #include <cassert> 24 #include <cstdint> 25 #include <cstdio> 26 #include <vector> 27 28 namespace llvm { 29 30 using namespace dwarf; 31 32 void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) { 33 parseImpl(C, Section, C.getDebugAbbrev(), C.getRangeSection(), 34 C.getStringSection(), StringRef(), C.getAddrSection(), 35 C.getLineSection().Data, C.isLittleEndian(), false); 36 } 37 38 void DWARFUnitSectionBase::parseDWO(DWARFContext &C, 39 const DWARFSection &DWOSection, 40 DWARFUnitIndex *Index) { 41 parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), C.getRangeDWOSection(), 42 C.getStringDWOSection(), C.getStringOffsetDWOSection(), 43 C.getAddrSection(), C.getLineDWOSection().Data, C.isLittleEndian(), 44 true); 45 } 46 47 DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section, 48 const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, 49 StringRef SOS, StringRef AOS, StringRef LS, bool LE, 50 bool IsDWO, const DWARFUnitSectionBase &UnitSection, 51 const DWARFUnitIndex::Entry *IndexEntry) 52 : Context(DC), InfoSection(Section), Abbrev(DA), RangeSection(RS), 53 LineSection(LS), StringSection(SS), StringOffsetSection([&]() { 54 if (IndexEntry) 55 if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS)) 56 return SOS.slice(C->Offset, C->Offset + C->Length); 57 return SOS; 58 }()), 59 AddrOffsetSection(AOS), isLittleEndian(LE), isDWO(IsDWO), 60 UnitSection(UnitSection), IndexEntry(IndexEntry) { 61 clear(); 62 } 63 64 DWARFUnit::~DWARFUnit() = default; 65 66 bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index, 67 uint64_t &Result) const { 68 uint32_t Offset = AddrOffsetSectionBase + Index * AddrSize; 69 if (AddrOffsetSection.size() < Offset + AddrSize) 70 return false; 71 DataExtractor DA(AddrOffsetSection, isLittleEndian, AddrSize); 72 Result = DA.getAddress(&Offset); 73 return true; 74 } 75 76 bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index, 77 uint32_t &Result) const { 78 // FIXME: string offset section entries are 8-byte for DWARF64. 79 const uint32_t ItemSize = 4; 80 uint32_t Offset = Index * ItemSize; 81 if (StringOffsetSection.size() < Offset + ItemSize) 82 return false; 83 DataExtractor DA(StringOffsetSection, isLittleEndian, 0); 84 Result = DA.getU32(&Offset); 85 return true; 86 } 87 88 bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) { 89 Length = debug_info.getU32(offset_ptr); 90 Version = debug_info.getU16(offset_ptr); 91 uint64_t AbbrOffset = debug_info.getU32(offset_ptr); 92 if (IndexEntry) { 93 if (AbbrOffset) 94 return false; 95 auto *UnitContrib = IndexEntry->getOffset(); 96 if (!UnitContrib || UnitContrib->Length != (Length + 4)) 97 return false; 98 auto *AbbrEntry = IndexEntry->getOffset(DW_SECT_ABBREV); 99 if (!AbbrEntry) 100 return false; 101 AbbrOffset = AbbrEntry->Offset; 102 } 103 AddrSize = debug_info.getU8(offset_ptr); 104 105 bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1); 106 bool VersionOK = DWARFContext::isSupportedVersion(Version); 107 bool AddrSizeOK = AddrSize == 4 || AddrSize == 8; 108 109 if (!LengthOK || !VersionOK || !AddrSizeOK) 110 return false; 111 112 Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset); 113 return Abbrevs != nullptr; 114 } 115 116 bool DWARFUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) { 117 clear(); 118 119 Offset = *offset_ptr; 120 121 if (debug_info.isValidOffset(*offset_ptr)) { 122 if (extractImpl(debug_info, offset_ptr)) 123 return true; 124 125 // reset the offset to where we tried to parse from if anything went wrong 126 *offset_ptr = Offset; 127 } 128 129 return false; 130 } 131 132 bool DWARFUnit::extractRangeList(uint32_t RangeListOffset, 133 DWARFDebugRangeList &RangeList) const { 134 // Require that compile unit is extracted. 135 assert(!DieArray.empty()); 136 DataExtractor RangesData(RangeSection, isLittleEndian, AddrSize); 137 uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset; 138 return RangeList.extract(RangesData, &ActualRangeListOffset); 139 } 140 141 void DWARFUnit::clear() { 142 Offset = 0; 143 Length = 0; 144 Version = 0; 145 Abbrevs = nullptr; 146 AddrSize = 0; 147 BaseAddr = 0; 148 RangeSectionBase = 0; 149 AddrOffsetSectionBase = 0; 150 clearDIEs(false); 151 DWO.reset(); 152 } 153 154 const char *DWARFUnit::getCompilationDir() { 155 return toString(getUnitDIE().find(DW_AT_comp_dir), nullptr); 156 } 157 158 Optional<uint64_t> DWARFUnit::getDWOId() { 159 return toUnsigned(getUnitDIE().find(DW_AT_GNU_dwo_id)); 160 } 161 162 void DWARFUnit::extractDIEsToVector( 163 bool AppendCUDie, bool AppendNonCUDies, 164 std::vector<DWARFDebugInfoEntry> &Dies) const { 165 if (!AppendCUDie && !AppendNonCUDies) 166 return; 167 168 // Set the offset to that of the first DIE and calculate the start of the 169 // next compilation unit header. 170 uint32_t DIEOffset = Offset + getHeaderSize(); 171 uint32_t NextCUOffset = getNextUnitOffset(); 172 DWARFDebugInfoEntry DIE; 173 DataExtractor DebugInfoData = getDebugInfoExtractor(); 174 uint32_t Depth = 0; 175 bool IsCUDie = true; 176 177 while (DIE.extractFast(*this, &DIEOffset, DebugInfoData, NextCUOffset, 178 Depth)) { 179 if (IsCUDie) { 180 if (AppendCUDie) 181 Dies.push_back(DIE); 182 if (!AppendNonCUDies) 183 break; 184 // The average bytes per DIE entry has been seen to be 185 // around 14-20 so let's pre-reserve the needed memory for 186 // our DIE entries accordingly. 187 Dies.reserve(Dies.size() + getDebugInfoSize() / 14); 188 IsCUDie = false; 189 } else { 190 Dies.push_back(DIE); 191 } 192 193 if (const DWARFAbbreviationDeclaration *AbbrDecl = 194 DIE.getAbbreviationDeclarationPtr()) { 195 // Normal DIE 196 if (AbbrDecl->hasChildren()) 197 ++Depth; 198 } else { 199 // NULL DIE. 200 if (Depth > 0) 201 --Depth; 202 if (Depth == 0) 203 break; // We are done with this compile unit! 204 } 205 } 206 207 // Give a little bit of info if we encounter corrupt DWARF (our offset 208 // should always terminate at or before the start of the next compilation 209 // unit header). 210 if (DIEOffset > NextCUOffset) 211 fprintf(stderr, "warning: DWARF compile unit extends beyond its " 212 "bounds cu 0x%8.8x at 0x%8.8x'\n", getOffset(), DIEOffset); 213 } 214 215 size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) { 216 if ((CUDieOnly && !DieArray.empty()) || 217 DieArray.size() > 1) 218 return 0; // Already parsed. 219 220 bool HasCUDie = !DieArray.empty(); 221 extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray); 222 223 if (DieArray.empty()) 224 return 0; 225 226 // If CU DIE was just parsed, copy several attribute values from it. 227 if (!HasCUDie) { 228 DWARFDie UnitDie = getUnitDIE(); 229 auto BaseAddr = toAddress(UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc})); 230 if (BaseAddr) 231 setBaseAddress(*BaseAddr); 232 AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0); 233 RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0); 234 // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for 235 // skeleton CU DIE, so that DWARF users not aware of it are not broken. 236 } 237 238 return DieArray.size(); 239 } 240 241 DWARFUnit::DWOHolder::DWOHolder(StringRef DWOPath) 242 : DWOU(nullptr) { 243 auto Obj = object::ObjectFile::createObjectFile(DWOPath); 244 if (!Obj) { 245 // TODO: Actually report errors helpfully. 246 consumeError(Obj.takeError()); 247 return; 248 } 249 DWOFile = std::move(Obj.get()); 250 DWOContext.reset( 251 cast<DWARFContext>(new DWARFContextInMemory(*DWOFile.getBinary()))); 252 if (DWOContext->getNumDWOCompileUnits() > 0) 253 DWOU = DWOContext->getDWOCompileUnitAtIndex(0); 254 } 255 256 bool DWARFUnit::parseDWO() { 257 if (isDWO) 258 return false; 259 if (DWO.get()) 260 return false; 261 DWARFDie UnitDie = getUnitDIE(); 262 if (!UnitDie) 263 return false; 264 auto DWOFileName = toString(UnitDie.find(DW_AT_GNU_dwo_name)); 265 if (!DWOFileName) 266 return false; 267 auto CompilationDir = toString(UnitDie.find(DW_AT_comp_dir)); 268 SmallString<16> AbsolutePath; 269 if (sys::path::is_relative(*DWOFileName) && CompilationDir && 270 *CompilationDir) { 271 sys::path::append(AbsolutePath, *CompilationDir); 272 } 273 sys::path::append(AbsolutePath, *DWOFileName); 274 DWO = llvm::make_unique<DWOHolder>(AbsolutePath); 275 DWARFUnit *DWOCU = DWO->getUnit(); 276 // Verify that compile unit in .dwo file is valid. 277 if (!DWOCU || DWOCU->getDWOId() != getDWOId()) { 278 DWO.reset(); 279 return false; 280 } 281 // Share .debug_addr and .debug_ranges section with compile unit in .dwo 282 DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase); 283 auto DWORangesBase = UnitDie.getRangesBaseAttribute(); 284 DWOCU->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0); 285 return true; 286 } 287 288 void DWARFUnit::clearDIEs(bool KeepCUDie) { 289 if (DieArray.size() > (unsigned)KeepCUDie) { 290 // std::vectors never get any smaller when resized to a smaller size, 291 // or when clear() or erase() are called, the size will report that it 292 // is smaller, but the memory allocated remains intact (call capacity() 293 // to see this). So we need to create a temporary vector and swap the 294 // contents which will cause just the internal pointers to be swapped 295 // so that when temporary vector goes out of scope, it will destroy the 296 // contents. 297 std::vector<DWARFDebugInfoEntry> TmpArray; 298 DieArray.swap(TmpArray); 299 // Save at least the compile unit DIE 300 if (KeepCUDie) 301 DieArray.push_back(TmpArray.front()); 302 } 303 } 304 305 void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) { 306 DWARFDie UnitDie = getUnitDIE(); 307 if (!UnitDie) 308 return; 309 // First, check if unit DIE describes address ranges for the whole unit. 310 const auto &CUDIERanges = UnitDie.getAddressRanges(); 311 if (!CUDIERanges.empty()) { 312 CURanges.insert(CURanges.end(), CUDIERanges.begin(), CUDIERanges.end()); 313 return; 314 } 315 316 // This function is usually called if there in no .debug_aranges section 317 // in order to produce a compile unit level set of address ranges that 318 // is accurate. If the DIEs weren't parsed, then we don't want all dies for 319 // all compile units to stay loaded when they weren't needed. So we can end 320 // up parsing the DWARF and then throwing them all away to keep memory usage 321 // down. 322 const bool ClearDIEs = extractDIEsIfNeeded(false) > 1; 323 getUnitDIE().collectChildrenAddressRanges(CURanges); 324 325 // Collect address ranges from DIEs in .dwo if necessary. 326 bool DWOCreated = parseDWO(); 327 if (DWO.get()) 328 DWO->getUnit()->collectAddressRanges(CURanges); 329 if (DWOCreated) 330 DWO.reset(); 331 332 // Keep memory down by clearing DIEs if this generate function 333 // caused them to be parsed. 334 if (ClearDIEs) 335 clearDIEs(true); 336 } 337 338 DWARFDie 339 DWARFUnit::getSubprogramForAddress(uint64_t Address) { 340 extractDIEsIfNeeded(false); 341 for (const DWARFDebugInfoEntry &D : DieArray) { 342 DWARFDie DIE(this, &D); 343 if (DIE.isSubprogramDIE() && 344 DIE.addressRangeContainsAddress(Address)) { 345 return DIE; 346 } 347 } 348 return DWARFDie(); 349 } 350 351 void 352 DWARFUnit::getInlinedChainForAddress(uint64_t Address, 353 SmallVectorImpl<DWARFDie> &InlinedChain) { 354 // First, find a subprogram that contains the given address (the root 355 // of inlined chain). 356 DWARFDie SubprogramDIE; 357 // Try to look for subprogram DIEs in the DWO file. 358 parseDWO(); 359 if (DWO) 360 SubprogramDIE = DWO->getUnit()->getSubprogramForAddress(Address); 361 else 362 SubprogramDIE = getSubprogramForAddress(Address); 363 364 // Get inlined chain rooted at this subprogram DIE. 365 if (SubprogramDIE) 366 SubprogramDIE.getInlinedChainForAddress(Address, InlinedChain); 367 else 368 InlinedChain.clear(); 369 } 370 371 const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context, 372 DWARFSectionKind Kind) { 373 if (Kind == DW_SECT_INFO) 374 return Context.getCUIndex(); 375 assert(Kind == DW_SECT_TYPES); 376 return Context.getTUIndex(); 377 } 378 379 DWARFDie DWARFUnit::getParent(const DWARFDebugInfoEntry *Die) { 380 if (!Die) 381 return DWARFDie(); 382 const uint32_t Depth = Die->getDepth(); 383 // Unit DIEs always have a depth of zero and never have parents. 384 if (Depth == 0) 385 return DWARFDie(); 386 // Depth of 1 always means parent is the compile/type unit. 387 if (Depth == 1) 388 return getUnitDIE(); 389 // Look for previous DIE with a depth that is one less than the Die's depth. 390 const uint32_t ParentDepth = Depth - 1; 391 for (uint32_t I = getDIEIndex(Die) - 1; I > 0; --I) { 392 if (DieArray[I].getDepth() == ParentDepth) 393 return DWARFDie(this, &DieArray[I]); 394 } 395 return DWARFDie(); 396 } 397 398 DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) { 399 if (!Die) 400 return DWARFDie(); 401 uint32_t Depth = Die->getDepth(); 402 // Unit DIEs always have a depth of zero and never have siblings. 403 if (Depth == 0) 404 return DWARFDie(); 405 // NULL DIEs don't have siblings. 406 if (Die->getAbbreviationDeclarationPtr() == nullptr) 407 return DWARFDie(); 408 409 // Find the next DIE whose depth is the same as the Die's depth. 410 for (size_t I=getDIEIndex(Die)+1, EndIdx = DieArray.size(); I<EndIdx; ++I) { 411 if (DieArray[I].getDepth() == Depth) 412 return DWARFDie(this, &DieArray[I]); 413 } 414 return DWARFDie(); 415 } 416 417 } // end namespace llvm 418