blob: 120ae5e4aa7cfc1a2750c49b2fa80a68570df2f1 [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"
11#include "lldb/Core/Module.h"
12#include "lldb/Core/Section.h"
13#include "lldb/Symbol/ObjectFile.h"
Greg Claytonc749eb82011-07-11 05:12:02 +000014#include "lldb/Symbol/Variable.h"
15#include "lldb/Symbol/VariableList.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000016#include "lldb/Target/ExecutionContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "lldb/Target/Process.h"
18#include "lldb/Target/Target.h"
19
Greg Clayton3f5c08f2011-05-18 22:01:49 +000020#include "llvm/ADT/Triple.h"
21
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022using namespace lldb;
23using namespace lldb_private;
24
25static size_t
26ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst, size_t dst_len)
27{
28 if (exe_scope == NULL)
29 return 0;
30
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031 Target *target = exe_scope->CalculateTarget();
32 if (target)
33 {
34 Error error;
Greg Claytondb598232011-01-07 01:57:07 +000035 bool prefer_file_cache = false;
36 return target->ReadMemory (address, prefer_file_cache, dst, dst_len, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037 }
38 return 0;
39}
40
41static bool
42GetByteOrderAndAddressSize (ExecutionContextScope *exe_scope, const Address &address, ByteOrder& byte_order, uint32_t& addr_size)
43{
44 byte_order = eByteOrderInvalid;
45 addr_size = 0;
46 if (exe_scope == NULL)
47 return false;
48
Greg Clayton514487e2011-02-15 21:59:32 +000049 Target *target = exe_scope->CalculateTarget();
50 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051 {
Greg Clayton514487e2011-02-15 21:59:32 +000052 byte_order = target->GetArchitecture().GetByteOrder();
53 addr_size = target->GetArchitecture().GetAddressByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054 }
55
56 if (byte_order == eByteOrderInvalid || addr_size == 0)
57 {
Greg Claytone1cd1be2012-01-29 20:56:30 +000058 Module *module = address.GetModulePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059 if (module)
60 {
Greg Clayton514487e2011-02-15 21:59:32 +000061 byte_order = module->GetArchitecture().GetByteOrder();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000062 addr_size = module->GetArchitecture().GetAddressByteSize();
63 }
64 }
65 return byte_order != eByteOrderInvalid && addr_size != 0;
66}
67
68static uint64_t
69ReadUIntMax64 (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, bool &success)
70{
71 uint64_t uval64 = 0;
72 if (exe_scope == NULL || byte_size > sizeof(uint64_t))
73 {
74 success = false;
75 return 0;
76 }
Johnny Chen40e35922011-08-25 17:40:39 +000077 uint64_t buf = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078
79 success = ReadBytes (exe_scope, address, &buf, byte_size) == byte_size;
80 if (success)
81 {
82 ByteOrder byte_order = eByteOrderInvalid;
83 uint32_t addr_size = 0;
84 if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size))
85 {
86 DataExtractor data (&buf, sizeof(buf), byte_order, addr_size);
87 uint32_t offset = 0;
88 uval64 = data.GetU64(&offset);
89 }
90 else
91 success = false;
92 }
93 return uval64;
94}
95
96static bool
97ReadAddress (ExecutionContextScope *exe_scope, const Address &address, uint32_t pointer_size, Address &deref_so_addr)
98{
99 if (exe_scope == NULL)
100 return false;
101
102
103 bool success = false;
104 addr_t deref_addr = ReadUIntMax64 (exe_scope, address, pointer_size, success);
105 if (success)
106 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000107 ExecutionContext exe_ctx;
Greg Clayton0603aa92010-10-04 01:05:56 +0000108 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Claytonf5e56de2010-09-14 23:36:40 +0000109 // If we have any sections that are loaded, try and resolve using the
110 // section load list
Greg Claytonc14ee322011-09-22 04:58:26 +0000111 Target *target = exe_ctx.GetTargetPtr();
112 if (target && !target->GetSectionLoadList().IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000113 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000114 if (target->GetSectionLoadList().ResolveLoadAddress (deref_addr, deref_so_addr))
Greg Claytonf5e56de2010-09-14 23:36:40 +0000115 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000116 }
117 else
118 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000119 // If we were not running, yet able to read an integer, we must
120 // have a module
Greg Claytone1cd1be2012-01-29 20:56:30 +0000121 Module *module = address.GetModulePtr();
Greg Claytonf5e56de2010-09-14 23:36:40 +0000122 assert (module);
123 if (module->ResolveFileAddress(deref_addr, deref_so_addr))
124 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000125 }
Greg Claytonf5e56de2010-09-14 23:36:40 +0000126
127 // We couldn't make "deref_addr" into a section offset value, but we were
128 // able to read the address, so we return a section offset address with
129 // no section and "deref_addr" as the offset (address).
130 deref_so_addr.SetSection(NULL);
131 deref_so_addr.SetOffset(deref_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000132 return true;
133 }
134 return false;
135}
136
137static bool
138DumpUInt (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, Stream* strm)
139{
Greg Clayton471b31c2010-07-20 22:52:08 +0000140 if (exe_scope == NULL || byte_size == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000141 return 0;
142 std::vector<uint8_t> buf(byte_size, 0);
143
144 if (ReadBytes (exe_scope, address, &buf[0], buf.size()) == buf.size())
145 {
146 ByteOrder byte_order = eByteOrderInvalid;
147 uint32_t addr_size = 0;
148 if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size))
149 {
Greg Clayton471b31c2010-07-20 22:52:08 +0000150 DataExtractor data (&buf.front(), buf.size(), byte_order, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000151
152 data.Dump (strm,
153 0, // Start offset in "data"
154 eFormatHex, // Print as characters
155 buf.size(), // Size of item
156 1, // Items count
157 UINT32_MAX, // num per line
158 LLDB_INVALID_ADDRESS,// base address
159 0, // bitfield bit size
160 0); // bitfield bit offset
161
162 return true;
163 }
164 }
165 return false;
166}
167
168
169static size_t
170ReadCStringFromMemory (ExecutionContextScope *exe_scope, const Address &address, Stream *strm)
171{
172 if (exe_scope == NULL)
173 return 0;
174 const size_t k_buf_len = 256;
175 char buf[k_buf_len+1];
176 buf[k_buf_len] = '\0'; // NULL terminate
177
Greg Clayton710dd5a2011-01-08 20:28:42 +0000178 // Byte order and address size don't matter for C string dumping..
Greg Clayton7fb56d02011-02-01 01:31:41 +0000179 DataExtractor data (buf, sizeof(buf), lldb::endian::InlHostByteOrder(), 4);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000180 size_t total_len = 0;
181 size_t bytes_read;
182 Address curr_address(address);
183 strm->PutChar ('"');
184 while ((bytes_read = ReadBytes (exe_scope, curr_address, buf, k_buf_len)) > 0)
185 {
186 size_t len = strlen(buf);
187 if (len == 0)
188 break;
189 if (len > bytes_read)
190 len = bytes_read;
191
192 data.Dump (strm,
193 0, // Start offset in "data"
194 eFormatChar, // Print as characters
195 1, // Size of item (1 byte for a char!)
196 len, // How many bytes to print?
197 UINT32_MAX, // num per line
198 LLDB_INVALID_ADDRESS,// base address
199 0, // bitfield bit size
200
201 0); // bitfield bit offset
202
203 total_len += bytes_read;
204
205 if (len < k_buf_len)
206 break;
207 curr_address.SetOffset (curr_address.GetOffset() + bytes_read);
208 }
209 strm->PutChar ('"');
210 return total_len;
211}
212
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000213Address::Address (addr_t address, const SectionList * sections) :
214 m_section (NULL),
215 m_offset (LLDB_INVALID_ADDRESS)
216{
217 ResolveAddressUsingFileSections(address, sections);
218}
219
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000220const Address&
221Address::operator= (const Address& rhs)
222{
223 if (this != &rhs)
224 {
225 m_section = rhs.m_section;
226 m_offset = rhs.m_offset;
227 }
228 return *this;
229}
230
231bool
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232Address::ResolveAddressUsingFileSections (addr_t addr, const SectionList *sections)
233{
234 if (sections)
235 m_section = sections->FindSectionContainingFileAddress(addr).get();
236 else
237 m_section = NULL;
238
239 if (m_section != NULL)
240 {
241 assert( m_section->ContainsFileAddress(addr) );
242 m_offset = addr - m_section->GetFileAddress();
243 return true; // Successfully transformed addr into a section offset address
244 }
245
246 m_offset = addr;
247 return false; // Failed to resolve this address to a section offset value
248}
249
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250Module *
Greg Claytone1cd1be2012-01-29 20:56:30 +0000251Address::GetModulePtr () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000252{
253 if (m_section)
254 return m_section->GetModule();
255 return NULL;
256}
257
Greg Claytone1cd1be2012-01-29 20:56:30 +0000258ModuleSP
259Address::GetModuleSP () const
260{
261 lldb::ModuleSP module_sp;
262 if (m_section)
263 {
264 Module *module = m_section->GetModule();
265 if (module)
266 module_sp = module->shared_from_this();
267 }
268 return module_sp;
269}
270
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000271addr_t
272Address::GetFileAddress () const
273{
274 if (m_section != NULL)
275 {
276 addr_t sect_file_addr = m_section->GetFileAddress();
277 if (sect_file_addr == LLDB_INVALID_ADDRESS)
278 {
279 // Section isn't resolved, we can't return a valid file address
280 return LLDB_INVALID_ADDRESS;
281 }
282 // We have a valid file range, so we can return the file based
283 // address by adding the file base address to our offset
284 return sect_file_addr + m_offset;
285 }
286 // No section, we just return the offset since it is the value in this case
287 return m_offset;
288}
289
290addr_t
Greg Claytonf5e56de2010-09-14 23:36:40 +0000291Address::GetLoadAddress (Target *target) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000292{
Greg Claytonf5e56de2010-09-14 23:36:40 +0000293 if (m_section == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000294 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000295 // No section, we just return the offset since it is the value in this case
296 return m_offset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000297 }
Greg Claytonf5e56de2010-09-14 23:36:40 +0000298
299 if (target)
300 {
301 addr_t sect_load_addr = m_section->GetLoadBaseAddress (target);
302
303 if (sect_load_addr != LLDB_INVALID_ADDRESS)
304 {
305 // We have a valid file range, so we can return the file based
306 // address by adding the file base address to our offset
307 return sect_load_addr + m_offset;
308 }
309 }
310 // The section isn't resolved or no process was supplied so we can't
311 // return a valid file address.
312 return LLDB_INVALID_ADDRESS;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313}
314
Greg Clayton3f5c08f2011-05-18 22:01:49 +0000315addr_t
316Address::GetCallableLoadAddress (Target *target) const
317{
318 addr_t code_addr = GetLoadAddress (target);
Greg Claytonf3ef3d22011-05-22 22:46:53 +0000319
320 if (target)
321 return target->GetCallableLoadAddress (code_addr, GetAddressClass());
Greg Clayton3f5c08f2011-05-18 22:01:49 +0000322 return code_addr;
323}
324
Greg Claytoncff851a2011-05-22 04:32:55 +0000325bool
326Address::SetCallableLoadAddress (lldb::addr_t load_addr, Target *target)
327{
328 if (SetLoadAddress (load_addr, target))
329 {
Greg Claytonf3ef3d22011-05-22 22:46:53 +0000330 if (target)
331 m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass());
Greg Claytoncff851a2011-05-22 04:32:55 +0000332 return true;
333 }
334 return false;
335}
336
Greg Clayton92bb12c2011-05-19 18:17:41 +0000337addr_t
338Address::GetOpcodeLoadAddress (Target *target) const
339{
340 addr_t code_addr = GetLoadAddress (target);
Greg Clayton92bb12c2011-05-19 18:17:41 +0000341 if (code_addr != LLDB_INVALID_ADDRESS)
Greg Claytonf3ef3d22011-05-22 22:46:53 +0000342 code_addr = target->GetOpcodeLoadAddress (code_addr, GetAddressClass());
Greg Clayton92bb12c2011-05-19 18:17:41 +0000343 return code_addr;
344}
345
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000346bool
Greg Claytoncff851a2011-05-22 04:32:55 +0000347Address::SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target)
348{
349 if (SetLoadAddress (load_addr, target))
350 {
Greg Claytonf3ef3d22011-05-22 22:46:53 +0000351 if (target)
352 m_offset = target->GetOpcodeLoadAddress (m_offset, GetAddressClass());
Greg Claytoncff851a2011-05-22 04:32:55 +0000353 return true;
354 }
355 return false;
356}
357
358bool
Greg Claytondda4f7b2010-06-30 23:03:03 +0000359Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360{
361 // If the section was NULL, only load address is going to work.
362 if (m_section == NULL)
363 style = DumpStyleLoadAddress;
364
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000365 Target *target = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366 Process *process = NULL;
367 if (exe_scope)
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000368 {
369 target = exe_scope->CalculateTarget();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000370 process = exe_scope->CalculateProcess();
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000371 }
Greg Claytondda4f7b2010-06-30 23:03:03 +0000372 // If addr_byte_size is UINT32_MAX, then determine the correct address
373 // byte size for the process or default to the size of addr_t
374 if (addr_size == UINT32_MAX)
375 {
376 if (process)
Greg Clayton514487e2011-02-15 21:59:32 +0000377 addr_size = target->GetArchitecture().GetAddressByteSize ();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000378 else
379 addr_size = sizeof(addr_t);
380 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381
Greg Claytonc9800662010-09-10 01:30:46 +0000382 Address so_addr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000383 switch (style)
384 {
Greg Claytonc982c762010-07-09 20:39:50 +0000385 case DumpStyleInvalid:
386 return false;
387
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000388 case DumpStyleSectionNameOffset:
389 if (m_section != NULL)
390 {
391 m_section->DumpName(s);
392 s->Printf (" + %llu", m_offset);
393 }
394 else
395 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000396 s->Address(m_offset, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000397 }
398 break;
399
400 case DumpStyleSectionPointerOffset:
Jason Molendafd54b362011-09-20 21:44:10 +0000401 s->Printf("(Section *)%p + ", m_section);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000402 s->Address(m_offset, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403 break;
404
405 case DumpStyleModuleWithFileAddress:
Greg Claytoncfd1ace2010-10-31 03:01:06 +0000406 if (m_section)
407 s->Printf("%s[", m_section->GetModule()->GetFileSpec().GetFilename().AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000408 // Fall through
409 case DumpStyleFileAddress:
410 {
411 addr_t file_addr = GetFileAddress();
412 if (file_addr == LLDB_INVALID_ADDRESS)
413 {
414 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000415 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416 return false;
417 }
418 s->Address (file_addr, addr_size);
Greg Claytoncfd1ace2010-10-31 03:01:06 +0000419 if (style == DumpStyleModuleWithFileAddress && m_section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000420 s->PutChar(']');
421 }
422 break;
423
424 case DumpStyleLoadAddress:
425 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000426 addr_t load_addr = GetLoadAddress (target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000427 if (load_addr == LLDB_INVALID_ADDRESS)
428 {
429 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000430 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431 return false;
432 }
433 s->Address (load_addr, addr_size);
434 }
435 break;
436
437 case DumpStyleResolvedDescription:
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000438 case DumpStyleResolvedDescriptionNoModule:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439 if (IsSectionOffset())
440 {
Greg Claytone0d378b2011-03-24 21:19:54 +0000441 AddressType addr_type = eAddressTypeLoad;
Greg Claytonf5e56de2010-09-14 23:36:40 +0000442 addr_t addr = GetLoadAddress (target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000443 if (addr == LLDB_INVALID_ADDRESS)
444 {
445 addr = GetFileAddress();
446 addr_type = eAddressTypeFile;
447 }
448
449 uint32_t pointer_size = 4;
Greg Claytone1cd1be2012-01-29 20:56:30 +0000450 Module *module = GetModulePtr();
Greg Clayton514487e2011-02-15 21:59:32 +0000451 if (target)
452 pointer_size = target->GetArchitecture().GetAddressByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453 else if (module)
454 pointer_size = module->GetArchitecture().GetAddressByteSize();
455
456 bool showed_info = false;
457 const Section *section = GetSection();
458 if (section)
459 {
Greg Clayton70e33eb2010-07-21 21:49:46 +0000460 SectionType sect_type = section->GetType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461 switch (sect_type)
462 {
Greg Clayton89411422010-10-08 00:21:05 +0000463 case eSectionTypeData:
464 if (module)
465 {
466 ObjectFile *objfile = module->GetObjectFile();
467 if (objfile)
468 {
469 Symtab *symtab = objfile->GetSymtab();
470 if (symtab)
471 {
472 const addr_t file_Addr = GetFileAddress();
473 Symbol *symbol = symtab->FindSymbolContainingFileAddress (file_Addr);
474 if (symbol)
475 {
476 const char *symbol_name = symbol->GetName().AsCString();
477 if (symbol_name)
478 {
479 s->PutCString(symbol_name);
480 addr_t delta = file_Addr - symbol->GetAddressRangePtr()->GetBaseAddress().GetFileAddress();
481 if (delta)
482 s->Printf(" + %llu", delta);
483 showed_info = true;
484 }
485 }
486 }
487 }
488 }
489 break;
490
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491 case eSectionTypeDataCString:
492 // Read the C string from memory and display it
493 showed_info = true;
494 ReadCStringFromMemory (exe_scope, *this, s);
495 break;
496
497 case eSectionTypeDataCStringPointers:
498 {
499 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
500 {
501#if VERBOSE_OUTPUT
502 s->PutCString("(char *)");
503 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
504 s->PutCString(": ");
505#endif
506 showed_info = true;
507 ReadCStringFromMemory (exe_scope, so_addr, s);
508 }
509 }
510 break;
511
512 case eSectionTypeDataObjCMessageRefs:
513 {
514 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
515 {
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000516 if (target && so_addr.IsSectionOffset())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000517 {
Greg Claytonc9800662010-09-10 01:30:46 +0000518 SymbolContext func_sc;
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000519 target->GetImages().ResolveSymbolContextForAddress (so_addr,
520 eSymbolContextEverything,
521 func_sc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000522 if (func_sc.function || func_sc.symbol)
523 {
524 showed_info = true;
525#if VERBOSE_OUTPUT
526 s->PutCString ("(objc_msgref *) -> { (func*)");
527 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
528#else
529 s->PutCString ("{ ");
530#endif
531 Address cstr_addr(*this);
532 cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
Greg Clayton6dadd502010-09-02 21:44:10 +0000533 func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000534 if (ReadAddress (exe_scope, cstr_addr, pointer_size, so_addr))
535 {
536#if VERBOSE_OUTPUT
537 s->PutCString("), (char *)");
538 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
539 s->PutCString(" (");
540#else
541 s->PutCString(", ");
542#endif
543 ReadCStringFromMemory (exe_scope, so_addr, s);
544 }
545#if VERBOSE_OUTPUT
546 s->PutCString(") }");
547#else
548 s->PutCString(" }");
549#endif
550 }
551 }
552 }
553 }
554 break;
555
556 case eSectionTypeDataObjCCFStrings:
557 {
558 Address cfstring_data_addr(*this);
559 cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() + (2 * pointer_size));
560 if (ReadAddress (exe_scope, cfstring_data_addr, pointer_size, so_addr))
561 {
562#if VERBOSE_OUTPUT
563 s->PutCString("(CFString *) ");
564 cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
565 s->PutCString(" -> @");
566#else
567 s->PutChar('@');
568#endif
569 if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
570 showed_info = true;
571 }
572 }
573 break;
574
575 case eSectionTypeData4:
576 // Read the 4 byte data and display it
577 showed_info = true;
578 s->PutCString("(uint32_t) ");
579 DumpUInt (exe_scope, *this, 4, s);
580 break;
581
582 case eSectionTypeData8:
583 // Read the 8 byte data and display it
584 showed_info = true;
585 s->PutCString("(uint64_t) ");
586 DumpUInt (exe_scope, *this, 8, s);
587 break;
588
589 case eSectionTypeData16:
590 // Read the 16 byte data and display it
591 showed_info = true;
592 s->PutCString("(uint128_t) ");
593 DumpUInt (exe_scope, *this, 16, s);
594 break;
595
596 case eSectionTypeDataPointers:
597 // Read the pointer data and display it
598 {
599 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
600 {
601 s->PutCString ("(void *)");
602 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
603
604 showed_info = true;
605 if (so_addr.IsSectionOffset())
606 {
Greg Claytonc9800662010-09-10 01:30:46 +0000607 SymbolContext pointer_sc;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000608 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000609 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000610 target->GetImages().ResolveSymbolContextForAddress (so_addr,
611 eSymbolContextEverything,
612 pointer_sc);
613 if (pointer_sc.function || pointer_sc.symbol)
614 {
615 s->PutCString(": ");
Greg Clayton6dadd502010-09-02 21:44:10 +0000616 pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000617 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000618 }
619 }
620 }
621 }
622 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000623
624 default:
625 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000626 }
627 }
628
629 if (!showed_info)
630 {
631 if (module)
632 {
Greg Claytonc9800662010-09-10 01:30:46 +0000633 SymbolContext sc;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000634 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
635 if (sc.function || sc.symbol)
636 {
637 bool show_stop_context = true;
Greg Clayton8dc0a982010-09-07 21:56:53 +0000638 const bool show_module = (style == DumpStyleResolvedDescription);
639 const bool show_fullpaths = false;
Greg Clayton513c26c2011-01-29 07:10:55 +0000640 const bool show_inlined_frames = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000641 if (sc.function == NULL && sc.symbol != NULL)
642 {
643 // If we have just a symbol make sure it is in the right section
644 if (sc.symbol->GetAddressRangePtr())
645 {
646 if (sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection())
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000647 {
648 // don't show the module if the symbol is a trampoline symbol
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000649 show_stop_context = false;
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000650 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000651 }
652 }
653 if (show_stop_context)
654 {
655 // We have a function or a symbol from the same
656 // sections as this address.
Greg Clayton8dc0a982010-09-07 21:56:53 +0000657 sc.DumpStopContext (s,
658 exe_scope,
659 *this,
660 show_fullpaths,
661 show_module,
662 show_inlined_frames);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000663 }
664 else
665 {
666 // We found a symbol but it was in a different
667 // section so it isn't the symbol we should be
668 // showing, just show the section name + offset
669 Dump (s, exe_scope, DumpStyleSectionNameOffset);
670 }
671 }
672 }
673 }
674 }
675 else
676 {
677 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000678 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000679 return false;
680 }
681 break;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000682
683 case DumpStyleDetailedSymbolContext:
684 if (IsSectionOffset())
685 {
Greg Claytone1cd1be2012-01-29 20:56:30 +0000686 Module *module = GetModulePtr();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000687 if (module)
688 {
Greg Claytonc9800662010-09-10 01:30:46 +0000689 SymbolContext sc;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000690 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000691 if (sc.symbol)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000692 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000693 // If we have just a symbol make sure it is in the same section
694 // as our address. If it isn't, then we might have just found
695 // the last symbol that came before the address that we are
696 // looking up that has nothing to do with our address lookup.
697 if (sc.symbol->GetAddressRangePtr() && sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection())
698 sc.symbol = NULL;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000699 }
Greg Claytonf5e56de2010-09-14 23:36:40 +0000700 sc.GetDescription(s, eDescriptionLevelBrief, target);
Greg Claytonc749eb82011-07-11 05:12:02 +0000701
702 if (sc.block)
703 {
704 bool can_create = true;
705 bool get_parent_variables = true;
706 bool stop_if_block_is_inlined_function = false;
707 VariableList variable_list;
708 sc.block->AppendVariables (can_create,
709 get_parent_variables,
710 stop_if_block_is_inlined_function,
711 &variable_list);
712
713 uint32_t num_variables = variable_list.GetSize();
714 for (uint32_t var_idx = 0; var_idx < num_variables; ++var_idx)
715 {
716 Variable *var = variable_list.GetVariableAtIndex (var_idx).get();
717 if (var && var->LocationIsValidForAddress (*this))
718 {
Greg Clayton81c22f62011-10-19 18:09:39 +0000719 s->Printf (" Variable: id = {0x%8.8llx}, name = \"%s\", type= \"%s\", location =",
Greg Claytonc749eb82011-07-11 05:12:02 +0000720 var->GetID(),
721 var->GetName().GetCString(),
722 var->GetType()->GetName().GetCString());
723 var->DumpLocationForAddress(s, *this);
724 s->PutCString(", decl = ");
725 var->GetDeclaration().DumpStopContext(s, false);
726 s->EOL();
727 }
728 }
729 }
Greg Claytondda4f7b2010-06-30 23:03:03 +0000730 }
731 }
Greg Claytonc749eb82011-07-11 05:12:02 +0000732 else
733 {
734 if (fallback_style != DumpStyleInvalid)
735 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
736 return false;
737 }
Greg Claytondda4f7b2010-06-30 23:03:03 +0000738 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000739 }
740
741 return true;
742}
743
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000744uint32_t
Greg Clayton6f6bf262011-12-10 21:05:26 +0000745Address::CalculateSymbolContext (SymbolContext *sc, uint32_t resolve_scope) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000746{
747 sc->Clear();
748 // Absolute addresses don't have enough information to reconstruct even their target.
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000749 if (m_section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000750 {
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000751 Module *address_module = m_section->GetModule();
752 if (address_module)
753 {
Greg Claytone1cd1be2012-01-29 20:56:30 +0000754 sc->module_sp = address_module->shared_from_this();
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000755 if (sc->module_sp)
756 return sc->module_sp->ResolveSymbolContextForAddress (*this, resolve_scope, *sc);
757 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000758 }
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000759 return 0;
760}
761
762Module *
Greg Clayton6f6bf262011-12-10 21:05:26 +0000763Address::CalculateSymbolContextModule () const
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000764{
765 if (m_section)
766 return m_section->GetModule();
767 return NULL;
768}
769
770CompileUnit *
Greg Clayton6f6bf262011-12-10 21:05:26 +0000771Address::CalculateSymbolContextCompileUnit () const
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000772{
773 if (m_section)
774 {
775 SymbolContext sc;
Greg Claytone1cd1be2012-01-29 20:56:30 +0000776 sc.module_sp = m_section->GetModule()->shared_from_this();
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000777 if (sc.module_sp)
778 {
779 sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextCompUnit, sc);
780 return sc.comp_unit;
781 }
782 }
783 return NULL;
784}
785
786Function *
Greg Clayton6f6bf262011-12-10 21:05:26 +0000787Address::CalculateSymbolContextFunction () const
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000788{
789 if (m_section)
790 {
791 SymbolContext sc;
Greg Claytone1cd1be2012-01-29 20:56:30 +0000792 sc.module_sp = m_section->GetModule()->shared_from_this();
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000793 if (sc.module_sp)
794 {
795 sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextFunction, sc);
796 return sc.function;
797 }
798 }
799 return NULL;
800}
801
802Block *
Greg Clayton6f6bf262011-12-10 21:05:26 +0000803Address::CalculateSymbolContextBlock () const
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000804{
805 if (m_section)
806 {
807 SymbolContext sc;
Greg Claytone1cd1be2012-01-29 20:56:30 +0000808 sc.module_sp = m_section->GetModule()->shared_from_this();
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000809 if (sc.module_sp)
810 {
811 sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextBlock, sc);
812 return sc.block;
813 }
814 }
815 return NULL;
816}
817
818Symbol *
Greg Clayton6f6bf262011-12-10 21:05:26 +0000819Address::CalculateSymbolContextSymbol () const
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000820{
821 if (m_section)
822 {
823 SymbolContext sc;
Greg Claytone1cd1be2012-01-29 20:56:30 +0000824 sc.module_sp = m_section->GetModule()->shared_from_this();
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000825 if (sc.module_sp)
826 {
827 sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextSymbol, sc);
828 return sc.symbol;
829 }
830 }
831 return NULL;
832}
833
834bool
Greg Clayton6f6bf262011-12-10 21:05:26 +0000835Address::CalculateSymbolContextLineEntry (LineEntry &line_entry) const
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000836{
837 if (m_section)
838 {
839 SymbolContext sc;
Greg Claytone1cd1be2012-01-29 20:56:30 +0000840 sc.module_sp = m_section->GetModule()->shared_from_this();
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000841 if (sc.module_sp)
842 {
843 sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextLineEntry, sc);
844 if (sc.line_entry.IsValid())
845 {
846 line_entry = sc.line_entry;
847 return true;
848 }
849 }
850 }
851 line_entry.Clear();
852 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000853}
854
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000855int
856Address::CompareFileAddress (const Address& a, const Address& b)
857{
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
867
868int
Greg Claytonf5e56de2010-09-14 23:36:40 +0000869Address::CompareLoadAddress (const Address& a, const Address& b, Target *target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000870{
Greg Claytonf5e56de2010-09-14 23:36:40 +0000871 assert (target != NULL);
872 addr_t a_load_addr = a.GetLoadAddress (target);
873 addr_t b_load_addr = b.GetLoadAddress (target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000874 if (a_load_addr < b_load_addr)
875 return -1;
876 if (a_load_addr > b_load_addr)
877 return +1;
878 return 0;
879}
880
881int
882Address::CompareModulePointerAndOffset (const Address& a, const Address& b)
883{
Greg Claytone1cd1be2012-01-29 20:56:30 +0000884 Module *a_module = a.GetModulePtr ();
885 Module *b_module = b.GetModulePtr ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000886 if (a_module < b_module)
887 return -1;
888 if (a_module > b_module)
889 return +1;
890 // Modules are the same, just compare the file address since they should
891 // be unique
892 addr_t a_file_addr = a.GetFileAddress();
893 addr_t b_file_addr = b.GetFileAddress();
894 if (a_file_addr < b_file_addr)
895 return -1;
896 if (a_file_addr > b_file_addr)
897 return +1;
898 return 0;
899}
900
901
902size_t
903Address::MemorySize () const
904{
905 // Noting special for the memory size of a single Address object,
906 // it is just the size of itself.
907 return sizeof(Address);
908}
909
910
Greg Claytonb0848c52011-01-08 00:05:12 +0000911//----------------------------------------------------------------------
912// NOTE: Be careful using this operator. It can correctly compare two
913// addresses from the same Module correctly. It can't compare two
914// addresses from different modules in any meaningful way, but it will
915// compare the module pointers.
916//
917// To sum things up:
918// - works great for addresses within the same module
919// - it works for addresses across multiple modules, but don't expect the
920// address results to make much sense
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000921//
Greg Claytonb0848c52011-01-08 00:05:12 +0000922// This basically lets Address objects be used in ordered collection
923// classes.
924//----------------------------------------------------------------------
925
926bool
927lldb_private::operator< (const Address& lhs, const Address& rhs)
928{
Greg Claytone1cd1be2012-01-29 20:56:30 +0000929 Module *lhs_module = lhs.GetModulePtr();
930 Module *rhs_module = rhs.GetModulePtr();
Greg Claytonb0848c52011-01-08 00:05:12 +0000931 if (lhs_module == rhs_module)
932 {
933 // Addresses are in the same module, just compare the file addresses
934 return lhs.GetFileAddress() < rhs.GetFileAddress();
935 }
936 else
937 {
938 // The addresses are from different modules, just use the module
939 // pointer value to get consistent ordering
940 return lhs_module < rhs_module;
941 }
942}
943
944bool
945lldb_private::operator> (const Address& lhs, const Address& rhs)
946{
Greg Claytone1cd1be2012-01-29 20:56:30 +0000947 Module *lhs_module = lhs.GetModulePtr();
948 Module *rhs_module = rhs.GetModulePtr();
Greg Claytonb0848c52011-01-08 00:05:12 +0000949 if (lhs_module == rhs_module)
950 {
951 // Addresses are in the same module, just compare the file addresses
952 return lhs.GetFileAddress() > rhs.GetFileAddress();
953 }
954 else
955 {
956 // The addresses are from different modules, just use the module
957 // pointer value to get consistent ordering
958 return lhs_module > rhs_module;
959 }
960}
961
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000962
963// The operator == checks for exact equality only (same section, same offset)
964bool
965lldb_private::operator== (const Address& a, const Address& rhs)
966{
967 return a.GetSection() == rhs.GetSection() &&
968 a.GetOffset() == rhs.GetOffset();
969}
970// The operator != checks for exact inequality only (differing section, or
971// different offset)
972bool
973lldb_private::operator!= (const Address& a, const Address& rhs)
974{
975 return a.GetSection() != rhs.GetSection() ||
976 a.GetOffset() != rhs.GetOffset();
977}
978
979bool
980Address::IsLinkedAddress () const
981{
982 return m_section && m_section->GetLinkedSection();
983}
984
985
986void
987Address::ResolveLinkedAddress ()
988{
989 if (m_section)
990 {
991 const Section *linked_section = m_section->GetLinkedSection();
992 if (linked_section)
993 {
994 m_offset += m_section->GetLinkedOffset();
995 m_section = linked_section;
996 }
997 }
998}
Greg Claytonded470d2011-03-19 01:12:21 +0000999
Greg Claytone0d378b2011-03-24 21:19:54 +00001000AddressClass
Greg Claytonded470d2011-03-19 01:12:21 +00001001Address::GetAddressClass () const
1002{
Greg Claytone1cd1be2012-01-29 20:56:30 +00001003 Module *module = GetModulePtr();
Greg Claytonded470d2011-03-19 01:12:21 +00001004 if (module)
1005 {
1006 ObjectFile *obj_file = module->GetObjectFile();
1007 if (obj_file)
1008 return obj_file->GetAddressClass (GetFileAddress());
1009 }
1010 return eAddressClassUnknown;
1011}
Greg Claytoncd482e32011-05-18 01:58:14 +00001012
1013bool
1014Address::SetLoadAddress (lldb::addr_t load_addr, Target *target)
1015{
1016 if (target && target->GetSectionLoadList().ResolveLoadAddress(load_addr, *this))
1017 return true;
1018 m_section = NULL;
1019 m_offset = load_addr;
1020 return false;
1021}
1022