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
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)
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),
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)
57 m_is_synthetic(is_artificial), m_is_debug(is_debug),
58 m_is_external(external), m_size_is_sibling(false),
60 m_size_is_valid(size_is_valid || range.GetByteSize() > 0),
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
77
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
148 m_mangled.Clear();
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;
162 m_addr_range.Clear();
163}
164
166 return (bool)m_addr_range.GetBaseAddress().GetSection();
167}
168
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.
210 m_addr_range.SetByteSize(
211 (uintptr_t)ConstString(fspec.GetPath().c_str()).GetCString());
212 return true;
213 }
214 return false;
215}
216
217uint32_t Symbol::GetSiblingIndex() const {
218 return m_size_is_sibling ? m_addr_range.GetByteSize() : UINT32_MAX;
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
230 if (m_addr_range.GetBaseAddress().GetSection()) {
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,
245 m_addr_range.GetBaseAddress().GetOffset());
246 } else {
248 s->Printf(", sibling = %5" PRIu64,
249 m_addr_range.GetBaseAddress().GetOffset());
250 else
251 s->Printf(", value = 0x%16.16" PRIx64,
252 m_addr_range.GetBaseAddress().GetOffset());
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";
308 s->Printf(format, m_addr_range.GetBaseAddress().GetOffset(), GetByteSize(),
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.
371 if (m_type_data >= m_addr_range.GetByteSize())
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
395const char *Symbol::GetTypeAsString() const {
396 return GetTypeAsString(static_cast<lldb::SymbolType>(m_type));
397}
398
400 // Symbols can reconstruct the symbol and the module in the symbol context
401 sc->symbol = this;
402 if (ValueIsAddress())
404 else
405 sc->module_sp.reset();
406}
407
413
415
417 bool dumped_module = false;
418 if (ValueIsAddress()) {
419 ModuleSP module_sp(GetAddressRef().GetModule());
420 if (module_sp) {
421 dumped_module = true;
422 module_sp->DumpSymbolContext(s);
423 }
424 }
425 if (dumped_module)
426 s->PutCString(", ");
427
428 s->Printf("Symbol{0x%8.8x}", GetID());
429}
430
431lldb::addr_t Symbol::GetByteSize() const { return m_addr_range.GetByteSize(); }
432
434 Target &target, ConstString &reexport_name, ModuleSpec &module_spec,
435 ModuleList &seen_modules) const {
436 ModuleSP module_sp;
437 if (module_spec.GetFileSpec()) {
438 // Try searching for the module file spec first using the full path
439 module_sp = target.GetImages().FindFirstModule(module_spec);
440 if (!module_sp) {
441 // Next try and find the module by basename in case environment variables
442 // or other runtime trickery causes shared libraries to be loaded from
443 // alternate paths
444 module_spec.GetFileSpec().ClearDirectory();
445 module_sp = target.GetImages().FindFirstModule(module_spec);
446 }
447 }
448
449 if (module_sp) {
450 // There should not be cycles in the reexport list, but we don't want to
451 // crash if there are so make sure we haven't seen this before:
452 if (!seen_modules.AppendIfNeeded(module_sp))
453 return nullptr;
454
456 module_sp->FindSymbolsWithNameAndType(reexport_name, eSymbolTypeAny,
457 sc_list);
458 for (const SymbolContext &sc : sc_list) {
459 if (sc.symbol->IsExternal())
460 return sc.symbol;
461 }
462 // If we didn't find the symbol in this module, it may be because this
463 // module re-exports some whole other library. We have to search those as
464 // well:
465 seen_modules.Append(module_sp);
466
467 FileSpecList reexported_libraries =
468 module_sp->GetObjectFile()->GetReExportedLibraries();
469 size_t num_reexported_libraries = reexported_libraries.GetSize();
470 for (size_t idx = 0; idx < num_reexported_libraries; idx++) {
471 ModuleSpec reexported_module_spec;
472 reexported_module_spec.GetFileSpec() =
473 reexported_libraries.GetFileSpecAtIndex(idx);
475 target, reexport_name, reexported_module_spec, seen_modules);
476 if (result_symbol)
477 return result_symbol;
478 }
479 }
480 return nullptr;
481}
482
484 ConstString reexport_name(GetReExportedSymbolName());
485 if (reexport_name) {
486 ModuleSpec module_spec;
487 ModuleList seen_modules;
489 if (module_spec.GetFileSpec()) {
490 return ResolveReExportedSymbolInModuleSpec(target, reexport_name,
491 module_spec, seen_modules);
492 }
493 }
494 return nullptr;
495}
496
498 if (ValueIsAddress())
499 return GetAddressRef().GetFileAddress();
500 else
502}
503
505 if (ValueIsAddress())
506 return GetAddressRef().GetLoadAddress(target);
507 else
509}
510
512
516
520
521 Address func_so_addr;
522
523 bool is_indirect = IsIndirect();
525 Symbol *reexported_symbol = ResolveReExportedSymbol(target);
526 if (reexported_symbol) {
527 func_so_addr = reexported_symbol->GetAddress();
528 is_indirect = reexported_symbol->IsIndirect();
529 }
530 } else {
531 func_so_addr = GetAddress();
532 is_indirect = IsIndirect();
533 }
534
535 if (func_so_addr.IsValid()) {
536 if (!target.GetProcessSP() && is_indirect) {
537 // can't resolve indirect symbols without calling a function...
539 }
540
541 lldb::addr_t load_addr =
542 func_so_addr.GetCallableLoadAddress(&target, is_indirect);
543
544 if (load_addr != LLDB_INVALID_ADDRESS) {
545 return load_addr;
546 }
547 }
548
550}
551
553 const char *flavor,
554 bool prefer_file_cache) {
555 ModuleSP module_sp(m_addr_range.GetBaseAddress().GetModule());
556 if (module_sp && exe_ctx.HasTargetScope()) {
558 module_sp->GetArchitecture(), nullptr, flavor, nullptr, nullptr,
559 exe_ctx.GetTargetRef(), m_addr_range, !prefer_file_cache);
560 }
561 return lldb::DisassemblerSP();
562}
563
564bool Symbol::GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor,
565 bool prefer_file_cache, Stream &strm) {
566 lldb::DisassemblerSP disassembler_sp =
567 GetInstructions(exe_ctx, flavor, prefer_file_cache);
568 if (disassembler_sp) {
569 const bool show_address = true;
570 const bool show_bytes = false;
571 const bool show_control_flow_kind = false;
572 disassembler_sp->GetInstructionList().Dump(
573 &strm, show_address, show_bytes, show_control_flow_kind, &exe_ctx);
574 return true;
575 }
576 return false;
577}
578
580 return m_addr_range.ContainsFileAddress(file_addr);
581}
582
584 if (!IsSynthetic())
585 return false;
586 if (!m_mangled)
587 return true;
588 ConstString demangled = m_mangled.GetDemangledName();
589 return demangled.GetStringRef().starts_with(GetSyntheticSymbolPrefix());
590}
591
593 if (m_is_synthetic && !m_mangled) {
594 // Synthetic symbol names don't mean anything, but they do uniquely
595 // identify individual symbols so we give them a unique name. The name
596 // starts with the synthetic symbol prefix, followed by a unique number.
597 // Typically the UserID of a real symbol is the symbol table index of the
598 // symbol in the object file's symbol table(s), so it will be the same
599 // every time you read in the object file. We want the same persistence for
600 // synthetic symbols so that users can identify them across multiple debug
601 // sessions, to understand crashes in those symbols and to reliably set
602 // breakpoints on them.
603 llvm::SmallString<256> name;
604 llvm::raw_svector_ostream os(name);
606 << llvm::format_hex_no_prefix(
607 m_addr_range.GetBaseAddress().GetFileAddress(), 0);
608 m_mangled.SetDemangledName(ConstString(os.str()));
609 }
610}
611
612bool Symbol::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
613 const SectionList *section_list,
614 const StringTableReader &strtab) {
615 if (!data.ValidOffsetForDataOfSize(*offset_ptr, 8))
616 return false;
617 m_uid = data.GetU32(offset_ptr);
618 m_type_data = data.GetU16(offset_ptr);
619 const uint16_t bitfields = data.GetU16(offset_ptr);
620 m_type_data_resolved = (1u << 15 & bitfields) != 0;
621 m_is_synthetic = (1u << 14 & bitfields) != 0;
622 m_is_debug = (1u << 13 & bitfields) != 0;
623 m_is_external = (1u << 12 & bitfields) != 0;
624 m_size_is_sibling = (1u << 11 & bitfields) != 0;
625 m_size_is_synthesized = (1u << 10 & bitfields) != 0;
626 m_size_is_valid = (1u << 9 & bitfields) != 0;
627 m_demangled_is_synthesized = (1u << 8 & bitfields) != 0;
628 m_contains_linker_annotations = (1u << 7 & bitfields) != 0;
629 m_is_weak = (1u << 6 & bitfields) != 0;
630 m_type = bitfields & 0x003f;
631 if (!m_mangled.Decode(data, offset_ptr, strtab))
632 return false;
633 if (!data.ValidOffsetForDataOfSize(*offset_ptr, 20))
634 return false;
635 const bool is_addr = data.GetU8(offset_ptr) != 0;
636 const uint64_t value = data.GetU64(offset_ptr);
637 if (is_addr) {
638 m_addr_range.GetBaseAddress().ResolveAddressUsingFileSections(value,
639 section_list);
640 } else {
641 m_addr_range.GetBaseAddress().Clear();
642 m_addr_range.GetBaseAddress().SetOffset(value);
643 }
644 m_addr_range.SetByteSize(data.GetU64(offset_ptr));
645 m_flags = data.GetU32(offset_ptr);
646 return true;
647}
648
649/// The encoding format for the symbol is as follows:
650///
651/// uint32_t m_uid;
652/// uint16_t m_type_data;
653/// uint16_t bitfield_data;
654/// Mangled mangled;
655/// uint8_t is_addr;
656/// uint64_t file_addr_or_value;
657/// uint64_t size;
658/// uint32_t flags;
659///
660/// The only tricky thing in this encoding is encoding all of the bits in the
661/// bitfields. We use a trick to store all bitfields as a 16 bit value and we
662/// do the same thing when decoding the symbol. There are test that ensure this
663/// encoding works for each individual bit. Everything else is very easy to
664/// store.
665void Symbol::Encode(DataEncoder &file, ConstStringTable &strtab) const {
666 file.AppendU32(m_uid);
668 uint16_t bitfields = m_type;
670 bitfields |= 1u << 15;
671 if (m_is_synthetic)
672 bitfields |= 1u << 14;
673 if (m_is_debug)
674 bitfields |= 1u << 13;
675 if (m_is_external)
676 bitfields |= 1u << 12;
678 bitfields |= 1u << 11;
680 bitfields |= 1u << 10;
681 if (m_size_is_valid)
682 bitfields |= 1u << 9;
684 bitfields |= 1u << 8;
686 bitfields |= 1u << 7;
687 if (m_is_weak)
688 bitfields |= 1u << 6;
689 file.AppendU16(bitfields);
690 m_mangled.Encode(file, strtab);
691 // A symbol's value might be an address, or it might be a constant. If the
692 // symbol's base address doesn't have a section, then it is a constant value.
693 // If it does have a section, we will encode the file address and re-resolve
694 // the address when we decode it.
695 bool is_addr = m_addr_range.GetBaseAddress().GetSection().get() != nullptr;
696 file.AppendU8(is_addr);
697 file.AppendU64(m_addr_range.GetBaseAddress().GetFileAddress());
698 file.AppendU64(m_addr_range.GetByteSize());
699 file.AppendU32(m_flags);
700}
701
702bool Symbol::operator==(const Symbol &rhs) const {
703 if (m_uid != rhs.m_uid)
704 return false;
705 if (m_type_data != rhs.m_type_data)
706 return false;
708 return false;
710 return false;
711 if (m_is_debug != rhs.m_is_debug)
712 return false;
713 if (m_is_external != rhs.m_is_external)
714 return false;
716 return false;
718 return false;
720 return false;
722 return false;
724 return false;
725 if (m_is_weak != rhs.m_is_weak)
726 return false;
727 if (m_type != rhs.m_type)
728 return false;
729 if (m_mangled != rhs.m_mangled)
730 return false;
731 if (m_addr_range.GetBaseAddress() != rhs.m_addr_range.GetBaseAddress())
732 return false;
733 if (m_addr_range.GetByteSize() != rhs.m_addr_range.GetByteSize())
734 return false;
735 if (m_flags != rhs.m_flags)
736 return false;
737 return true;
738}
739
740#define ENUM_TO_CSTRING(x) \
741 case eSymbolType##x: \
742 return #x;
743
745 switch (symbol_type) {
747 ENUM_TO_CSTRING(Absolute);
748 ENUM_TO_CSTRING(Code);
749 ENUM_TO_CSTRING(Resolver);
750 ENUM_TO_CSTRING(Data);
751 ENUM_TO_CSTRING(Trampoline);
754 ENUM_TO_CSTRING(SourceFile);
755 ENUM_TO_CSTRING(HeaderFile);
757 ENUM_TO_CSTRING(CommonBlock);
759 ENUM_TO_CSTRING(Local);
760 ENUM_TO_CSTRING(Param);
762 ENUM_TO_CSTRING(VariableType);
764 ENUM_TO_CSTRING(LineHeader);
765 ENUM_TO_CSTRING(ScopeBegin);
766 ENUM_TO_CSTRING(ScopeEnd);
767 ENUM_TO_CSTRING(Additional);
768 ENUM_TO_CSTRING(Compiler);
769 ENUM_TO_CSTRING(Instrumentation);
770 ENUM_TO_CSTRING(Undefined);
771 ENUM_TO_CSTRING(ObjCClass);
772 ENUM_TO_CSTRING(ObjCMetaClass);
773 ENUM_TO_CSTRING(ObjCIVar);
774 ENUM_TO_CSTRING(ReExported);
775 }
776 return "<unknown SymbolType>";
777}
778
780 std::string str_lower = llvm::StringRef(str).lower();
781 return llvm::StringSwitch<lldb::SymbolType>(str_lower)
782 .Case("absolute", eSymbolTypeAbsolute)
783 .Case("code", eSymbolTypeCode)
784 .Case("resolver", eSymbolTypeResolver)
785 .Case("data", eSymbolTypeData)
786 .Case("trampoline", eSymbolTypeTrampoline)
787 .Case("runtime", eSymbolTypeRuntime)
788 .Case("exception", eSymbolTypeException)
789 .Case("sourcefile", eSymbolTypeSourceFile)
790 .Case("headerfile", eSymbolTypeHeaderFile)
791 .Case("objectfile", eSymbolTypeObjectFile)
792 .Case("commonblock", eSymbolTypeCommonBlock)
793 .Case("block", eSymbolTypeBlock)
794 .Case("local", eSymbolTypeLocal)
795 .Case("param", eSymbolTypeParam)
796 .Case("variable", eSymbolTypeVariable)
797 .Case("variableType", eSymbolTypeVariableType)
798 .Case("lineentry", eSymbolTypeLineEntry)
799 .Case("lineheader", eSymbolTypeLineHeader)
800 .Case("scopebegin", eSymbolTypeScopeBegin)
801 .Case("scopeend", eSymbolTypeScopeEnd)
802 .Case("additional,", eSymbolTypeAdditional)
803 .Case("compiler", eSymbolTypeCompiler)
804 .Case("instrumentation", eSymbolTypeInstrumentation)
805 .Case("undefined", eSymbolTypeUndefined)
806 .Case("objcclass", eSymbolTypeObjCClass)
807 .Case("objcmetaclass", eSymbolTypeObjCMetaClass)
808 .Case("objcivar", eSymbolTypeObjCIVar)
809 .Case("reexported", eSymbolTypeReExported)
810 .Default(eSymbolTypeInvalid);
811}
812
813namespace llvm {
814namespace json {
815
816bool fromJSON(const llvm::json::Value &value, lldb_private::JSONSymbol &symbol,
817 llvm::json::Path path) {
818 llvm::json::ObjectMapper o(value, path);
819 const bool mapped = o && o.map("value", symbol.value) &&
820 o.map("address", symbol.address) &&
821 o.map("size", symbol.size) && o.map("id", symbol.id) &&
822 o.map("type", symbol.type) && o.map("name", symbol.name);
823
824 if (!mapped)
825 return false;
826
827 if (!symbol.value && !symbol.address) {
828 path.report("symbol must have either a value or an address");
829 return false;
830 }
831
832 if (symbol.value && symbol.address) {
833 path.report("symbol cannot have both a value and an address");
834 return false;
835 }
836
837 return true;
838}
839
840bool fromJSON(const llvm::json::Value &value, lldb::SymbolType &type,
841 llvm::json::Path path) {
842 if (auto str = value.getAsString()) {
843 llvm::StringRef str_ref = str.value_or("");
844 type = Symbol::GetTypeFromString(str_ref.data());
845
846 if (type == eSymbolTypeInvalid) {
847 path.report("invalid symbol type");
848 return false;
849 }
850
851 return true;
852 }
853 path.report("expected string");
854 return false;
855}
856} // namespace json
857} // namespace llvm
#define ENUM_TO_CSTRING(x)
Definition Symbol.cpp:740
A section + offset based address range class.
Address & GetBaseAddress()
Get accessor for the base address of the range.
lldb::addr_t GetByteSize() const
Get accessor for the byte size of this range.
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition Address.cpp:301
lldb::addr_t GetCallableLoadAddress(Target *target, bool is_indirect=false) const
Get the load address as a callable code load address.
Definition Address.cpp:326
Function * CalculateSymbolContextFunction() const
Definition Address.cpp:860
@ 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:452
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition Address.cpp:273
lldb::addr_t GetFileAddress() const
Get the file address.
Definition Address.cpp:281
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
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.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
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.
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, const char *cpu, const char *features, Target &target, llvm::ArrayRef< AddressRange > disasm_ranges, 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.
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:367
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:374
A class that describes a function.
Definition Function.h:400
uint32_t GetPrologueByteSize()
Get the size of the prologue instructions for this function.
Definition Function.cpp:578
A class that handles mangled names.
Definition Mangled.h:34
@ ePreferDemangledWithoutArguments
Definition Mangled.h:39
ConstString GetDemangledName() const
Demangled name get accessor.
Definition Mangled.cpp:284
ConstString & GetMangledName()
Mangled name get accessor.
Definition Mangled.h:152
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
Definition Mangled.cpp:369
ConstString GetDisplayDemangledName() const
Display demangled name get accessor.
Definition Mangled.cpp:354
A collection class for Module objects.
Definition ModuleList.h:104
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Finds the first module whose file specification matches module_spec.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
FileSpec & GetFileSpec()
Definition ModuleSpec.h:53
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:45
lldb::SectionSP FindSectionContainingFileAddress(lldb::addr_t addr, uint32_t depth=UINT32_MAX) const
Definition Section.cpp:617
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.
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:612
uint32_t GetSiblingIndex() const
Definition Symbol.cpp:217
uint16_t m_is_external
Definition Symbol.h:331
uint32_t GetID() const
Definition Symbol.h:137
lldb::addr_t GetLoadAddress(Target *target) const
Definition Symbol.cpp:504
bool ValueIsAddress() const
Definition Symbol.cpp:165
uint16_t m_type_data_resolved
Definition Symbol.h:324
void SetReExportedSymbolName(ConstString name)
Definition Symbol.cpp:199
void SetType(lldb::SymbolType type)
Definition Symbol.h:171
void CalculateSymbolContext(SymbolContext *sc) override
Reconstruct the object's symbol context into sc.
Definition Symbol.cpp:399
bool IsIndirect() const
Definition Symbol.cpp:223
void SynthesizeNameIfNeeded() const
Definition Symbol.cpp:592
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:433
bool IsSynthetic() const
Definition Symbol.h:183
uint16_t m_is_synthetic
Definition Symbol.h:326
uint16_t m_demangled_is_synthesized
Definition Symbol.h:338
lldb::DisassemblerSP GetInstructions(const ExecutionContext &exe_ctx, const char *flavor, bool prefer_file_cache)
Definition Symbol.cpp:552
lldb::addr_t GetFileAddress() const
Definition Symbol.cpp:497
void DumpSymbolContext(Stream *s) override
Dump the object's symbol context to the stream s.
Definition Symbol.cpp:416
lldb::ModuleSP CalculateSymbolContextModule() override
Definition Symbol.cpp:408
bool ContainsFileAddress(lldb::addr_t file_addr) const
Definition Symbol.cpp:579
Mangled & GetMangled()
Definition Symbol.h:147
static lldb::SymbolType GetTypeFromString(const char *str)
Definition Symbol.cpp:779
uint16_t m_contains_linker_annotations
Definition Symbol.h:341
uint16_t m_size_is_valid
Definition Symbol.h:337
bool IsTrampoline() const
Definition Symbol.cpp:221
Address & GetAddressRef()
Definition Symbol.h:73
const Symbol & operator=(const Symbol &rhs)
Definition Symbol.cpp:78
bool IsSyntheticWithAutoGeneratedName() const
Definition Symbol.cpp:583
void Encode(DataEncoder &encoder, ConstStringTable &strtab) const
Encode this object into a data encoder object.
Definition Symbol.cpp:665
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:329
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:702
static llvm::StringRef GetSyntheticSymbolPrefix()
Definition Symbol.h:261
lldb::addr_t GetByteSize() const
Definition Symbol.cpp:431
ConstString GetName() const
Definition Symbol.cpp:511
lldb::SymbolType GetType() const
Definition Symbol.h:169
Address GetAddress() const
Definition Symbol.h:89
AddressRange m_addr_range
Definition Symbol.h:347
ConstString GetNameNoArguments() const
Definition Symbol.cpp:513
uint16_t m_size_is_sibling
Definition Symbol.h:332
Symbol * ResolveReExportedSymbol(Target &target) const
Definition Symbol.cpp:483
FileSpec GetReExportedSymbolSharedLibrary() const
Definition Symbol.cpp:187
uint16_t m_is_weak
Definition Symbol.h:344
uint32_t GetPrologueByteSize()
Definition Symbol.cpp:313
uint16_t m_type_data
Definition Symbol.h:323
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:564
lldb::addr_t ResolveCallableAddress(Target &target) const
Definition Symbol.cpp:517
uint16_t m_size_is_synthesized
Definition Symbol.h:334
Symbol * CalculateSymbolContextSymbol() override
Definition Symbol.cpp:414
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:306
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition Target.h:1014
#define LLDB_INVALID_ADDRESS
#define UINT32_MAX
A class that represents a running process on the host machine.
bool fromJSON(const llvm::json::Value &value, TraceSupportedResponse &info, llvm::json::Path path)
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
@ eSymbolTypeSourceFile
@ eSymbolTypeException
@ eSymbolTypeVariable
@ eSymbolTypeAbsolute
@ eSymbolTypeAdditional
When symbols take more than one entry, the extra entries get this type.
@ eSymbolTypeInstrumentation
@ eSymbolTypeHeaderFile
@ eSymbolTypeCommonBlock
@ eSymbolTypeCompiler
@ eSymbolTypeLineHeader
@ eSymbolTypeObjCIVar
@ eSymbolTypeLineEntry
@ eSymbolTypeScopeBegin
@ eSymbolTypeScopeEnd
std::shared_ptr< lldb_private::Disassembler > DisassemblerSP
std::shared_ptr< lldb_private::Section > SectionSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Module > ModuleSP
std::optional< uint64_t > address
Definition Symbol.h:25
std::optional< uint64_t > id
Definition Symbol.h:28
std::optional< lldb::SymbolType > type
Definition Symbol.h:29
std::optional< uint64_t > value
Definition Symbol.h:26
std::optional< uint64_t > size
Definition Symbol.h:27
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