180814287SRaphael Isemann //===-- Address.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/Core/Address.h"
101435f6b0SMed Ismail Bennani #include "lldb/Core/Declaration.h"
1129cb868aSZachary Turner #include "lldb/Core/DumpDataExtractor.h"
1230fdc8d8SChris Lattner #include "lldb/Core/Module.h"
13672d2c12SJonas Devlieghere #include "lldb/Core/ModuleList.h"
1430fdc8d8SChris Lattner #include "lldb/Core/Section.h"
151f746071SGreg Clayton #include "lldb/Symbol/Block.h"
16672d2c12SJonas Devlieghere #include "lldb/Symbol/LineEntry.h"
1730fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
18672d2c12SJonas Devlieghere #include "lldb/Symbol/Symbol.h"
19672d2c12SJonas Devlieghere #include "lldb/Symbol/SymbolContext.h"
20b9c1b51eSKate Stone #include "lldb/Symbol/SymbolVendor.h"
21672d2c12SJonas Devlieghere #include "lldb/Symbol/Symtab.h"
22672d2c12SJonas Devlieghere #include "lldb/Symbol/Type.h"
23c749eb89SGreg Clayton #include "lldb/Symbol/Variable.h"
24c749eb89SGreg Clayton #include "lldb/Symbol/VariableList.h"
2515983c28SZequan Wu #include "lldb/Target/ABI.h"
26f5e56de0SGreg Clayton #include "lldb/Target/ExecutionContext.h"
27672d2c12SJonas Devlieghere #include "lldb/Target/ExecutionContextScope.h"
2830fdc8d8SChris Lattner #include "lldb/Target/Process.h"
29d5944cd1SGreg Clayton #include "lldb/Target/SectionLoadList.h"
3030fdc8d8SChris Lattner #include "lldb/Target/Target.h"
31672d2c12SJonas Devlieghere #include "lldb/Utility/ConstString.h"
32672d2c12SJonas Devlieghere #include "lldb/Utility/DataExtractor.h"
33672d2c12SJonas Devlieghere #include "lldb/Utility/Endian.h"
34672d2c12SJonas Devlieghere #include "lldb/Utility/FileSpec.h"
35672d2c12SJonas Devlieghere #include "lldb/Utility/Status.h"
36672d2c12SJonas Devlieghere #include "lldb/Utility/Stream.h"
37672d2c12SJonas Devlieghere #include "lldb/Utility/StreamString.h"
382f3df613SZachary Turner
39672d2c12SJonas Devlieghere #include "llvm/ADT/StringRef.h"
402f3df613SZachary Turner #include "llvm/ADT/Triple.h"
41672d2c12SJonas Devlieghere #include "llvm/Support/Compiler.h"
422f3df613SZachary Turner
43672d2c12SJonas Devlieghere #include <cstdint>
44672d2c12SJonas Devlieghere #include <memory>
45672d2c12SJonas Devlieghere #include <vector>
462f3df613SZachary Turner
4776e47d48SRaphael Isemann #include <cassert>
4876e47d48SRaphael Isemann #include <cinttypes>
4976e47d48SRaphael Isemann #include <cstring>
502f3df613SZachary Turner
512f3df613SZachary Turner namespace lldb_private {
522f3df613SZachary Turner class CompileUnit;
532f3df613SZachary Turner }
542f3df613SZachary Turner namespace lldb_private {
552f3df613SZachary Turner class Function;
562f3df613SZachary Turner }
5730fdc8d8SChris Lattner
5830fdc8d8SChris Lattner using namespace lldb;
5930fdc8d8SChris Lattner using namespace lldb_private;
6030fdc8d8SChris Lattner
ReadBytes(ExecutionContextScope * exe_scope,const Address & address,void * dst,size_t dst_len)61b9c1b51eSKate Stone static size_t ReadBytes(ExecutionContextScope *exe_scope,
62b9c1b51eSKate Stone const Address &address, void *dst, size_t dst_len) {
63896ddd03SEugene Zelenko if (exe_scope == nullptr)
6430fdc8d8SChris Lattner return 0;
6530fdc8d8SChris Lattner
66d9e416c0SGreg Clayton TargetSP target_sp(exe_scope->CalculateTarget());
67b9c1b51eSKate Stone if (target_sp) {
6897206d57SZachary Turner Status error;
69e9fe788dSJason Molenda bool force_live_memory = true;
70e9fe788dSJason Molenda return target_sp->ReadMemory(address, dst, dst_len, error,
71e9fe788dSJason Molenda force_live_memory);
7230fdc8d8SChris Lattner }
7330fdc8d8SChris Lattner return 0;
7430fdc8d8SChris Lattner }
7530fdc8d8SChris Lattner
GetByteOrderAndAddressSize(ExecutionContextScope * exe_scope,const Address & address,ByteOrder & byte_order,uint32_t & addr_size)76b9c1b51eSKate Stone static bool GetByteOrderAndAddressSize(ExecutionContextScope *exe_scope,
77b9c1b51eSKate Stone const Address &address,
78b9c1b51eSKate Stone ByteOrder &byte_order,
79b9c1b51eSKate Stone uint32_t &addr_size) {
8030fdc8d8SChris Lattner byte_order = eByteOrderInvalid;
8130fdc8d8SChris Lattner addr_size = 0;
82896ddd03SEugene Zelenko if (exe_scope == nullptr)
8330fdc8d8SChris Lattner return false;
8430fdc8d8SChris Lattner
85d9e416c0SGreg Clayton TargetSP target_sp(exe_scope->CalculateTarget());
86b9c1b51eSKate Stone if (target_sp) {
87d9e416c0SGreg Clayton byte_order = target_sp->GetArchitecture().GetByteOrder();
88d9e416c0SGreg Clayton addr_size = target_sp->GetArchitecture().GetAddressByteSize();
8930fdc8d8SChris Lattner }
9030fdc8d8SChris Lattner
91b9c1b51eSKate Stone if (byte_order == eByteOrderInvalid || addr_size == 0) {
92e72dfb32SGreg Clayton ModuleSP module_sp(address.GetModule());
93b9c1b51eSKate Stone if (module_sp) {
94e72dfb32SGreg Clayton byte_order = module_sp->GetArchitecture().GetByteOrder();
95e72dfb32SGreg Clayton addr_size = module_sp->GetArchitecture().GetAddressByteSize();
9630fdc8d8SChris Lattner }
9730fdc8d8SChris Lattner }
9830fdc8d8SChris Lattner return byte_order != eByteOrderInvalid && addr_size != 0;
9930fdc8d8SChris Lattner }
10030fdc8d8SChris Lattner
ReadUIntMax64(ExecutionContextScope * exe_scope,const Address & address,uint32_t byte_size,bool & success)101b9c1b51eSKate Stone static uint64_t ReadUIntMax64(ExecutionContextScope *exe_scope,
102b9c1b51eSKate Stone const Address &address, uint32_t byte_size,
103b9c1b51eSKate Stone bool &success) {
10430fdc8d8SChris Lattner uint64_t uval64 = 0;
105b9c1b51eSKate Stone if (exe_scope == nullptr || byte_size > sizeof(uint64_t)) {
10630fdc8d8SChris Lattner success = false;
10730fdc8d8SChris Lattner return 0;
10830fdc8d8SChris Lattner }
10940e35929SJohnny Chen uint64_t buf = 0;
11030fdc8d8SChris Lattner
11130fdc8d8SChris Lattner success = ReadBytes(exe_scope, address, &buf, byte_size) == byte_size;
112b9c1b51eSKate Stone if (success) {
11330fdc8d8SChris Lattner ByteOrder byte_order = eByteOrderInvalid;
11430fdc8d8SChris Lattner uint32_t addr_size = 0;
115b9c1b51eSKate Stone if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
11630fdc8d8SChris Lattner DataExtractor data(&buf, sizeof(buf), byte_order, addr_size);
117c7bece56SGreg Clayton lldb::offset_t offset = 0;
11830fdc8d8SChris Lattner uval64 = data.GetU64(&offset);
119b9c1b51eSKate Stone } else
12030fdc8d8SChris Lattner success = false;
12130fdc8d8SChris Lattner }
12230fdc8d8SChris Lattner return uval64;
12330fdc8d8SChris Lattner }
12430fdc8d8SChris Lattner
ReadAddress(ExecutionContextScope * exe_scope,const Address & address,uint32_t pointer_size,Address & deref_so_addr)125b9c1b51eSKate Stone static bool ReadAddress(ExecutionContextScope *exe_scope,
126b9c1b51eSKate Stone const Address &address, uint32_t pointer_size,
127b9c1b51eSKate Stone Address &deref_so_addr) {
128896ddd03SEugene Zelenko if (exe_scope == nullptr)
12930fdc8d8SChris Lattner return false;
13030fdc8d8SChris Lattner
13130fdc8d8SChris Lattner bool success = false;
13230fdc8d8SChris Lattner addr_t deref_addr = ReadUIntMax64(exe_scope, address, pointer_size, success);
133b9c1b51eSKate Stone if (success) {
134f5e56de0SGreg Clayton ExecutionContext exe_ctx;
1350603aa9dSGreg Clayton exe_scope->CalculateExecutionContext(exe_ctx);
136f5e56de0SGreg Clayton // If we have any sections that are loaded, try and resolve using the
137f5e56de0SGreg Clayton // section load list
138c14ee32dSGreg Clayton Target *target = exe_ctx.GetTargetPtr();
139b9c1b51eSKate Stone if (target && !target->GetSectionLoadList().IsEmpty()) {
140b9c1b51eSKate Stone if (target->GetSectionLoadList().ResolveLoadAddress(deref_addr,
141b9c1b51eSKate Stone deref_so_addr))
142f5e56de0SGreg Clayton return true;
143b9c1b51eSKate Stone } else {
14405097246SAdrian Prantl // If we were not running, yet able to read an integer, we must have a
14505097246SAdrian Prantl // module
146e72dfb32SGreg Clayton ModuleSP module_sp(address.GetModule());
147e72dfb32SGreg Clayton
148e72dfb32SGreg Clayton assert(module_sp);
149e72dfb32SGreg Clayton if (module_sp->ResolveFileAddress(deref_addr, deref_so_addr))
150f5e56de0SGreg Clayton return true;
151f5e56de0SGreg Clayton }
15230fdc8d8SChris Lattner
153f5e56de0SGreg Clayton // We couldn't make "deref_addr" into a section offset value, but we were
15405097246SAdrian Prantl // able to read the address, so we return a section offset address with no
15505097246SAdrian Prantl // section and "deref_addr" as the offset (address).
156e72dfb32SGreg Clayton deref_so_addr.SetRawAddress(deref_addr);
15730fdc8d8SChris Lattner return true;
15830fdc8d8SChris Lattner }
15930fdc8d8SChris Lattner return false;
16030fdc8d8SChris Lattner }
16130fdc8d8SChris Lattner
DumpUInt(ExecutionContextScope * exe_scope,const Address & address,uint32_t byte_size,Stream * strm)162b9c1b51eSKate Stone static bool DumpUInt(ExecutionContextScope *exe_scope, const Address &address,
163b9c1b51eSKate Stone uint32_t byte_size, Stream *strm) {
164896ddd03SEugene Zelenko if (exe_scope == nullptr || byte_size == 0)
16509ad8c8fSJonas Devlieghere return false;
16630fdc8d8SChris Lattner std::vector<uint8_t> buf(byte_size, 0);
16730fdc8d8SChris Lattner
168b9c1b51eSKate Stone if (ReadBytes(exe_scope, address, &buf[0], buf.size()) == buf.size()) {
16930fdc8d8SChris Lattner ByteOrder byte_order = eByteOrderInvalid;
17030fdc8d8SChris Lattner uint32_t addr_size = 0;
171b9c1b51eSKate Stone if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
172471b31ceSGreg Clayton DataExtractor data(&buf.front(), buf.size(), byte_order, addr_size);
17330fdc8d8SChris Lattner
17429cb868aSZachary Turner DumpDataExtractor(data, strm,
17530fdc8d8SChris Lattner 0, // Start offset in "data"
17630fdc8d8SChris Lattner eFormatHex, // Print as characters
17730fdc8d8SChris Lattner buf.size(), // Size of item
17830fdc8d8SChris Lattner 1, // Items count
17930fdc8d8SChris Lattner UINT32_MAX, // num per line
18030fdc8d8SChris Lattner LLDB_INVALID_ADDRESS, // base address
18130fdc8d8SChris Lattner 0, // bitfield bit size
18230fdc8d8SChris Lattner 0); // bitfield bit offset
18330fdc8d8SChris Lattner
18430fdc8d8SChris Lattner return true;
18530fdc8d8SChris Lattner }
18630fdc8d8SChris Lattner }
18730fdc8d8SChris Lattner return false;
18830fdc8d8SChris Lattner }
18930fdc8d8SChris Lattner
ReadCStringFromMemory(ExecutionContextScope * exe_scope,const Address & address,Stream * strm)190b9c1b51eSKate Stone static size_t ReadCStringFromMemory(ExecutionContextScope *exe_scope,
191b9c1b51eSKate Stone const Address &address, Stream *strm) {
192896ddd03SEugene Zelenko if (exe_scope == nullptr)
19330fdc8d8SChris Lattner return 0;
19430fdc8d8SChris Lattner const size_t k_buf_len = 256;
19530fdc8d8SChris Lattner char buf[k_buf_len + 1];
19630fdc8d8SChris Lattner buf[k_buf_len] = '\0'; // NULL terminate
19730fdc8d8SChris Lattner
198710dd5aeSGreg Clayton // Byte order and address size don't matter for C string dumping..
1999ccb970fSBruce Mitchener DataExtractor data(buf, sizeof(buf), endian::InlHostByteOrder(), 4);
20030fdc8d8SChris Lattner size_t total_len = 0;
20130fdc8d8SChris Lattner size_t bytes_read;
20230fdc8d8SChris Lattner Address curr_address(address);
20330fdc8d8SChris Lattner strm->PutChar('"');
204b9c1b51eSKate Stone while ((bytes_read = ReadBytes(exe_scope, curr_address, buf, k_buf_len)) >
205b9c1b51eSKate Stone 0) {
20630fdc8d8SChris Lattner size_t len = strlen(buf);
20730fdc8d8SChris Lattner if (len == 0)
20830fdc8d8SChris Lattner break;
20930fdc8d8SChris Lattner if (len > bytes_read)
21030fdc8d8SChris Lattner len = bytes_read;
21130fdc8d8SChris Lattner
21229cb868aSZachary Turner DumpDataExtractor(data, strm,
21330fdc8d8SChris Lattner 0, // Start offset in "data"
21430fdc8d8SChris Lattner eFormatChar, // Print as characters
21530fdc8d8SChris Lattner 1, // Size of item (1 byte for a char!)
21630fdc8d8SChris Lattner len, // How many bytes to print?
21730fdc8d8SChris Lattner UINT32_MAX, // num per line
21830fdc8d8SChris Lattner LLDB_INVALID_ADDRESS, // base address
21930fdc8d8SChris Lattner 0, // bitfield bit size
22030fdc8d8SChris Lattner
22130fdc8d8SChris Lattner 0); // bitfield bit offset
22230fdc8d8SChris Lattner
22330fdc8d8SChris Lattner total_len += bytes_read;
22430fdc8d8SChris Lattner
22530fdc8d8SChris Lattner if (len < k_buf_len)
22630fdc8d8SChris Lattner break;
22730fdc8d8SChris Lattner curr_address.SetOffset(curr_address.GetOffset() + bytes_read);
22830fdc8d8SChris Lattner }
22930fdc8d8SChris Lattner strm->PutChar('"');
23030fdc8d8SChris Lattner return total_len;
23130fdc8d8SChris Lattner }
23230fdc8d8SChris Lattner
Address(lldb::addr_t abs_addr)233b9c1b51eSKate Stone Address::Address(lldb::addr_t abs_addr) : m_section_wp(), m_offset(abs_addr) {}
234e72dfb32SGreg Clayton
Address(addr_t address,const SectionList * section_list)235b9c1b51eSKate Stone Address::Address(addr_t address, const SectionList *section_list)
236*28c878aeSShafik Yaghmour : m_section_wp() {
237e72dfb32SGreg Clayton ResolveAddressUsingFileSections(address, section_list);
23830fdc8d8SChris Lattner }
23930fdc8d8SChris Lattner
operator =(const Address & rhs)240b9c1b51eSKate Stone const Address &Address::operator=(const Address &rhs) {
241b9c1b51eSKate Stone if (this != &rhs) {
242e72dfb32SGreg Clayton m_section_wp = rhs.m_section_wp;
2439b1669aeSZachary Turner m_offset = rhs.m_offset;
24430fdc8d8SChris Lattner }
24530fdc8d8SChris Lattner return *this;
24630fdc8d8SChris Lattner }
24730fdc8d8SChris Lattner
ResolveAddressUsingFileSections(addr_t file_addr,const SectionList * section_list)248b9c1b51eSKate Stone bool Address::ResolveAddressUsingFileSections(addr_t file_addr,
249b9c1b51eSKate Stone const SectionList *section_list) {
250b9c1b51eSKate Stone if (section_list) {
251b9c1b51eSKate Stone SectionSP section_sp(
252b9c1b51eSKate Stone section_list->FindSectionContainingFileAddress(file_addr));
253e72dfb32SGreg Clayton m_section_wp = section_sp;
254b9c1b51eSKate Stone if (section_sp) {
255e72dfb32SGreg Clayton assert(section_sp->ContainsFileAddress(file_addr));
256e72dfb32SGreg Clayton m_offset = file_addr - section_sp->GetFileAddress();
257b9c1b51eSKate Stone return true; // Successfully transformed addr into a section offset
258b9c1b51eSKate Stone // address
25930fdc8d8SChris Lattner }
260e72dfb32SGreg Clayton }
261e72dfb32SGreg Clayton m_offset = file_addr;
26230fdc8d8SChris Lattner return false; // Failed to resolve this address to a section offset value
26330fdc8d8SChris Lattner }
26430fdc8d8SChris Lattner
26531e6dbe1SJoseph Tremoulet /// if "addr_range_ptr" is not NULL, then fill in with the address range of the function.
ResolveFunctionScope(SymbolContext & sym_ctx,AddressRange * addr_range_ptr)26631e6dbe1SJoseph Tremoulet bool Address::ResolveFunctionScope(SymbolContext &sym_ctx,
26731e6dbe1SJoseph Tremoulet AddressRange *addr_range_ptr) {
26831e6dbe1SJoseph Tremoulet constexpr SymbolContextItem resolve_scope =
26931e6dbe1SJoseph Tremoulet eSymbolContextFunction | eSymbolContextSymbol;
27031e6dbe1SJoseph Tremoulet
27131e6dbe1SJoseph Tremoulet if (!(CalculateSymbolContext(&sym_ctx, resolve_scope) & resolve_scope)) {
27231e6dbe1SJoseph Tremoulet if (addr_range_ptr)
27331e6dbe1SJoseph Tremoulet addr_range_ptr->Clear();
27431e6dbe1SJoseph Tremoulet return false;
27531e6dbe1SJoseph Tremoulet }
27631e6dbe1SJoseph Tremoulet
27731e6dbe1SJoseph Tremoulet if (!addr_range_ptr)
27831e6dbe1SJoseph Tremoulet return true;
27931e6dbe1SJoseph Tremoulet
28031e6dbe1SJoseph Tremoulet return sym_ctx.GetAddressRange(resolve_scope, 0, false, *addr_range_ptr);
28131e6dbe1SJoseph Tremoulet }
28231e6dbe1SJoseph Tremoulet
GetModule() const283b9c1b51eSKate Stone ModuleSP Address::GetModule() const {
284e1cd1be6SGreg Clayton lldb::ModuleSP module_sp;
285e72dfb32SGreg Clayton SectionSP section_sp(GetSection());
286e72dfb32SGreg Clayton if (section_sp)
287e72dfb32SGreg Clayton module_sp = section_sp->GetModule();
288e1cd1be6SGreg Clayton return module_sp;
289e1cd1be6SGreg Clayton }
290e1cd1be6SGreg Clayton
GetFileAddress() const291b9c1b51eSKate Stone addr_t Address::GetFileAddress() const {
292e72dfb32SGreg Clayton SectionSP section_sp(GetSection());
293b9c1b51eSKate Stone if (section_sp) {
294e72dfb32SGreg Clayton addr_t sect_file_addr = section_sp->GetFileAddress();
295b9c1b51eSKate Stone if (sect_file_addr == LLDB_INVALID_ADDRESS) {
29630fdc8d8SChris Lattner // Section isn't resolved, we can't return a valid file address
29730fdc8d8SChris Lattner return LLDB_INVALID_ADDRESS;
29830fdc8d8SChris Lattner }
29905097246SAdrian Prantl // We have a valid file range, so we can return the file based address by
30005097246SAdrian Prantl // adding the file base address to our offset
30130fdc8d8SChris Lattner return sect_file_addr + m_offset;
302ae3f793eSDavide Italiano } else if (SectionWasDeletedPrivate()) {
30305097246SAdrian Prantl // Used to have a valid section but it got deleted so the offset doesn't
30405097246SAdrian Prantl // mean anything without the section
305cae56528SGreg Clayton return LLDB_INVALID_ADDRESS;
306cae56528SGreg Clayton }
30730fdc8d8SChris Lattner // No section, we just return the offset since it is the value in this case
30830fdc8d8SChris Lattner return m_offset;
30930fdc8d8SChris Lattner }
31030fdc8d8SChris Lattner
GetLoadAddress(Target * target) const311b9c1b51eSKate Stone addr_t Address::GetLoadAddress(Target *target) const {
312e72dfb32SGreg Clayton SectionSP section_sp(GetSection());
313b9c1b51eSKate Stone if (section_sp) {
314b9c1b51eSKate Stone if (target) {
315e72dfb32SGreg Clayton addr_t sect_load_addr = section_sp->GetLoadBaseAddress(target);
31630fdc8d8SChris Lattner
317b9c1b51eSKate Stone if (sect_load_addr != LLDB_INVALID_ADDRESS) {
31805097246SAdrian Prantl // We have a valid file range, so we can return the file based address
31905097246SAdrian Prantl // by adding the file base address to our offset
32030fdc8d8SChris Lattner return sect_load_addr + m_offset;
32130fdc8d8SChris Lattner }
32230fdc8d8SChris Lattner }
323ae3f793eSDavide Italiano } else if (SectionWasDeletedPrivate()) {
32405097246SAdrian Prantl // Used to have a valid section but it got deleted so the offset doesn't
32505097246SAdrian Prantl // mean anything without the section
326cae56528SGreg Clayton return LLDB_INVALID_ADDRESS;
327b9c1b51eSKate Stone } else {
328cae56528SGreg Clayton // We don't have a section so the offset is the load address
329cae56528SGreg Clayton return m_offset;
330cae56528SGreg Clayton }
33105097246SAdrian Prantl // The section isn't resolved or an invalid target was passed in so we can't
33205097246SAdrian Prantl // return a valid load address.
33330fdc8d8SChris Lattner return LLDB_INVALID_ADDRESS;
33430fdc8d8SChris Lattner }
33530fdc8d8SChris Lattner
GetCallableLoadAddress(Target * target,bool is_indirect) const336b9c1b51eSKate Stone addr_t Address::GetCallableLoadAddress(Target *target, bool is_indirect) const {
3371460e4bfSJim Ingham addr_t code_addr = LLDB_INVALID_ADDRESS;
3381460e4bfSJim Ingham
339b9c1b51eSKate Stone if (is_indirect && target) {
34000049b8bSMatt Kopec ProcessSP processSP = target->GetProcessSP();
34197206d57SZachary Turner Status error;
342b9c1b51eSKate Stone if (processSP) {
3431460e4bfSJim Ingham code_addr = processSP->ResolveIndirectFunction(this, error);
3441460e4bfSJim Ingham if (!error.Success())
3451460e4bfSJim Ingham code_addr = LLDB_INVALID_ADDRESS;
3461460e4bfSJim Ingham }
347b9c1b51eSKate Stone } else {
3481460e4bfSJim Ingham code_addr = GetLoadAddress(target);
34900049b8bSMatt Kopec }
35000049b8bSMatt Kopec
3511460e4bfSJim Ingham if (code_addr == LLDB_INVALID_ADDRESS)
3521460e4bfSJim Ingham return code_addr;
3533f5c08f5SGreg Clayton
354f3ef3d2aSGreg Clayton if (target)
355f3ef3d2aSGreg Clayton return target->GetCallableLoadAddress(code_addr, GetAddressClass());
3563f5c08f5SGreg Clayton return code_addr;
3573f5c08f5SGreg Clayton }
3583f5c08f5SGreg Clayton
SetCallableLoadAddress(lldb::addr_t load_addr,Target * target)359b9c1b51eSKate Stone bool Address::SetCallableLoadAddress(lldb::addr_t load_addr, Target *target) {
360b9c1b51eSKate Stone if (SetLoadAddress(load_addr, target)) {
361f3ef3d2aSGreg Clayton if (target)
362f3ef3d2aSGreg Clayton m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass());
363cff851abSGreg Clayton return true;
364cff851abSGreg Clayton }
365cff851abSGreg Clayton return false;
366cff851abSGreg Clayton }
367cff851abSGreg Clayton
GetOpcodeLoadAddress(Target * target,AddressClass addr_class) const368b9c1b51eSKate Stone addr_t Address::GetOpcodeLoadAddress(Target *target,
369b9c1b51eSKate Stone AddressClass addr_class) const {
37092bb12caSGreg Clayton addr_t code_addr = GetLoadAddress(target);
371b9c1b51eSKate Stone if (code_addr != LLDB_INVALID_ADDRESS) {
37204803b3eSTatyana Krasnukha if (addr_class == AddressClass::eInvalid)
37325b9f7ebSTamas Berghammer addr_class = GetAddressClass();
37425b9f7ebSTamas Berghammer code_addr = target->GetOpcodeLoadAddress(code_addr, addr_class);
37525b9f7ebSTamas Berghammer }
37692bb12caSGreg Clayton return code_addr;
37792bb12caSGreg Clayton }
37892bb12caSGreg Clayton
SetOpcodeLoadAddress(lldb::addr_t load_addr,Target * target,AddressClass addr_class,bool allow_section_end)379b9c1b51eSKate Stone bool Address::SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target,
380c3c72122SPavel Labath AddressClass addr_class,
381c3c72122SPavel Labath bool allow_section_end) {
382c3c72122SPavel Labath if (SetLoadAddress(load_addr, target, allow_section_end)) {
383b9c1b51eSKate Stone if (target) {
38404803b3eSTatyana Krasnukha if (addr_class == AddressClass::eInvalid)
38525b9f7ebSTamas Berghammer addr_class = GetAddressClass();
38625b9f7ebSTamas Berghammer m_offset = target->GetOpcodeLoadAddress(m_offset, addr_class);
38725b9f7ebSTamas Berghammer }
388cff851abSGreg Clayton return true;
389cff851abSGreg Clayton }
390cff851abSGreg Clayton return false;
391cff851abSGreg Clayton }
392cff851abSGreg Clayton
GetDescription(Stream & s,Target & target,DescriptionLevel level) const39366902a32SVedant Kumar bool Address::GetDescription(Stream &s, Target &target,
39466902a32SVedant Kumar DescriptionLevel level) const {
39566902a32SVedant Kumar assert(level == eDescriptionLevelBrief &&
39666902a32SVedant Kumar "Non-brief descriptions not implemented");
39766902a32SVedant Kumar LineEntry line_entry;
39866902a32SVedant Kumar if (CalculateSymbolContextLineEntry(line_entry)) {
39966902a32SVedant Kumar s.Printf(" (%s:%u:%u)", line_entry.file.GetFilename().GetCString(),
40066902a32SVedant Kumar line_entry.line, line_entry.column);
40166902a32SVedant Kumar return true;
40266902a32SVedant Kumar }
40366902a32SVedant Kumar return false;
40466902a32SVedant Kumar }
40566902a32SVedant Kumar
Dump(Stream * s,ExecutionContextScope * exe_scope,DumpStyle style,DumpStyle fallback_style,uint32_t addr_size,bool all_ranges) const406b9c1b51eSKate Stone bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
40715983c28SZequan Wu DumpStyle fallback_style, uint32_t addr_size,
40815983c28SZequan Wu bool all_ranges) const {
409b9c1b51eSKate Stone // If the section was nullptr, only load address is going to work unless we
41005097246SAdrian Prantl // are trying to deref a pointer
411e72dfb32SGreg Clayton SectionSP section_sp(GetSection());
412c3a86bf9SGreg Clayton if (!section_sp && style != DumpStyleResolvedPointerDescription)
41330fdc8d8SChris Lattner style = DumpStyleLoadAddress;
41430fdc8d8SChris Lattner
415d9e416c0SGreg Clayton ExecutionContext exe_ctx(exe_scope);
416d9e416c0SGreg Clayton Target *target = exe_ctx.GetTargetPtr();
41705097246SAdrian Prantl // If addr_byte_size is UINT32_MAX, then determine the correct address byte
41805097246SAdrian Prantl // size for the process or default to the size of addr_t
419b9c1b51eSKate Stone if (addr_size == UINT32_MAX) {
420d9e416c0SGreg Clayton if (target)
421514487e8SGreg Clayton addr_size = target->GetArchitecture().GetAddressByteSize();
422dda4f7b5SGreg Clayton else
423dda4f7b5SGreg Clayton addr_size = sizeof(addr_t);
424dda4f7b5SGreg Clayton }
42530fdc8d8SChris Lattner
426c9800667SGreg Clayton Address so_addr;
427b9c1b51eSKate Stone switch (style) {
428c982c768SGreg Clayton case DumpStyleInvalid:
429c982c768SGreg Clayton return false;
430c982c768SGreg Clayton
43130fdc8d8SChris Lattner case DumpStyleSectionNameOffset:
432b9c1b51eSKate Stone if (section_sp) {
4333a168297SPavel Labath section_sp->DumpName(s->AsRawOstream());
4349b1669aeSZachary Turner s->Printf(" + %" PRIu64, m_offset);
435b9c1b51eSKate Stone } else {
4361462f5a4SRaphael Isemann DumpAddress(s->AsRawOstream(), m_offset, addr_size);
43730fdc8d8SChris Lattner }
43830fdc8d8SChris Lattner break;
43930fdc8d8SChris Lattner
44030fdc8d8SChris Lattner case DumpStyleSectionPointerOffset:
441324a1036SSaleem Abdulrasool s->Printf("(Section *)%p + ", static_cast<void *>(section_sp.get()));
4421462f5a4SRaphael Isemann DumpAddress(s->AsRawOstream(), m_offset, addr_size);
44330fdc8d8SChris Lattner break;
44430fdc8d8SChris Lattner
44530fdc8d8SChris Lattner case DumpStyleModuleWithFileAddress:
446b9c1b51eSKate Stone if (section_sp) {
447cbff63adSJim Ingham ModuleSP module_sp = section_sp->GetModule();
448cbff63adSJim Ingham if (module_sp)
449b9c1b51eSKate Stone s->Printf("%s[", module_sp->GetFileSpec().GetFilename().AsCString(
450b9c1b51eSKate Stone "<Unknown>"));
451cbff63adSJim Ingham else
452cbff63adSJim Ingham s->Printf("%s[", "<Unknown>");
4534af5961cSJim Ingham }
45462e0681aSJason Molenda LLVM_FALLTHROUGH;
455b9c1b51eSKate Stone case DumpStyleFileAddress: {
45630fdc8d8SChris Lattner addr_t file_addr = GetFileAddress();
457b9c1b51eSKate Stone if (file_addr == LLDB_INVALID_ADDRESS) {
45830fdc8d8SChris Lattner if (fallback_style != DumpStyleInvalid)
459dda4f7b5SGreg Clayton return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
46030fdc8d8SChris Lattner return false;
46130fdc8d8SChris Lattner }
4621462f5a4SRaphael Isemann DumpAddress(s->AsRawOstream(), file_addr, addr_size);
463e72dfb32SGreg Clayton if (style == DumpStyleModuleWithFileAddress && section_sp)
46430fdc8d8SChris Lattner s->PutChar(']');
465b9c1b51eSKate Stone } break;
46630fdc8d8SChris Lattner
467b9c1b51eSKate Stone case DumpStyleLoadAddress: {
468f5e56de0SGreg Clayton addr_t load_addr = GetLoadAddress(target);
46944d07fccSJaydeep Patil
47044d07fccSJaydeep Patil /*
47144d07fccSJaydeep Patil * MIPS:
47244d07fccSJaydeep Patil * Display address in compressed form for MIPS16 or microMIPS
47304803b3eSTatyana Krasnukha * if the address belongs to AddressClass::eCodeAlternateISA.
47444d07fccSJaydeep Patil */
475b9c1b51eSKate Stone if (target) {
476b9c1b51eSKate Stone const llvm::Triple::ArchType llvm_arch =
477b9c1b51eSKate Stone target->GetArchitecture().GetMachine();
478b9c1b51eSKate Stone if (llvm_arch == llvm::Triple::mips ||
479b9c1b51eSKate Stone llvm_arch == llvm::Triple::mipsel ||
480b9c1b51eSKate Stone llvm_arch == llvm::Triple::mips64 ||
481b9c1b51eSKate Stone llvm_arch == llvm::Triple::mips64el)
48244d07fccSJaydeep Patil load_addr = GetCallableLoadAddress(target);
48344d07fccSJaydeep Patil }
48444d07fccSJaydeep Patil
485b9c1b51eSKate Stone if (load_addr == LLDB_INVALID_ADDRESS) {
48630fdc8d8SChris Lattner if (fallback_style != DumpStyleInvalid)
487dda4f7b5SGreg Clayton return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
48830fdc8d8SChris Lattner return false;
48930fdc8d8SChris Lattner }
4901462f5a4SRaphael Isemann DumpAddress(s->AsRawOstream(), load_addr, addr_size);
491b9c1b51eSKate Stone } break;
49230fdc8d8SChris Lattner
49330fdc8d8SChris Lattner case DumpStyleResolvedDescription:
49454b8b8c1SGreg Clayton case DumpStyleResolvedDescriptionNoModule:
495aff1b357SJason Molenda case DumpStyleResolvedDescriptionNoFunctionArguments:
496c980fa92SJason Molenda case DumpStyleNoFunctionName:
497b9c1b51eSKate Stone if (IsSectionOffset()) {
49830fdc8d8SChris Lattner uint32_t pointer_size = 4;
499e72dfb32SGreg Clayton ModuleSP module_sp(GetModule());
500514487e8SGreg Clayton if (target)
501514487e8SGreg Clayton pointer_size = target->GetArchitecture().GetAddressByteSize();
502e72dfb32SGreg Clayton else if (module_sp)
503e72dfb32SGreg Clayton pointer_size = module_sp->GetArchitecture().GetAddressByteSize();
50430fdc8d8SChris Lattner
50530fdc8d8SChris Lattner bool showed_info = false;
506b9c1b51eSKate Stone if (section_sp) {
507e72dfb32SGreg Clayton SectionType sect_type = section_sp->GetType();
508b9c1b51eSKate Stone switch (sect_type) {
5098941142aSGreg Clayton case eSectionTypeData:
510b9c1b51eSKate Stone if (module_sp) {
511d5d47a35SPavel Labath if (Symtab *symtab = module_sp->GetSymtab()) {
5128941142aSGreg Clayton const addr_t file_Addr = GetFileAddress();
513b9c1b51eSKate Stone Symbol *symbol =
514b9c1b51eSKate Stone symtab->FindSymbolContainingFileAddress(file_Addr);
515b9c1b51eSKate Stone if (symbol) {
5168941142aSGreg Clayton const char *symbol_name = symbol->GetName().AsCString();
517b9c1b51eSKate Stone if (symbol_name) {
5188941142aSGreg Clayton s->PutCString(symbol_name);
519b9c1b51eSKate Stone addr_t delta =
520b9c1b51eSKate Stone file_Addr - symbol->GetAddressRef().GetFileAddress();
5218941142aSGreg Clayton if (delta)
522d01b2953SDaniel Malea s->Printf(" + %" PRIu64, delta);
5238941142aSGreg Clayton showed_info = true;
5248941142aSGreg Clayton }
5258941142aSGreg Clayton }
5268941142aSGreg Clayton }
5278941142aSGreg Clayton }
5288941142aSGreg Clayton break;
5298941142aSGreg Clayton
53030fdc8d8SChris Lattner case eSectionTypeDataCString:
53130fdc8d8SChris Lattner // Read the C string from memory and display it
53230fdc8d8SChris Lattner showed_info = true;
53330fdc8d8SChris Lattner ReadCStringFromMemory(exe_scope, *this, s);
53430fdc8d8SChris Lattner break;
53530fdc8d8SChris Lattner
53630fdc8d8SChris Lattner case eSectionTypeDataCStringPointers:
537b9c1b51eSKate Stone if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
53830fdc8d8SChris Lattner #if VERBOSE_OUTPUT
53930fdc8d8SChris Lattner s->PutCString("(char *)");
540b9c1b51eSKate Stone so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
541b9c1b51eSKate Stone DumpStyleFileAddress);
54230fdc8d8SChris Lattner s->PutCString(": ");
54330fdc8d8SChris Lattner #endif
54430fdc8d8SChris Lattner showed_info = true;
54530fdc8d8SChris Lattner ReadCStringFromMemory(exe_scope, so_addr, s);
54630fdc8d8SChris Lattner }
54730fdc8d8SChris Lattner break;
54830fdc8d8SChris Lattner
54930fdc8d8SChris Lattner case eSectionTypeDataObjCMessageRefs:
550b9c1b51eSKate Stone if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
551b9c1b51eSKate Stone if (target && so_addr.IsSectionOffset()) {
552c9800667SGreg Clayton SymbolContext func_sc;
553b9c1b51eSKate Stone target->GetImages().ResolveSymbolContextForAddress(
554b9c1b51eSKate Stone so_addr, eSymbolContextEverything, func_sc);
555b9c1b51eSKate Stone if (func_sc.function != nullptr || func_sc.symbol != nullptr) {
55630fdc8d8SChris Lattner showed_info = true;
55730fdc8d8SChris Lattner #if VERBOSE_OUTPUT
55830fdc8d8SChris Lattner s->PutCString("(objc_msgref *) -> { (func*)");
559b9c1b51eSKate Stone so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
560b9c1b51eSKate Stone DumpStyleFileAddress);
56130fdc8d8SChris Lattner #else
56230fdc8d8SChris Lattner s->PutCString("{ ");
56330fdc8d8SChris Lattner #endif
56430fdc8d8SChris Lattner Address cstr_addr(*this);
56530fdc8d8SChris Lattner cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
566b9c1b51eSKate Stone func_sc.DumpStopContext(s, exe_scope, so_addr, true, true,
567b9c1b51eSKate Stone false, true, true);
568b9c1b51eSKate Stone if (ReadAddress(exe_scope, cstr_addr, pointer_size, so_addr)) {
56930fdc8d8SChris Lattner #if VERBOSE_OUTPUT
57030fdc8d8SChris Lattner s->PutCString("), (char *)");
571b9c1b51eSKate Stone so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
572b9c1b51eSKate Stone DumpStyleFileAddress);
57330fdc8d8SChris Lattner s->PutCString(" (");
57430fdc8d8SChris Lattner #else
57530fdc8d8SChris Lattner s->PutCString(", ");
57630fdc8d8SChris Lattner #endif
57730fdc8d8SChris Lattner ReadCStringFromMemory(exe_scope, so_addr, s);
57830fdc8d8SChris Lattner }
57930fdc8d8SChris Lattner #if VERBOSE_OUTPUT
58030fdc8d8SChris Lattner s->PutCString(") }");
58130fdc8d8SChris Lattner #else
58230fdc8d8SChris Lattner s->PutCString(" }");
58330fdc8d8SChris Lattner #endif
58430fdc8d8SChris Lattner }
58530fdc8d8SChris Lattner }
58630fdc8d8SChris Lattner }
58730fdc8d8SChris Lattner break;
58830fdc8d8SChris Lattner
589b9c1b51eSKate Stone case eSectionTypeDataObjCCFStrings: {
59030fdc8d8SChris Lattner Address cfstring_data_addr(*this);
591b9c1b51eSKate Stone cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() +
592b9c1b51eSKate Stone (2 * pointer_size));
593b9c1b51eSKate Stone if (ReadAddress(exe_scope, cfstring_data_addr, pointer_size,
594b9c1b51eSKate Stone so_addr)) {
59530fdc8d8SChris Lattner #if VERBOSE_OUTPUT
59630fdc8d8SChris Lattner s->PutCString("(CFString *) ");
597b9c1b51eSKate Stone cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
598b9c1b51eSKate Stone DumpStyleFileAddress);
59930fdc8d8SChris Lattner s->PutCString(" -> @");
60030fdc8d8SChris Lattner #else
60130fdc8d8SChris Lattner s->PutChar('@');
60230fdc8d8SChris Lattner #endif
60330fdc8d8SChris Lattner if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
60430fdc8d8SChris Lattner showed_info = true;
60530fdc8d8SChris Lattner }
606b9c1b51eSKate Stone } break;
60730fdc8d8SChris Lattner
60830fdc8d8SChris Lattner case eSectionTypeData4:
60930fdc8d8SChris Lattner // Read the 4 byte data and display it
61030fdc8d8SChris Lattner showed_info = true;
61130fdc8d8SChris Lattner s->PutCString("(uint32_t) ");
61230fdc8d8SChris Lattner DumpUInt(exe_scope, *this, 4, s);
61330fdc8d8SChris Lattner break;
61430fdc8d8SChris Lattner
61530fdc8d8SChris Lattner case eSectionTypeData8:
61630fdc8d8SChris Lattner // Read the 8 byte data and display it
61730fdc8d8SChris Lattner showed_info = true;
61830fdc8d8SChris Lattner s->PutCString("(uint64_t) ");
61930fdc8d8SChris Lattner DumpUInt(exe_scope, *this, 8, s);
62030fdc8d8SChris Lattner break;
62130fdc8d8SChris Lattner
62230fdc8d8SChris Lattner case eSectionTypeData16:
62330fdc8d8SChris Lattner // Read the 16 byte data and display it
62430fdc8d8SChris Lattner showed_info = true;
62530fdc8d8SChris Lattner s->PutCString("(uint128_t) ");
62630fdc8d8SChris Lattner DumpUInt(exe_scope, *this, 16, s);
62730fdc8d8SChris Lattner break;
62830fdc8d8SChris Lattner
62930fdc8d8SChris Lattner case eSectionTypeDataPointers:
63030fdc8d8SChris Lattner // Read the pointer data and display it
631b9c1b51eSKate Stone if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
63230fdc8d8SChris Lattner s->PutCString("(void *)");
633b9c1b51eSKate Stone so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
634b9c1b51eSKate Stone DumpStyleFileAddress);
63530fdc8d8SChris Lattner
63630fdc8d8SChris Lattner showed_info = true;
637b9c1b51eSKate Stone if (so_addr.IsSectionOffset()) {
638c9800667SGreg Clayton SymbolContext pointer_sc;
639b9c1b51eSKate Stone if (target) {
640b9c1b51eSKate Stone target->GetImages().ResolveSymbolContextForAddress(
641b9c1b51eSKate Stone so_addr, eSymbolContextEverything, pointer_sc);
642b9c1b51eSKate Stone if (pointer_sc.function != nullptr ||
643b9c1b51eSKate Stone pointer_sc.symbol != nullptr) {
64430fdc8d8SChris Lattner s->PutCString(": ");
645b9c1b51eSKate Stone pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false,
646b9c1b51eSKate Stone false, true, true);
64730fdc8d8SChris Lattner }
64830fdc8d8SChris Lattner }
64930fdc8d8SChris Lattner }
65030fdc8d8SChris Lattner }
65130fdc8d8SChris Lattner break;
652c982c768SGreg Clayton
653c982c768SGreg Clayton default:
654c982c768SGreg Clayton break;
65530fdc8d8SChris Lattner }
65630fdc8d8SChris Lattner }
65730fdc8d8SChris Lattner
658b9c1b51eSKate Stone if (!showed_info) {
659b9c1b51eSKate Stone if (module_sp) {
660c9800667SGreg Clayton SymbolContext sc;
661b9c1b51eSKate Stone module_sp->ResolveSymbolContextForAddress(
662b9c1b51eSKate Stone *this, eSymbolContextEverything, sc);
663b9c1b51eSKate Stone if (sc.function || sc.symbol) {
66430fdc8d8SChris Lattner bool show_stop_context = true;
6658dc0a987SGreg Clayton const bool show_module = (style == DumpStyleResolvedDescription);
6668dc0a987SGreg Clayton const bool show_fullpaths = false;
667513c26ceSGreg Clayton const bool show_inlined_frames = true;
668b9c1b51eSKate Stone const bool show_function_arguments =
669b9c1b51eSKate Stone (style != DumpStyleResolvedDescriptionNoFunctionArguments);
670c980fa92SJason Molenda const bool show_function_name = (style != DumpStyleNoFunctionName);
671b9c1b51eSKate Stone if (sc.function == nullptr && sc.symbol != nullptr) {
67230fdc8d8SChris Lattner // If we have just a symbol make sure it is in the right section
673b9c1b51eSKate Stone if (sc.symbol->ValueIsAddress()) {
674b9c1b51eSKate Stone if (sc.symbol->GetAddressRef().GetSection() != GetSection()) {
67554b8b8c1SGreg Clayton // don't show the module if the symbol is a trampoline symbol
67630fdc8d8SChris Lattner show_stop_context = false;
67730fdc8d8SChris Lattner }
67830fdc8d8SChris Lattner }
67954b8b8c1SGreg Clayton }
680b9c1b51eSKate Stone if (show_stop_context) {
68105097246SAdrian Prantl // We have a function or a symbol from the same sections as this
68205097246SAdrian Prantl // address.
683b9c1b51eSKate Stone sc.DumpStopContext(s, exe_scope, *this, show_fullpaths,
684b9c1b51eSKate Stone show_module, show_inlined_frames,
685b9c1b51eSKate Stone show_function_arguments, show_function_name);
686b9c1b51eSKate Stone } else {
68705097246SAdrian Prantl // We found a symbol but it was in a different section so it
68805097246SAdrian Prantl // isn't the symbol we should be showing, just show the section
68905097246SAdrian Prantl // name + offset
69030fdc8d8SChris Lattner Dump(s, exe_scope, DumpStyleSectionNameOffset);
69130fdc8d8SChris Lattner }
69230fdc8d8SChris Lattner }
69330fdc8d8SChris Lattner }
69430fdc8d8SChris Lattner }
695b9c1b51eSKate Stone } else {
69630fdc8d8SChris Lattner if (fallback_style != DumpStyleInvalid)
697dda4f7b5SGreg Clayton return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
69830fdc8d8SChris Lattner return false;
69930fdc8d8SChris Lattner }
70030fdc8d8SChris Lattner break;
701dda4f7b5SGreg Clayton
702dda4f7b5SGreg Clayton case DumpStyleDetailedSymbolContext:
703b9c1b51eSKate Stone if (IsSectionOffset()) {
704e72dfb32SGreg Clayton ModuleSP module_sp(GetModule());
705b9c1b51eSKate Stone if (module_sp) {
706c9800667SGreg Clayton SymbolContext sc;
707b9c1b51eSKate Stone module_sp->ResolveSymbolContextForAddress(
708b9c1b51eSKate Stone *this, eSymbolContextEverything | eSymbolContextVariable, sc);
709b9c1b51eSKate Stone if (sc.symbol) {
71005097246SAdrian Prantl // If we have just a symbol make sure it is in the same section as
71105097246SAdrian Prantl // our address. If it isn't, then we might have just found the last
71205097246SAdrian Prantl // symbol that came before the address that we are looking up that
71305097246SAdrian Prantl // has nothing to do with our address lookup.
714b9c1b51eSKate Stone if (sc.symbol->ValueIsAddress() &&
715b9c1b51eSKate Stone sc.symbol->GetAddressRef().GetSection() != GetSection())
716896ddd03SEugene Zelenko sc.symbol = nullptr;
717b0b9fe61SGreg Clayton }
718f5e56de0SGreg Clayton sc.GetDescription(s, eDescriptionLevelBrief, target);
719c749eb89SGreg Clayton
720b9c1b51eSKate Stone if (sc.block) {
721c749eb89SGreg Clayton bool can_create = true;
722c749eb89SGreg Clayton bool get_parent_variables = true;
723c749eb89SGreg Clayton bool stop_if_block_is_inlined_function = false;
724c749eb89SGreg Clayton VariableList variable_list;
72515983c28SZequan Wu addr_t file_addr = GetFileAddress();
72615983c28SZequan Wu sc.block->AppendVariables(
72715983c28SZequan Wu can_create, get_parent_variables,
728c749eb89SGreg Clayton stop_if_block_is_inlined_function,
72915983c28SZequan Wu [&](Variable *var) {
73015983c28SZequan Wu return var && var->LocationIsValidForAddress(*this);
73115983c28SZequan Wu },
732c749eb89SGreg Clayton &variable_list);
73315983c28SZequan Wu ABISP abi =
73415983c28SZequan Wu ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture());
735d1782133SRaphael Isemann for (const VariableSP &var_sp : variable_list) {
736c4a8a760SGreg Clayton s->Indent();
7376e46512eSIlia K s->Printf(" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"",
738d1782133SRaphael Isemann var_sp->GetID(), var_sp->GetName().GetCString());
739d1782133SRaphael Isemann Type *type = var_sp->GetType();
7406e46512eSIlia K if (type)
7416e46512eSIlia K s->Printf(", type = \"%s\"", type->GetName().GetCString());
7426e46512eSIlia K else
7436e46512eSIlia K s->PutCString(", type = <unknown>");
74415983c28SZequan Wu s->PutCString(", valid ranges = ");
74515983c28SZequan Wu if (var_sp->GetScopeRange().IsEmpty())
74615983c28SZequan Wu s->PutCString("<block>");
74715983c28SZequan Wu else if (all_ranges) {
74815983c28SZequan Wu for (auto range : var_sp->GetScopeRange())
74915983c28SZequan Wu DumpAddressRange(s->AsRawOstream(), range.GetRangeBase(),
75015983c28SZequan Wu range.GetRangeEnd(), addr_size);
75115983c28SZequan Wu } else if (auto *range =
75215983c28SZequan Wu var_sp->GetScopeRange().FindEntryThatContains(
75315983c28SZequan Wu file_addr))
75415983c28SZequan Wu DumpAddressRange(s->AsRawOstream(), range->GetRangeBase(),
75515983c28SZequan Wu range->GetRangeEnd(), addr_size);
7566e46512eSIlia K s->PutCString(", location = ");
75715983c28SZequan Wu var_sp->DumpLocations(s, all_ranges ? LLDB_INVALID_ADDRESS : *this);
758c749eb89SGreg Clayton s->PutCString(", decl = ");
759d1782133SRaphael Isemann var_sp->GetDeclaration().DumpStopContext(s, false);
760c749eb89SGreg Clayton s->EOL();
761dda4f7b5SGreg Clayton }
762dda4f7b5SGreg Clayton }
763c749eb89SGreg Clayton }
764b9c1b51eSKate Stone } else {
765dda4f7b5SGreg Clayton if (fallback_style != DumpStyleInvalid)
766dda4f7b5SGreg Clayton return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
767dda4f7b5SGreg Clayton return false;
768c749eb89SGreg Clayton }
769dda4f7b5SGreg Clayton break;
770896ddd03SEugene Zelenko
771b9c1b51eSKate Stone case DumpStyleResolvedPointerDescription: {
772c3a86bf9SGreg Clayton Process *process = exe_ctx.GetProcessPtr();
773b9c1b51eSKate Stone if (process) {
774c3a86bf9SGreg Clayton addr_t load_addr = GetLoadAddress(target);
775b9c1b51eSKate Stone if (load_addr != LLDB_INVALID_ADDRESS) {
77697206d57SZachary Turner Status memory_error;
777b9c1b51eSKate Stone addr_t dereferenced_load_addr =
778b9c1b51eSKate Stone process->ReadPointerFromMemory(load_addr, memory_error);
779b9c1b51eSKate Stone if (dereferenced_load_addr != LLDB_INVALID_ADDRESS) {
780c3a86bf9SGreg Clayton Address dereferenced_addr;
781b9c1b51eSKate Stone if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr,
782b9c1b51eSKate Stone target)) {
783c3a86bf9SGreg Clayton StreamString strm;
784b9c1b51eSKate Stone if (dereferenced_addr.Dump(&strm, exe_scope,
785b9c1b51eSKate Stone DumpStyleResolvedDescription,
786b9c1b51eSKate Stone DumpStyleInvalid, addr_size)) {
7871462f5a4SRaphael Isemann DumpAddress(s->AsRawOstream(), dereferenced_load_addr, addr_size,
7881462f5a4SRaphael Isemann " -> ", " ");
789c156427dSZachary Turner s->Write(strm.GetString().data(), strm.GetSize());
790c3a86bf9SGreg Clayton return true;
791c3a86bf9SGreg Clayton }
792c3a86bf9SGreg Clayton }
793c3a86bf9SGreg Clayton }
794c3a86bf9SGreg Clayton }
795c3a86bf9SGreg Clayton }
796c3a86bf9SGreg Clayton if (fallback_style != DumpStyleInvalid)
797c3a86bf9SGreg Clayton return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
798c3a86bf9SGreg Clayton return false;
799b9c1b51eSKate Stone } break;
80030fdc8d8SChris Lattner }
80130fdc8d8SChris Lattner
80230fdc8d8SChris Lattner return true;
80330fdc8d8SChris Lattner }
80430fdc8d8SChris Lattner
SectionWasDeleted() const805b9c1b51eSKate Stone bool Address::SectionWasDeleted() const {
806ae3f793eSDavide Italiano if (GetSection())
807ae3f793eSDavide Italiano return false;
808ae3f793eSDavide Italiano return SectionWasDeletedPrivate();
809ae3f793eSDavide Italiano }
810ae3f793eSDavide Italiano
SectionWasDeletedPrivate() const811ae3f793eSDavide Italiano bool Address::SectionWasDeletedPrivate() const {
812cae56528SGreg Clayton lldb::SectionWP empty_section_wp;
813cae56528SGreg Clayton
814b9c1b51eSKate Stone // If either call to "std::weak_ptr::owner_before(...) value returns true,
81505097246SAdrian Prantl // this indicates that m_section_wp once contained (possibly still does) a
81605097246SAdrian Prantl // reference to a valid shared pointer. This helps us know if we had a valid
81705097246SAdrian Prantl // reference to a section which is now invalid because the module it was in
81805097246SAdrian Prantl // was unloaded/deleted, or if the address doesn't have a valid reference to
81905097246SAdrian Prantl // a section.
820b9c1b51eSKate Stone return empty_section_wp.owner_before(m_section_wp) ||
821b9c1b51eSKate Stone m_section_wp.owner_before(empty_section_wp);
822cae56528SGreg Clayton }
823cae56528SGreg Clayton
824991e4453SZachary Turner uint32_t
CalculateSymbolContext(SymbolContext * sc,SymbolContextItem resolve_scope) const825991e4453SZachary Turner Address::CalculateSymbolContext(SymbolContext *sc,
826991e4453SZachary Turner SymbolContextItem resolve_scope) const {
82772310355SGreg Clayton sc->Clear(false);
828b9c1b51eSKate Stone // Absolute addresses don't have enough information to reconstruct even their
829b9c1b51eSKate Stone // target.
830e72dfb32SGreg Clayton
831e72dfb32SGreg Clayton SectionSP section_sp(GetSection());
832b9c1b51eSKate Stone if (section_sp) {
833e72dfb32SGreg Clayton ModuleSP module_sp(section_sp->GetModule());
834b9c1b51eSKate Stone if (module_sp) {
835e72dfb32SGreg Clayton sc->module_sp = module_sp;
83630fdc8d8SChris Lattner if (sc->module_sp)
837b9c1b51eSKate Stone return sc->module_sp->ResolveSymbolContextForAddress(
838b9c1b51eSKate Stone *this, resolve_scope, *sc);
83930fdc8d8SChris Lattner }
84030fdc8d8SChris Lattner }
8417e9b1fd0SGreg Clayton return 0;
8427e9b1fd0SGreg Clayton }
8437e9b1fd0SGreg Clayton
CalculateSymbolContextModule() const844b9c1b51eSKate Stone ModuleSP Address::CalculateSymbolContextModule() const {
845e72dfb32SGreg Clayton SectionSP section_sp(GetSection());
846e72dfb32SGreg Clayton if (section_sp)
847e72dfb32SGreg Clayton return section_sp->GetModule();
848e72dfb32SGreg Clayton return ModuleSP();
8497e9b1fd0SGreg Clayton }
8507e9b1fd0SGreg Clayton
CalculateSymbolContextCompileUnit() const851b9c1b51eSKate Stone CompileUnit *Address::CalculateSymbolContextCompileUnit() const {
852e72dfb32SGreg Clayton SectionSP section_sp(GetSection());
853b9c1b51eSKate Stone if (section_sp) {
8547e9b1fd0SGreg Clayton SymbolContext sc;
855e72dfb32SGreg Clayton sc.module_sp = section_sp->GetModule();
856b9c1b51eSKate Stone if (sc.module_sp) {
857b9c1b51eSKate Stone sc.module_sp->ResolveSymbolContextForAddress(*this,
858b9c1b51eSKate Stone eSymbolContextCompUnit, sc);
8597e9b1fd0SGreg Clayton return sc.comp_unit;
8607e9b1fd0SGreg Clayton }
8617e9b1fd0SGreg Clayton }
862896ddd03SEugene Zelenko return nullptr;
8637e9b1fd0SGreg Clayton }
8647e9b1fd0SGreg Clayton
CalculateSymbolContextFunction() const865b9c1b51eSKate Stone Function *Address::CalculateSymbolContextFunction() const {
866e72dfb32SGreg Clayton SectionSP section_sp(GetSection());
867b9c1b51eSKate Stone if (section_sp) {
8687e9b1fd0SGreg Clayton SymbolContext sc;
869e72dfb32SGreg Clayton sc.module_sp = section_sp->GetModule();
870b9c1b51eSKate Stone if (sc.module_sp) {
871b9c1b51eSKate Stone sc.module_sp->ResolveSymbolContextForAddress(*this,
872b9c1b51eSKate Stone eSymbolContextFunction, sc);
8737e9b1fd0SGreg Clayton return sc.function;
8747e9b1fd0SGreg Clayton }
8757e9b1fd0SGreg Clayton }
876896ddd03SEugene Zelenko return nullptr;
8777e9b1fd0SGreg Clayton }
8787e9b1fd0SGreg Clayton
CalculateSymbolContextBlock() const879b9c1b51eSKate Stone Block *Address::CalculateSymbolContextBlock() const {
880e72dfb32SGreg Clayton SectionSP section_sp(GetSection());
881b9c1b51eSKate Stone if (section_sp) {
8827e9b1fd0SGreg Clayton SymbolContext sc;
883e72dfb32SGreg Clayton sc.module_sp = section_sp->GetModule();
884b9c1b51eSKate Stone if (sc.module_sp) {
885b9c1b51eSKate Stone sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextBlock,
886b9c1b51eSKate Stone sc);
8877e9b1fd0SGreg Clayton return sc.block;
8887e9b1fd0SGreg Clayton }
8897e9b1fd0SGreg Clayton }
890896ddd03SEugene Zelenko return nullptr;
8917e9b1fd0SGreg Clayton }
8927e9b1fd0SGreg Clayton
CalculateSymbolContextSymbol() const893b9c1b51eSKate Stone Symbol *Address::CalculateSymbolContextSymbol() const {
894e72dfb32SGreg Clayton SectionSP section_sp(GetSection());
895b9c1b51eSKate Stone if (section_sp) {
8967e9b1fd0SGreg Clayton SymbolContext sc;
897e72dfb32SGreg Clayton sc.module_sp = section_sp->GetModule();
898b9c1b51eSKate Stone if (sc.module_sp) {
899b9c1b51eSKate Stone sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextSymbol,
900b9c1b51eSKate Stone sc);
9017e9b1fd0SGreg Clayton return sc.symbol;
9027e9b1fd0SGreg Clayton }
9037e9b1fd0SGreg Clayton }
904896ddd03SEugene Zelenko return nullptr;
9057e9b1fd0SGreg Clayton }
9067e9b1fd0SGreg Clayton
CalculateSymbolContextLineEntry(LineEntry & line_entry) const907b9c1b51eSKate Stone bool Address::CalculateSymbolContextLineEntry(LineEntry &line_entry) const {
908e72dfb32SGreg Clayton SectionSP section_sp(GetSection());
909b9c1b51eSKate Stone if (section_sp) {
9107e9b1fd0SGreg Clayton SymbolContext sc;
911e72dfb32SGreg Clayton sc.module_sp = section_sp->GetModule();
912b9c1b51eSKate Stone if (sc.module_sp) {
913b9c1b51eSKate Stone sc.module_sp->ResolveSymbolContextForAddress(*this,
914b9c1b51eSKate Stone eSymbolContextLineEntry, sc);
915b9c1b51eSKate Stone if (sc.line_entry.IsValid()) {
9167e9b1fd0SGreg Clayton line_entry = sc.line_entry;
9177e9b1fd0SGreg Clayton return true;
9187e9b1fd0SGreg Clayton }
9197e9b1fd0SGreg Clayton }
9207e9b1fd0SGreg Clayton }
9217e9b1fd0SGreg Clayton line_entry.Clear();
9227e9b1fd0SGreg Clayton return false;
9237e9b1fd0SGreg Clayton }
92430fdc8d8SChris Lattner
CompareFileAddress(const Address & a,const Address & b)925b9c1b51eSKate Stone int Address::CompareFileAddress(const Address &a, const Address &b) {
92630fdc8d8SChris Lattner addr_t a_file_addr = a.GetFileAddress();
92730fdc8d8SChris Lattner addr_t b_file_addr = b.GetFileAddress();
92830fdc8d8SChris Lattner if (a_file_addr < b_file_addr)
92930fdc8d8SChris Lattner return -1;
93030fdc8d8SChris Lattner if (a_file_addr > b_file_addr)
93130fdc8d8SChris Lattner return +1;
93230fdc8d8SChris Lattner return 0;
93330fdc8d8SChris Lattner }
93430fdc8d8SChris Lattner
CompareLoadAddress(const Address & a,const Address & b,Target * target)935b9c1b51eSKate Stone int Address::CompareLoadAddress(const Address &a, const Address &b,
936b9c1b51eSKate Stone Target *target) {
937896ddd03SEugene Zelenko assert(target != nullptr);
938f5e56de0SGreg Clayton addr_t a_load_addr = a.GetLoadAddress(target);
939f5e56de0SGreg Clayton addr_t b_load_addr = b.GetLoadAddress(target);
94030fdc8d8SChris Lattner if (a_load_addr < b_load_addr)
94130fdc8d8SChris Lattner return -1;
94230fdc8d8SChris Lattner if (a_load_addr > b_load_addr)
94330fdc8d8SChris Lattner return +1;
94430fdc8d8SChris Lattner return 0;
94530fdc8d8SChris Lattner }
94630fdc8d8SChris Lattner
CompareModulePointerAndOffset(const Address & a,const Address & b)947b9c1b51eSKate Stone int Address::CompareModulePointerAndOffset(const Address &a, const Address &b) {
948e72dfb32SGreg Clayton ModuleSP a_module_sp(a.GetModule());
949e72dfb32SGreg Clayton ModuleSP b_module_sp(b.GetModule());
950e72dfb32SGreg Clayton Module *a_module = a_module_sp.get();
951e72dfb32SGreg Clayton Module *b_module = b_module_sp.get();
95230fdc8d8SChris Lattner if (a_module < b_module)
95330fdc8d8SChris Lattner return -1;
95430fdc8d8SChris Lattner if (a_module > b_module)
95530fdc8d8SChris Lattner return +1;
95605097246SAdrian Prantl // Modules are the same, just compare the file address since they should be
95705097246SAdrian Prantl // unique
95830fdc8d8SChris Lattner addr_t a_file_addr = a.GetFileAddress();
95930fdc8d8SChris Lattner addr_t b_file_addr = b.GetFileAddress();
96030fdc8d8SChris Lattner if (a_file_addr < b_file_addr)
96130fdc8d8SChris Lattner return -1;
96230fdc8d8SChris Lattner if (a_file_addr > b_file_addr)
96330fdc8d8SChris Lattner return +1;
96430fdc8d8SChris Lattner return 0;
96530fdc8d8SChris Lattner }
96630fdc8d8SChris Lattner
MemorySize() const967b9c1b51eSKate Stone size_t Address::MemorySize() const {
96805097246SAdrian Prantl // Noting special for the memory size of a single Address object, it is just
96905097246SAdrian Prantl // the size of itself.
97030fdc8d8SChris Lattner return sizeof(Address);
97130fdc8d8SChris Lattner }
97230fdc8d8SChris Lattner
973b0848c5dSGreg Clayton // NOTE: Be careful using this operator. It can correctly compare two
97405097246SAdrian Prantl // addresses from the same Module correctly. It can't compare two addresses
97505097246SAdrian Prantl // from different modules in any meaningful way, but it will compare the module
97605097246SAdrian Prantl // pointers.
97730fdc8d8SChris Lattner //
978b0848c5dSGreg Clayton // To sum things up:
97905097246SAdrian Prantl // - works great for addresses within the same module - it works for addresses
98005097246SAdrian Prantl // across multiple modules, but don't expect the
981b0848c5dSGreg Clayton // address results to make much sense
98230fdc8d8SChris Lattner //
98305097246SAdrian Prantl // This basically lets Address objects be used in ordered collection classes.
984b0848c5dSGreg Clayton
operator <(const Address & lhs,const Address & rhs)985b9c1b51eSKate Stone bool lldb_private::operator<(const Address &lhs, const Address &rhs) {
986e72dfb32SGreg Clayton ModuleSP lhs_module_sp(lhs.GetModule());
987e72dfb32SGreg Clayton ModuleSP rhs_module_sp(rhs.GetModule());
988e72dfb32SGreg Clayton Module *lhs_module = lhs_module_sp.get();
989e72dfb32SGreg Clayton Module *rhs_module = rhs_module_sp.get();
990b9c1b51eSKate Stone if (lhs_module == rhs_module) {
991b0848c5dSGreg Clayton // Addresses are in the same module, just compare the file addresses
992b0848c5dSGreg Clayton return lhs.GetFileAddress() < rhs.GetFileAddress();
993b9c1b51eSKate Stone } else {
99405097246SAdrian Prantl // The addresses are from different modules, just use the module pointer
99505097246SAdrian Prantl // value to get consistent ordering
996b0848c5dSGreg Clayton return lhs_module < rhs_module;
997b0848c5dSGreg Clayton }
998b0848c5dSGreg Clayton }
999b0848c5dSGreg Clayton
operator >(const Address & lhs,const Address & rhs)1000b9c1b51eSKate Stone bool lldb_private::operator>(const Address &lhs, const Address &rhs) {
1001e72dfb32SGreg Clayton ModuleSP lhs_module_sp(lhs.GetModule());
1002e72dfb32SGreg Clayton ModuleSP rhs_module_sp(rhs.GetModule());
1003e72dfb32SGreg Clayton Module *lhs_module = lhs_module_sp.get();
1004e72dfb32SGreg Clayton Module *rhs_module = rhs_module_sp.get();
1005b9c1b51eSKate Stone if (lhs_module == rhs_module) {
1006b0848c5dSGreg Clayton // Addresses are in the same module, just compare the file addresses
1007b0848c5dSGreg Clayton return lhs.GetFileAddress() > rhs.GetFileAddress();
1008b9c1b51eSKate Stone } else {
100905097246SAdrian Prantl // The addresses are from different modules, just use the module pointer
101005097246SAdrian Prantl // value to get consistent ordering
1011b0848c5dSGreg Clayton return lhs_module > rhs_module;
1012b0848c5dSGreg Clayton }
1013b0848c5dSGreg Clayton }
1014b0848c5dSGreg Clayton
101530fdc8d8SChris Lattner // The operator == checks for exact equality only (same section, same offset)
operator ==(const Address & a,const Address & rhs)1016b9c1b51eSKate Stone bool lldb_private::operator==(const Address &a, const Address &rhs) {
1017b9c1b51eSKate Stone return a.GetOffset() == rhs.GetOffset() && a.GetSection() == rhs.GetSection();
101830fdc8d8SChris Lattner }
1019896ddd03SEugene Zelenko
102030fdc8d8SChris Lattner // The operator != checks for exact inequality only (differing section, or
102130fdc8d8SChris Lattner // different offset)
operator !=(const Address & a,const Address & rhs)1022b9c1b51eSKate Stone bool lldb_private::operator!=(const Address &a, const Address &rhs) {
1023b9c1b51eSKate Stone return a.GetOffset() != rhs.GetOffset() || a.GetSection() != rhs.GetSection();
102430fdc8d8SChris Lattner }
102530fdc8d8SChris Lattner
GetAddressClass() const1026b9c1b51eSKate Stone AddressClass Address::GetAddressClass() const {
1027e72dfb32SGreg Clayton ModuleSP module_sp(GetModule());
1028b9c1b51eSKate Stone if (module_sp) {
1029e72dfb32SGreg Clayton ObjectFile *obj_file = module_sp->GetObjectFile();
1030b9c1b51eSKate Stone if (obj_file) {
1031d5d47a35SPavel Labath // Give the symbol file a chance to add to the unified section list
1032d5d47a35SPavel Labath // and to the symtab.
1033d5d47a35SPavel Labath module_sp->GetSymtab();
1034ded470d3SGreg Clayton return obj_file->GetAddressClass(GetFileAddress());
1035ded470d3SGreg Clayton }
1036a7499c98SMichael Sartain }
103704803b3eSTatyana Krasnukha return AddressClass::eUnknown;
1038ded470d3SGreg Clayton }
1039cd482e35SGreg Clayton
SetLoadAddress(lldb::addr_t load_addr,Target * target,bool allow_section_end)1040c3c72122SPavel Labath bool Address::SetLoadAddress(lldb::addr_t load_addr, Target *target,
1041c3c72122SPavel Labath bool allow_section_end) {
1042c3c72122SPavel Labath if (target && target->GetSectionLoadList().ResolveLoadAddress(
1043c3c72122SPavel Labath load_addr, *this, allow_section_end))
1044cd482e35SGreg Clayton return true;
1045e72dfb32SGreg Clayton m_section_wp.reset();
1046cd482e35SGreg Clayton m_offset = load_addr;
1047cd482e35SGreg Clayton return false;
1048cd482e35SGreg Clayton }
1049