blob: 4830c36a8ee791209e558571c8e3b5d2995e4bb0 [file] [log] [blame]
Eugene Zelenkoe94042c2017-02-27 23:43:14 +00001//===- DWARFDebugAbbrev.cpp -----------------------------------------------===//
Benjamin Krameraa2f78f2011-09-13 19:42:23 +00002//
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
Zachary Turner82af9432015-01-30 18:07:45 +000010#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000011#include "llvm/Support/Format.h"
12#include "llvm/Support/raw_ostream.h"
Eugene Zelenkoe94042c2017-02-27 23:43:14 +000013#include <algorithm>
14#include <cinttypes>
15#include <cstdint>
16
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000017using namespace llvm;
18
Alexey Samsonov4316df52014-04-25 21:10:56 +000019DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000020 clear();
Alexey Samsonov4316df52014-04-25 21:10:56 +000021}
22
23void DWARFAbbreviationDeclarationSet::clear() {
24 Offset = 0;
25 FirstAbbrCode = 0;
26 Decls.clear();
27}
28
29bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
30 uint32_t *OffsetPtr) {
31 clear();
32 const uint32_t BeginOffset = *OffsetPtr;
33 Offset = BeginOffset;
34 DWARFAbbreviationDeclaration AbbrDecl;
35 uint32_t PrevAbbrCode = 0;
36 while (AbbrDecl.extract(Data, OffsetPtr)) {
Alexey Samsonov4316df52014-04-25 21:10:56 +000037 if (FirstAbbrCode == 0) {
38 FirstAbbrCode = AbbrDecl.getCode();
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000039 } else {
Alexey Samsonov4316df52014-04-25 21:10:56 +000040 if (PrevAbbrCode + 1 != AbbrDecl.getCode()) {
41 // Codes are not consecutive, can't do O(1) lookups.
42 FirstAbbrCode = UINT32_MAX;
43 }
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000044 }
Alexey Samsonov4316df52014-04-25 21:10:56 +000045 PrevAbbrCode = AbbrDecl.getCode();
Benjamin Kramerc6cc58e2014-10-04 16:55:56 +000046 Decls.push_back(std::move(AbbrDecl));
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000047 }
Alexey Samsonov4316df52014-04-25 21:10:56 +000048 return BeginOffset != *OffsetPtr;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000049}
50
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000051void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
Alexey Samsonov1eabf982014-03-13 07:52:54 +000052 for (const auto &Decl : Decls)
53 Decl.dump(OS);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000054}
55
Alexey Samsonov4316df52014-04-25 21:10:56 +000056const DWARFAbbreviationDeclaration *
57DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(
58 uint32_t AbbrCode) const {
59 if (FirstAbbrCode == UINT32_MAX) {
Alexey Samsonov1eabf982014-03-13 07:52:54 +000060 for (const auto &Decl : Decls) {
Alexey Samsonov4316df52014-04-25 21:10:56 +000061 if (Decl.getCode() == AbbrCode)
Alexey Samsonov1eabf982014-03-13 07:52:54 +000062 return &Decl;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000063 }
Alexey Samsonov4316df52014-04-25 21:10:56 +000064 return nullptr;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000065 }
Alexey Samsonov4316df52014-04-25 21:10:56 +000066 if (AbbrCode < FirstAbbrCode || AbbrCode >= FirstAbbrCode + Decls.size())
67 return nullptr;
68 return &Decls[AbbrCode - FirstAbbrCode];
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000069}
70
David Blaikie485e01b2017-09-19 15:13:55 +000071DWARFDebugAbbrev::DWARFDebugAbbrev() { clear(); }
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000072
Alexey Samsonov4316df52014-04-25 21:10:56 +000073void DWARFDebugAbbrev::clear() {
74 AbbrDeclSets.clear();
75 PrevAbbrOffsetPos = AbbrDeclSets.end();
76}
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000077
Alexey Samsonov4316df52014-04-25 21:10:56 +000078void DWARFDebugAbbrev::extract(DataExtractor Data) {
79 clear();
David Blaikie485e01b2017-09-19 15:13:55 +000080 this->Data = Data;
81}
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000082
David Blaikie485e01b2017-09-19 15:13:55 +000083void DWARFDebugAbbrev::parse() const {
84 if (!Data)
85 return;
Alexey Samsonov4316df52014-04-25 21:10:56 +000086 uint32_t Offset = 0;
87 DWARFAbbreviationDeclarationSet AbbrDecls;
David Blaikie485e01b2017-09-19 15:13:55 +000088 auto I = AbbrDeclSets.begin();
89 while (Data->isValidOffset(Offset)) {
90 while (I != AbbrDeclSets.end() && I->first < Offset)
91 ++I;
Alexey Samsonov4316df52014-04-25 21:10:56 +000092 uint32_t CUAbbrOffset = Offset;
David Blaikie485e01b2017-09-19 15:13:55 +000093 if (!AbbrDecls.extract(*Data, &Offset))
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000094 break;
David Blaikie485e01b2017-09-19 15:13:55 +000095 AbbrDeclSets.insert(I, std::make_pair(CUAbbrOffset, std::move(AbbrDecls)));
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000096 }
David Blaikie485e01b2017-09-19 15:13:55 +000097 Data = None;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000098}
99
100void DWARFDebugAbbrev::dump(raw_ostream &OS) const {
David Blaikie485e01b2017-09-19 15:13:55 +0000101 parse();
102
Alexey Samsonov4316df52014-04-25 21:10:56 +0000103 if (AbbrDeclSets.empty()) {
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000104 OS << "< EMPTY >\n";
105 return;
106 }
107
Alexey Samsonov4316df52014-04-25 21:10:56 +0000108 for (const auto &I : AbbrDeclSets) {
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000109 OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first);
110 I.second.dump(OS);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000111 }
112}
113
114const DWARFAbbreviationDeclarationSet*
Alexey Samsonov9a5c95a2014-04-24 22:41:09 +0000115DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
Alexey Samsonov4316df52014-04-25 21:10:56 +0000116 const auto End = AbbrDeclSets.end();
Alexey Samsonov9a5c95a2014-04-24 22:41:09 +0000117 if (PrevAbbrOffsetPos != End && PrevAbbrOffsetPos->first == CUAbbrOffset) {
Benjamin Kramereaa74332011-09-13 21:47:32 +0000118 return &(PrevAbbrOffsetPos->second);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000119 }
120
Alexey Samsonov4316df52014-04-25 21:10:56 +0000121 const auto Pos = AbbrDeclSets.find(CUAbbrOffset);
Alexey Samsonov9a5c95a2014-04-24 22:41:09 +0000122 if (Pos != End) {
123 PrevAbbrOffsetPos = Pos;
124 return &(Pos->second);
125 }
126
David Blaikie485e01b2017-09-19 15:13:55 +0000127 if (Data && CUAbbrOffset < Data->getData().size()) {
128 uint32_t Offset = CUAbbrOffset;
129 DWARFAbbreviationDeclarationSet AbbrDecls;
130 if (!AbbrDecls.extract(*Data, &Offset))
131 return nullptr;
132 PrevAbbrOffsetPos =
133 AbbrDeclSets.insert(std::make_pair(CUAbbrOffset, std::move(AbbrDecls)))
134 .first;
135 return &PrevAbbrOffsetPos->second;
136 }
137
Craig Topper2617dcc2014-04-15 06:32:26 +0000138 return nullptr;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000139}