blob: 97595326b346a22a53fa05d464c75f123548a97a [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"
14#include "lldb/Target/Process.h"
15#include "lldb/Target/Target.h"
16
17using namespace lldb;
18using namespace lldb_private;
19
Greg Claytondda4f7b2010-06-30 23:03:03 +000020//static size_t
21//ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst, size_t dst_len)
22//{
23// if (exe_scope == NULL)
24// return 0;
25//
26// lldb::AddressType addr_type = eAddressTypeInvalid;
27// addr_t addr = LLDB_INVALID_ADDRESS;
28//
29// Process *process = exe_scope->CalculateProcess();
30//
31// if (process && process->IsAlive())
32// {
33// addr = address.GetLoadAddress(process);
34// if (addr != LLDB_INVALID_ADDRESS)
35// addr_type = eAddressTypeLoad;
36// }
37//
38// if (addr == LLDB_INVALID_ADDRESS)
39// {
40// addr = address.GetFileAddress();
41// if (addr != LLDB_INVALID_ADDRESS)
42// addr_type = eAddressTypeFile;
43// }
44//
45// if (addr_type == eAddressTypeInvalid)
46// return false;
47//
48// Target *target = exe_scope->CalculateTarget();
49// if (target)
50// {
51// Error error;
52// ObjectFile *objfile = NULL;
53// if (address.GetModule())
54// objfile = address.GetModule()->GetObjectFile();
55// return target->ReadMemory (addr_type, addr, dst, dst_len, error, objfile);
56// }
57// return 0;
58//}
59
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060static size_t
61ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst, size_t dst_len)
62{
63 if (exe_scope == NULL)
64 return 0;
65
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066 Target *target = exe_scope->CalculateTarget();
67 if (target)
68 {
69 Error error;
Greg Claytondda4f7b2010-06-30 23:03:03 +000070 return target->ReadMemory (address, dst, dst_len, error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071 }
72 return 0;
73}
74
75static bool
76GetByteOrderAndAddressSize (ExecutionContextScope *exe_scope, const Address &address, ByteOrder& byte_order, uint32_t& addr_size)
77{
78 byte_order = eByteOrderInvalid;
79 addr_size = 0;
80 if (exe_scope == NULL)
81 return false;
82
83 Process *process = exe_scope->CalculateProcess();
84 if (process)
85 {
86 byte_order = process->GetByteOrder();
87 addr_size = process->GetAddressByteSize();
88 }
89
90 if (byte_order == eByteOrderInvalid || addr_size == 0)
91 {
92 Module *module = address.GetModule();
93 if (module)
94 {
95 byte_order = module->GetArchitecture().GetDefaultEndian();
96 addr_size = module->GetArchitecture().GetAddressByteSize();
97 }
98 }
99 return byte_order != eByteOrderInvalid && addr_size != 0;
100}
101
102static uint64_t
103ReadUIntMax64 (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, bool &success)
104{
105 uint64_t uval64 = 0;
106 if (exe_scope == NULL || byte_size > sizeof(uint64_t))
107 {
108 success = false;
109 return 0;
110 }
111 uint64_t buf;
112
113 success = ReadBytes (exe_scope, address, &buf, byte_size) == byte_size;
114 if (success)
115 {
116 ByteOrder byte_order = eByteOrderInvalid;
117 uint32_t addr_size = 0;
118 if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size))
119 {
120 DataExtractor data (&buf, sizeof(buf), byte_order, addr_size);
121 uint32_t offset = 0;
122 uval64 = data.GetU64(&offset);
123 }
124 else
125 success = false;
126 }
127 return uval64;
128}
129
130static bool
131ReadAddress (ExecutionContextScope *exe_scope, const Address &address, uint32_t pointer_size, Address &deref_so_addr)
132{
133 if (exe_scope == NULL)
134 return false;
135
136
137 bool success = false;
138 addr_t deref_addr = ReadUIntMax64 (exe_scope, address, pointer_size, success);
139 if (success)
140 {
141 Process *process = exe_scope->CalculateProcess();
142 if (process && process->IsAlive())
143 {
144 if (!process->ResolveLoadAddress (deref_addr, deref_so_addr))
145 {
146 deref_so_addr.SetSection(NULL);
147 deref_so_addr.SetOffset(deref_addr);
148 }
149 }
150 else
151 {
152 Target *target = exe_scope->CalculateTarget();
153 if (target == NULL)
154 return false;
155
156 if (!target->GetImages().ResolveFileAddress(deref_addr, deref_so_addr))
157 {
158 deref_so_addr.SetSection(NULL);
159 deref_so_addr.SetOffset(deref_addr);
160 }
161 }
162 return true;
163 }
164 return false;
165}
166
167static bool
168DumpUInt (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, Stream* strm)
169{
Greg Clayton471b31c2010-07-20 22:52:08 +0000170 if (exe_scope == NULL || byte_size == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171 return 0;
172 std::vector<uint8_t> buf(byte_size, 0);
173
174 if (ReadBytes (exe_scope, address, &buf[0], buf.size()) == buf.size())
175 {
176 ByteOrder byte_order = eByteOrderInvalid;
177 uint32_t addr_size = 0;
178 if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size))
179 {
Greg Clayton471b31c2010-07-20 22:52:08 +0000180 DataExtractor data (&buf.front(), buf.size(), byte_order, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181
182 data.Dump (strm,
183 0, // Start offset in "data"
184 eFormatHex, // Print as characters
185 buf.size(), // Size of item
186 1, // Items count
187 UINT32_MAX, // num per line
188 LLDB_INVALID_ADDRESS,// base address
189 0, // bitfield bit size
190 0); // bitfield bit offset
191
192 return true;
193 }
194 }
195 return false;
196}
197
198
199static size_t
200ReadCStringFromMemory (ExecutionContextScope *exe_scope, const Address &address, Stream *strm)
201{
202 if (exe_scope == NULL)
203 return 0;
204 const size_t k_buf_len = 256;
205 char buf[k_buf_len+1];
206 buf[k_buf_len] = '\0'; // NULL terminate
207
208 // Byte order and adderss size don't matter for C string dumping..
209 DataExtractor data (buf, sizeof(buf), eByteOrderHost, 4);
210 size_t total_len = 0;
211 size_t bytes_read;
212 Address curr_address(address);
213 strm->PutChar ('"');
214 while ((bytes_read = ReadBytes (exe_scope, curr_address, buf, k_buf_len)) > 0)
215 {
216 size_t len = strlen(buf);
217 if (len == 0)
218 break;
219 if (len > bytes_read)
220 len = bytes_read;
221
222 data.Dump (strm,
223 0, // Start offset in "data"
224 eFormatChar, // Print as characters
225 1, // Size of item (1 byte for a char!)
226 len, // How many bytes to print?
227 UINT32_MAX, // num per line
228 LLDB_INVALID_ADDRESS,// base address
229 0, // bitfield bit size
230
231 0); // bitfield bit offset
232
233 total_len += bytes_read;
234
235 if (len < k_buf_len)
236 break;
237 curr_address.SetOffset (curr_address.GetOffset() + bytes_read);
238 }
239 strm->PutChar ('"');
240 return total_len;
241}
242
243Address::Address () :
Greg Claytonc982c762010-07-09 20:39:50 +0000244 SymbolContextScope(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245 m_section (NULL),
246 m_offset (LLDB_INVALID_ADDRESS)
247{
248}
249
250Address::Address (const Address& rhs) :
Greg Claytonc982c762010-07-09 20:39:50 +0000251 SymbolContextScope(rhs),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000252 m_section (rhs.m_section),
253 m_offset (rhs.m_offset)
254{
255}
256
257Address::Address (const Section* section, addr_t offset) :
Greg Claytonc982c762010-07-09 20:39:50 +0000258 SymbolContextScope(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259 m_section (section),
260 m_offset (offset)
261{
262}
263
264Address::Address (addr_t address, const SectionList * sections) :
Greg Claytonc982c762010-07-09 20:39:50 +0000265 SymbolContextScope(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000266 m_section (NULL),
267 m_offset (LLDB_INVALID_ADDRESS)
268{
269 ResolveAddressUsingFileSections(address, sections);
270}
271
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000272const Address&
273Address::operator= (const Address& rhs)
274{
275 if (this != &rhs)
276 {
277 m_section = rhs.m_section;
278 m_offset = rhs.m_offset;
279 }
280 return *this;
281}
282
283bool
284Address::IsValid() const
285{
286 return m_offset != LLDB_INVALID_ADDRESS;
287}
288
289bool
290Address::IsSectionOffset() const
291{
292 return m_section != NULL && IsValid();
293}
294
295bool
296Address::ResolveAddressUsingFileSections (addr_t addr, const SectionList *sections)
297{
298 if (sections)
299 m_section = sections->FindSectionContainingFileAddress(addr).get();
300 else
301 m_section = NULL;
302
303 if (m_section != NULL)
304 {
305 assert( m_section->ContainsFileAddress(addr) );
306 m_offset = addr - m_section->GetFileAddress();
307 return true; // Successfully transformed addr into a section offset address
308 }
309
310 m_offset = addr;
311 return false; // Failed to resolve this address to a section offset value
312}
313
314//bool
315//Address::ResolveAddressUsingLoadSections (addr_t addr, const SectionList *sections)
316//{
317// if (sections)
318// m_section = sections->FindSectionContainingLoadAddress(addr).get();
319// else
320// m_section = NULL;
321//
322// if (m_section != NULL)
323// {
324// assert( m_section->ContainsLoadAddress(addr) );
325// m_offset = addr - m_section->GetLoadBaseAddress();
326// return true; // Successfully transformed addr into a section offset address
327// }
328//
329// m_offset = addr;
330// return false; // Failed to resolve this address to a section offset value
331//}
332//
333Module *
334Address::GetModule () const
335{
336 if (m_section)
337 return m_section->GetModule();
338 return NULL;
339}
340
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341//addr_t
342//Address::Address() const
343//{
344// addr_t addr = GetLoadAddress();
345// if (addr != LLDB_INVALID_ADDRESS)
346// return addr;
347// return GetFileAddress();
348//}
349//
350
351addr_t
352Address::GetFileAddress () const
353{
354 if (m_section != NULL)
355 {
356 addr_t sect_file_addr = m_section->GetFileAddress();
357 if (sect_file_addr == LLDB_INVALID_ADDRESS)
358 {
359 // Section isn't resolved, we can't return a valid file address
360 return LLDB_INVALID_ADDRESS;
361 }
362 // We have a valid file range, so we can return the file based
363 // address by adding the file base address to our offset
364 return sect_file_addr + m_offset;
365 }
366 // No section, we just return the offset since it is the value in this case
367 return m_offset;
368}
369
370addr_t
371Address::GetLoadAddress (Process *process) const
372{
373 if (m_section != NULL)
374 {
375 if (process)
376 {
377 addr_t sect_load_addr = m_section->GetLoadBaseAddress (process);
378
379 if (sect_load_addr != LLDB_INVALID_ADDRESS)
380 {
381 // We have a valid file range, so we can return the file based
382 // address by adding the file base address to our offset
383 return sect_load_addr + m_offset;
384 }
385 }
386 // The section isn't resolved or no process was supplied so we can't
387 // return a valid file address.
388 return LLDB_INVALID_ADDRESS;
389 }
390 // No section, we just return the offset since it is the value in this case
391 return m_offset;
392}
393
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000394bool
395Address::SetOffset (addr_t offset)
396{
397 bool changed = m_offset != offset;
398 m_offset = offset;
399 return changed;
400}
401
402void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403Address::Clear()
404{
405 m_section = NULL;
406 m_offset = LLDB_INVALID_ADDRESS;
407}
408
409
410bool
Greg Claytondda4f7b2010-06-30 23:03:03 +0000411Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000412{
413 // If the section was NULL, only load address is going to work.
414 if (m_section == NULL)
415 style = DumpStyleLoadAddress;
416
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000417 Target *target = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000418 Process *process = NULL;
419 if (exe_scope)
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000420 {
421 target = exe_scope->CalculateTarget();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422 process = exe_scope->CalculateProcess();
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000423 }
Greg Claytondda4f7b2010-06-30 23:03:03 +0000424 // If addr_byte_size is UINT32_MAX, then determine the correct address
425 // byte size for the process or default to the size of addr_t
426 if (addr_size == UINT32_MAX)
427 {
428 if (process)
429 addr_size = process->GetAddressByteSize ();
430 else
431 addr_size = sizeof(addr_t);
432 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000433
434 lldb_private::Address so_addr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435 switch (style)
436 {
Greg Claytonc982c762010-07-09 20:39:50 +0000437 case DumpStyleInvalid:
438 return false;
439
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000440 case DumpStyleSectionNameOffset:
441 if (m_section != NULL)
442 {
443 m_section->DumpName(s);
444 s->Printf (" + %llu", m_offset);
445 }
446 else
447 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000448 s->Address(m_offset, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000449 }
450 break;
451
452 case DumpStyleSectionPointerOffset:
Greg Claytondda4f7b2010-06-30 23:03:03 +0000453 s->Printf("(Section *)%.*p + ", (int)sizeof(void*) * 2, m_section);
454 s->Address(m_offset, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455 break;
456
457 case DumpStyleModuleWithFileAddress:
458 s->Printf("%s[", m_section->GetModule()->GetFileSpec().GetFilename().AsCString());
459 // Fall through
460 case DumpStyleFileAddress:
461 {
462 addr_t file_addr = GetFileAddress();
463 if (file_addr == LLDB_INVALID_ADDRESS)
464 {
465 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000466 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467 return false;
468 }
469 s->Address (file_addr, addr_size);
470 if (style == DumpStyleModuleWithFileAddress)
471 s->PutChar(']');
472 }
473 break;
474
475 case DumpStyleLoadAddress:
476 {
477 addr_t load_addr = GetLoadAddress (process);
478 if (load_addr == LLDB_INVALID_ADDRESS)
479 {
480 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000481 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000482 return false;
483 }
484 s->Address (load_addr, addr_size);
485 }
486 break;
487
488 case DumpStyleResolvedDescription:
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000489 case DumpStyleResolvedDescriptionNoModule:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000490 if (IsSectionOffset())
491 {
492 lldb::AddressType addr_type = eAddressTypeLoad;
493 addr_t addr = GetLoadAddress (process);
494 if (addr == LLDB_INVALID_ADDRESS)
495 {
496 addr = GetFileAddress();
497 addr_type = eAddressTypeFile;
498 }
499
500 uint32_t pointer_size = 4;
501 lldb_private::Module *module = GetModule();
502 if (process)
503 pointer_size = process->GetAddressByteSize();
504 else if (module)
505 pointer_size = module->GetArchitecture().GetAddressByteSize();
506
507 bool showed_info = false;
508 const Section *section = GetSection();
509 if (section)
510 {
Greg Clayton70e33eb2010-07-21 21:49:46 +0000511 SectionType sect_type = section->GetType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000512 switch (sect_type)
513 {
514 case eSectionTypeDataCString:
515 // Read the C string from memory and display it
516 showed_info = true;
517 ReadCStringFromMemory (exe_scope, *this, s);
518 break;
519
520 case eSectionTypeDataCStringPointers:
521 {
522 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
523 {
524#if VERBOSE_OUTPUT
525 s->PutCString("(char *)");
526 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
527 s->PutCString(": ");
528#endif
529 showed_info = true;
530 ReadCStringFromMemory (exe_scope, so_addr, s);
531 }
532 }
533 break;
534
535 case eSectionTypeDataObjCMessageRefs:
536 {
537 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
538 {
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000539 if (target && so_addr.IsSectionOffset())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000540 {
541 lldb_private::SymbolContext func_sc;
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000542 target->GetImages().ResolveSymbolContextForAddress (so_addr,
543 eSymbolContextEverything,
544 func_sc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000545 if (func_sc.function || func_sc.symbol)
546 {
547 showed_info = true;
548#if VERBOSE_OUTPUT
549 s->PutCString ("(objc_msgref *) -> { (func*)");
550 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
551#else
552 s->PutCString ("{ ");
553#endif
554 Address cstr_addr(*this);
555 cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000556 func_sc.DumpStopContext(s, exe_scope, so_addr, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000557 if (ReadAddress (exe_scope, cstr_addr, pointer_size, so_addr))
558 {
559#if VERBOSE_OUTPUT
560 s->PutCString("), (char *)");
561 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
562 s->PutCString(" (");
563#else
564 s->PutCString(", ");
565#endif
566 ReadCStringFromMemory (exe_scope, so_addr, s);
567 }
568#if VERBOSE_OUTPUT
569 s->PutCString(") }");
570#else
571 s->PutCString(" }");
572#endif
573 }
574 }
575 }
576 }
577 break;
578
579 case eSectionTypeDataObjCCFStrings:
580 {
581 Address cfstring_data_addr(*this);
582 cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() + (2 * pointer_size));
583 if (ReadAddress (exe_scope, cfstring_data_addr, pointer_size, so_addr))
584 {
585#if VERBOSE_OUTPUT
586 s->PutCString("(CFString *) ");
587 cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
588 s->PutCString(" -> @");
589#else
590 s->PutChar('@');
591#endif
592 if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
593 showed_info = true;
594 }
595 }
596 break;
597
598 case eSectionTypeData4:
599 // Read the 4 byte data and display it
600 showed_info = true;
601 s->PutCString("(uint32_t) ");
602 DumpUInt (exe_scope, *this, 4, s);
603 break;
604
605 case eSectionTypeData8:
606 // Read the 8 byte data and display it
607 showed_info = true;
608 s->PutCString("(uint64_t) ");
609 DumpUInt (exe_scope, *this, 8, s);
610 break;
611
612 case eSectionTypeData16:
613 // Read the 16 byte data and display it
614 showed_info = true;
615 s->PutCString("(uint128_t) ");
616 DumpUInt (exe_scope, *this, 16, s);
617 break;
618
619 case eSectionTypeDataPointers:
620 // Read the pointer data and display it
621 {
622 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
623 {
624 s->PutCString ("(void *)");
625 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
626
627 showed_info = true;
628 if (so_addr.IsSectionOffset())
629 {
630 lldb_private::SymbolContext pointer_sc;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000631 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000632 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000633 target->GetImages().ResolveSymbolContextForAddress (so_addr,
634 eSymbolContextEverything,
635 pointer_sc);
636 if (pointer_sc.function || pointer_sc.symbol)
637 {
638 s->PutCString(": ");
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000639 pointer_sc.DumpStopContext(s, exe_scope, so_addr, false);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000640 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000641 }
642 }
643 }
644 }
645 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000646
647 default:
648 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000649 }
650 }
651
652 if (!showed_info)
653 {
654 if (module)
655 {
656 lldb_private::SymbolContext sc;
657 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
658 if (sc.function || sc.symbol)
659 {
660 bool show_stop_context = true;
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000661 bool show_module = (style == DumpStyleResolvedDescription);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000662 if (sc.function == NULL && sc.symbol != NULL)
663 {
664 // If we have just a symbol make sure it is in the right section
665 if (sc.symbol->GetAddressRangePtr())
666 {
667 if (sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection())
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000668 {
669 // don't show the module if the symbol is a trampoline symbol
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000670 show_stop_context = false;
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000671 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000672 }
673 }
674 if (show_stop_context)
675 {
676 // We have a function or a symbol from the same
677 // sections as this address.
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000678 sc.DumpStopContext(s, exe_scope, *this, show_module);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000679 }
680 else
681 {
682 // We found a symbol but it was in a different
683 // section so it isn't the symbol we should be
684 // showing, just show the section name + offset
685 Dump (s, exe_scope, DumpStyleSectionNameOffset);
686 }
687 }
688 }
689 }
690 }
691 else
692 {
693 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000694 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000695 return false;
696 }
697 break;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000698
699 case DumpStyleDetailedSymbolContext:
700 if (IsSectionOffset())
701 {
702 lldb::AddressType addr_type = eAddressTypeLoad;
703 addr_t addr = GetLoadAddress (process);
704 if (addr == LLDB_INVALID_ADDRESS)
705 {
706 addr = GetFileAddress();
707 addr_type = eAddressTypeFile;
708 }
709
710 lldb_private::Module *module = GetModule();
711 if (module)
712 {
713 lldb_private::SymbolContext sc;
714 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
715 if (sc.function || sc.symbol)
716 {
717 if (sc.function == NULL && sc.symbol != NULL)
718 {
719 // If we have just a symbol make sure it is in the right section
720 if (sc.symbol->GetAddressRangePtr() && sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() == GetSection())
721 {
722 sc.GetDescription(s, eDescriptionLevelBrief, process);
723 break;
724 }
725 }
726 }
727 }
728 }
729 if (fallback_style != DumpStyleInvalid)
730 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
731 return false;
732 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000733 }
734
735 return true;
736}
737
738//Stream& operator << (Stream& s, const Address& so_addr)
739//{
740// so_addr.Dump(&s, Address::DumpStyleSectionNameOffset);
741// return s;
742//}
743//
744void
745Address::CalculateSymbolContext (SymbolContext *sc)
746{
747 sc->Clear();
748 // Absolute addresses don't have enough information to reconstruct even their target.
749 if (m_section == NULL)
750 return;
751
752 if (m_section->GetModule())
753 {
754 sc->module_sp = m_section->GetModule()->GetSP();
755 if (sc->module_sp)
756 sc->module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextEverything, *sc);
757 }
758}
759
760void
761Address::DumpSymbolContext (Stream *s)
762{
763 SymbolContext sc;
764 CalculateSymbolContext (&sc);
765 sc.Dump (s, NULL);
766}
767
768void
769Address::DumpDebug(Stream *s) const
770{
771 *s << (void *)this << ": " << "Address";
772 if (m_section != NULL)
773 {
774 *s << ", section = " << (void *)m_section << " (" << m_section->GetName() << "), offset = " << m_offset;
775 }
776 else
777 {
778 *s << ", vm_addr = " << m_offset;
779 }
780 s->EOL();
781}
782
783int
784Address::CompareFileAddress (const Address& a, const Address& b)
785{
786 addr_t a_file_addr = a.GetFileAddress();
787 addr_t b_file_addr = b.GetFileAddress();
788 if (a_file_addr < b_file_addr)
789 return -1;
790 if (a_file_addr > b_file_addr)
791 return +1;
792 return 0;
793}
794
795
796int
797Address::CompareLoadAddress (const Address& a, const Address& b, Process *process)
798{
799 assert (process != NULL);
800 addr_t a_load_addr = a.GetLoadAddress (process);
801 addr_t b_load_addr = b.GetLoadAddress (process);
802 if (a_load_addr < b_load_addr)
803 return -1;
804 if (a_load_addr > b_load_addr)
805 return +1;
806 return 0;
807}
808
809int
810Address::CompareModulePointerAndOffset (const Address& a, const Address& b)
811{
812 Module *a_module = a.GetModule ();
813 Module *b_module = b.GetModule ();
814 if (a_module < b_module)
815 return -1;
816 if (a_module > b_module)
817 return +1;
818 // Modules are the same, just compare the file address since they should
819 // be unique
820 addr_t a_file_addr = a.GetFileAddress();
821 addr_t b_file_addr = b.GetFileAddress();
822 if (a_file_addr < b_file_addr)
823 return -1;
824 if (a_file_addr > b_file_addr)
825 return +1;
826 return 0;
827}
828
829
830size_t
831Address::MemorySize () const
832{
833 // Noting special for the memory size of a single Address object,
834 // it is just the size of itself.
835 return sizeof(Address);
836}
837
838
839/// The only comparisons that make sense are the load addresses
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//bool
855//lldb::operator<= (const Address& lhs, const Address& rhs)
856//{
857// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
858// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
859//
860// if (lhs_addr == rhs_addr)
861// {
862// lhs_addr = lhs.GetFileAddress();
863// rhs_addr = rhs.GetFileAddress();
864// }
865// return lhs_addr <= rhs_addr;
866//}
867//
868//bool
869//lldb::operator> (const Address& lhs, const Address& rhs)
870//{
871// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
872// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
873//
874// if (lhs_addr == rhs_addr)
875// {
876// lhs_addr = lhs.GetFileAddress();
877// rhs_addr = rhs.GetFileAddress();
878// }
879// return lhs_addr > rhs_addr;
880//}
881//
882//bool
883//lldb::operator>= (const Address& lhs, const Address& rhs)
884//{
885// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
886// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
887//
888// if (lhs_addr == rhs_addr)
889// {
890// lhs_addr = lhs.GetFileAddress();
891// rhs_addr = rhs.GetFileAddress();
892// }
893// return lhs_addr >= rhs_addr;
894//}
895//
896
897// The operator == checks for exact equality only (same section, same offset)
898bool
899lldb_private::operator== (const Address& a, const Address& rhs)
900{
901 return a.GetSection() == rhs.GetSection() &&
902 a.GetOffset() == rhs.GetOffset();
903}
904// The operator != checks for exact inequality only (differing section, or
905// different offset)
906bool
907lldb_private::operator!= (const Address& a, const Address& rhs)
908{
909 return a.GetSection() != rhs.GetSection() ||
910 a.GetOffset() != rhs.GetOffset();
911}
912
913bool
914Address::IsLinkedAddress () const
915{
916 return m_section && m_section->GetLinkedSection();
917}
918
919
920void
921Address::ResolveLinkedAddress ()
922{
923 if (m_section)
924 {
925 const Section *linked_section = m_section->GetLinkedSection();
926 if (linked_section)
927 {
928 m_offset += m_section->GetLinkedOffset();
929 m_section = linked_section;
930 }
931 }
932}