Example #1
0
bool DWARFUnit::parseDWO() {
  if (isDWO)
    return false;
  if (DWO.get())
    return false;
  DWARFDie UnitDie = getUnitDIE();
  if (!UnitDie)
    return false;
  const char *DWOFileName =
      UnitDie.getAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr);
  if (!DWOFileName)
    return false;
  const char *CompilationDir =
      UnitDie.getAttributeValueAsString(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);
  auto DWORangesBase = UnitDie.getRangesBaseAttribute();
  DWOCU->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);
  return true;
}
Example #2
0
bool DWARFUnit::parseDWO() {
  if (isDWO)
    return false;
  if (DWO.get())
    return false;
  DWARFDie UnitDie = getUnitDIE();
  if (!UnitDie)
    return false;
  auto DWOFileName = dwarf::toString(UnitDie.find(DW_AT_GNU_dwo_name));
  if (!DWOFileName)
    return false;
  auto CompilationDir = dwarf::toString(UnitDie.find(DW_AT_comp_dir));
  SmallString<16> AbsolutePath;
  if (sys::path::is_relative(*DWOFileName) && CompilationDir &&
      *CompilationDir) {
    sys::path::append(AbsolutePath, *CompilationDir);
  }
  sys::path::append(AbsolutePath, *DWOFileName);
  auto DWOId = getDWOId();
  if (!DWOId)
    return false;
  auto DWOContext = Context.getDWOContext(AbsolutePath);
  if (!DWOContext)
    return false;

  DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId);
  if (!DWOCU)
    return false;
  DWO = std::shared_ptr<DWARFCompileUnit>(std::move(DWOContext), DWOCU);
  // Share .debug_addr and .debug_ranges section with compile unit in .dwo
  DWO->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
  auto DWORangesBase = UnitDie.getRangesBaseAttribute();
  DWO->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);
  return true;
}
Example #3
0
bool DWARFUnit::parseDWO() {
  if (isDWO)
    return false;
  if (DWO.get())
    return false;
  DWARFDie UnitDie = getUnitDIE();
  if (!UnitDie)
    return false;
  auto DWOFileName = dwarf::toString(UnitDie.find(DW_AT_GNU_dwo_name));
  if (!DWOFileName)
    return false;
  auto CompilationDir = dwarf::toString(UnitDie.find(DW_AT_comp_dir));
  SmallString<16> AbsolutePath;
  if (sys::path::is_relative(*DWOFileName) && CompilationDir &&
      *CompilationDir) {
    sys::path::append(AbsolutePath, *CompilationDir);
  }
  sys::path::append(AbsolutePath, *DWOFileName);
  auto DWOId = getDWOId();
  if (!DWOId)
    return false;
  auto DWOContext = Context.getDWOContext(AbsolutePath);
  if (!DWOContext)
    return false;

  DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId);
  if (!DWOCU)
    return false;
  DWO = std::shared_ptr<DWARFCompileUnit>(std::move(DWOContext), DWOCU);
  // Share .debug_addr and .debug_ranges section with compile unit in .dwo
  DWO->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
  if (getVersion() >= 5) {
    DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
    DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
                                isLittleEndian, 0);
    if (auto TableOrError = parseRngListTableHeader(RangesDA, RangeSectionBase))
      DWO->RngListTable = TableOrError.get();
    else
      WithColor::error() << "parsing a range list table: "
                         << toString(TableOrError.takeError())
                         << '\n';
    if (DWO->RngListTable)
      DWO->RangeSectionBase = DWO->RngListTable->getHeaderSize();
  } else {
    auto DWORangesBase = UnitDie.getRangesBaseAttribute();
    DWO->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);
  }

  return true;
}