コード例 #1
0
ファイル: CompileUnit.cpp プロジェクト: jvesely/llvm
uint16_t CompileUnit::getLanguage() {
  if (!Language) {
    DWARFDie CU = getOrigUnit().getUnitDIE();
    Language = dwarf::toUnsigned(CU.find(dwarf::DW_AT_language), 0);
  }
  return Language;
}
コード例 #2
0
ファイル: DWARFUnit.cpp プロジェクト: earl/llvm-mirror
size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
  if ((CUDieOnly && !DieArray.empty()) ||
      DieArray.size() > 1)
    return 0; // Already parsed.

  bool HasCUDie = !DieArray.empty();
  extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);

  if (DieArray.empty())
    return 0;

  // If CU DIE was just parsed, copy several attribute values from it.
  if (!HasCUDie) {
    DWARFDie UnitDie = getUnitDIE();
    auto BaseAddr = UnitDie.getAttributeValueAsAddress(DW_AT_low_pc);
    if (!BaseAddr)
      BaseAddr = UnitDie.getAttributeValueAsAddress(DW_AT_entry_pc);
    if (BaseAddr)
      setBaseAddress(*BaseAddr);
    AddrOffsetSectionBase = UnitDie.getAttributeValueAsSectionOffset(
        DW_AT_GNU_addr_base, 0);
    RangeSectionBase = UnitDie.getAttributeValueAsSectionOffset(
        DW_AT_rnglists_base, 0);
    // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
    // skeleton CU DIE, so that DWARF users not aware of it are not broken.
  }

  return DieArray.size();
}
コード例 #3
0
ファイル: DWARFUnit.cpp プロジェクト: Lucretia/llvm
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);
}
コード例 #4
0
ファイル: DWARFUnit.cpp プロジェクト: earl/llvm-mirror
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;
}
コード例 #5
0
ファイル: DWARFUnit.cpp プロジェクト: cambridgehackers/llvm
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;
}
コード例 #6
0
void DWARFTypeUnit::dump(raw_ostream &OS, bool SummarizeTypes) {
  DWARFDie TD = getDIEForOffset(TypeOffset + getOffset());
  const char *Name = TD.getName(DINameKind::ShortName);

  if (SummarizeTypes) {
    OS << "name = '" << Name << "'"
       << " type_signature = " << format("0x%16" PRIx64, TypeHash)
       << " length = " << format("0x%08x", getLength()) << '\n';
    return;
  }

  OS << format("0x%08x", getOffset()) << ": Type Unit:"
     << " length = " << format("0x%08x", getLength())
     << " version = " << format("0x%04x", getVersion())
     << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset())
     << " addr_size = " << format("0x%02x", getAddressByteSize())
     << " name = '" << Name << "'"
     << " type_signature = " << format("0x%16" PRIx64, TypeHash)
     << " type_offset = " << format("0x%04x", TypeOffset)
     << " (next unit at " << format("0x%08x", getNextUnitOffset()) << ")\n";

  if (DWARFDie TU = getUnitDIE(false))
    TU.dump(OS, -1U);
  else
    OS << "<type unit can't be parsed!>\n\n";
}
コード例 #7
0
/// Print only DIEs that have a certain name.
static void filterByName(const StringSet<> &Names,
                         DWARFContext::cu_iterator_range CUs, raw_ostream &OS) {
  for (const auto &CU : CUs)
    for (const auto &Entry : CU->dies()) {
      DWARFDie Die = {CU.get(), &Entry};
      if (const char *NamePtr = Die.getName(DINameKind::ShortName)) {
        std::string Name =
            (IgnoreCase && !UseRegex) ? StringRef(NamePtr).lower() : NamePtr;
        // Match regular expression.
        if (UseRegex)
          for (auto Pattern : Names.keys()) {
            Regex RE(Pattern, IgnoreCase ? Regex::IgnoreCase : Regex::NoFlags);
            std::string Error;
            if (!RE.isValid(Error)) {
              errs() << "error in regular expression: " << Error << "\n";
              exit(1);
            }
            if (RE.match(Name))
              Die.dump(OS, 0, getDumpOpts());
          }
        // Match full text.
        else if (Names.count(Name))
          Die.dump(OS, 0, getDumpOpts());
      }
    }

}
コード例 #8
0
ファイル: DWARFVerifier.cpp プロジェクト: Lucretia/llvm
static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) {
  Optional<DWARFFormValue> Location = Die.findRecursively(DW_AT_location);
  if (!Location)
    return false;

  auto ContainsInterestingOperators = [&](StringRef D) {
    DWARFUnit *U = Die.getDwarfUnit();
    DataExtractor Data(D, DCtx.isLittleEndian(), U->getAddressByteSize());
    DWARFExpression Expression(Data, U->getVersion(), U->getAddressByteSize());
    return any_of(Expression, [](DWARFExpression::Operation &Op) {
      return !Op.isError() && (Op.getCode() == DW_OP_addr ||
                               Op.getCode() == DW_OP_form_tls_address ||
                               Op.getCode() == DW_OP_GNU_push_tls_address);
    });
  };

  if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) {
    // Inlined location.
    if (ContainsInterestingOperators(toStringRef(*Expr)))
      return true;
  } else if (Optional<uint64_t> Offset = Location->getAsSectionOffset()) {
    // Location list.
    if (const DWARFDebugLoc *DebugLoc = DCtx.getDebugLoc()) {
      if (const DWARFDebugLoc::LocationList *LocList =
              DebugLoc->getLocationListAtOffset(*Offset)) {
        if (any_of(LocList->Entries, [&](const DWARFDebugLoc::Entry &E) {
              return ContainsInterestingOperators({E.Loc.data(), E.Loc.size()});
            }))
          return true;
      }
    }
  }
  return false;
}
コード例 #9
0
ファイル: DWARFUnit.cpp プロジェクト: earl/llvm-mirror
void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
  DWARFDie UnitDie = getUnitDIE();
  if (!UnitDie)
    return;
  // First, check if unit DIE describes address ranges for the whole unit.
  const auto &CUDIERanges = UnitDie.getAddressRanges();
  if (!CUDIERanges.empty()) {
    CURanges.insert(CURanges.end(), CUDIERanges.begin(), CUDIERanges.end());
    return;
  }

  // This function is usually called if there in no .debug_aranges section
  // in order to produce a compile unit level set of address ranges that
  // is accurate. If the DIEs weren't parsed, then we don't want all dies for
  // all compile units to stay loaded when they weren't needed. So we can end
  // up parsing the DWARF and then throwing them all away to keep memory usage
  // down.
  const bool ClearDIEs = extractDIEsIfNeeded(false) > 1;
  getUnitDIE().collectChildrenAddressRanges(CURanges);

  // Collect address ranges from DIEs in .dwo if necessary.
  bool DWOCreated = parseDWO();
  if (DWO.get())
    DWO->getUnit()->collectAddressRanges(CURanges);
  if (DWOCreated)
    DWO.reset();

  // Keep memory down by clearing DIEs if this generate function
  // caused them to be parsed.
  if (ClearDIEs)
    clearDIEs(true);
}
コード例 #10
0
ファイル: DWARFDie.cpp プロジェクト: bugsnag/llvm
void DWARFDie::getInlinedChainForAddress(
    const uint64_t Address, SmallVectorImpl<DWARFDie> &InlinedChain) const {
  if (isNULL())
    return;
  DWARFDie DIE(*this);
  while (DIE) {
    // Append current DIE to inlined chain only if it has correct tag
    // (e.g. it is not a lexical block).
    if (DIE.isSubroutineDIE())
      InlinedChain.push_back(DIE);

    // Try to get child which also contains provided address.
    DWARFDie Child = DIE.getFirstChild();
    while (Child) {
      if (Child.addressRangeContainsAddress(Address)) {
        // Assume there is only one such child.
        break;
      }
      Child = Child.getSibling();
    }
    DIE = Child;
  }
  // Reverse the obtained chain to make the root of inlined chain last.
  std::reverse(InlinedChain.begin(), InlinedChain.end());
}
コード例 #11
0
ファイル: DWARFDie.cpp プロジェクト: jvesely/llvm
Optional<DWARFFormValue>
DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {
  std::vector<DWARFDie> Worklist;
  Worklist.push_back(*this);

  // Keep track if DIEs already seen to prevent infinite recursion.
  // Empirically we rarely see a depth of more than 3 when dealing with valid
  // DWARF. This corresponds to following the DW_AT_abstract_origin and
  // DW_AT_specification just once.
  SmallSet<DWARFDie, 3> Seen;
  Seen.insert(*this);

  while (!Worklist.empty()) {
    DWARFDie Die = Worklist.back();
    Worklist.pop_back();

    if (!Die.isValid())
      continue;

    if (auto Value = Die.find(Attrs))
      return Value;

    if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
      if (Seen.insert(D).second)
        Worklist.push_back(D);

    if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification))
      if (Seen.insert(D).second)
        Worklist.push_back(D);
  }

  return None;
}
コード例 #12
0
ファイル: DWARFDie.cpp プロジェクト: jvesely/llvm
/// Helper to dump a DIE with all of its parents, but no siblings.
static unsigned dumpParentChain(DWARFDie Die, raw_ostream &OS, unsigned Indent,
                                DIDumpOptions DumpOpts) {
  if (!Die)
    return Indent;
  Indent = dumpParentChain(Die.getParent(), OS, Indent, DumpOpts);
  Die.dump(OS, Indent, DumpOpts);
  return Indent + 2;
}
コード例 #13
0
ファイル: utils.cpp プロジェクト: sdasgup3/compilers
void DwarfVariableFinder::getInfo(const DWARFDie &die) {
  auto tagString = TagString(die.getTag());
  if (tagString.empty()) {
    outs() << format("DW_TAG_Unknown_%x", die.getTag());
  }
  auto formVal = die.find(dwarf::DW_AT_name);
  formVal->dump(outs());
}
コード例 #14
0
ファイル: DWARFVerifier.cpp プロジェクト: franchiotta/llvm
unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
                                        DieRangeInfo &ParentRI) {
  unsigned NumErrors = 0;

  if (!Die.isValid())
    return NumErrors;

  DWARFAddressRangesVector Ranges = Die.getAddressRanges();

  // Build RI for this DIE and check that ranges within this DIE do not
  // overlap.
  DieRangeInfo RI(Die);
  for (auto Range : Ranges) {
    if (!Range.valid()) {
      ++NumErrors;
      error() << "Invalid address range " << Range << "\n";
      continue;
    }

    // Verify that ranges don't intersect.
    const auto IntersectingRange = RI.insert(Range);
    if (IntersectingRange != RI.Ranges.end()) {
      ++NumErrors;
      error() << "DIE has overlapping address ranges: " << Range << " and "
              << *IntersectingRange << "\n";
      break;
    }
  }

  // Verify that children don't intersect.
  const auto IntersectingChild = ParentRI.insert(RI);
  if (IntersectingChild != ParentRI.Children.end()) {
    ++NumErrors;
    error() << "DIEs have overlapping address ranges:";
    Die.dump(OS, 0);
    IntersectingChild->Die.dump(OS, 0);
    OS << "\n";
  }

  // Verify that ranges are contained within their parent.
  bool ShouldBeContained = !Ranges.empty() && !ParentRI.Ranges.empty() &&
                           !(Die.getTag() == DW_TAG_subprogram &&
                             ParentRI.Die.getTag() == DW_TAG_subprogram);
  if (ShouldBeContained && !ParentRI.contains(RI)) {
    ++NumErrors;
    error() << "DIE address ranges are not "
               "contained in its parent's ranges:";
    Die.dump(OS, 0);
    ParentRI.Die.dump(OS, 0);
    OS << "\n";
  }

  // Recursively check children.
  for (DWARFDie Child : Die)
    NumErrors += verifyDieRanges(Child, RI);

  return NumErrors;
}
コード例 #15
0
ファイル: DWARFUnit.cpp プロジェクト: MatzeB/llvm
llvm::Optional<SectionedAddress> DWARFUnit::getBaseAddress() {
  if (BaseAddr)
    return BaseAddr;

  DWARFDie UnitDie = getUnitDIE();
  Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
  BaseAddr = toSectionedAddress(PC);
  return BaseAddr;
}
コード例 #16
0
ファイル: DWARFVerifier.cpp プロジェクト: BNieuwenhuizen/llvm
unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
                                                 DWARFAttribute &AttrValue) {
  unsigned NumErrors = 0;
  auto ReportError = [&](const Twine &TitleMsg) {
    ++NumErrors;
    error() << TitleMsg << '\n';
    Die.dump(OS, 0, DumpOpts);
    OS << "\n";
  };

  const DWARFObject &DObj = DCtx.getDWARFObj();
  const auto Attr = AttrValue.Attr;
  switch (Attr) {
  case DW_AT_ranges:
    // Make sure the offset in the DW_AT_ranges attribute is valid.
    if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
      if (*SectionOffset >= DObj.getRangeSection().Data.size())
        ReportError("DW_AT_ranges offset is beyond .debug_ranges bounds:");
      break;
    }
    ReportError("DIE has invalid DW_AT_ranges encoding:");
    break;
  case DW_AT_stmt_list:
    // Make sure the offset in the DW_AT_stmt_list attribute is valid.
    if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
      if (*SectionOffset >= DObj.getLineSection().Data.size())
        ReportError("DW_AT_stmt_list offset is beyond .debug_line bounds: " +
                    llvm::formatv("{0:x8}", *SectionOffset));
      break;
    }
    ReportError("DIE has invalid DW_AT_stmt_list encoding:");
    break;
  case DW_AT_location: {
    Optional<ArrayRef<uint8_t>> Expr = AttrValue.Value.getAsBlock();
    if (!Expr) {
      ReportError("DIE has invalid DW_AT_location encoding:");
      break;
    }

    DWARFUnit *U = Die.getDwarfUnit();
    DataExtractor Data(
        StringRef(reinterpret_cast<const char *>(Expr->data()), Expr->size()),
        DCtx.isLittleEndian(), 0);
    DWARFExpression Expression(Data, U->getVersion(), U->getAddressByteSize());
    bool Error = llvm::any_of(Expression, [](DWARFExpression::Operation &Op) {
      return Op.isError();
    });
    if (Error)
      ReportError("DIE contains invalid DWARF expression:");
    break;
  }

  default:
    break;
  }
  return NumErrors;
}
コード例 #17
0
ファイル: DWARFUnit.cpp プロジェクト: Lucretia/llvm
llvm::Optional<BaseAddress> DWARFUnit::getBaseAddress() {
  if (BaseAddr)
    return BaseAddr;

  DWARFDie UnitDie = getUnitDIE();
  Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
  if (Optional<uint64_t> Addr = toAddress(PC))
    BaseAddr = {*Addr, PC->getSectionIndex()};

  return BaseAddr;
}
コード例 #18
0
ファイル: DWARFDie.cpp プロジェクト: bugsnag/llvm
void DWARFDie::dump(raw_ostream &OS, unsigned RecurseDepth,
                    unsigned Indent) const {
  if (!isValid())
    return;
  DataExtractor debug_info_data = U->getDebugInfoExtractor();
  const uint32_t Offset = getOffset();
  uint32_t offset = Offset;
  
  if (debug_info_data.isValidOffset(offset)) {
    uint32_t abbrCode = debug_info_data.getULEB128(&offset);
    WithColor(OS, syntax::Address).get() << format("\n0x%8.8x: ", Offset);
    
    if (abbrCode) {
      auto AbbrevDecl = getAbbreviationDeclarationPtr();
      if (AbbrevDecl) {
        auto tagString = TagString(getTag());
        if (!tagString.empty())
          WithColor(OS, syntax::Tag).get().indent(Indent) << tagString;
        else
          WithColor(OS, syntax::Tag).get().indent(Indent)
          << format("DW_TAG_Unknown_%x", getTag());
        
        OS << format(" [%u] %c\n", abbrCode,
                     AbbrevDecl->hasChildren() ? '*' : ' ');
        
        // Dump all data in the DIE for the attributes.
        for (const auto &AttrSpec : AbbrevDecl->attributes()) {
          if (AttrSpec.Form == DW_FORM_implicit_const) {
            // We are dumping .debug_info section ,
            // implicit_const attribute values are not really stored here,
            // but in .debug_abbrev section. So we just skip such attrs.
            continue;
          }
          dumpAttribute(OS, *this, &offset, AttrSpec.Attr, AttrSpec.Form,
                        Indent);
        }
        
        DWARFDie child = getFirstChild();
        if (RecurseDepth > 0 && child) {
          while (child) {
            child.dump(OS, RecurseDepth-1, Indent+2);
            child = child.getSibling();
          }
        }
      } else {
        OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
        << abbrCode << '\n';
      }
    } else {
      OS.indent(Indent) << "NULL\n";
    }
  }
}
コード例 #19
0
ファイル: DWARFUnit.cpp プロジェクト: Lucretia/llvm
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;
}
コード例 #20
0
ファイル: DWARFDie.cpp プロジェクト: franchiotta/llvm
/// Recursively dump the DIE type name when applicable.
static void dumpTypeName(raw_ostream &OS, const DWARFDie &Die) {
  DWARFDie D = Die.getAttributeValueAsReferencedDie(DW_AT_type);

  if (!D.isValid())
    return;

  if (const char *Name = D.getName(DINameKind::LinkageName)) {
    OS << Name;
    return;
  }

  // FIXME: We should have pretty printers per language. Currently we print
  // everything as if it was C++ and fall back to the TAG type name.
  const dwarf::Tag T = D.getTag();
  switch (T) {
  case DW_TAG_array_type:
  case DW_TAG_pointer_type:
  case DW_TAG_ptr_to_member_type:
  case DW_TAG_reference_type:
  case DW_TAG_rvalue_reference_type:
    break;
  default:
    dumpTypeTagName(OS, T);
  }

  // Follow the DW_AT_type if possible.
  dumpTypeName(OS, D);

  switch (T) {
  case DW_TAG_array_type:
    OS << "[]";
    break;
  case DW_TAG_pointer_type:
    OS << '*';
    break;
  case DW_TAG_ptr_to_member_type:
    OS << '*';
    break;
  case DW_TAG_reference_type:
    OS << '&';
    break;
  case DW_TAG_rvalue_reference_type:
    OS << "&&";
    break;
  default:
    break;
  }
}
コード例 #21
0
ファイル: utils.cpp プロジェクト: sdasgup3/compilers
std::shared_ptr<TypeInfo> DwarfVariableFinder::getType(const DWARFDie &die) {

  if (!die.isValid()) {
    assert(0);
    return std::make_shared<TypeInfo>("", ~0u);
  }

  auto die_offset = die.getOffset();  
  if(typeDict.count(die_offset)) {
    return typeDict[die_offset];
  }

  auto result = makeType(die);
  typeDict[die_offset] = result;
  return result;
}
コード例 #22
0
ファイル: utils.cpp プロジェクト: sdasgup3/compilers
void DwarfVariableFinder::handleVariable(const DWARFDie &die) {
  //die.dump(outs(), 10);
  getInfo(die);
  auto type = getType(die.getAttributeValueAsReferencedDie(dwarf::DW_AT_type));
  type->dump(outs());

}
コード例 #23
0
ファイル: DWARFVerifier.cpp プロジェクト: dstep/llvm
unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
                                                 DWARFAttribute &AttrValue) {
  const DWARFObject &DObj = DCtx.getDWARFObj();
  unsigned NumErrors = 0;
  const auto Attr = AttrValue.Attr;
  switch (Attr) {
  case DW_AT_ranges:
    // Make sure the offset in the DW_AT_ranges attribute is valid.
    if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
      if (*SectionOffset >= DObj.getRangeSection().Data.size()) {
        ++NumErrors;
        OS << "error: DW_AT_ranges offset is beyond .debug_ranges "
              "bounds:\n";
        Die.dump(OS, 0);
        OS << "\n";
      }
    } else {
      ++NumErrors;
      OS << "error: DIE has invalid DW_AT_ranges encoding:\n";
      Die.dump(OS, 0);
      OS << "\n";
    }
    break;
  case DW_AT_stmt_list:
    // Make sure the offset in the DW_AT_stmt_list attribute is valid.
    if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
      if (*SectionOffset >= DObj.getLineSection().Data.size()) {
        ++NumErrors;
        OS << "error: DW_AT_stmt_list offset is beyond .debug_line "
              "bounds: "
           << format("0x%08" PRIx64, *SectionOffset) << "\n";
        Die.dump(OS, 0);
        OS << "\n";
      }
    } else {
      ++NumErrors;
      OS << "error: DIE has invalid DW_AT_stmt_list encoding:\n";
      Die.dump(OS, 0);
      OS << "\n";
    }
    break;

  default:
    break;
  }
  return NumErrors;
}
コード例 #24
0
ファイル: llvm-dwarfdump.cpp プロジェクト: crabtw/llvm
/// Print only DIEs that have a certain name.
static void filterByAccelName(ArrayRef<std::string> Names, DWARFContext &DICtx,
                              raw_ostream &OS) {
  SmallVector<uint64_t, 4> Offsets;
  for (const auto &Name : Names) {
    getDIEOffset(DICtx.getAppleNames(), Name, Offsets);
    getDIEOffset(DICtx.getAppleTypes(), Name, Offsets);
    getDIEOffset(DICtx.getAppleNamespaces(), Name, Offsets);
    getDIEOffset(DICtx.getDebugNames(), Name, Offsets);
  }
  llvm::sort(Offsets.begin(), Offsets.end());
  Offsets.erase(std::unique(Offsets.begin(), Offsets.end()), Offsets.end());

  for (uint64_t Off: Offsets) {
    DWARFDie Die = DICtx.getDIEForOffset(Off);
    Die.dump(OS, 0, getDumpOpts());
  }
}
コード例 #25
0
ファイル: DWARFVerifier.cpp プロジェクト: Lucretia/llvm
static SmallVector<StringRef, 2> getNames(const DWARFDie &DIE,
                                          bool IncludeLinkageName = true) {
  SmallVector<StringRef, 2> Result;
  if (const char *Str = DIE.getName(DINameKind::ShortName))
    Result.emplace_back(Str);
  else if (DIE.getTag() == dwarf::DW_TAG_namespace)
    Result.emplace_back("(anonymous namespace)");

  if (IncludeLinkageName) {
    if (const char *Str = DIE.getName(DINameKind::LinkageName)) {
      if (Result.empty() || Result[0] != Str)
        Result.emplace_back(Str);
    }
  }

  return Result;
}
コード例 #26
0
ファイル: DWARFUnit.cpp プロジェクト: cambridgehackers/llvm
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();
  }
}
コード例 #27
0
ファイル: DWARFDie.cpp プロジェクト: jvesely/llvm
static void dumpArrayType(raw_ostream &OS, const DWARFDie &D) {
  Optional<uint64_t> Bound;
  for (const DWARFDie &C : D.children())
    if (C.getTag() == DW_TAG_subrange_type) {
      Optional<uint64_t> LB;
      Optional<uint64_t> Count;
      Optional<uint64_t> UB;
      Optional<unsigned> DefaultLB;
      if (Optional<DWARFFormValue> L = C.find(DW_AT_lower_bound))
        LB = L->getAsUnsignedConstant();
      if (Optional<DWARFFormValue> CountV = C.find(DW_AT_count))
        Count = CountV->getAsUnsignedConstant();
      if (Optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound))
        UB = UpperV->getAsUnsignedConstant();
      if (Optional<DWARFFormValue> LV =
              D.getDwarfUnit()->getUnitDIE().find(DW_AT_language))
        if (Optional<uint64_t> LC = LV->getAsUnsignedConstant())
          if ((DefaultLB =
                   LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC))))
            if (LB && *LB == *DefaultLB)
              LB = None;
      if (!LB && !Count && !UB)
        OS << "[]";
      else if (!LB && (Count || UB) && DefaultLB)
        OS << '[' << (Count ? *Count : *UB - *DefaultLB + 1) << ']';
      else {
        OS << "[[";
        if (LB)
          OS << *LB;
        else
          OS << '?';
        OS << ", ";
        if (Count)
          if (LB)
            OS << *LB + *Count;
          else
            OS << "? + " << *Count;
        else if (UB)
          OS << *UB + 1;
        else
          OS << '?';
        OS << ")]";
      }
    }
}
コード例 #28
0
ファイル: DWARFUnit.cpp プロジェクト: earl/llvm-mirror
void
DWARFUnit::getInlinedChainForAddress(uint64_t Address,
                                     SmallVectorImpl<DWARFDie> &InlinedChain) {
  // First, find a subprogram that contains the given address (the root
  // of inlined chain).
  DWARFDie SubprogramDIE;
  // Try to look for subprogram DIEs in the DWO file.
  parseDWO();
  if (DWO)
    SubprogramDIE = DWO->getUnit()->getSubprogramForAddress(Address);
  else
    SubprogramDIE = getSubprogramForAddress(Address);

  // Get inlined chain rooted at this subprogram DIE.
  if (SubprogramDIE)
    SubprogramDIE.getInlinedChainForAddress(Address, InlinedChain);
  else
    InlinedChain.clear();
}
コード例 #29
0
ファイル: utils.cpp プロジェクト: sdasgup3/compilers
DwarfVariableFinder::DwarfVariableFinder(const DWARFDie &die, raw_ostream &os) : OS(os) {
  if(!die.hasChildren()) {
    outs() << "No child \n\n";
    return;
  }

  for (auto child = die.getFirstChild(); child; child = child.getSibling()) {
    //Go over all the top level sub_programs
    if(child.isSubprogramDIE() || child.isSubroutineDIE()) {
      getInfo(child);

      //Look for variables among children of sub_program die
      if(!child.hasChildren()) {
        continue;
      }
      findVariables(child);
    }
  }
}
コード例 #30
0
ファイル: DWARFUnit.cpp プロジェクト: cambridgehackers/llvm
size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
  if ((CUDieOnly && !DieArray.empty()) ||
      DieArray.size() > 1)
    return 0; // Already parsed.

  bool HasCUDie = !DieArray.empty();
  extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);

  if (DieArray.empty())
    return 0;

  // If CU DIE was just parsed, copy several attribute values from it.
  if (!HasCUDie) {
    DWARFDie UnitDie = getUnitDIE();
    Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
    if (Optional<uint64_t> Addr = toAddress(PC))
        setBaseAddress({*Addr, PC->getSectionIndex()});

    if (!isDWO) {
      assert(AddrOffsetSectionBase == 0);
      assert(RangeSectionBase == 0);
      AddrOffsetSectionBase =
          toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);
      RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
    }

    // In general, we derive the offset of the unit's contibution to the
    // debug_str_offsets{.dwo} section from the unit DIE's
    // DW_AT_str_offsets_base attribute. In dwp files we add to it the offset
    // we get from the index table.
    StringOffsetSectionBase =
        toSectionOffset(UnitDie.find(DW_AT_str_offsets_base), 0);
    if (IndexEntry)
      if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
        StringOffsetSectionBase += C->Offset;

    // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
    // skeleton CU DIE, so that DWARF users not aware of it are not broken.
  }

  return DieArray.size();
}