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