LLDB mainline
Symbol.cpp
Go to the documentation of this file.
1//===-- Symbol.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
10
11#include "lldb/Core/Address.h"
12#include "lldb/Core/Debugger.h"
13#include "lldb/Core/Module.h"
15#include "lldb/Core/Section.h"
19#include "lldb/Symbol/Symtab.h"
20#include "lldb/Target/Process.h"
21#include "lldb/Target/Target.h"
23#include "lldb/Utility/Stream.h"
24#include "llvm/ADT/StringSwitch.h"
25
26using namespace lldb;
27using namespace lldb_private;
28
30 : SymbolContextScope(), m_type_data_resolved(false), m_is_synthetic(false),
31 m_is_debug(false), m_is_external(false), m_size_is_sibling(false),
32 m_size_is_synthesized(false), m_size_is_valid(false),
33 m_demangled_is_synthesized(false), m_contains_linker_annotations(false),
34 m_is_weak(false), m_type(eSymbolTypeInvalid), m_mangled(),
35 m_addr_range() {}
36
37Symbol::Symbol(uint32_t symID, llvm::StringRef name, SymbolType type,
38 bool external, bool is_debug, bool is_trampoline,
39 bool is_artificial, const lldb::SectionSP &section_sp,
40 addr_t offset, addr_t size, bool size_is_valid,
41 bool contains_linker_annotations, uint32_t flags)
42 : SymbolContextScope(), m_uid(symID), m_type_data_resolved(false),
43 m_is_synthetic(is_artificial), m_is_debug(is_debug),
44 m_is_external(external), m_size_is_sibling(false),
45 m_size_is_synthesized(false), m_size_is_valid(size_is_valid || size > 0),
46 m_demangled_is_synthesized(false),
47 m_contains_linker_annotations(contains_linker_annotations),
48 m_is_weak(false), m_type(type), m_mangled(name),
49 m_addr_range(section_sp, offset, size), m_flags(flags) {}
50
51Symbol::Symbol(uint32_t symID, const Mangled &mangled, SymbolType type,
52 bool external, bool is_debug, bool is_trampoline,
53 bool is_artificial, const AddressRange &range,
54 bool size_is_valid, bool contains_linker_annotations,
55 uint32_t flags)
56 : SymbolContextScope(), m_uid(symID), m_type_data_resolved(false),
57 m_is_synthetic(is_artificial), m_is_debug(is_debug),
58 m_is_external(external), m_size_is_sibling(false),
59 m_size_is_synthesized(false),
60 m_size_is_valid(size_is_valid || range.GetByteSize() > 0),
61 m_demangled_is_synthesized(false),
62 m_contains_linker_annotations(contains_linker_annotations),
63 m_is_weak(false), m_type(type), m_mangled(mangled), m_addr_range(range),
64 m_flags(flags) {}
65
67 : SymbolContextScope(rhs), m_uid(rhs.m_uid), m_type_data(rhs.m_type_data),
68 m_type_data_resolved(rhs.m_type_data_resolved),
69 m_is_synthetic(rhs.m_is_synthetic), m_is_debug(rhs.m_is_debug),
70 m_is_external(rhs.m_is_external),
71 m_size_is_sibling(rhs.m_size_is_sibling), m_size_is_synthesized(false),
72 m_size_is_valid(rhs.m_size_is_valid),
73 m_demangled_is_synthesized(rhs.m_demangled_is_synthesized),
74 m_contains_linker_annotations(rhs.m_contains_linker_annotations),
75 m_is_weak(rhs.m_is_weak), m_type(rhs.m_type), m_mangled(rhs.m_mangled),
76 m_addr_range(rhs.m_addr_range), m_flags(rhs.m_flags) {}
77
78const Symbol &Symbol::operator=(const Symbol &rhs) {
79 if (this != &rhs) {
80 SymbolContextScope::operator=(rhs);
81 m_uid = rhs.m_uid;
92 m_is_weak = rhs.m_is_weak;
93 m_type = rhs.m_type;
94 m_mangled = rhs.m_mangled;
96 m_flags = rhs.m_flags;
97 }
98 return *this;
99}
100
101llvm::Expected<Symbol> Symbol::FromJSON(const JSONSymbol &symbol,
102 SectionList *section_list) {
103 if (!section_list)
104 return llvm::make_error<llvm::StringError>("no section list provided",
105 llvm::inconvertibleErrorCode());
106
107 if (!symbol.value && !symbol.address)
108 return llvm::make_error<llvm::StringError>(
109 "symbol must contain either a value or an address",
110 llvm::inconvertibleErrorCode());
111
112 if (symbol.value && symbol.address)
113 return llvm::make_error<llvm::StringError>(
114 "symbol cannot contain both a value and an address",
115 llvm::inconvertibleErrorCode());
116
117 const uint64_t size = symbol.size.value_or(0);
118 const bool is_artificial = false;
119 const bool is_trampoline = false;
120 const bool is_debug = false;
121 const bool external = false;
122 const bool size_is_valid = symbol.size.has_value();
123 const bool contains_linker_annotations = false;
124 const uint32_t flags = 0;
125
126 if (symbol.address) {
127 if (SectionSP section_sp =
128 section_list->FindSectionContainingFileAddress(*symbol.address)) {
129 const uint64_t offset = *symbol.address - section_sp->GetFileAddress();
130 return Symbol(symbol.id.value_or(0), Mangled(symbol.name),
131 symbol.type.value_or(eSymbolTypeAny), external, is_debug,
132 is_trampoline, is_artificial,
133 AddressRange(section_sp, offset, size), size_is_valid,
134 contains_linker_annotations, flags);
135 }
136 return llvm::make_error<llvm::StringError>(
137 llvm::formatv("no section found for address: {0:x}", *symbol.address),
138 llvm::inconvertibleErrorCode());
139 }
140
141 // Absolute symbols encode the integer value in the m_offset of the
142 // AddressRange object and the section is set to nothing.
143 return Symbol(symbol.id.value_or(0), Mangled(symbol.name),
144 symbol.type.value_or(eSymbolTypeAny), external, is_debug,
145 is_trampoline, is_artificial,
146 AddressRange(SectionSP(), *symbol.value, size), size_is_valid,
147 contains_linker_annotations, flags);
148}
149
153 m_type_data = 0;
154 m_type_data_resolved = false;
155 m_is_synthetic = false;
156 m_is_debug = false;
157 m_is_external = false;
158 m_size_is_sibling = false;
159 m_size_is_synthesized = false;
160 m_size_is_valid = false;
163 m_is_weak = false;
165 m_flags = 0;
167}
168
170 return (bool)m_addr_range.GetBaseAddress().GetSection();
171}
172
175}
176
179 // For eSymbolTypeReExported, the "const char *" from a ConstString is used
180 // as the offset in the address range base address. We can then make this
181 // back into a string that is the re-exported name.
182 intptr_t str_ptr = m_addr_range.GetBaseAddress().GetOffset();
183 if (str_ptr != 0)
184 return ConstString((const char *)str_ptr);
185 else
186 return GetName();
187 }
188 return ConstString();
189}
190
193 // For eSymbolTypeReExported, the "const char *" from a ConstString is used
194 // as the offset in the address range base address. We can then make this
195 // back into a string that is the re-exported name.
196 intptr_t str_ptr = m_addr_range.GetByteSize();
197 if (str_ptr != 0)
198 return FileSpec((const char *)str_ptr);
199 }
200 return FileSpec();
201}
202
205 // For eSymbolTypeReExported, the "const char *" from a ConstString is used
206 // as the offset in the address range base address.
207 m_addr_range.GetBaseAddress().SetOffset((uintptr_t)name.GetCString());
208}
209
212 // For eSymbolTypeReExported, the "const char *" from a ConstString is used
213 // as the offset in the address range base address.
215 (uintptr_t)ConstString(fspec.GetPath().c_str()).GetCString());
216 return true;
217 }
218 return false;
219}
220
221uint32_t Symbol::GetSiblingIndex() const {
223}
224
226
228
230 Stream *s, lldb::DescriptionLevel level, Target *target,
231 std::optional<Stream::HighlightSettings> settings) const {
232 s->Printf("id = {0x%8.8x}", m_uid);
233
235 if (ValueIsAddress()) {
236 const lldb::addr_t byte_size = GetByteSize();
237 if (byte_size > 0) {
238 s->PutCString(", range = ");
241 } else {
242 s->PutCString(", address = ");
243 m_addr_range.GetBaseAddress().Dump(s, target,
246 }
247 } else
248 s->Printf(", value = 0x%16.16" PRIx64,
250 } else {
252 s->Printf(", sibling = %5" PRIu64,
254 else
255 s->Printf(", value = 0x%16.16" PRIx64,
257 }
258 if (ConstString demangled = m_mangled.GetDemangledName()) {
259 s->PutCString(", name=\"");
260 s->PutCStringColorHighlighted(demangled.GetStringRef(), settings);
261 s->PutCString("\"");
262 }
263 if (ConstString mangled_name = m_mangled.GetMangledName()) {
264 s->PutCString(", mangled=\"");
265 s->PutCStringColorHighlighted(mangled_name.GetStringRef(), settings);
266 s->PutCString("\"");
267 }
268}
269
270void Symbol::Dump(Stream *s, Target *target, uint32_t index,
271 Mangled::NamePreference name_preference) const {
272 s->Printf("[%5u] %6u %c%c%c %-15s ", index, GetID(), m_is_debug ? 'D' : ' ',
273 m_is_synthetic ? 'S' : ' ', m_is_external ? 'X' : ' ',
275
276 // Make sure the size of the symbol is up to date before dumping
277 GetByteSize();
278
279 ConstString name = GetMangled().GetName(name_preference);
280 if (ValueIsAddress()) {
281 if (!m_addr_range.GetBaseAddress().Dump(s, nullptr,
283 s->Printf("%*s", 18, "");
284
285 s->PutChar(' ');
286
287 if (!m_addr_range.GetBaseAddress().Dump(s, target,
289 s->Printf("%*s", 18, "");
290
291 const char *format = m_size_is_sibling ? " Sibling -> [%5llu] 0x%8.8x %s\n"
292 : " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
293 s->Printf(format, GetByteSize(), m_flags, name.AsCString(""));
294 } else if (m_type == eSymbolTypeReExported) {
295 s->Printf(
296 " 0x%8.8x %s",
297 m_flags, name.AsCString(""));
298
299 ConstString reexport_name = GetReExportedSymbolName();
300 intptr_t shlib = m_addr_range.GetByteSize();
301 if (shlib)
302 s->Printf(" -> %s`%s\n", (const char *)shlib, reexport_name.GetCString());
303 else
304 s->Printf(" -> %s\n", reexport_name.GetCString());
305 } else {
306 const char *format =
308 ? "0x%16.16" PRIx64
309 " Sibling -> [%5llu] 0x%8.8x %s\n"
310 : "0x%16.16" PRIx64 " 0x%16.16" PRIx64
311 " 0x%8.8x %s\n";
313 m_flags, name.AsCString(""));
314 }
315}
316
321
322 const Address &base_address = m_addr_range.GetBaseAddress();
323 Function *function = base_address.CalculateSymbolContextFunction();
324 if (function) {
325 // Functions have line entries which can also potentially have end of
326 // prologue information. So if this symbol points to a function, use
327 // the prologue information from there.
328 m_type_data = function->GetPrologueByteSize();
329 } else {
330 ModuleSP module_sp(base_address.GetModule());
331 SymbolContext sc;
332 if (module_sp) {
333 uint32_t resolved_flags = module_sp->ResolveSymbolContextForAddress(
334 base_address, eSymbolContextLineEntry, sc);
335 if (resolved_flags & eSymbolContextLineEntry) {
336 // Default to the end of the first line entry.
338
339 // Set address for next line.
340 Address addr(base_address);
341 addr.Slide(m_type_data);
342
343 // Check the first few instructions and look for one that has a
344 // line number that is different than the first entry. This is also
345 // done in Function::GetPrologueByteSize().
346 uint16_t total_offset = m_type_data;
347 for (int idx = 0; idx < 6; ++idx) {
348 SymbolContext sc_temp;
349 resolved_flags = module_sp->ResolveSymbolContextForAddress(
350 addr, eSymbolContextLineEntry, sc_temp);
351 // Make sure we got line number information...
352 if (!(resolved_flags & eSymbolContextLineEntry))
353 break;
354
355 // If this line number is different than our first one, use it
356 // and we're done.
357 if (sc_temp.line_entry.line != sc.line_entry.line) {
358 m_type_data = total_offset;
359 break;
360 }
361
362 // Slide addr up to the next line address.
363 addr.Slide(sc_temp.line_entry.range.GetByteSize());
364 total_offset += sc_temp.line_entry.range.GetByteSize();
365 // If we've gone too far, bail out.
366 if (total_offset >= m_addr_range.GetByteSize())
367 break;
368 }
369
370 // Sanity check - this may be a function in the middle of code that
371 // has debug information, but not for this symbol. So the line
372 // entries surrounding us won't lie inside our function. In that
373 // case, the line entry will be bigger than we are, so we do that
374 // quick check and if that is true, we just return 0.
376 m_type_data = 0;
377 } else {
378 // TODO: expose something in Process to figure out the
379 // size of a function prologue.
380 m_type_data = 0;
381 }
382 }
383 }
384 }
385 return m_type_data;
386 }
387 return 0;
388}
389
390bool Symbol::Compare(ConstString name, SymbolType type) const {
391 if (type == eSymbolTypeAny || m_type == type) {
392 const Mangled &mangled = GetMangled();
393 return mangled.GetMangledName() == name ||
394 mangled.GetDemangledName() == name;
395 }
396 return false;
397}
398
399#define ENUM_TO_CSTRING(x) \
400 case eSymbolType##x: \
401 return #x;
402
403const char *Symbol::GetTypeAsString() const {
404 switch (m_type) {
406 ENUM_TO_CSTRING(Absolute);
407 ENUM_TO_CSTRING(Code);
408 ENUM_TO_CSTRING(Resolver);
409 ENUM_TO_CSTRING(Data);
410 ENUM_TO_CSTRING(Trampoline);
413 ENUM_TO_CSTRING(SourceFile);
414 ENUM_TO_CSTRING(HeaderFile);
416 ENUM_TO_CSTRING(CommonBlock);
418 ENUM_TO_CSTRING(Local);
419 ENUM_TO_CSTRING(Param);
421 ENUM_TO_CSTRING(VariableType);
423 ENUM_TO_CSTRING(LineHeader);
424 ENUM_TO_CSTRING(ScopeBegin);
425 ENUM_TO_CSTRING(ScopeEnd);
426 ENUM_TO_CSTRING(Additional);
427 ENUM_TO_CSTRING(Compiler);
428 ENUM_TO_CSTRING(Instrumentation);
429 ENUM_TO_CSTRING(Undefined);
430 ENUM_TO_CSTRING(ObjCClass);
431 ENUM_TO_CSTRING(ObjCMetaClass);
432 ENUM_TO_CSTRING(ObjCIVar);
433 ENUM_TO_CSTRING(ReExported);
434 default:
435 break;
436 }
437 return "<unknown SymbolType>";
438}
439
441 // Symbols can reconstruct the symbol and the module in the symbol context
442 sc->symbol = this;
443 if (ValueIsAddress())
445 else
446 sc->module_sp.reset();
447}
448
450 if (ValueIsAddress())
451 return GetAddressRef().GetModule();
452 return ModuleSP();
453}
454
456
458 bool dumped_module = false;
459 if (ValueIsAddress()) {
460 ModuleSP module_sp(GetAddressRef().GetModule());
461 if (module_sp) {
462 dumped_module = true;
463 module_sp->DumpSymbolContext(s);
464 }
465 }
466 if (dumped_module)
467 s->PutCString(", ");
468
469 s->Printf("Symbol{0x%8.8x}", GetID());
470}
471
473
475 Target &target, ConstString &reexport_name, ModuleSpec &module_spec,
476 ModuleList &seen_modules) const {
477 ModuleSP module_sp;
478 if (module_spec.GetFileSpec()) {
479 // Try searching for the module file spec first using the full path
480 module_sp = target.GetImages().FindFirstModule(module_spec);
481 if (!module_sp) {
482 // Next try and find the module by basename in case environment variables
483 // or other runtime trickery causes shared libraries to be loaded from
484 // alternate paths
485 module_spec.GetFileSpec().ClearDirectory();
486 module_sp = target.GetImages().FindFirstModule(module_spec);
487 }
488 }
489
490 if (module_sp) {
491 // There should not be cycles in the reexport list, but we don't want to
492 // crash if there are so make sure we haven't seen this before:
493 if (!seen_modules.AppendIfNeeded(module_sp))
494 return nullptr;
495
497 module_sp->FindSymbolsWithNameAndType(reexport_name, eSymbolTypeAny,
498 sc_list);
499 for (const SymbolContext &sc : sc_list) {
500 if (sc.symbol->IsExternal())
501 return sc.symbol;
502 }
503 // If we didn't find the symbol in this module, it may be because this
504 // module re-exports some whole other library. We have to search those as
505 // well:
506 seen_modules.Append(module_sp);
507
508 FileSpecList reexported_libraries =
509 module_sp->GetObjectFile()->GetReExportedLibraries();
510 size_t num_reexported_libraries = reexported_libraries.GetSize();
511 for (size_t idx = 0; idx < num_reexported_libraries; idx++) {
512 ModuleSpec reexported_module_spec;
513 reexported_module_spec.GetFileSpec() =
514 reexported_libraries.GetFileSpecAtIndex(idx);
516 target, reexport_name, reexported_module_spec, seen_modules);
517 if (result_symbol)
518 return result_symbol;
519 }
520 }
521 return nullptr;
522}
523
525 ConstString reexport_name(GetReExportedSymbolName());
526 if (reexport_name) {
527 ModuleSpec module_spec;
528 ModuleList seen_modules;
530 if (module_spec.GetFileSpec()) {
531 return ResolveReExportedSymbolInModuleSpec(target, reexport_name,
532 module_spec, seen_modules);
533 }
534 }
535 return nullptr;
536}
537
539 if (ValueIsAddress())
540 return GetAddressRef().GetFileAddress();
541 else
543}
544
546 if (ValueIsAddress())
547 return GetAddressRef().GetLoadAddress(target);
548 else
550}
551
553
556}
557
561
562 Address func_so_addr;
563
564 bool is_indirect = IsIndirect();
566 Symbol *reexported_symbol = ResolveReExportedSymbol(target);
567 if (reexported_symbol) {
568 func_so_addr = reexported_symbol->GetAddress();
569 is_indirect = reexported_symbol->IsIndirect();
570 }
571 } else {
572 func_so_addr = GetAddress();
573 is_indirect = IsIndirect();
574 }
575
576 if (func_so_addr.IsValid()) {
577 if (!target.GetProcessSP() && is_indirect) {
578 // can't resolve indirect symbols without calling a function...
580 }
581
582 lldb::addr_t load_addr =
583 func_so_addr.GetCallableLoadAddress(&target, is_indirect);
584
585 if (load_addr != LLDB_INVALID_ADDRESS) {
586 return load_addr;
587 }
588 }
589
591}
592
594 const char *flavor,
595 bool prefer_file_cache) {
597 if (module_sp && exe_ctx.HasTargetScope()) {
598 return Disassembler::DisassembleRange(module_sp->GetArchitecture(), nullptr,
599 flavor, exe_ctx.GetTargetRef(),
600 m_addr_range, !prefer_file_cache);
601 }
602 return lldb::DisassemblerSP();
603}
604
605bool Symbol::GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor,
606 bool prefer_file_cache, Stream &strm) {
607 lldb::DisassemblerSP disassembler_sp =
608 GetInstructions(exe_ctx, flavor, prefer_file_cache);
609 if (disassembler_sp) {
610 const bool show_address = true;
611 const bool show_bytes = false;
612 const bool show_control_flow_kind = false;
613 disassembler_sp->GetInstructionList().Dump(
614 &strm, show_address, show_bytes, show_control_flow_kind, &exe_ctx);
615 return true;
616 }
617 return false;
618}
619
621 return m_addr_range.ContainsFileAddress(file_addr);
622}
623
625 if (!IsSynthetic())
626 return false;
627 if (!m_mangled)
628 return true;
630 return demangled.GetStringRef().starts_with(GetSyntheticSymbolPrefix());
631}
632
634 if (m_is_synthetic && !m_mangled) {
635 // Synthetic symbol names don't mean anything, but they do uniquely
636 // identify individual symbols so we give them a unique name. The name
637 // starts with the synthetic symbol prefix, followed by a unique number.
638 // Typically the UserID of a real symbol is the symbol table index of the
639 // symbol in the object file's symbol table(s), so it will be the same
640 // every time you read in the object file. We want the same persistence for
641 // synthetic symbols so that users can identify them across multiple debug
642 // sessions, to understand crashes in those symbols and to reliably set
643 // breakpoints on them.
644 llvm::SmallString<256> name;
645 llvm::raw_svector_ostream os(name);
646 os << GetSyntheticSymbolPrefix() << GetID();
648 }
649}
650
651bool Symbol::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
652 const SectionList *section_list,
653 const StringTableReader &strtab) {
654 if (!data.ValidOffsetForDataOfSize(*offset_ptr, 8))
655 return false;
656 m_uid = data.GetU32(offset_ptr);
657 m_type_data = data.GetU16(offset_ptr);
658 const uint16_t bitfields = data.GetU16(offset_ptr);
659 m_type_data_resolved = (1u << 15 & bitfields) != 0;
660 m_is_synthetic = (1u << 14 & bitfields) != 0;
661 m_is_debug = (1u << 13 & bitfields) != 0;
662 m_is_external = (1u << 12 & bitfields) != 0;
663 m_size_is_sibling = (1u << 11 & bitfields) != 0;
664 m_size_is_synthesized = (1u << 10 & bitfields) != 0;
665 m_size_is_valid = (1u << 9 & bitfields) != 0;
666 m_demangled_is_synthesized = (1u << 8 & bitfields) != 0;
667 m_contains_linker_annotations = (1u << 7 & bitfields) != 0;
668 m_is_weak = (1u << 6 & bitfields) != 0;
669 m_type = bitfields & 0x003f;
670 if (!m_mangled.Decode(data, offset_ptr, strtab))
671 return false;
672 if (!data.ValidOffsetForDataOfSize(*offset_ptr, 20))
673 return false;
674 const bool is_addr = data.GetU8(offset_ptr) != 0;
675 const uint64_t value = data.GetU64(offset_ptr);
676 if (is_addr) {
678 section_list);
679 } else {
682 }
683 m_addr_range.SetByteSize(data.GetU64(offset_ptr));
684 m_flags = data.GetU32(offset_ptr);
685 return true;
686}
687
688/// The encoding format for the symbol is as follows:
689///
690/// uint32_t m_uid;
691/// uint16_t m_type_data;
692/// uint16_t bitfield_data;
693/// Mangled mangled;
694/// uint8_t is_addr;
695/// uint64_t file_addr_or_value;
696/// uint64_t size;
697/// uint32_t flags;
698///
699/// The only tricky thing in this encoding is encoding all of the bits in the
700/// bitfields. We use a trick to store all bitfields as a 16 bit value and we
701/// do the same thing when decoding the symbol. There are test that ensure this
702/// encoding works for each individual bit. Everything else is very easy to
703/// store.
704void Symbol::Encode(DataEncoder &file, ConstStringTable &strtab) const {
705 file.AppendU32(m_uid);
707 uint16_t bitfields = m_type;
709 bitfields |= 1u << 15;
710 if (m_is_synthetic)
711 bitfields |= 1u << 14;
712 if (m_is_debug)
713 bitfields |= 1u << 13;
714 if (m_is_external)
715 bitfields |= 1u << 12;
717 bitfields |= 1u << 11;
719 bitfields |= 1u << 10;
720 if (m_size_is_valid)
721 bitfields |= 1u << 9;
723 bitfields |= 1u << 8;
725 bitfields |= 1u << 7;
726 if (m_is_weak)
727 bitfields |= 1u << 6;
728 file.AppendU16(bitfields);
729 m_mangled.Encode(file, strtab);
730 // A symbol's value might be an address, or it might be a constant. If the
731 // symbol's base address doesn't have a section, then it is a constant value.
732 // If it does have a section, we will encode the file address and re-resolve
733 // the address when we decode it.
734 bool is_addr = m_addr_range.GetBaseAddress().GetSection().get() != nullptr;
735 file.AppendU8(is_addr);
738 file.AppendU32(m_flags);
739}
740
741bool Symbol::operator==(const Symbol &rhs) const {
742 if (m_uid != rhs.m_uid)
743 return false;
744 if (m_type_data != rhs.m_type_data)
745 return false;
747 return false;
749 return false;
750 if (m_is_debug != rhs.m_is_debug)
751 return false;
752 if (m_is_external != rhs.m_is_external)
753 return false;
755 return false;
757 return false;
759 return false;
761 return false;
763 return false;
764 if (m_is_weak != rhs.m_is_weak)
765 return false;
766 if (m_type != rhs.m_type)
767 return false;
768 if (m_mangled != rhs.m_mangled)
769 return false;
771 return false;
773 return false;
774 if (m_flags != rhs.m_flags)
775 return false;
776 return true;
777}
778
779namespace llvm {
780namespace json {
781
782bool fromJSON(const llvm::json::Value &value, lldb_private::JSONSymbol &symbol,
783 llvm::json::Path path) {
784 llvm::json::ObjectMapper o(value, path);
785 const bool mapped = o && o.map("value", symbol.value) &&
786 o.map("address", symbol.address) &&
787 o.map("size", symbol.size) && o.map("id", symbol.id) &&
788 o.map("type", symbol.type) && o.map("name", symbol.name);
789
790 if (!mapped)
791 return false;
792
793 if (!symbol.value && !symbol.address) {
794 path.report("symbol must have either a value or an address");
795 return false;
796 }
797
798 if (symbol.value && symbol.address) {
799 path.report("symbol cannot have both a value and an address");
800 return false;
801 }
802
803 return true;
804}
805
806bool fromJSON(const llvm::json::Value &value, lldb::SymbolType &type,
807 llvm::json::Path path) {
808 if (auto str = value.getAsString()) {
809 type = llvm::StringSwitch<lldb::SymbolType>(*str)
810 .Case("absolute", eSymbolTypeAbsolute)
811 .Case("code", eSymbolTypeCode)
812 .Case("resolver", eSymbolTypeResolver)
813 .Case("data", eSymbolTypeData)
814 .Case("trampoline", eSymbolTypeTrampoline)
815 .Case("runtime", eSymbolTypeRuntime)
816 .Case("exception", eSymbolTypeException)
817 .Case("sourcefile", eSymbolTypeSourceFile)
818 .Case("headerfile", eSymbolTypeHeaderFile)
819 .Case("objectfile", eSymbolTypeObjectFile)
820 .Case("commonblock", eSymbolTypeCommonBlock)
821 .Case("block", eSymbolTypeBlock)
822 .Case("local", eSymbolTypeLocal)
823 .Case("param", eSymbolTypeParam)
824 .Case("variable", eSymbolTypeVariable)
825 .Case("variableType", eSymbolTypeVariableType)
826 .Case("lineentry", eSymbolTypeLineEntry)
827 .Case("lineheader", eSymbolTypeLineHeader)
828 .Case("scopebegin", eSymbolTypeScopeBegin)
829 .Case("scopeend", eSymbolTypeScopeEnd)
830 .Case("additional,", eSymbolTypeAdditional)
831 .Case("compiler", eSymbolTypeCompiler)
832 .Case("instrumentation", eSymbolTypeInstrumentation)
833 .Case("undefined", eSymbolTypeUndefined)
834 .Case("objcclass", eSymbolTypeObjCClass)
835 .Case("objcmetaClass", eSymbolTypeObjCMetaClass)
836 .Case("objcivar", eSymbolTypeObjCIVar)
837 .Case("reexporte", eSymbolTypeReExported)
838 .Default(eSymbolTypeInvalid);
839
840 if (type == eSymbolTypeInvalid) {
841 path.report("invalid symbol type");
842 return false;
843 }
844
845 return true;
846 }
847 path.report("expected string");
848 return false;
849}
850} // namespace json
851} // namespace llvm
#define ENUM_TO_CSTRING(x)
Definition: Symbol.cpp:399
A section + offset based address range class.
Definition: AddressRange.h:25
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:209
bool ContainsFileAddress(const Address &so_addr) const
Check if a section offset address is contained in this range.
bool Dump(Stream *s, Target *target, Address::DumpStyle style, Address::DumpStyle fallback_style=Address::DumpStyleInvalid) const
Dump a description of this object to a Stream.
void Clear()
Clear the object's state.
void SetByteSize(lldb::addr_t byte_size)
Set accessor for the byte size of this range.
Definition: AddressRange.h:237
lldb::addr_t GetByteSize() const
Get accessor for the byte size of this range.
Definition: AddressRange.h:221
A section + offset based address class.
Definition: Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition: Address.cpp:313
bool ResolveAddressUsingFileSections(lldb::addr_t addr, const SectionList *sections)
Resolve a file virtual address using a section list.
Definition: Address.cpp:250
lldb::addr_t GetCallableLoadAddress(Target *target, bool is_indirect=false) const
Get the load address as a callable code load address.
Definition: Address.cpp:338
lldb::SectionSP GetSection() const
Get const accessor for the section.
Definition: Address.h:439
void Clear()
Clear the object's state.
Definition: Address.h:181
Function * CalculateSymbolContextFunction() const
Definition: Address.cpp:871
@ DumpStyleFileAddress
Display as the file address (if any).
Definition: Address.h:87
@ DumpStyleLoadAddress
Display as the load address (if resolved).
Definition: Address.h:99
bool Slide(int64_t offset)
Definition: Address.h:459
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX, bool all_ranges=false, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Dump a description of this object to a Stream.
Definition: Address.cpp:408
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition: Address.cpp:285
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:293
lldb::addr_t GetOffset() const
Get the section relative offset value.
Definition: Address.h:329
bool IsValid() const
Check if the object state is valid.
Definition: Address.h:355
bool SetOffset(lldb::addr_t offset)
Set accessor for the offset.
Definition: Address.h:448
A class that describes a single lexical block.
Definition: Block.h:41
Many cache files require string tables to store data efficiently.
A uniqued constant string class.
Definition: ConstString.h:40
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:188
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:197
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:214
An binary data encoding class.
Definition: DataEncoder.h:42
void AppendU32(uint32_t value)
void AppendU8(uint8_t value)
Append a unsigned integer to the end of the owned data.
void AppendU16(uint16_t value)
void AppendU64(uint64_t value)
An data extractor class.
Definition: DataExtractor.h:48
uint64_t GetU64(lldb::offset_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
bool ValidOffsetForDataOfSize(lldb::offset_t offset, lldb::offset_t length) const
Test the availability of length bytes of data from offset.
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
uint16_t GetU16(lldb::offset_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
uint8_t GetU8(lldb::offset_t *offset_ptr) const
Extract a uint8_t value from *offset_ptr.
static lldb::DisassemblerSP DisassembleRange(const ArchSpec &arch, const char *plugin_name, const char *flavor, Target &target, const AddressRange &disasm_range, bool force_live_memory=false)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
bool HasTargetScope() const
Returns true the ExecutionContext object contains a valid target.
Target & GetTargetRef() const
Returns a reference to the target object.
A file collection class.
Definition: FileSpecList.h:85
const FileSpec & GetFileSpecAtIndex(size_t idx) const
Get file at index.
size_t GetSize() const
Get the number of files in the file list.
A file utility class.
Definition: FileSpec.h:56
void ClearDirectory()
Clear the directory in this object.
Definition: FileSpec.cpp:360
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:367
A class that describes a function.
Definition: Function.h:399
uint32_t GetPrologueByteSize()
Get the size of the prologue instructions for this function.
Definition: Function.cpp:566
A class that handles mangled names.
Definition: Mangled.h:33
void Encode(DataEncoder &encoder, ConstStringTable &strtab) const
Encode this object into a data encoder object.
Definition: Mangled.cpp:483
@ ePreferDemangledWithoutArguments
Definition: Mangled.h:38
void SetDemangledName(ConstString name)
Definition: Mangled.h:137
ConstString GetDemangledName() const
Demangled name get accessor.
Definition: Mangled.cpp:262
bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr, const StringTableReader &strtab)
Decode a serialized version of this object from data.
Definition: Mangled.cpp:433
ConstString & GetMangledName()
Mangled name get accessor.
Definition: Mangled.h:145
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
Definition: Mangled.cpp:325
ConstString GetDisplayDemangledName() const
Display demangled name get accessor.
Definition: Mangled.cpp:312
void Clear()
Clear the mangled and demangled values.
Definition: Mangled.cpp:101
A collection class for Module objects.
Definition: ModuleList.h:103
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Definition: ModuleList.cpp:626
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
Definition: ModuleList.cpp:280
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
Definition: ModuleList.cpp:247
FileSpec & GetFileSpec()
Definition: ModuleSpec.h:53
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:44
lldb::SectionSP FindSectionContainingFileAddress(lldb::addr_t addr, uint32_t depth=UINT32_MAX) const
Definition: Section.cpp:611
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:65
size_t PutChar(char ch)
Definition: Stream.cpp:131
void PutCStringColorHighlighted(llvm::StringRef text, std::optional< HighlightSettings > settings=std::nullopt)
Output a C string to the stream with color highlighting.
Definition: Stream.cpp:75
Many cache files require string tables to store data efficiently.
Defines a list of symbol context objects.
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:34
lldb::ModuleSP module_sp
The Module for a given query.
Symbol * symbol
The Symbol for a given query.
LineEntry line_entry
The LineEntry for a given query.
bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr, const SectionList *section_list, const StringTableReader &strtab)
Decode a serialized version of this object from data.
Definition: Symbol.cpp:651
uint32_t m_uid
Definition: Symbol.h:316
uint32_t GetSiblingIndex() const
Definition: Symbol.cpp:221
uint16_t m_is_external
Definition: Symbol.h:326
uint32_t GetID() const
Definition: Symbol.h:136
lldb::addr_t GetLoadAddress(Target *target) const
Definition: Symbol.cpp:545
bool ValueIsAddress() const
Definition: Symbol.cpp:169
uint16_t m_type_data_resolved
Definition: Symbol.h:319
void SetReExportedSymbolName(ConstString name)
Definition: Symbol.cpp:203
void SetType(lldb::SymbolType type)
Definition: Symbol.h:170
void CalculateSymbolContext(SymbolContext *sc) override
Reconstruct the object's symbol context into sc.
Definition: Symbol.cpp:440
bool IsIndirect() const
Definition: Symbol.cpp:227
void SynthesizeNameIfNeeded() const
Definition: Symbol.cpp:633
const char * GetTypeAsString() const
Definition: Symbol.cpp:403
Symbol * ResolveReExportedSymbolInModuleSpec(Target &target, ConstString &reexport_name, lldb_private::ModuleSpec &module_spec, lldb_private::ModuleList &seen_modules) const
Definition: Symbol.cpp:474
bool IsSynthetic() const
Definition: Symbol.h:182
uint16_t m_is_synthetic
Definition: Symbol.h:321
uint16_t m_demangled_is_synthesized
Definition: Symbol.h:333
lldb::DisassemblerSP GetInstructions(const ExecutionContext &exe_ctx, const char *flavor, bool prefer_file_cache)
Definition: Symbol.cpp:593
lldb::addr_t GetFileAddress() const
Definition: Symbol.cpp:538
void DumpSymbolContext(Stream *s) override
Dump the object's symbol context to the stream s.
Definition: Symbol.cpp:457
lldb::ModuleSP CalculateSymbolContextModule() override
Definition: Symbol.cpp:449
bool ContainsFileAddress(lldb::addr_t file_addr) const
Definition: Symbol.cpp:620
Mangled & GetMangled()
Definition: Symbol.h:146
uint32_t m_flags
Definition: Symbol.h:345
uint16_t m_contains_linker_annotations
Definition: Symbol.h:336
uint16_t m_size_is_valid
Definition: Symbol.h:332
bool IsTrampoline() const
Definition: Symbol.cpp:225
Address & GetAddressRef()
Definition: Symbol.h:72
const Symbol & operator=(const Symbol &rhs)
Definition: Symbol.cpp:78
bool IsSyntheticWithAutoGeneratedName() const
Definition: Symbol.cpp:624
void Encode(DataEncoder &encoder, ConstStringTable &strtab) const
Encode this object into a data encoder object.
Definition: Symbol.cpp:704
Mangled m_mangled
Definition: Symbol.h:341
uint16_t m_type
Definition: Symbol.h:340
ConstString GetReExportedSymbolName() const
Definition: Symbol.cpp:177
bool Compare(ConstString name, lldb::SymbolType type) const
Definition: Symbol.cpp:390
uint16_t m_is_debug
Definition: Symbol.h:324
bool SetReExportedSymbolSharedLibrary(const FileSpec &fspec)
Definition: Symbol.cpp:210
void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Definition: Symbol.cpp:229
bool operator==(const Symbol &rhs) const
Definition: Symbol.cpp:741
static llvm::StringRef GetSyntheticSymbolPrefix()
Definition: Symbol.h:260
lldb::addr_t GetByteSize() const
Definition: Symbol.cpp:472
ConstString GetName() const
Definition: Symbol.cpp:552
lldb::SymbolType GetType() const
Definition: Symbol.h:168
Address GetAddress() const
Definition: Symbol.h:88
AddressRange m_addr_range
Definition: Symbol.h:342
ConstString GetNameNoArguments() const
Definition: Symbol.cpp:554
uint16_t m_size_is_sibling
Definition: Symbol.h:327
Symbol * ResolveReExportedSymbol(Target &target) const
Definition: Symbol.cpp:524
FileSpec GetReExportedSymbolSharedLibrary() const
Definition: Symbol.cpp:191
uint16_t m_is_weak
Definition: Symbol.h:339
uint32_t GetPrologueByteSize()
Definition: Symbol.cpp:317
uint16_t m_type_data
Definition: Symbol.h:318
ConstString GetDisplayName() const
Definition: Symbol.cpp:173
bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor, bool prefer_file_cache, Stream &strm)
Definition: Symbol.cpp:605
lldb::addr_t ResolveCallableAddress(Target &target) const
Definition: Symbol.cpp:558
uint16_t m_size_is_synthesized
Definition: Symbol.h:329
Symbol * CalculateSymbolContextSymbol() override
Definition: Symbol.cpp:455
static llvm::Expected< Symbol > FromJSON(const JSONSymbol &symbol, SectionList *section_list)
Definition: Symbol.cpp:101
void Dump(Stream *s, Target *target, uint32_t index, Mangled::NamePreference name_preference=Mangled::ePreferDemangled) const
Definition: Symbol.cpp:270
const lldb::ProcessSP & GetProcessSP() const
Definition: Target.cpp:221
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:972
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:82
#define UINT32_MAX
Definition: lldb-defines.h:19
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
bool fromJSON(const llvm::json::Value &value, TraceSupportedResponse &info, llvm::json::Path path)
Definition: SBAddress.h:15
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
uint64_t offset_t
Definition: lldb-types.h:83
SymbolType
Symbol types.
@ eSymbolTypeUndefined
@ eSymbolTypeVariableType
@ eSymbolTypeObjCMetaClass
@ eSymbolTypeReExported
@ eSymbolTypeObjCClass
@ eSymbolTypeObjectFile
@ eSymbolTypeTrampoline
@ eSymbolTypeResolver
@ eSymbolTypeParam
@ eSymbolTypeSourceFile
@ eSymbolTypeException
@ eSymbolTypeInvalid
@ eSymbolTypeVariable
@ eSymbolTypeAbsolute
@ eSymbolTypeAdditional
When symbols take more than one entry, the extra entries get this type.
@ eSymbolTypeInstrumentation
@ eSymbolTypeLocal
@ eSymbolTypeHeaderFile
@ eSymbolTypeBlock
@ eSymbolTypeCommonBlock
@ eSymbolTypeCompiler
@ eSymbolTypeLineHeader
@ eSymbolTypeObjCIVar
@ eSymbolTypeLineEntry
@ eSymbolTypeRuntime
@ eSymbolTypeScopeBegin
@ eSymbolTypeScopeEnd
std::shared_ptr< lldb_private::Disassembler > DisassemblerSP
Definition: lldb-forward.h:333
std::shared_ptr< lldb_private::Section > SectionSP
Definition: lldb-forward.h:406
uint64_t addr_t
Definition: lldb-types.h:79
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:365
Definition: Debugger.h:53
std::string name
Definition: Symbol.h:29
std::optional< uint64_t > address
Definition: Symbol.h:24
std::optional< uint64_t > id
Definition: Symbol.h:27
std::optional< lldb::SymbolType > type
Definition: Symbol.h:28
std::optional< uint64_t > value
Definition: Symbol.h:25
std::optional< uint64_t > size
Definition: Symbol.h:26
A line table entry class.
Definition: LineEntry.h:21
AddressRange range
The section offset address range for this line entry.
Definition: LineEntry.h:137
uint32_t line
The source line number, or LLDB_INVALID_LINE_NUMBER if there is no line number information.
Definition: LineEntry.h:147