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::createStringError("no section list provided");
105
106 if (!symbol.value && !symbol.address)
107 return llvm::createStringError(
108 "symbol must contain either a value or an address");
109
110 if (symbol.value && symbol.address)
111 return llvm::createStringError(
112 "symbol cannot contain both a value and an address");
113
114 const uint64_t size = symbol.size.value_or(0);
115 const bool is_artificial = false;
116 const bool is_trampoline = false;
117 const bool is_debug = false;
118 const bool external = false;
119 const bool size_is_valid = symbol.size.has_value();
120 const bool contains_linker_annotations = false;
121 const uint32_t flags = 0;
122
123 if (symbol.address) {
124 if (SectionSP section_sp =
125 section_list->FindSectionContainingFileAddress(*symbol.address)) {
126 const uint64_t offset = *symbol.address - section_sp->GetFileAddress();
127 return Symbol(symbol.id.value_or(0), Mangled(symbol.name),
128 symbol.type.value_or(eSymbolTypeAny), external, is_debug,
129 is_trampoline, is_artificial,
130 AddressRange(section_sp, offset, size), size_is_valid,
131 contains_linker_annotations, flags);
132 }
133 return llvm::createStringError(
134 llvm::formatv("no section found for address: {0:x}", *symbol.address));
135 }
136
137 // Absolute symbols encode the integer value in the m_offset of the
138 // AddressRange object and the section is set to nothing.
139 return Symbol(symbol.id.value_or(0), Mangled(symbol.name),
140 symbol.type.value_or(eSymbolTypeAny), external, is_debug,
141 is_trampoline, is_artificial,
142 AddressRange(SectionSP(), *symbol.value, size), size_is_valid,
143 contains_linker_annotations, flags);
144}
145
149 m_type_data = 0;
150 m_type_data_resolved = false;
151 m_is_synthetic = false;
152 m_is_debug = false;
153 m_is_external = false;
154 m_size_is_sibling = false;
155 m_size_is_synthesized = false;
156 m_size_is_valid = false;
159 m_is_weak = false;
161 m_flags = 0;
163}
164
166 return (bool)m_addr_range.GetBaseAddress().GetSection();
167}
168
171}
172
175 // For eSymbolTypeReExported, the "const char *" from a ConstString is used
176 // as the offset in the address range base address. We can then make this
177 // back into a string that is the re-exported name.
178 intptr_t str_ptr = m_addr_range.GetBaseAddress().GetOffset();
179 if (str_ptr != 0)
180 return ConstString((const char *)str_ptr);
181 else
182 return GetName();
183 }
184 return ConstString();
185}
186
189 // For eSymbolTypeReExported, the "const char *" from a ConstString is used
190 // as the offset in the address range base address. We can then make this
191 // back into a string that is the re-exported name.
192 intptr_t str_ptr = m_addr_range.GetByteSize();
193 if (str_ptr != 0)
194 return FileSpec((const char *)str_ptr);
195 }
196 return FileSpec();
197}
198
201 // For eSymbolTypeReExported, the "const char *" from a ConstString is used
202 // as the offset in the address range base address.
203 m_addr_range.GetBaseAddress().SetOffset((uintptr_t)name.GetCString());
204}
205
208 // For eSymbolTypeReExported, the "const char *" from a ConstString is used
209 // as the offset in the address range base address.
211 (uintptr_t)ConstString(fspec.GetPath().c_str()).GetCString());
212 return true;
213 }
214 return false;
215}
216
217uint32_t Symbol::GetSiblingIndex() const {
219}
220
222
224
226 Stream *s, lldb::DescriptionLevel level, Target *target,
227 std::optional<Stream::HighlightSettings> settings) const {
228 s->Printf("id = {0x%8.8x}", m_uid);
229
231 if (ValueIsAddress()) {
232 const lldb::addr_t byte_size = GetByteSize();
233 if (byte_size > 0) {
234 s->PutCString(", range = ");
237 } else {
238 s->PutCString(", address = ");
239 m_addr_range.GetBaseAddress().Dump(s, target,
242 }
243 } else
244 s->Printf(", value = 0x%16.16" PRIx64,
246 } else {
248 s->Printf(", sibling = %5" PRIu64,
250 else
251 s->Printf(", value = 0x%16.16" PRIx64,
253 }
254 if (ConstString demangled = m_mangled.GetDemangledName()) {
255 s->PutCString(", name=\"");
256 s->PutCStringColorHighlighted(demangled.GetStringRef(), settings);
257 s->PutCString("\"");
258 }
259 if (ConstString mangled_name = m_mangled.GetMangledName()) {
260 s->PutCString(", mangled=\"");
261 s->PutCStringColorHighlighted(mangled_name.GetStringRef(), settings);
262 s->PutCString("\"");
263 }
264}
265
266void Symbol::Dump(Stream *s, Target *target, uint32_t index,
267 Mangled::NamePreference name_preference) const {
268 s->Printf("[%5u] %6u %c%c%c %-15s ", index, GetID(), m_is_debug ? 'D' : ' ',
269 m_is_synthetic ? 'S' : ' ', m_is_external ? 'X' : ' ',
271
272 // Make sure the size of the symbol is up to date before dumping
273 GetByteSize();
274
275 ConstString name = GetMangled().GetName(name_preference);
276 if (ValueIsAddress()) {
277 if (!m_addr_range.GetBaseAddress().Dump(s, nullptr,
279 s->Printf("%*s", 18, "");
280
281 s->PutChar(' ');
282
283 if (!m_addr_range.GetBaseAddress().Dump(s, target,
285 s->Printf("%*s", 18, "");
286
287 const char *format = m_size_is_sibling ? " Sibling -> [%5llu] 0x%8.8x %s\n"
288 : " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
289 s->Printf(format, GetByteSize(), m_flags, name.AsCString(""));
290 } else if (m_type == eSymbolTypeReExported) {
291 s->Printf(
292 " 0x%8.8x %s",
293 m_flags, name.AsCString(""));
294
295 ConstString reexport_name = GetReExportedSymbolName();
296 intptr_t shlib = m_addr_range.GetByteSize();
297 if (shlib)
298 s->Printf(" -> %s`%s\n", (const char *)shlib, reexport_name.GetCString());
299 else
300 s->Printf(" -> %s\n", reexport_name.GetCString());
301 } else {
302 const char *format =
304 ? "0x%16.16" PRIx64
305 " Sibling -> [%5llu] 0x%8.8x %s\n"
306 : "0x%16.16" PRIx64 " 0x%16.16" PRIx64
307 " 0x%8.8x %s\n";
309 m_flags, name.AsCString(""));
310 }
311}
312
317
318 const Address &base_address = m_addr_range.GetBaseAddress();
319 Function *function = base_address.CalculateSymbolContextFunction();
320 if (function) {
321 // Functions have line entries which can also potentially have end of
322 // prologue information. So if this symbol points to a function, use
323 // the prologue information from there.
324 m_type_data = function->GetPrologueByteSize();
325 } else {
326 ModuleSP module_sp(base_address.GetModule());
327 SymbolContext sc;
328 if (module_sp) {
329 uint32_t resolved_flags = module_sp->ResolveSymbolContextForAddress(
330 base_address, eSymbolContextLineEntry, sc);
331 if (resolved_flags & eSymbolContextLineEntry) {
332 // Default to the end of the first line entry.
334
335 // Set address for next line.
336 Address addr(base_address);
337 addr.Slide(m_type_data);
338
339 // Check the first few instructions and look for one that has a
340 // line number that is different than the first entry. This is also
341 // done in Function::GetPrologueByteSize().
342 uint16_t total_offset = m_type_data;
343 for (int idx = 0; idx < 6; ++idx) {
344 SymbolContext sc_temp;
345 resolved_flags = module_sp->ResolveSymbolContextForAddress(
346 addr, eSymbolContextLineEntry, sc_temp);
347 // Make sure we got line number information...
348 if (!(resolved_flags & eSymbolContextLineEntry))
349 break;
350
351 // If this line number is different than our first one, use it
352 // and we're done.
353 if (sc_temp.line_entry.line != sc.line_entry.line) {
354 m_type_data = total_offset;
355 break;
356 }
357
358 // Slide addr up to the next line address.
359 addr.Slide(sc_temp.line_entry.range.GetByteSize());
360 total_offset += sc_temp.line_entry.range.GetByteSize();
361 // If we've gone too far, bail out.
362 if (total_offset >= m_addr_range.GetByteSize())
363 break;
364 }
365
366 // Sanity check - this may be a function in the middle of code that
367 // has debug information, but not for this symbol. So the line
368 // entries surrounding us won't lie inside our function. In that
369 // case, the line entry will be bigger than we are, so we do that
370 // quick check and if that is true, we just return 0.
372 m_type_data = 0;
373 } else {
374 // TODO: expose something in Process to figure out the
375 // size of a function prologue.
376 m_type_data = 0;
377 }
378 }
379 }
380 }
381 return m_type_data;
382 }
383 return 0;
384}
385
386bool Symbol::Compare(ConstString name, SymbolType type) const {
387 if (type == eSymbolTypeAny || m_type == type) {
388 const Mangled &mangled = GetMangled();
389 return mangled.GetMangledName() == name ||
390 mangled.GetDemangledName() == name;
391 }
392 return false;
393}
394
395#define ENUM_TO_CSTRING(x) \
396 case eSymbolType##x: \
397 return #x;
398
399const char *Symbol::GetTypeAsString() const {
400 switch (m_type) {
402 ENUM_TO_CSTRING(Absolute);
403 ENUM_TO_CSTRING(Code);
404 ENUM_TO_CSTRING(Resolver);
405 ENUM_TO_CSTRING(Data);
406 ENUM_TO_CSTRING(Trampoline);
409 ENUM_TO_CSTRING(SourceFile);
410 ENUM_TO_CSTRING(HeaderFile);
412 ENUM_TO_CSTRING(CommonBlock);
414 ENUM_TO_CSTRING(Local);
415 ENUM_TO_CSTRING(Param);
417 ENUM_TO_CSTRING(VariableType);
419 ENUM_TO_CSTRING(LineHeader);
420 ENUM_TO_CSTRING(ScopeBegin);
421 ENUM_TO_CSTRING(ScopeEnd);
422 ENUM_TO_CSTRING(Additional);
423 ENUM_TO_CSTRING(Compiler);
424 ENUM_TO_CSTRING(Instrumentation);
425 ENUM_TO_CSTRING(Undefined);
426 ENUM_TO_CSTRING(ObjCClass);
427 ENUM_TO_CSTRING(ObjCMetaClass);
428 ENUM_TO_CSTRING(ObjCIVar);
429 ENUM_TO_CSTRING(ReExported);
430 default:
431 break;
432 }
433 return "<unknown SymbolType>";
434}
435
437 // Symbols can reconstruct the symbol and the module in the symbol context
438 sc->symbol = this;
439 if (ValueIsAddress())
441 else
442 sc->module_sp.reset();
443}
444
446 if (ValueIsAddress())
447 return GetAddressRef().GetModule();
448 return ModuleSP();
449}
450
452
454 bool dumped_module = false;
455 if (ValueIsAddress()) {
456 ModuleSP module_sp(GetAddressRef().GetModule());
457 if (module_sp) {
458 dumped_module = true;
459 module_sp->DumpSymbolContext(s);
460 }
461 }
462 if (dumped_module)
463 s->PutCString(", ");
464
465 s->Printf("Symbol{0x%8.8x}", GetID());
466}
467
469
471 Target &target, ConstString &reexport_name, ModuleSpec &module_spec,
472 ModuleList &seen_modules) const {
473 ModuleSP module_sp;
474 if (module_spec.GetFileSpec()) {
475 // Try searching for the module file spec first using the full path
476 module_sp = target.GetImages().FindFirstModule(module_spec);
477 if (!module_sp) {
478 // Next try and find the module by basename in case environment variables
479 // or other runtime trickery causes shared libraries to be loaded from
480 // alternate paths
481 module_spec.GetFileSpec().ClearDirectory();
482 module_sp = target.GetImages().FindFirstModule(module_spec);
483 }
484 }
485
486 if (module_sp) {
487 // There should not be cycles in the reexport list, but we don't want to
488 // crash if there are so make sure we haven't seen this before:
489 if (!seen_modules.AppendIfNeeded(module_sp))
490 return nullptr;
491
493 module_sp->FindSymbolsWithNameAndType(reexport_name, eSymbolTypeAny,
494 sc_list);
495 for (const SymbolContext &sc : sc_list) {
496 if (sc.symbol->IsExternal())
497 return sc.symbol;
498 }
499 // If we didn't find the symbol in this module, it may be because this
500 // module re-exports some whole other library. We have to search those as
501 // well:
502 seen_modules.Append(module_sp);
503
504 FileSpecList reexported_libraries =
505 module_sp->GetObjectFile()->GetReExportedLibraries();
506 size_t num_reexported_libraries = reexported_libraries.GetSize();
507 for (size_t idx = 0; idx < num_reexported_libraries; idx++) {
508 ModuleSpec reexported_module_spec;
509 reexported_module_spec.GetFileSpec() =
510 reexported_libraries.GetFileSpecAtIndex(idx);
512 target, reexport_name, reexported_module_spec, seen_modules);
513 if (result_symbol)
514 return result_symbol;
515 }
516 }
517 return nullptr;
518}
519
521 ConstString reexport_name(GetReExportedSymbolName());
522 if (reexport_name) {
523 ModuleSpec module_spec;
524 ModuleList seen_modules;
526 if (module_spec.GetFileSpec()) {
527 return ResolveReExportedSymbolInModuleSpec(target, reexport_name,
528 module_spec, seen_modules);
529 }
530 }
531 return nullptr;
532}
533
535 if (ValueIsAddress())
536 return GetAddressRef().GetFileAddress();
537 else
539}
540
542 if (ValueIsAddress())
543 return GetAddressRef().GetLoadAddress(target);
544 else
546}
547
549
552}
553
557
558 Address func_so_addr;
559
560 bool is_indirect = IsIndirect();
562 Symbol *reexported_symbol = ResolveReExportedSymbol(target);
563 if (reexported_symbol) {
564 func_so_addr = reexported_symbol->GetAddress();
565 is_indirect = reexported_symbol->IsIndirect();
566 }
567 } else {
568 func_so_addr = GetAddress();
569 is_indirect = IsIndirect();
570 }
571
572 if (func_so_addr.IsValid()) {
573 if (!target.GetProcessSP() && is_indirect) {
574 // can't resolve indirect symbols without calling a function...
576 }
577
578 lldb::addr_t load_addr =
579 func_so_addr.GetCallableLoadAddress(&target, is_indirect);
580
581 if (load_addr != LLDB_INVALID_ADDRESS) {
582 return load_addr;
583 }
584 }
585
587}
588
590 const char *flavor,
591 bool prefer_file_cache) {
593 if (module_sp && exe_ctx.HasTargetScope()) {
594 return Disassembler::DisassembleRange(module_sp->GetArchitecture(), nullptr,
595 flavor, exe_ctx.GetTargetRef(),
596 m_addr_range, !prefer_file_cache);
597 }
598 return lldb::DisassemblerSP();
599}
600
601bool Symbol::GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor,
602 bool prefer_file_cache, Stream &strm) {
603 lldb::DisassemblerSP disassembler_sp =
604 GetInstructions(exe_ctx, flavor, prefer_file_cache);
605 if (disassembler_sp) {
606 const bool show_address = true;
607 const bool show_bytes = false;
608 const bool show_control_flow_kind = false;
609 disassembler_sp->GetInstructionList().Dump(
610 &strm, show_address, show_bytes, show_control_flow_kind, &exe_ctx);
611 return true;
612 }
613 return false;
614}
615
617 return m_addr_range.ContainsFileAddress(file_addr);
618}
619
621 if (!IsSynthetic())
622 return false;
623 if (!m_mangled)
624 return true;
626 return demangled.GetStringRef().starts_with(GetSyntheticSymbolPrefix());
627}
628
630 if (m_is_synthetic && !m_mangled) {
631 // Synthetic symbol names don't mean anything, but they do uniquely
632 // identify individual symbols so we give them a unique name. The name
633 // starts with the synthetic symbol prefix, followed by a unique number.
634 // Typically the UserID of a real symbol is the symbol table index of the
635 // symbol in the object file's symbol table(s), so it will be the same
636 // every time you read in the object file. We want the same persistence for
637 // synthetic symbols so that users can identify them across multiple debug
638 // sessions, to understand crashes in those symbols and to reliably set
639 // breakpoints on them.
640 llvm::SmallString<256> name;
641 llvm::raw_svector_ostream os(name);
642 os << GetSyntheticSymbolPrefix() << GetID();
644 }
645}
646
647bool Symbol::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
648 const SectionList *section_list,
649 const StringTableReader &strtab) {
650 if (!data.ValidOffsetForDataOfSize(*offset_ptr, 8))
651 return false;
652 m_uid = data.GetU32(offset_ptr);
653 m_type_data = data.GetU16(offset_ptr);
654 const uint16_t bitfields = data.GetU16(offset_ptr);
655 m_type_data_resolved = (1u << 15 & bitfields) != 0;
656 m_is_synthetic = (1u << 14 & bitfields) != 0;
657 m_is_debug = (1u << 13 & bitfields) != 0;
658 m_is_external = (1u << 12 & bitfields) != 0;
659 m_size_is_sibling = (1u << 11 & bitfields) != 0;
660 m_size_is_synthesized = (1u << 10 & bitfields) != 0;
661 m_size_is_valid = (1u << 9 & bitfields) != 0;
662 m_demangled_is_synthesized = (1u << 8 & bitfields) != 0;
663 m_contains_linker_annotations = (1u << 7 & bitfields) != 0;
664 m_is_weak = (1u << 6 & bitfields) != 0;
665 m_type = bitfields & 0x003f;
666 if (!m_mangled.Decode(data, offset_ptr, strtab))
667 return false;
668 if (!data.ValidOffsetForDataOfSize(*offset_ptr, 20))
669 return false;
670 const bool is_addr = data.GetU8(offset_ptr) != 0;
671 const uint64_t value = data.GetU64(offset_ptr);
672 if (is_addr) {
674 section_list);
675 } else {
678 }
679 m_addr_range.SetByteSize(data.GetU64(offset_ptr));
680 m_flags = data.GetU32(offset_ptr);
681 return true;
682}
683
684/// The encoding format for the symbol is as follows:
685///
686/// uint32_t m_uid;
687/// uint16_t m_type_data;
688/// uint16_t bitfield_data;
689/// Mangled mangled;
690/// uint8_t is_addr;
691/// uint64_t file_addr_or_value;
692/// uint64_t size;
693/// uint32_t flags;
694///
695/// The only tricky thing in this encoding is encoding all of the bits in the
696/// bitfields. We use a trick to store all bitfields as a 16 bit value and we
697/// do the same thing when decoding the symbol. There are test that ensure this
698/// encoding works for each individual bit. Everything else is very easy to
699/// store.
700void Symbol::Encode(DataEncoder &file, ConstStringTable &strtab) const {
701 file.AppendU32(m_uid);
703 uint16_t bitfields = m_type;
705 bitfields |= 1u << 15;
706 if (m_is_synthetic)
707 bitfields |= 1u << 14;
708 if (m_is_debug)
709 bitfields |= 1u << 13;
710 if (m_is_external)
711 bitfields |= 1u << 12;
713 bitfields |= 1u << 11;
715 bitfields |= 1u << 10;
716 if (m_size_is_valid)
717 bitfields |= 1u << 9;
719 bitfields |= 1u << 8;
721 bitfields |= 1u << 7;
722 if (m_is_weak)
723 bitfields |= 1u << 6;
724 file.AppendU16(bitfields);
725 m_mangled.Encode(file, strtab);
726 // A symbol's value might be an address, or it might be a constant. If the
727 // symbol's base address doesn't have a section, then it is a constant value.
728 // If it does have a section, we will encode the file address and re-resolve
729 // the address when we decode it.
730 bool is_addr = m_addr_range.GetBaseAddress().GetSection().get() != nullptr;
731 file.AppendU8(is_addr);
734 file.AppendU32(m_flags);
735}
736
737bool Symbol::operator==(const Symbol &rhs) const {
738 if (m_uid != rhs.m_uid)
739 return false;
740 if (m_type_data != rhs.m_type_data)
741 return false;
743 return false;
745 return false;
746 if (m_is_debug != rhs.m_is_debug)
747 return false;
748 if (m_is_external != rhs.m_is_external)
749 return false;
751 return false;
753 return false;
755 return false;
757 return false;
759 return false;
760 if (m_is_weak != rhs.m_is_weak)
761 return false;
762 if (m_type != rhs.m_type)
763 return false;
764 if (m_mangled != rhs.m_mangled)
765 return false;
767 return false;
769 return false;
770 if (m_flags != rhs.m_flags)
771 return false;
772 return true;
773}
774
775namespace llvm {
776namespace json {
777
778bool fromJSON(const llvm::json::Value &value, lldb_private::JSONSymbol &symbol,
779 llvm::json::Path path) {
780 llvm::json::ObjectMapper o(value, path);
781 const bool mapped = o && o.map("value", symbol.value) &&
782 o.map("address", symbol.address) &&
783 o.map("size", symbol.size) && o.map("id", symbol.id) &&
784 o.map("type", symbol.type) && o.map("name", symbol.name);
785
786 if (!mapped)
787 return false;
788
789 if (!symbol.value && !symbol.address) {
790 path.report("symbol must have either a value or an address");
791 return false;
792 }
793
794 if (symbol.value && symbol.address) {
795 path.report("symbol cannot have both a value and an address");
796 return false;
797 }
798
799 return true;
800}
801
802bool fromJSON(const llvm::json::Value &value, lldb::SymbolType &type,
803 llvm::json::Path path) {
804 if (auto str = value.getAsString()) {
805 type = llvm::StringSwitch<lldb::SymbolType>(*str)
806 .Case("absolute", eSymbolTypeAbsolute)
807 .Case("code", eSymbolTypeCode)
808 .Case("resolver", eSymbolTypeResolver)
809 .Case("data", eSymbolTypeData)
810 .Case("trampoline", eSymbolTypeTrampoline)
811 .Case("runtime", eSymbolTypeRuntime)
812 .Case("exception", eSymbolTypeException)
813 .Case("sourcefile", eSymbolTypeSourceFile)
814 .Case("headerfile", eSymbolTypeHeaderFile)
815 .Case("objectfile", eSymbolTypeObjectFile)
816 .Case("commonblock", eSymbolTypeCommonBlock)
817 .Case("block", eSymbolTypeBlock)
818 .Case("local", eSymbolTypeLocal)
819 .Case("param", eSymbolTypeParam)
820 .Case("variable", eSymbolTypeVariable)
821 .Case("variableType", eSymbolTypeVariableType)
822 .Case("lineentry", eSymbolTypeLineEntry)
823 .Case("lineheader", eSymbolTypeLineHeader)
824 .Case("scopebegin", eSymbolTypeScopeBegin)
825 .Case("scopeend", eSymbolTypeScopeEnd)
826 .Case("additional,", eSymbolTypeAdditional)
827 .Case("compiler", eSymbolTypeCompiler)
828 .Case("instrumentation", eSymbolTypeInstrumentation)
829 .Case("undefined", eSymbolTypeUndefined)
830 .Case("objcclass", eSymbolTypeObjCClass)
831 .Case("objcmetaClass", eSymbolTypeObjCMetaClass)
832 .Case("objcivar", eSymbolTypeObjCIVar)
833 .Case("reexporte", eSymbolTypeReExported)
834 .Default(eSymbolTypeInvalid);
835
836 if (type == eSymbolTypeInvalid) {
837 path.report("invalid symbol type");
838 return false;
839 }
840
841 return true;
842 }
843 path.report("expected string");
844 return false;
845}
846} // namespace json
847} // namespace llvm
#define ENUM_TO_CSTRING(x)
Definition: Symbol.cpp:395
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:211
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:239
lldb::addr_t GetByteSize() const
Get accessor for the byte size of this range.
Definition: AddressRange.h:223
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:872
@ 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:216
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:567
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:493
@ ePreferDemangledWithoutArguments
Definition: Mangled.h:38
void SetDemangledName(ConstString name)
Definition: Mangled.h:137
ConstString GetDemangledName() const
Demangled name get accessor.
Definition: Mangled.cpp:270
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:443
ConstString & GetMangledName()
Mangled name get accessor.
Definition: Mangled.h:145
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
Definition: Mangled.cpp:335
ConstString GetDisplayDemangledName() const
Display demangled name get accessor.
Definition: Mangled.cpp:320
void Clear()
Clear the mangled and demangled values.
Definition: Mangled.cpp:109
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:647
uint32_t m_uid
Definition: Symbol.h:316
uint32_t GetSiblingIndex() const
Definition: Symbol.cpp:217
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:541
bool ValueIsAddress() const
Definition: Symbol.cpp:165
uint16_t m_type_data_resolved
Definition: Symbol.h:319
void SetReExportedSymbolName(ConstString name)
Definition: Symbol.cpp:199
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:436
bool IsIndirect() const
Definition: Symbol.cpp:223
void SynthesizeNameIfNeeded() const
Definition: Symbol.cpp:629
const char * GetTypeAsString() const
Definition: Symbol.cpp:399
Symbol * ResolveReExportedSymbolInModuleSpec(Target &target, ConstString &reexport_name, lldb_private::ModuleSpec &module_spec, lldb_private::ModuleList &seen_modules) const
Definition: Symbol.cpp:470
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:589
lldb::addr_t GetFileAddress() const
Definition: Symbol.cpp:534
void DumpSymbolContext(Stream *s) override
Dump the object's symbol context to the stream s.
Definition: Symbol.cpp:453
lldb::ModuleSP CalculateSymbolContextModule() override
Definition: Symbol.cpp:445
bool ContainsFileAddress(lldb::addr_t file_addr) const
Definition: Symbol.cpp:616
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:221
Address & GetAddressRef()
Definition: Symbol.h:72
const Symbol & operator=(const Symbol &rhs)
Definition: Symbol.cpp:78
bool IsSyntheticWithAutoGeneratedName() const
Definition: Symbol.cpp:620
void Encode(DataEncoder &encoder, ConstStringTable &strtab) const
Encode this object into a data encoder object.
Definition: Symbol.cpp:700
Mangled m_mangled
Definition: Symbol.h:341
uint16_t m_type
Definition: Symbol.h:340
ConstString GetReExportedSymbolName() const
Definition: Symbol.cpp:173
bool Compare(ConstString name, lldb::SymbolType type) const
Definition: Symbol.cpp:386
uint16_t m_is_debug
Definition: Symbol.h:324
bool SetReExportedSymbolSharedLibrary(const FileSpec &fspec)
Definition: Symbol.cpp:206
void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Definition: Symbol.cpp:225
bool operator==(const Symbol &rhs) const
Definition: Symbol.cpp:737
static llvm::StringRef GetSyntheticSymbolPrefix()
Definition: Symbol.h:260
lldb::addr_t GetByteSize() const
Definition: Symbol.cpp:468
ConstString GetName() const
Definition: Symbol.cpp:548
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:550
uint16_t m_size_is_sibling
Definition: Symbol.h:327
Symbol * ResolveReExportedSymbol(Target &target) const
Definition: Symbol.cpp:520
FileSpec GetReExportedSymbolSharedLibrary() const
Definition: Symbol.cpp:187
uint16_t m_is_weak
Definition: Symbol.h:339
uint32_t GetPrologueByteSize()
Definition: Symbol.cpp:313
uint16_t m_type_data
Definition: Symbol.h:318
ConstString GetDisplayName() const
Definition: Symbol.cpp:169
bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor, bool prefer_file_cache, Stream &strm)
Definition: Symbol.cpp:601
lldb::addr_t ResolveCallableAddress(Target &target) const
Definition: Symbol.cpp:554
uint16_t m_size_is_synthesized
Definition: Symbol.h:329
Symbol * CalculateSymbolContextSymbol() override
Definition: Symbol.cpp:451
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:266
const lldb::ProcessSP & GetProcessSP() const
Definition: Target.cpp:221
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:981
#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.
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:85
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:338
std::shared_ptr< lldb_private::Section > SectionSP
Definition: lldb-forward.h:413
uint64_t addr_t
Definition: lldb-types.h:80
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:370
Definition: Debugger.h:54
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