aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
blob: b72c5071ea349c8f3c837bcf4cd94f8be00c5612 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//===- DWARFDebugInfoEntry.cpp --------------------------------------------===// 
// 
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
// See https://llvm.org/LICENSE.txt for license information. 
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
// 
//===----------------------------------------------------------------------===// 
 
#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" 
#include "llvm/ADT/Optional.h" 
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" 
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 
#include "llvm/DebugInfo/DWARF/DWARFUnit.h" 
#include "llvm/Support/DataExtractor.h" 
#include <cstddef> 
#include <cstdint> 
 
using namespace llvm; 
using namespace dwarf; 
 
bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, 
                                             uint64_t *OffsetPtr) { 
  DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor(); 
  const uint64_t UEndOffset = U.getNextUnitOffset(); 
  return extractFast(U, OffsetPtr, DebugInfoData, UEndOffset, 0); 
} 
 
bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint64_t *OffsetPtr, 
                                      const DWARFDataExtractor &DebugInfoData, 
                                      uint64_t UEndOffset, uint32_t D) { 
  Offset = *OffsetPtr; 
  Depth = D; 
  if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset)) 
    return false; 
  uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr); 
  if (0 == AbbrCode) { 
    // NULL debug tag entry. 
    AbbrevDecl = nullptr; 
    return true; 
  } 
  if (const auto *AbbrevSet = U.getAbbreviations())
    AbbrevDecl = AbbrevSet->getAbbreviationDeclaration(AbbrCode);
  if (nullptr == AbbrevDecl) { 
    // Restore the original offset. 
    *OffsetPtr = Offset; 
    return false; 
  } 
  // See if all attributes in this DIE have fixed byte sizes. If so, we can 
  // just add this size to the offset to skip to the next DIE. 
  if (Optional<size_t> FixedSize = AbbrevDecl->getFixedAttributesByteSize(U)) { 
    *OffsetPtr += *FixedSize; 
    return true; 
  } 
 
  // Skip all data in the .debug_info for the attributes 
  for (const auto &AttrSpec : AbbrevDecl->attributes()) { 
    // Check if this attribute has a fixed byte size. 
    if (auto FixedSize = AttrSpec.getByteSize(U)) { 
      // Attribute byte size if fixed, just add the size to the offset. 
      *OffsetPtr += *FixedSize; 
    } else if (!DWARFFormValue::skipValue(AttrSpec.Form, DebugInfoData, 
                                          OffsetPtr, U.getFormParams())) { 
      // We failed to skip this attribute's value, restore the original offset 
      // and return the failure status. 
      *OffsetPtr = Offset; 
      return false; 
    } 
  } 
  return true; 
}