blob: 68b4b48bce2d7db165a2858d1b6a122743841b07 [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
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000243Address::Address (addr_t address, const SectionList * sections) :
244 m_section (NULL),
245 m_offset (LLDB_INVALID_ADDRESS)
246{
247 ResolveAddressUsingFileSections(address, sections);
248}
249
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250const Address&
251Address::operator= (const Address& rhs)
252{
253 if (this != &rhs)
254 {
255 m_section = rhs.m_section;
256 m_offset = rhs.m_offset;
257 }
258 return *this;
259}
260
261bool
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262Address::ResolveAddressUsingFileSections (addr_t addr, const SectionList *sections)
263{
264 if (sections)
265 m_section = sections->FindSectionContainingFileAddress(addr).get();
266 else
267 m_section = NULL;
268
269 if (m_section != NULL)
270 {
271 assert( m_section->ContainsFileAddress(addr) );
272 m_offset = addr - m_section->GetFileAddress();
273 return true; // Successfully transformed addr into a section offset address
274 }
275
276 m_offset = addr;
277 return false; // Failed to resolve this address to a section offset value
278}
279
280//bool
281//Address::ResolveAddressUsingLoadSections (addr_t addr, const SectionList *sections)
282//{
283// if (sections)
284// m_section = sections->FindSectionContainingLoadAddress(addr).get();
285// else
286// m_section = NULL;
287//
288// if (m_section != NULL)
289// {
290// assert( m_section->ContainsLoadAddress(addr) );
291// m_offset = addr - m_section->GetLoadBaseAddress();
292// return true; // Successfully transformed addr into a section offset address
293// }
294//
295// m_offset = addr;
296// return false; // Failed to resolve this address to a section offset value
297//}
298//
299Module *
300Address::GetModule () const
301{
302 if (m_section)
303 return m_section->GetModule();
304 return NULL;
305}
306
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000307//addr_t
308//Address::Address() const
309//{
310// addr_t addr = GetLoadAddress();
311// if (addr != LLDB_INVALID_ADDRESS)
312// return addr;
313// return GetFileAddress();
314//}
315//
316
317addr_t
318Address::GetFileAddress () const
319{
320 if (m_section != NULL)
321 {
322 addr_t sect_file_addr = m_section->GetFileAddress();
323 if (sect_file_addr == LLDB_INVALID_ADDRESS)
324 {
325 // Section isn't resolved, we can't return a valid file address
326 return LLDB_INVALID_ADDRESS;
327 }
328 // We have a valid file range, so we can return the file based
329 // address by adding the file base address to our offset
330 return sect_file_addr + m_offset;
331 }
332 // No section, we just return the offset since it is the value in this case
333 return m_offset;
334}
335
336addr_t
337Address::GetLoadAddress (Process *process) const
338{
339 if (m_section != NULL)
340 {
341 if (process)
342 {
343 addr_t sect_load_addr = m_section->GetLoadBaseAddress (process);
344
345 if (sect_load_addr != LLDB_INVALID_ADDRESS)
346 {
347 // We have a valid file range, so we can return the file based
348 // address by adding the file base address to our offset
349 return sect_load_addr + m_offset;
350 }
351 }
352 // The section isn't resolved or no process was supplied so we can't
353 // return a valid file address.
354 return LLDB_INVALID_ADDRESS;
355 }
356 // No section, we just return the offset since it is the value in this case
357 return m_offset;
358}
359
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360bool
Greg Claytondda4f7b2010-06-30 23:03:03 +0000361Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000362{
363 // If the section was NULL, only load address is going to work.
364 if (m_section == NULL)
365 style = DumpStyleLoadAddress;
366
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000367 Target *target = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368 Process *process = NULL;
369 if (exe_scope)
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000370 {
371 target = exe_scope->CalculateTarget();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372 process = exe_scope->CalculateProcess();
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000373 }
Greg Claytondda4f7b2010-06-30 23:03:03 +0000374 // If addr_byte_size is UINT32_MAX, then determine the correct address
375 // byte size for the process or default to the size of addr_t
376 if (addr_size == UINT32_MAX)
377 {
378 if (process)
379 addr_size = process->GetAddressByteSize ();
380 else
381 addr_size = sizeof(addr_t);
382 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000383
384 lldb_private::Address so_addr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385 switch (style)
386 {
Greg Claytonc982c762010-07-09 20:39:50 +0000387 case DumpStyleInvalid:
388 return false;
389
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390 case DumpStyleSectionNameOffset:
391 if (m_section != NULL)
392 {
393 m_section->DumpName(s);
394 s->Printf (" + %llu", m_offset);
395 }
396 else
397 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000398 s->Address(m_offset, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000399 }
400 break;
401
402 case DumpStyleSectionPointerOffset:
Greg Claytondda4f7b2010-06-30 23:03:03 +0000403 s->Printf("(Section *)%.*p + ", (int)sizeof(void*) * 2, m_section);
404 s->Address(m_offset, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405 break;
406
407 case DumpStyleModuleWithFileAddress:
408 s->Printf("%s[", m_section->GetModule()->GetFileSpec().GetFilename().AsCString());
409 // Fall through
410 case DumpStyleFileAddress:
411 {
412 addr_t file_addr = GetFileAddress();
413 if (file_addr == LLDB_INVALID_ADDRESS)
414 {
415 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000416 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417 return false;
418 }
419 s->Address (file_addr, addr_size);
420 if (style == DumpStyleModuleWithFileAddress)
421 s->PutChar(']');
422 }
423 break;
424
425 case DumpStyleLoadAddress:
426 {
427 addr_t load_addr = GetLoadAddress (process);
428 if (load_addr == LLDB_INVALID_ADDRESS)
429 {
430 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000431 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000432 return false;
433 }
434 s->Address (load_addr, addr_size);
435 }
436 break;
437
438 case DumpStyleResolvedDescription:
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000439 case DumpStyleResolvedDescriptionNoModule:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000440 if (IsSectionOffset())
441 {
442 lldb::AddressType addr_type = eAddressTypeLoad;
443 addr_t addr = GetLoadAddress (process);
444 if (addr == LLDB_INVALID_ADDRESS)
445 {
446 addr = GetFileAddress();
447 addr_type = eAddressTypeFile;
448 }
449
450 uint32_t pointer_size = 4;
451 lldb_private::Module *module = GetModule();
452 if (process)
453 pointer_size = process->GetAddressByteSize();
454 else if (module)
455 pointer_size = module->GetArchitecture().GetAddressByteSize();
456
457 bool showed_info = false;
458 const Section *section = GetSection();
459 if (section)
460 {
Greg Clayton70e33eb2010-07-21 21:49:46 +0000461 SectionType sect_type = section->GetType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000462 switch (sect_type)
463 {
464 case eSectionTypeDataCString:
465 // Read the C string from memory and display it
466 showed_info = true;
467 ReadCStringFromMemory (exe_scope, *this, s);
468 break;
469
470 case eSectionTypeDataCStringPointers:
471 {
472 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
473 {
474#if VERBOSE_OUTPUT
475 s->PutCString("(char *)");
476 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
477 s->PutCString(": ");
478#endif
479 showed_info = true;
480 ReadCStringFromMemory (exe_scope, so_addr, s);
481 }
482 }
483 break;
484
485 case eSectionTypeDataObjCMessageRefs:
486 {
487 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
488 {
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000489 if (target && so_addr.IsSectionOffset())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000490 {
491 lldb_private::SymbolContext func_sc;
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000492 target->GetImages().ResolveSymbolContextForAddress (so_addr,
493 eSymbolContextEverything,
494 func_sc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000495 if (func_sc.function || func_sc.symbol)
496 {
497 showed_info = true;
498#if VERBOSE_OUTPUT
499 s->PutCString ("(objc_msgref *) -> { (func*)");
500 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
501#else
502 s->PutCString ("{ ");
503#endif
504 Address cstr_addr(*this);
505 cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
Greg Clayton6dadd502010-09-02 21:44:10 +0000506 func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000507 if (ReadAddress (exe_scope, cstr_addr, 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#else
514 s->PutCString(", ");
515#endif
516 ReadCStringFromMemory (exe_scope, so_addr, s);
517 }
518#if VERBOSE_OUTPUT
519 s->PutCString(") }");
520#else
521 s->PutCString(" }");
522#endif
523 }
524 }
525 }
526 }
527 break;
528
529 case eSectionTypeDataObjCCFStrings:
530 {
531 Address cfstring_data_addr(*this);
532 cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() + (2 * pointer_size));
533 if (ReadAddress (exe_scope, cfstring_data_addr, pointer_size, so_addr))
534 {
535#if VERBOSE_OUTPUT
536 s->PutCString("(CFString *) ");
537 cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
538 s->PutCString(" -> @");
539#else
540 s->PutChar('@');
541#endif
542 if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
543 showed_info = true;
544 }
545 }
546 break;
547
548 case eSectionTypeData4:
549 // Read the 4 byte data and display it
550 showed_info = true;
551 s->PutCString("(uint32_t) ");
552 DumpUInt (exe_scope, *this, 4, s);
553 break;
554
555 case eSectionTypeData8:
556 // Read the 8 byte data and display it
557 showed_info = true;
558 s->PutCString("(uint64_t) ");
559 DumpUInt (exe_scope, *this, 8, s);
560 break;
561
562 case eSectionTypeData16:
563 // Read the 16 byte data and display it
564 showed_info = true;
565 s->PutCString("(uint128_t) ");
566 DumpUInt (exe_scope, *this, 16, s);
567 break;
568
569 case eSectionTypeDataPointers:
570 // Read the pointer data and display it
571 {
572 if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
573 {
574 s->PutCString ("(void *)");
575 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
576
577 showed_info = true;
578 if (so_addr.IsSectionOffset())
579 {
580 lldb_private::SymbolContext pointer_sc;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000581 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000582 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000583 target->GetImages().ResolveSymbolContextForAddress (so_addr,
584 eSymbolContextEverything,
585 pointer_sc);
586 if (pointer_sc.function || pointer_sc.symbol)
587 {
588 s->PutCString(": ");
Greg Clayton6dadd502010-09-02 21:44:10 +0000589 pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000590 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000591 }
592 }
593 }
594 }
595 break;
Greg Claytonc982c762010-07-09 20:39:50 +0000596
597 default:
598 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000599 }
600 }
601
602 if (!showed_info)
603 {
604 if (module)
605 {
606 lldb_private::SymbolContext sc;
607 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
608 if (sc.function || sc.symbol)
609 {
610 bool show_stop_context = true;
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000611 bool show_module = (style == DumpStyleResolvedDescription);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000612 if (sc.function == NULL && sc.symbol != NULL)
613 {
614 // If we have just a symbol make sure it is in the right section
615 if (sc.symbol->GetAddressRangePtr())
616 {
617 if (sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection())
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000618 {
619 // don't show the module if the symbol is a trampoline symbol
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000620 show_stop_context = false;
Greg Clayton54b8b8c2010-07-01 01:26:43 +0000621 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000622 }
623 }
624 if (show_stop_context)
625 {
626 // We have a function or a symbol from the same
627 // sections as this address.
Greg Clayton6dadd502010-09-02 21:44:10 +0000628 sc.DumpStopContext(s, exe_scope, *this, true, show_module, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000629 }
630 else
631 {
632 // We found a symbol but it was in a different
633 // section so it isn't the symbol we should be
634 // showing, just show the section name + offset
635 Dump (s, exe_scope, DumpStyleSectionNameOffset);
636 }
637 }
638 }
639 }
640 }
641 else
642 {
643 if (fallback_style != DumpStyleInvalid)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000644 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000645 return false;
646 }
647 break;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000648
649 case DumpStyleDetailedSymbolContext:
650 if (IsSectionOffset())
651 {
652 lldb::AddressType addr_type = eAddressTypeLoad;
653 addr_t addr = GetLoadAddress (process);
654 if (addr == LLDB_INVALID_ADDRESS)
655 {
656 addr = GetFileAddress();
657 addr_type = eAddressTypeFile;
658 }
659
660 lldb_private::Module *module = GetModule();
661 if (module)
662 {
663 lldb_private::SymbolContext sc;
664 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000665 if (sc.symbol)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000666 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000667 // If we have just a symbol make sure it is in the same section
668 // as our address. If it isn't, then we might have just found
669 // the last symbol that came before the address that we are
670 // looking up that has nothing to do with our address lookup.
671 if (sc.symbol->GetAddressRangePtr() && sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection())
672 sc.symbol = NULL;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000673 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000674 sc.GetDescription(s, eDescriptionLevelBrief, process);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000675 }
676 }
677 if (fallback_style != DumpStyleInvalid)
678 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
679 return false;
680 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000681 }
682
683 return true;
684}
685
686//Stream& operator << (Stream& s, const Address& so_addr)
687//{
688// so_addr.Dump(&s, Address::DumpStyleSectionNameOffset);
689// return s;
690//}
691//
692void
693Address::CalculateSymbolContext (SymbolContext *sc)
694{
695 sc->Clear();
696 // Absolute addresses don't have enough information to reconstruct even their target.
697 if (m_section == NULL)
698 return;
699
700 if (m_section->GetModule())
701 {
702 sc->module_sp = m_section->GetModule()->GetSP();
703 if (sc->module_sp)
704 sc->module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextEverything, *sc);
705 }
706}
707
708void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000709Address::DumpDebug(Stream *s) const
710{
711 *s << (void *)this << ": " << "Address";
712 if (m_section != NULL)
713 {
714 *s << ", section = " << (void *)m_section << " (" << m_section->GetName() << "), offset = " << m_offset;
715 }
716 else
717 {
718 *s << ", vm_addr = " << m_offset;
719 }
720 s->EOL();
721}
722
723int
724Address::CompareFileAddress (const Address& a, const Address& b)
725{
726 addr_t a_file_addr = a.GetFileAddress();
727 addr_t b_file_addr = b.GetFileAddress();
728 if (a_file_addr < b_file_addr)
729 return -1;
730 if (a_file_addr > b_file_addr)
731 return +1;
732 return 0;
733}
734
735
736int
737Address::CompareLoadAddress (const Address& a, const Address& b, Process *process)
738{
739 assert (process != NULL);
740 addr_t a_load_addr = a.GetLoadAddress (process);
741 addr_t b_load_addr = b.GetLoadAddress (process);
742 if (a_load_addr < b_load_addr)
743 return -1;
744 if (a_load_addr > b_load_addr)
745 return +1;
746 return 0;
747}
748
749int
750Address::CompareModulePointerAndOffset (const Address& a, const Address& b)
751{
752 Module *a_module = a.GetModule ();
753 Module *b_module = b.GetModule ();
754 if (a_module < b_module)
755 return -1;
756 if (a_module > b_module)
757 return +1;
758 // Modules are the same, just compare the file address since they should
759 // be unique
760 addr_t a_file_addr = a.GetFileAddress();
761 addr_t b_file_addr = b.GetFileAddress();
762 if (a_file_addr < b_file_addr)
763 return -1;
764 if (a_file_addr > b_file_addr)
765 return +1;
766 return 0;
767}
768
769
770size_t
771Address::MemorySize () const
772{
773 // Noting special for the memory size of a single Address object,
774 // it is just the size of itself.
775 return sizeof(Address);
776}
777
778
779/// The only comparisons that make sense are the load addresses
780//bool
781//lldb::operator< (const Address& lhs, const Address& rhs)
782//{
783// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
784// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
785//
786// if (lhs_addr == rhs_addr)
787// {
788// lhs_addr = lhs.GetFileAddress();
789// rhs_addr = rhs.GetFileAddress();
790// }
791// return lhs_addr < rhs_addr;
792//}
793//
794//bool
795//lldb::operator<= (const Address& lhs, const Address& rhs)
796//{
797// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
798// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
799//
800// if (lhs_addr == rhs_addr)
801// {
802// lhs_addr = lhs.GetFileAddress();
803// rhs_addr = rhs.GetFileAddress();
804// }
805// return lhs_addr <= rhs_addr;
806//}
807//
808//bool
809//lldb::operator> (const Address& lhs, const Address& rhs)
810//{
811// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
812// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
813//
814// if (lhs_addr == rhs_addr)
815// {
816// lhs_addr = lhs.GetFileAddress();
817// rhs_addr = rhs.GetFileAddress();
818// }
819// return lhs_addr > rhs_addr;
820//}
821//
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
837// The operator == checks for exact equality only (same section, same offset)
838bool
839lldb_private::operator== (const Address& a, const Address& rhs)
840{
841 return a.GetSection() == rhs.GetSection() &&
842 a.GetOffset() == rhs.GetOffset();
843}
844// The operator != checks for exact inequality only (differing section, or
845// different offset)
846bool
847lldb_private::operator!= (const Address& a, const Address& rhs)
848{
849 return a.GetSection() != rhs.GetSection() ||
850 a.GetOffset() != rhs.GetOffset();
851}
852
853bool
854Address::IsLinkedAddress () const
855{
856 return m_section && m_section->GetLinkedSection();
857}
858
859
860void
861Address::ResolveLinkedAddress ()
862{
863 if (m_section)
864 {
865 const Section *linked_section = m_section->GetLinkedSection();
866 if (linked_section)
867 {
868 m_offset += m_section->GetLinkedOffset();
869 m_section = linked_section;
870 }
871 }
872}