blob: a038dd83edc4b1c6c7662b3edb7509e8e7d91f8e [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 Claytondda4f7b2010-06-30 23:03:03 +000071 return target->ReadMemory (address, dst, dst_len, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000072 }
73 return 0;
74}
75
76static bool
77GetByteOrderAndAddressSize (ExecutionContextScope *exe_scope, const Address &address, ByteOrder& byte_order, uint32_t& addr_size)
78{
79 byte_order = eByteOrderInvalid;
80 addr_size = 0;
81 if (exe_scope == NULL)
82 return false;
83
84 Process *process = exe_scope->CalculateProcess();
85 if (process)
86 {
87 byte_order = process->GetByteOrder();
88 addr_size = process->GetAddressByteSize();
89 }
90
91 if (byte_order == eByteOrderInvalid || addr_size == 0)
92 {
93 Module *module = address.GetModule();
94 if (module)
95 {
96 byte_order = module->GetArchitecture().GetDefaultEndian();
97 addr_size = module->GetArchitecture().GetAddressByteSize();
98 }
99 }
100 return byte_order != eByteOrderInvalid && addr_size != 0;
101}
102
103static uint64_t
104ReadUIntMax64 (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, bool &success)
105{
106 uint64_t uval64 = 0;
107 if (exe_scope == NULL || byte_size > sizeof(uint64_t))
108 {
109 success = false;
110 return 0;
111 }
112 uint64_t buf;
113
114 success = ReadBytes (exe_scope, address, &buf, byte_size) == byte_size;
115 if (success)
116 {
117 ByteOrder byte_order = eByteOrderInvalid;
118 uint32_t addr_size = 0;
119 if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size))
120 {
121 DataExtractor data (&buf, sizeof(buf), byte_order, addr_size);
122 uint32_t offset = 0;
123 uval64 = data.GetU64(&offset);
124 }
125 else
126 success = false;
127 }
128 return uval64;
129}
130
131static bool
132ReadAddress (ExecutionContextScope *exe_scope, const Address &address, uint32_t pointer_size, Address &deref_so_addr)
133{
134 if (exe_scope == NULL)
135 return false;
136
137
138 bool success = false;
139 addr_t deref_addr = ReadUIntMax64 (exe_scope, address, pointer_size, success);
140 if (success)
141 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000142 ExecutionContext exe_ctx;
Greg Clayton0603aa92010-10-04 01:05:56 +0000143 exe_scope->CalculateExecutionContext(exe_ctx);
Greg Claytonf5e56de2010-09-14 23:36:40 +0000144 // If we have any sections that are loaded, try and resolve using the
145 // section load list
146 if (exe_ctx.target && !exe_ctx.target->GetSectionLoadList().IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000148 if (exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (deref_addr, deref_so_addr))
149 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150 }
151 else
152 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000153 // If we were not running, yet able to read an integer, we must
154 // have a module
155 Module *module = address.GetModule();
156 assert (module);
157 if (module->ResolveFileAddress(deref_addr, deref_so_addr))
158 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159 }
Greg Claytonf5e56de2010-09-14 23:36:40 +0000160
161 // We couldn't make "deref_addr" into a section offset value, but we were
162 // able to read the address, so we return a section offset address with
163 // no section and "deref_addr" as the offset (address).
164 deref_so_addr.SetSection(NULL);
165 deref_so_addr.SetOffset(deref_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166 return true;
167 }
168 return false;
169}
170
171static bool
172DumpUInt (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, Stream* strm)
173{
Greg Clayton471b31c2010-07-20 22:52:08 +0000174 if (exe_scope == NULL || byte_size == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175 return 0;
176 std::vector<uint8_t> buf(byte_size, 0);
177
178 if (ReadBytes (exe_scope, address, &buf[0], buf.size()) == buf.size())
179 {
180 ByteOrder byte_order = eByteOrderInvalid;
181 uint32_t addr_size = 0;
182 if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size))
183 {
Greg Clayton471b31c2010-07-20 22:52:08 +0000184 DataExtractor data (&buf.front(), buf.size(), byte_order, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185
186 data.Dump (strm,
187 0, // Start offset in "data"
188 eFormatHex, // Print as characters
189 buf.size(), // Size of item
190 1, // Items count
191 UINT32_MAX, // num per line
192 LLDB_INVALID_ADDRESS,// base address
193 0, // bitfield bit size
194 0); // bitfield bit offset
195
196 return true;
197 }
198 }
199 return false;
200}
201
202
203static size_t
204ReadCStringFromMemory (ExecutionContextScope *exe_scope, const Address &address, Stream *strm)
205{
206 if (exe_scope == NULL)
207 return 0;
208 const size_t k_buf_len = 256;
209 char buf[k_buf_len+1];
210 buf[k_buf_len] = '\0'; // NULL terminate
211
212 // Byte order and adderss size don't matter for C string dumping..
213 DataExtractor data (buf, sizeof(buf), eByteOrderHost, 4);
214 size_t total_len = 0;
215 size_t bytes_read;
216 Address curr_address(address);
217 strm->PutChar ('"');
218 while ((bytes_read = ReadBytes (exe_scope, curr_address, buf, k_buf_len)) > 0)
219 {
220 size_t len = strlen(buf);
221 if (len == 0)
222 break;
223 if (len > bytes_read)
224 len = bytes_read;
225
226 data.Dump (strm,
227 0, // Start offset in "data"
228 eFormatChar, // Print as characters
229 1, // Size of item (1 byte for a char!)
230 len, // How many bytes to print?
231 UINT32_MAX, // num per line
232 LLDB_INVALID_ADDRESS,// base address
233 0, // bitfield bit size
234
235 0); // bitfield bit offset
236
237 total_len += bytes_read;
238
239 if (len < k_buf_len)
240 break;
241 curr_address.SetOffset (curr_address.GetOffset() + bytes_read);
242 }
243 strm->PutChar ('"');
244 return total_len;
245}
246
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000247Address::Address (addr_t address, const SectionList * sections) :
248 m_section (NULL),
249 m_offset (LLDB_INVALID_ADDRESS)
250{
251 ResolveAddressUsingFileSections(address, sections);
252}
253
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000254const Address&
255Address::operator= (const Address& rhs)
256{
257 if (this != &rhs)
258 {
259 m_section = rhs.m_section;
260 m_offset = rhs.m_offset;
261 }
262 return *this;
263}
264
265bool
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000266Address::ResolveAddressUsingFileSections (addr_t addr, const SectionList *sections)
267{
268 if (sections)
269 m_section = sections->FindSectionContainingFileAddress(addr).get();
270 else
271 m_section = NULL;
272
273 if (m_section != NULL)
274 {
275 assert( m_section->ContainsFileAddress(addr) );
276 m_offset = addr - m_section->GetFileAddress();
277 return true; // Successfully transformed addr into a section offset address
278 }
279
280 m_offset = addr;
281 return false; // Failed to resolve this address to a section offset value
282}
283
284//bool
285//Address::ResolveAddressUsingLoadSections (addr_t addr, const SectionList *sections)
286//{
287// if (sections)
288// m_section = sections->FindSectionContainingLoadAddress(addr).get();
289// else
290// m_section = NULL;
291//
292// if (m_section != NULL)
293// {
294// assert( m_section->ContainsLoadAddress(addr) );
295// m_offset = addr - m_section->GetLoadBaseAddress();
296// return true; // Successfully transformed addr into a section offset address
297// }
298//
299// m_offset = addr;
300// return false; // Failed to resolve this address to a section offset value
301//}
302//
303Module *
304Address::GetModule () const
305{
306 if (m_section)
307 return m_section->GetModule();
308 return NULL;
309}
310
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000311//addr_t
312//Address::Address() const
313//{
314// addr_t addr = GetLoadAddress();
315// if (addr != LLDB_INVALID_ADDRESS)
316// return addr;
317// return GetFileAddress();
318//}
319//
320
321addr_t
322Address::GetFileAddress () const
323{
324 if (m_section != NULL)
325 {
326 addr_t sect_file_addr = m_section->GetFileAddress();
327 if (sect_file_addr == LLDB_INVALID_ADDRESS)
328 {
329 // Section isn't resolved, we can't return a valid file address
330 return LLDB_INVALID_ADDRESS;
331 }
332 // We have a valid file range, so we can return the file based
333 // address by adding the file base address to our offset
334 return sect_file_addr + m_offset;
335 }
336 // No section, we just return the offset since it is the value in this case
337 return m_offset;
338}
339
340addr_t
Greg Claytonf5e56de2010-09-14 23:36:40 +0000341Address::GetLoadAddress (Target *target) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342{
Greg Claytonf5e56de2010-09-14 23:36:40 +0000343 if (m_section == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000345 // No section, we just return the offset since it is the value in this case
346 return m_offset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000347 }
Greg Claytonf5e56de2010-09-14 23:36:40 +0000348
349 if (target)
350 {
351 addr_t sect_load_addr = m_section->GetLoadBaseAddress (target);
352
353 if (sect_load_addr != LLDB_INVALID_ADDRESS)
354 {
355 // We have a valid file range, so we can return the file based
356 // address by adding the file base address to our offset
357 return sect_load_addr + m_offset;
358 }
359 }
360 // The section isn't resolved or no process was supplied so we can't
361 // return a valid file address.
362 return LLDB_INVALID_ADDRESS;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000363}
364
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000365bool
Greg Claytondda4f7b2010-06-30 23:03:03 +0000366Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000367{
368 // If the section was NULL, only load address is going to work.
369 if (m_section == NULL)
370 style = DumpStyleLoadAddress;
371
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000372 Target *target = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373 Process *process = NULL;
374 if (exe_scope)
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000375 {
376 target = exe_scope->CalculateTarget();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000377 process = exe_scope->CalculateProcess();
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000378 }
Greg Claytondda4f7b2010-06-30 23:03:03 +0000379 // If addr_byte_size is UINT32_MAX, then determine the correct address
380 // byte size for the process or default to the size of addr_t
381 if (addr_size == UINT32_MAX)
382 {
383 if (process)
384 addr_size = process->GetAddressByteSize ();
385 else
386 addr_size = sizeof(addr_t);
387 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000388
Greg Claytonc9800662010-09-10 01:30:46 +0000389 Address so_addr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390 switch (style)
391 {
Greg Claytonc982c762010-07-09 20:39:50 +0000392 case DumpStyleInvalid:
393 return false;
394
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395 case DumpStyleSectionNameOffset:
396 if (m_section != NULL)
397 {
398 m_section->DumpName(s);
399 s->Printf (" + %llu", m_offset);
400 }
401 else
402 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000403 s->Address(m_offset, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000404 }
405 break;
406
407 case DumpStyleSectionPointerOffset:
Greg Claytondda4f7b2010-06-30 23:03:03 +0000408 s->Printf("(Section *)%.*p + ", (int)sizeof(void*) * 2, m_section);
409 s->Address(m_offset, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000410 break;
411
412 case DumpStyleModuleWithFileAddress:
Greg Claytoncfd1ace2010-10-31 03:01:06 +0000413 if (m_section)
414 s->Printf("%s[", m_section->GetModule()->GetFileSpec().GetFilename().AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000415 // Fall through
416 case DumpStyleFileAddress:
417 {
418 addr_t file_addr = GetFileAddress();
419 if (file_addr == LLDB_INVALID_ADDRESS)
420 {
421 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000422 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423 return false;
424 }
425 s->Address (file_addr, addr_size);
Greg Claytoncfd1ace2010-10-31 03:01:06 +0000426 if (style == DumpStyleModuleWithFileAddress && m_section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000427 s->PutChar(']');
428 }
429 break;
430
431 case DumpStyleLoadAddress:
432 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000433 addr_t load_addr = GetLoadAddress (target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000434 if (load_addr == LLDB_INVALID_ADDRESS)
435 {
436 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000437 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438 return false;
439 }
440 s->Address (load_addr, addr_size);
441 }
442 break;
443
444 case DumpStyleResolvedDescription:
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000445 case DumpStyleResolvedDescriptionNoModule:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446 if (IsSectionOffset())
447 {
448 lldb::AddressType addr_type = eAddressTypeLoad;
Greg Claytonf5e56de2010-09-14 23:36:40 +0000449 addr_t addr = GetLoadAddress (target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000450 if (addr == LLDB_INVALID_ADDRESS)
451 {
452 addr = GetFileAddress();
453 addr_type = eAddressTypeFile;
454 }
455
456 uint32_t pointer_size = 4;
Greg Claytonc9800662010-09-10 01:30:46 +0000457 Module *module = GetModule();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000458 if (process)
459 pointer_size = process->GetAddressByteSize();
460 else if (module)
461 pointer_size = module->GetArchitecture().GetAddressByteSize();
462
463 bool showed_info = false;
464 const Section *section = GetSection();
465 if (section)
466 {
Greg Clayton70e33eb2010-07-21 21:49:46 +0000467 SectionType sect_type = section->GetType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000468 switch (sect_type)
469 {
Greg Clayton89411422010-10-08 00:21:05 +0000470 case eSectionTypeData:
471 if (module)
472 {
473 ObjectFile *objfile = module->GetObjectFile();
474 if (objfile)
475 {
476 Symtab *symtab = objfile->GetSymtab();
477 if (symtab)
478 {
479 const addr_t file_Addr = GetFileAddress();
480 Symbol *symbol = symtab->FindSymbolContainingFileAddress (file_Addr);
481 if (symbol)
482 {
483 const char *symbol_name = symbol->GetName().AsCString();
484 if (symbol_name)
485 {
486 s->PutCString(symbol_name);
487 addr_t delta = file_Addr - symbol->GetAddressRangePtr()->GetBaseAddress().GetFileAddress();
488 if (delta)
489 s->Printf(" + %llu", delta);
490 showed_info = true;
491 }
492 }
493 }
494 }
495 }
496 break;
497
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000498 case eSectionTypeDataCString:
499 // Read the C string from memory and display it
500 showed_info = true;
501 ReadCStringFromMemory (exe_scope, *this, s);
502 break;
503
504 case eSectionTypeDataCStringPointers:
505 {
506 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
507 {
508#if VERBOSE_OUTPUT
509 s->PutCString("(char *)");
510 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
511 s->PutCString(": ");
512#endif
513 showed_info = true;
514 ReadCStringFromMemory (exe_scope, so_addr, s);
515 }
516 }
517 break;
518
519 case eSectionTypeDataObjCMessageRefs:
520 {
521 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
522 {
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000523 if (target && so_addr.IsSectionOffset())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000524 {
Greg Claytonc9800662010-09-10 01:30:46 +0000525 SymbolContext func_sc;
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000526 target->GetImages().ResolveSymbolContextForAddress (so_addr,
527 eSymbolContextEverything,
528 func_sc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529 if (func_sc.function || func_sc.symbol)
530 {
531 showed_info = true;
532#if VERBOSE_OUTPUT
533 s->PutCString ("(objc_msgref *) -> { (func*)");
534 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
535#else
536 s->PutCString ("{ ");
537#endif
538 Address cstr_addr(*this);
539 cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
Greg Clayton6dadd502010-09-02 21:44:10 +0000540 func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000541 if (ReadAddress (exe_scope, cstr_addr, pointer_size, so_addr))
542 {
543#if VERBOSE_OUTPUT
544 s->PutCString("), (char *)");
545 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
546 s->PutCString(" (");
547#else
548 s->PutCString(", ");
549#endif
550 ReadCStringFromMemory (exe_scope, so_addr, s);
551 }
552#if VERBOSE_OUTPUT
553 s->PutCString(") }");
554#else
555 s->PutCString(" }");
556#endif
557 }
558 }
559 }
560 }
561 break;
562
563 case eSectionTypeDataObjCCFStrings:
564 {
565 Address cfstring_data_addr(*this);
566 cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() + (2 * pointer_size));
567 if (ReadAddress (exe_scope, cfstring_data_addr, pointer_size, so_addr))
568 {
569#if VERBOSE_OUTPUT
570 s->PutCString("(CFString *) ");
571 cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
572 s->PutCString(" -> @");
573#else
574 s->PutChar('@');
575#endif
576 if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
577 showed_info = true;
578 }
579 }
580 break;
581
582 case eSectionTypeData4:
583 // Read the 4 byte data and display it
584 showed_info = true;
585 s->PutCString("(uint32_t) ");
586 DumpUInt (exe_scope, *this, 4, s);
587 break;
588
589 case eSectionTypeData8:
590 // Read the 8 byte data and display it
591 showed_info = true;
592 s->PutCString("(uint64_t) ");
593 DumpUInt (exe_scope, *this, 8, s);
594 break;
595
596 case eSectionTypeData16:
597 // Read the 16 byte data and display it
598 showed_info = true;
599 s->PutCString("(uint128_t) ");
600 DumpUInt (exe_scope, *this, 16, s);
601 break;
602
603 case eSectionTypeDataPointers:
604 // Read the pointer data and display it
605 {
606 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
607 {
608 s->PutCString ("(void *)");
609 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
610
611 showed_info = true;
612 if (so_addr.IsSectionOffset())
613 {
Greg Claytonc9800662010-09-10 01:30:46 +0000614 SymbolContext pointer_sc;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000615 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000616 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000617 target->GetImages().ResolveSymbolContextForAddress (so_addr,
618 eSymbolContextEverything,
619 pointer_sc);
620 if (pointer_sc.function || pointer_sc.symbol)
621 {
622 s->PutCString(": ");
Greg Clayton6dadd502010-09-02 21:44:10 +0000623 pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000624 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000625 }
626 }
627 }
628 }
629 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000630
631 default:
632 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000633 }
634 }
635
636 if (!showed_info)
637 {
638 if (module)
639 {
Greg Claytonc9800662010-09-10 01:30:46 +0000640 SymbolContext sc;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000641 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
642 if (sc.function || sc.symbol)
643 {
644 bool show_stop_context = true;
Greg Clayton8dc0a982010-09-07 21:56:53 +0000645 const bool show_module = (style == DumpStyleResolvedDescription);
646 const bool show_fullpaths = false;
647 const bool show_inlined_frames = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000648 if (sc.function == NULL && sc.symbol != NULL)
649 {
650 // If we have just a symbol make sure it is in the right section
651 if (sc.symbol->GetAddressRangePtr())
652 {
653 if (sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection())
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000654 {
655 // don't show the module if the symbol is a trampoline symbol
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000656 show_stop_context = false;
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000657 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000658 }
659 }
660 if (show_stop_context)
661 {
662 // We have a function or a symbol from the same
663 // sections as this address.
Greg Clayton8dc0a982010-09-07 21:56:53 +0000664 sc.DumpStopContext (s,
665 exe_scope,
666 *this,
667 show_fullpaths,
668 show_module,
669 show_inlined_frames);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000670 }
671 else
672 {
673 // We found a symbol but it was in a different
674 // section so it isn't the symbol we should be
675 // showing, just show the section name + offset
676 Dump (s, exe_scope, DumpStyleSectionNameOffset);
677 }
678 }
679 }
680 }
681 }
682 else
683 {
684 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000685 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000686 return false;
687 }
688 break;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000689
690 case DumpStyleDetailedSymbolContext:
691 if (IsSectionOffset())
692 {
Greg Claytonc9800662010-09-10 01:30:46 +0000693 Module *module = GetModule();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000694 if (module)
695 {
Greg Claytonc9800662010-09-10 01:30:46 +0000696 SymbolContext sc;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000697 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000698 if (sc.symbol)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000699 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000700 // If we have just a symbol make sure it is in the same section
701 // as our address. If it isn't, then we might have just found
702 // the last symbol that came before the address that we are
703 // looking up that has nothing to do with our address lookup.
704 if (sc.symbol->GetAddressRangePtr() && sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection())
705 sc.symbol = NULL;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000706 }
Greg Claytonf5e56de2010-09-14 23:36:40 +0000707 sc.GetDescription(s, eDescriptionLevelBrief, target);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000708 }
709 }
710 if (fallback_style != DumpStyleInvalid)
711 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
712 return false;
713 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000714 }
715
716 return true;
717}
718
719//Stream& operator << (Stream& s, const Address& so_addr)
720//{
721// so_addr.Dump(&s, Address::DumpStyleSectionNameOffset);
722// return s;
723//}
724//
725void
726Address::CalculateSymbolContext (SymbolContext *sc)
727{
728 sc->Clear();
729 // Absolute addresses don't have enough information to reconstruct even their target.
730 if (m_section == NULL)
731 return;
732
733 if (m_section->GetModule())
734 {
735 sc->module_sp = m_section->GetModule()->GetSP();
736 if (sc->module_sp)
737 sc->module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextEverything, *sc);
738 }
739}
740
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000741int
742Address::CompareFileAddress (const Address& a, const Address& b)
743{
744 addr_t a_file_addr = a.GetFileAddress();
745 addr_t b_file_addr = b.GetFileAddress();
746 if (a_file_addr < b_file_addr)
747 return -1;
748 if (a_file_addr > b_file_addr)
749 return +1;
750 return 0;
751}
752
753
754int
Greg Claytonf5e56de2010-09-14 23:36:40 +0000755Address::CompareLoadAddress (const Address& a, const Address& b, Target *target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000756{
Greg Claytonf5e56de2010-09-14 23:36:40 +0000757 assert (target != NULL);
758 addr_t a_load_addr = a.GetLoadAddress (target);
759 addr_t b_load_addr = b.GetLoadAddress (target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000760 if (a_load_addr < b_load_addr)
761 return -1;
762 if (a_load_addr > b_load_addr)
763 return +1;
764 return 0;
765}
766
767int
768Address::CompareModulePointerAndOffset (const Address& a, const Address& b)
769{
770 Module *a_module = a.GetModule ();
771 Module *b_module = b.GetModule ();
772 if (a_module < b_module)
773 return -1;
774 if (a_module > b_module)
775 return +1;
776 // Modules are the same, just compare the file address since they should
777 // be unique
778 addr_t a_file_addr = a.GetFileAddress();
779 addr_t b_file_addr = b.GetFileAddress();
780 if (a_file_addr < b_file_addr)
781 return -1;
782 if (a_file_addr > b_file_addr)
783 return +1;
784 return 0;
785}
786
787
788size_t
789Address::MemorySize () const
790{
791 // Noting special for the memory size of a single Address object,
792 // it is just the size of itself.
793 return sizeof(Address);
794}
795
796
797/// The only comparisons that make sense are the load addresses
798//bool
799//lldb::operator< (const Address& lhs, const Address& rhs)
800//{
801// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
802// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
803//
804// if (lhs_addr == rhs_addr)
805// {
806// lhs_addr = lhs.GetFileAddress();
807// rhs_addr = rhs.GetFileAddress();
808// }
809// return lhs_addr < rhs_addr;
810//}
811//
812//bool
813//lldb::operator<= (const Address& lhs, const Address& rhs)
814//{
815// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
816// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
817//
818// if (lhs_addr == rhs_addr)
819// {
820// lhs_addr = lhs.GetFileAddress();
821// rhs_addr = rhs.GetFileAddress();
822// }
823// return lhs_addr <= rhs_addr;
824//}
825//
826//bool
827//lldb::operator> (const Address& lhs, const Address& rhs)
828//{
829// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
830// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
831//
832// if (lhs_addr == rhs_addr)
833// {
834// lhs_addr = lhs.GetFileAddress();
835// rhs_addr = rhs.GetFileAddress();
836// }
837// return lhs_addr > rhs_addr;
838//}
839//
840//bool
841//lldb::operator>= (const Address& lhs, const Address& rhs)
842//{
843// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
844// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
845//
846// if (lhs_addr == rhs_addr)
847// {
848// lhs_addr = lhs.GetFileAddress();
849// rhs_addr = rhs.GetFileAddress();
850// }
851// return lhs_addr >= rhs_addr;
852//}
853//
854
855// The operator == checks for exact equality only (same section, same offset)
856bool
857lldb_private::operator== (const Address& a, const Address& rhs)
858{
859 return a.GetSection() == rhs.GetSection() &&
860 a.GetOffset() == rhs.GetOffset();
861}
862// The operator != checks for exact inequality only (differing section, or
863// different offset)
864bool
865lldb_private::operator!= (const Address& a, const Address& rhs)
866{
867 return a.GetSection() != rhs.GetSection() ||
868 a.GetOffset() != rhs.GetOffset();
869}
870
871bool
872Address::IsLinkedAddress () const
873{
874 return m_section && m_section->GetLinkedSection();
875}
876
877
878void
879Address::ResolveLinkedAddress ()
880{
881 if (m_section)
882 {
883 const Section *linked_section = m_section->GetLinkedSection();
884 if (linked_section)
885 {
886 m_offset += m_section->GetLinkedOffset();
887 m_section = linked_section;
888 }
889 }
890}