blob: d7931364d7b326b057c497c9ef0718e0c5aafca6 [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 Clayton1b72fcb2010-08-24 00:45:41 +0000556 func_sc.DumpStopContext(s, exe_scope, so_addr, true, false);
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 Clayton1b72fcb2010-08-24 00:45:41 +0000639 pointer_sc.DumpStopContext(s, exe_scope, so_addr, false, 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 Clayton1b72fcb2010-08-24 00:45:41 +0000678 sc.DumpStopContext(s, exe_scope, *this, show_module, false);
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);
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000715 if (sc.symbol)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000716 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000717 // If we have just a symbol make sure it is in the same section
718 // as our address. If it isn't, then we might have just found
719 // the last symbol that came before the address that we are
720 // looking up that has nothing to do with our address lookup.
721 if (sc.symbol->GetAddressRangePtr() && sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection())
722 sc.symbol = NULL;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000723 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000724 sc.GetDescription(s, eDescriptionLevelBrief, process);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000725 }
726 }
727 if (fallback_style != DumpStyleInvalid)
728 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
729 return false;
730 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000731 }
732
733 return true;
734}
735
736//Stream& operator << (Stream& s, const Address& so_addr)
737//{
738// so_addr.Dump(&s, Address::DumpStyleSectionNameOffset);
739// return s;
740//}
741//
742void
743Address::CalculateSymbolContext (SymbolContext *sc)
744{
745 sc->Clear();
746 // Absolute addresses don't have enough information to reconstruct even their target.
747 if (m_section == NULL)
748 return;
749
750 if (m_section->GetModule())
751 {
752 sc->module_sp = m_section->GetModule()->GetSP();
753 if (sc->module_sp)
754 sc->module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextEverything, *sc);
755 }
756}
757
758void
759Address::DumpSymbolContext (Stream *s)
760{
761 SymbolContext sc;
762 CalculateSymbolContext (&sc);
763 sc.Dump (s, NULL);
764}
765
766void
767Address::DumpDebug(Stream *s) const
768{
769 *s << (void *)this << ": " << "Address";
770 if (m_section != NULL)
771 {
772 *s << ", section = " << (void *)m_section << " (" << m_section->GetName() << "), offset = " << m_offset;
773 }
774 else
775 {
776 *s << ", vm_addr = " << m_offset;
777 }
778 s->EOL();
779}
780
781int
782Address::CompareFileAddress (const Address& a, const Address& b)
783{
784 addr_t a_file_addr = a.GetFileAddress();
785 addr_t b_file_addr = b.GetFileAddress();
786 if (a_file_addr < b_file_addr)
787 return -1;
788 if (a_file_addr > b_file_addr)
789 return +1;
790 return 0;
791}
792
793
794int
795Address::CompareLoadAddress (const Address& a, const Address& b, Process *process)
796{
797 assert (process != NULL);
798 addr_t a_load_addr = a.GetLoadAddress (process);
799 addr_t b_load_addr = b.GetLoadAddress (process);
800 if (a_load_addr < b_load_addr)
801 return -1;
802 if (a_load_addr > b_load_addr)
803 return +1;
804 return 0;
805}
806
807int
808Address::CompareModulePointerAndOffset (const Address& a, const Address& b)
809{
810 Module *a_module = a.GetModule ();
811 Module *b_module = b.GetModule ();
812 if (a_module < b_module)
813 return -1;
814 if (a_module > b_module)
815 return +1;
816 // Modules are the same, just compare the file address since they should
817 // be unique
818 addr_t a_file_addr = a.GetFileAddress();
819 addr_t b_file_addr = b.GetFileAddress();
820 if (a_file_addr < b_file_addr)
821 return -1;
822 if (a_file_addr > b_file_addr)
823 return +1;
824 return 0;
825}
826
827
828size_t
829Address::MemorySize () const
830{
831 // Noting special for the memory size of a single Address object,
832 // it is just the size of itself.
833 return sizeof(Address);
834}
835
836
837/// The only comparisons that make sense are the load addresses
838//bool
839//lldb::operator< (const Address& lhs, const Address& rhs)
840//{
841// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
842// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
843//
844// if (lhs_addr == rhs_addr)
845// {
846// lhs_addr = lhs.GetFileAddress();
847// rhs_addr = rhs.GetFileAddress();
848// }
849// return lhs_addr < rhs_addr;
850//}
851//
852//bool
853//lldb::operator<= (const Address& lhs, const Address& rhs)
854//{
855// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
856// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
857//
858// if (lhs_addr == rhs_addr)
859// {
860// lhs_addr = lhs.GetFileAddress();
861// rhs_addr = rhs.GetFileAddress();
862// }
863// return lhs_addr <= rhs_addr;
864//}
865//
866//bool
867//lldb::operator> (const Address& lhs, const Address& rhs)
868//{
869// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
870// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
871//
872// if (lhs_addr == rhs_addr)
873// {
874// lhs_addr = lhs.GetFileAddress();
875// rhs_addr = rhs.GetFileAddress();
876// }
877// return lhs_addr > rhs_addr;
878//}
879//
880//bool
881//lldb::operator>= (const Address& lhs, const Address& rhs)
882//{
883// lldb::addr_t lhs_addr = lhs.GetLoadAddress();
884// lldb::addr_t rhs_addr = rhs.GetLoadAddress();
885//
886// if (lhs_addr == rhs_addr)
887// {
888// lhs_addr = lhs.GetFileAddress();
889// rhs_addr = rhs.GetFileAddress();
890// }
891// return lhs_addr >= rhs_addr;
892//}
893//
894
895// The operator == checks for exact equality only (same section, same offset)
896bool
897lldb_private::operator== (const Address& a, const Address& rhs)
898{
899 return a.GetSection() == rhs.GetSection() &&
900 a.GetOffset() == rhs.GetOffset();
901}
902// The operator != checks for exact inequality only (differing section, or
903// different offset)
904bool
905lldb_private::operator!= (const Address& a, const Address& rhs)
906{
907 return a.GetSection() != rhs.GetSection() ||
908 a.GetOffset() != rhs.GetOffset();
909}
910
911bool
912Address::IsLinkedAddress () const
913{
914 return m_section && m_section->GetLinkedSection();
915}
916
917
918void
919Address::ResolveLinkedAddress ()
920{
921 if (m_section)
922 {
923 const Section *linked_section = m_section->GetLinkedSection();
924 if (linked_section)
925 {
926 m_offset += m_section->GetLinkedOffset();
927 m_section = linked_section;
928 }
929 }
930}