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