Home | History | Annotate | Download | only in API
      1 //===-- SBAddress.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/API/SBAddress.h"
     11 #include "lldb/API/SBProcess.h"
     12 #include "lldb/API/SBSection.h"
     13 #include "lldb/API/SBStream.h"
     14 #include "lldb/Core/Address.h"
     15 #include "lldb/Core/Log.h"
     16 #include "lldb/Core/Module.h"
     17 #include "lldb/Host/Mutex.h"
     18 #include "lldb/Target/Target.h"
     19 
     20 
     21 using namespace lldb;
     22 using namespace lldb_private;
     23 
     24 
     25 SBAddress::SBAddress () :
     26     m_opaque_ap ()
     27 {
     28 }
     29 
     30 SBAddress::SBAddress (const Address *lldb_object_ptr) :
     31     m_opaque_ap ()
     32 {
     33     if (lldb_object_ptr)
     34         ref() = *lldb_object_ptr;
     35 }
     36 
     37 SBAddress::SBAddress (const SBAddress &rhs) :
     38     m_opaque_ap ()
     39 {
     40     if (rhs.IsValid())
     41         ref() = rhs.ref();
     42 }
     43 
     44 
     45 SBAddress::SBAddress (lldb::SBSection section, lldb::addr_t offset) :
     46     m_opaque_ap(new Address (section.GetSP(), offset))
     47 {
     48 }
     49 
     50 // Create an address by resolving a load address using the supplied target
     51 SBAddress::SBAddress (lldb::addr_t load_addr, lldb::SBTarget &target) :
     52     m_opaque_ap()
     53 {
     54     SetLoadAddress (load_addr, target);
     55 }
     56 
     57 
     58 
     59 SBAddress::~SBAddress ()
     60 {
     61 }
     62 
     63 const SBAddress &
     64 SBAddress::operator = (const SBAddress &rhs)
     65 {
     66     if (this != &rhs)
     67     {
     68         if (rhs.IsValid())
     69             ref() = rhs.ref();
     70         else
     71             m_opaque_ap.reset();
     72     }
     73     return *this;
     74 }
     75 
     76 bool
     77 SBAddress::IsValid () const
     78 {
     79     return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid();
     80 }
     81 
     82 void
     83 SBAddress::Clear ()
     84 {
     85     m_opaque_ap.reset();
     86 }
     87 
     88 void
     89 SBAddress::SetAddress (lldb::SBSection section, lldb::addr_t offset)
     90 {
     91     Address &addr = ref();
     92     addr.SetSection (section.GetSP());
     93     addr.SetOffset (offset);
     94 }
     95 
     96 
     97 void
     98 SBAddress::SetAddress (const Address *lldb_object_ptr)
     99 {
    100     if (lldb_object_ptr)
    101         ref() =  *lldb_object_ptr;
    102     else
    103         m_opaque_ap.reset();
    104 }
    105 
    106 lldb::addr_t
    107 SBAddress::GetFileAddress () const
    108 {
    109     if (m_opaque_ap.get())
    110         return m_opaque_ap->GetFileAddress();
    111     else
    112         return LLDB_INVALID_ADDRESS;
    113 }
    114 
    115 lldb::addr_t
    116 SBAddress::GetLoadAddress (const SBTarget &target) const
    117 {
    118     Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    119 
    120     lldb::addr_t addr = LLDB_INVALID_ADDRESS;
    121     TargetSP target_sp (target.GetSP());
    122     if (target_sp)
    123     {
    124         if (m_opaque_ap.get())
    125         {
    126             Mutex::Locker api_locker (target_sp->GetAPIMutex());
    127             addr = m_opaque_ap->GetLoadAddress (target_sp.get());
    128         }
    129     }
    130 
    131     if (log)
    132     {
    133         if (addr == LLDB_INVALID_ADDRESS)
    134             log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => LLDB_INVALID_ADDRESS", target_sp.get());
    135         else
    136             log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => 0x%" PRIx64, target_sp.get(), addr);
    137     }
    138 
    139     return addr;
    140 }
    141 
    142 void
    143 SBAddress::SetLoadAddress (lldb::addr_t load_addr, lldb::SBTarget &target)
    144 {
    145     // Create the address object if we don't already have one
    146     ref();
    147     if (target.IsValid())
    148         *this = target.ResolveLoadAddress(load_addr);
    149     else
    150         m_opaque_ap->Clear();
    151 
    152     // Check if we weren't were able to resolve a section offset address.
    153     // If we weren't it is ok, the load address might be a location on the
    154     // stack or heap, so we should just have an address with no section and
    155     // a valid offset
    156     if (!m_opaque_ap->IsValid())
    157         m_opaque_ap->SetOffset(load_addr);
    158 }
    159 
    160 bool
    161 SBAddress::OffsetAddress (addr_t offset)
    162 {
    163     if (m_opaque_ap.get())
    164     {
    165         addr_t addr_offset = m_opaque_ap->GetOffset();
    166         if (addr_offset != LLDB_INVALID_ADDRESS)
    167         {
    168             m_opaque_ap->SetOffset(addr_offset + offset);
    169             return true;
    170         }
    171     }
    172     return false;
    173 }
    174 
    175 lldb::SBSection
    176 SBAddress::GetSection ()
    177 {
    178     lldb::SBSection sb_section;
    179     if (m_opaque_ap.get())
    180         sb_section.SetSP (m_opaque_ap->GetSection());
    181     return sb_section;
    182 }
    183 
    184 lldb::addr_t
    185 SBAddress::GetOffset ()
    186 {
    187     if (m_opaque_ap.get())
    188         return m_opaque_ap->GetOffset();
    189     return 0;
    190 }
    191 
    192 Address *
    193 SBAddress::operator->()
    194 {
    195     return m_opaque_ap.get();
    196 }
    197 
    198 const Address *
    199 SBAddress::operator->() const
    200 {
    201     return m_opaque_ap.get();
    202 }
    203 
    204 Address &
    205 SBAddress::ref ()
    206 {
    207     if (m_opaque_ap.get() == NULL)
    208         m_opaque_ap.reset (new Address());
    209     return *m_opaque_ap;
    210 }
    211 
    212 const Address &
    213 SBAddress::ref () const
    214 {
    215     // This object should already have checked with "IsValid()"
    216     // prior to calling this function. In case you didn't we will assert
    217     // and die to let you know.
    218     assert (m_opaque_ap.get());
    219     return *m_opaque_ap;
    220 }
    221 
    222 Address *
    223 SBAddress::get ()
    224 {
    225     return m_opaque_ap.get();
    226 }
    227 
    228 bool
    229 SBAddress::GetDescription (SBStream &description)
    230 {
    231     // Call "ref()" on the stream to make sure it creates a backing stream in
    232     // case there isn't one already...
    233     Stream &strm = description.ref();
    234     if (m_opaque_ap.get())
    235     {
    236         m_opaque_ap->Dump (&strm,
    237                            NULL,
    238                            Address::DumpStyleResolvedDescription,
    239                            Address::DumpStyleModuleWithFileAddress,
    240                            4);
    241         StreamString sstrm;
    242 //        m_opaque_ap->Dump (&sstrm, NULL, Address::DumpStyleResolvedDescription, Address::DumpStyleInvalid, 4);
    243 //        if (sstrm.GetData())
    244 //            strm.Printf (" (%s)", sstrm.GetData());
    245     }
    246     else
    247         strm.PutCString ("No value");
    248 
    249     return true;
    250 }
    251 
    252 SBModule
    253 SBAddress::GetModule ()
    254 {
    255     SBModule sb_module;
    256     if (m_opaque_ap.get())
    257         sb_module.SetSP (m_opaque_ap->GetModule());
    258     return sb_module;
    259 }
    260 
    261 SBSymbolContext
    262 SBAddress::GetSymbolContext (uint32_t resolve_scope)
    263 {
    264     SBSymbolContext sb_sc;
    265     if (m_opaque_ap.get())
    266         m_opaque_ap->CalculateSymbolContext (&sb_sc.ref(), resolve_scope);
    267     return sb_sc;
    268 }
    269 
    270 SBCompileUnit
    271 SBAddress::GetCompileUnit ()
    272 {
    273     SBCompileUnit sb_comp_unit;
    274     if (m_opaque_ap.get())
    275         sb_comp_unit.reset(m_opaque_ap->CalculateSymbolContextCompileUnit());
    276     return sb_comp_unit;
    277 }
    278 
    279 SBFunction
    280 SBAddress::GetFunction ()
    281 {
    282     SBFunction sb_function;
    283     if (m_opaque_ap.get())
    284         sb_function.reset(m_opaque_ap->CalculateSymbolContextFunction());
    285     return sb_function;
    286 }
    287 
    288 SBBlock
    289 SBAddress::GetBlock ()
    290 {
    291     SBBlock sb_block;
    292     if (m_opaque_ap.get())
    293         sb_block.SetPtr(m_opaque_ap->CalculateSymbolContextBlock());
    294     return sb_block;
    295 }
    296 
    297 SBSymbol
    298 SBAddress::GetSymbol ()
    299 {
    300     SBSymbol sb_symbol;
    301     if (m_opaque_ap.get())
    302         sb_symbol.reset(m_opaque_ap->CalculateSymbolContextSymbol());
    303     return sb_symbol;
    304 }
    305 
    306 SBLineEntry
    307 SBAddress::GetLineEntry ()
    308 {
    309     SBLineEntry sb_line_entry;
    310     if (m_opaque_ap.get())
    311     {
    312         LineEntry line_entry;
    313         if (m_opaque_ap->CalculateSymbolContextLineEntry (line_entry))
    314             sb_line_entry.SetLineEntry (line_entry);
    315     }
    316     return sb_line_entry;
    317 }
    318 
    319 AddressClass
    320 SBAddress::GetAddressClass ()
    321 {
    322     if (m_opaque_ap.get())
    323         return m_opaque_ap->GetAddressClass();
    324     return eAddressClassInvalid;
    325 }
    326 
    327