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