LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFAbbreviationDeclaration.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 89 93 95.7 %
Date: 2018-10-20 13:21:21 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/FormatVariadic.h"
      20             : #include "llvm/Support/raw_ostream.h"
      21             : #include <cstddef>
      22             : #include <cstdint>
      23             : 
      24             : using namespace llvm;
      25             : using namespace dwarf;
      26             : 
      27       35071 : void DWARFAbbreviationDeclaration::clear() {
      28       35071 :   Code = 0;
      29       35071 :   Tag = DW_TAG_null;
      30       35071 :   CodeByteSize = 0;
      31       35071 :   HasChildren = false;
      32             :   AttributeSpecs.clear();
      33             :   FixedAttributeSize.reset();
      34       35071 : }
      35             : 
      36        3612 : DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
      37        3612 :   clear();
      38        3612 : }
      39             : 
      40             : bool
      41       31459 : DWARFAbbreviationDeclaration::extract(DataExtractor Data,
      42             :                                       uint32_t* OffsetPtr) {
      43       31459 :   clear();
      44       31459 :   const uint32_t Offset = *OffsetPtr;
      45       31459 :   Code = Data.getULEB128(OffsetPtr);
      46       31459 :   if (Code == 0) {
      47             :     return false;
      48             :   }
      49       27847 :   CodeByteSize = *OffsetPtr - Offset;
      50       27847 :   Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
      51       27847 :   if (Tag == DW_TAG_null) {
      52           0 :     clear();
      53           0 :     return false;
      54             :   }
      55       27847 :   uint8_t ChildrenByte = Data.getU8(OffsetPtr);
      56       27847 :   HasChildren = (ChildrenByte == DW_CHILDREN_yes);
      57             :   // Assign a value to our optional FixedAttributeSize member variable. If
      58             :   // this member variable still has a value after the while loop below, then
      59             :   // all attribute data in this abbreviation declaration has a fixed byte size.
      60       27847 :   FixedAttributeSize = FixedSizeInfo();
      61             : 
      62             :   // Read all of the abbreviation attributes and forms.
      63             :   while (true) {
      64      161272 :     auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
      65      161272 :     auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
      66      161272 :     if (A && F) {
      67             :       bool IsImplicitConst = (F == DW_FORM_implicit_const);
      68      133425 :       if (IsImplicitConst) {
      69           6 :         int64_t V = Data.getSLEB128(OffsetPtr);
      70          12 :         AttributeSpecs.push_back(AttributeSpec(A, F, V));
      71             :         continue;
      72             :       }
      73             :       Optional<uint8_t> ByteSize;
      74             :       // If this abbrevation still has a fixed byte size, then update the
      75             :       // FixedAttributeSize as needed.
      76      133419 :       switch (F) {
      77       14665 :       case DW_FORM_addr:
      78       14665 :         if (FixedAttributeSize)
      79       14588 :           ++FixedAttributeSize->NumAddrs;
      80             :         break;
      81             : 
      82         313 :       case DW_FORM_ref_addr:
      83         313 :         if (FixedAttributeSize)
      84         228 :           ++FixedAttributeSize->NumRefAddrs;
      85             :         break;
      86             : 
      87       27403 :       case DW_FORM_strp:
      88             :       case DW_FORM_GNU_ref_alt:
      89             :       case DW_FORM_GNU_strp_alt:
      90             :       case DW_FORM_line_strp:
      91             :       case DW_FORM_sec_offset:
      92             :       case DW_FORM_strp_sup:
      93       27403 :         if (FixedAttributeSize)
      94       26154 :           ++FixedAttributeSize->NumDwarfOffsets;
      95             :         break;
      96             : 
      97       91038 :       default:
      98             :         // The form has a byte size that doesn't depend on Params.
      99             :         // If it's a fixed size, keep track of it.
     100      182076 :         if ((ByteSize = dwarf::getFixedFormByteSize(F, dwarf::FormParams()))) {
     101       87585 :           if (FixedAttributeSize)
     102       82324 :             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      266838 :       AttributeSpecs.push_back(AttributeSpec(A, F, ByteSize));
     113       27847 :     } 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        1485 : void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
     130        1485 :   OS << '[' << getCode() << "] ";
     131        1485 :   OS << formatv("{0}", getTag());
     132        2435 :   OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
     133        8454 :   for (const AttributeSpec &Spec : AttributeSpecs) {
     134        6969 :     OS << formatv("\t{0}\t{1}", Spec.Attr, Spec.Form);
     135        6969 :     if (Spec.isImplicitConst())
     136           3 :       OS << '\t' << Spec.getImplicitConstValue();
     137             :     OS << '\n';
     138             :   }
     139             :   OS << '\n';
     140        1485 : }
     141             : 
     142             : Optional<uint32_t>
     143       91870 : DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const {
     144      485427 :   for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
     145      847776 :     if (AttributeSpecs[i].Attr == Attr)
     146             :       return i;
     147             :   }
     148             :   return None;
     149             : }
     150             : 
     151       91028 : Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
     152             :     const uint32_t DIEOffset, const dwarf::Attribute Attr,
     153             :     const DWARFUnit &U) const {
     154       91028 :   Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
     155       91028 :   if (!MatchAttrIndex)
     156             :     return None;
     157             : 
     158       29772 :   auto DebugInfoData = U.getDebugInfoExtractor();
     159             : 
     160             :   // Add the byte size of ULEB that for the abbrev Code so we can start
     161             :   // skipping the attribute data.
     162       29772 :   uint32_t Offset = DIEOffset + CodeByteSize;
     163             :   uint32_t AttrIndex = 0;
     164      120198 :   for (const auto &Spec : AttributeSpecs) {
     165      120198 :     if (*MatchAttrIndex == AttrIndex) {
     166             :       // We have arrived at the attribute to extract, extract if from Offset.
     167       29772 :       DWARFFormValue FormValue(Spec.Form);
     168       29772 :       if (Spec.isImplicitConst()) {
     169           7 :         FormValue.setSValue(Spec.getImplicitConstValue());
     170       29772 :         return FormValue;
     171             :       }
     172       29765 :       if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
     173             :         return FormValue;
     174             :     }
     175             :     // March Offset along until we get to the attribute we want.
     176       90426 :     if (auto FixedSize = Spec.getByteSize(U))
     177       86188 :       Offset += *FixedSize;
     178             :     else
     179        4238 :       DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset,
     180             :                                 U.getFormParams());
     181       90426 :     ++AttrIndex;
     182             :   }
     183             :   return None;
     184             : }
     185             : 
     186       26366 : size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
     187             :     const DWARFUnit &U) const {
     188       26366 :   size_t ByteSize = NumBytes;
     189       26366 :   if (NumAddrs)
     190        6352 :     ByteSize += NumAddrs * U.getAddressByteSize();
     191       26366 :   if (NumRefAddrs)
     192         542 :     ByteSize += NumRefAddrs * U.getRefAddrByteSize();
     193       26366 :   if (NumDwarfOffsets)
     194       12232 :     ByteSize += NumDwarfOffsets * U.getDwarfOffsetByteSize();
     195       26366 :   return ByteSize;
     196             : }
     197             : 
     198      122315 : Optional<int64_t> DWARFAbbreviationDeclaration::AttributeSpec::getByteSize(
     199             :     const DWARFUnit &U) const {
     200      122315 :   if (isImplicitConst())
     201             :     return 0;
     202      122305 :   if (ByteSize.HasByteSize)
     203       53193 :     return ByteSize.ByteSize;
     204             :   Optional<int64_t> S;
     205       69112 :   auto FixedByteSize = dwarf::getFixedFormByteSize(Form, U.getFormParams());
     206       69112 :   if (FixedByteSize)
     207       58786 :     S = *FixedByteSize;
     208             :   return S;
     209             : }
     210             : 
     211       31763 : Optional<size_t> DWARFAbbreviationDeclaration::getFixedAttributesByteSize(
     212             :     const DWARFUnit &U) const {
     213       31763 :   if (FixedAttributeSize)
     214       26366 :     return FixedAttributeSize->getByteSize(U);
     215             :   return None;
     216             : }

Generated by: LCOV version 1.13