1 //===-- 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/Symbol/Variable.h"
15 #include "lldb/Symbol/VariableList.h"
16 #include "lldb/Target/ExecutionContext.h"
17 #include "lldb/Target/Process.h"
18 #include "lldb/Target/Target.h"
19 
20 #include "llvm/ADT/Triple.h"
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 
25 static size_t
26 ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst, size_t dst_len)
27 {
28     if (exe_scope == NULL)
29         return 0;
30 
31     TargetSP target_sp (exe_scope->CalculateTarget());
32     if (target_sp)
33     {
34         Error error;
35         bool prefer_file_cache = false;
36         return target_sp->ReadMemory (address, prefer_file_cache, dst, dst_len, error);
37     }
38     return 0;
39 }
40 
41 static bool
42 GetByteOrderAndAddressSize (ExecutionContextScope *exe_scope, const Address &address, ByteOrder& byte_order, uint32_t& addr_size)
43 {
44     byte_order = eByteOrderInvalid;
45     addr_size = 0;
46     if (exe_scope == NULL)
47         return false;
48 
49     TargetSP target_sp (exe_scope->CalculateTarget());
50     if (target_sp)
51     {
52         byte_order = target_sp->GetArchitecture().GetByteOrder();
53         addr_size = target_sp->GetArchitecture().GetAddressByteSize();
54     }
55 
56     if (byte_order == eByteOrderInvalid || addr_size == 0)
57     {
58         Module *module = address.GetModulePtr();
59         if (module)
60         {
61             byte_order = module->GetArchitecture().GetByteOrder();
62             addr_size = module->GetArchitecture().GetAddressByteSize();
63         }
64     }
65     return byte_order != eByteOrderInvalid && addr_size != 0;
66 }
67 
68 static uint64_t
69 ReadUIntMax64 (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, bool &success)
70 {
71     uint64_t uval64 = 0;
72     if (exe_scope == NULL || byte_size > sizeof(uint64_t))
73     {
74         success = false;
75         return 0;
76     }
77     uint64_t buf = 0;
78 
79     success = ReadBytes (exe_scope, address, &buf, byte_size) == byte_size;
80     if (success)
81     {
82         ByteOrder byte_order = eByteOrderInvalid;
83         uint32_t addr_size = 0;
84         if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size))
85         {
86             DataExtractor data (&buf, sizeof(buf), byte_order, addr_size);
87             uint32_t offset = 0;
88             uval64 = data.GetU64(&offset);
89         }
90         else
91             success = false;
92     }
93     return uval64;
94 }
95 
96 static bool
97 ReadAddress (ExecutionContextScope *exe_scope, const Address &address, uint32_t pointer_size, Address &deref_so_addr)
98 {
99     if (exe_scope == NULL)
100         return false;
101 
102 
103     bool success = false;
104     addr_t deref_addr = ReadUIntMax64 (exe_scope, address, pointer_size, success);
105     if (success)
106     {
107         ExecutionContext exe_ctx;
108         exe_scope->CalculateExecutionContext(exe_ctx);
109         // If we have any sections that are loaded, try and resolve using the
110         // section load list
111         Target *target = exe_ctx.GetTargetPtr();
112         if (target && !target->GetSectionLoadList().IsEmpty())
113         {
114             if (target->GetSectionLoadList().ResolveLoadAddress (deref_addr, deref_so_addr))
115                 return true;
116         }
117         else
118         {
119             // If we were not running, yet able to read an integer, we must
120             // have a module
121             Module *module = address.GetModulePtr();
122             assert (module);
123             if (module->ResolveFileAddress(deref_addr, deref_so_addr))
124                 return true;
125         }
126 
127         // We couldn't make "deref_addr" into a section offset value, but we were
128         // able to read the address, so we return a section offset address with
129         // no section and "deref_addr" as the offset (address).
130         deref_so_addr.SetSection(NULL);
131         deref_so_addr.SetOffset(deref_addr);
132         return true;
133     }
134     return false;
135 }
136 
137 static bool
138 DumpUInt (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, Stream* strm)
139 {
140     if (exe_scope == NULL || byte_size == 0)
141         return 0;
142     std::vector<uint8_t> buf(byte_size, 0);
143 
144     if (ReadBytes (exe_scope, address, &buf[0], buf.size()) == buf.size())
145     {
146         ByteOrder byte_order = eByteOrderInvalid;
147         uint32_t addr_size = 0;
148         if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size))
149         {
150             DataExtractor data (&buf.front(), buf.size(), byte_order, addr_size);
151 
152             data.Dump (strm,
153                        0,                 // Start offset in "data"
154                        eFormatHex,        // Print as characters
155                        buf.size(),        // Size of item
156                        1,                 // Items count
157                        UINT32_MAX,        // num per line
158                        LLDB_INVALID_ADDRESS,// base address
159                        0,                 // bitfield bit size
160                        0);                // bitfield bit offset
161 
162             return true;
163         }
164     }
165     return false;
166 }
167 
168 
169 static size_t
170 ReadCStringFromMemory (ExecutionContextScope *exe_scope, const Address &address, Stream *strm)
171 {
172     if (exe_scope == NULL)
173         return 0;
174     const size_t k_buf_len = 256;
175     char buf[k_buf_len+1];
176     buf[k_buf_len] = '\0'; // NULL terminate
177 
178     // Byte order and address size don't matter for C string dumping..
179     DataExtractor data (buf, sizeof(buf), lldb::endian::InlHostByteOrder(), 4);
180     size_t total_len = 0;
181     size_t bytes_read;
182     Address curr_address(address);
183     strm->PutChar ('"');
184     while ((bytes_read = ReadBytes (exe_scope, curr_address, buf, k_buf_len)) > 0)
185     {
186         size_t len = strlen(buf);
187         if (len == 0)
188             break;
189         if (len > bytes_read)
190             len = bytes_read;
191 
192         data.Dump (strm,
193                    0,                 // Start offset in "data"
194                    eFormatChar,       // Print as characters
195                    1,                 // Size of item (1 byte for a char!)
196                    len,               // How many bytes to print?
197                    UINT32_MAX,        // num per line
198                    LLDB_INVALID_ADDRESS,// base address
199                    0,                 // bitfield bit size
200 
201                    0);                // bitfield bit offset
202 
203         total_len += bytes_read;
204 
205         if (len < k_buf_len)
206             break;
207         curr_address.SetOffset (curr_address.GetOffset() + bytes_read);
208     }
209     strm->PutChar ('"');
210     return total_len;
211 }
212 
213 Address::Address (addr_t address, const SectionList * sections) :
214     m_section (NULL),
215     m_offset (LLDB_INVALID_ADDRESS)
216 {
217     ResolveAddressUsingFileSections(address, sections);
218 }
219 
220 const Address&
221 Address::operator= (const Address& rhs)
222 {
223     if (this != &rhs)
224     {
225         m_section = rhs.m_section;
226         m_offset = rhs.m_offset;
227     }
228     return *this;
229 }
230 
231 bool
232 Address::ResolveAddressUsingFileSections (addr_t addr, const SectionList *sections)
233 {
234     if (sections)
235         m_section = sections->FindSectionContainingFileAddress(addr).get();
236     else
237         m_section = NULL;
238 
239     if (m_section != NULL)
240     {
241         assert( m_section->ContainsFileAddress(addr) );
242         m_offset = addr - m_section->GetFileAddress();
243         return true;    // Successfully transformed addr into a section offset address
244     }
245 
246     m_offset = addr;
247     return false;       // Failed to resolve this address to a section offset value
248 }
249 
250 Module *
251 Address::GetModulePtr () const
252 {
253     if (m_section)
254         return m_section->GetModule();
255     return NULL;
256 }
257 
258 ModuleSP
259 Address::GetModuleSP () const
260 {
261     lldb::ModuleSP module_sp;
262     if (m_section)
263     {
264         Module *module = m_section->GetModule();
265         if (module)
266             module_sp = module->shared_from_this();
267     }
268     return module_sp;
269 }
270 
271 addr_t
272 Address::GetFileAddress () const
273 {
274     if (m_section != NULL)
275     {
276         addr_t sect_file_addr = m_section->GetFileAddress();
277         if (sect_file_addr == LLDB_INVALID_ADDRESS)
278         {
279             // Section isn't resolved, we can't return a valid file address
280             return LLDB_INVALID_ADDRESS;
281         }
282         // We have a valid file range, so we can return the file based
283         // address by adding the file base address to our offset
284         return sect_file_addr + m_offset;
285     }
286     // No section, we just return the offset since it is the value in this case
287     return m_offset;
288 }
289 
290 addr_t
291 Address::GetLoadAddress (Target *target) const
292 {
293     if (m_section == NULL)
294     {
295         // No section, we just return the offset since it is the value in this case
296         return m_offset;
297     }
298 
299     if (target)
300     {
301         addr_t sect_load_addr = m_section->GetLoadBaseAddress (target);
302 
303         if (sect_load_addr != LLDB_INVALID_ADDRESS)
304         {
305             // We have a valid file range, so we can return the file based
306             // address by adding the file base address to our offset
307             return sect_load_addr + m_offset;
308         }
309     }
310     // The section isn't resolved or no process was supplied so we can't
311     // return a valid file address.
312     return LLDB_INVALID_ADDRESS;
313 }
314 
315 addr_t
316 Address::GetCallableLoadAddress (Target *target) const
317 {
318     addr_t code_addr = GetLoadAddress (target);
319 
320     if (target)
321         return target->GetCallableLoadAddress (code_addr, GetAddressClass());
322     return code_addr;
323 }
324 
325 bool
326 Address::SetCallableLoadAddress (lldb::addr_t load_addr, Target *target)
327 {
328     if (SetLoadAddress (load_addr, target))
329     {
330         if (target)
331             m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass());
332         return true;
333     }
334     return false;
335 }
336 
337 addr_t
338 Address::GetOpcodeLoadAddress (Target *target) const
339 {
340     addr_t code_addr = GetLoadAddress (target);
341     if (code_addr != LLDB_INVALID_ADDRESS)
342         code_addr = target->GetOpcodeLoadAddress (code_addr, GetAddressClass());
343     return code_addr;
344 }
345 
346 bool
347 Address::SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target)
348 {
349     if (SetLoadAddress (load_addr, target))
350     {
351         if (target)
352             m_offset = target->GetOpcodeLoadAddress (m_offset, GetAddressClass());
353         return true;
354     }
355     return false;
356 }
357 
358 bool
359 Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
360 {
361     // If the section was NULL, only load address is going to work.
362     if (m_section == NULL)
363         style = DumpStyleLoadAddress;
364 
365     ExecutionContext exe_ctx (exe_scope);
366     Target *target = exe_ctx.GetTargetPtr();
367     // If addr_byte_size is UINT32_MAX, then determine the correct address
368     // byte size for the process or default to the size of addr_t
369     if (addr_size == UINT32_MAX)
370     {
371         if (target)
372             addr_size = target->GetArchitecture().GetAddressByteSize ();
373         else
374             addr_size = sizeof(addr_t);
375     }
376 
377     Address so_addr;
378     switch (style)
379     {
380     case DumpStyleInvalid:
381         return false;
382 
383     case DumpStyleSectionNameOffset:
384         if (m_section != NULL)
385         {
386             m_section->DumpName(s);
387             s->Printf (" + %llu", m_offset);
388         }
389         else
390         {
391             s->Address(m_offset, addr_size);
392         }
393         break;
394 
395     case DumpStyleSectionPointerOffset:
396         s->Printf("(Section *)%p + ", m_section);
397         s->Address(m_offset, addr_size);
398         break;
399 
400     case DumpStyleModuleWithFileAddress:
401         if (m_section)
402             s->Printf("%s[", m_section->GetModule()->GetFileSpec().GetFilename().AsCString());
403         // Fall through
404     case DumpStyleFileAddress:
405         {
406             addr_t file_addr = GetFileAddress();
407             if (file_addr == LLDB_INVALID_ADDRESS)
408             {
409                 if (fallback_style != DumpStyleInvalid)
410                     return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
411                 return false;
412             }
413             s->Address (file_addr, addr_size);
414             if (style == DumpStyleModuleWithFileAddress && m_section)
415                 s->PutChar(']');
416         }
417         break;
418 
419     case DumpStyleLoadAddress:
420         {
421             addr_t load_addr = GetLoadAddress (target);
422             if (load_addr == LLDB_INVALID_ADDRESS)
423             {
424                 if (fallback_style != DumpStyleInvalid)
425                     return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
426                 return false;
427             }
428             s->Address (load_addr, addr_size);
429         }
430         break;
431 
432     case DumpStyleResolvedDescription:
433     case DumpStyleResolvedDescriptionNoModule:
434         if (IsSectionOffset())
435         {
436             AddressType addr_type = eAddressTypeLoad;
437             addr_t addr = GetLoadAddress (target);
438             if (addr == LLDB_INVALID_ADDRESS)
439             {
440                 addr = GetFileAddress();
441                 addr_type = eAddressTypeFile;
442             }
443 
444             uint32_t pointer_size = 4;
445             Module *module = GetModulePtr();
446             if (target)
447                 pointer_size = target->GetArchitecture().GetAddressByteSize();
448             else if (module)
449                 pointer_size = module->GetArchitecture().GetAddressByteSize();
450 
451             bool showed_info = false;
452             const Section *section = GetSection();
453             if (section)
454             {
455                 SectionType sect_type = section->GetType();
456                 switch (sect_type)
457                 {
458                 case eSectionTypeData:
459                     if (module)
460                     {
461                         ObjectFile *objfile = module->GetObjectFile();
462                         if (objfile)
463                         {
464                             Symtab *symtab = objfile->GetSymtab();
465                             if (symtab)
466                             {
467                                 const addr_t file_Addr = GetFileAddress();
468                                 Symbol *symbol = symtab->FindSymbolContainingFileAddress (file_Addr);
469                                 if (symbol)
470                                 {
471                                     const char *symbol_name = symbol->GetName().AsCString();
472                                     if (symbol_name)
473                                     {
474                                         s->PutCString(symbol_name);
475                                         addr_t delta = file_Addr - symbol->GetAddressRangePtr()->GetBaseAddress().GetFileAddress();
476                                         if (delta)
477                                             s->Printf(" + %llu", delta);
478                                         showed_info = true;
479                                     }
480                                 }
481                             }
482                         }
483                     }
484                     break;
485 
486                 case eSectionTypeDataCString:
487                     // Read the C string from memory and display it
488                     showed_info = true;
489                     ReadCStringFromMemory (exe_scope, *this, s);
490                     break;
491 
492                 case eSectionTypeDataCStringPointers:
493                     {
494                         if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
495                         {
496 #if VERBOSE_OUTPUT
497                             s->PutCString("(char *)");
498                             so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
499                             s->PutCString(": ");
500 #endif
501                             showed_info = true;
502                             ReadCStringFromMemory (exe_scope, so_addr, s);
503                         }
504                     }
505                     break;
506 
507                 case eSectionTypeDataObjCMessageRefs:
508                     {
509                         if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
510                         {
511                             if (target && so_addr.IsSectionOffset())
512                             {
513                                 SymbolContext func_sc;
514                                 target->GetImages().ResolveSymbolContextForAddress (so_addr,
515                                                                                              eSymbolContextEverything,
516                                                                                              func_sc);
517                                 if (func_sc.function || func_sc.symbol)
518                                 {
519                                     showed_info = true;
520 #if VERBOSE_OUTPUT
521                                     s->PutCString ("(objc_msgref *) -> { (func*)");
522                                     so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
523 #else
524                                     s->PutCString ("{ ");
525 #endif
526                                     Address cstr_addr(*this);
527                                     cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
528                                     func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false);
529                                     if (ReadAddress (exe_scope, cstr_addr, pointer_size, so_addr))
530                                     {
531 #if VERBOSE_OUTPUT
532                                         s->PutCString("), (char *)");
533                                         so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
534                                         s->PutCString(" (");
535 #else
536                                         s->PutCString(", ");
537 #endif
538                                         ReadCStringFromMemory (exe_scope, so_addr, s);
539                                     }
540 #if VERBOSE_OUTPUT
541                                     s->PutCString(") }");
542 #else
543                                     s->PutCString(" }");
544 #endif
545                                 }
546                             }
547                         }
548                     }
549                     break;
550 
551                 case eSectionTypeDataObjCCFStrings:
552                     {
553                         Address cfstring_data_addr(*this);
554                         cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() + (2 * pointer_size));
555                         if (ReadAddress (exe_scope, cfstring_data_addr, pointer_size, so_addr))
556                         {
557 #if VERBOSE_OUTPUT
558                             s->PutCString("(CFString *) ");
559                             cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
560                             s->PutCString(" -> @");
561 #else
562                             s->PutChar('@');
563 #endif
564                             if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
565                                 showed_info = true;
566                         }
567                     }
568                     break;
569 
570                 case eSectionTypeData4:
571                     // Read the 4 byte data and display it
572                     showed_info = true;
573                     s->PutCString("(uint32_t) ");
574                     DumpUInt (exe_scope, *this, 4, s);
575                     break;
576 
577                 case eSectionTypeData8:
578                     // Read the 8 byte data and display it
579                     showed_info = true;
580                     s->PutCString("(uint64_t) ");
581                     DumpUInt (exe_scope, *this, 8, s);
582                     break;
583 
584                 case eSectionTypeData16:
585                     // Read the 16 byte data and display it
586                     showed_info = true;
587                     s->PutCString("(uint128_t) ");
588                     DumpUInt (exe_scope, *this, 16, s);
589                     break;
590 
591                 case eSectionTypeDataPointers:
592                     // Read the pointer data and display it
593                     {
594                         if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
595                         {
596                             s->PutCString ("(void *)");
597                             so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
598 
599                             showed_info = true;
600                             if (so_addr.IsSectionOffset())
601                             {
602                                 SymbolContext pointer_sc;
603                                 if (target)
604                                 {
605                                     target->GetImages().ResolveSymbolContextForAddress (so_addr,
606                                                                                                  eSymbolContextEverything,
607                                                                                                  pointer_sc);
608                                     if (pointer_sc.function || pointer_sc.symbol)
609                                     {
610                                         s->PutCString(": ");
611                                         pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false);
612                                     }
613                                 }
614                             }
615                         }
616                     }
617                     break;
618 
619                 default:
620                     break;
621                 }
622             }
623 
624             if (!showed_info)
625             {
626                 if (module)
627                 {
628                     SymbolContext sc;
629                     module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
630                     if (sc.function || sc.symbol)
631                     {
632                         bool show_stop_context = true;
633                         const bool show_module = (style == DumpStyleResolvedDescription);
634                         const bool show_fullpaths = false;
635                         const bool show_inlined_frames = true;
636                         if (sc.function == NULL && sc.symbol != NULL)
637                         {
638                             // If we have just a symbol make sure it is in the right section
639                             if (sc.symbol->GetAddressRangePtr())
640                             {
641                                 if (sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection())
642                                 {
643                                     // don't show the module if the symbol is a trampoline symbol
644                                     show_stop_context = false;
645                                 }
646                             }
647                         }
648                         if (show_stop_context)
649                         {
650                             // We have a function or a symbol from the same
651                             // sections as this address.
652                             sc.DumpStopContext (s,
653                                                 exe_scope,
654                                                 *this,
655                                                 show_fullpaths,
656                                                 show_module,
657                                                 show_inlined_frames);
658                         }
659                         else
660                         {
661                             // We found a symbol but it was in a different
662                             // section so it isn't the symbol we should be
663                             // showing, just show the section name + offset
664                             Dump (s, exe_scope, DumpStyleSectionNameOffset);
665                         }
666                     }
667                 }
668             }
669         }
670         else
671         {
672             if (fallback_style != DumpStyleInvalid)
673                 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
674             return false;
675         }
676         break;
677 
678     case DumpStyleDetailedSymbolContext:
679         if (IsSectionOffset())
680         {
681             Module *module = GetModulePtr();
682             if (module)
683             {
684                 SymbolContext sc;
685                 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
686                 if (sc.symbol)
687                 {
688                     // If we have just a symbol make sure it is in the same section
689                     // as our address. If it isn't, then we might have just found
690                     // the last symbol that came before the address that we are
691                     // looking up that has nothing to do with our address lookup.
692                     if (sc.symbol->GetAddressRangePtr() && sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection())
693                         sc.symbol = NULL;
694                 }
695                 sc.GetDescription(s, eDescriptionLevelBrief, target);
696 
697                 if (sc.block)
698                 {
699                     bool can_create = true;
700                     bool get_parent_variables = true;
701                     bool stop_if_block_is_inlined_function = false;
702                     VariableList variable_list;
703                     sc.block->AppendVariables (can_create,
704                                                get_parent_variables,
705                                                stop_if_block_is_inlined_function,
706                                                &variable_list);
707 
708                     uint32_t num_variables = variable_list.GetSize();
709                     for (uint32_t var_idx = 0; var_idx < num_variables; ++var_idx)
710                     {
711                         Variable *var = variable_list.GetVariableAtIndex (var_idx).get();
712                         if (var && var->LocationIsValidForAddress (*this))
713                         {
714                             s->Printf ("     Variable: id = {0x%8.8llx}, name = \"%s\", type= \"%s\", location =",
715                                        var->GetID(),
716                                        var->GetName().GetCString(),
717                                        var->GetType()->GetName().GetCString());
718                             var->DumpLocationForAddress(s, *this);
719                             s->PutCString(", decl = ");
720                             var->GetDeclaration().DumpStopContext(s, false);
721                             s->EOL();
722                         }
723                     }
724                 }
725             }
726         }
727         else
728         {
729             if (fallback_style != DumpStyleInvalid)
730                 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
731             return false;
732         }
733         break;
734     }
735 
736     return true;
737 }
738 
739 uint32_t
740 Address::CalculateSymbolContext (SymbolContext *sc, uint32_t resolve_scope) const
741 {
742     sc->Clear();
743     // Absolute addresses don't have enough information to reconstruct even their target.
744     if (m_section)
745     {
746         Module *address_module = m_section->GetModule();
747         if (address_module)
748         {
749             sc->module_sp = address_module->shared_from_this();
750             if (sc->module_sp)
751                 return sc->module_sp->ResolveSymbolContextForAddress (*this, resolve_scope, *sc);
752         }
753     }
754     return 0;
755 }
756 
757 Module *
758 Address::CalculateSymbolContextModule () const
759 {
760     if (m_section)
761         return m_section->GetModule();
762     return NULL;
763 }
764 
765 CompileUnit *
766 Address::CalculateSymbolContextCompileUnit () const
767 {
768     if (m_section)
769     {
770         SymbolContext sc;
771         sc.module_sp = m_section->GetModule()->shared_from_this();
772         if (sc.module_sp)
773         {
774             sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextCompUnit, sc);
775             return sc.comp_unit;
776         }
777     }
778     return NULL;
779 }
780 
781 Function *
782 Address::CalculateSymbolContextFunction () const
783 {
784     if (m_section)
785     {
786         SymbolContext sc;
787         sc.module_sp = m_section->GetModule()->shared_from_this();
788         if (sc.module_sp)
789         {
790             sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextFunction, sc);
791             return sc.function;
792         }
793     }
794     return NULL;
795 }
796 
797 Block *
798 Address::CalculateSymbolContextBlock () const
799 {
800     if (m_section)
801     {
802         SymbolContext sc;
803         sc.module_sp = m_section->GetModule()->shared_from_this();
804         if (sc.module_sp)
805         {
806             sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextBlock, sc);
807             return sc.block;
808         }
809     }
810     return NULL;
811 }
812 
813 Symbol *
814 Address::CalculateSymbolContextSymbol () const
815 {
816     if (m_section)
817     {
818         SymbolContext sc;
819         sc.module_sp = m_section->GetModule()->shared_from_this();
820         if (sc.module_sp)
821         {
822             sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextSymbol, sc);
823             return sc.symbol;
824         }
825     }
826     return NULL;
827 }
828 
829 bool
830 Address::CalculateSymbolContextLineEntry (LineEntry &line_entry) const
831 {
832     if (m_section)
833     {
834         SymbolContext sc;
835         sc.module_sp = m_section->GetModule()->shared_from_this();
836         if (sc.module_sp)
837         {
838             sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextLineEntry, sc);
839             if (sc.line_entry.IsValid())
840             {
841                 line_entry = sc.line_entry;
842                 return true;
843             }
844         }
845     }
846     line_entry.Clear();
847     return false;
848 }
849 
850 int
851 Address::CompareFileAddress (const Address& a, const Address& b)
852 {
853     addr_t a_file_addr = a.GetFileAddress();
854     addr_t b_file_addr = b.GetFileAddress();
855     if (a_file_addr < b_file_addr)
856         return -1;
857     if (a_file_addr > b_file_addr)
858         return +1;
859     return 0;
860 }
861 
862 
863 int
864 Address::CompareLoadAddress (const Address& a, const Address& b, Target *target)
865 {
866     assert (target != NULL);
867     addr_t a_load_addr = a.GetLoadAddress (target);
868     addr_t b_load_addr = b.GetLoadAddress (target);
869     if (a_load_addr < b_load_addr)
870         return -1;
871     if (a_load_addr > b_load_addr)
872         return +1;
873     return 0;
874 }
875 
876 int
877 Address::CompareModulePointerAndOffset (const Address& a, const Address& b)
878 {
879     Module *a_module = a.GetModulePtr ();
880     Module *b_module = b.GetModulePtr ();
881     if (a_module < b_module)
882         return -1;
883     if (a_module > b_module)
884         return +1;
885     // Modules are the same, just compare the file address since they should
886     // be unique
887     addr_t a_file_addr = a.GetFileAddress();
888     addr_t b_file_addr = b.GetFileAddress();
889     if (a_file_addr < b_file_addr)
890         return -1;
891     if (a_file_addr > b_file_addr)
892         return +1;
893     return 0;
894 }
895 
896 
897 size_t
898 Address::MemorySize () const
899 {
900     // Noting special for the memory size of a single Address object,
901     // it is just the size of itself.
902     return sizeof(Address);
903 }
904 
905 
906 //----------------------------------------------------------------------
907 // NOTE: Be careful using this operator. It can correctly compare two
908 // addresses from the same Module correctly. It can't compare two
909 // addresses from different modules in any meaningful way, but it will
910 // compare the module pointers.
911 //
912 // To sum things up:
913 // - works great for addresses within the same module
914 // - it works for addresses across multiple modules, but don't expect the
915 //   address results to make much sense
916 //
917 // This basically lets Address objects be used in ordered collection
918 // classes.
919 //----------------------------------------------------------------------
920 
921 bool
922 lldb_private::operator< (const Address& lhs, const Address& rhs)
923 {
924     Module *lhs_module = lhs.GetModulePtr();
925     Module *rhs_module = rhs.GetModulePtr();
926     if (lhs_module == rhs_module)
927     {
928         // Addresses are in the same module, just compare the file addresses
929         return lhs.GetFileAddress() < rhs.GetFileAddress();
930     }
931     else
932     {
933         // The addresses are from different modules, just use the module
934         // pointer value to get consistent ordering
935         return lhs_module < rhs_module;
936     }
937 }
938 
939 bool
940 lldb_private::operator> (const Address& lhs, const Address& rhs)
941 {
942     Module *lhs_module = lhs.GetModulePtr();
943     Module *rhs_module = rhs.GetModulePtr();
944     if (lhs_module == rhs_module)
945     {
946         // Addresses are in the same module, just compare the file addresses
947         return lhs.GetFileAddress() > rhs.GetFileAddress();
948     }
949     else
950     {
951         // The addresses are from different modules, just use the module
952         // pointer value to get consistent ordering
953         return lhs_module > rhs_module;
954     }
955 }
956 
957 
958 // The operator == checks for exact equality only (same section, same offset)
959 bool
960 lldb_private::operator== (const Address& a, const Address& rhs)
961 {
962     return  a.GetSection() == rhs.GetSection() &&
963             a.GetOffset()  == rhs.GetOffset();
964 }
965 // The operator != checks for exact inequality only (differing section, or
966 // different offset)
967 bool
968 lldb_private::operator!= (const Address& a, const Address& rhs)
969 {
970     return  a.GetSection() != rhs.GetSection() ||
971             a.GetOffset()  != rhs.GetOffset();
972 }
973 
974 bool
975 Address::IsLinkedAddress () const
976 {
977     return m_section && m_section->GetLinkedSection();
978 }
979 
980 
981 void
982 Address::ResolveLinkedAddress ()
983 {
984     if (m_section)
985     {
986         const Section *linked_section = m_section->GetLinkedSection();
987         if (linked_section)
988         {
989             m_offset += m_section->GetLinkedOffset();
990             m_section = linked_section;
991         }
992     }
993 }
994 
995 AddressClass
996 Address::GetAddressClass () const
997 {
998     Module *module = GetModulePtr();
999     if (module)
1000     {
1001         ObjectFile *obj_file = module->GetObjectFile();
1002         if (obj_file)
1003             return obj_file->GetAddressClass (GetFileAddress());
1004     }
1005     return eAddressClassUnknown;
1006 }
1007 
1008 bool
1009 Address::SetLoadAddress (lldb::addr_t load_addr, Target *target)
1010 {
1011     if (target && target->GetSectionLoadList().ResolveLoadAddress(load_addr, *this))
1012         return true;
1013     m_section = NULL;
1014     m_offset = load_addr;
1015     return false;
1016 }
1017 
1018