Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- DWARFAbbreviationDeclaration.cpp -----------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
10
11
#include "llvm/ADT/None.h"
12
#include "llvm/ADT/Optional.h"
13
#include "llvm/BinaryFormat/Dwarf.h"
14
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
15
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
16
#include "llvm/Support/DataExtractor.h"
17
#include "llvm/Support/Format.h"
18
#include "llvm/Support/FormatVariadic.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
12.2k
void DWARFAbbreviationDeclaration::clear() {
27
12.2k
  Code = 0;
28
12.2k
  Tag = DW_TAG_null;
29
12.2k
  CodeByteSize = 0;
30
12.2k
  HasChildren = false;
31
12.2k
  AttributeSpecs.clear();
32
12.2k
  FixedAttributeSize.reset();
33
12.2k
}
34
35
1.69k
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
36
1.69k
  clear();
37
1.69k
}
38
39
bool
40
DWARFAbbreviationDeclaration::extract(DataExtractor Data,
41
10.5k
                                      uint32_t* OffsetPtr) {
42
10.5k
  clear();
43
10.5k
  const uint32_t Offset = *OffsetPtr;
44
10.5k
  Code = Data.getULEB128(OffsetPtr);
45
10.5k
  if (Code == 0) {
46
1.69k
    return false;
47
1.69k
  }
48
8.90k
  CodeByteSize = *OffsetPtr - Offset;
49
8.90k
  Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
50
8.90k
  if (Tag == DW_TAG_null) {
51
0
    clear();
52
0
    return false;
53
0
  }
54
8.90k
  uint8_t ChildrenByte = Data.getU8(OffsetPtr);
55
8.90k
  HasChildren = (ChildrenByte == DW_CHILDREN_yes);
56
8.90k
  // Assign a value to our optional FixedAttributeSize member variable. If
57
8.90k
  // this member variable still has a value after the while loop below, then
58
8.90k
  // all attribute data in this abbreviation declaration has a fixed byte size.
59
8.90k
  FixedAttributeSize = FixedSizeInfo();
60
8.90k
61
8.90k
  // Read all of the abbreviation attributes and forms.
62
51.8k
  while (true) {
63
51.8k
    auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
64
51.8k
    auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
65
51.8k
    if (A && 
F42.9k
) {
66
42.9k
      bool IsImplicitConst = (F == DW_FORM_implicit_const);
67
42.9k
      if (IsImplicitConst) {
68
6
        int64_t V = Data.getSLEB128(OffsetPtr);
69
6
        AttributeSpecs.push_back(AttributeSpec(A, F, V));
70
6
        continue;
71
6
      }
72
42.9k
      Optional<uint8_t> ByteSize;
73
42.9k
      // If this abbrevation still has a fixed byte size, then update the
74
42.9k
      // FixedAttributeSize as needed.
75
42.9k
      switch (F) {
76
42.9k
      case DW_FORM_addr:
77
3.83k
        if (FixedAttributeSize)
78
3.74k
          ++FixedAttributeSize->NumAddrs;
79
3.83k
        break;
80
42.9k
81
42.9k
      case DW_FORM_ref_addr:
82
321
        if (FixedAttributeSize)
83
228
          ++FixedAttributeSize->NumRefAddrs;
84
321
        break;
85
42.9k
86
42.9k
      case DW_FORM_strp:
87
10.0k
      case DW_FORM_GNU_ref_alt:
88
10.0k
      case DW_FORM_GNU_strp_alt:
89
10.0k
      case DW_FORM_line_strp:
90
10.0k
      case DW_FORM_sec_offset:
91
10.0k
      case DW_FORM_strp_sup:
92
10.0k
        if (FixedAttributeSize)
93
8.70k
          ++FixedAttributeSize->NumDwarfOffsets;
94
10.0k
        break;
95
10.0k
96
28.7k
      default:
97
28.7k
        // The form has a byte size that doesn't depend on Params.
98
28.7k
        // If it's a fixed size, keep track of it.
99
28.7k
        if ((ByteSize = dwarf::getFixedFormByteSize(F, dwarf::FormParams()))) {
100
25.1k
          if (FixedAttributeSize)
101
19.3k
            FixedAttributeSize->NumBytes += *ByteSize;
102
25.1k
          break;
103
25.1k
        }
104
3.62k
        // Indicate we no longer have a fixed byte size for this
105
3.62k
        // abbreviation by clearing the FixedAttributeSize optional value
106
3.62k
        // so it doesn't have a value.
107
3.62k
        FixedAttributeSize.reset();
108
3.62k
        break;
109
42.9k
      }
110
42.9k
      // Record this attribute and its fixed size if it has one.
111
42.9k
      AttributeSpecs.push_back(AttributeSpec(A, F, ByteSize));
112
42.9k
    } else 
if (8.90k
A == 08.90k
&&
F == 08.90k
) {
113
8.90k
      // We successfully reached the end of this abbreviation declaration
114
8.90k
      // since both attribute and form are zero.
115
8.90k
      break;
116
8.90k
    } else {
117
0
      // Attribute and form pairs must either both be non-zero, in which case
118
0
      // they are added to the abbreviation declaration, or both be zero to
119
0
      // terminate the abbrevation declaration. In this case only one was
120
0
      // zero which is an error.
121
0
      clear();
122
0
      return false;
123
0
    }
124
51.8k
  }
125
8.90k
  return true;
126
8.90k
}
127
128
1.53k
void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
129
1.53k
  OS << '[' << getCode() << "] ";
130
1.53k
  OS << formatv("{0}", getTag());
131
1.53k
  OS << "\tDW_CHILDREN_" << (hasChildren() ? 
"yes"556
:
"no"978
) << '\n';
132
7.22k
  for (const AttributeSpec &Spec : AttributeSpecs) {
133
7.22k
    OS << formatv("\t{0}\t{1}", Spec.Attr, Spec.Form);
134
7.22k
    if (Spec.isImplicitConst())
135
3
      OS << '\t' << Spec.getImplicitConstValue();
136
7.22k
    OS << '\n';
137
7.22k
  }
138
1.53k
  OS << '\n';
139
1.53k
}
140
141
Optional<uint32_t>
142
73.0k
DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const {
143
327k
  for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; 
++i254k
) {
144
279k
    if (AttributeSpecs[i].Attr == Attr)
145
25.4k
      return i;
146
279k
  }
147
73.0k
  
return None47.6k
;
148
73.0k
}
149
150
Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
151
    const uint32_t DIEOffset, const dwarf::Attribute Attr,
152
72.1k
    const DWARFUnit &U) const {
153
72.1k
  Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
154
72.1k
  if (!MatchAttrIndex)
155
47.3k
    return None;
156
24.8k
157
24.8k
  auto DebugInfoData = U.getDebugInfoExtractor();
158
24.8k
159
24.8k
  // Add the byte size of ULEB that for the abbrev Code so we can start
160
24.8k
  // skipping the attribute data.
161
24.8k
  uint32_t Offset = DIEOffset + CodeByteSize;
162
24.8k
  uint32_t AttrIndex = 0;
163
85.9k
  for (const auto &Spec : AttributeSpecs) {
164
85.9k
    if (*MatchAttrIndex == AttrIndex) {
165
24.8k
      // We have arrived at the attribute to extract, extract if from Offset.
166
24.8k
      if (Spec.isImplicitConst())
167
7
        return DWARFFormValue::createFromSValue(Spec.Form,
168
7
                                                Spec.getImplicitConstValue());
169
24.8k
170
24.8k
      DWARFFormValue FormValue(Spec.Form);
171
24.8k
      if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
172
24.8k
        return FormValue;
173
61.1k
    }
174
61.1k
    // March Offset along until we get to the attribute we want.
175
61.1k
    if (auto FixedSize = Spec.getByteSize(U))
176
57.7k
      Offset += *FixedSize;
177
3.33k
    else
178
3.33k
      DWARFFormValue::skipValue(Spec.Form, DebugInfoData, &Offset,
179
3.33k
                                U.getFormParams());
180
61.1k
    ++AttrIndex;
181
61.1k
  }
182
18.4E
  return None;
183
24.8k
}
184
185
size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
186
7.82k
    const DWARFUnit &U) const {
187
7.82k
  size_t ByteSize = NumBytes;
188
7.82k
  if (NumAddrs)
189
1.81k
    ByteSize += NumAddrs * U.getAddressByteSize();
190
7.82k
  if (NumRefAddrs)
191
273
    ByteSize += NumRefAddrs * U.getRefAddrByteSize();
192
7.82k
  if (NumDwarfOffsets)
193
5.44k
    ByteSize += NumDwarfOffsets * U.getDwarfOffsetByteSize();
194
7.82k
  return ByteSize;
195
7.82k
}
196
197
Optional<int64_t> DWARFAbbreviationDeclaration::AttributeSpec::getByteSize(
198
92.7k
    const DWARFUnit &U) const {
199
92.7k
  if (isImplicitConst())
200
10
    return 0;
201
92.7k
  if (ByteSize.HasByteSize)
202
43.2k
    return ByteSize.ByteSize;
203
49.5k
  Optional<int64_t> S;
204
49.5k
  auto FixedByteSize = dwarf::getFixedFormByteSize(Form, U.getFormParams());
205
49.5k
  if (FixedByteSize)
206
40.1k
    S = *FixedByteSize;
207
49.5k
  return S;
208
49.5k
}
209
210
Optional<size_t> DWARFAbbreviationDeclaration::getFixedAttributesByteSize(
211
13.1k
    const DWARFUnit &U) const {
212
13.1k
  if (FixedAttributeSize)
213
7.82k
    return FixedAttributeSize->getByteSize(U);
214
5.28k
  return None;
215
5.28k
}