Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
    const uint32_t DIEOffset, const dwarf::Attribute Attr,
    const DWARFUnit &U) const {
  Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
  if (!MatchAttrIndex)
    return None;

  auto DebugInfoData = U.getDebugInfoExtractor();

  // Add the byte size of ULEB that for the abbrev Code so we can start
  // skipping the attribute data.
  uint32_t Offset = DIEOffset + CodeByteSize;
  uint32_t AttrIndex = 0;
  for (const auto &Spec : AttributeSpecs) {
    if (*MatchAttrIndex == AttrIndex) {
      // We have arrived at the attribute to extract, extract if from Offset.
      DWARFFormValue FormValue(Spec.Form);
      if (FormValue.extractValue(DebugInfoData, &Offset, &U))
        return FormValue;
    }
    // March Offset along until we get to the attribute we want.
    if (Optional<uint8_t> FixedSize = Spec.getByteSize(U))
      Offset += *FixedSize;
    else
      DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset, &U);
    ++AttrIndex;
  }
  return None;
}
Пример #2
0
bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U,
                                             uint32_t *OffsetPtr) {
  DataExtractor DebugInfoData = U.getDebugInfoExtractor();
  const uint32_t UEndOffset = U.getNextUnitOffset();
  return extractFast(U, OffsetPtr, DebugInfoData, UEndOffset, 0);
}
Пример #3
0
static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
                          uint32_t *OffsetPtr, dwarf::Attribute Attr,
                          dwarf::Form Form, unsigned Indent) {
  if (!Die.isValid())
    return;
  const char BaseIndent[] = "            ";
  OS << BaseIndent;
  OS.indent(Indent+2);
  auto attrString = AttributeString(Attr);
  if (!attrString.empty())
    WithColor(OS, syntax::Attribute) << attrString;
  else
    WithColor(OS, syntax::Attribute).get() << format("DW_AT_Unknown_%x", Attr);
  
  auto formString = FormEncodingString(Form);
  if (!formString.empty())
    OS << " [" << formString << ']';
  else
    OS << format(" [DW_FORM_Unknown_%x]", Form);
  
  DWARFUnit *U = Die.getDwarfUnit();
  DWARFFormValue formValue(Form);
  
  if (!formValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr, U))
    return;
  
  OS << "\t(";
  
  StringRef Name;
  std::string File;
  auto Color = syntax::Enumerator;
  if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) {
    Color = syntax::String;
    if (const auto *LT = U->getContext().getLineTableForUnit(U))
      if (LT->getFileNameByIndex(formValue.getAsUnsignedConstant().getValue(), U->getCompilationDir(), DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
        File = '"' + File + '"';
        Name = File;
      }
  } else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant())
    Name = AttributeValueString(Attr, *Val);
  
  if (!Name.empty())
    WithColor(OS, Color) << Name;
  else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line)
    OS << *formValue.getAsUnsignedConstant();
  else
    formValue.dump(OS);
  
  // We have dumped the attribute raw value. For some attributes
  // having both the raw value and the pretty-printed value is
  // interesting. These attributes are handled below.
  if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) {
    if (const char *Name = Die.getAttributeValueAsReferencedDie(Attr).getName(DINameKind::LinkageName))
        OS << " \"" << Name << '\"';
  } else if (Attr == DW_AT_APPLE_property_attribute) {
    if (Optional<uint64_t> OptVal = formValue.getAsUnsignedConstant())
      dumpApplePropertyAttribute(OS, *OptVal);
  } else if (Attr == DW_AT_ranges) {
    dumpRanges(OS, Die.getAddressRanges(), U->getAddressByteSize(),
               sizeof(BaseIndent)+Indent+4);
  }
  
  OS << ")\n";
}
Пример #4
0
static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
                          uint32_t *OffsetPtr, dwarf::Attribute Attr,
                          dwarf::Form Form, unsigned Indent,
                          DIDumpOptions DumpOpts) {
  if (!Die.isValid())
    return;
  const char BaseIndent[] = "            ";
  OS << BaseIndent;
  OS.indent(Indent + 2);
  auto attrString = AttributeString(Attr);
  if (!attrString.empty())
    WithColor(OS, HighlightColor::Attribute) << attrString;
  else
    WithColor(OS, HighlightColor::Attribute).get()
        << format("DW_AT_Unknown_%x", Attr);

  if (DumpOpts.Verbose || DumpOpts.ShowForm) {
    auto formString = FormEncodingString(Form);
    if (!formString.empty())
      OS << " [" << formString << ']';
    else
      OS << format(" [DW_FORM_Unknown_%x]", Form);
  }

  DWARFUnit *U = Die.getDwarfUnit();
  DWARFFormValue formValue(Form);

  if (!formValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr,
                              U->getFormParams(), U))
    return;

  OS << "\t(";

  StringRef Name;
  std::string File;
  auto Color = HighlightColor::Enumerator;
  if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) {
    Color = HighlightColor::String;
    if (const auto *LT = U->getContext().getLineTableForUnit(U))
      if (LT->getFileNameByIndex(
              formValue.getAsUnsignedConstant().getValue(),
              U->getCompilationDir(),
              DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
        File = '"' + File + '"';
        Name = File;
      }
  } else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant())
    Name = AttributeValueString(Attr, *Val);

  if (!Name.empty())
    WithColor(OS, Color) << Name;
  else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line)
    OS << *formValue.getAsUnsignedConstant();
  else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose &&
           formValue.getAsUnsignedConstant()) {
    if (DumpOpts.ShowAddresses) {
      // Print the actual address rather than the offset.
      uint64_t LowPC, HighPC, Index;
      if (Die.getLowAndHighPC(LowPC, HighPC, Index))
        OS << format("0x%016" PRIx64, HighPC);
      else
        formValue.dump(OS, DumpOpts);
    }
  } else if (Attr == DW_AT_location || Attr == DW_AT_frame_base ||
             Attr == DW_AT_data_member_location ||
             Attr == DW_AT_GNU_call_site_value)
    dumpLocation(OS, formValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts);
  else
    formValue.dump(OS, DumpOpts);

  // We have dumped the attribute raw value. For some attributes
  // having both the raw value and the pretty-printed value is
  // interesting. These attributes are handled below.
  if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) {
    if (const char *Name = Die.getAttributeValueAsReferencedDie(Attr).getName(
            DINameKind::LinkageName))
      OS << " \"" << Name << '\"';
  } else if (Attr == DW_AT_type) {
    OS << " \"";
    dumpTypeName(OS, Die);
    OS << '"';
  } else if (Attr == DW_AT_APPLE_property_attribute) {
    if (Optional<uint64_t> OptVal = formValue.getAsUnsignedConstant())
      dumpApplePropertyAttribute(OS, *OptVal);
  } else if (Attr == DW_AT_ranges) {
    const DWARFObject &Obj = Die.getDwarfUnit()->getContext().getDWARFObj();
    dumpRanges(Obj, OS, Die.getAddressRanges(), U->getAddressByteSize(),
               sizeof(BaseIndent) + Indent + 4, DumpOpts);
  }

  OS << ")\n";
}