bool DWARFUnit::parseDWO() { if (DWO.get()) return false; extractDIEsIfNeeded(true); if (DieArray.empty()) return false; const char *DWOFileName = DieArray[0].getAttributeValueAsString(this, DW_AT_GNU_dwo_name, nullptr); if (!DWOFileName) return false; const char *CompilationDir = DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, nullptr); SmallString<16> AbsolutePath; if (sys::path::is_relative(DWOFileName) && CompilationDir != nullptr) { sys::path::append(AbsolutePath, CompilationDir); } sys::path::append(AbsolutePath, DWOFileName); DWO = llvm::make_unique<DWOHolder>(AbsolutePath); DWARFUnit *DWOCU = DWO->getUnit(); // Verify that compile unit in .dwo file is valid. if (!DWOCU || DWOCU->getDWOId() != getDWOId()) { DWO.reset(); return false; } // Share .debug_addr and .debug_ranges section with compile unit in .dwo DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase); uint32_t DWORangesBase = DieArray[0].getRangesBaseAttribute(this, 0); DWOCU->setRangesSection(RangeSection, DWORangesBase); return true; }
bool DWARFUnit::parseDWO() { if (DWO.get() != 0) return false; extractDIEsIfNeeded(true); if (DieArray.empty()) return false; const char *DWOFileName = DieArray[0].getAttributeValueAsString(this, DW_AT_GNU_dwo_name, 0); if (DWOFileName == 0) return false; const char *CompilationDir = DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, 0); SmallString<16> AbsolutePath; if (sys::path::is_relative(DWOFileName) && CompilationDir != 0) { sys::path::append(AbsolutePath, CompilationDir); } sys::path::append(AbsolutePath, DWOFileName); ErrorOr<object::ObjectFile *> DWOFile = object::ObjectFile::createObjectFile(AbsolutePath); if (!DWOFile) return false; // Reset DWOHolder. DWO.reset(new DWOHolder(DWOFile.get())); DWARFUnit *DWOCU = DWO->getUnit(); // Verify that compile unit in .dwo file is valid. if (DWOCU == 0 || DWOCU->getDWOId() != getDWOId()) { DWO.reset(); return false; } // Share .debug_addr and .debug_ranges section with compile unit in .dwo DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase); DWOCU->setRangesSection(RangeSection, RangeSectionBase); return true; }