LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFAbbreviationDeclaration.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 116 122 95.1 %
Date: 2017-09-14 15:23:50 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- DWARFAbbreviationDeclaration.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/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
      11             : 
      12             : #include "llvm/ADT/None.h"
      13             : #include "llvm/ADT/Optional.h"
      14             : #include "llvm/BinaryFormat/Dwarf.h"
      15             : #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
      16             : #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
      17             : #include "llvm/Support/DataExtractor.h"
      18             : #include "llvm/Support/Format.h"
      19             : #include "llvm/Support/raw_ostream.h"
      20             : #include <cstddef>
      21             : #include <cstdint>
      22             : 
      23             : using namespace llvm;
      24             : using namespace dwarf;
      25             : 
      26     8246193 : void DWARFAbbreviationDeclaration::clear() {
      27     8246193 :   Code = 0;
      28     8246193 :   Tag = DW_TAG_null;
      29     8246193 :   CodeByteSize = 0;
      30     8246193 :   HasChildren = false;
      31    16492386 :   AttributeSpecs.clear();
      32    16492386 :   FixedAttributeSize.reset();
      33     8246193 : }
      34             : 
      35       82758 : DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
      36       27586 :   clear();
      37       27586 : }
      38             : 
      39             : bool
      40     8218607 : DWARFAbbreviationDeclaration::extract(DataExtractor Data, 
      41             :                                       uint32_t* OffsetPtr) {
      42     8218607 :   clear();
      43     8218607 :   const uint32_t Offset = *OffsetPtr;
      44     8218607 :   Code = Data.getULEB128(OffsetPtr);
      45     8218607 :   if (Code == 0) {
      46             :     return false;
      47             :   }
      48     8191021 :   CodeByteSize = *OffsetPtr - Offset;
      49     8191021 :   Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
      50     8191021 :   if (Tag == DW_TAG_null) {
      51           0 :     clear();
      52           0 :     return false;
      53             :   }
      54     8191021 :   uint8_t ChildrenByte = Data.getU8(OffsetPtr);
      55     8191021 :   HasChildren = (ChildrenByte == DW_CHILDREN_yes);
      56             :   // Assign a value to our optional FixedAttributeSize member variable. If
      57             :   // this member variable still has a value after the while loop below, then
      58             :   // all attribute data in this abbreviation declaration has a fixed byte size.
      59     8191021 :   FixedAttributeSize = FixedSizeInfo();
      60             : 
      61             :   // Read all of the abbreviation attributes and forms.
      62             :   while (true) {
      63    54408031 :     auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
      64    54408031 :     auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
      65    54408031 :     if (A && F) {
      66    92434014 :       Optional<int64_t> V;
      67    46217010 :       bool IsImplicitConst = (F == DW_FORM_implicit_const);
      68    46217016 :       if (IsImplicitConst) {
      69          12 :         V = Data.getSLEB128(OffsetPtr);
      70          30 :         AttributeSpecs.push_back(AttributeSpec(A, F, V));
      71           6 :         continue;
      72             :       }
      73             :       // If this abbrevation still has a fixed byte size, then update the
      74             :       // FixedAttributeSize as needed.
      75    46217004 :       switch (F) {
      76      580584 :       case DW_FORM_addr:
      77      580584 :         if (FixedAttributeSize)
      78     1160536 :           ++FixedAttributeSize->NumAddrs;
      79             :         break;
      80             : 
      81         228 :       case DW_FORM_ref_addr:
      82         228 :         if (FixedAttributeSize)
      83         326 :           ++FixedAttributeSize->NumRefAddrs;
      84             :         break;
      85             : 
      86     7933556 :       case DW_FORM_strp:
      87             :       case DW_FORM_GNU_ref_alt:
      88             :       case DW_FORM_GNU_strp_alt:
      89             :       case DW_FORM_line_strp:
      90             :       case DW_FORM_sec_offset:
      91             :       case DW_FORM_strp_sup:
      92     7933556 :         if (FixedAttributeSize)
      93    15020034 :           ++FixedAttributeSize->NumDwarfOffsets;
      94             :         break;
      95             : 
      96    37702636 :       default:
      97             :         // The form has a byte size that doesn't depend on Params.
      98             :         // If it's a fixed size, keep track of it.
      99    37702636 :         if (auto Size =
     100    39813570 :                 DWARFFormValue::getFixedByteSize(F, DWARFFormParams())) {
     101    71183404 :           V = *Size;
     102    35591702 :           if (FixedAttributeSize)
     103    59398730 :             FixedAttributeSize->NumBytes += *V;
     104    35591702 :           break;
     105    37702636 :         }
     106             :         // Indicate we no longer have a fixed byte size for this
     107             :         // abbreviation by clearing the FixedAttributeSize optional value
     108             :         // so it doesn't have a value.
     109     2110934 :         FixedAttributeSize.reset();
     110             :         break;
     111             :       }
     112             :       // Record this attribute and its fixed size if it has one.
     113   231085020 :       AttributeSpecs.push_back(AttributeSpec(A, F, V));
     114     8191021 :     } else if (A == 0 && F == 0) {
     115             :       // We successfully reached the end of this abbreviation declaration
     116             :       // since both attribute and form are zero.
     117             :       break;
     118             :     } else {
     119             :       // Attribute and form pairs must either both be non-zero, in which case
     120             :       // they are added to the abbreviation declaration, or both be zero to
     121             :       // terminate the abbrevation declaration. In this case only one was
     122             :       // zero which is an error.
     123           0 :       clear();
     124           0 :       return false;
     125             :     }
     126             :   }
     127             :   return true;
     128             : }
     129             : 
     130        1298 : void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
     131        1298 :   auto tagString = TagString(getTag());
     132        2596 :   OS << '[' << getCode() << "] ";
     133             :   if (!tagString.empty())
     134        1298 :     OS << tagString;
     135             :   else
     136           0 :     OS << format("DW_TAG_Unknown_%x", getTag());
     137        2596 :   OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
     138       10003 :   for (const AttributeSpec &Spec : AttributeSpecs) {
     139        6109 :     OS << '\t';
     140        6109 :     auto attrString = AttributeString(Spec.Attr);
     141        6109 :     if (!attrString.empty())
     142        6104 :       OS << attrString;
     143             :     else
     144          10 :       OS << format("DW_AT_Unknown_%x", Spec.Attr);
     145        6109 :     OS << '\t';
     146        6109 :     auto formString = FormEncodingString(Spec.Form);
     147        6109 :     if (!formString.empty())
     148        6109 :       OS << formString;
     149             :     else
     150           0 :       OS << format("DW_FORM_Unknown_%x", Spec.Form);
     151        6109 :     if (Spec.isImplicitConst())
     152           6 :       OS << '\t' << *Spec.ByteSizeOrValue;
     153        6109 :     OS << '\n';
     154             :   }
     155        1298 :   OS << '\n';
     156        1298 : }
     157             : 
     158             : Optional<uint32_t>
     159     7443873 : DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const {
     160    77408683 :   for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
     161   126141992 :     if (AttributeSpecs[i].Attr == Attr)
     162      550059 :       return i;
     163             :   }
     164             :   return None;
     165             : }
     166             : 
     167     7443319 : Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
     168             :     const uint32_t DIEOffset, const dwarf::Attribute Attr,
     169             :     const DWARFUnit &U) const {
     170    14886638 :   Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
     171     7443319 :   if (!MatchAttrIndex)
     172             :     return None;
     173             : 
     174      549696 :   auto DebugInfoData = U.getDebugInfoExtractor();
     175             : 
     176             :   // Add the byte size of ULEB that for the abbrev Code so we can start
     177             :   // skipping the attribute data.
     178      549696 :   uint32_t Offset = DIEOffset + CodeByteSize;
     179      549696 :   uint32_t AttrIndex = 0;
     180     2815071 :   for (const auto &Spec : AttributeSpecs) {
     181     1715679 :     if (*MatchAttrIndex == AttrIndex) {
     182             :       // We have arrived at the attribute to extract, extract if from Offset.
     183     1099392 :       DWARFFormValue FormValue(Spec.Form);
     184      549696 :       if (Spec.isImplicitConst()) {
     185          21 :         FormValue.setSValue(*Spec.ByteSizeOrValue);
     186      549696 :         return FormValue;
     187             :       }
     188      549689 :       if (FormValue.extractValue(DebugInfoData, &Offset, &U))
     189             :         return FormValue;
     190             :     }
     191             :     // March Offset along until we get to the attribute we want.
     192     2331966 :     if (auto FixedSize = Spec.getByteSize(U))
     193     1163240 :       Offset += *FixedSize;
     194             :     else
     195        2743 :       DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset,
     196        2743 :                                 U.getFormParams());
     197     1165983 :     ++AttrIndex;
     198             :   }
     199             :   return None;
     200             : }
     201             : 
     202    13377150 : size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
     203             :     const DWARFUnit &U) const {
     204    13377150 :   size_t ByteSize = NumBytes;
     205    13377150 :   if (NumAddrs)
     206      381918 :     ByteSize += NumAddrs * U.getAddressByteSize();
     207    13377150 :   if (NumRefAddrs)
     208         400 :     ByteSize += NumRefAddrs * U.getRefAddrByteSize();
     209    13377150 :   if (NumDwarfOffsets)
     210    11195992 :     ByteSize += NumDwarfOffsets * U.getDwarfOffsetByteSize();
     211    13377150 :   return ByteSize;
     212             : }
     213             : 
     214     3994160 : Optional<int64_t> DWARFAbbreviationDeclaration::AttributeSpec::getByteSize(
     215             :     const DWARFUnit &U) const {
     216     3994160 :   if (isImplicitConst())
     217          20 :     return 0;
     218     3994150 :   if (ByteSizeOrValue)
     219     2330250 :     return ByteSizeOrValue;
     220     1663900 :   Optional<int64_t> S;
     221             :   auto FixedByteSize =
     222     3327800 :       DWARFFormValue::getFixedByteSize(Form, U.getFormParams());
     223     1663900 :   if (FixedByteSize)
     224     1563208 :     S = *FixedByteSize;
     225     1663900 :   return S;
     226             : }
     227             : 
     228    14115051 : Optional<size_t> DWARFAbbreviationDeclaration::getFixedAttributesByteSize(
     229             :     const DWARFUnit &U) const {
     230    14115051 :   if (FixedAttributeSize)
     231    40131450 :     return FixedAttributeSize->getByteSize(U);
     232             :   return None;
     233             : }

Generated by: LCOV version 1.13