blob: c87814fa1f6401f4271cce39edad3b4befa18820 [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 Claytonf5e56de2010-09-14 23:36:40 +000014#include "lldb/Target/ExecutionContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015#include "lldb/Target/Process.h"
16#include "lldb/Target/Target.h"
17
18using namespace lldb;
19using namespace lldb_private;
20
Greg Claytondda4f7b2010-06-30 23:03:03 +000021//static size_t
22//ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst, size_t dst_len)
23//{
24// if (exe_scope == NULL)
25// return 0;
26//
27// lldb::AddressType addr_type = eAddressTypeInvalid;
28// addr_t addr = LLDB_INVALID_ADDRESS;
29//
30// Process *process = exe_scope->CalculateProcess();
31//
32// if (process && process->IsAlive())
33// {
34// addr = address.GetLoadAddress(process);
35// if (addr != LLDB_INVALID_ADDRESS)
36// addr_type = eAddressTypeLoad;
37// }
38//
39// if (addr == LLDB_INVALID_ADDRESS)
40// {
41// addr = address.GetFileAddress();
42// if (addr != LLDB_INVALID_ADDRESS)
43// addr_type = eAddressTypeFile;
44// }
45//
46// if (addr_type == eAddressTypeInvalid)
47// return false;
48//
49// Target *target = exe_scope->CalculateTarget();
50// if (target)
51// {
52// Error error;
53// ObjectFile *objfile = NULL;
54// if (address.GetModule())
55// objfile = address.GetModule()->GetObjectFile();
56// return target->ReadMemory (addr_type, addr, dst, dst_len, error, objfile);
57// }
58// return 0;
59//}
60
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061static size_t
62ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst, size_t dst_len)
63{
64 if (exe_scope == NULL)
65 return 0;
66
Chris Lattner30fdc8d2010-06-08 16:52:24 +000067 Target *target = exe_scope->CalculateTarget();
68 if (target)
69 {
70 Error error;
Greg Claytondb598232011-01-07 01:57:07 +000071 bool prefer_file_cache = false;
72 return target->ReadMemory (address, prefer_file_cache, dst, dst_len, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073 }
74 return 0;
75}
76
77static bool
78GetByteOrderAndAddressSize (ExecutionContextScope *exe_scope, const Address &address, ByteOrder& byte_order, uint32_t& addr_size)
79{
80 byte_order = eByteOrderInvalid;
81 addr_size = 0;
82 if (exe_scope == NULL)
83 return false;
84
85 Process *process = exe_scope->CalculateProcess();
86 if (process)
87 {
88 byte_order = process->GetByteOrder();
89 addr_size = process->GetAddressByteSize();
90 }
91
92 if (byte_order == eByteOrderInvalid || addr_size == 0)
93 {
94 Module *module = address.GetModule();
95 if (module)
96 {
97 byte_order = module->GetArchitecture().GetDefaultEndian();
98 addr_size = module->GetArchitecture().GetAddressByteSize();
99 }
100 }
101 return byte_order != eByteOrderInvalid && addr_size != 0;
102}
103
104static uint64_t
105ReadUIntMax64 (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, bool &success)
106{
107 uint64_t uval64 = 0;
108 if (exe_scope == NULL || byte_size > sizeof(uint64_t))
109 {
110 success = false;
111 return 0;
112 }
113 uint64_t buf;
114
115 success = ReadBytes (exe_scope, address, &buf, byte_size) == byte_size;
116 if (success)
117 {
118 ByteOrder byte_order = eByteOrderInvalid;
119 uint32_t addr_size = 0;
120 if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size))
121 {
122 DataExtractor data (&buf, sizeof(buf), byte_order, addr_size);
123 uint32_t offset = 0;
124 uval64 = data.GetU64(&offset);
125 }
126 else
127 success = false;
128 }
129 return uval64;
130}
131
132static bool
133ReadAddress (ExecutionContextScope *exe_scope, const Address &address, uint32_t pointer_size, Address &deref_so_addr)
134{
135 if (exe_scope == NULL)
136 return false;
137
138
139 bool success = false;
140 addr_t deref_addr = ReadUIntMax64 (exe_scope, address, pointer_size, success);
141 if (success)
142 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000143 ExecutionContext exe_ctx;
Greg Clayton0603aa92010-10-04 01:05:56 +0000144 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Claytonf5e56de2010-09-14 23:36:40 +0000145 // If we have any sections that are loaded, try and resolve using the
146 // section load list
147 if (exe_ctx.target && !exe_ctx.target->GetSectionLoadList().IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000149 if (exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (deref_addr, deref_so_addr))
150 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000151 }
152 else
153 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000154 // If we were not running, yet able to read an integer, we must
155 // have a module
156 Module *module = address.GetModule();
157 assert (module);
158 if (module->ResolveFileAddress(deref_addr, deref_so_addr))
159 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160 }
Greg Claytonf5e56de2010-09-14 23:36:40 +0000161
162 // We couldn't make "deref_addr" into a section offset value, but we were
163 // able to read the address, so we return a section offset address with
164 // no section and "deref_addr" as the offset (address).
165 deref_so_addr.SetSection(NULL);
166 deref_so_addr.SetOffset(deref_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167 return true;
168 }
169 return false;
170}
171
172static bool
173DumpUInt (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, Stream* strm)
174{
Greg Clayton471b31c2010-07-20 22:52:08 +0000175 if (exe_scope == NULL || byte_size == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176 return 0;
177 std::vector<uint8_t> buf(byte_size, 0);
178
179 if (ReadBytes (exe_scope, address, &buf[0], buf.size()) == buf.size())
180 {
181 ByteOrder byte_order = eByteOrderInvalid;
182 uint32_t addr_size = 0;
183 if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size))
184 {
Greg Clayton471b31c2010-07-20 22:52:08 +0000185 DataExtractor data (&buf.front(), buf.size(), byte_order, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186
187 data.Dump (strm,
188 0, // Start offset in "data"
189 eFormatHex, // Print as characters
190 buf.size(), // Size of item
191 1, // Items count
192 UINT32_MAX, // num per line
193 LLDB_INVALID_ADDRESS,// base address
194 0, // bitfield bit size
195 0); // bitfield bit offset
196
197 return true;
198 }
199 }
200 return false;
201}
202
203
204static size_t
205ReadCStringFromMemory (ExecutionContextScope *exe_scope, const Address &address, Stream *strm)
206{
207 if (exe_scope == NULL)
208 return 0;
209 const size_t k_buf_len = 256;
210 char buf[k_buf_len+1];
211 buf[k_buf_len] = '\0'; // NULL terminate
212
213 // Byte order and adderss size don't matter for C string dumping..
214 DataExtractor data (buf, sizeof(buf), eByteOrderHost, 4);
215 size_t total_len = 0;
216 size_t bytes_read;
217 Address curr_address(address);
218 strm->PutChar ('"');
219 while ((bytes_read = ReadBytes (exe_scope, curr_address, buf, k_buf_len)) > 0)
220 {
221 size_t len = strlen(buf);
222 if (len == 0)
223 break;
224 if (len > bytes_read)
225 len = bytes_read;
226
227 data.Dump (strm,
228 0, // Start offset in "data"
229 eFormatChar, // Print as characters
230 1, // Size of item (1 byte for a char!)
231 len, // How many bytes to print?
232 UINT32_MAX, // num per line
233 LLDB_INVALID_ADDRESS,// base address
234 0, // bitfield bit size
235
236 0); // bitfield bit offset
237
238 total_len += bytes_read;
239
240 if (len < k_buf_len)
241 break;
242 curr_address.SetOffset (curr_address.GetOffset() + bytes_read);
243 }
244 strm->PutChar ('"');
245 return total_len;
246}
247
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000248Address::Address (addr_t address, const SectionList * sections) :
249 m_section (NULL),
250 m_offset (LLDB_INVALID_ADDRESS)
251{
252 ResolveAddressUsingFileSections(address, sections);
253}
254
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255const Address&
256Address::operator= (const Address& rhs)
257{
258 if (this != &rhs)
259 {
260 m_section = rhs.m_section;
261 m_offset = rhs.m_offset;
262 }
263 return *this;
264}
265
266bool
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000267Address::ResolveAddressUsingFileSections (addr_t addr, const SectionList *sections)
268{
269 if (sections)
270 m_section = sections->FindSectionContainingFileAddress(addr).get();
271 else
272 m_section = NULL;
273
274 if (m_section != NULL)
275 {
276 assert( m_section->ContainsFileAddress(addr) );
277 m_offset = addr - m_section->GetFileAddress();
278 return true; // Successfully transformed addr into a section offset address
279 }
280
281 m_offset = addr;
282 return false; // Failed to resolve this address to a section offset value
283}
284
285//bool
286//Address::ResolveAddressUsingLoadSections (addr_t addr, const SectionList *sections)
287//{
288// if (sections)
289// m_section = sections->FindSectionContainingLoadAddress(addr).get();
290// else
291// m_section = NULL;
292//
293// if (m_section != NULL)
294// {
295// assert( m_section->ContainsLoadAddress(addr) );
296// m_offset = addr - m_section->GetLoadBaseAddress();
297// return true; // Successfully transformed addr into a section offset address
298// }
299//
300// m_offset = addr;
301// return false; // Failed to resolve this address to a section offset value
302//}
303//
304Module *
305Address::GetModule () const
306{
307 if (m_section)
308 return m_section->GetModule();
309 return NULL;
310}
311
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312//addr_t
313//Address::Address() const
314//{
315// addr_t addr = GetLoadAddress();
316// if (addr != LLDB_INVALID_ADDRESS)
317// return addr;
318// return GetFileAddress();
319//}
320//
321
322addr_t
323Address::GetFileAddress () const
324{
325 if (m_section != NULL)
326 {
327 addr_t sect_file_addr = m_section->GetFileAddress();
328 if (sect_file_addr == LLDB_INVALID_ADDRESS)
329 {
330 // Section isn't resolved, we can't return a valid file address
331 return LLDB_INVALID_ADDRESS;
332 }
333 // We have a valid file range, so we can return the file based
334 // address by adding the file base address to our offset
335 return sect_file_addr + m_offset;
336 }
337 // No section, we just return the offset since it is the value in this case
338 return m_offset;
339}
340
341addr_t
Greg Claytonf5e56de2010-09-14 23:36:40 +0000342Address::GetLoadAddress (Target *target) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343{
Greg Claytonf5e56de2010-09-14 23:36:40 +0000344 if (m_section == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000346 // No section, we just return the offset since it is the value in this case
347 return m_offset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348 }
Greg Claytonf5e56de2010-09-14 23:36:40 +0000349
350 if (target)
351 {
352 addr_t sect_load_addr = m_section->GetLoadBaseAddress (target);
353
354 if (sect_load_addr != LLDB_INVALID_ADDRESS)
355 {
356 // We have a valid file range, so we can return the file based
357 // address by adding the file base address to our offset
358 return sect_load_addr + m_offset;
359 }
360 }
361 // The section isn't resolved or no process was supplied so we can't
362 // return a valid file address.
363 return LLDB_INVALID_ADDRESS;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000364}
365
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366bool
Greg Claytondda4f7b2010-06-30 23:03:03 +0000367Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368{
369 // If the section was NULL, only load address is going to work.
370 if (m_section == NULL)
371 style = DumpStyleLoadAddress;
372
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000373 Target *target = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000374 Process *process = NULL;
375 if (exe_scope)
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000376 {
377 target = exe_scope->CalculateTarget();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378 process = exe_scope->CalculateProcess();
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000379 }
Greg Claytondda4f7b2010-06-30 23:03:03 +0000380 // If addr_byte_size is UINT32_MAX, then determine the correct address
381 // byte size for the process or default to the size of addr_t
382 if (addr_size == UINT32_MAX)
383 {
384 if (process)
385 addr_size = process->GetAddressByteSize ();
386 else
387 addr_size = sizeof(addr_t);
388 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000389
Greg Claytonc9800662010-09-10 01:30:46 +0000390 Address so_addr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391 switch (style)
392 {
Greg Claytonc982c762010-07-09 20:39:50 +0000393 case DumpStyleInvalid:
394 return false;
395
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000396 case DumpStyleSectionNameOffset:
397 if (m_section != NULL)
398 {
399 m_section->DumpName(s);
400 s->Printf (" + %llu", m_offset);
401 }
402 else
403 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000404 s->Address(m_offset, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405 }
406 break;
407
408 case DumpStyleSectionPointerOffset:
Greg Claytondda4f7b2010-06-30 23:03:03 +0000409 s->Printf("(Section *)%.*p + ", (int)sizeof(void*) * 2, m_section);
410 s->Address(m_offset, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411 break;
412
413 case DumpStyleModuleWithFileAddress:
Greg Claytoncfd1ace2010-10-31 03:01:06 +0000414 if (m_section)
415 s->Printf("%s[", m_section->GetModule()->GetFileSpec().GetFilename().AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416 // Fall through
417 case DumpStyleFileAddress:
418 {
419 addr_t file_addr = GetFileAddress();
420 if (file_addr == LLDB_INVALID_ADDRESS)
421 {
422 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000423 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000424 return false;
425 }
426 s->Address (file_addr, addr_size);
Greg Claytoncfd1ace2010-10-31 03:01:06 +0000427 if (style == DumpStyleModuleWithFileAddress && m_section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000428 s->PutChar(']');
429 }
430 break;
431
432 case DumpStyleLoadAddress:
433 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000434 addr_t load_addr = GetLoadAddress (target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435 if (load_addr == LLDB_INVALID_ADDRESS)
436 {
437 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000438 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439 return false;
440 }
441 s->Address (load_addr, addr_size);
442 }
443 break;
444
445 case DumpStyleResolvedDescription:
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000446 case DumpStyleResolvedDescriptionNoModule:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000447 if (IsSectionOffset())
448 {
449 lldb::AddressType addr_type = eAddressTypeLoad;
Greg Claytonf5e56de2010-09-14 23:36:40 +0000450 addr_t addr = GetLoadAddress (target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000451 if (addr == LLDB_INVALID_ADDRESS)
452 {
453 addr = GetFileAddress();
454 addr_type = eAddressTypeFile;
455 }
456
457 uint32_t pointer_size = 4;
Greg Claytonc9800662010-09-10 01:30:46 +0000458 Module *module = GetModule();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459 if (process)
460 pointer_size = process->GetAddressByteSize();
461 else if (module)
462 pointer_size = module->GetArchitecture().GetAddressByteSize();
463
464 bool showed_info = false;
465 const Section *section = GetSection();
466 if (section)
467 {
Greg Clayton70e33eb2010-07-21 21:49:46 +0000468 SectionType sect_type = section->GetType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000469 switch (sect_type)
470 {
Greg Clayton89411422010-10-08 00:21:05 +0000471 case eSectionTypeData:
472 if (module)
473 {
474 ObjectFile *objfile = module->GetObjectFile();
475 if (objfile)
476 {
477 Symtab *symtab = objfile->GetSymtab();
478 if (symtab)
479 {
480 const addr_t file_Addr = GetFileAddress();
481 Symbol *symbol = symtab->FindSymbolContainingFileAddress (file_Addr);
482 if (symbol)
483 {
484 const char *symbol_name = symbol->GetName().AsCString();
485 if (symbol_name)
486 {
487 s->PutCString(symbol_name);
488 addr_t delta = file_Addr - symbol->GetAddressRangePtr()->GetBaseAddress().GetFileAddress();
489 if (delta)
490 s->Printf(" + %llu", delta);
491 showed_info = true;
492 }
493 }
494 }
495 }
496 }
497 break;
498
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000499 case eSectionTypeDataCString:
500 // Read the C string from memory and display it
501 showed_info = true;
502 ReadCStringFromMemory (exe_scope, *this, s);
503 break;
504
505 case eSectionTypeDataCStringPointers:
506 {
507 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
508 {
509#if VERBOSE_OUTPUT
510 s->PutCString("(char *)");
511 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
512 s->PutCString(": ");
513#endif
514 showed_info = true;
515 ReadCStringFromMemory (exe_scope, so_addr, s);
516 }
517 }
518 break;
519
520 case eSectionTypeDataObjCMessageRefs:
521 {
522 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
523 {
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000524 if (target && so_addr.IsSectionOffset())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000525 {
Greg Claytonc9800662010-09-10 01:30:46 +0000526 SymbolContext func_sc;
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000527 target->GetImages().ResolveSymbolContextForAddress (so_addr,
528 eSymbolContextEverything,
529 func_sc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000530 if (func_sc.function || func_sc.symbol)
531 {
532 showed_info = true;
533#if VERBOSE_OUTPUT
534 s->PutCString ("(objc_msgref *) -> { (func*)");
535 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
536#else
537 s->PutCString ("{ ");
538#endif
539 Address cstr_addr(*this);
540 cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
Greg Clayton6dadd502010-09-02 21:44:10 +0000541 func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000542 if (ReadAddress (exe_scope, cstr_addr, pointer_size, so_addr))
543 {
544#if VERBOSE_OUTPUT
545 s->PutCString("), (char *)");
546 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
547 s->PutCString(" (");
548#else
549 s->PutCString(", ");
550#endif
551 ReadCStringFromMemory (exe_scope, so_addr, s);
552 }
553#if VERBOSE_OUTPUT
554 s->PutCString(") }");
555#else
556 s->PutCString(" }");
557#endif
558 }
559 }
560 }
561 }
562 break;
563
564 case eSectionTypeDataObjCCFStrings:
565 {
566 Address cfstring_data_addr(*this);
567 cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() + (2 * pointer_size));
568 if (ReadAddress (exe_scope, cfstring_data_addr, pointer_size, so_addr))
569 {
570#if VERBOSE_OUTPUT
571 s->PutCString("(CFString *) ");
572 cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
573 s->PutCString(" -> @");
574#else
575 s->PutChar('@');
576#endif
577 if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
578 showed_info = true;
579 }
580 }
581 break;
582
583 case eSectionTypeData4:
584 // Read the 4 byte data and display it
585 showed_info = true;
586 s->PutCString("(uint32_t) ");
587 DumpUInt (exe_scope, *this, 4, s);
588 break;
589
590 case eSectionTypeData8:
591 // Read the 8 byte data and display it
592 showed_info = true;
593 s->PutCString("(uint64_t) ");
594 DumpUInt (exe_scope, *this, 8, s);
595 break;
596
597 case eSectionTypeData16:
598 // Read the 16 byte data and display it
599 showed_info = true;
600 s->PutCString("(uint128_t) ");
601 DumpUInt (exe_scope, *this, 16, s);
602 break;
603
604 case eSectionTypeDataPointers:
605 // Read the pointer data and display it
606 {
607 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
608 {
609 s->PutCString ("(void *)");
610 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
611
612 showed_info = true;
613 if (so_addr.IsSectionOffset())
614 {
Greg Claytonc9800662010-09-10 01:30:46 +0000615 SymbolContext pointer_sc;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000616 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000617 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000618 target->GetImages().ResolveSymbolContextForAddress (so_addr,
619 eSymbolContextEverything,
620 pointer_sc);
621 if (pointer_sc.function || pointer_sc.symbol)
622 {
623 s->PutCString(": ");
Greg Clayton6dadd502010-09-02 21:44:10 +0000624 pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000625 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000626 }
627 }
628 }
629 }
630 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000631
632 default:
633 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000634 }
635 }
636
637 if (!showed_info)
638 {
639 if (module)
640 {
Greg Claytonc9800662010-09-10 01:30:46 +0000641 SymbolContext sc;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000642 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
643 if (sc.function || sc.symbol)
644 {
645 bool show_stop_context = true;
Greg Clayton8dc0a982010-09-07 21:56:53 +0000646 const bool show_module = (style == DumpStyleResolvedDescription);
647 const bool show_fullpaths = false;
648 const bool show_inlined_frames = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000649 if (sc.function == NULL && sc.symbol != NULL)
650 {
651 // If we have just a symbol make sure it is in the right section
652 if (sc.symbol->GetAddressRangePtr())
653 {
654 if (sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection())
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000655 {
656 // don't show the module if the symbol is a trampoline symbol
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000657 show_stop_context = false;
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000658 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000659 }
660 }
661 if (show_stop_context)
662 {
663 // We have a function or a symbol from the same
664 // sections as this address.
Greg Clayton8dc0a982010-09-07 21:56:53 +0000665 sc.DumpStopContext (s,
666 exe_scope,
667 *this,
668 show_fullpaths,
669 show_module,
670 show_inlined_frames);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000671 }
672 else
673 {
674 // We found a symbol but it was in a different
675 // section so it isn't the symbol we should be
676 // showing, just show the section name + offset
677 Dump (s, exe_scope, DumpStyleSectionNameOffset);
678 }
679 }
680 }
681 }
682 }
683 else
684 {
685 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000686 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000687 return false;
688 }
689 break;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000690
691 case DumpStyleDetailedSymbolContext:
692 if (IsSectionOffset())
693 {
Greg Claytonc9800662010-09-10 01:30:46 +0000694 Module *module = GetModule();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000695 if (module)
696 {
Greg Claytonc9800662010-09-10 01:30:46 +0000697 SymbolContext sc;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000698 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000699 if (sc.symbol)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000700 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000701 // If we have just a symbol make sure it is in the same section
702 // as our address. If it isn't, then we might have just found
703 // the last symbol that came before the address that we are
704 // looking up that has nothing to do with our address lookup.
705 if (sc.symbol->GetAddressRangePtr() && sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection())
706 sc.symbol = NULL;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000707 }
Greg Claytonf5e56de2010-09-14 23:36:40 +0000708 sc.GetDescription(s, eDescriptionLevelBrief, target);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000709 }
710 }
711 if (fallback_style != DumpStyleInvalid)
712 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
713 return false;
714 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000715 }
716
717 return true;
718}
719
720//Stream& operator << (Stream& s, const Address& so_addr)
721//{
722// so_addr.Dump(&s, Address::DumpStyleSectionNameOffset);
723// return s;
724//}
725//
726void
727Address::CalculateSymbolContext (SymbolContext *sc)
728{
729 sc->Clear();
730 // Absolute addresses don't have enough information to reconstruct even their target.
731 if (m_section == NULL)
732 return;
733
734 if (m_section->GetModule())
735 {
736 sc->module_sp = m_section->GetModule()->GetSP();
737 if (sc->module_sp)
738 sc->module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextEverything, *sc);
739 }
740}
741
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000742int
743Address::CompareFileAddress (const Address& a, const Address& b)
744{
745 addr_t a_file_addr = a.GetFileAddress();
746 addr_t b_file_addr = b.GetFileAddress();
747 if (a_file_addr < b_file_addr)
748 return -1;
749 if (a_file_addr > b_file_addr)
750 return +1;
751 return 0;
752}
753
754
755int
Greg Claytonf5e56de2010-09-14 23:36:40 +0000756Address::CompareLoadAddress (const Address& a, const Address& b, Target *target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000757{
Greg Claytonf5e56de2010-09-14 23:36:40 +0000758 assert (target != NULL);
759 addr_t a_load_addr = a.GetLoadAddress (target);
760 addr_t b_load_addr = b.GetLoadAddress (target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000761 if (a_load_addr < b_load_addr)
762 return -1;
763 if (a_load_addr > b_load_addr)
764 return +1;
765 return 0;
766}
767
768int
769Address::CompareModulePointerAndOffset (const Address& a, const Address& b)
770{
771 Module *a_module = a.GetModule ();
772 Module *b_module = b.GetModule ();
773 if (a_module < b_module)
774 return -1;
775 if (a_module > b_module)
776 return +1;
777 // Modules are the same, just compare the file address since they should
778 // be unique
779 addr_t a_file_addr = a.GetFileAddress();
780 addr_t b_file_addr = b.GetFileAddress();
781 if (a_file_addr < b_file_addr)
782 return -1;
783 if (a_file_addr > b_file_addr)
784 return +1;
785 return 0;
786}
787
788
789size_t
790Address::MemorySize () const
791{
792 // Noting special for the memory size of a single Address object,
793 // it is just the size of itself.
794 return sizeof(Address);
795}
796
797
798/// The only comparisons that make sense are the load addresses
799//bool
800//lldb::operator< (const Address& lhs, const Address& rhs)
801//{
802// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
803// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
804//
805// if (lhs_addr == rhs_addr)
806// {
807// lhs_addr = lhs.GetFileAddress();
808// rhs_addr = rhs.GetFileAddress();
809// }
810// return lhs_addr < rhs_addr;
811//}
812//
813//bool
814//lldb::operator<= (const Address& lhs, const Address& rhs)
815//{
816// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
817// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
818//
819// if (lhs_addr == rhs_addr)
820// {
821// lhs_addr = lhs.GetFileAddress();
822// rhs_addr = rhs.GetFileAddress();
823// }
824// return lhs_addr <= rhs_addr;
825//}
826//
827//bool
828//lldb::operator> (const Address& lhs, const Address& rhs)
829//{
830// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
831// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
832//
833// if (lhs_addr == rhs_addr)
834// {
835// lhs_addr = lhs.GetFileAddress();
836// rhs_addr = rhs.GetFileAddress();
837// }
838// return lhs_addr > rhs_addr;
839//}
840//
841//bool
842//lldb::operator>= (const Address& lhs, const Address& rhs)
843//{
844// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
845// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
846//
847// if (lhs_addr == rhs_addr)
848// {
849// lhs_addr = lhs.GetFileAddress();
850// rhs_addr = rhs.GetFileAddress();
851// }
852// return lhs_addr >= rhs_addr;
853//}
854//
855
856// The operator == checks for exact equality only (same section, same offset)
857bool
858lldb_private::operator== (const Address& a, const Address& rhs)
859{
860 return a.GetSection() == rhs.GetSection() &&
861 a.GetOffset() == rhs.GetOffset();
862}
863// The operator != checks for exact inequality only (differing section, or
864// different offset)
865bool
866lldb_private::operator!= (const Address& a, const Address& rhs)
867{
868 return a.GetSection() != rhs.GetSection() ||
869 a.GetOffset() != rhs.GetOffset();
870}
871
872bool
873Address::IsLinkedAddress () const
874{
875 return m_section && m_section->GetLinkedSection();
876}
877
878
879void
880Address::ResolveLinkedAddress ()
881{
882 if (m_section)
883 {
884 const Section *linked_section = m_section->GetLinkedSection();
885 if (linked_section)
886 {
887 m_offset += m_section->GetLinkedOffset();
888 m_section = linked_section;
889 }
890 }
891}