LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFAbbreviationDeclaration.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 97 103 94.2 %
Date: 2018-02-20 16:54:40 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       33973 : void DWARFAbbreviationDeclaration::clear() {
      27       33973 :   Code = 0;
      28       33973 :   Tag = DW_TAG_null;
      29       33973 :   CodeByteSize = 0;
      30       33973 :   HasChildren = false;
      31             :   AttributeSpecs.clear();
      32             :   FixedAttributeSize.reset();
      33       33973 : }
      34             : 
      35        3445 : DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
      36             :   clear();
      37        3445 : }
      38             : 
      39             : bool
      40       30528 : DWARFAbbreviationDeclaration::extract(DataExtractor Data, 
      41             :                                       uint32_t* OffsetPtr) {
      42       30528 :   clear();
      43       30528 :   const uint32_t Offset = *OffsetPtr;
      44       30528 :   Code = Data.getULEB128(OffsetPtr);
      45       30528 :   if (Code == 0) {
      46             :     return false;
      47             :   }
      48       27083 :   CodeByteSize = *OffsetPtr - Offset;
      49       27083 :   Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
      50       27083 :   if (Tag == DW_TAG_null) {
      51           0 :     clear();
      52           0 :     return false;
      53             :   }
      54       27083 :   uint8_t ChildrenByte = Data.getU8(OffsetPtr);
      55       27083 :   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             :   FixedAttributeSize = FixedSizeInfo();
      60             : 
      61             :   // Read all of the abbreviation attributes and forms.
      62             :   while (true) {
      63      156916 :     auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
      64      156916 :     auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
      65      156916 :     if (A && F) {
      66             :       bool IsImplicitConst = (F == DW_FORM_implicit_const);
      67      129833 :       if (IsImplicitConst) {
      68           6 :         int64_t V = Data.getSLEB128(OffsetPtr);
      69          12 :         AttributeSpecs.push_back(AttributeSpec(A, F, V));
      70           6 :         continue;
      71             :       }
      72             :       Optional<uint8_t> ByteSize;
      73             :       // If this abbrevation still has a fixed byte size, then update the
      74             :       // FixedAttributeSize as needed.
      75      129827 :       switch (F) {
      76       14362 :       case DW_FORM_addr:
      77       14362 :         if (FixedAttributeSize)
      78       14297 :           ++FixedAttributeSize->NumAddrs;
      79             :         break;
      80             : 
      81         294 :       case DW_FORM_ref_addr:
      82         294 :         if (FixedAttributeSize)
      83         215 :           ++FixedAttributeSize->NumRefAddrs;
      84             :         break;
      85             : 
      86       26548 :       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       26548 :         if (FixedAttributeSize)
      93       25399 :           ++FixedAttributeSize->NumDwarfOffsets;
      94             :         break;
      95             : 
      96       88623 :       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       88623 :         if ((ByteSize =
     100      177246 :                  DWARFFormValue::getFixedByteSize(F, DWARFFormParams()))) {
     101       85534 :           if (FixedAttributeSize)
     102       80853 :             FixedAttributeSize->NumBytes += *ByteSize;
     103             :           break;
     104             :         }
     105             :         // Indicate we no longer have a fixed byte size for this
     106             :         // abbreviation by clearing the FixedAttributeSize optional value
     107             :         // so it doesn't have a value.
     108             :         FixedAttributeSize.reset();
     109             :         break;
     110             :       }
     111             :       // Record this attribute and its fixed size if it has one.
     112      259654 :       AttributeSpecs.push_back(AttributeSpec(A, F, ByteSize));
     113       27083 :     } else if (A == 0 && F == 0) {
     114             :       // We successfully reached the end of this abbreviation declaration
     115             :       // since both attribute and form are zero.
     116             :       break;
     117             :     } else {
     118             :       // Attribute and form pairs must either both be non-zero, in which case
     119             :       // they are added to the abbreviation declaration, or both be zero to
     120             :       // terminate the abbrevation declaration. In this case only one was
     121             :       // zero which is an error.
     122           0 :       clear();
     123           0 :       return false;
     124             :     }
     125             :   }
     126             :   return true;
     127             : }
     128             : 
     129        1407 : void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
     130        1407 :   auto tagString = TagString(getTag());
     131        2814 :   OS << '[' << getCode() << "] ";
     132        1407 :   if (!tagString.empty())
     133        1407 :     OS << tagString;
     134             :   else
     135           0 :     OS << format("DW_TAG_Unknown_%x", getTag());
     136        1407 :   OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
     137       14599 :   for (const AttributeSpec &Spec : AttributeSpecs) {
     138             :     OS << '\t';
     139        6596 :     auto attrString = AttributeString(Spec.Attr);
     140        6596 :     if (!attrString.empty())
     141        6591 :       OS << attrString;
     142             :     else
     143          10 :       OS << format("DW_AT_Unknown_%x", Spec.Attr);
     144             :     OS << '\t';
     145        6596 :     auto formString = FormEncodingString(Spec.Form);
     146        6596 :     if (!formString.empty())
     147        6596 :       OS << formString;
     148             :     else
     149           0 :       OS << format("DW_FORM_Unknown_%x", Spec.Form);
     150        6596 :     if (Spec.isImplicitConst())
     151           3 :       OS << '\t' << Spec.getImplicitConstValue();
     152             :     OS << '\n';
     153             :   }
     154             :   OS << '\n';
     155        1407 : }
     156             : 
     157             : Optional<uint32_t>
     158       81793 : DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const {
     159      431225 :   for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
     160      754340 :     if (AttributeSpecs[i].Attr == Attr)
     161             :       return i;
     162             :   }
     163             :   return None;
     164             : }
     165             : 
     166       81017 : Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
     167             :     const uint32_t DIEOffset, const dwarf::Attribute Attr,
     168             :     const DWARFUnit &U) const {
     169       81017 :   Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
     170       81017 :   if (!MatchAttrIndex)
     171             :     return None;
     172             : 
     173       27228 :   auto DebugInfoData = U.getDebugInfoExtractor();
     174             : 
     175             :   // Add the byte size of ULEB that for the abbrev Code so we can start
     176             :   // skipping the attribute data.
     177       27228 :   uint32_t Offset = DIEOffset + CodeByteSize;
     178             :   uint32_t AttrIndex = 0;
     179      205032 :   for (const auto &Spec : AttributeSpecs) {
     180      116130 :     if (*MatchAttrIndex == AttrIndex) {
     181             :       // We have arrived at the attribute to extract, extract if from Offset.
     182       27228 :       DWARFFormValue FormValue(Spec.Form);
     183       27228 :       if (Spec.isImplicitConst()) {
     184           7 :         FormValue.setSValue(Spec.getImplicitConstValue());
     185       27228 :         return FormValue;
     186             :       }
     187       27221 :       if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
     188             :         return FormValue;
     189             :     }
     190             :     // March Offset along until we get to the attribute we want.
     191       88902 :     if (auto FixedSize = Spec.getByteSize(U))
     192       85322 :       Offset += *FixedSize;
     193             :     else
     194        3580 :       DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset,
     195             :                                 U.getFormParams());
     196       88902 :     ++AttrIndex;
     197             :   }
     198             :   return None;
     199             : }
     200             : 
     201       25354 : size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
     202             :     const DWARFUnit &U) const {
     203       25354 :   size_t ByteSize = NumBytes;
     204       25354 :   if (NumAddrs)
     205        2984 :     ByteSize += NumAddrs * U.getAddressByteSize();
     206       25354 :   if (NumRefAddrs)
     207         518 :     ByteSize += NumRefAddrs * U.getRefAddrByteSize();
     208       25354 :   if (NumDwarfOffsets)
     209       22934 :     ByteSize += NumDwarfOffsets * U.getDwarfOffsetByteSize();
     210       25354 :   return ByteSize;
     211             : }
     212             : 
     213      116144 : Optional<int64_t> DWARFAbbreviationDeclaration::AttributeSpec::getByteSize(
     214             :     const DWARFUnit &U) const {
     215      116144 :   if (isImplicitConst())
     216             :     return 0;
     217      116134 :   if (ByteSize.HasByteSize)
     218       48568 :     return ByteSize.ByteSize;
     219             :   Optional<int64_t> S;
     220             :   auto FixedByteSize =
     221       67566 :       DWARFFormValue::getFixedByteSize(Form, U.getFormParams());
     222       67566 :   if (FixedByteSize)
     223       58702 :     S = *FixedByteSize;
     224             :   return S;
     225             : }
     226             : 
     227       30010 : Optional<size_t> DWARFAbbreviationDeclaration::getFixedAttributesByteSize(
     228             :     const DWARFUnit &U) const {
     229       30010 :   if (FixedAttributeSize)
     230       25354 :     return FixedAttributeSize->getByteSize(U);
     231             :   return None;
     232             : }

Generated by: LCOV version 1.13