Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndexSet.cpp
213845 views
1
//===-- ManualDWARFIndex.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 "Plugins/SymbolFile/DWARF/ManualDWARFIndexSet.h"
10
#include "lldb/Core/DataFileCache.h"
11
#include "lldb/Utility/DataEncoder.h"
12
#include "lldb/Utility/DataExtractor.h"
13
#include <cstdint>
14
15
using namespace lldb_private;
16
using namespace lldb_private::plugin::dwarf;
17
18
namespace {
19
// Define IDs for the different tables when encoding and decoding the
20
// ManualDWARFIndex NameToDIE objects so we can avoid saving any empty maps.
21
enum DataID {
22
kDataIDFunctionBasenames = 1u,
23
kDataIDFunctionFullnames,
24
kDataIDFunctionMethods,
25
kDataIDFunctionSelectors,
26
kDataIDFunctionObjcClassSelectors,
27
kDataIDGlobals,
28
kDataIDTypes,
29
kDataIDNamespaces,
30
kDataIDEnd = 255u,
31
};
32
} // namespace
33
34
// Version 2 changes the encoding of DIERef objects used in the DWARF manual
35
// index name tables. See DIERef class for details.
36
static constexpr uint32_t CURRENT_CACHE_VERSION = 2;
37
38
static constexpr llvm::StringLiteral kIdentifierManualDWARFIndex("DIDX");
39
40
std::optional<IndexSet<NameToDIE>>
41
plugin::dwarf::DecodeIndexSet(const DataExtractor &data,
42
lldb::offset_t *offset_ptr) {
43
StringTableReader strtab;
44
// We now decode the string table for all strings in the data cache file.
45
if (!strtab.Decode(data, offset_ptr))
46
return std::nullopt;
47
48
llvm::StringRef identifier((const char *)data.GetData(offset_ptr, 4), 4);
49
if (identifier != kIdentifierManualDWARFIndex)
50
return std::nullopt;
51
const uint32_t version = data.GetU32(offset_ptr);
52
if (version != CURRENT_CACHE_VERSION)
53
return std::nullopt;
54
55
IndexSet<NameToDIE> result;
56
while (true) {
57
switch (data.GetU8(offset_ptr)) {
58
default:
59
// If we got here, this is not expected, we expect the data IDs to match
60
// one of the values from the DataID enumeration.
61
return std::nullopt;
62
case kDataIDFunctionBasenames:
63
if (!result.function_basenames.Decode(data, offset_ptr, strtab))
64
return std::nullopt;
65
break;
66
case kDataIDFunctionFullnames:
67
if (!result.function_fullnames.Decode(data, offset_ptr, strtab))
68
return std::nullopt;
69
break;
70
case kDataIDFunctionMethods:
71
if (!result.function_methods.Decode(data, offset_ptr, strtab))
72
return std::nullopt;
73
break;
74
case kDataIDFunctionSelectors:
75
if (!result.function_selectors.Decode(data, offset_ptr, strtab))
76
return std::nullopt;
77
break;
78
case kDataIDFunctionObjcClassSelectors:
79
if (!result.objc_class_selectors.Decode(data, offset_ptr, strtab))
80
return std::nullopt;
81
break;
82
case kDataIDGlobals:
83
if (!result.globals.Decode(data, offset_ptr, strtab))
84
return std::nullopt;
85
break;
86
case kDataIDTypes:
87
if (!result.types.Decode(data, offset_ptr, strtab))
88
return std::nullopt;
89
break;
90
case kDataIDNamespaces:
91
if (!result.namespaces.Decode(data, offset_ptr, strtab))
92
return std::nullopt;
93
break;
94
case kDataIDEnd:
95
// We got to the end of our NameToDIE encodings.
96
return std::move(result);
97
break;
98
}
99
}
100
}
101
102
void plugin::dwarf::EncodeIndexSet(const IndexSet<NameToDIE> &set,
103
DataEncoder &encoder) {
104
ConstStringTable strtab;
105
106
// Encoder the DWARF index into a separate encoder first. This allows us
107
// gather all of the strings we willl need in "strtab" as we will need to
108
// write the string table out before the symbol table.
109
DataEncoder index_encoder(encoder.GetByteOrder(),
110
encoder.GetAddressByteSize());
111
112
index_encoder.AppendData(kIdentifierManualDWARFIndex);
113
// Encode the data version.
114
index_encoder.AppendU32(CURRENT_CACHE_VERSION);
115
116
if (!set.function_basenames.IsEmpty()) {
117
index_encoder.AppendU8(kDataIDFunctionBasenames);
118
set.function_basenames.Encode(index_encoder, strtab);
119
}
120
if (!set.function_fullnames.IsEmpty()) {
121
index_encoder.AppendU8(kDataIDFunctionFullnames);
122
set.function_fullnames.Encode(index_encoder, strtab);
123
}
124
if (!set.function_methods.IsEmpty()) {
125
index_encoder.AppendU8(kDataIDFunctionMethods);
126
set.function_methods.Encode(index_encoder, strtab);
127
}
128
if (!set.function_selectors.IsEmpty()) {
129
index_encoder.AppendU8(kDataIDFunctionSelectors);
130
set.function_selectors.Encode(index_encoder, strtab);
131
}
132
if (!set.objc_class_selectors.IsEmpty()) {
133
index_encoder.AppendU8(kDataIDFunctionObjcClassSelectors);
134
set.objc_class_selectors.Encode(index_encoder, strtab);
135
}
136
if (!set.globals.IsEmpty()) {
137
index_encoder.AppendU8(kDataIDGlobals);
138
set.globals.Encode(index_encoder, strtab);
139
}
140
if (!set.types.IsEmpty()) {
141
index_encoder.AppendU8(kDataIDTypes);
142
set.types.Encode(index_encoder, strtab);
143
}
144
if (!set.namespaces.IsEmpty()) {
145
index_encoder.AppendU8(kDataIDNamespaces);
146
set.namespaces.Encode(index_encoder, strtab);
147
}
148
index_encoder.AppendU8(kDataIDEnd);
149
150
// Now that all strings have been gathered, we will emit the string table.
151
strtab.Encode(encoder);
152
// Followed by the symbol table data.
153
encoder.AppendData(index_encoder.GetData());
154
}
155
156