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/CTF/SymbolFileCTF.cpp
39644 views
1
//===-- SymbolFileCTF.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 "SymbolFileCTF.h"
10
11
#include "lldb/Core/Module.h"
12
#include "lldb/Core/PluginManager.h"
13
#include "lldb/Host/Config.h"
14
#include "lldb/Symbol/CompileUnit.h"
15
#include "lldb/Symbol/Function.h"
16
#include "lldb/Symbol/ObjectFile.h"
17
#include "lldb/Symbol/Symbol.h"
18
#include "lldb/Symbol/SymbolContext.h"
19
#include "lldb/Symbol/Symtab.h"
20
#include "lldb/Symbol/TypeList.h"
21
#include "lldb/Symbol/TypeMap.h"
22
#include "lldb/Symbol/Variable.h"
23
#include "lldb/Symbol/VariableList.h"
24
#include "lldb/Utility/DataExtractor.h"
25
#include "lldb/Utility/LLDBLog.h"
26
#include "lldb/Utility/Log.h"
27
#include "lldb/Utility/RegularExpression.h"
28
#include "lldb/Utility/StreamBuffer.h"
29
#include "lldb/Utility/StreamString.h"
30
#include "lldb/Utility/Timer.h"
31
#include "llvm/Support/MemoryBuffer.h"
32
33
#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
34
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
35
36
#include <memory>
37
#include <optional>
38
39
#if LLVM_ENABLE_ZLIB
40
#include <zlib.h>
41
#endif
42
43
using namespace llvm;
44
using namespace lldb;
45
using namespace lldb_private;
46
47
LLDB_PLUGIN_DEFINE(SymbolFileCTF)
48
49
char SymbolFileCTF::ID;
50
51
SymbolFileCTF::SymbolFileCTF(lldb::ObjectFileSP objfile_sp)
52
: SymbolFileCommon(std::move(objfile_sp)) {}
53
54
void SymbolFileCTF::Initialize() {
55
PluginManager::RegisterPlugin(GetPluginNameStatic(),
56
GetPluginDescriptionStatic(), CreateInstance);
57
}
58
59
void SymbolFileCTF::Terminate() {
60
PluginManager::UnregisterPlugin(CreateInstance);
61
}
62
63
llvm::StringRef SymbolFileCTF::GetPluginDescriptionStatic() {
64
return "Compact C Type Format Symbol Reader";
65
}
66
67
SymbolFile *SymbolFileCTF::CreateInstance(ObjectFileSP objfile_sp) {
68
return new SymbolFileCTF(std::move(objfile_sp));
69
}
70
71
bool SymbolFileCTF::ParseHeader() {
72
if (m_header)
73
return true;
74
75
Log *log = GetLog(LLDBLog::Symbols);
76
77
ModuleSP module_sp(m_objfile_sp->GetModule());
78
const SectionList *section_list = module_sp->GetSectionList();
79
if (!section_list)
80
return false;
81
82
SectionSP section_sp(
83
section_list->FindSectionByType(lldb::eSectionTypeCTF, true));
84
if (!section_sp)
85
return false;
86
87
m_objfile_sp->ReadSectionData(section_sp.get(), m_data);
88
89
if (m_data.GetByteSize() == 0)
90
return false;
91
92
StreamString module_desc;
93
GetObjectFile()->GetModule()->GetDescription(module_desc.AsRawOstream(),
94
lldb::eDescriptionLevelBrief);
95
LLDB_LOG(log, "Parsing Compact C Type format for {0}", module_desc.GetData());
96
97
lldb::offset_t offset = 0;
98
99
// Parse CTF header.
100
constexpr size_t ctf_header_size = sizeof(ctf_header_t);
101
if (!m_data.ValidOffsetForDataOfSize(offset, ctf_header_size)) {
102
LLDB_LOG(log, "CTF parsing failed: insufficient data for CTF header");
103
return false;
104
}
105
106
m_header.emplace();
107
108
ctf_header_t &ctf_header = *m_header;
109
ctf_header.preamble.magic = m_data.GetU16(&offset);
110
ctf_header.preamble.version = m_data.GetU8(&offset);
111
ctf_header.preamble.flags = m_data.GetU8(&offset);
112
ctf_header.parlabel = m_data.GetU32(&offset);
113
ctf_header.parname = m_data.GetU32(&offset);
114
ctf_header.lbloff = m_data.GetU32(&offset);
115
ctf_header.objtoff = m_data.GetU32(&offset);
116
ctf_header.funcoff = m_data.GetU32(&offset);
117
ctf_header.typeoff = m_data.GetU32(&offset);
118
ctf_header.stroff = m_data.GetU32(&offset);
119
ctf_header.strlen = m_data.GetU32(&offset);
120
121
// Validate the preamble.
122
if (ctf_header.preamble.magic != g_ctf_magic) {
123
LLDB_LOG(log, "CTF parsing failed: invalid magic: {0:x}",
124
ctf_header.preamble.magic);
125
return false;
126
}
127
128
if (ctf_header.preamble.version != g_ctf_version) {
129
LLDB_LOG(log, "CTF parsing failed: unsupported version: {0}",
130
ctf_header.preamble.version);
131
return false;
132
}
133
134
LLDB_LOG(log, "Parsed valid CTF preamble: version {0}, flags {1:x}",
135
ctf_header.preamble.version, ctf_header.preamble.flags);
136
137
m_body_offset = offset;
138
139
if (ctf_header.preamble.flags & eFlagCompress) {
140
// The body has been compressed with zlib deflate. Header offsets point into
141
// the decompressed data.
142
#if LLVM_ENABLE_ZLIB
143
const std::size_t decompressed_size = ctf_header.stroff + ctf_header.strlen;
144
DataBufferSP decompressed_data =
145
std::make_shared<DataBufferHeap>(decompressed_size, 0x0);
146
147
z_stream zstr;
148
memset(&zstr, 0, sizeof(zstr));
149
zstr.next_in = (Bytef *)const_cast<uint8_t *>(m_data.GetDataStart() +
150
sizeof(ctf_header_t));
151
zstr.avail_in = m_data.BytesLeft(offset);
152
zstr.next_out =
153
(Bytef *)const_cast<uint8_t *>(decompressed_data->GetBytes());
154
zstr.avail_out = decompressed_size;
155
156
int rc = inflateInit(&zstr);
157
if (rc != Z_OK) {
158
LLDB_LOG(log, "CTF parsing failed: inflate initialization error: {0}",
159
zError(rc));
160
return false;
161
}
162
163
rc = inflate(&zstr, Z_FINISH);
164
if (rc != Z_STREAM_END) {
165
LLDB_LOG(log, "CTF parsing failed: inflate error: {0}", zError(rc));
166
return false;
167
}
168
169
rc = inflateEnd(&zstr);
170
if (rc != Z_OK) {
171
LLDB_LOG(log, "CTF parsing failed: inflate end error: {0}", zError(rc));
172
return false;
173
}
174
175
if (zstr.total_out != decompressed_size) {
176
LLDB_LOG(log,
177
"CTF parsing failed: decompressed size ({0}) doesn't match "
178
"expected size ([1})",
179
zstr.total_out, decompressed_size);
180
return false;
181
}
182
183
m_data = DataExtractor(decompressed_data, m_data.GetByteOrder(),
184
m_data.GetAddressByteSize());
185
m_body_offset = 0;
186
#else
187
LLDB_LOG(
188
log,
189
"CTF parsing failed: data is compressed but no zlib inflate support");
190
return false;
191
#endif
192
}
193
194
// Validate the header.
195
if (!m_data.ValidOffset(m_body_offset + ctf_header.lbloff)) {
196
LLDB_LOG(log,
197
"CTF parsing failed: invalid label section offset in header: {0}",
198
ctf_header.lbloff);
199
return false;
200
}
201
202
if (!m_data.ValidOffset(m_body_offset + ctf_header.objtoff)) {
203
LLDB_LOG(log,
204
"CTF parsing failed: invalid object section offset in header: {0}",
205
ctf_header.objtoff);
206
return false;
207
}
208
209
if (!m_data.ValidOffset(m_body_offset + ctf_header.funcoff)) {
210
LLDB_LOG(
211
log,
212
"CTF parsing failed: invalid function section offset in header: {0}",
213
ctf_header.funcoff);
214
return false;
215
}
216
217
if (!m_data.ValidOffset(m_body_offset + ctf_header.typeoff)) {
218
LLDB_LOG(log,
219
"CTF parsing failed: invalid type section offset in header: {0}",
220
ctf_header.typeoff);
221
return false;
222
}
223
224
if (!m_data.ValidOffset(m_body_offset + ctf_header.stroff)) {
225
LLDB_LOG(log,
226
"CTF parsing failed: invalid string section offset in header: {0}",
227
ctf_header.stroff);
228
return false;
229
}
230
231
const lldb::offset_t str_end_offset =
232
m_body_offset + ctf_header.stroff + ctf_header.strlen;
233
if (!m_data.ValidOffset(str_end_offset - 1)) {
234
LLDB_LOG(log,
235
"CTF parsing failed: invalid string section length in header: {0}",
236
ctf_header.strlen);
237
return false;
238
}
239
240
if (m_body_offset + ctf_header.stroff + ctf_header.parlabel >
241
str_end_offset) {
242
LLDB_LOG(log,
243
"CTF parsing failed: invalid parent label offset: {0} exceeds end "
244
"of string section ({1})",
245
ctf_header.parlabel, str_end_offset);
246
return false;
247
}
248
249
if (m_body_offset + ctf_header.stroff + ctf_header.parname > str_end_offset) {
250
LLDB_LOG(log,
251
"CTF parsing failed: invalid parent name offset: {0} exceeds end "
252
"of string section ({1})",
253
ctf_header.parname, str_end_offset);
254
return false;
255
}
256
257
LLDB_LOG(log,
258
"Parsed valid CTF header: lbloff = {0}, objtoff = {1}, funcoff = "
259
"{2}, typeoff = {3}, stroff = {4}, strlen = {5}",
260
ctf_header.lbloff, ctf_header.objtoff, ctf_header.funcoff,
261
ctf_header.typeoff, ctf_header.stroff, ctf_header.strlen);
262
263
return true;
264
}
265
266
void SymbolFileCTF::InitializeObject() {
267
Log *log = GetLog(LLDBLog::Symbols);
268
269
auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC);
270
if (auto err = type_system_or_err.takeError()) {
271
LLDB_LOG_ERROR(log, std::move(err), "Unable to get type system: {0}");
272
return;
273
}
274
275
auto ts = *type_system_or_err;
276
m_ast = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
277
LazyBool optimized = eLazyBoolNo;
278
m_comp_unit_sp = std::make_shared<CompileUnit>(
279
m_objfile_sp->GetModule(), nullptr, "", 0, eLanguageTypeC, optimized);
280
281
ParseTypes(*m_comp_unit_sp);
282
}
283
284
llvm::StringRef SymbolFileCTF::ReadString(lldb::offset_t str_offset) const {
285
lldb::offset_t offset = m_body_offset + m_header->stroff + str_offset;
286
if (!m_data.ValidOffset(offset))
287
return "(invalid)";
288
const char *str = m_data.GetCStr(&offset);
289
if (str && !*str)
290
return "(anon)";
291
return llvm::StringRef(str);
292
}
293
294
/// Return the integer display representation encoded in the given data.
295
static uint32_t GetEncoding(uint32_t data) {
296
// Mask bits 24–31.
297
return ((data)&0xff000000) >> 24;
298
}
299
300
/// Return the integral width in bits encoded in the given data.
301
static uint32_t GetBits(uint32_t data) {
302
// Mask bits 0-15.
303
return (data)&0x0000ffff;
304
}
305
306
/// Return the type kind encoded in the given data.
307
uint32_t GetKind(uint32_t data) {
308
// Mask bits 26–31.
309
return ((data)&0xf800) >> 11;
310
}
311
312
/// Return the variable length encoded in the given data.
313
uint32_t GetVLen(uint32_t data) {
314
// Mask bits 0–24.
315
return (data)&0x3ff;
316
}
317
318
static uint32_t GetBytes(uint32_t bits) { return bits / sizeof(unsigned); }
319
320
static clang::TagTypeKind TranslateRecordKind(CTFType::Kind type) {
321
switch (type) {
322
case CTFType::Kind::eStruct:
323
return clang::TagTypeKind::Struct;
324
case CTFType::Kind::eUnion:
325
return clang::TagTypeKind::Union;
326
default:
327
lldbassert(false && "Invalid record kind!");
328
return clang::TagTypeKind::Struct;
329
}
330
}
331
332
llvm::Expected<TypeSP>
333
SymbolFileCTF::CreateInteger(const CTFInteger &ctf_integer) {
334
lldb::BasicType basic_type =
335
TypeSystemClang::GetBasicTypeEnumeration(ctf_integer.name);
336
if (basic_type == eBasicTypeInvalid)
337
return llvm::make_error<llvm::StringError>(
338
llvm::formatv("unsupported integer type: no corresponding basic clang "
339
"type for '{0}'",
340
ctf_integer.name),
341
llvm::inconvertibleErrorCode());
342
343
CompilerType compiler_type = m_ast->GetBasicType(basic_type);
344
345
if (basic_type != eBasicTypeVoid && basic_type != eBasicTypeBool) {
346
// Make sure the type we got is an integer type.
347
bool compiler_type_is_signed = false;
348
if (!compiler_type.IsIntegerType(compiler_type_is_signed))
349
return llvm::make_error<llvm::StringError>(
350
llvm::formatv(
351
"Found compiler type for '{0}' but it's not an integer type: {1}",
352
ctf_integer.name,
353
compiler_type.GetDisplayTypeName().GetStringRef()),
354
llvm::inconvertibleErrorCode());
355
356
// Make sure the signing matches between the CTF and the compiler type.
357
const bool type_is_signed = (ctf_integer.encoding & IntEncoding::eSigned);
358
if (compiler_type_is_signed != type_is_signed)
359
return llvm::make_error<llvm::StringError>(
360
llvm::formatv("Found integer compiler type for {0} but compiler type "
361
"is {1} and {0} is {2}",
362
ctf_integer.name,
363
compiler_type_is_signed ? "signed" : "unsigned",
364
type_is_signed ? "signed" : "unsigned"),
365
llvm::inconvertibleErrorCode());
366
}
367
368
Declaration decl;
369
return MakeType(ctf_integer.uid, ConstString(ctf_integer.name),
370
GetBytes(ctf_integer.bits), nullptr, LLDB_INVALID_UID,
371
lldb_private::Type::eEncodingIsUID, decl, compiler_type,
372
lldb_private::Type::ResolveState::Full);
373
}
374
375
llvm::Expected<lldb::TypeSP>
376
SymbolFileCTF::CreateModifier(const CTFModifier &ctf_modifier) {
377
Type *ref_type = ResolveTypeUID(ctf_modifier.type);
378
if (!ref_type)
379
return llvm::make_error<llvm::StringError>(
380
llvm::formatv("Could not find modified type: {0}", ctf_modifier.type),
381
llvm::inconvertibleErrorCode());
382
383
CompilerType compiler_type;
384
385
switch (ctf_modifier.kind) {
386
case CTFType::ePointer:
387
compiler_type = ref_type->GetFullCompilerType().GetPointerType();
388
break;
389
case CTFType::eConst:
390
compiler_type = ref_type->GetFullCompilerType().AddConstModifier();
391
break;
392
case CTFType::eVolatile:
393
compiler_type = ref_type->GetFullCompilerType().AddVolatileModifier();
394
break;
395
case CTFType::eRestrict:
396
compiler_type = ref_type->GetFullCompilerType().AddRestrictModifier();
397
break;
398
default:
399
return llvm::make_error<llvm::StringError>(
400
llvm::formatv("ParseModifier called with unsupported kind: {0}",
401
ctf_modifier.kind),
402
llvm::inconvertibleErrorCode());
403
}
404
405
Declaration decl;
406
return MakeType(ctf_modifier.uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
407
Type::eEncodingIsUID, decl, compiler_type,
408
lldb_private::Type::ResolveState::Full);
409
}
410
411
llvm::Expected<lldb::TypeSP>
412
SymbolFileCTF::CreateTypedef(const CTFTypedef &ctf_typedef) {
413
Type *underlying_type = ResolveTypeUID(ctf_typedef.type);
414
if (!underlying_type)
415
return llvm::make_error<llvm::StringError>(
416
llvm::formatv("Could not find typedef underlying type: {0}",
417
ctf_typedef.type),
418
llvm::inconvertibleErrorCode());
419
420
CompilerType target_ast_type = underlying_type->GetFullCompilerType();
421
clang::DeclContext *decl_ctx = m_ast->GetTranslationUnitDecl();
422
CompilerType ast_typedef = target_ast_type.CreateTypedef(
423
ctf_typedef.name.data(), m_ast->CreateDeclContext(decl_ctx), 0);
424
425
Declaration decl;
426
return MakeType(ctf_typedef.uid, ConstString(ctf_typedef.name), 0, nullptr,
427
LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
428
ast_typedef, lldb_private::Type::ResolveState::Full);
429
}
430
431
llvm::Expected<lldb::TypeSP>
432
SymbolFileCTF::CreateArray(const CTFArray &ctf_array) {
433
Type *element_type = ResolveTypeUID(ctf_array.type);
434
if (!element_type)
435
return llvm::make_error<llvm::StringError>(
436
llvm::formatv("Could not find array element type: {0}", ctf_array.type),
437
llvm::inconvertibleErrorCode());
438
439
std::optional<uint64_t> element_size = element_type->GetByteSize(nullptr);
440
if (!element_size)
441
return llvm::make_error<llvm::StringError>(
442
llvm::formatv("could not get element size of type: {0}",
443
ctf_array.type),
444
llvm::inconvertibleErrorCode());
445
446
uint64_t size = ctf_array.nelems * *element_size;
447
448
CompilerType compiler_type = m_ast->CreateArrayType(
449
element_type->GetFullCompilerType(), ctf_array.nelems,
450
/*is_gnu_vector*/ false);
451
452
Declaration decl;
453
return MakeType(ctf_array.uid, ConstString(), size, nullptr, LLDB_INVALID_UID,
454
Type::eEncodingIsUID, decl, compiler_type,
455
lldb_private::Type::ResolveState::Full);
456
}
457
458
llvm::Expected<lldb::TypeSP>
459
SymbolFileCTF::CreateEnum(const CTFEnum &ctf_enum) {
460
Declaration decl;
461
CompilerType enum_type = m_ast->CreateEnumerationType(
462
ctf_enum.name, m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(),
463
decl, m_ast->GetBasicType(eBasicTypeInt),
464
/*is_scoped=*/false);
465
466
for (const CTFEnum::Value &value : ctf_enum.values) {
467
Declaration value_decl;
468
m_ast->AddEnumerationValueToEnumerationType(
469
enum_type, value_decl, value.name.data(), value.value, ctf_enum.size);
470
}
471
TypeSystemClang::CompleteTagDeclarationDefinition(enum_type);
472
473
return MakeType(ctf_enum.uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
474
Type::eEncodingIsUID, decl, enum_type,
475
lldb_private::Type::ResolveState::Full);
476
}
477
478
llvm::Expected<lldb::TypeSP>
479
SymbolFileCTF::CreateFunction(const CTFFunction &ctf_function) {
480
std::vector<CompilerType> arg_types;
481
for (uint32_t arg : ctf_function.args) {
482
if (Type *arg_type = ResolveTypeUID(arg))
483
arg_types.push_back(arg_type->GetFullCompilerType());
484
}
485
486
Type *ret_type = ResolveTypeUID(ctf_function.return_type);
487
if (!ret_type)
488
return llvm::make_error<llvm::StringError>(
489
llvm::formatv("Could not find function return type: {0}",
490
ctf_function.return_type),
491
llvm::inconvertibleErrorCode());
492
493
CompilerType func_type = m_ast->CreateFunctionType(
494
ret_type->GetFullCompilerType(), arg_types.data(), arg_types.size(),
495
ctf_function.variadic, 0, clang::CallingConv::CC_C);
496
497
Declaration decl;
498
return MakeType(ctf_function.uid, ConstString(ctf_function.name), 0, nullptr,
499
LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_type,
500
lldb_private::Type::ResolveState::Full);
501
}
502
503
llvm::Expected<lldb::TypeSP>
504
SymbolFileCTF::CreateRecord(const CTFRecord &ctf_record) {
505
const clang::TagTypeKind tag_kind = TranslateRecordKind(ctf_record.kind);
506
CompilerType record_type = m_ast->CreateRecordType(
507
nullptr, OptionalClangModuleID(), eAccessPublic, ctf_record.name.data(),
508
llvm::to_underlying(tag_kind), eLanguageTypeC);
509
m_compiler_types[record_type.GetOpaqueQualType()] = &ctf_record;
510
Declaration decl;
511
return MakeType(ctf_record.uid, ConstString(ctf_record.name), ctf_record.size,
512
nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID,
513
decl, record_type, lldb_private::Type::ResolveState::Forward);
514
}
515
516
bool SymbolFileCTF::CompleteType(CompilerType &compiler_type) {
517
// Check if we have a CTF type for the given incomplete compiler type.
518
auto it = m_compiler_types.find(compiler_type.GetOpaqueQualType());
519
if (it == m_compiler_types.end())
520
return false;
521
522
const CTFType *ctf_type = it->second;
523
assert(ctf_type && "m_compiler_types should only contain valid CTF types");
524
525
// We only support resolving record types.
526
assert(llvm::isa<CTFRecord>(ctf_type));
527
528
// Cast to the appropriate CTF type.
529
const CTFRecord *ctf_record = static_cast<const CTFRecord *>(ctf_type);
530
531
// If any of the fields are incomplete, we cannot complete the type.
532
for (const CTFRecord::Field &field : ctf_record->fields) {
533
if (!ResolveTypeUID(field.type)) {
534
LLDB_LOG(GetLog(LLDBLog::Symbols),
535
"Cannot complete type {0} because field {1} is incomplete",
536
ctf_type->uid, field.type);
537
return false;
538
}
539
}
540
541
// Complete the record type.
542
m_ast->StartTagDeclarationDefinition(compiler_type);
543
for (const CTFRecord::Field &field : ctf_record->fields) {
544
Type *field_type = ResolveTypeUID(field.type);
545
assert(field_type && "field must be complete");
546
const uint32_t field_size = field_type->GetByteSize(nullptr).value_or(0);
547
TypeSystemClang::AddFieldToRecordType(compiler_type, field.name,
548
field_type->GetFullCompilerType(),
549
eAccessPublic, field_size);
550
}
551
m_ast->CompleteTagDeclarationDefinition(compiler_type);
552
553
// Now that the compiler type is complete, we don't need to remember it
554
// anymore and can remove the CTF record type.
555
m_compiler_types.erase(compiler_type.GetOpaqueQualType());
556
m_ctf_types.erase(ctf_type->uid);
557
558
return true;
559
}
560
561
llvm::Expected<lldb::TypeSP>
562
SymbolFileCTF::CreateForward(const CTFForward &ctf_forward) {
563
CompilerType forward_compiler_type = m_ast->CreateRecordType(
564
nullptr, OptionalClangModuleID(), eAccessPublic, ctf_forward.name,
565
llvm::to_underlying(clang::TagTypeKind::Struct), eLanguageTypeC);
566
Declaration decl;
567
return MakeType(ctf_forward.uid, ConstString(ctf_forward.name), 0, nullptr,
568
LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
569
forward_compiler_type, Type::ResolveState::Forward);
570
}
571
572
llvm::Expected<TypeSP> SymbolFileCTF::CreateType(CTFType *ctf_type) {
573
if (!ctf_type)
574
return llvm::make_error<llvm::StringError>(
575
"cannot create type for unparsed type", llvm::inconvertibleErrorCode());
576
577
switch (ctf_type->kind) {
578
case CTFType::Kind::eInteger:
579
return CreateInteger(*static_cast<CTFInteger *>(ctf_type));
580
case CTFType::Kind::eConst:
581
case CTFType::Kind::ePointer:
582
case CTFType::Kind::eRestrict:
583
case CTFType::Kind::eVolatile:
584
return CreateModifier(*static_cast<CTFModifier *>(ctf_type));
585
case CTFType::Kind::eTypedef:
586
return CreateTypedef(*static_cast<CTFTypedef *>(ctf_type));
587
case CTFType::Kind::eArray:
588
return CreateArray(*static_cast<CTFArray *>(ctf_type));
589
case CTFType::Kind::eEnum:
590
return CreateEnum(*static_cast<CTFEnum *>(ctf_type));
591
case CTFType::Kind::eFunction:
592
return CreateFunction(*static_cast<CTFFunction *>(ctf_type));
593
case CTFType::Kind::eStruct:
594
case CTFType::Kind::eUnion:
595
return CreateRecord(*static_cast<CTFRecord *>(ctf_type));
596
case CTFType::Kind::eForward:
597
return CreateForward(*static_cast<CTFForward *>(ctf_type));
598
case CTFType::Kind::eUnknown:
599
case CTFType::Kind::eFloat:
600
case CTFType::Kind::eSlice:
601
return llvm::make_error<llvm::StringError>(
602
llvm::formatv("unsupported type (uid = {0}, name = {1}, kind = {2})",
603
ctf_type->uid, ctf_type->name, ctf_type->kind),
604
llvm::inconvertibleErrorCode());
605
}
606
llvm_unreachable("Unexpected CTF type kind");
607
}
608
609
llvm::Expected<std::unique_ptr<CTFType>>
610
SymbolFileCTF::ParseType(lldb::offset_t &offset, lldb::user_id_t uid) {
611
ctf_stype_t ctf_stype;
612
ctf_stype.name = m_data.GetU32(&offset);
613
ctf_stype.info = m_data.GetU32(&offset);
614
ctf_stype.size = m_data.GetU32(&offset);
615
616
llvm::StringRef name = ReadString(ctf_stype.name);
617
const uint32_t kind = GetKind(ctf_stype.info);
618
const uint32_t variable_length = GetVLen(ctf_stype.info);
619
const uint32_t type = ctf_stype.GetType();
620
const uint32_t size = ctf_stype.GetSize();
621
622
switch (kind) {
623
case TypeKind::eInteger: {
624
const uint32_t vdata = m_data.GetU32(&offset);
625
const uint32_t bits = GetBits(vdata);
626
const uint32_t encoding = GetEncoding(vdata);
627
return std::make_unique<CTFInteger>(uid, name, bits, encoding);
628
}
629
case TypeKind::eConst:
630
return std::make_unique<CTFConst>(uid, type);
631
case TypeKind::ePointer:
632
return std::make_unique<CTFPointer>(uid, type);
633
case TypeKind::eRestrict:
634
return std::make_unique<CTFRestrict>(uid, type);
635
case TypeKind::eVolatile:
636
return std::make_unique<CTFVolatile>(uid, type);
637
case TypeKind::eTypedef:
638
return std::make_unique<CTFTypedef>(uid, name, type);
639
case TypeKind::eArray: {
640
const uint32_t type = m_data.GetU32(&offset);
641
const uint32_t index = m_data.GetU32(&offset);
642
const uint32_t nelems = m_data.GetU32(&offset);
643
return std::make_unique<CTFArray>(uid, name, type, index, nelems);
644
}
645
case TypeKind::eEnum: {
646
std::vector<CTFEnum::Value> values;
647
for (uint32_t i = 0; i < variable_length; ++i) {
648
const uint32_t value_name = m_data.GetU32(&offset);
649
const uint32_t value = m_data.GetU32(&offset);
650
values.emplace_back(ReadString(value_name), value);
651
}
652
return std::make_unique<CTFEnum>(uid, name, variable_length, size, values);
653
}
654
case TypeKind::eFunction: {
655
std::vector<uint32_t> args;
656
bool variadic = false;
657
for (uint32_t i = 0; i < variable_length; ++i) {
658
const uint32_t arg_uid = m_data.GetU32(&offset);
659
// If the last argument is 0, this is a variadic function.
660
if (arg_uid == 0) {
661
variadic = true;
662
break;
663
}
664
args.push_back(arg_uid);
665
}
666
// If the number of arguments is odd, a single uint32_t of padding is
667
// inserted to maintain alignment.
668
if (variable_length % 2 == 1)
669
m_data.GetU32(&offset);
670
return std::make_unique<CTFFunction>(uid, name, variable_length, type, args,
671
variadic);
672
}
673
case TypeKind::eStruct:
674
case TypeKind::eUnion: {
675
std::vector<CTFRecord::Field> fields;
676
for (uint32_t i = 0; i < variable_length; ++i) {
677
const uint32_t field_name = m_data.GetU32(&offset);
678
const uint32_t type = m_data.GetU32(&offset);
679
uint64_t field_offset = 0;
680
if (size < g_ctf_field_threshold) {
681
field_offset = m_data.GetU16(&offset);
682
m_data.GetU16(&offset); // Padding
683
} else {
684
const uint32_t offset_hi = m_data.GetU32(&offset);
685
const uint32_t offset_lo = m_data.GetU32(&offset);
686
field_offset = (((uint64_t)offset_hi) << 32) | ((uint64_t)offset_lo);
687
}
688
fields.emplace_back(ReadString(field_name), type, field_offset);
689
}
690
return std::make_unique<CTFRecord>(static_cast<CTFType::Kind>(kind), uid,
691
name, variable_length, size, fields);
692
}
693
case TypeKind::eForward:
694
return std::make_unique<CTFForward>(uid, name);
695
case TypeKind::eUnknown:
696
return std::make_unique<CTFType>(static_cast<CTFType::Kind>(kind), uid,
697
name);
698
case TypeKind::eFloat:
699
case TypeKind::eSlice:
700
offset += (variable_length * sizeof(uint32_t));
701
break;
702
}
703
704
return llvm::make_error<llvm::StringError>(
705
llvm::formatv("unsupported type (name = {0}, kind = {1}, vlength = {2})",
706
name, kind, variable_length),
707
llvm::inconvertibleErrorCode());
708
}
709
710
size_t SymbolFileCTF::ParseTypes(CompileUnit &cu) {
711
if (!ParseHeader())
712
return 0;
713
714
if (!m_types.empty())
715
return 0;
716
717
if (!m_ast)
718
return 0;
719
720
Log *log = GetLog(LLDBLog::Symbols);
721
LLDB_LOG(log, "Parsing CTF types");
722
723
lldb::offset_t type_offset = m_body_offset + m_header->typeoff;
724
const lldb::offset_t type_offset_end = m_body_offset + m_header->stroff;
725
726
lldb::user_id_t type_uid = 1;
727
while (type_offset < type_offset_end) {
728
llvm::Expected<std::unique_ptr<CTFType>> type_or_error =
729
ParseType(type_offset, type_uid);
730
if (type_or_error) {
731
m_ctf_types[(*type_or_error)->uid] = std::move(*type_or_error);
732
} else {
733
LLDB_LOG_ERROR(log, type_or_error.takeError(),
734
"Failed to parse type {1} at offset {2}: {0}", type_uid,
735
type_offset);
736
}
737
type_uid++;
738
}
739
740
LLDB_LOG(log, "Parsed {0} CTF types", m_ctf_types.size());
741
742
for (lldb::user_id_t uid = 1; uid < type_uid; ++uid)
743
ResolveTypeUID(uid);
744
745
LLDB_LOG(log, "Created {0} CTF types", m_types.size());
746
747
return m_types.size();
748
}
749
750
size_t SymbolFileCTF::ParseFunctions(CompileUnit &cu) {
751
if (!ParseHeader())
752
return 0;
753
754
if (!m_functions.empty())
755
return 0;
756
757
if (!m_ast)
758
return 0;
759
760
Symtab *symtab = GetObjectFile()->GetModule()->GetSymtab();
761
if (!symtab)
762
return 0;
763
764
Log *log = GetLog(LLDBLog::Symbols);
765
LLDB_LOG(log, "Parsing CTF functions");
766
767
lldb::offset_t function_offset = m_body_offset + m_header->funcoff;
768
const lldb::offset_t function_offset_end = m_body_offset + m_header->typeoff;
769
770
uint32_t symbol_idx = 0;
771
Declaration decl;
772
while (function_offset < function_offset_end) {
773
const uint32_t info = m_data.GetU32(&function_offset);
774
const uint16_t kind = GetKind(info);
775
const uint16_t variable_length = GetVLen(info);
776
777
Symbol *symbol = symtab->FindSymbolWithType(
778
eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, symbol_idx);
779
780
// Skip padding.
781
if (kind == TypeKind::eUnknown && variable_length == 0)
782
continue;
783
784
// Skip unexpected kinds.
785
if (kind != TypeKind::eFunction)
786
continue;
787
788
const uint32_t ret_uid = m_data.GetU32(&function_offset);
789
const uint32_t num_args = variable_length;
790
791
std::vector<CompilerType> arg_types;
792
arg_types.reserve(num_args);
793
794
bool is_variadic = false;
795
for (uint32_t i = 0; i < variable_length; i++) {
796
const uint32_t arg_uid = m_data.GetU32(&function_offset);
797
798
// If the last argument is 0, this is a variadic function.
799
if (arg_uid == 0) {
800
is_variadic = true;
801
break;
802
}
803
804
Type *arg_type = ResolveTypeUID(arg_uid);
805
arg_types.push_back(arg_type ? arg_type->GetFullCompilerType()
806
: CompilerType());
807
}
808
809
if (symbol) {
810
Type *ret_type = ResolveTypeUID(ret_uid);
811
AddressRange func_range =
812
AddressRange(symbol->GetFileAddress(), symbol->GetByteSize(),
813
GetObjectFile()->GetModule()->GetSectionList());
814
815
// Create function type.
816
CompilerType func_type = m_ast->CreateFunctionType(
817
ret_type ? ret_type->GetFullCompilerType() : CompilerType(),
818
arg_types.data(), arg_types.size(), is_variadic, 0,
819
clang::CallingConv::CC_C);
820
lldb::user_id_t function_type_uid = m_types.size() + 1;
821
TypeSP type_sp =
822
MakeType(function_type_uid, symbol->GetName(), 0, nullptr,
823
LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_type,
824
lldb_private::Type::ResolveState::Full);
825
m_types[function_type_uid] = type_sp;
826
827
// Create function.
828
lldb::user_id_t func_uid = m_functions.size();
829
FunctionSP function_sp = std::make_shared<Function>(
830
&cu, func_uid, function_type_uid, symbol->GetMangled(), type_sp.get(),
831
func_range);
832
m_functions.emplace_back(function_sp);
833
cu.AddFunction(function_sp);
834
}
835
}
836
837
LLDB_LOG(log, "CTF parsed {0} functions", m_functions.size());
838
839
return m_functions.size();
840
}
841
842
static DWARFExpression CreateDWARFExpression(ModuleSP module_sp,
843
const Symbol &symbol) {
844
if (!module_sp)
845
return DWARFExpression();
846
847
const ArchSpec &architecture = module_sp->GetArchitecture();
848
ByteOrder byte_order = architecture.GetByteOrder();
849
uint32_t address_size = architecture.GetAddressByteSize();
850
uint32_t byte_size = architecture.GetDataByteSize();
851
852
StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
853
stream.PutHex8(lldb_private::dwarf::DW_OP_addr);
854
stream.PutMaxHex64(symbol.GetFileAddress(), address_size, byte_order);
855
856
DataBufferSP buffer =
857
std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
858
lldb_private::DataExtractor extractor(buffer, byte_order, address_size,
859
byte_size);
860
DWARFExpression result(extractor);
861
result.SetRegisterKind(eRegisterKindDWARF);
862
863
return result;
864
}
865
866
size_t SymbolFileCTF::ParseObjects(CompileUnit &comp_unit) {
867
if (!ParseHeader())
868
return 0;
869
870
if (!m_variables.empty())
871
return 0;
872
873
if (!m_ast)
874
return 0;
875
876
ModuleSP module_sp = GetObjectFile()->GetModule();
877
Symtab *symtab = module_sp->GetSymtab();
878
if (!symtab)
879
return 0;
880
881
Log *log = GetLog(LLDBLog::Symbols);
882
LLDB_LOG(log, "Parsing CTF objects");
883
884
lldb::offset_t object_offset = m_body_offset + m_header->objtoff;
885
const lldb::offset_t object_offset_end = m_body_offset + m_header->funcoff;
886
887
uint32_t symbol_idx = 0;
888
Declaration decl;
889
while (object_offset < object_offset_end) {
890
const uint32_t type_uid = m_data.GetU32(&object_offset);
891
892
if (Symbol *symbol =
893
symtab->FindSymbolWithType(eSymbolTypeData, Symtab::eDebugYes,
894
Symtab::eVisibilityAny, symbol_idx)) {
895
Variable::RangeList ranges;
896
ranges.Append(symbol->GetFileAddress(), symbol->GetByteSize());
897
898
auto type_sp = std::make_shared<SymbolFileType>(*this, type_uid);
899
900
DWARFExpressionList location(
901
module_sp, CreateDWARFExpression(module_sp, *symbol), nullptr);
902
903
lldb::user_id_t variable_type_uid = m_variables.size();
904
m_variables.emplace_back(std::make_shared<Variable>(
905
variable_type_uid, symbol->GetName().AsCString(),
906
symbol->GetName().AsCString(), type_sp, eValueTypeVariableGlobal,
907
m_comp_unit_sp.get(), ranges, &decl, location, symbol->IsExternal(),
908
/*artificial=*/false,
909
/*location_is_constant_data*/ false));
910
}
911
}
912
913
LLDB_LOG(log, "Parsed {0} CTF objects", m_variables.size());
914
915
return m_variables.size();
916
}
917
918
uint32_t SymbolFileCTF::CalculateAbilities() {
919
if (!m_objfile_sp)
920
return 0;
921
922
if (!ParseHeader())
923
return 0;
924
925
return VariableTypes | Functions | GlobalVariables;
926
}
927
928
uint32_t SymbolFileCTF::ResolveSymbolContext(const Address &so_addr,
929
SymbolContextItem resolve_scope,
930
SymbolContext &sc) {
931
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
932
if (m_objfile_sp->GetSymtab() == nullptr)
933
return 0;
934
935
uint32_t resolved_flags = 0;
936
937
// Resolve symbols.
938
if (resolve_scope & eSymbolContextSymbol) {
939
sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress(
940
so_addr.GetFileAddress());
941
if (sc.symbol)
942
resolved_flags |= eSymbolContextSymbol;
943
}
944
945
// Resolve functions.
946
if (resolve_scope & eSymbolContextFunction) {
947
for (FunctionSP function_sp : m_functions) {
948
if (function_sp->GetAddressRange().ContainsFileAddress(
949
so_addr.GetFileAddress())) {
950
sc.function = function_sp.get();
951
resolved_flags |= eSymbolContextFunction;
952
break;
953
}
954
}
955
}
956
957
// Resolve variables.
958
if (resolve_scope & eSymbolContextVariable) {
959
for (VariableSP variable_sp : m_variables) {
960
if (variable_sp->LocationIsValidForAddress(so_addr.GetFileAddress())) {
961
sc.variable = variable_sp.get();
962
break;
963
}
964
}
965
}
966
967
return resolved_flags;
968
}
969
970
CompUnitSP SymbolFileCTF::ParseCompileUnitAtIndex(uint32_t idx) {
971
if (idx == 0)
972
return m_comp_unit_sp;
973
return {};
974
}
975
976
size_t
977
SymbolFileCTF::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
978
return ParseObjects(*m_comp_unit_sp);
979
}
980
981
void SymbolFileCTF::AddSymbols(Symtab &symtab) {
982
// CTF does not encode symbols.
983
// We rely on the existing symbol table to map symbols to type.
984
}
985
986
lldb_private::Type *SymbolFileCTF::ResolveTypeUID(lldb::user_id_t type_uid) {
987
auto type_it = m_types.find(type_uid);
988
if (type_it != m_types.end())
989
return type_it->second.get();
990
991
auto ctf_type_it = m_ctf_types.find(type_uid);
992
if (ctf_type_it == m_ctf_types.end())
993
return nullptr;
994
995
CTFType *ctf_type = ctf_type_it->second.get();
996
assert(ctf_type && "m_ctf_types should only contain valid CTF types");
997
998
Log *log = GetLog(LLDBLog::Symbols);
999
1000
llvm::Expected<TypeSP> type_or_error = CreateType(ctf_type);
1001
if (!type_or_error) {
1002
LLDB_LOG_ERROR(log, type_or_error.takeError(),
1003
"Failed to create type for {1}: {0}", ctf_type->uid);
1004
return {};
1005
}
1006
1007
TypeSP type_sp = *type_or_error;
1008
1009
if (log) {
1010
StreamString ss;
1011
type_sp->Dump(&ss, true);
1012
LLDB_LOGV(log, "Adding type {0}: {1}", type_sp->GetID(),
1013
llvm::StringRef(ss.GetString()).rtrim());
1014
}
1015
1016
m_types[type_uid] = type_sp;
1017
1018
// Except for record types which we'll need to complete later, we don't need
1019
// the CTF type anymore.
1020
if (!isa<CTFRecord>(ctf_type))
1021
m_ctf_types.erase(type_uid);
1022
1023
return type_sp.get();
1024
}
1025
1026
void SymbolFileCTF::FindTypes(const lldb_private::TypeQuery &match,
1027
lldb_private::TypeResults &results) {
1028
// Make sure we haven't already searched this SymbolFile before.
1029
if (results.AlreadySearched(this))
1030
return;
1031
1032
ConstString name = match.GetTypeBasename();
1033
for (TypeSP type_sp : GetTypeList().Types()) {
1034
if (type_sp && type_sp->GetName() == name) {
1035
results.InsertUnique(type_sp);
1036
if (results.Done(match))
1037
return;
1038
}
1039
}
1040
}
1041
1042
void SymbolFileCTF::FindTypesByRegex(
1043
const lldb_private::RegularExpression &regex, uint32_t max_matches,
1044
lldb_private::TypeMap &types) {
1045
ParseTypes(*m_comp_unit_sp);
1046
1047
size_t matches = 0;
1048
for (TypeSP type_sp : GetTypeList().Types()) {
1049
if (matches == max_matches)
1050
break;
1051
if (type_sp && regex.Execute(type_sp->GetName()))
1052
types.Insert(type_sp);
1053
matches++;
1054
}
1055
}
1056
1057
void SymbolFileCTF::FindFunctions(
1058
const lldb_private::Module::LookupInfo &lookup_info,
1059
const lldb_private::CompilerDeclContext &parent_decl_ctx,
1060
bool include_inlines, lldb_private::SymbolContextList &sc_list) {
1061
ParseFunctions(*m_comp_unit_sp);
1062
1063
ConstString name = lookup_info.GetLookupName();
1064
for (FunctionSP function_sp : m_functions) {
1065
if (function_sp && function_sp->GetName() == name) {
1066
lldb_private::SymbolContext sc;
1067
sc.comp_unit = m_comp_unit_sp.get();
1068
sc.function = function_sp.get();
1069
sc_list.Append(sc);
1070
}
1071
}
1072
}
1073
1074
void SymbolFileCTF::FindFunctions(const lldb_private::RegularExpression &regex,
1075
bool include_inlines,
1076
lldb_private::SymbolContextList &sc_list) {
1077
for (FunctionSP function_sp : m_functions) {
1078
if (function_sp && regex.Execute(function_sp->GetName())) {
1079
lldb_private::SymbolContext sc;
1080
sc.comp_unit = m_comp_unit_sp.get();
1081
sc.function = function_sp.get();
1082
sc_list.Append(sc);
1083
}
1084
}
1085
}
1086
1087
void SymbolFileCTF::FindGlobalVariables(
1088
lldb_private::ConstString name,
1089
const lldb_private::CompilerDeclContext &parent_decl_ctx,
1090
uint32_t max_matches, lldb_private::VariableList &variables) {
1091
ParseObjects(*m_comp_unit_sp);
1092
1093
size_t matches = 0;
1094
for (VariableSP variable_sp : m_variables) {
1095
if (matches == max_matches)
1096
break;
1097
if (variable_sp && variable_sp->GetName() == name) {
1098
variables.AddVariable(variable_sp);
1099
matches++;
1100
}
1101
}
1102
}
1103
1104
void SymbolFileCTF::FindGlobalVariables(
1105
const lldb_private::RegularExpression &regex, uint32_t max_matches,
1106
lldb_private::VariableList &variables) {
1107
ParseObjects(*m_comp_unit_sp);
1108
1109
size_t matches = 0;
1110
for (VariableSP variable_sp : m_variables) {
1111
if (matches == max_matches)
1112
break;
1113
if (variable_sp && regex.Execute(variable_sp->GetName())) {
1114
variables.AddVariable(variable_sp);
1115
matches++;
1116
}
1117
}
1118
}
1119
1120