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