blob: 4658cf27add997cacbee6d86fac62eb6713b7735 [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{
170 if (exe_scope == NULL)
171 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 {
180 DataExtractor data (buf.data(), buf.size(), byte_order, addr_size);
181
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 () :
244 m_section (NULL),
245 m_offset (LLDB_INVALID_ADDRESS)
246{
247}
248
249Address::Address (const Address& rhs) :
250 m_section (rhs.m_section),
251 m_offset (rhs.m_offset)
252{
253}
254
255Address::Address (const Section* section, addr_t offset) :
256 m_section (section),
257 m_offset (offset)
258{
259}
260
261Address::Address (addr_t address, const SectionList * sections) :
262 m_section (NULL),
263 m_offset (LLDB_INVALID_ADDRESS)
264{
265 ResolveAddressUsingFileSections(address, sections);
266}
267
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268const Address&
269Address::operator= (const Address& rhs)
270{
271 if (this != &rhs)
272 {
273 m_section = rhs.m_section;
274 m_offset = rhs.m_offset;
275 }
276 return *this;
277}
278
279bool
280Address::IsValid() const
281{
282 return m_offset != LLDB_INVALID_ADDRESS;
283}
284
285bool
286Address::IsSectionOffset() const
287{
288 return m_section != NULL && IsValid();
289}
290
291bool
292Address::ResolveAddressUsingFileSections (addr_t addr, const SectionList *sections)
293{
294 if (sections)
295 m_section = sections->FindSectionContainingFileAddress(addr).get();
296 else
297 m_section = NULL;
298
299 if (m_section != NULL)
300 {
301 assert( m_section->ContainsFileAddress(addr) );
302 m_offset = addr - m_section->GetFileAddress();
303 return true; // Successfully transformed addr into a section offset address
304 }
305
306 m_offset = addr;
307 return false; // Failed to resolve this address to a section offset value
308}
309
310//bool
311//Address::ResolveAddressUsingLoadSections (addr_t addr, const SectionList *sections)
312//{
313// if (sections)
314// m_section = sections->FindSectionContainingLoadAddress(addr).get();
315// else
316// m_section = NULL;
317//
318// if (m_section != NULL)
319// {
320// assert( m_section->ContainsLoadAddress(addr) );
321// m_offset = addr - m_section->GetLoadBaseAddress();
322// return true; // Successfully transformed addr into a section offset address
323// }
324//
325// m_offset = addr;
326// return false; // Failed to resolve this address to a section offset value
327//}
328//
329Module *
330Address::GetModule () const
331{
332 if (m_section)
333 return m_section->GetModule();
334 return NULL;
335}
336
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337//addr_t
338//Address::Address() const
339//{
340// addr_t addr = GetLoadAddress();
341// if (addr != LLDB_INVALID_ADDRESS)
342// return addr;
343// return GetFileAddress();
344//}
345//
346
347addr_t
348Address::GetFileAddress () const
349{
350 if (m_section != NULL)
351 {
352 addr_t sect_file_addr = m_section->GetFileAddress();
353 if (sect_file_addr == LLDB_INVALID_ADDRESS)
354 {
355 // Section isn't resolved, we can't return a valid file address
356 return LLDB_INVALID_ADDRESS;
357 }
358 // We have a valid file range, so we can return the file based
359 // address by adding the file base address to our offset
360 return sect_file_addr + m_offset;
361 }
362 // No section, we just return the offset since it is the value in this case
363 return m_offset;
364}
365
366addr_t
367Address::GetLoadAddress (Process *process) const
368{
369 if (m_section != NULL)
370 {
371 if (process)
372 {
373 addr_t sect_load_addr = m_section->GetLoadBaseAddress (process);
374
375 if (sect_load_addr != LLDB_INVALID_ADDRESS)
376 {
377 // We have a valid file range, so we can return the file based
378 // address by adding the file base address to our offset
379 return sect_load_addr + m_offset;
380 }
381 }
382 // The section isn't resolved or no process was supplied so we can't
383 // return a valid file address.
384 return LLDB_INVALID_ADDRESS;
385 }
386 // No section, we just return the offset since it is the value in this case
387 return m_offset;
388}
389
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390bool
391Address::SetOffset (addr_t offset)
392{
393 bool changed = m_offset != offset;
394 m_offset = offset;
395 return changed;
396}
397
398void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000399Address::Clear()
400{
401 m_section = NULL;
402 m_offset = LLDB_INVALID_ADDRESS;
403}
404
405
406bool
Greg Claytondda4f7b2010-06-30 23:03:03 +0000407Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000408{
409 // If the section was NULL, only load address is going to work.
410 if (m_section == NULL)
411 style = DumpStyleLoadAddress;
412
413 Process *process = NULL;
414 if (exe_scope)
415 process = exe_scope->CalculateProcess();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000416 // If addr_byte_size is UINT32_MAX, then determine the correct address
417 // byte size for the process or default to the size of addr_t
418 if (addr_size == UINT32_MAX)
419 {
420 if (process)
421 addr_size = process->GetAddressByteSize ();
422 else
423 addr_size = sizeof(addr_t);
424 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000425
426 lldb_private::Address so_addr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000427 switch (style)
428 {
429 case DumpStyleSectionNameOffset:
430 if (m_section != NULL)
431 {
432 m_section->DumpName(s);
433 s->Printf (" + %llu", m_offset);
434 }
435 else
436 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000437 s->Address(m_offset, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438 }
439 break;
440
441 case DumpStyleSectionPointerOffset:
Greg Claytondda4f7b2010-06-30 23:03:03 +0000442 s->Printf("(Section *)%.*p + ", (int)sizeof(void*) * 2, m_section);
443 s->Address(m_offset, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000444 break;
445
446 case DumpStyleModuleWithFileAddress:
447 s->Printf("%s[", m_section->GetModule()->GetFileSpec().GetFilename().AsCString());
448 // Fall through
449 case DumpStyleFileAddress:
450 {
451 addr_t file_addr = GetFileAddress();
452 if (file_addr == LLDB_INVALID_ADDRESS)
453 {
454 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000455 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456 return false;
457 }
458 s->Address (file_addr, addr_size);
459 if (style == DumpStyleModuleWithFileAddress)
460 s->PutChar(']');
461 }
462 break;
463
464 case DumpStyleLoadAddress:
465 {
466 addr_t load_addr = GetLoadAddress (process);
467 if (load_addr == LLDB_INVALID_ADDRESS)
468 {
469 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000470 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000471 return false;
472 }
473 s->Address (load_addr, addr_size);
474 }
475 break;
476
477 case DumpStyleResolvedDescription:
478 if (IsSectionOffset())
479 {
480 lldb::AddressType addr_type = eAddressTypeLoad;
481 addr_t addr = GetLoadAddress (process);
482 if (addr == LLDB_INVALID_ADDRESS)
483 {
484 addr = GetFileAddress();
485 addr_type = eAddressTypeFile;
486 }
487
488 uint32_t pointer_size = 4;
489 lldb_private::Module *module = GetModule();
490 if (process)
491 pointer_size = process->GetAddressByteSize();
492 else if (module)
493 pointer_size = module->GetArchitecture().GetAddressByteSize();
494
495 bool showed_info = false;
496 const Section *section = GetSection();
497 if (section)
498 {
499 SectionType sect_type = section->GetSectionType();
500 switch (sect_type)
501 {
502 case eSectionTypeDataCString:
503 // Read the C string from memory and display it
504 showed_info = true;
505 ReadCStringFromMemory (exe_scope, *this, s);
506 break;
507
508 case eSectionTypeDataCStringPointers:
509 {
510 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
511 {
512#if VERBOSE_OUTPUT
513 s->PutCString("(char *)");
514 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
515 s->PutCString(": ");
516#endif
517 showed_info = true;
518 ReadCStringFromMemory (exe_scope, so_addr, s);
519 }
520 }
521 break;
522
523 case eSectionTypeDataObjCMessageRefs:
524 {
525 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
526 {
527 if (so_addr.IsSectionOffset())
528 {
529 lldb_private::SymbolContext func_sc;
530 process->GetTarget().GetImages().ResolveSymbolContextForAddress (so_addr,
531 eSymbolContextEverything,
532 func_sc);
533 if (func_sc.function || func_sc.symbol)
534 {
535 showed_info = true;
536#if VERBOSE_OUTPUT
537 s->PutCString ("(objc_msgref *) -> { (func*)");
538 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
539#else
540 s->PutCString ("{ ");
541#endif
542 Address cstr_addr(*this);
543 cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
544 func_sc.DumpStopContext(s, process, so_addr, true);
545 if (ReadAddress (exe_scope, cstr_addr, pointer_size, so_addr))
546 {
547#if VERBOSE_OUTPUT
548 s->PutCString("), (char *)");
549 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
550 s->PutCString(" (");
551#else
552 s->PutCString(", ");
553#endif
554 ReadCStringFromMemory (exe_scope, so_addr, s);
555 }
556#if VERBOSE_OUTPUT
557 s->PutCString(") }");
558#else
559 s->PutCString(" }");
560#endif
561 }
562 }
563 }
564 }
565 break;
566
567 case eSectionTypeDataObjCCFStrings:
568 {
569 Address cfstring_data_addr(*this);
570 cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() + (2 * pointer_size));
571 if (ReadAddress (exe_scope, cfstring_data_addr, pointer_size, so_addr))
572 {
573#if VERBOSE_OUTPUT
574 s->PutCString("(CFString *) ");
575 cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
576 s->PutCString(" -> @");
577#else
578 s->PutChar('@');
579#endif
580 if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
581 showed_info = true;
582 }
583 }
584 break;
585
586 case eSectionTypeData4:
587 // Read the 4 byte data and display it
588 showed_info = true;
589 s->PutCString("(uint32_t) ");
590 DumpUInt (exe_scope, *this, 4, s);
591 break;
592
593 case eSectionTypeData8:
594 // Read the 8 byte data and display it
595 showed_info = true;
596 s->PutCString("(uint64_t) ");
597 DumpUInt (exe_scope, *this, 8, s);
598 break;
599
600 case eSectionTypeData16:
601 // Read the 16 byte data and display it
602 showed_info = true;
603 s->PutCString("(uint128_t) ");
604 DumpUInt (exe_scope, *this, 16, s);
605 break;
606
607 case eSectionTypeDataPointers:
608 // Read the pointer data and display it
609 {
610 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
611 {
612 s->PutCString ("(void *)");
613 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
614
615 showed_info = true;
616 if (so_addr.IsSectionOffset())
617 {
618 lldb_private::SymbolContext pointer_sc;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000619 Target *target = exe_scope->CalculateTarget();
620 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000621 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000622 target->GetImages().ResolveSymbolContextForAddress (so_addr,
623 eSymbolContextEverything,
624 pointer_sc);
625 if (pointer_sc.function || pointer_sc.symbol)
626 {
627 s->PutCString(": ");
628 pointer_sc.DumpStopContext(s, process, so_addr, false);
629 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000630 }
631 }
632 }
633 }
634 break;
635 }
636 }
637
638 if (!showed_info)
639 {
640 if (module)
641 {
642 lldb_private::SymbolContext sc;
643 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
644 if (sc.function || sc.symbol)
645 {
646 bool show_stop_context = true;
647 if (sc.function == NULL && sc.symbol != NULL)
648 {
649 // If we have just a symbol make sure it is in the right section
650 if (sc.symbol->GetAddressRangePtr())
651 {
652 if (sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection())
653 show_stop_context = false;
654 }
655 }
656 if (show_stop_context)
657 {
658 // We have a function or a symbol from the same
659 // sections as this address.
Greg Claytondda4f7b2010-06-30 23:03:03 +0000660 sc.DumpStopContext(s, process, *this, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000661 }
662 else
663 {
664 // We found a symbol but it was in a different
665 // section so it isn't the symbol we should be
666 // showing, just show the section name + offset
667 Dump (s, exe_scope, DumpStyleSectionNameOffset);
668 }
669 }
670 }
671 }
672 }
673 else
674 {
675 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000676 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000677 return false;
678 }
679 break;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000680
681 case DumpStyleDetailedSymbolContext:
682 if (IsSectionOffset())
683 {
684 lldb::AddressType addr_type = eAddressTypeLoad;
685 addr_t addr = GetLoadAddress (process);
686 if (addr == LLDB_INVALID_ADDRESS)
687 {
688 addr = GetFileAddress();
689 addr_type = eAddressTypeFile;
690 }
691
692 lldb_private::Module *module = GetModule();
693 if (module)
694 {
695 lldb_private::SymbolContext sc;
696 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
697 if (sc.function || sc.symbol)
698 {
699 if (sc.function == NULL && sc.symbol != NULL)
700 {
701 // If we have just a symbol make sure it is in the right section
702 if (sc.symbol->GetAddressRangePtr() && sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() == GetSection())
703 {
704 sc.GetDescription(s, eDescriptionLevelBrief, process);
705 break;
706 }
707 }
708 }
709 }
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
742void
743Address::DumpSymbolContext (Stream *s)
744{
745 SymbolContext sc;
746 CalculateSymbolContext (&sc);
747 sc.Dump (s, NULL);
748}
749
750void
751Address::DumpDebug(Stream *s) const
752{
753 *s << (void *)this << ": " << "Address";
754 if (m_section != NULL)
755 {
756 *s << ", section = " << (void *)m_section << " (" << m_section->GetName() << "), offset = " << m_offset;
757 }
758 else
759 {
760 *s << ", vm_addr = " << m_offset;
761 }
762 s->EOL();
763}
764
765int
766Address::CompareFileAddress (const Address& a, const Address& b)
767{
768 addr_t a_file_addr = a.GetFileAddress();
769 addr_t b_file_addr = b.GetFileAddress();
770 if (a_file_addr < b_file_addr)
771 return -1;
772 if (a_file_addr > b_file_addr)
773 return +1;
774 return 0;
775}
776
777
778int
779Address::CompareLoadAddress (const Address& a, const Address& b, Process *process)
780{
781 assert (process != NULL);
782 addr_t a_load_addr = a.GetLoadAddress (process);
783 addr_t b_load_addr = b.GetLoadAddress (process);
784 if (a_load_addr < b_load_addr)
785 return -1;
786 if (a_load_addr > b_load_addr)
787 return +1;
788 return 0;
789}
790
791int
792Address::CompareModulePointerAndOffset (const Address& a, const Address& b)
793{
794 Module *a_module = a.GetModule ();
795 Module *b_module = b.GetModule ();
796 if (a_module < b_module)
797 return -1;
798 if (a_module > b_module)
799 return +1;
800 // Modules are the same, just compare the file address since they should
801 // be unique
802 addr_t a_file_addr = a.GetFileAddress();
803 addr_t b_file_addr = b.GetFileAddress();
804 if (a_file_addr < b_file_addr)
805 return -1;
806 if (a_file_addr > b_file_addr)
807 return +1;
808 return 0;
809}
810
811
812size_t
813Address::MemorySize () const
814{
815 // Noting special for the memory size of a single Address object,
816 // it is just the size of itself.
817 return sizeof(Address);
818}
819
820
821/// The only comparisons that make sense are the load addresses
822//bool
823//lldb::operator< (const Address& lhs, const Address& rhs)
824//{
825// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
826// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
827//
828// if (lhs_addr == rhs_addr)
829// {
830// lhs_addr = lhs.GetFileAddress();
831// rhs_addr = rhs.GetFileAddress();
832// }
833// return lhs_addr < rhs_addr;
834//}
835//
836//bool
837//lldb::operator<= (const Address& lhs, const Address& rhs)
838//{
839// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
840// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
841//
842// if (lhs_addr == rhs_addr)
843// {
844// lhs_addr = lhs.GetFileAddress();
845// rhs_addr = rhs.GetFileAddress();
846// }
847// return lhs_addr <= rhs_addr;
848//}
849//
850//bool
851//lldb::operator> (const Address& lhs, const Address& rhs)
852//{
853// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
854// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
855//
856// if (lhs_addr == rhs_addr)
857// {
858// lhs_addr = lhs.GetFileAddress();
859// rhs_addr = rhs.GetFileAddress();
860// }
861// return lhs_addr > rhs_addr;
862//}
863//
864//bool
865//lldb::operator>= (const Address& lhs, const Address& rhs)
866//{
867// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
868// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
869//
870// if (lhs_addr == rhs_addr)
871// {
872// lhs_addr = lhs.GetFileAddress();
873// rhs_addr = rhs.GetFileAddress();
874// }
875// return lhs_addr >= rhs_addr;
876//}
877//
878
879// The operator == checks for exact equality only (same section, same offset)
880bool
881lldb_private::operator== (const Address& a, const Address& rhs)
882{
883 return a.GetSection() == rhs.GetSection() &&
884 a.GetOffset() == rhs.GetOffset();
885}
886// The operator != checks for exact inequality only (differing section, or
887// different offset)
888bool
889lldb_private::operator!= (const Address& a, const Address& rhs)
890{
891 return a.GetSection() != rhs.GetSection() ||
892 a.GetOffset() != rhs.GetOffset();
893}
894
895bool
896Address::IsLinkedAddress () const
897{
898 return m_section && m_section->GetLinkedSection();
899}
900
901
902void
903Address::ResolveLinkedAddress ()
904{
905 if (m_section)
906 {
907 const Section *linked_section = m_section->GetLinkedSection();
908 if (linked_section)
909 {
910 m_offset += m_section->GetLinkedOffset();
911 m_section = linked_section;
912 }
913 }
914}