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