Home | History | Annotate | Download | only in Core
      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 
     25 using namespace lldb;
     26 using namespace lldb_private;
     27 
     28 static size_t
     29 ReadBytes (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 
     44 static bool
     45 GetByteOrderAndAddressSize (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 
     71 static uint64_t
     72 ReadUIntMax64 (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 
     99 static bool
    100 ReadAddress (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 
    140 static bool
    141 DumpUInt (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 
    172 static size_t
    173 ReadCStringFromMemory (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 
    216 Address::Address (lldb::addr_t abs_addr) :
    217     m_section_wp (),
    218     m_offset (abs_addr)
    219 {
    220 }
    221 
    222 Address::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 
    229 const Address&
    230 Address::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 
    240 bool
    241 Address::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 
    258 ModuleSP
    259 Address::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 
    268 addr_t
    269 Address::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 
    288 addr_t
    289 Address::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 
    314 addr_t
    315 Address::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 
    331 bool
    332 Address::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 
    343 addr_t
    344 Address::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 
    352 bool
    353 Address::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 
    364 bool
    365 Address::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 
    770 uint32_t
    771 Address::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 
    790 ModuleSP
    791 Address::CalculateSymbolContextModule () const
    792 {
    793     SectionSP section_sp (GetSection());
    794     if (section_sp)
    795         return section_sp->GetModule();
    796     return ModuleSP();
    797 }
    798 
    799 CompileUnit *
    800 Address::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 
    816 Function *
    817 Address::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 
    833 Block *
    834 Address::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 
    850 Symbol *
    851 Address::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 
    867 bool
    868 Address::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 
    889 int
    890 Address::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 
    902 int
    903 Address::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 
    915 int
    916 Address::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 
    938 size_t
    939 Address::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 
    962 bool
    963 lldb_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 
    982 bool
    983 lldb_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)
   1004 bool
   1005 lldb_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)
   1012 bool
   1013 lldb_private::operator!= (const Address& a, const Address& rhs)
   1014 {
   1015     return  a.GetOffset()  != rhs.GetOffset() ||
   1016             a.GetSection() != rhs.GetSection();
   1017 }
   1018 
   1019 AddressClass
   1020 Address::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 
   1036 bool
   1037 Address::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