180814287SRaphael Isemann //===-- Symbol.cpp --------------------------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner
930fdc8d8SChris Lattner #include "lldb/Symbol/Symbol.h"
1030fdc8d8SChris Lattner
1130fdc8d8SChris Lattner #include "lldb/Core/Module.h"
129191db47SGreg Clayton #include "lldb/Core/ModuleSpec.h"
1330fdc8d8SChris Lattner #include "lldb/Core/Section.h"
14bf43d1adSMichael Sartain #include "lldb/Symbol/Function.h"
15b9c1b51eSKate Stone #include "lldb/Symbol/ObjectFile.h"
16b9c1b51eSKate Stone #include "lldb/Symbol/SymbolVendor.h"
17b9c1b51eSKate Stone #include "lldb/Symbol/Symtab.h"
1830fdc8d8SChris Lattner #include "lldb/Target/Process.h"
19f5e56de0SGreg Clayton #include "lldb/Target/Target.h"
20da816ca0SGreg Clayton #include "lldb/Utility/DataEncoder.h"
21bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
2230fdc8d8SChris Lattner
2330fdc8d8SChris Lattner using namespace lldb;
2430fdc8d8SChris Lattner using namespace lldb_private;
2530fdc8d8SChris Lattner
Symbol()26b9c1b51eSKate Stone Symbol::Symbol()
279494c510SJonas Devlieghere : SymbolContextScope(), m_type_data_resolved(false), m_is_synthetic(false),
289494c510SJonas Devlieghere m_is_debug(false), m_is_external(false), m_size_is_sibling(false),
29b9c1b51eSKate Stone m_size_is_synthesized(false), m_size_is_valid(false),
30b9c1b51eSKate Stone m_demangled_is_synthesized(false), m_contains_linker_annotations(false),
319494c510SJonas Devlieghere m_is_weak(false), m_type(eSymbolTypeInvalid), m_mangled(),
329494c510SJonas Devlieghere m_addr_range() {}
3330fdc8d8SChris Lattner
Symbol(uint32_t symID,llvm::StringRef name,SymbolType type,bool external,bool is_debug,bool is_trampoline,bool is_artificial,const lldb::SectionSP & section_sp,addr_t offset,addr_t size,bool size_is_valid,bool contains_linker_annotations,uint32_t flags)3428c878aeSShafik Yaghmour Symbol::Symbol(uint32_t symID, llvm::StringRef name, SymbolType type,
3528c878aeSShafik Yaghmour bool external, bool is_debug, bool is_trampoline,
3628c878aeSShafik Yaghmour bool is_artificial, const lldb::SectionSP §ion_sp,
3728c878aeSShafik Yaghmour addr_t offset, addr_t size, bool size_is_valid,
3828c878aeSShafik Yaghmour bool contains_linker_annotations, uint32_t flags)
3928c878aeSShafik Yaghmour : SymbolContextScope(), m_uid(symID), m_type_data_resolved(false),
4028c878aeSShafik Yaghmour m_is_synthetic(is_artificial), m_is_debug(is_debug),
4128c878aeSShafik Yaghmour m_is_external(external), m_size_is_sibling(false),
42b9c1b51eSKate Stone m_size_is_synthesized(false), m_size_is_valid(size_is_valid || size > 0),
433d51b9f9SGreg Clayton m_demangled_is_synthesized(false),
44f2128b28SJim Ingham m_contains_linker_annotations(contains_linker_annotations),
4528c878aeSShafik Yaghmour m_is_weak(false), m_type(type), m_mangled(name),
46b9c1b51eSKate Stone m_addr_range(section_sp, offset, size), m_flags(flags) {}
4730fdc8d8SChris Lattner
Symbol(uint32_t symID,const Mangled & mangled,SymbolType type,bool external,bool is_debug,bool is_trampoline,bool is_artificial,const AddressRange & range,bool size_is_valid,bool contains_linker_annotations,uint32_t flags)48b9c1b51eSKate Stone Symbol::Symbol(uint32_t symID, const Mangled &mangled, SymbolType type,
49b9c1b51eSKate Stone bool external, bool is_debug, bool is_trampoline,
50b9c1b51eSKate Stone bool is_artificial, const AddressRange &range,
51b9c1b51eSKate Stone bool size_is_valid, bool contains_linker_annotations,
52b9c1b51eSKate Stone uint32_t flags)
5328c878aeSShafik Yaghmour : SymbolContextScope(), m_uid(symID), m_type_data_resolved(false),
5428c878aeSShafik Yaghmour m_is_synthetic(is_artificial), m_is_debug(is_debug),
5528c878aeSShafik Yaghmour m_is_external(external), m_size_is_sibling(false),
5630fdc8d8SChris Lattner m_size_is_synthesized(false),
573046e668SGreg Clayton m_size_is_valid(size_is_valid || range.GetByteSize() > 0),
583d51b9f9SGreg Clayton m_demangled_is_synthesized(false),
59f2128b28SJim Ingham m_contains_linker_annotations(contains_linker_annotations),
60f2128b28SJim Ingham m_is_weak(false), m_type(type), m_mangled(mangled), m_addr_range(range),
61f2128b28SJim Ingham m_flags(flags) {}
6230fdc8d8SChris Lattner
Symbol(const Symbol & rhs)63b9c1b51eSKate Stone Symbol::Symbol(const Symbol &rhs)
64b9c1b51eSKate Stone : SymbolContextScope(rhs), m_uid(rhs.m_uid), m_type_data(rhs.m_type_data),
6530fdc8d8SChris Lattner m_type_data_resolved(rhs.m_type_data_resolved),
66b9c1b51eSKate Stone m_is_synthetic(rhs.m_is_synthetic), m_is_debug(rhs.m_is_debug),
6730fdc8d8SChris Lattner m_is_external(rhs.m_is_external),
68b9c1b51eSKate Stone m_size_is_sibling(rhs.m_size_is_sibling), m_size_is_synthesized(false),
693046e668SGreg Clayton m_size_is_valid(rhs.m_size_is_valid),
703d51b9f9SGreg Clayton m_demangled_is_synthesized(rhs.m_demangled_is_synthesized),
71c6ae7eaaSPavel Labath m_contains_linker_annotations(rhs.m_contains_linker_annotations),
72f2128b28SJim Ingham m_is_weak(rhs.m_is_weak), m_type(rhs.m_type), m_mangled(rhs.m_mangled),
73b9c1b51eSKate Stone m_addr_range(rhs.m_addr_range), m_flags(rhs.m_flags) {}
7430fdc8d8SChris Lattner
operator =(const Symbol & rhs)75b9c1b51eSKate Stone const Symbol &Symbol::operator=(const Symbol &rhs) {
76b9c1b51eSKate Stone if (this != &rhs) {
7759e8fc1cSGreg Clayton SymbolContextScope::operator=(rhs);
7881c22f61SGreg Clayton m_uid = rhs.m_uid;
7930fdc8d8SChris Lattner m_type_data = rhs.m_type_data;
8030fdc8d8SChris Lattner m_type_data_resolved = rhs.m_type_data_resolved;
8130fdc8d8SChris Lattner m_is_synthetic = rhs.m_is_synthetic;
8230fdc8d8SChris Lattner m_is_debug = rhs.m_is_debug;
8330fdc8d8SChris Lattner m_is_external = rhs.m_is_external;
8430fdc8d8SChris Lattner m_size_is_sibling = rhs.m_size_is_sibling;
8530fdc8d8SChris Lattner m_size_is_synthesized = rhs.m_size_is_sibling;
863046e668SGreg Clayton m_size_is_valid = rhs.m_size_is_valid;
873d51b9f9SGreg Clayton m_demangled_is_synthesized = rhs.m_demangled_is_synthesized;
88c6ae7eaaSPavel Labath m_contains_linker_annotations = rhs.m_contains_linker_annotations;
89f2128b28SJim Ingham m_is_weak = rhs.m_is_weak;
9001575f86SGreg Clayton m_type = rhs.m_type;
91d8c3d4b1SGreg Clayton m_mangled = rhs.m_mangled;
9201575f86SGreg Clayton m_addr_range = rhs.m_addr_range;
93d8c3d4b1SGreg Clayton m_flags = rhs.m_flags;
9430fdc8d8SChris Lattner }
9530fdc8d8SChris Lattner return *this;
9630fdc8d8SChris Lattner }
9730fdc8d8SChris Lattner
Clear()98b9c1b51eSKate Stone void Symbol::Clear() {
9981c22f61SGreg Clayton m_uid = UINT32_MAX;
10081c22f61SGreg Clayton m_mangled.Clear();
10181c22f61SGreg Clayton m_type_data = 0;
10281c22f61SGreg Clayton m_type_data_resolved = false;
10381c22f61SGreg Clayton m_is_synthetic = false;
10481c22f61SGreg Clayton m_is_debug = false;
10581c22f61SGreg Clayton m_is_external = false;
10681c22f61SGreg Clayton m_size_is_sibling = false;
10781c22f61SGreg Clayton m_size_is_synthesized = false;
1083046e668SGreg Clayton m_size_is_valid = false;
1093d51b9f9SGreg Clayton m_demangled_is_synthesized = false;
110c6ae7eaaSPavel Labath m_contains_linker_annotations = false;
111f2128b28SJim Ingham m_is_weak = false;
11201575f86SGreg Clayton m_type = eSymbolTypeInvalid;
11381c22f61SGreg Clayton m_flags = 0;
11401575f86SGreg Clayton m_addr_range.Clear();
11581c22f61SGreg Clayton }
11681c22f61SGreg Clayton
ValueIsAddress() const117b9c1b51eSKate Stone bool Symbol::ValueIsAddress() const {
118c9881c7dSAdrian Prantl return m_addr_range.GetBaseAddress().GetSection().get() != nullptr ||
119c9881c7dSAdrian Prantl m_type == eSymbolTypeAbsolute;
12030fdc8d8SChris Lattner }
12130fdc8d8SChris Lattner
GetDisplayName() const122b9c1b51eSKate Stone ConstString Symbol::GetDisplayName() const {
123ec1a4917SGreg Clayton return GetMangled().GetDisplayDemangledName();
124c1f705c2SEnrico Granata }
125c1f705c2SEnrico Granata
GetReExportedSymbolName() const126b9c1b51eSKate Stone ConstString Symbol::GetReExportedSymbolName() const {
127b9c1b51eSKate Stone if (m_type == eSymbolTypeReExported) {
12805097246SAdrian Prantl // For eSymbolTypeReExported, the "const char *" from a ConstString is used
12905097246SAdrian Prantl // as the offset in the address range base address. We can then make this
13005097246SAdrian Prantl // back into a string that is the re-exported name.
1319191db47SGreg Clayton intptr_t str_ptr = m_addr_range.GetBaseAddress().GetOffset();
1329191db47SGreg Clayton if (str_ptr != 0)
1339191db47SGreg Clayton return ConstString((const char *)str_ptr);
1349191db47SGreg Clayton else
1359191db47SGreg Clayton return GetName();
1369191db47SGreg Clayton }
1379191db47SGreg Clayton return ConstString();
1389191db47SGreg Clayton }
1399191db47SGreg Clayton
GetReExportedSymbolSharedLibrary() const140b9c1b51eSKate Stone FileSpec Symbol::GetReExportedSymbolSharedLibrary() const {
141b9c1b51eSKate Stone if (m_type == eSymbolTypeReExported) {
14205097246SAdrian Prantl // For eSymbolTypeReExported, the "const char *" from a ConstString is used
14305097246SAdrian Prantl // as the offset in the address range base address. We can then make this
14405097246SAdrian Prantl // back into a string that is the re-exported name.
1459191db47SGreg Clayton intptr_t str_ptr = m_addr_range.GetByteSize();
1469191db47SGreg Clayton if (str_ptr != 0)
1478f3be7a3SJonas Devlieghere return FileSpec((const char *)str_ptr);
1489191db47SGreg Clayton }
1499191db47SGreg Clayton return FileSpec();
1509191db47SGreg Clayton }
1519191db47SGreg Clayton
SetReExportedSymbolName(ConstString name)1520e4c4821SAdrian Prantl void Symbol::SetReExportedSymbolName(ConstString name) {
15360038bebSGreg Clayton SetType(eSymbolTypeReExported);
15405097246SAdrian Prantl // For eSymbolTypeReExported, the "const char *" from a ConstString is used
15505097246SAdrian Prantl // as the offset in the address range base address.
15660038bebSGreg Clayton m_addr_range.GetBaseAddress().SetOffset((uintptr_t)name.GetCString());
1579191db47SGreg Clayton }
1589191db47SGreg Clayton
SetReExportedSymbolSharedLibrary(const FileSpec & fspec)159b9c1b51eSKate Stone bool Symbol::SetReExportedSymbolSharedLibrary(const FileSpec &fspec) {
160b9c1b51eSKate Stone if (m_type == eSymbolTypeReExported) {
16105097246SAdrian Prantl // For eSymbolTypeReExported, the "const char *" from a ConstString is used
16205097246SAdrian Prantl // as the offset in the address range base address.
163b9c1b51eSKate Stone m_addr_range.SetByteSize(
164b9c1b51eSKate Stone (uintptr_t)ConstString(fspec.GetPath().c_str()).GetCString());
1659191db47SGreg Clayton return true;
1669191db47SGreg Clayton }
1679191db47SGreg Clayton return false;
1689191db47SGreg Clayton }
1699191db47SGreg Clayton
GetSiblingIndex() const170b9c1b51eSKate Stone uint32_t Symbol::GetSiblingIndex() const {
171bc63aaccSGreg Clayton return m_size_is_sibling ? m_addr_range.GetByteSize() : UINT32_MAX;
17230fdc8d8SChris Lattner }
17330fdc8d8SChris Lattner
IsTrampoline() const174b9c1b51eSKate Stone bool Symbol::IsTrampoline() const { return m_type == eSymbolTypeTrampoline; }
17530fdc8d8SChris Lattner
IsIndirect() const176b9c1b51eSKate Stone bool Symbol::IsIndirect() const { return m_type == eSymbolTypeResolver; }
17700049b8bSMatt Kopec
GetDescription(Stream * s,lldb::DescriptionLevel level,Target * target) const178b9c1b51eSKate Stone void Symbol::GetDescription(Stream *s, lldb::DescriptionLevel level,
179b9c1b51eSKate Stone Target *target) const {
180c4a8a760SGreg Clayton s->Printf("id = {0x%8.8x}", m_uid);
181d9dc52dcSGreg Clayton
182b9c1b51eSKate Stone if (m_addr_range.GetBaseAddress().GetSection()) {
183b9c1b51eSKate Stone if (ValueIsAddress()) {
1848f89a7b0SGreg Clayton const lldb::addr_t byte_size = GetByteSize();
185b9c1b51eSKate Stone if (byte_size > 0) {
1860c5cd90dSGreg Clayton s->PutCString(", range = ");
187b9c1b51eSKate Stone m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress,
188b9c1b51eSKate Stone Address::DumpStyleFileAddress);
189b9c1b51eSKate Stone } else {
1900c5cd90dSGreg Clayton s->PutCString(", address = ");
191b9c1b51eSKate Stone m_addr_range.GetBaseAddress().Dump(s, target,
192b9c1b51eSKate Stone Address::DumpStyleLoadAddress,
193b9c1b51eSKate Stone Address::DumpStyleFileAddress);
194c9800667SGreg Clayton }
195b9c1b51eSKate Stone } else
196b9c1b51eSKate Stone s->Printf(", value = 0x%16.16" PRIx64,
197b9c1b51eSKate Stone m_addr_range.GetBaseAddress().GetOffset());
198b9c1b51eSKate Stone } else {
199c9800667SGreg Clayton if (m_size_is_sibling)
200b9c1b51eSKate Stone s->Printf(", sibling = %5" PRIu64,
201b9c1b51eSKate Stone m_addr_range.GetBaseAddress().GetOffset());
202c9800667SGreg Clayton else
203b9c1b51eSKate Stone s->Printf(", value = 0x%16.16" PRIx64,
204b9c1b51eSKate Stone m_addr_range.GetBaseAddress().GetOffset());
2050c5cd90dSGreg Clayton }
206ec1a4917SGreg Clayton ConstString demangled = GetMangled().GetDemangledName();
207ddaf6a72SGreg Clayton if (demangled)
208ddaf6a72SGreg Clayton s->Printf(", name=\"%s\"", demangled.AsCString());
2096b2bd939SGreg Clayton if (m_mangled.GetMangledName())
2106b2bd939SGreg Clayton s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString());
2110c5cd90dSGreg Clayton }
2120c5cd90dSGreg Clayton
Dump(Stream * s,Target * target,uint32_t index,Mangled::NamePreference name_preference) const21387bc320bSRaphael Isemann void Symbol::Dump(Stream *s, Target *target, uint32_t index,
21487bc320bSRaphael Isemann Mangled::NamePreference name_preference) const {
215b9c1b51eSKate Stone s->Printf("[%5u] %6u %c%c%c %-15s ", index, GetID(), m_is_debug ? 'D' : ' ',
216b9c1b51eSKate Stone m_is_synthetic ? 'S' : ' ', m_is_external ? 'X' : ' ',
21730fdc8d8SChris Lattner GetTypeAsString());
21830fdc8d8SChris Lattner
219e7612134SGreg Clayton // Make sure the size of the symbol is up to date before dumping
220e7612134SGreg Clayton GetByteSize();
221e7612134SGreg Clayton
222ec1a4917SGreg Clayton ConstString name = GetMangled().GetName(name_preference);
223b9c1b51eSKate Stone if (ValueIsAddress()) {
224b9c1b51eSKate Stone if (!m_addr_range.GetBaseAddress().Dump(s, nullptr,
225b9c1b51eSKate Stone Address::DumpStyleFileAddress))
22630fdc8d8SChris Lattner s->Printf("%*s", 18, "");
22730fdc8d8SChris Lattner
22830fdc8d8SChris Lattner s->PutChar(' ');
22930fdc8d8SChris Lattner
230b9c1b51eSKate Stone if (!m_addr_range.GetBaseAddress().Dump(s, target,
231b9c1b51eSKate Stone Address::DumpStyleLoadAddress))
23230fdc8d8SChris Lattner s->Printf("%*s", 18, "");
23330fdc8d8SChris Lattner
234b9c1b51eSKate Stone const char *format = m_size_is_sibling ? " Sibling -> [%5llu] 0x%8.8x %s\n"
235b9c1b51eSKate Stone : " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
236b9c1b51eSKate Stone s->Printf(format, GetByteSize(), m_flags, name.AsCString(""));
237b9c1b51eSKate Stone } else if (m_type == eSymbolTypeReExported) {
238b9c1b51eSKate Stone s->Printf(
239b9c1b51eSKate Stone " 0x%8.8x %s",
240b9c1b51eSKate Stone m_flags, name.AsCString(""));
2419191db47SGreg Clayton
2429191db47SGreg Clayton ConstString reexport_name = GetReExportedSymbolName();
2439191db47SGreg Clayton intptr_t shlib = m_addr_range.GetByteSize();
2449191db47SGreg Clayton if (shlib)
2459191db47SGreg Clayton s->Printf(" -> %s`%s\n", (const char *)shlib, reexport_name.GetCString());
2469191db47SGreg Clayton else
2479191db47SGreg Clayton s->Printf(" -> %s\n", reexport_name.GetCString());
248b9c1b51eSKate Stone } else {
249b9c1b51eSKate Stone const char *format =
250b9c1b51eSKate Stone m_size_is_sibling
251b9c1b51eSKate Stone ? "0x%16.16" PRIx64
252b9c1b51eSKate Stone " Sibling -> [%5llu] 0x%8.8x %s\n"
253b9c1b51eSKate Stone : "0x%16.16" PRIx64 " 0x%16.16" PRIx64
254b9c1b51eSKate Stone " 0x%8.8x %s\n";
255b9c1b51eSKate Stone s->Printf(format, m_addr_range.GetBaseAddress().GetOffset(), GetByteSize(),
256b9c1b51eSKate Stone m_flags, name.AsCString(""));
25730fdc8d8SChris Lattner }
25830fdc8d8SChris Lattner }
25930fdc8d8SChris Lattner
GetPrologueByteSize()260b9c1b51eSKate Stone uint32_t Symbol::GetPrologueByteSize() {
261b9c1b51eSKate Stone if (m_type == eSymbolTypeCode || m_type == eSymbolTypeResolver) {
262b9c1b51eSKate Stone if (!m_type_data_resolved) {
26330fdc8d8SChris Lattner m_type_data_resolved = true;
264bf43d1adSMichael Sartain
265bf43d1adSMichael Sartain const Address &base_address = m_addr_range.GetBaseAddress();
266bf43d1adSMichael Sartain Function *function = base_address.CalculateSymbolContextFunction();
267b9c1b51eSKate Stone if (function) {
268b9c1b51eSKate Stone // Functions have line entries which can also potentially have end of
26905097246SAdrian Prantl // prologue information. So if this symbol points to a function, use
27005097246SAdrian Prantl // the prologue information from there.
271bf43d1adSMichael Sartain m_type_data = function->GetPrologueByteSize();
272b9c1b51eSKate Stone } else {
273bf43d1adSMichael Sartain ModuleSP module_sp(base_address.GetModule());
27430fdc8d8SChris Lattner SymbolContext sc;
275b9c1b51eSKate Stone if (module_sp) {
276b9c1b51eSKate Stone uint32_t resolved_flags = module_sp->ResolveSymbolContextForAddress(
277b9c1b51eSKate Stone base_address, eSymbolContextLineEntry, sc);
278b9c1b51eSKate Stone if (resolved_flags & eSymbolContextLineEntry) {
279a7499c98SMichael Sartain // Default to the end of the first line entry.
28030fdc8d8SChris Lattner m_type_data = sc.line_entry.range.GetByteSize();
281a7499c98SMichael Sartain
282a7499c98SMichael Sartain // Set address for next line.
283bf43d1adSMichael Sartain Address addr(base_address);
284a7499c98SMichael Sartain addr.Slide(m_type_data);
285a7499c98SMichael Sartain
28605097246SAdrian Prantl // Check the first few instructions and look for one that has a
28705097246SAdrian Prantl // line number that is different than the first entry. This is also
28805097246SAdrian Prantl // done in Function::GetPrologueByteSize().
289a7499c98SMichael Sartain uint16_t total_offset = m_type_data;
290b9c1b51eSKate Stone for (int idx = 0; idx < 6; ++idx) {
291a7499c98SMichael Sartain SymbolContext sc_temp;
292b9c1b51eSKate Stone resolved_flags = module_sp->ResolveSymbolContextForAddress(
293b9c1b51eSKate Stone addr, eSymbolContextLineEntry, sc_temp);
294a7499c98SMichael Sartain // Make sure we got line number information...
295a7499c98SMichael Sartain if (!(resolved_flags & eSymbolContextLineEntry))
296a7499c98SMichael Sartain break;
297a7499c98SMichael Sartain
29805097246SAdrian Prantl // If this line number is different than our first one, use it
29905097246SAdrian Prantl // and we're done.
300b9c1b51eSKate Stone if (sc_temp.line_entry.line != sc.line_entry.line) {
301a7499c98SMichael Sartain m_type_data = total_offset;
302a7499c98SMichael Sartain break;
303a7499c98SMichael Sartain }
304a7499c98SMichael Sartain
305a7499c98SMichael Sartain // Slide addr up to the next line address.
306a7499c98SMichael Sartain addr.Slide(sc_temp.line_entry.range.GetByteSize());
307a7499c98SMichael Sartain total_offset += sc_temp.line_entry.range.GetByteSize();
308a7499c98SMichael Sartain // If we've gone too far, bail out.
309a7499c98SMichael Sartain if (total_offset >= m_addr_range.GetByteSize())
310a7499c98SMichael Sartain break;
311a7499c98SMichael Sartain }
312a7499c98SMichael Sartain
313b9c1b51eSKate Stone // Sanity check - this may be a function in the middle of code that
31405097246SAdrian Prantl // has debug information, but not for this symbol. So the line
31505097246SAdrian Prantl // entries surrounding us won't lie inside our function. In that
31605097246SAdrian Prantl // case, the line entry will be bigger than we are, so we do that
31705097246SAdrian Prantl // quick check and if that is true, we just return 0.
318c8ff80d6SJim Ingham if (m_type_data >= m_addr_range.GetByteSize())
319c8ff80d6SJim Ingham m_type_data = 0;
320b9c1b51eSKate Stone } else {
32130fdc8d8SChris Lattner // TODO: expose something in Process to figure out the
32230fdc8d8SChris Lattner // size of a function prologue.
323a7499c98SMichael Sartain m_type_data = 0;
324a7499c98SMichael Sartain }
32530fdc8d8SChris Lattner }
32630fdc8d8SChris Lattner }
327bf43d1adSMichael Sartain }
32830fdc8d8SChris Lattner return m_type_data;
32930fdc8d8SChris Lattner }
33030fdc8d8SChris Lattner return 0;
33130fdc8d8SChris Lattner }
33230fdc8d8SChris Lattner
Compare(ConstString name,SymbolType type) const3330e4c4821SAdrian Prantl bool Symbol::Compare(ConstString name, SymbolType type) const {
334ec1a4917SGreg Clayton if (type == eSymbolTypeAny || m_type == type) {
335ec1a4917SGreg Clayton const Mangled &mangled = GetMangled();
336ec1a4917SGreg Clayton return mangled.GetMangledName() == name ||
337ec1a4917SGreg Clayton mangled.GetDemangledName() == name;
338ec1a4917SGreg Clayton }
33930fdc8d8SChris Lattner return false;
34030fdc8d8SChris Lattner }
34130fdc8d8SChris Lattner
342b9c1b51eSKate Stone #define ENUM_TO_CSTRING(x) \
343b9c1b51eSKate Stone case eSymbolType##x: \
344b9c1b51eSKate Stone return #x;
34530fdc8d8SChris Lattner
GetTypeAsString() const346b9c1b51eSKate Stone const char *Symbol::GetTypeAsString() const {
347b9c1b51eSKate Stone switch (m_type) {
34830fdc8d8SChris Lattner ENUM_TO_CSTRING(Invalid);
34930fdc8d8SChris Lattner ENUM_TO_CSTRING(Absolute);
35030fdc8d8SChris Lattner ENUM_TO_CSTRING(Code);
3519191db47SGreg Clayton ENUM_TO_CSTRING(Resolver);
35230fdc8d8SChris Lattner ENUM_TO_CSTRING(Data);
35330fdc8d8SChris Lattner ENUM_TO_CSTRING(Trampoline);
35430fdc8d8SChris Lattner ENUM_TO_CSTRING(Runtime);
35530fdc8d8SChris Lattner ENUM_TO_CSTRING(Exception);
35630fdc8d8SChris Lattner ENUM_TO_CSTRING(SourceFile);
35730fdc8d8SChris Lattner ENUM_TO_CSTRING(HeaderFile);
35830fdc8d8SChris Lattner ENUM_TO_CSTRING(ObjectFile);
35930fdc8d8SChris Lattner ENUM_TO_CSTRING(CommonBlock);
36030fdc8d8SChris Lattner ENUM_TO_CSTRING(Block);
36130fdc8d8SChris Lattner ENUM_TO_CSTRING(Local);
36230fdc8d8SChris Lattner ENUM_TO_CSTRING(Param);
36330fdc8d8SChris Lattner ENUM_TO_CSTRING(Variable);
36430fdc8d8SChris Lattner ENUM_TO_CSTRING(VariableType);
36530fdc8d8SChris Lattner ENUM_TO_CSTRING(LineEntry);
36630fdc8d8SChris Lattner ENUM_TO_CSTRING(LineHeader);
36730fdc8d8SChris Lattner ENUM_TO_CSTRING(ScopeBegin);
36830fdc8d8SChris Lattner ENUM_TO_CSTRING(ScopeEnd);
36930fdc8d8SChris Lattner ENUM_TO_CSTRING(Additional);
37030fdc8d8SChris Lattner ENUM_TO_CSTRING(Compiler);
37130fdc8d8SChris Lattner ENUM_TO_CSTRING(Instrumentation);
37230fdc8d8SChris Lattner ENUM_TO_CSTRING(Undefined);
373456809c1SGreg Clayton ENUM_TO_CSTRING(ObjCClass);
374456809c1SGreg Clayton ENUM_TO_CSTRING(ObjCMetaClass);
375456809c1SGreg Clayton ENUM_TO_CSTRING(ObjCIVar);
3769191db47SGreg Clayton ENUM_TO_CSTRING(ReExported);
37730fdc8d8SChris Lattner default:
37830fdc8d8SChris Lattner break;
37930fdc8d8SChris Lattner }
38030fdc8d8SChris Lattner return "<unknown SymbolType>";
38130fdc8d8SChris Lattner }
38230fdc8d8SChris Lattner
CalculateSymbolContext(SymbolContext * sc)383b9c1b51eSKate Stone void Symbol::CalculateSymbolContext(SymbolContext *sc) {
38459e8fc1cSGreg Clayton // Symbols can reconstruct the symbol and the module in the symbol context
38559e8fc1cSGreg Clayton sc->symbol = this;
386e7612134SGreg Clayton if (ValueIsAddress())
387358cf1eaSGreg Clayton sc->module_sp = GetAddressRef().GetModule();
388e1cd1be6SGreg Clayton else
38959e8fc1cSGreg Clayton sc->module_sp.reset();
39059e8fc1cSGreg Clayton }
39159e8fc1cSGreg Clayton
CalculateSymbolContextModule()392b9c1b51eSKate Stone ModuleSP Symbol::CalculateSymbolContextModule() {
393e7612134SGreg Clayton if (ValueIsAddress())
394358cf1eaSGreg Clayton return GetAddressRef().GetModule();
395e72dfb32SGreg Clayton return ModuleSP();
3967e9b1fd0SGreg Clayton }
3977e9b1fd0SGreg Clayton
CalculateSymbolContextSymbol()398b9c1b51eSKate Stone Symbol *Symbol::CalculateSymbolContextSymbol() { return this; }
3997e9b1fd0SGreg Clayton
DumpSymbolContext(Stream * s)400b9c1b51eSKate Stone void Symbol::DumpSymbolContext(Stream *s) {
40159e8fc1cSGreg Clayton bool dumped_module = false;
402b9c1b51eSKate Stone if (ValueIsAddress()) {
403358cf1eaSGreg Clayton ModuleSP module_sp(GetAddressRef().GetModule());
404b9c1b51eSKate Stone if (module_sp) {
40559e8fc1cSGreg Clayton dumped_module = true;
406e72dfb32SGreg Clayton module_sp->DumpSymbolContext(s);
40759e8fc1cSGreg Clayton }
40859e8fc1cSGreg Clayton }
40959e8fc1cSGreg Clayton if (dumped_module)
41059e8fc1cSGreg Clayton s->PutCString(", ");
41159e8fc1cSGreg Clayton
41259e8fc1cSGreg Clayton s->Printf("Symbol{0x%8.8x}", GetID());
41359e8fc1cSGreg Clayton }
41459e8fc1cSGreg Clayton
GetByteSize() const415b9c1b51eSKate Stone lldb::addr_t Symbol::GetByteSize() const { return m_addr_range.GetByteSize(); }
416da171f11SGreg Clayton
ResolveReExportedSymbolInModuleSpec(Target & target,ConstString & reexport_name,ModuleSpec & module_spec,ModuleList & seen_modules) const417b9c1b51eSKate Stone Symbol *Symbol::ResolveReExportedSymbolInModuleSpec(
418b9c1b51eSKate Stone Target &target, ConstString &reexport_name, ModuleSpec &module_spec,
419b9c1b51eSKate Stone ModuleList &seen_modules) const {
4209191db47SGreg Clayton ModuleSP module_sp;
421b9c1b51eSKate Stone if (module_spec.GetFileSpec()) {
4229191db47SGreg Clayton // Try searching for the module file spec first using the full path
4239191db47SGreg Clayton module_sp = target.GetImages().FindFirstModule(module_spec);
424b9c1b51eSKate Stone if (!module_sp) {
42505097246SAdrian Prantl // Next try and find the module by basename in case environment variables
42605097246SAdrian Prantl // or other runtime trickery causes shared libraries to be loaded from
42705097246SAdrian Prantl // alternate paths
428*1b4b12a3SNico Weber module_spec.GetFileSpec().GetDirectory().Clear();
4299191db47SGreg Clayton module_sp = target.GetImages().FindFirstModule(module_spec);
4309191db47SGreg Clayton }
4319191db47SGreg Clayton }
4329191db47SGreg Clayton
433b9c1b51eSKate Stone if (module_sp) {
434b9c1b51eSKate Stone // There should not be cycles in the reexport list, but we don't want to
43505097246SAdrian Prantl // crash if there are so make sure we haven't seen this before:
436fbe0b9abSJim Ingham if (!seen_modules.AppendIfNeeded(module_sp))
437fbe0b9abSJim Ingham return nullptr;
438fbe0b9abSJim Ingham
4399191db47SGreg Clayton lldb_private::SymbolContextList sc_list;
440b9c1b51eSKate Stone module_sp->FindSymbolsWithNameAndType(reexport_name, eSymbolTypeAny,
441b9c1b51eSKate Stone sc_list);
4429191db47SGreg Clayton const size_t num_scs = sc_list.GetSize();
443b9c1b51eSKate Stone if (num_scs > 0) {
444b9c1b51eSKate Stone for (size_t i = 0; i < num_scs; ++i) {
4459191db47SGreg Clayton lldb_private::SymbolContext sc;
446b9c1b51eSKate Stone if (sc_list.GetContextAtIndex(i, sc)) {
4479191db47SGreg Clayton if (sc.symbol->IsExternal())
4489191db47SGreg Clayton return sc.symbol;
4499191db47SGreg Clayton }
4509191db47SGreg Clayton }
4519191db47SGreg Clayton }
452b9c1b51eSKate Stone // If we didn't find the symbol in this module, it may be because this
45305097246SAdrian Prantl // module re-exports some whole other library. We have to search those as
45405097246SAdrian Prantl // well:
455fbe0b9abSJim Ingham seen_modules.Append(module_sp);
456fbe0b9abSJim Ingham
457b9c1b51eSKate Stone FileSpecList reexported_libraries =
458b9c1b51eSKate Stone module_sp->GetObjectFile()->GetReExportedLibraries();
459fbe0b9abSJim Ingham size_t num_reexported_libraries = reexported_libraries.GetSize();
460b9c1b51eSKate Stone for (size_t idx = 0; idx < num_reexported_libraries; idx++) {
461fbe0b9abSJim Ingham ModuleSpec reexported_module_spec;
462b9c1b51eSKate Stone reexported_module_spec.GetFileSpec() =
463b9c1b51eSKate Stone reexported_libraries.GetFileSpecAtIndex(idx);
464b9c1b51eSKate Stone Symbol *result_symbol = ResolveReExportedSymbolInModuleSpec(
465b9c1b51eSKate Stone target, reexport_name, reexported_module_spec, seen_modules);
466fbe0b9abSJim Ingham if (result_symbol)
467fbe0b9abSJim Ingham return result_symbol;
468fbe0b9abSJim Ingham }
469fbe0b9abSJim Ingham }
470fbe0b9abSJim Ingham return nullptr;
471fbe0b9abSJim Ingham }
472fbe0b9abSJim Ingham
ResolveReExportedSymbol(Target & target) const473b9c1b51eSKate Stone Symbol *Symbol::ResolveReExportedSymbol(Target &target) const {
474fbe0b9abSJim Ingham ConstString reexport_name(GetReExportedSymbolName());
475b9c1b51eSKate Stone if (reexport_name) {
476fbe0b9abSJim Ingham ModuleSpec module_spec;
477fbe0b9abSJim Ingham ModuleList seen_modules;
478fbe0b9abSJim Ingham module_spec.GetFileSpec() = GetReExportedSymbolSharedLibrary();
479b9c1b51eSKate Stone if (module_spec.GetFileSpec()) {
480b9c1b51eSKate Stone return ResolveReExportedSymbolInModuleSpec(target, reexport_name,
481b9c1b51eSKate Stone module_spec, seen_modules);
4829191db47SGreg Clayton }
4839191db47SGreg Clayton }
484d4612ad0SEd Maste return nullptr;
4859191db47SGreg Clayton }
48644d93782SGreg Clayton
GetFileAddress() const487b9c1b51eSKate Stone lldb::addr_t Symbol::GetFileAddress() const {
488358cf1eaSGreg Clayton if (ValueIsAddress())
489358cf1eaSGreg Clayton return GetAddressRef().GetFileAddress();
490358cf1eaSGreg Clayton else
491358cf1eaSGreg Clayton return LLDB_INVALID_ADDRESS;
492358cf1eaSGreg Clayton }
493358cf1eaSGreg Clayton
GetLoadAddress(Target * target) const494b9c1b51eSKate Stone lldb::addr_t Symbol::GetLoadAddress(Target *target) const {
495358cf1eaSGreg Clayton if (ValueIsAddress())
496358cf1eaSGreg Clayton return GetAddressRef().GetLoadAddress(target);
497358cf1eaSGreg Clayton else
498358cf1eaSGreg Clayton return LLDB_INVALID_ADDRESS;
499358cf1eaSGreg Clayton }
500358cf1eaSGreg Clayton
GetName() const501ec1a4917SGreg Clayton ConstString Symbol::GetName() const { return GetMangled().GetName(); }
502b9c1b51eSKate Stone
GetNameNoArguments() const503b9c1b51eSKate Stone ConstString Symbol::GetNameNoArguments() const {
504ec1a4917SGreg Clayton return GetMangled().GetName(Mangled::ePreferDemangledWithoutArguments);
505ddaf6a72SGreg Clayton }
506ddaf6a72SGreg Clayton
ResolveCallableAddress(Target & target) const507b9c1b51eSKate Stone lldb::addr_t Symbol::ResolveCallableAddress(Target &target) const {
50825ea6a1bSSean Callanan if (GetType() == lldb::eSymbolTypeUndefined)
50925ea6a1bSSean Callanan return LLDB_INVALID_ADDRESS;
51025ea6a1bSSean Callanan
51125ea6a1bSSean Callanan Address func_so_addr;
51225ea6a1bSSean Callanan
5139aae9fcbSJason Molenda bool is_indirect = IsIndirect();
514b9c1b51eSKate Stone if (GetType() == eSymbolTypeReExported) {
51525ea6a1bSSean Callanan Symbol *reexported_symbol = ResolveReExportedSymbol(target);
516b9c1b51eSKate Stone if (reexported_symbol) {
51725ea6a1bSSean Callanan func_so_addr = reexported_symbol->GetAddress();
51825ea6a1bSSean Callanan is_indirect = reexported_symbol->IsIndirect();
51925ea6a1bSSean Callanan }
520b9c1b51eSKate Stone } else {
52125ea6a1bSSean Callanan func_so_addr = GetAddress();
52225ea6a1bSSean Callanan is_indirect = IsIndirect();
52325ea6a1bSSean Callanan }
52425ea6a1bSSean Callanan
525b9c1b51eSKate Stone if (func_so_addr.IsValid()) {
526b9c1b51eSKate Stone if (!target.GetProcessSP() && is_indirect) {
52725ea6a1bSSean Callanan // can't resolve indirect symbols without calling a function...
52825ea6a1bSSean Callanan return LLDB_INVALID_ADDRESS;
52925ea6a1bSSean Callanan }
53025ea6a1bSSean Callanan
531b9c1b51eSKate Stone lldb::addr_t load_addr =
532b9c1b51eSKate Stone func_so_addr.GetCallableLoadAddress(&target, is_indirect);
53325ea6a1bSSean Callanan
534b9c1b51eSKate Stone if (load_addr != LLDB_INVALID_ADDRESS) {
53525ea6a1bSSean Callanan return load_addr;
53625ea6a1bSSean Callanan }
53725ea6a1bSSean Callanan }
53825ea6a1bSSean Callanan
53925ea6a1bSSean Callanan return LLDB_INVALID_ADDRESS;
54025ea6a1bSSean Callanan }
54125ea6a1bSSean Callanan
GetInstructions(const ExecutionContext & exe_ctx,const char * flavor,bool prefer_file_cache)542b9c1b51eSKate Stone lldb::DisassemblerSP Symbol::GetInstructions(const ExecutionContext &exe_ctx,
54344d93782SGreg Clayton const char *flavor,
544b9c1b51eSKate Stone bool prefer_file_cache) {
54544d93782SGreg Clayton ModuleSP module_sp(m_addr_range.GetBaseAddress().GetModule());
54604592d5bSPavel Labath if (module_sp && exe_ctx.HasTargetScope()) {
547b9c1b51eSKate Stone return Disassembler::DisassembleRange(module_sp->GetArchitecture(), nullptr,
54804592d5bSPavel Labath flavor, exe_ctx.GetTargetRef(),
549e9fe788dSJason Molenda m_addr_range, !prefer_file_cache);
55044d93782SGreg Clayton }
55144d93782SGreg Clayton return lldb::DisassemblerSP();
55244d93782SGreg Clayton }
55344d93782SGreg Clayton
GetDisassembly(const ExecutionContext & exe_ctx,const char * flavor,bool prefer_file_cache,Stream & strm)554b9c1b51eSKate Stone bool Symbol::GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor,
555b9c1b51eSKate Stone bool prefer_file_cache, Stream &strm) {
556b9c1b51eSKate Stone lldb::DisassemblerSP disassembler_sp =
557b9c1b51eSKate Stone GetInstructions(exe_ctx, flavor, prefer_file_cache);
558b9c1b51eSKate Stone if (disassembler_sp) {
55944d93782SGreg Clayton const bool show_address = true;
56044d93782SGreg Clayton const bool show_bytes = false;
561ad7bcda9SWalter Erquinigo const bool show_control_flow_kind = false;
562ad7bcda9SWalter Erquinigo disassembler_sp->GetInstructionList().Dump(
563ad7bcda9SWalter Erquinigo &strm, show_address, show_bytes, show_control_flow_kind, &exe_ctx);
56444d93782SGreg Clayton return true;
56544d93782SGreg Clayton }
56644d93782SGreg Clayton return false;
56744d93782SGreg Clayton }
5688c6996f7STamas Berghammer
ContainsFileAddress(lldb::addr_t file_addr) const569b9c1b51eSKate Stone bool Symbol::ContainsFileAddress(lldb::addr_t file_addr) const {
5708c6996f7STamas Berghammer return m_addr_range.ContainsFileAddress(file_addr);
5718c6996f7STamas Berghammer }
572ec1a4917SGreg Clayton
IsSyntheticWithAutoGeneratedName() const573ec1a4917SGreg Clayton bool Symbol::IsSyntheticWithAutoGeneratedName() const {
574ec1a4917SGreg Clayton if (!IsSynthetic())
575ec1a4917SGreg Clayton return false;
576ec1a4917SGreg Clayton if (!m_mangled)
577ec1a4917SGreg Clayton return true;
578ec1a4917SGreg Clayton ConstString demangled = m_mangled.GetDemangledName();
579ec1a4917SGreg Clayton return demangled.GetStringRef().startswith(GetSyntheticSymbolPrefix());
580ec1a4917SGreg Clayton }
581ec1a4917SGreg Clayton
SynthesizeNameIfNeeded() const582ec1a4917SGreg Clayton void Symbol::SynthesizeNameIfNeeded() const {
583ec1a4917SGreg Clayton if (m_is_synthetic && !m_mangled) {
584ec1a4917SGreg Clayton // Synthetic symbol names don't mean anything, but they do uniquely
585ec1a4917SGreg Clayton // identify individual symbols so we give them a unique name. The name
586ec1a4917SGreg Clayton // starts with the synthetic symbol prefix, followed by a unique number.
587ec1a4917SGreg Clayton // Typically the UserID of a real symbol is the symbol table index of the
588ec1a4917SGreg Clayton // symbol in the object file's symbol table(s), so it will be the same
589ec1a4917SGreg Clayton // every time you read in the object file. We want the same persistence for
590ec1a4917SGreg Clayton // synthetic symbols so that users can identify them across multiple debug
591ec1a4917SGreg Clayton // sessions, to understand crashes in those symbols and to reliably set
592ec1a4917SGreg Clayton // breakpoints on them.
593ec1a4917SGreg Clayton llvm::SmallString<256> name;
594ec1a4917SGreg Clayton llvm::raw_svector_ostream os(name);
595ec1a4917SGreg Clayton os << GetSyntheticSymbolPrefix() << GetID();
596ec1a4917SGreg Clayton m_mangled.SetDemangledName(ConstString(os.str()));
597ec1a4917SGreg Clayton }
598ec1a4917SGreg Clayton }
599da816ca0SGreg Clayton
Decode(const DataExtractor & data,lldb::offset_t * offset_ptr,const SectionList * section_list,const StringTableReader & strtab)600da816ca0SGreg Clayton bool Symbol::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
601da816ca0SGreg Clayton const SectionList *section_list,
602da816ca0SGreg Clayton const StringTableReader &strtab) {
603da816ca0SGreg Clayton if (!data.ValidOffsetForDataOfSize(*offset_ptr, 8))
604da816ca0SGreg Clayton return false;
605da816ca0SGreg Clayton m_uid = data.GetU32(offset_ptr);
606da816ca0SGreg Clayton m_type_data = data.GetU16(offset_ptr);
607da816ca0SGreg Clayton const uint16_t bitfields = data.GetU16(offset_ptr);
608da816ca0SGreg Clayton m_type_data_resolved = (1u << 15 & bitfields) != 0;
609da816ca0SGreg Clayton m_is_synthetic = (1u << 14 & bitfields) != 0;
610da816ca0SGreg Clayton m_is_debug = (1u << 13 & bitfields) != 0;
611da816ca0SGreg Clayton m_is_external = (1u << 12 & bitfields) != 0;
612da816ca0SGreg Clayton m_size_is_sibling = (1u << 11 & bitfields) != 0;
613da816ca0SGreg Clayton m_size_is_synthesized = (1u << 10 & bitfields) != 0;
614da816ca0SGreg Clayton m_size_is_valid = (1u << 9 & bitfields) != 0;
615da816ca0SGreg Clayton m_demangled_is_synthesized = (1u << 8 & bitfields) != 0;
616da816ca0SGreg Clayton m_contains_linker_annotations = (1u << 7 & bitfields) != 0;
617da816ca0SGreg Clayton m_is_weak = (1u << 6 & bitfields) != 0;
618da816ca0SGreg Clayton m_type = bitfields & 0x003f;
619da816ca0SGreg Clayton if (!m_mangled.Decode(data, offset_ptr, strtab))
620da816ca0SGreg Clayton return false;
621da816ca0SGreg Clayton if (!data.ValidOffsetForDataOfSize(*offset_ptr, 20))
622da816ca0SGreg Clayton return false;
623da816ca0SGreg Clayton const bool is_addr = data.GetU8(offset_ptr) != 0;
624da816ca0SGreg Clayton const uint64_t value = data.GetU64(offset_ptr);
625da816ca0SGreg Clayton if (is_addr) {
626da816ca0SGreg Clayton m_addr_range.GetBaseAddress().ResolveAddressUsingFileSections(
627da816ca0SGreg Clayton value, section_list);
628da816ca0SGreg Clayton } else {
629da816ca0SGreg Clayton m_addr_range.GetBaseAddress().Clear();
630da816ca0SGreg Clayton m_addr_range.GetBaseAddress().SetOffset(value);
631da816ca0SGreg Clayton }
632da816ca0SGreg Clayton m_addr_range.SetByteSize(data.GetU64(offset_ptr));
633da816ca0SGreg Clayton m_flags = data.GetU32(offset_ptr);
634da816ca0SGreg Clayton return true;
635da816ca0SGreg Clayton }
636da816ca0SGreg Clayton
637da816ca0SGreg Clayton /// The encoding format for the symbol is as follows:
638da816ca0SGreg Clayton ///
639da816ca0SGreg Clayton /// uint32_t m_uid;
640da816ca0SGreg Clayton /// uint16_t m_type_data;
641da816ca0SGreg Clayton /// uint16_t bitfield_data;
642da816ca0SGreg Clayton /// Mangled mangled;
643da816ca0SGreg Clayton /// uint8_t is_addr;
644da816ca0SGreg Clayton /// uint64_t file_addr_or_value;
645da816ca0SGreg Clayton /// uint64_t size;
646da816ca0SGreg Clayton /// uint32_t flags;
647da816ca0SGreg Clayton ///
648da816ca0SGreg Clayton /// The only tricky thing in this encoding is encoding all of the bits in the
649da816ca0SGreg Clayton /// bitfields. We use a trick to store all bitfields as a 16 bit value and we
650da816ca0SGreg Clayton /// do the same thing when decoding the symbol. There are test that ensure this
651da816ca0SGreg Clayton /// encoding works for each individual bit. Everything else is very easy to
652da816ca0SGreg Clayton /// store.
Encode(DataEncoder & file,ConstStringTable & strtab) const653da816ca0SGreg Clayton void Symbol::Encode(DataEncoder &file, ConstStringTable &strtab) const {
654da816ca0SGreg Clayton file.AppendU32(m_uid);
655da816ca0SGreg Clayton file.AppendU16(m_type_data);
656da816ca0SGreg Clayton uint16_t bitfields = m_type;
657da816ca0SGreg Clayton if (m_type_data_resolved)
658da816ca0SGreg Clayton bitfields |= 1u << 15;
659da816ca0SGreg Clayton if (m_is_synthetic)
660da816ca0SGreg Clayton bitfields |= 1u << 14;
661da816ca0SGreg Clayton if (m_is_debug)
662da816ca0SGreg Clayton bitfields |= 1u << 13;
663da816ca0SGreg Clayton if (m_is_external)
664da816ca0SGreg Clayton bitfields |= 1u << 12;
665da816ca0SGreg Clayton if (m_size_is_sibling)
666da816ca0SGreg Clayton bitfields |= 1u << 11;
667da816ca0SGreg Clayton if (m_size_is_synthesized)
668da816ca0SGreg Clayton bitfields |= 1u << 10;
669da816ca0SGreg Clayton if (m_size_is_valid)
670da816ca0SGreg Clayton bitfields |= 1u << 9;
671da816ca0SGreg Clayton if (m_demangled_is_synthesized)
672da816ca0SGreg Clayton bitfields |= 1u << 8;
673da816ca0SGreg Clayton if (m_contains_linker_annotations)
674da816ca0SGreg Clayton bitfields |= 1u << 7;
675da816ca0SGreg Clayton if (m_is_weak)
676da816ca0SGreg Clayton bitfields |= 1u << 6;
677da816ca0SGreg Clayton file.AppendU16(bitfields);
678da816ca0SGreg Clayton m_mangled.Encode(file, strtab);
679da816ca0SGreg Clayton // A symbol's value might be an address, or it might be a constant. If the
680da816ca0SGreg Clayton // symbol's base address doesn't have a section, then it is a constant value.
681da816ca0SGreg Clayton // If it does have a section, we will encode the file address and re-resolve
682da816ca0SGreg Clayton // the address when we decode it.
683b8336280SKazu Hirata bool is_addr = m_addr_range.GetBaseAddress().GetSection().get() != nullptr;
684da816ca0SGreg Clayton file.AppendU8(is_addr);
685da816ca0SGreg Clayton file.AppendU64(m_addr_range.GetBaseAddress().GetFileAddress());
686da816ca0SGreg Clayton file.AppendU64(m_addr_range.GetByteSize());
687da816ca0SGreg Clayton file.AppendU32(m_flags);
688da816ca0SGreg Clayton }
689da816ca0SGreg Clayton
operator ==(const Symbol & rhs) const690da816ca0SGreg Clayton bool Symbol::operator==(const Symbol &rhs) const {
691da816ca0SGreg Clayton if (m_uid != rhs.m_uid)
692da816ca0SGreg Clayton return false;
693da816ca0SGreg Clayton if (m_type_data != rhs.m_type_data)
694da816ca0SGreg Clayton return false;
695da816ca0SGreg Clayton if (m_type_data_resolved != rhs.m_type_data_resolved)
696da816ca0SGreg Clayton return false;
697da816ca0SGreg Clayton if (m_is_synthetic != rhs.m_is_synthetic)
698da816ca0SGreg Clayton return false;
699da816ca0SGreg Clayton if (m_is_debug != rhs.m_is_debug)
700da816ca0SGreg Clayton return false;
701da816ca0SGreg Clayton if (m_is_external != rhs.m_is_external)
702da816ca0SGreg Clayton return false;
703da816ca0SGreg Clayton if (m_size_is_sibling != rhs.m_size_is_sibling)
704da816ca0SGreg Clayton return false;
705da816ca0SGreg Clayton if (m_size_is_synthesized != rhs.m_size_is_synthesized)
706da816ca0SGreg Clayton return false;
707da816ca0SGreg Clayton if (m_size_is_valid != rhs.m_size_is_valid)
708da816ca0SGreg Clayton return false;
709da816ca0SGreg Clayton if (m_demangled_is_synthesized != rhs.m_demangled_is_synthesized)
710da816ca0SGreg Clayton return false;
711da816ca0SGreg Clayton if (m_contains_linker_annotations != rhs.m_contains_linker_annotations)
712da816ca0SGreg Clayton return false;
713da816ca0SGreg Clayton if (m_is_weak != rhs.m_is_weak)
714da816ca0SGreg Clayton return false;
715da816ca0SGreg Clayton if (m_type != rhs.m_type)
716da816ca0SGreg Clayton return false;
717da816ca0SGreg Clayton if (m_mangled != rhs.m_mangled)
718da816ca0SGreg Clayton return false;
719da816ca0SGreg Clayton if (m_addr_range.GetBaseAddress() != rhs.m_addr_range.GetBaseAddress())
720da816ca0SGreg Clayton return false;
721da816ca0SGreg Clayton if (m_addr_range.GetByteSize() != rhs.m_addr_range.GetByteSize())
722da816ca0SGreg Clayton return false;
723da816ca0SGreg Clayton if (m_flags != rhs.m_flags)
724da816ca0SGreg Clayton return false;
725da816ca0SGreg Clayton return true;
726da816ca0SGreg Clayton }
727