1cfca06d7SDimitry Andric //===-- Address.cpp -------------------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste
9f034231aSEd Maste #include "lldb/Core/Address.h"
10b1c73532SDimitry Andric #include "lldb/Core/Debugger.h"
11344a3780SDimitry Andric #include "lldb/Core/Declaration.h"
1274a628f7SDimitry Andric #include "lldb/Core/DumpDataExtractor.h"
13f034231aSEd Maste #include "lldb/Core/Module.h"
1494994d37SDimitry Andric #include "lldb/Core/ModuleList.h"
15f034231aSEd Maste #include "lldb/Core/Section.h"
16f034231aSEd Maste #include "lldb/Symbol/Block.h"
1794994d37SDimitry Andric #include "lldb/Symbol/LineEntry.h"
18f034231aSEd Maste #include "lldb/Symbol/ObjectFile.h"
1994994d37SDimitry Andric #include "lldb/Symbol/Symbol.h"
2094994d37SDimitry Andric #include "lldb/Symbol/SymbolContext.h"
2114f1b3e8SDimitry Andric #include "lldb/Symbol/SymbolVendor.h"
2294994d37SDimitry Andric #include "lldb/Symbol/Symtab.h"
2394994d37SDimitry Andric #include "lldb/Symbol/Type.h"
24f034231aSEd Maste #include "lldb/Symbol/Variable.h"
25f034231aSEd Maste #include "lldb/Symbol/VariableList.h"
26145449b1SDimitry Andric #include "lldb/Target/ABI.h"
27f034231aSEd Maste #include "lldb/Target/ExecutionContext.h"
2894994d37SDimitry Andric #include "lldb/Target/ExecutionContextScope.h"
29f034231aSEd Maste #include "lldb/Target/Process.h"
30866dcdacSEd Maste #include "lldb/Target/SectionLoadList.h"
31f034231aSEd Maste #include "lldb/Target/Target.h"
32b1c73532SDimitry Andric #include "lldb/Utility/AnsiTerminal.h"
3394994d37SDimitry Andric #include "lldb/Utility/ConstString.h"
3494994d37SDimitry Andric #include "lldb/Utility/DataExtractor.h"
3594994d37SDimitry Andric #include "lldb/Utility/Endian.h"
3694994d37SDimitry Andric #include "lldb/Utility/FileSpec.h"
3794994d37SDimitry Andric #include "lldb/Utility/Status.h"
3894994d37SDimitry Andric #include "lldb/Utility/Stream.h"
3994994d37SDimitry Andric #include "lldb/Utility/StreamString.h"
4074a628f7SDimitry Andric
4194994d37SDimitry Andric #include "llvm/ADT/StringRef.h"
4294994d37SDimitry Andric #include "llvm/Support/Compiler.h"
437fa27ce4SDimitry Andric #include "llvm/TargetParser/Triple.h"
4474a628f7SDimitry Andric
4594994d37SDimitry Andric #include <cstdint>
4694994d37SDimitry Andric #include <memory>
4794994d37SDimitry Andric #include <vector>
4874a628f7SDimitry Andric
49344a3780SDimitry Andric #include <cassert>
50344a3780SDimitry Andric #include <cinttypes>
51344a3780SDimitry Andric #include <cstring>
5274a628f7SDimitry Andric
5374a628f7SDimitry Andric namespace lldb_private {
5474a628f7SDimitry Andric class CompileUnit;
5574a628f7SDimitry Andric }
5674a628f7SDimitry Andric namespace lldb_private {
5774a628f7SDimitry Andric class Function;
5874a628f7SDimitry Andric }
59f034231aSEd Maste
60f034231aSEd Maste using namespace lldb;
61f034231aSEd Maste using namespace lldb_private;
62f034231aSEd Maste
ReadBytes(ExecutionContextScope * exe_scope,const Address & address,void * dst,size_t dst_len)6314f1b3e8SDimitry Andric static size_t ReadBytes(ExecutionContextScope *exe_scope,
6414f1b3e8SDimitry Andric const Address &address, void *dst, size_t dst_len) {
65f3fbd1c0SDimitry Andric if (exe_scope == nullptr)
66f034231aSEd Maste return 0;
67f034231aSEd Maste
68f034231aSEd Maste TargetSP target_sp(exe_scope->CalculateTarget());
6914f1b3e8SDimitry Andric if (target_sp) {
70b76161e4SDimitry Andric Status error;
71344a3780SDimitry Andric bool force_live_memory = true;
72344a3780SDimitry Andric return target_sp->ReadMemory(address, dst, dst_len, error,
73344a3780SDimitry Andric force_live_memory);
74f034231aSEd Maste }
75f034231aSEd Maste return 0;
76f034231aSEd Maste }
77f034231aSEd Maste
GetByteOrderAndAddressSize(ExecutionContextScope * exe_scope,const Address & address,ByteOrder & byte_order,uint32_t & addr_size)7814f1b3e8SDimitry Andric static bool GetByteOrderAndAddressSize(ExecutionContextScope *exe_scope,
7914f1b3e8SDimitry Andric const Address &address,
8014f1b3e8SDimitry Andric ByteOrder &byte_order,
8114f1b3e8SDimitry Andric uint32_t &addr_size) {
82f034231aSEd Maste byte_order = eByteOrderInvalid;
83f034231aSEd Maste addr_size = 0;
84f3fbd1c0SDimitry Andric if (exe_scope == nullptr)
85f034231aSEd Maste return false;
86f034231aSEd Maste
87f034231aSEd Maste TargetSP target_sp(exe_scope->CalculateTarget());
8814f1b3e8SDimitry Andric if (target_sp) {
89f034231aSEd Maste byte_order = target_sp->GetArchitecture().GetByteOrder();
90f034231aSEd Maste addr_size = target_sp->GetArchitecture().GetAddressByteSize();
91f034231aSEd Maste }
92f034231aSEd Maste
9314f1b3e8SDimitry Andric if (byte_order == eByteOrderInvalid || addr_size == 0) {
94f034231aSEd Maste ModuleSP module_sp(address.GetModule());
9514f1b3e8SDimitry Andric if (module_sp) {
96f034231aSEd Maste byte_order = module_sp->GetArchitecture().GetByteOrder();
97f034231aSEd Maste addr_size = module_sp->GetArchitecture().GetAddressByteSize();
98f034231aSEd Maste }
99f034231aSEd Maste }
100f034231aSEd Maste return byte_order != eByteOrderInvalid && addr_size != 0;
101f034231aSEd Maste }
102f034231aSEd Maste
ReadUIntMax64(ExecutionContextScope * exe_scope,const Address & address,uint32_t byte_size,bool & success)10314f1b3e8SDimitry Andric static uint64_t ReadUIntMax64(ExecutionContextScope *exe_scope,
10414f1b3e8SDimitry Andric const Address &address, uint32_t byte_size,
10514f1b3e8SDimitry Andric bool &success) {
106f034231aSEd Maste uint64_t uval64 = 0;
10714f1b3e8SDimitry Andric if (exe_scope == nullptr || byte_size > sizeof(uint64_t)) {
108f034231aSEd Maste success = false;
109f034231aSEd Maste return 0;
110f034231aSEd Maste }
111f034231aSEd Maste uint64_t buf = 0;
112f034231aSEd Maste
113f034231aSEd Maste success = ReadBytes(exe_scope, address, &buf, byte_size) == byte_size;
11414f1b3e8SDimitry Andric if (success) {
115f034231aSEd Maste ByteOrder byte_order = eByteOrderInvalid;
116f034231aSEd Maste uint32_t addr_size = 0;
11714f1b3e8SDimitry Andric if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
118f034231aSEd Maste DataExtractor data(&buf, sizeof(buf), byte_order, addr_size);
119f034231aSEd Maste lldb::offset_t offset = 0;
120f034231aSEd Maste uval64 = data.GetU64(&offset);
12114f1b3e8SDimitry Andric } else
122f034231aSEd Maste success = false;
123f034231aSEd Maste }
124f034231aSEd Maste return uval64;
125f034231aSEd Maste }
126f034231aSEd Maste
ReadAddress(ExecutionContextScope * exe_scope,const Address & address,uint32_t pointer_size,Address & deref_so_addr)12714f1b3e8SDimitry Andric static bool ReadAddress(ExecutionContextScope *exe_scope,
12814f1b3e8SDimitry Andric const Address &address, uint32_t pointer_size,
12914f1b3e8SDimitry Andric Address &deref_so_addr) {
130f3fbd1c0SDimitry Andric if (exe_scope == nullptr)
131f034231aSEd Maste return false;
132f034231aSEd Maste
133f034231aSEd Maste bool success = false;
134f034231aSEd Maste addr_t deref_addr = ReadUIntMax64(exe_scope, address, pointer_size, success);
13514f1b3e8SDimitry Andric if (success) {
136f034231aSEd Maste ExecutionContext exe_ctx;
137f034231aSEd Maste exe_scope->CalculateExecutionContext(exe_ctx);
138f034231aSEd Maste // If we have any sections that are loaded, try and resolve using the
139f034231aSEd Maste // section load list
140f034231aSEd Maste Target *target = exe_ctx.GetTargetPtr();
14114f1b3e8SDimitry Andric if (target && !target->GetSectionLoadList().IsEmpty()) {
14214f1b3e8SDimitry Andric if (target->GetSectionLoadList().ResolveLoadAddress(deref_addr,
14314f1b3e8SDimitry Andric deref_so_addr))
144f034231aSEd Maste return true;
14514f1b3e8SDimitry Andric } else {
146f73363f1SDimitry Andric // If we were not running, yet able to read an integer, we must have a
147f73363f1SDimitry Andric // module
148f034231aSEd Maste ModuleSP module_sp(address.GetModule());
149f034231aSEd Maste
150f034231aSEd Maste assert(module_sp);
151f034231aSEd Maste if (module_sp->ResolveFileAddress(deref_addr, deref_so_addr))
152f034231aSEd Maste return true;
153f034231aSEd Maste }
154f034231aSEd Maste
155f034231aSEd Maste // We couldn't make "deref_addr" into a section offset value, but we were
156f73363f1SDimitry Andric // able to read the address, so we return a section offset address with no
157f73363f1SDimitry Andric // section and "deref_addr" as the offset (address).
158f034231aSEd Maste deref_so_addr.SetRawAddress(deref_addr);
159f034231aSEd Maste return true;
160f034231aSEd Maste }
161f034231aSEd Maste return false;
162f034231aSEd Maste }
163f034231aSEd Maste
DumpUInt(ExecutionContextScope * exe_scope,const Address & address,uint32_t byte_size,Stream * strm)16414f1b3e8SDimitry Andric static bool DumpUInt(ExecutionContextScope *exe_scope, const Address &address,
16514f1b3e8SDimitry Andric uint32_t byte_size, Stream *strm) {
166f3fbd1c0SDimitry Andric if (exe_scope == nullptr || byte_size == 0)
1675f29bb8aSDimitry Andric return false;
168f034231aSEd Maste std::vector<uint8_t> buf(byte_size, 0);
169f034231aSEd Maste
17014f1b3e8SDimitry Andric if (ReadBytes(exe_scope, address, &buf[0], buf.size()) == buf.size()) {
171f034231aSEd Maste ByteOrder byte_order = eByteOrderInvalid;
172f034231aSEd Maste uint32_t addr_size = 0;
17314f1b3e8SDimitry Andric if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
174f034231aSEd Maste DataExtractor data(&buf.front(), buf.size(), byte_order, addr_size);
175f034231aSEd Maste
17674a628f7SDimitry Andric DumpDataExtractor(data, strm,
177f034231aSEd Maste 0, // Start offset in "data"
178f034231aSEd Maste eFormatHex, // Print as characters
179f034231aSEd Maste buf.size(), // Size of item
180f034231aSEd Maste 1, // Items count
181f034231aSEd Maste UINT32_MAX, // num per line
182f034231aSEd Maste LLDB_INVALID_ADDRESS, // base address
183f034231aSEd Maste 0, // bitfield bit size
184f034231aSEd Maste 0); // bitfield bit offset
185f034231aSEd Maste
186f034231aSEd Maste return true;
187f034231aSEd Maste }
188f034231aSEd Maste }
189f034231aSEd Maste return false;
190f034231aSEd Maste }
191f034231aSEd Maste
ReadCStringFromMemory(ExecutionContextScope * exe_scope,const Address & address,Stream * strm)19214f1b3e8SDimitry Andric static size_t ReadCStringFromMemory(ExecutionContextScope *exe_scope,
19314f1b3e8SDimitry Andric const Address &address, Stream *strm) {
194f3fbd1c0SDimitry Andric if (exe_scope == nullptr)
195f034231aSEd Maste return 0;
196f034231aSEd Maste const size_t k_buf_len = 256;
197f034231aSEd Maste char buf[k_buf_len + 1];
198f034231aSEd Maste buf[k_buf_len] = '\0'; // NULL terminate
199f034231aSEd Maste
200f034231aSEd Maste // Byte order and address size don't matter for C string dumping..
201e81d9d49SDimitry Andric DataExtractor data(buf, sizeof(buf), endian::InlHostByteOrder(), 4);
202f034231aSEd Maste size_t total_len = 0;
203f034231aSEd Maste size_t bytes_read;
204f034231aSEd Maste Address curr_address(address);
205f034231aSEd Maste strm->PutChar('"');
20614f1b3e8SDimitry Andric while ((bytes_read = ReadBytes(exe_scope, curr_address, buf, k_buf_len)) >
20714f1b3e8SDimitry Andric 0) {
208f034231aSEd Maste size_t len = strlen(buf);
209f034231aSEd Maste if (len == 0)
210f034231aSEd Maste break;
211f034231aSEd Maste if (len > bytes_read)
212f034231aSEd Maste len = bytes_read;
213f034231aSEd Maste
21474a628f7SDimitry Andric DumpDataExtractor(data, strm,
215f034231aSEd Maste 0, // Start offset in "data"
216f034231aSEd Maste eFormatChar, // Print as characters
217f034231aSEd Maste 1, // Size of item (1 byte for a char!)
218f034231aSEd Maste len, // How many bytes to print?
219f034231aSEd Maste UINT32_MAX, // num per line
220f034231aSEd Maste LLDB_INVALID_ADDRESS, // base address
221f034231aSEd Maste 0, // bitfield bit size
222f034231aSEd Maste
223f034231aSEd Maste 0); // bitfield bit offset
224f034231aSEd Maste
225f034231aSEd Maste total_len += bytes_read;
226f034231aSEd Maste
227f034231aSEd Maste if (len < k_buf_len)
228f034231aSEd Maste break;
229f034231aSEd Maste curr_address.SetOffset(curr_address.GetOffset() + bytes_read);
230f034231aSEd Maste }
231f034231aSEd Maste strm->PutChar('"');
232f034231aSEd Maste return total_len;
233f034231aSEd Maste }
234f034231aSEd Maste
Address(lldb::addr_t abs_addr)23514f1b3e8SDimitry Andric Address::Address(lldb::addr_t abs_addr) : m_section_wp(), m_offset(abs_addr) {}
236f034231aSEd Maste
Address(addr_t address,const SectionList * section_list)23714f1b3e8SDimitry Andric Address::Address(addr_t address, const SectionList *section_list)
238145449b1SDimitry Andric : m_section_wp() {
239f034231aSEd Maste ResolveAddressUsingFileSections(address, section_list);
240f034231aSEd Maste }
241f034231aSEd Maste
operator =(const Address & rhs)24214f1b3e8SDimitry Andric const Address &Address::operator=(const Address &rhs) {
24314f1b3e8SDimitry Andric if (this != &rhs) {
244f034231aSEd Maste m_section_wp = rhs.m_section_wp;
24514f1b3e8SDimitry Andric m_offset = rhs.m_offset;
246f034231aSEd Maste }
247f034231aSEd Maste return *this;
248f034231aSEd Maste }
249f034231aSEd Maste
ResolveAddressUsingFileSections(addr_t file_addr,const SectionList * section_list)25014f1b3e8SDimitry Andric bool Address::ResolveAddressUsingFileSections(addr_t file_addr,
25114f1b3e8SDimitry Andric const SectionList *section_list) {
25214f1b3e8SDimitry Andric if (section_list) {
25314f1b3e8SDimitry Andric SectionSP section_sp(
25414f1b3e8SDimitry Andric section_list->FindSectionContainingFileAddress(file_addr));
255f034231aSEd Maste m_section_wp = section_sp;
25614f1b3e8SDimitry Andric if (section_sp) {
257f034231aSEd Maste assert(section_sp->ContainsFileAddress(file_addr));
258f034231aSEd Maste m_offset = file_addr - section_sp->GetFileAddress();
25914f1b3e8SDimitry Andric return true; // Successfully transformed addr into a section offset
26014f1b3e8SDimitry Andric // address
261f034231aSEd Maste }
262f034231aSEd Maste }
263f034231aSEd Maste m_offset = file_addr;
264f034231aSEd Maste return false; // Failed to resolve this address to a section offset value
265f034231aSEd Maste }
266f034231aSEd Maste
267ead24645SDimitry Andric /// 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)268ead24645SDimitry Andric bool Address::ResolveFunctionScope(SymbolContext &sym_ctx,
269ead24645SDimitry Andric AddressRange *addr_range_ptr) {
270ead24645SDimitry Andric constexpr SymbolContextItem resolve_scope =
271ead24645SDimitry Andric eSymbolContextFunction | eSymbolContextSymbol;
272ead24645SDimitry Andric
273ead24645SDimitry Andric if (!(CalculateSymbolContext(&sym_ctx, resolve_scope) & resolve_scope)) {
274ead24645SDimitry Andric if (addr_range_ptr)
275ead24645SDimitry Andric addr_range_ptr->Clear();
276ead24645SDimitry Andric return false;
277ead24645SDimitry Andric }
278ead24645SDimitry Andric
279ead24645SDimitry Andric if (!addr_range_ptr)
280ead24645SDimitry Andric return true;
281ead24645SDimitry Andric
282ead24645SDimitry Andric return sym_ctx.GetAddressRange(resolve_scope, 0, false, *addr_range_ptr);
283ead24645SDimitry Andric }
284ead24645SDimitry Andric
GetModule() const28514f1b3e8SDimitry Andric ModuleSP Address::GetModule() const {
286f034231aSEd Maste lldb::ModuleSP module_sp;
287f034231aSEd Maste SectionSP section_sp(GetSection());
288f034231aSEd Maste if (section_sp)
289f034231aSEd Maste module_sp = section_sp->GetModule();
290f034231aSEd Maste return module_sp;
291f034231aSEd Maste }
292f034231aSEd Maste
GetFileAddress() const29314f1b3e8SDimitry Andric addr_t Address::GetFileAddress() const {
294f034231aSEd Maste SectionSP section_sp(GetSection());
29514f1b3e8SDimitry Andric if (section_sp) {
296f034231aSEd Maste addr_t sect_file_addr = section_sp->GetFileAddress();
29714f1b3e8SDimitry Andric if (sect_file_addr == LLDB_INVALID_ADDRESS) {
298f034231aSEd Maste // Section isn't resolved, we can't return a valid file address
299f034231aSEd Maste return LLDB_INVALID_ADDRESS;
300f034231aSEd Maste }
301f73363f1SDimitry Andric // We have a valid file range, so we can return the file based address by
302f73363f1SDimitry Andric // adding the file base address to our offset
303f034231aSEd Maste return sect_file_addr + m_offset;
30414f1b3e8SDimitry Andric } else if (SectionWasDeletedPrivate()) {
305f73363f1SDimitry Andric // Used to have a valid section but it got deleted so the offset doesn't
306f73363f1SDimitry Andric // mean anything without the section
307f21a844fSEd Maste return LLDB_INVALID_ADDRESS;
308f21a844fSEd Maste }
309f034231aSEd Maste // No section, we just return the offset since it is the value in this case
310f034231aSEd Maste return m_offset;
311f034231aSEd Maste }
312f034231aSEd Maste
GetLoadAddress(Target * target) const31314f1b3e8SDimitry Andric addr_t Address::GetLoadAddress(Target *target) const {
314f034231aSEd Maste SectionSP section_sp(GetSection());
31514f1b3e8SDimitry Andric if (section_sp) {
31614f1b3e8SDimitry Andric if (target) {
317f034231aSEd Maste addr_t sect_load_addr = section_sp->GetLoadBaseAddress(target);
318f034231aSEd Maste
31914f1b3e8SDimitry Andric if (sect_load_addr != LLDB_INVALID_ADDRESS) {
320f73363f1SDimitry Andric // We have a valid file range, so we can return the file based address
321f73363f1SDimitry Andric // by adding the file base address to our offset
322f034231aSEd Maste return sect_load_addr + m_offset;
323f034231aSEd Maste }
324f034231aSEd Maste }
32514f1b3e8SDimitry Andric } else if (SectionWasDeletedPrivate()) {
326f73363f1SDimitry Andric // Used to have a valid section but it got deleted so the offset doesn't
327f73363f1SDimitry Andric // mean anything without the section
328f21a844fSEd Maste return LLDB_INVALID_ADDRESS;
32914f1b3e8SDimitry Andric } else {
330f21a844fSEd Maste // We don't have a section so the offset is the load address
331f21a844fSEd Maste return m_offset;
332f21a844fSEd Maste }
333f73363f1SDimitry Andric // The section isn't resolved or an invalid target was passed in so we can't
334f73363f1SDimitry Andric // return a valid load address.
335f034231aSEd Maste return LLDB_INVALID_ADDRESS;
336f034231aSEd Maste }
337f034231aSEd Maste
GetCallableLoadAddress(Target * target,bool is_indirect) const33814f1b3e8SDimitry Andric addr_t Address::GetCallableLoadAddress(Target *target, bool is_indirect) const {
339866dcdacSEd Maste addr_t code_addr = LLDB_INVALID_ADDRESS;
340866dcdacSEd Maste
34114f1b3e8SDimitry Andric if (is_indirect && target) {
342f034231aSEd Maste ProcessSP processSP = target->GetProcessSP();
343b76161e4SDimitry Andric Status error;
34414f1b3e8SDimitry Andric if (processSP) {
345866dcdacSEd Maste code_addr = processSP->ResolveIndirectFunction(this, error);
346866dcdacSEd Maste if (!error.Success())
347866dcdacSEd Maste code_addr = LLDB_INVALID_ADDRESS;
348866dcdacSEd Maste }
34914f1b3e8SDimitry Andric } else {
350866dcdacSEd Maste code_addr = GetLoadAddress(target);
351f034231aSEd Maste }
352f034231aSEd Maste
353866dcdacSEd Maste if (code_addr == LLDB_INVALID_ADDRESS)
354866dcdacSEd Maste return code_addr;
355f034231aSEd Maste
356f034231aSEd Maste if (target)
357f034231aSEd Maste return target->GetCallableLoadAddress(code_addr, GetAddressClass());
358f034231aSEd Maste return code_addr;
359f034231aSEd Maste }
360f034231aSEd Maste
SetCallableLoadAddress(lldb::addr_t load_addr,Target * target)36114f1b3e8SDimitry Andric bool Address::SetCallableLoadAddress(lldb::addr_t load_addr, Target *target) {
36214f1b3e8SDimitry Andric if (SetLoadAddress(load_addr, target)) {
363f034231aSEd Maste if (target)
364f034231aSEd Maste m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass());
365f034231aSEd Maste return true;
366f034231aSEd Maste }
367f034231aSEd Maste return false;
368f034231aSEd Maste }
369f034231aSEd Maste
GetOpcodeLoadAddress(Target * target,AddressClass addr_class) const37014f1b3e8SDimitry Andric addr_t Address::GetOpcodeLoadAddress(Target *target,
37114f1b3e8SDimitry Andric AddressClass addr_class) const {
372f034231aSEd Maste addr_t code_addr = GetLoadAddress(target);
37314f1b3e8SDimitry Andric if (code_addr != LLDB_INVALID_ADDRESS) {
374f73363f1SDimitry Andric if (addr_class == AddressClass::eInvalid)
375e81d9d49SDimitry Andric addr_class = GetAddressClass();
376e81d9d49SDimitry Andric code_addr = target->GetOpcodeLoadAddress(code_addr, addr_class);
377e81d9d49SDimitry Andric }
378f034231aSEd Maste return code_addr;
379f034231aSEd Maste }
380f034231aSEd Maste
SetOpcodeLoadAddress(lldb::addr_t load_addr,Target * target,AddressClass addr_class,bool allow_section_end)38114f1b3e8SDimitry Andric bool Address::SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target,
382f1d04915SDimitry Andric AddressClass addr_class,
383f1d04915SDimitry Andric bool allow_section_end) {
384f1d04915SDimitry Andric if (SetLoadAddress(load_addr, target, allow_section_end)) {
38514f1b3e8SDimitry Andric if (target) {
386f73363f1SDimitry Andric if (addr_class == AddressClass::eInvalid)
387e81d9d49SDimitry Andric addr_class = GetAddressClass();
388e81d9d49SDimitry Andric m_offset = target->GetOpcodeLoadAddress(m_offset, addr_class);
389e81d9d49SDimitry Andric }
390f034231aSEd Maste return true;
391f034231aSEd Maste }
392f034231aSEd Maste return false;
393f034231aSEd Maste }
394f034231aSEd Maste
GetDescription(Stream & s,Target & target,DescriptionLevel level) const395c0981da4SDimitry Andric bool Address::GetDescription(Stream &s, Target &target,
396c0981da4SDimitry Andric DescriptionLevel level) const {
397c0981da4SDimitry Andric assert(level == eDescriptionLevelBrief &&
398c0981da4SDimitry Andric "Non-brief descriptions not implemented");
399c0981da4SDimitry Andric LineEntry line_entry;
400c0981da4SDimitry Andric if (CalculateSymbolContextLineEntry(line_entry)) {
401ac9a064cSDimitry Andric s.Printf(" (%s:%u:%u)", line_entry.GetFile().GetFilename().GetCString(),
402c0981da4SDimitry Andric line_entry.line, line_entry.column);
403c0981da4SDimitry Andric return true;
404c0981da4SDimitry Andric }
405c0981da4SDimitry Andric return false;
406c0981da4SDimitry Andric }
407c0981da4SDimitry Andric
Dump(Stream * s,ExecutionContextScope * exe_scope,DumpStyle style,DumpStyle fallback_style,uint32_t addr_size,bool all_ranges,std::optional<Stream::HighlightSettings> settings) const40814f1b3e8SDimitry Andric bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
409145449b1SDimitry Andric DumpStyle fallback_style, uint32_t addr_size,
4104df029ccSDimitry Andric bool all_ranges,
4114df029ccSDimitry Andric std::optional<Stream::HighlightSettings> settings) const {
41214f1b3e8SDimitry Andric // If the section was nullptr, only load address is going to work unless we
413f73363f1SDimitry Andric // are trying to deref a pointer
414f034231aSEd Maste SectionSP section_sp(GetSection());
415f034231aSEd Maste if (!section_sp && style != DumpStyleResolvedPointerDescription)
416f034231aSEd Maste style = DumpStyleLoadAddress;
417f034231aSEd Maste
418f034231aSEd Maste ExecutionContext exe_ctx(exe_scope);
419f034231aSEd Maste Target *target = exe_ctx.GetTargetPtr();
420f73363f1SDimitry Andric // If addr_byte_size is UINT32_MAX, then determine the correct address byte
421f73363f1SDimitry Andric // size for the process or default to the size of addr_t
42214f1b3e8SDimitry Andric if (addr_size == UINT32_MAX) {
423f034231aSEd Maste if (target)
424f034231aSEd Maste addr_size = target->GetArchitecture().GetAddressByteSize();
425f034231aSEd Maste else
426f034231aSEd Maste addr_size = sizeof(addr_t);
427f034231aSEd Maste }
428f034231aSEd Maste
429f034231aSEd Maste Address so_addr;
43014f1b3e8SDimitry Andric switch (style) {
431f034231aSEd Maste case DumpStyleInvalid:
432f034231aSEd Maste return false;
433f034231aSEd Maste
434f034231aSEd Maste case DumpStyleSectionNameOffset:
43514f1b3e8SDimitry Andric if (section_sp) {
436cfca06d7SDimitry Andric section_sp->DumpName(s->AsRawOstream());
43714f1b3e8SDimitry Andric s->Printf(" + %" PRIu64, m_offset);
43814f1b3e8SDimitry Andric } else {
439706b4fc4SDimitry Andric DumpAddress(s->AsRawOstream(), m_offset, addr_size);
440f034231aSEd Maste }
441f034231aSEd Maste break;
442f034231aSEd Maste
443f034231aSEd Maste case DumpStyleSectionPointerOffset:
4440cac4ca3SEd Maste s->Printf("(Section *)%p + ", static_cast<void *>(section_sp.get()));
445706b4fc4SDimitry Andric DumpAddress(s->AsRawOstream(), m_offset, addr_size);
446f034231aSEd Maste break;
447f034231aSEd Maste
448f034231aSEd Maste case DumpStyleModuleWithFileAddress:
44914f1b3e8SDimitry Andric if (section_sp) {
450f3fbd1c0SDimitry Andric ModuleSP module_sp = section_sp->GetModule();
451f3fbd1c0SDimitry Andric if (module_sp)
45214f1b3e8SDimitry Andric s->Printf("%s[", module_sp->GetFileSpec().GetFilename().AsCString(
45314f1b3e8SDimitry Andric "<Unknown>"));
454f3fbd1c0SDimitry Andric else
455f3fbd1c0SDimitry Andric s->Printf("%s[", "<Unknown>");
456205afe67SEd Maste }
457e3b55780SDimitry Andric [[fallthrough]];
45814f1b3e8SDimitry Andric case DumpStyleFileAddress: {
459f034231aSEd Maste addr_t file_addr = GetFileAddress();
46014f1b3e8SDimitry Andric if (file_addr == LLDB_INVALID_ADDRESS) {
461f034231aSEd Maste if (fallback_style != DumpStyleInvalid)
462f034231aSEd Maste return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
463f034231aSEd Maste return false;
464f034231aSEd Maste }
465706b4fc4SDimitry Andric DumpAddress(s->AsRawOstream(), file_addr, addr_size);
466f034231aSEd Maste if (style == DumpStyleModuleWithFileAddress && section_sp)
467f034231aSEd Maste s->PutChar(']');
46814f1b3e8SDimitry Andric } break;
469f034231aSEd Maste
47014f1b3e8SDimitry Andric case DumpStyleLoadAddress: {
471f034231aSEd Maste addr_t load_addr = GetLoadAddress(target);
472e81d9d49SDimitry Andric
473e81d9d49SDimitry Andric /*
474e81d9d49SDimitry Andric * MIPS:
475e81d9d49SDimitry Andric * Display address in compressed form for MIPS16 or microMIPS
476f73363f1SDimitry Andric * if the address belongs to AddressClass::eCodeAlternateISA.
477e81d9d49SDimitry Andric */
47814f1b3e8SDimitry Andric if (target) {
47914f1b3e8SDimitry Andric const llvm::Triple::ArchType llvm_arch =
48014f1b3e8SDimitry Andric target->GetArchitecture().GetMachine();
48114f1b3e8SDimitry Andric if (llvm_arch == llvm::Triple::mips ||
48214f1b3e8SDimitry Andric llvm_arch == llvm::Triple::mipsel ||
48314f1b3e8SDimitry Andric llvm_arch == llvm::Triple::mips64 ||
48414f1b3e8SDimitry Andric llvm_arch == llvm::Triple::mips64el)
485e81d9d49SDimitry Andric load_addr = GetCallableLoadAddress(target);
486e81d9d49SDimitry Andric }
487e81d9d49SDimitry Andric
48814f1b3e8SDimitry Andric if (load_addr == LLDB_INVALID_ADDRESS) {
489f034231aSEd Maste if (fallback_style != DumpStyleInvalid)
490f034231aSEd Maste return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
491f034231aSEd Maste return false;
492f034231aSEd Maste }
493706b4fc4SDimitry Andric DumpAddress(s->AsRawOstream(), load_addr, addr_size);
49414f1b3e8SDimitry Andric } break;
495f034231aSEd Maste
496f034231aSEd Maste case DumpStyleResolvedDescription:
497f034231aSEd Maste case DumpStyleResolvedDescriptionNoModule:
498205afe67SEd Maste case DumpStyleResolvedDescriptionNoFunctionArguments:
4995e95aa85SEd Maste case DumpStyleNoFunctionName:
50014f1b3e8SDimitry Andric if (IsSectionOffset()) {
501f034231aSEd Maste uint32_t pointer_size = 4;
502f034231aSEd Maste ModuleSP module_sp(GetModule());
503f034231aSEd Maste if (target)
504f034231aSEd Maste pointer_size = target->GetArchitecture().GetAddressByteSize();
505f034231aSEd Maste else if (module_sp)
506f034231aSEd Maste pointer_size = module_sp->GetArchitecture().GetAddressByteSize();
507f034231aSEd Maste bool showed_info = false;
50814f1b3e8SDimitry Andric if (section_sp) {
509f034231aSEd Maste SectionType sect_type = section_sp->GetType();
51014f1b3e8SDimitry Andric switch (sect_type) {
511f034231aSEd Maste case eSectionTypeData:
51214f1b3e8SDimitry Andric if (module_sp) {
513ead24645SDimitry Andric if (Symtab *symtab = module_sp->GetSymtab()) {
514f034231aSEd Maste const addr_t file_Addr = GetFileAddress();
51514f1b3e8SDimitry Andric Symbol *symbol =
51614f1b3e8SDimitry Andric symtab->FindSymbolContainingFileAddress(file_Addr);
51714f1b3e8SDimitry Andric if (symbol) {
518f034231aSEd Maste const char *symbol_name = symbol->GetName().AsCString();
51914f1b3e8SDimitry Andric if (symbol_name) {
5204df029ccSDimitry Andric s->PutCStringColorHighlighted(symbol_name, settings);
52114f1b3e8SDimitry Andric addr_t delta =
52214f1b3e8SDimitry Andric file_Addr - symbol->GetAddressRef().GetFileAddress();
523f034231aSEd Maste if (delta)
524f034231aSEd Maste s->Printf(" + %" PRIu64, delta);
525f034231aSEd Maste showed_info = true;
526f034231aSEd Maste }
527f034231aSEd Maste }
528f034231aSEd Maste }
529f034231aSEd Maste }
530f034231aSEd Maste break;
531f034231aSEd Maste
532f034231aSEd Maste case eSectionTypeDataCString:
533f034231aSEd Maste // Read the C string from memory and display it
534f034231aSEd Maste showed_info = true;
535f034231aSEd Maste ReadCStringFromMemory(exe_scope, *this, s);
536f034231aSEd Maste break;
537f034231aSEd Maste
538f034231aSEd Maste case eSectionTypeDataCStringPointers:
53914f1b3e8SDimitry Andric if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
540f034231aSEd Maste #if VERBOSE_OUTPUT
541f034231aSEd Maste s->PutCString("(char *)");
54214f1b3e8SDimitry Andric so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
54314f1b3e8SDimitry Andric DumpStyleFileAddress);
544f034231aSEd Maste s->PutCString(": ");
545f034231aSEd Maste #endif
546f034231aSEd Maste showed_info = true;
547f034231aSEd Maste ReadCStringFromMemory(exe_scope, so_addr, s);
548f034231aSEd Maste }
549f034231aSEd Maste break;
550f034231aSEd Maste
551f034231aSEd Maste case eSectionTypeDataObjCMessageRefs:
55214f1b3e8SDimitry Andric if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
55314f1b3e8SDimitry Andric if (target && so_addr.IsSectionOffset()) {
554f034231aSEd Maste SymbolContext func_sc;
55514f1b3e8SDimitry Andric target->GetImages().ResolveSymbolContextForAddress(
55614f1b3e8SDimitry Andric so_addr, eSymbolContextEverything, func_sc);
55714f1b3e8SDimitry Andric if (func_sc.function != nullptr || func_sc.symbol != nullptr) {
558f034231aSEd Maste showed_info = true;
559f034231aSEd Maste #if VERBOSE_OUTPUT
560f034231aSEd Maste s->PutCString("(objc_msgref *) -> { (func*)");
56114f1b3e8SDimitry Andric so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
56214f1b3e8SDimitry Andric DumpStyleFileAddress);
563f034231aSEd Maste #else
564f034231aSEd Maste s->PutCString("{ ");
565f034231aSEd Maste #endif
566f034231aSEd Maste Address cstr_addr(*this);
567f034231aSEd Maste cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
56814f1b3e8SDimitry Andric func_sc.DumpStopContext(s, exe_scope, so_addr, true, true,
56914f1b3e8SDimitry Andric false, true, true);
57014f1b3e8SDimitry Andric if (ReadAddress(exe_scope, cstr_addr, pointer_size, so_addr)) {
571f034231aSEd Maste #if VERBOSE_OUTPUT
572f034231aSEd Maste s->PutCString("), (char *)");
57314f1b3e8SDimitry Andric so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
57414f1b3e8SDimitry Andric DumpStyleFileAddress);
575f034231aSEd Maste s->PutCString(" (");
576f034231aSEd Maste #else
577f034231aSEd Maste s->PutCString(", ");
578f034231aSEd Maste #endif
579f034231aSEd Maste ReadCStringFromMemory(exe_scope, so_addr, s);
580f034231aSEd Maste }
581f034231aSEd Maste #if VERBOSE_OUTPUT
582f034231aSEd Maste s->PutCString(") }");
583f034231aSEd Maste #else
584f034231aSEd Maste s->PutCString(" }");
585f034231aSEd Maste #endif
586f034231aSEd Maste }
587f034231aSEd Maste }
588f034231aSEd Maste }
589f034231aSEd Maste break;
590f034231aSEd Maste
59114f1b3e8SDimitry Andric case eSectionTypeDataObjCCFStrings: {
592f034231aSEd Maste Address cfstring_data_addr(*this);
59314f1b3e8SDimitry Andric cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() +
59414f1b3e8SDimitry Andric (2 * pointer_size));
59514f1b3e8SDimitry Andric if (ReadAddress(exe_scope, cfstring_data_addr, pointer_size,
59614f1b3e8SDimitry Andric so_addr)) {
597f034231aSEd Maste #if VERBOSE_OUTPUT
598f034231aSEd Maste s->PutCString("(CFString *) ");
59914f1b3e8SDimitry Andric cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
60014f1b3e8SDimitry Andric DumpStyleFileAddress);
601f034231aSEd Maste s->PutCString(" -> @");
602f034231aSEd Maste #else
603f034231aSEd Maste s->PutChar('@');
604f034231aSEd Maste #endif
605f034231aSEd Maste if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
606f034231aSEd Maste showed_info = true;
607f034231aSEd Maste }
60814f1b3e8SDimitry Andric } break;
609f034231aSEd Maste
610f034231aSEd Maste case eSectionTypeData4:
611f034231aSEd Maste // Read the 4 byte data and display it
612f034231aSEd Maste showed_info = true;
613f034231aSEd Maste s->PutCString("(uint32_t) ");
614f034231aSEd Maste DumpUInt(exe_scope, *this, 4, s);
615f034231aSEd Maste break;
616f034231aSEd Maste
617f034231aSEd Maste case eSectionTypeData8:
618f034231aSEd Maste // Read the 8 byte data and display it
619f034231aSEd Maste showed_info = true;
620f034231aSEd Maste s->PutCString("(uint64_t) ");
621f034231aSEd Maste DumpUInt(exe_scope, *this, 8, s);
622f034231aSEd Maste break;
623f034231aSEd Maste
624f034231aSEd Maste case eSectionTypeData16:
625f034231aSEd Maste // Read the 16 byte data and display it
626f034231aSEd Maste showed_info = true;
627f034231aSEd Maste s->PutCString("(uint128_t) ");
628f034231aSEd Maste DumpUInt(exe_scope, *this, 16, s);
629f034231aSEd Maste break;
630f034231aSEd Maste
631f034231aSEd Maste case eSectionTypeDataPointers:
632f034231aSEd Maste // Read the pointer data and display it
63314f1b3e8SDimitry Andric if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
634f034231aSEd Maste s->PutCString("(void *)");
63514f1b3e8SDimitry Andric so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
63614f1b3e8SDimitry Andric DumpStyleFileAddress);
637f034231aSEd Maste
638f034231aSEd Maste showed_info = true;
63914f1b3e8SDimitry Andric if (so_addr.IsSectionOffset()) {
640f034231aSEd Maste SymbolContext pointer_sc;
64114f1b3e8SDimitry Andric if (target) {
64214f1b3e8SDimitry Andric target->GetImages().ResolveSymbolContextForAddress(
64314f1b3e8SDimitry Andric so_addr, eSymbolContextEverything, pointer_sc);
64414f1b3e8SDimitry Andric if (pointer_sc.function != nullptr ||
64514f1b3e8SDimitry Andric pointer_sc.symbol != nullptr) {
646f034231aSEd Maste s->PutCString(": ");
64714f1b3e8SDimitry Andric pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false,
648ac9a064cSDimitry Andric false, true, true, false,
649ac9a064cSDimitry Andric settings);
650f034231aSEd Maste }
651f034231aSEd Maste }
652f034231aSEd Maste }
653f034231aSEd Maste }
654f034231aSEd Maste break;
655f034231aSEd Maste
656f034231aSEd Maste default:
657f034231aSEd Maste break;
658f034231aSEd Maste }
659f034231aSEd Maste }
660f034231aSEd Maste
66114f1b3e8SDimitry Andric if (!showed_info) {
66214f1b3e8SDimitry Andric if (module_sp) {
663f034231aSEd Maste SymbolContext sc;
66414f1b3e8SDimitry Andric module_sp->ResolveSymbolContextForAddress(
66514f1b3e8SDimitry Andric *this, eSymbolContextEverything, sc);
66614f1b3e8SDimitry Andric if (sc.function || sc.symbol) {
667f034231aSEd Maste bool show_stop_context = true;
668f034231aSEd Maste const bool show_module = (style == DumpStyleResolvedDescription);
669f034231aSEd Maste const bool show_fullpaths = false;
670f034231aSEd Maste const bool show_inlined_frames = true;
67114f1b3e8SDimitry Andric const bool show_function_arguments =
67214f1b3e8SDimitry Andric (style != DumpStyleResolvedDescriptionNoFunctionArguments);
6735e95aa85SEd Maste const bool show_function_name = (style != DumpStyleNoFunctionName);
67414f1b3e8SDimitry Andric if (sc.function == nullptr && sc.symbol != nullptr) {
675f034231aSEd Maste // If we have just a symbol make sure it is in the right section
67614f1b3e8SDimitry Andric if (sc.symbol->ValueIsAddress()) {
67714f1b3e8SDimitry Andric if (sc.symbol->GetAddressRef().GetSection() != GetSection()) {
678f034231aSEd Maste // don't show the module if the symbol is a trampoline symbol
679f034231aSEd Maste show_stop_context = false;
680f034231aSEd Maste }
681f034231aSEd Maste }
682f034231aSEd Maste }
68314f1b3e8SDimitry Andric if (show_stop_context) {
684f73363f1SDimitry Andric // We have a function or a symbol from the same sections as this
685f73363f1SDimitry Andric // address.
68614f1b3e8SDimitry Andric sc.DumpStopContext(s, exe_scope, *this, show_fullpaths,
68714f1b3e8SDimitry Andric show_module, show_inlined_frames,
688b1c73532SDimitry Andric show_function_arguments, show_function_name,
689ac9a064cSDimitry Andric false, settings);
69014f1b3e8SDimitry Andric } else {
691f73363f1SDimitry Andric // We found a symbol but it was in a different section so it
692f73363f1SDimitry Andric // isn't the symbol we should be showing, just show the section
693f73363f1SDimitry Andric // name + offset
694b1c73532SDimitry Andric Dump(s, exe_scope, DumpStyleSectionNameOffset, DumpStyleInvalid,
6954df029ccSDimitry Andric UINT32_MAX, false, settings);
696f034231aSEd Maste }
697f034231aSEd Maste }
698f034231aSEd Maste }
699f034231aSEd Maste }
70014f1b3e8SDimitry Andric } else {
701f034231aSEd Maste if (fallback_style != DumpStyleInvalid)
702b1c73532SDimitry Andric return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size,
7034df029ccSDimitry Andric false, settings);
704f034231aSEd Maste return false;
705f034231aSEd Maste }
706f034231aSEd Maste break;
707f034231aSEd Maste
708f034231aSEd Maste case DumpStyleDetailedSymbolContext:
70914f1b3e8SDimitry Andric if (IsSectionOffset()) {
710f034231aSEd Maste ModuleSP module_sp(GetModule());
71114f1b3e8SDimitry Andric if (module_sp) {
712f034231aSEd Maste SymbolContext sc;
71314f1b3e8SDimitry Andric module_sp->ResolveSymbolContextForAddress(
71414f1b3e8SDimitry Andric *this, eSymbolContextEverything | eSymbolContextVariable, sc);
71514f1b3e8SDimitry Andric if (sc.symbol) {
716f73363f1SDimitry Andric // If we have just a symbol make sure it is in the same section as
717f73363f1SDimitry Andric // our address. If it isn't, then we might have just found the last
718f73363f1SDimitry Andric // symbol that came before the address that we are looking up that
719f73363f1SDimitry Andric // has nothing to do with our address lookup.
72014f1b3e8SDimitry Andric if (sc.symbol->ValueIsAddress() &&
72114f1b3e8SDimitry Andric sc.symbol->GetAddressRef().GetSection() != GetSection())
722f3fbd1c0SDimitry Andric sc.symbol = nullptr;
723f034231aSEd Maste }
7244df029ccSDimitry Andric sc.GetDescription(s, eDescriptionLevelBrief, target, settings);
725f034231aSEd Maste
72614f1b3e8SDimitry Andric if (sc.block) {
727f034231aSEd Maste bool can_create = true;
728f034231aSEd Maste bool get_parent_variables = true;
729f034231aSEd Maste bool stop_if_block_is_inlined_function = false;
730f034231aSEd Maste VariableList variable_list;
731145449b1SDimitry Andric addr_t file_addr = GetFileAddress();
732145449b1SDimitry Andric sc.block->AppendVariables(
733145449b1SDimitry Andric can_create, get_parent_variables,
734f034231aSEd Maste stop_if_block_is_inlined_function,
735145449b1SDimitry Andric [&](Variable *var) {
736145449b1SDimitry Andric return var && var->LocationIsValidForAddress(*this);
737145449b1SDimitry Andric },
738f034231aSEd Maste &variable_list);
739145449b1SDimitry Andric ABISP abi =
740145449b1SDimitry Andric ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture());
741706b4fc4SDimitry Andric for (const VariableSP &var_sp : variable_list) {
742f034231aSEd Maste s->Indent();
7435e95aa85SEd Maste s->Printf(" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"",
744706b4fc4SDimitry Andric var_sp->GetID(), var_sp->GetName().GetCString());
745706b4fc4SDimitry Andric Type *type = var_sp->GetType();
7465e95aa85SEd Maste if (type)
7475e95aa85SEd Maste s->Printf(", type = \"%s\"", type->GetName().GetCString());
7485e95aa85SEd Maste else
7495e95aa85SEd Maste s->PutCString(", type = <unknown>");
750145449b1SDimitry Andric s->PutCString(", valid ranges = ");
751145449b1SDimitry Andric if (var_sp->GetScopeRange().IsEmpty())
752145449b1SDimitry Andric s->PutCString("<block>");
753145449b1SDimitry Andric else if (all_ranges) {
754145449b1SDimitry Andric for (auto range : var_sp->GetScopeRange())
755145449b1SDimitry Andric DumpAddressRange(s->AsRawOstream(), range.GetRangeBase(),
756145449b1SDimitry Andric range.GetRangeEnd(), addr_size);
757145449b1SDimitry Andric } else if (auto *range =
758145449b1SDimitry Andric var_sp->GetScopeRange().FindEntryThatContains(
759145449b1SDimitry Andric file_addr))
760145449b1SDimitry Andric DumpAddressRange(s->AsRawOstream(), range->GetRangeBase(),
761145449b1SDimitry Andric range->GetRangeEnd(), addr_size);
7625e95aa85SEd Maste s->PutCString(", location = ");
763145449b1SDimitry Andric var_sp->DumpLocations(s, all_ranges ? LLDB_INVALID_ADDRESS : *this);
764f034231aSEd Maste s->PutCString(", decl = ");
765706b4fc4SDimitry Andric var_sp->GetDeclaration().DumpStopContext(s, false);
766f034231aSEd Maste s->EOL();
767f034231aSEd Maste }
768f034231aSEd Maste }
769f034231aSEd Maste }
77014f1b3e8SDimitry Andric } else {
771f034231aSEd Maste if (fallback_style != DumpStyleInvalid)
772b1c73532SDimitry Andric return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size,
7734df029ccSDimitry Andric false, settings);
774f034231aSEd Maste return false;
775f034231aSEd Maste }
776f034231aSEd Maste break;
777f3fbd1c0SDimitry Andric
77814f1b3e8SDimitry Andric case DumpStyleResolvedPointerDescription: {
779f034231aSEd Maste Process *process = exe_ctx.GetProcessPtr();
78014f1b3e8SDimitry Andric if (process) {
781f034231aSEd Maste addr_t load_addr = GetLoadAddress(target);
78214f1b3e8SDimitry Andric if (load_addr != LLDB_INVALID_ADDRESS) {
783b76161e4SDimitry Andric Status memory_error;
78414f1b3e8SDimitry Andric addr_t dereferenced_load_addr =
78514f1b3e8SDimitry Andric process->ReadPointerFromMemory(load_addr, memory_error);
78614f1b3e8SDimitry Andric if (dereferenced_load_addr != LLDB_INVALID_ADDRESS) {
787f034231aSEd Maste Address dereferenced_addr;
78814f1b3e8SDimitry Andric if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr,
78914f1b3e8SDimitry Andric target)) {
790f034231aSEd Maste StreamString strm;
79114f1b3e8SDimitry Andric if (dereferenced_addr.Dump(&strm, exe_scope,
79214f1b3e8SDimitry Andric DumpStyleResolvedDescription,
79314f1b3e8SDimitry Andric DumpStyleInvalid, addr_size)) {
794706b4fc4SDimitry Andric DumpAddress(s->AsRawOstream(), dereferenced_load_addr, addr_size,
795706b4fc4SDimitry Andric " -> ", " ");
79614f1b3e8SDimitry Andric s->Write(strm.GetString().data(), strm.GetSize());
797f034231aSEd Maste return true;
798f034231aSEd Maste }
799f034231aSEd Maste }
800f034231aSEd Maste }
801f034231aSEd Maste }
802f034231aSEd Maste }
803f034231aSEd Maste if (fallback_style != DumpStyleInvalid)
804f034231aSEd Maste return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
805f034231aSEd Maste return false;
80614f1b3e8SDimitry Andric } break;
807f034231aSEd Maste }
808f034231aSEd Maste
809f034231aSEd Maste return true;
810f034231aSEd Maste }
811f034231aSEd Maste
SectionWasDeleted() const81214f1b3e8SDimitry Andric bool Address::SectionWasDeleted() const {
81386758c71SEd Maste if (GetSection())
81486758c71SEd Maste return false;
81586758c71SEd Maste return SectionWasDeletedPrivate();
81686758c71SEd Maste }
81786758c71SEd Maste
SectionWasDeletedPrivate() const81814f1b3e8SDimitry Andric bool Address::SectionWasDeletedPrivate() const {
819f21a844fSEd Maste lldb::SectionWP empty_section_wp;
820f21a844fSEd Maste
82114f1b3e8SDimitry Andric // If either call to "std::weak_ptr::owner_before(...) value returns true,
822f73363f1SDimitry Andric // this indicates that m_section_wp once contained (possibly still does) a
823f73363f1SDimitry Andric // reference to a valid shared pointer. This helps us know if we had a valid
824f73363f1SDimitry Andric // reference to a section which is now invalid because the module it was in
825f73363f1SDimitry Andric // was unloaded/deleted, or if the address doesn't have a valid reference to
826f73363f1SDimitry Andric // a section.
82714f1b3e8SDimitry Andric return empty_section_wp.owner_before(m_section_wp) ||
82814f1b3e8SDimitry Andric m_section_wp.owner_before(empty_section_wp);
829f21a844fSEd Maste }
830f21a844fSEd Maste
83194994d37SDimitry Andric uint32_t
CalculateSymbolContext(SymbolContext * sc,SymbolContextItem resolve_scope) const83294994d37SDimitry Andric Address::CalculateSymbolContext(SymbolContext *sc,
83394994d37SDimitry Andric SymbolContextItem resolve_scope) const {
834f034231aSEd Maste sc->Clear(false);
83514f1b3e8SDimitry Andric // Absolute addresses don't have enough information to reconstruct even their
83614f1b3e8SDimitry Andric // target.
837f034231aSEd Maste
838f034231aSEd Maste SectionSP section_sp(GetSection());
83914f1b3e8SDimitry Andric if (section_sp) {
840f034231aSEd Maste ModuleSP module_sp(section_sp->GetModule());
84114f1b3e8SDimitry Andric if (module_sp) {
842f034231aSEd Maste sc->module_sp = module_sp;
843f034231aSEd Maste if (sc->module_sp)
84414f1b3e8SDimitry Andric return sc->module_sp->ResolveSymbolContextForAddress(
84514f1b3e8SDimitry Andric *this, resolve_scope, *sc);
846f034231aSEd Maste }
847f034231aSEd Maste }
848f034231aSEd Maste return 0;
849f034231aSEd Maste }
850f034231aSEd Maste
CalculateSymbolContextModule() const85114f1b3e8SDimitry Andric ModuleSP Address::CalculateSymbolContextModule() const {
852f034231aSEd Maste SectionSP section_sp(GetSection());
853f034231aSEd Maste if (section_sp)
854f034231aSEd Maste return section_sp->GetModule();
855f034231aSEd Maste return ModuleSP();
856f034231aSEd Maste }
857f034231aSEd Maste
CalculateSymbolContextCompileUnit() const85814f1b3e8SDimitry Andric CompileUnit *Address::CalculateSymbolContextCompileUnit() const {
859f034231aSEd Maste SectionSP section_sp(GetSection());
86014f1b3e8SDimitry Andric if (section_sp) {
861f034231aSEd Maste SymbolContext sc;
862f034231aSEd Maste sc.module_sp = section_sp->GetModule();
86314f1b3e8SDimitry Andric if (sc.module_sp) {
86414f1b3e8SDimitry Andric sc.module_sp->ResolveSymbolContextForAddress(*this,
86514f1b3e8SDimitry Andric eSymbolContextCompUnit, sc);
866f034231aSEd Maste return sc.comp_unit;
867f034231aSEd Maste }
868f034231aSEd Maste }
869f3fbd1c0SDimitry Andric return nullptr;
870f034231aSEd Maste }
871f034231aSEd Maste
CalculateSymbolContextFunction() const87214f1b3e8SDimitry Andric Function *Address::CalculateSymbolContextFunction() const {
873f034231aSEd Maste SectionSP section_sp(GetSection());
87414f1b3e8SDimitry Andric if (section_sp) {
875f034231aSEd Maste SymbolContext sc;
876f034231aSEd Maste sc.module_sp = section_sp->GetModule();
87714f1b3e8SDimitry Andric if (sc.module_sp) {
87814f1b3e8SDimitry Andric sc.module_sp->ResolveSymbolContextForAddress(*this,
87914f1b3e8SDimitry Andric eSymbolContextFunction, sc);
880f034231aSEd Maste return sc.function;
881f034231aSEd Maste }
882f034231aSEd Maste }
883f3fbd1c0SDimitry Andric return nullptr;
884f034231aSEd Maste }
885f034231aSEd Maste
CalculateSymbolContextBlock() const88614f1b3e8SDimitry Andric Block *Address::CalculateSymbolContextBlock() const {
887f034231aSEd Maste SectionSP section_sp(GetSection());
88814f1b3e8SDimitry Andric if (section_sp) {
889f034231aSEd Maste SymbolContext sc;
890f034231aSEd Maste sc.module_sp = section_sp->GetModule();
89114f1b3e8SDimitry Andric if (sc.module_sp) {
89214f1b3e8SDimitry Andric sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextBlock,
89314f1b3e8SDimitry Andric sc);
894f034231aSEd Maste return sc.block;
895f034231aSEd Maste }
896f034231aSEd Maste }
897f3fbd1c0SDimitry Andric return nullptr;
898f034231aSEd Maste }
899f034231aSEd Maste
CalculateSymbolContextSymbol() const90014f1b3e8SDimitry Andric Symbol *Address::CalculateSymbolContextSymbol() const {
901f034231aSEd Maste SectionSP section_sp(GetSection());
90214f1b3e8SDimitry Andric if (section_sp) {
903f034231aSEd Maste SymbolContext sc;
904f034231aSEd Maste sc.module_sp = section_sp->GetModule();
90514f1b3e8SDimitry Andric if (sc.module_sp) {
90614f1b3e8SDimitry Andric sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextSymbol,
90714f1b3e8SDimitry Andric sc);
908f034231aSEd Maste return sc.symbol;
909f034231aSEd Maste }
910f034231aSEd Maste }
911f3fbd1c0SDimitry Andric return nullptr;
912f034231aSEd Maste }
913f034231aSEd Maste
CalculateSymbolContextLineEntry(LineEntry & line_entry) const91414f1b3e8SDimitry Andric bool Address::CalculateSymbolContextLineEntry(LineEntry &line_entry) const {
915f034231aSEd Maste SectionSP section_sp(GetSection());
91614f1b3e8SDimitry Andric if (section_sp) {
917f034231aSEd Maste SymbolContext sc;
918f034231aSEd Maste sc.module_sp = section_sp->GetModule();
91914f1b3e8SDimitry Andric if (sc.module_sp) {
92014f1b3e8SDimitry Andric sc.module_sp->ResolveSymbolContextForAddress(*this,
92114f1b3e8SDimitry Andric eSymbolContextLineEntry, sc);
92214f1b3e8SDimitry Andric if (sc.line_entry.IsValid()) {
923f034231aSEd Maste line_entry = sc.line_entry;
924f034231aSEd Maste return true;
925f034231aSEd Maste }
926f034231aSEd Maste }
927f034231aSEd Maste }
928f034231aSEd Maste line_entry.Clear();
929f034231aSEd Maste return false;
930f034231aSEd Maste }
931f034231aSEd Maste
CompareFileAddress(const Address & a,const Address & b)93214f1b3e8SDimitry Andric int Address::CompareFileAddress(const Address &a, const Address &b) {
933f034231aSEd Maste addr_t a_file_addr = a.GetFileAddress();
934f034231aSEd Maste addr_t b_file_addr = b.GetFileAddress();
935f034231aSEd Maste if (a_file_addr < b_file_addr)
936f034231aSEd Maste return -1;
937f034231aSEd Maste if (a_file_addr > b_file_addr)
938f034231aSEd Maste return +1;
939f034231aSEd Maste return 0;
940f034231aSEd Maste }
941f034231aSEd Maste
CompareLoadAddress(const Address & a,const Address & b,Target * target)94214f1b3e8SDimitry Andric int Address::CompareLoadAddress(const Address &a, const Address &b,
94314f1b3e8SDimitry Andric Target *target) {
944f3fbd1c0SDimitry Andric assert(target != nullptr);
945f034231aSEd Maste addr_t a_load_addr = a.GetLoadAddress(target);
946f034231aSEd Maste addr_t b_load_addr = b.GetLoadAddress(target);
947f034231aSEd Maste if (a_load_addr < b_load_addr)
948f034231aSEd Maste return -1;
949f034231aSEd Maste if (a_load_addr > b_load_addr)
950f034231aSEd Maste return +1;
951f034231aSEd Maste return 0;
952f034231aSEd Maste }
953f034231aSEd Maste
CompareModulePointerAndOffset(const Address & a,const Address & b)95414f1b3e8SDimitry Andric int Address::CompareModulePointerAndOffset(const Address &a, const Address &b) {
955f034231aSEd Maste ModuleSP a_module_sp(a.GetModule());
956f034231aSEd Maste ModuleSP b_module_sp(b.GetModule());
957f034231aSEd Maste Module *a_module = a_module_sp.get();
958f034231aSEd Maste Module *b_module = b_module_sp.get();
959f034231aSEd Maste if (a_module < b_module)
960f034231aSEd Maste return -1;
961f034231aSEd Maste if (a_module > b_module)
962f034231aSEd Maste return +1;
963f73363f1SDimitry Andric // Modules are the same, just compare the file address since they should be
964f73363f1SDimitry Andric // unique
965f034231aSEd Maste addr_t a_file_addr = a.GetFileAddress();
966f034231aSEd Maste addr_t b_file_addr = b.GetFileAddress();
967f034231aSEd Maste if (a_file_addr < b_file_addr)
968f034231aSEd Maste return -1;
969f034231aSEd Maste if (a_file_addr > b_file_addr)
970f034231aSEd Maste return +1;
971f034231aSEd Maste return 0;
972f034231aSEd Maste }
973f034231aSEd Maste
MemorySize() const97414f1b3e8SDimitry Andric size_t Address::MemorySize() const {
975f73363f1SDimitry Andric // Noting special for the memory size of a single Address object, it is just
976f73363f1SDimitry Andric // the size of itself.
977f034231aSEd Maste return sizeof(Address);
978f034231aSEd Maste }
979f034231aSEd Maste
980f034231aSEd Maste // NOTE: Be careful using this operator. It can correctly compare two
981f73363f1SDimitry Andric // addresses from the same Module correctly. It can't compare two addresses
982f73363f1SDimitry Andric // from different modules in any meaningful way, but it will compare the module
983f73363f1SDimitry Andric // pointers.
984f034231aSEd Maste //
985f034231aSEd Maste // To sum things up:
986f73363f1SDimitry Andric // - works great for addresses within the same module - it works for addresses
987f73363f1SDimitry Andric // across multiple modules, but don't expect the
988f034231aSEd Maste // address results to make much sense
989f034231aSEd Maste //
990f73363f1SDimitry Andric // This basically lets Address objects be used in ordered collection classes.
991f034231aSEd Maste
operator <(const Address & lhs,const Address & rhs)99214f1b3e8SDimitry Andric bool lldb_private::operator<(const Address &lhs, const Address &rhs) {
993f034231aSEd Maste ModuleSP lhs_module_sp(lhs.GetModule());
994f034231aSEd Maste ModuleSP rhs_module_sp(rhs.GetModule());
995f034231aSEd Maste Module *lhs_module = lhs_module_sp.get();
996f034231aSEd Maste Module *rhs_module = rhs_module_sp.get();
99714f1b3e8SDimitry Andric if (lhs_module == rhs_module) {
998f034231aSEd Maste // Addresses are in the same module, just compare the file addresses
999f034231aSEd Maste return lhs.GetFileAddress() < rhs.GetFileAddress();
100014f1b3e8SDimitry Andric } else {
1001f73363f1SDimitry Andric // The addresses are from different modules, just use the module pointer
1002f73363f1SDimitry Andric // value to get consistent ordering
1003f034231aSEd Maste return lhs_module < rhs_module;
1004f034231aSEd Maste }
1005f034231aSEd Maste }
1006f034231aSEd Maste
operator >(const Address & lhs,const Address & rhs)100714f1b3e8SDimitry Andric bool lldb_private::operator>(const Address &lhs, const Address &rhs) {
1008f034231aSEd Maste ModuleSP lhs_module_sp(lhs.GetModule());
1009f034231aSEd Maste ModuleSP rhs_module_sp(rhs.GetModule());
1010f034231aSEd Maste Module *lhs_module = lhs_module_sp.get();
1011f034231aSEd Maste Module *rhs_module = rhs_module_sp.get();
101214f1b3e8SDimitry Andric if (lhs_module == rhs_module) {
1013f034231aSEd Maste // Addresses are in the same module, just compare the file addresses
1014f034231aSEd Maste return lhs.GetFileAddress() > rhs.GetFileAddress();
101514f1b3e8SDimitry Andric } else {
1016f73363f1SDimitry Andric // The addresses are from different modules, just use the module pointer
1017f73363f1SDimitry Andric // value to get consistent ordering
1018f034231aSEd Maste return lhs_module > rhs_module;
1019f034231aSEd Maste }
1020f034231aSEd Maste }
1021f034231aSEd Maste
1022f034231aSEd Maste // The operator == checks for exact equality only (same section, same offset)
operator ==(const Address & a,const Address & rhs)102314f1b3e8SDimitry Andric bool lldb_private::operator==(const Address &a, const Address &rhs) {
102414f1b3e8SDimitry Andric return a.GetOffset() == rhs.GetOffset() && a.GetSection() == rhs.GetSection();
1025f034231aSEd Maste }
1026f3fbd1c0SDimitry Andric
1027f034231aSEd Maste // The operator != checks for exact inequality only (differing section, or
1028f034231aSEd Maste // different offset)
operator !=(const Address & a,const Address & rhs)102914f1b3e8SDimitry Andric bool lldb_private::operator!=(const Address &a, const Address &rhs) {
103014f1b3e8SDimitry Andric return a.GetOffset() != rhs.GetOffset() || a.GetSection() != rhs.GetSection();
1031f034231aSEd Maste }
1032f034231aSEd Maste
GetAddressClass() const103314f1b3e8SDimitry Andric AddressClass Address::GetAddressClass() const {
1034f034231aSEd Maste ModuleSP module_sp(GetModule());
103514f1b3e8SDimitry Andric if (module_sp) {
1036f034231aSEd Maste ObjectFile *obj_file = module_sp->GetObjectFile();
103714f1b3e8SDimitry Andric if (obj_file) {
1038ead24645SDimitry Andric // Give the symbol file a chance to add to the unified section list
1039ead24645SDimitry Andric // and to the symtab.
1040ead24645SDimitry Andric module_sp->GetSymtab();
1041f034231aSEd Maste return obj_file->GetAddressClass(GetFileAddress());
1042f034231aSEd Maste }
1043f034231aSEd Maste }
1044f73363f1SDimitry Andric return AddressClass::eUnknown;
1045f034231aSEd Maste }
1046f034231aSEd Maste
SetLoadAddress(lldb::addr_t load_addr,Target * target,bool allow_section_end)1047f1d04915SDimitry Andric bool Address::SetLoadAddress(lldb::addr_t load_addr, Target *target,
1048f1d04915SDimitry Andric bool allow_section_end) {
1049f1d04915SDimitry Andric if (target && target->GetSectionLoadList().ResolveLoadAddress(
1050f1d04915SDimitry Andric load_addr, *this, allow_section_end))
1051f034231aSEd Maste return true;
1052f034231aSEd Maste m_section_wp.reset();
1053f034231aSEd Maste m_offset = load_addr;
1054f034231aSEd Maste return false;
1055f034231aSEd Maste }
1056