blob: 9e6bfd85b3afdd5a5b6fafdb328255c978c32ede [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Address.cpp ---------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Core/Address.h"
Eugene Zelenko896ddd02016-03-02 01:09:03 +000011
12// C Includes
13// C++ Includes
14#include "llvm/ADT/Triple.h"
15
16// Other libraries and framework includes
17// Project includes
Zachary Turner29cb8682017-03-03 20:57:05 +000018#include "lldb/Core/DumpDataExtractor.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/Module.h"
20#include "lldb/Core/Section.h"
Greg Clayton1f746072012-08-29 21:13:06 +000021#include "lldb/Symbol/Block.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Symbol/ObjectFile.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000023#include "lldb/Symbol/SymbolVendor.h"
Greg Claytonc749eb82011-07-11 05:12:02 +000024#include "lldb/Symbol/Variable.h"
25#include "lldb/Symbol/VariableList.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000026#include "lldb/Target/ExecutionContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Target/Process.h"
Greg Claytond5944cd2013-12-06 01:12:00 +000028#include "lldb/Target/SectionLoadList.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Target/Target.h"
30
31using namespace lldb;
32using namespace lldb_private;
33
Kate Stoneb9c1b512016-09-06 20:57:50 +000034static size_t ReadBytes(ExecutionContextScope *exe_scope,
35 const Address &address, void *dst, size_t dst_len) {
36 if (exe_scope == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +000038
39 TargetSP target_sp(exe_scope->CalculateTarget());
40 if (target_sp) {
41 Error error;
42 bool prefer_file_cache = false;
43 return target_sp->ReadMemory(address, prefer_file_cache, dst, dst_len,
44 error);
45 }
46 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047}
48
Kate Stoneb9c1b512016-09-06 20:57:50 +000049static bool GetByteOrderAndAddressSize(ExecutionContextScope *exe_scope,
50 const Address &address,
51 ByteOrder &byte_order,
52 uint32_t &addr_size) {
53 byte_order = eByteOrderInvalid;
54 addr_size = 0;
55 if (exe_scope == nullptr)
56 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057
Kate Stoneb9c1b512016-09-06 20:57:50 +000058 TargetSP target_sp(exe_scope->CalculateTarget());
59 if (target_sp) {
60 byte_order = target_sp->GetArchitecture().GetByteOrder();
61 addr_size = target_sp->GetArchitecture().GetAddressByteSize();
62 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063
Kate Stoneb9c1b512016-09-06 20:57:50 +000064 if (byte_order == eByteOrderInvalid || addr_size == 0) {
65 ModuleSP module_sp(address.GetModule());
66 if (module_sp) {
67 byte_order = module_sp->GetArchitecture().GetByteOrder();
68 addr_size = module_sp->GetArchitecture().GetAddressByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000070 }
71 return byte_order != eByteOrderInvalid && addr_size != 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000072}
73
Kate Stoneb9c1b512016-09-06 20:57:50 +000074static uint64_t ReadUIntMax64(ExecutionContextScope *exe_scope,
75 const Address &address, uint32_t byte_size,
76 bool &success) {
77 uint64_t uval64 = 0;
78 if (exe_scope == nullptr || byte_size > sizeof(uint64_t)) {
79 success = false;
80 return 0;
81 }
82 uint64_t buf = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000083
Kate Stoneb9c1b512016-09-06 20:57:50 +000084 success = ReadBytes(exe_scope, address, &buf, byte_size) == byte_size;
85 if (success) {
86 ByteOrder byte_order = eByteOrderInvalid;
87 uint32_t addr_size = 0;
88 if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
89 DataExtractor data(&buf, sizeof(buf), byte_order, addr_size);
90 lldb::offset_t offset = 0;
91 uval64 = data.GetU64(&offset);
92 } else
93 success = false;
94 }
95 return uval64;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000096}
97
Kate Stoneb9c1b512016-09-06 20:57:50 +000098static bool ReadAddress(ExecutionContextScope *exe_scope,
99 const Address &address, uint32_t pointer_size,
100 Address &deref_so_addr) {
101 if (exe_scope == nullptr)
102 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103
Kate Stoneb9c1b512016-09-06 20:57:50 +0000104 bool success = false;
105 addr_t deref_addr = ReadUIntMax64(exe_scope, address, pointer_size, success);
106 if (success) {
107 ExecutionContext exe_ctx;
108 exe_scope->CalculateExecutionContext(exe_ctx);
109 // If we have any sections that are loaded, try and resolve using the
110 // section load list
111 Target *target = exe_ctx.GetTargetPtr();
112 if (target && !target->GetSectionLoadList().IsEmpty()) {
113 if (target->GetSectionLoadList().ResolveLoadAddress(deref_addr,
114 deref_so_addr))
115 return true;
116 } else {
117 // If we were not running, yet able to read an integer, we must
118 // have a module
119 ModuleSP module_sp(address.GetModule());
Greg Claytone72dfb32012-02-24 01:59:29 +0000120
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121 assert(module_sp);
122 if (module_sp->ResolveFileAddress(deref_addr, deref_so_addr))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000123 return true;
124 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125
126 // We couldn't make "deref_addr" into a section offset value, but we were
127 // able to read the address, so we return a section offset address with
128 // no section and "deref_addr" as the offset (address).
129 deref_so_addr.SetRawAddress(deref_addr);
130 return true;
131 }
132 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000133}
134
Kate Stoneb9c1b512016-09-06 20:57:50 +0000135static bool DumpUInt(ExecutionContextScope *exe_scope, const Address &address,
136 uint32_t byte_size, Stream *strm) {
137 if (exe_scope == nullptr || byte_size == 0)
138 return 0;
139 std::vector<uint8_t> buf(byte_size, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141 if (ReadBytes(exe_scope, address, &buf[0], buf.size()) == buf.size()) {
142 ByteOrder byte_order = eByteOrderInvalid;
143 uint32_t addr_size = 0;
144 if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
145 DataExtractor data(&buf.front(), buf.size(), byte_order, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146
Zachary Turner29cb8682017-03-03 20:57:05 +0000147 DumpDataExtractor(data, strm,
148 0, // Start offset in "data"
149 eFormatHex, // Print as characters
150 buf.size(), // Size of item
151 1, // Items count
152 UINT32_MAX, // num per line
153 LLDB_INVALID_ADDRESS, // base address
154 0, // bitfield bit size
155 0); // bitfield bit offset
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000156
Kate Stoneb9c1b512016-09-06 20:57:50 +0000157 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000158 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000159 }
160 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161}
162
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163static size_t ReadCStringFromMemory(ExecutionContextScope *exe_scope,
164 const Address &address, Stream *strm) {
165 if (exe_scope == nullptr)
166 return 0;
167 const size_t k_buf_len = 256;
168 char buf[k_buf_len + 1];
169 buf[k_buf_len] = '\0'; // NULL terminate
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000170
Kate Stoneb9c1b512016-09-06 20:57:50 +0000171 // Byte order and address size don't matter for C string dumping..
172 DataExtractor data(buf, sizeof(buf), endian::InlHostByteOrder(), 4);
173 size_t total_len = 0;
174 size_t bytes_read;
175 Address curr_address(address);
176 strm->PutChar('"');
177 while ((bytes_read = ReadBytes(exe_scope, curr_address, buf, k_buf_len)) >
178 0) {
179 size_t len = strlen(buf);
180 if (len == 0)
181 break;
182 if (len > bytes_read)
183 len = bytes_read;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000184
Zachary Turner29cb8682017-03-03 20:57:05 +0000185 DumpDataExtractor(data, strm,
186 0, // Start offset in "data"
187 eFormatChar, // Print as characters
188 1, // Size of item (1 byte for a char!)
189 len, // How many bytes to print?
190 UINT32_MAX, // num per line
191 LLDB_INVALID_ADDRESS, // base address
192 0, // bitfield bit size
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000193
Zachary Turner29cb8682017-03-03 20:57:05 +0000194 0); // bitfield bit offset
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000195
Kate Stoneb9c1b512016-09-06 20:57:50 +0000196 total_len += bytes_read;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000197
Kate Stoneb9c1b512016-09-06 20:57:50 +0000198 if (len < k_buf_len)
199 break;
200 curr_address.SetOffset(curr_address.GetOffset() + bytes_read);
201 }
202 strm->PutChar('"');
203 return total_len;
204}
205
206Address::Address(lldb::addr_t abs_addr) : m_section_wp(), m_offset(abs_addr) {}
207
208Address::Address(addr_t address, const SectionList *section_list)
209 : m_section_wp(), m_offset(LLDB_INVALID_ADDRESS) {
210 ResolveAddressUsingFileSections(address, section_list);
211}
212
213const Address &Address::operator=(const Address &rhs) {
214 if (this != &rhs) {
215 m_section_wp = rhs.m_section_wp;
216 m_offset = rhs.m_offset;
217 }
218 return *this;
219}
220
221bool Address::ResolveAddressUsingFileSections(addr_t file_addr,
222 const SectionList *section_list) {
223 if (section_list) {
224 SectionSP section_sp(
225 section_list->FindSectionContainingFileAddress(file_addr));
226 m_section_wp = section_sp;
227 if (section_sp) {
228 assert(section_sp->ContainsFileAddress(file_addr));
229 m_offset = file_addr - section_sp->GetFileAddress();
230 return true; // Successfully transformed addr into a section offset
231 // address
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233 }
234 m_offset = file_addr;
235 return false; // Failed to resolve this address to a section offset value
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000236}
237
Kate Stoneb9c1b512016-09-06 20:57:50 +0000238ModuleSP Address::GetModule() const {
239 lldb::ModuleSP module_sp;
240 SectionSP section_sp(GetSection());
241 if (section_sp)
242 module_sp = section_sp->GetModule();
243 return module_sp;
Greg Claytone72dfb32012-02-24 01:59:29 +0000244}
245
Kate Stoneb9c1b512016-09-06 20:57:50 +0000246addr_t Address::GetFileAddress() const {
247 SectionSP section_sp(GetSection());
248 if (section_sp) {
249 addr_t sect_file_addr = section_sp->GetFileAddress();
250 if (sect_file_addr == LLDB_INVALID_ADDRESS) {
251 // Section isn't resolved, we can't return a valid file address
252 return LLDB_INVALID_ADDRESS;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000253 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254 // We have a valid file range, so we can return the file based
255 // address by adding the file base address to our offset
256 return sect_file_addr + m_offset;
257 } else if (SectionWasDeletedPrivate()) {
258 // Used to have a valid section but it got deleted so the
259 // offset doesn't mean anything without the section
260 return LLDB_INVALID_ADDRESS;
261 }
262 // No section, we just return the offset since it is the value in this case
263 return m_offset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000264}
265
Kate Stoneb9c1b512016-09-06 20:57:50 +0000266addr_t Address::GetLoadAddress(Target *target) const {
267 SectionSP section_sp(GetSection());
268 if (section_sp) {
269 if (target) {
270 addr_t sect_load_addr = section_sp->GetLoadBaseAddress(target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000271
Kate Stoneb9c1b512016-09-06 20:57:50 +0000272 if (sect_load_addr != LLDB_INVALID_ADDRESS) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000273 // We have a valid file range, so we can return the file based
274 // address by adding the file base address to our offset
Kate Stoneb9c1b512016-09-06 20:57:50 +0000275 return sect_load_addr + m_offset;
276 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000277 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000278 } else if (SectionWasDeletedPrivate()) {
279 // Used to have a valid section but it got deleted so the
280 // offset doesn't mean anything without the section
Greg Claytonf5e56de2010-09-14 23:36:40 +0000281 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000282 } else {
283 // We don't have a section so the offset is the load address
284 return m_offset;
285 }
286 // The section isn't resolved or an invalid target was passed in
287 // so we can't return a valid load address.
288 return LLDB_INVALID_ADDRESS;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000289}
290
Kate Stoneb9c1b512016-09-06 20:57:50 +0000291addr_t Address::GetCallableLoadAddress(Target *target, bool is_indirect) const {
292 addr_t code_addr = LLDB_INVALID_ADDRESS;
293
294 if (is_indirect && target) {
295 ProcessSP processSP = target->GetProcessSP();
296 Error error;
297 if (processSP) {
298 code_addr = processSP->ResolveIndirectFunction(this, error);
299 if (!error.Success())
300 code_addr = LLDB_INVALID_ADDRESS;
Matt Kopec00049b82013-02-27 20:13:38 +0000301 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000302 } else {
303 code_addr = GetLoadAddress(target);
304 }
305
306 if (code_addr == LLDB_INVALID_ADDRESS)
307 return code_addr;
308
309 if (target)
310 return target->GetCallableLoadAddress(code_addr, GetAddressClass());
311 return code_addr;
312}
313
314bool Address::SetCallableLoadAddress(lldb::addr_t load_addr, Target *target) {
315 if (SetLoadAddress(load_addr, target)) {
Greg Claytonf3ef3d22011-05-22 22:46:53 +0000316 if (target)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000317 m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000318 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000319 }
320 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321}
322
Kate Stoneb9c1b512016-09-06 20:57:50 +0000323addr_t Address::GetOpcodeLoadAddress(Target *target,
324 AddressClass addr_class) const {
325 addr_t code_addr = GetLoadAddress(target);
326 if (code_addr != LLDB_INVALID_ADDRESS) {
327 if (addr_class == eAddressClassInvalid)
328 addr_class = GetAddressClass();
329 code_addr = target->GetOpcodeLoadAddress(code_addr, addr_class);
330 }
331 return code_addr;
Greg Claytonb35db632013-11-09 00:03:31 +0000332}
333
Kate Stoneb9c1b512016-09-06 20:57:50 +0000334bool Address::SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target,
335 AddressClass addr_class) {
336 if (SetLoadAddress(load_addr, target)) {
337 if (target) {
338 if (addr_class == eAddressClassInvalid)
339 addr_class = GetAddressClass();
340 m_offset = target->GetOpcodeLoadAddress(m_offset, addr_class);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000342 return true;
343 }
344 return false;
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000345}
346
Kate Stoneb9c1b512016-09-06 20:57:50 +0000347bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
348 DumpStyle fallback_style, uint32_t addr_size) const {
349 // If the section was nullptr, only load address is going to work unless we
350 // are
351 // trying to deref a pointer
352 SectionSP section_sp(GetSection());
353 if (!section_sp && style != DumpStyleResolvedPointerDescription)
354 style = DumpStyleLoadAddress;
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000355
Kate Stoneb9c1b512016-09-06 20:57:50 +0000356 ExecutionContext exe_ctx(exe_scope);
357 Target *target = exe_ctx.GetTargetPtr();
358 // If addr_byte_size is UINT32_MAX, then determine the correct address
359 // byte size for the process or default to the size of addr_t
360 if (addr_size == UINT32_MAX) {
361 if (target)
362 addr_size = target->GetArchitecture().GetAddressByteSize();
363 else
364 addr_size = sizeof(addr_t);
365 }
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000366
Kate Stoneb9c1b512016-09-06 20:57:50 +0000367 Address so_addr;
368 switch (style) {
369 case DumpStyleInvalid:
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000370 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000371
372 case DumpStyleSectionNameOffset:
373 if (section_sp) {
374 section_sp->DumpName(s);
375 s->Printf(" + %" PRIu64, m_offset);
376 } else {
377 s->Address(m_offset, addr_size);
378 }
379 break;
380
381 case DumpStyleSectionPointerOffset:
382 s->Printf("(Section *)%p + ", static_cast<void *>(section_sp.get()));
383 s->Address(m_offset, addr_size);
384 break;
385
386 case DumpStyleModuleWithFileAddress:
387 if (section_sp) {
388 ModuleSP module_sp = section_sp->GetModule();
389 if (module_sp)
390 s->Printf("%s[", module_sp->GetFileSpec().GetFilename().AsCString(
391 "<Unknown>"));
392 else
393 s->Printf("%s[", "<Unknown>");
394 }
395 LLVM_FALLTHROUGH;
396 case DumpStyleFileAddress: {
397 addr_t file_addr = GetFileAddress();
398 if (file_addr == LLDB_INVALID_ADDRESS) {
399 if (fallback_style != DumpStyleInvalid)
400 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
401 return false;
402 }
403 s->Address(file_addr, addr_size);
404 if (style == DumpStyleModuleWithFileAddress && section_sp)
405 s->PutChar(']');
406 } break;
407
408 case DumpStyleLoadAddress: {
409 addr_t load_addr = GetLoadAddress(target);
410
411 /*
412 * MIPS:
413 * Display address in compressed form for MIPS16 or microMIPS
414 * if the address belongs to eAddressClassCodeAlternateISA.
415 */
416 if (target) {
417 const llvm::Triple::ArchType llvm_arch =
418 target->GetArchitecture().GetMachine();
419 if (llvm_arch == llvm::Triple::mips ||
420 llvm_arch == llvm::Triple::mipsel ||
421 llvm_arch == llvm::Triple::mips64 ||
422 llvm_arch == llvm::Triple::mips64el)
423 load_addr = GetCallableLoadAddress(target);
424 }
425
426 if (load_addr == LLDB_INVALID_ADDRESS) {
427 if (fallback_style != DumpStyleInvalid)
428 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
429 return false;
430 }
431 s->Address(load_addr, addr_size);
432 } break;
433
434 case DumpStyleResolvedDescription:
435 case DumpStyleResolvedDescriptionNoModule:
436 case DumpStyleResolvedDescriptionNoFunctionArguments:
437 case DumpStyleNoFunctionName:
438 if (IsSectionOffset()) {
439 uint32_t pointer_size = 4;
440 ModuleSP module_sp(GetModule());
441 if (target)
442 pointer_size = target->GetArchitecture().GetAddressByteSize();
443 else if (module_sp)
444 pointer_size = module_sp->GetArchitecture().GetAddressByteSize();
445
446 bool showed_info = false;
447 if (section_sp) {
448 SectionType sect_type = section_sp->GetType();
449 switch (sect_type) {
450 case eSectionTypeData:
451 if (module_sp) {
452 SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
453 if (sym_vendor) {
454 Symtab *symtab = sym_vendor->GetSymtab();
455 if (symtab) {
456 const addr_t file_Addr = GetFileAddress();
457 Symbol *symbol =
458 symtab->FindSymbolContainingFileAddress(file_Addr);
459 if (symbol) {
460 const char *symbol_name = symbol->GetName().AsCString();
461 if (symbol_name) {
462 s->PutCString(symbol_name);
463 addr_t delta =
464 file_Addr - symbol->GetAddressRef().GetFileAddress();
465 if (delta)
466 s->Printf(" + %" PRIu64, delta);
467 showed_info = true;
468 }
469 }
470 }
471 }
472 }
473 break;
474
475 case eSectionTypeDataCString:
476 // Read the C string from memory and display it
477 showed_info = true;
478 ReadCStringFromMemory(exe_scope, *this, s);
479 break;
480
481 case eSectionTypeDataCStringPointers:
482 if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
483#if VERBOSE_OUTPUT
484 s->PutCString("(char *)");
485 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
486 DumpStyleFileAddress);
487 s->PutCString(": ");
488#endif
489 showed_info = true;
490 ReadCStringFromMemory(exe_scope, so_addr, s);
491 }
492 break;
493
494 case eSectionTypeDataObjCMessageRefs:
495 if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
496 if (target && so_addr.IsSectionOffset()) {
497 SymbolContext func_sc;
498 target->GetImages().ResolveSymbolContextForAddress(
499 so_addr, eSymbolContextEverything, func_sc);
500 if (func_sc.function != nullptr || func_sc.symbol != nullptr) {
501 showed_info = true;
502#if VERBOSE_OUTPUT
503 s->PutCString("(objc_msgref *) -> { (func*)");
504 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
505 DumpStyleFileAddress);
506#else
507 s->PutCString("{ ");
508#endif
509 Address cstr_addr(*this);
510 cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
511 func_sc.DumpStopContext(s, exe_scope, so_addr, true, true,
512 false, true, true);
513 if (ReadAddress(exe_scope, cstr_addr, pointer_size, so_addr)) {
514#if VERBOSE_OUTPUT
515 s->PutCString("), (char *)");
516 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
517 DumpStyleFileAddress);
518 s->PutCString(" (");
519#else
520 s->PutCString(", ");
521#endif
522 ReadCStringFromMemory(exe_scope, so_addr, s);
523 }
524#if VERBOSE_OUTPUT
525 s->PutCString(") }");
526#else
527 s->PutCString(" }");
528#endif
529 }
530 }
531 }
532 break;
533
534 case eSectionTypeDataObjCCFStrings: {
535 Address cfstring_data_addr(*this);
536 cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() +
537 (2 * pointer_size));
538 if (ReadAddress(exe_scope, cfstring_data_addr, pointer_size,
539 so_addr)) {
540#if VERBOSE_OUTPUT
541 s->PutCString("(CFString *) ");
542 cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
543 DumpStyleFileAddress);
544 s->PutCString(" -> @");
545#else
546 s->PutChar('@');
547#endif
548 if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
549 showed_info = true;
550 }
551 } break;
552
553 case eSectionTypeData4:
554 // Read the 4 byte data and display it
555 showed_info = true;
556 s->PutCString("(uint32_t) ");
557 DumpUInt(exe_scope, *this, 4, s);
558 break;
559
560 case eSectionTypeData8:
561 // Read the 8 byte data and display it
562 showed_info = true;
563 s->PutCString("(uint64_t) ");
564 DumpUInt(exe_scope, *this, 8, s);
565 break;
566
567 case eSectionTypeData16:
568 // Read the 16 byte data and display it
569 showed_info = true;
570 s->PutCString("(uint128_t) ");
571 DumpUInt(exe_scope, *this, 16, s);
572 break;
573
574 case eSectionTypeDataPointers:
575 // Read the pointer data and display it
576 if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
577 s->PutCString("(void *)");
578 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
579 DumpStyleFileAddress);
580
581 showed_info = true;
582 if (so_addr.IsSectionOffset()) {
583 SymbolContext pointer_sc;
584 if (target) {
585 target->GetImages().ResolveSymbolContextForAddress(
586 so_addr, eSymbolContextEverything, pointer_sc);
587 if (pointer_sc.function != nullptr ||
588 pointer_sc.symbol != nullptr) {
589 s->PutCString(": ");
590 pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false,
591 false, true, true);
592 }
593 }
594 }
595 }
596 break;
597
598 default:
599 break;
600 }
601 }
602
603 if (!showed_info) {
604 if (module_sp) {
605 SymbolContext sc;
606 module_sp->ResolveSymbolContextForAddress(
607 *this, eSymbolContextEverything, sc);
608 if (sc.function || sc.symbol) {
609 bool show_stop_context = true;
610 const bool show_module = (style == DumpStyleResolvedDescription);
611 const bool show_fullpaths = false;
612 const bool show_inlined_frames = true;
613 const bool show_function_arguments =
614 (style != DumpStyleResolvedDescriptionNoFunctionArguments);
615 const bool show_function_name = (style != DumpStyleNoFunctionName);
616 if (sc.function == nullptr && sc.symbol != nullptr) {
617 // If we have just a symbol make sure it is in the right section
618 if (sc.symbol->ValueIsAddress()) {
619 if (sc.symbol->GetAddressRef().GetSection() != GetSection()) {
620 // don't show the module if the symbol is a trampoline symbol
621 show_stop_context = false;
622 }
623 }
624 }
625 if (show_stop_context) {
626 // We have a function or a symbol from the same
627 // sections as this address.
628 sc.DumpStopContext(s, exe_scope, *this, show_fullpaths,
629 show_module, show_inlined_frames,
630 show_function_arguments, show_function_name);
631 } else {
632 // We found a symbol but it was in a different
633 // section so it isn't the symbol we should be
634 // showing, just show the section name + offset
635 Dump(s, exe_scope, DumpStyleSectionNameOffset);
636 }
637 }
638 }
639 }
640 } else {
641 if (fallback_style != DumpStyleInvalid)
642 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
643 return false;
644 }
645 break;
646
647 case DumpStyleDetailedSymbolContext:
648 if (IsSectionOffset()) {
649 ModuleSP module_sp(GetModule());
650 if (module_sp) {
651 SymbolContext sc;
652 module_sp->ResolveSymbolContextForAddress(
653 *this, eSymbolContextEverything | eSymbolContextVariable, sc);
654 if (sc.symbol) {
655 // If we have just a symbol make sure it is in the same section
656 // as our address. If it isn't, then we might have just found
657 // the last symbol that came before the address that we are
658 // looking up that has nothing to do with our address lookup.
659 if (sc.symbol->ValueIsAddress() &&
660 sc.symbol->GetAddressRef().GetSection() != GetSection())
661 sc.symbol = nullptr;
662 }
663 sc.GetDescription(s, eDescriptionLevelBrief, target);
664
665 if (sc.block) {
666 bool can_create = true;
667 bool get_parent_variables = true;
668 bool stop_if_block_is_inlined_function = false;
669 VariableList variable_list;
670 sc.block->AppendVariables(can_create, get_parent_variables,
671 stop_if_block_is_inlined_function,
672 [](Variable *) { return true; },
673 &variable_list);
674
675 const size_t num_variables = variable_list.GetSize();
676 for (size_t var_idx = 0; var_idx < num_variables; ++var_idx) {
677 Variable *var = variable_list.GetVariableAtIndex(var_idx).get();
678 if (var && var->LocationIsValidForAddress(*this)) {
679 s->Indent();
680 s->Printf(" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"",
681 var->GetID(), var->GetName().GetCString());
682 Type *type = var->GetType();
683 if (type)
684 s->Printf(", type = \"%s\"", type->GetName().GetCString());
685 else
686 s->PutCString(", type = <unknown>");
687 s->PutCString(", location = ");
688 var->DumpLocationForAddress(s, *this);
689 s->PutCString(", decl = ");
690 var->GetDeclaration().DumpStopContext(s, false);
691 s->EOL();
692 }
693 }
694 }
695 }
696 } else {
697 if (fallback_style != DumpStyleInvalid)
698 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
699 return false;
700 }
701 break;
702
703 case DumpStyleResolvedPointerDescription: {
704 Process *process = exe_ctx.GetProcessPtr();
705 if (process) {
706 addr_t load_addr = GetLoadAddress(target);
707 if (load_addr != LLDB_INVALID_ADDRESS) {
708 Error memory_error;
709 addr_t dereferenced_load_addr =
710 process->ReadPointerFromMemory(load_addr, memory_error);
711 if (dereferenced_load_addr != LLDB_INVALID_ADDRESS) {
712 Address dereferenced_addr;
713 if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr,
714 target)) {
715 StreamString strm;
716 if (dereferenced_addr.Dump(&strm, exe_scope,
717 DumpStyleResolvedDescription,
718 DumpStyleInvalid, addr_size)) {
719 s->Address(dereferenced_load_addr, addr_size, " -> ", " ");
Zachary Turnerc1564272016-11-16 21:15:24 +0000720 s->Write(strm.GetString().data(), strm.GetSize());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000721 return true;
722 }
723 }
724 }
725 }
726 }
727 if (fallback_style != DumpStyleInvalid)
728 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
729 return false;
730 } break;
731 }
732
733 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000734}
735
Kate Stoneb9c1b512016-09-06 20:57:50 +0000736bool Address::SectionWasDeleted() const {
737 if (GetSection())
738 return false;
739 return SectionWasDeletedPrivate();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000740}
741
Kate Stoneb9c1b512016-09-06 20:57:50 +0000742bool Address::SectionWasDeletedPrivate() const {
743 lldb::SectionWP empty_section_wp;
744
745 // If either call to "std::weak_ptr::owner_before(...) value returns true,
746 // this
747 // indicates that m_section_wp once contained (possibly still does) a
748 // reference
749 // to a valid shared pointer. This helps us know if we had a valid reference
750 // to
751 // a section which is now invalid because the module it was in was
752 // unloaded/deleted,
753 // or if the address doesn't have a valid reference to a section.
754 return empty_section_wp.owner_before(m_section_wp) ||
755 m_section_wp.owner_before(empty_section_wp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000756}
757
Kate Stoneb9c1b512016-09-06 20:57:50 +0000758uint32_t Address::CalculateSymbolContext(SymbolContext *sc,
759 uint32_t resolve_scope) const {
760 sc->Clear(false);
761 // Absolute addresses don't have enough information to reconstruct even their
762 // target.
763
764 SectionSP section_sp(GetSection());
765 if (section_sp) {
766 ModuleSP module_sp(section_sp->GetModule());
767 if (module_sp) {
768 sc->module_sp = module_sp;
769 if (sc->module_sp)
770 return sc->module_sp->ResolveSymbolContextForAddress(
771 *this, resolve_scope, *sc);
772 }
773 }
774 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000775}
776
Kate Stoneb9c1b512016-09-06 20:57:50 +0000777ModuleSP Address::CalculateSymbolContextModule() const {
778 SectionSP section_sp(GetSection());
779 if (section_sp)
780 return section_sp->GetModule();
781 return ModuleSP();
782}
783
784CompileUnit *Address::CalculateSymbolContextCompileUnit() const {
785 SectionSP section_sp(GetSection());
786 if (section_sp) {
787 SymbolContext sc;
788 sc.module_sp = section_sp->GetModule();
789 if (sc.module_sp) {
790 sc.module_sp->ResolveSymbolContextForAddress(*this,
791 eSymbolContextCompUnit, sc);
792 return sc.comp_unit;
793 }
794 }
795 return nullptr;
796}
797
798Function *Address::CalculateSymbolContextFunction() const {
799 SectionSP section_sp(GetSection());
800 if (section_sp) {
801 SymbolContext sc;
802 sc.module_sp = section_sp->GetModule();
803 if (sc.module_sp) {
804 sc.module_sp->ResolveSymbolContextForAddress(*this,
805 eSymbolContextFunction, sc);
806 return sc.function;
807 }
808 }
809 return nullptr;
810}
811
812Block *Address::CalculateSymbolContextBlock() const {
813 SectionSP section_sp(GetSection());
814 if (section_sp) {
815 SymbolContext sc;
816 sc.module_sp = section_sp->GetModule();
817 if (sc.module_sp) {
818 sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextBlock,
819 sc);
820 return sc.block;
821 }
822 }
823 return nullptr;
824}
825
826Symbol *Address::CalculateSymbolContextSymbol() const {
827 SectionSP section_sp(GetSection());
828 if (section_sp) {
829 SymbolContext sc;
830 sc.module_sp = section_sp->GetModule();
831 if (sc.module_sp) {
832 sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextSymbol,
833 sc);
834 return sc.symbol;
835 }
836 }
837 return nullptr;
838}
839
840bool Address::CalculateSymbolContextLineEntry(LineEntry &line_entry) const {
841 SectionSP section_sp(GetSection());
842 if (section_sp) {
843 SymbolContext sc;
844 sc.module_sp = section_sp->GetModule();
845 if (sc.module_sp) {
846 sc.module_sp->ResolveSymbolContextForAddress(*this,
847 eSymbolContextLineEntry, sc);
848 if (sc.line_entry.IsValid()) {
849 line_entry = sc.line_entry;
850 return true;
851 }
852 }
853 }
854 line_entry.Clear();
855 return false;
856}
857
858int Address::CompareFileAddress(const Address &a, const Address &b) {
859 addr_t a_file_addr = a.GetFileAddress();
860 addr_t b_file_addr = b.GetFileAddress();
861 if (a_file_addr < b_file_addr)
862 return -1;
863 if (a_file_addr > b_file_addr)
864 return +1;
865 return 0;
866}
867
868int Address::CompareLoadAddress(const Address &a, const Address &b,
869 Target *target) {
870 assert(target != nullptr);
871 addr_t a_load_addr = a.GetLoadAddress(target);
872 addr_t b_load_addr = b.GetLoadAddress(target);
873 if (a_load_addr < b_load_addr)
874 return -1;
875 if (a_load_addr > b_load_addr)
876 return +1;
877 return 0;
878}
879
880int Address::CompareModulePointerAndOffset(const Address &a, const Address &b) {
881 ModuleSP a_module_sp(a.GetModule());
882 ModuleSP b_module_sp(b.GetModule());
883 Module *a_module = a_module_sp.get();
884 Module *b_module = b_module_sp.get();
885 if (a_module < b_module)
886 return -1;
887 if (a_module > b_module)
888 return +1;
889 // Modules are the same, just compare the file address since they should
890 // be unique
891 addr_t a_file_addr = a.GetFileAddress();
892 addr_t b_file_addr = b.GetFileAddress();
893 if (a_file_addr < b_file_addr)
894 return -1;
895 if (a_file_addr > b_file_addr)
896 return +1;
897 return 0;
898}
899
900size_t Address::MemorySize() const {
901 // Noting special for the memory size of a single Address object,
902 // it is just the size of itself.
903 return sizeof(Address);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000904}
905
Greg Claytonb0848c52011-01-08 00:05:12 +0000906//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000907// NOTE: Be careful using this operator. It can correctly compare two
908// addresses from the same Module correctly. It can't compare two
Greg Claytonb0848c52011-01-08 00:05:12 +0000909// addresses from different modules in any meaningful way, but it will
910// compare the module pointers.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000911//
Greg Claytonb0848c52011-01-08 00:05:12 +0000912// To sum things up:
913// - works great for addresses within the same module
914// - it works for addresses across multiple modules, but don't expect the
915// address results to make much sense
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000916//
Kate Stoneb9c1b512016-09-06 20:57:50 +0000917// This basically lets Address objects be used in ordered collection
Greg Claytonb0848c52011-01-08 00:05:12 +0000918// classes.
919//----------------------------------------------------------------------
920
Kate Stoneb9c1b512016-09-06 20:57:50 +0000921bool lldb_private::operator<(const Address &lhs, const Address &rhs) {
922 ModuleSP lhs_module_sp(lhs.GetModule());
923 ModuleSP rhs_module_sp(rhs.GetModule());
924 Module *lhs_module = lhs_module_sp.get();
925 Module *rhs_module = rhs_module_sp.get();
926 if (lhs_module == rhs_module) {
927 // Addresses are in the same module, just compare the file addresses
928 return lhs.GetFileAddress() < rhs.GetFileAddress();
929 } else {
930 // The addresses are from different modules, just use the module
931 // pointer value to get consistent ordering
932 return lhs_module < rhs_module;
933 }
Greg Claytonb0848c52011-01-08 00:05:12 +0000934}
935
Kate Stoneb9c1b512016-09-06 20:57:50 +0000936bool lldb_private::operator>(const Address &lhs, const Address &rhs) {
937 ModuleSP lhs_module_sp(lhs.GetModule());
938 ModuleSP rhs_module_sp(rhs.GetModule());
939 Module *lhs_module = lhs_module_sp.get();
940 Module *rhs_module = rhs_module_sp.get();
941 if (lhs_module == rhs_module) {
942 // Addresses are in the same module, just compare the file addresses
943 return lhs.GetFileAddress() > rhs.GetFileAddress();
944 } else {
945 // The addresses are from different modules, just use the module
946 // pointer value to get consistent ordering
947 return lhs_module > rhs_module;
948 }
Greg Claytonb0848c52011-01-08 00:05:12 +0000949}
950
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000951// The operator == checks for exact equality only (same section, same offset)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000952bool lldb_private::operator==(const Address &a, const Address &rhs) {
953 return a.GetOffset() == rhs.GetOffset() && a.GetSection() == rhs.GetSection();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000954}
Eugene Zelenko896ddd02016-03-02 01:09:03 +0000955
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000956// The operator != checks for exact inequality only (differing section, or
957// different offset)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000958bool lldb_private::operator!=(const Address &a, const Address &rhs) {
959 return a.GetOffset() != rhs.GetOffset() || a.GetSection() != rhs.GetSection();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000960}
961
Kate Stoneb9c1b512016-09-06 20:57:50 +0000962AddressClass Address::GetAddressClass() const {
963 ModuleSP module_sp(GetModule());
964 if (module_sp) {
965 ObjectFile *obj_file = module_sp->GetObjectFile();
966 if (obj_file) {
967 // Give the symbol vendor a chance to add to the unified section list.
968 module_sp->GetSymbolVendor();
969 return obj_file->GetAddressClass(GetFileAddress());
Greg Claytonded470d2011-03-19 01:12:21 +0000970 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000971 }
972 return eAddressClassUnknown;
Greg Claytonded470d2011-03-19 01:12:21 +0000973}
Greg Claytoncd482e32011-05-18 01:58:14 +0000974
Kate Stoneb9c1b512016-09-06 20:57:50 +0000975bool Address::SetLoadAddress(lldb::addr_t load_addr, Target *target) {
976 if (target &&
977 target->GetSectionLoadList().ResolveLoadAddress(load_addr, *this))
978 return true;
979 m_section_wp.reset();
980 m_offset = load_addr;
981 return false;
Greg Claytoncd482e32011-05-18 01:58:14 +0000982}