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