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/SBStream.h"
13 #include "lldb/Core/Address.h"
14 #include "lldb/Core/Log.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Host/Mutex.h"
17 #include "lldb/Target/Target.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 
23 SBAddress::SBAddress () :
24     m_opaque_ap ()
25 {
26 }
27 
28 SBAddress::SBAddress (const lldb_private::Address *lldb_object_ptr) :
29     m_opaque_ap ()
30 {
31     if (lldb_object_ptr)
32         m_opaque_ap.reset (new lldb_private::Address(*lldb_object_ptr));
33 }
34 
35 SBAddress::SBAddress (const SBAddress &rhs) :
36     m_opaque_ap ()
37 {
38     if (rhs.IsValid())
39         m_opaque_ap.reset (new lldb_private::Address(*rhs.m_opaque_ap.get()));
40 }
41 
42 SBAddress::~SBAddress ()
43 {
44 }
45 
46 const SBAddress &
47 SBAddress::operator = (const SBAddress &rhs)
48 {
49     if (this != &rhs && rhs.IsValid())
50         m_opaque_ap.reset (new lldb_private::Address(*rhs.m_opaque_ap.get()));
51     return *this;
52 }
53 
54 bool
55 SBAddress::IsValid () const
56 {
57     return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid();
58 }
59 
60 void
61 SBAddress::Clear ()
62 {
63     m_opaque_ap.reset();
64 }
65 
66 void
67 SBAddress::SetAddress (const lldb_private::Address *lldb_object_ptr)
68 {
69     if (lldb_object_ptr)
70     {
71         if (m_opaque_ap.get())
72             *m_opaque_ap = *lldb_object_ptr;
73         else
74             m_opaque_ap.reset (new lldb_private::Address(*lldb_object_ptr));
75         return;
76     }
77     if (m_opaque_ap.get())
78         m_opaque_ap->Clear();
79 }
80 
81 lldb::addr_t
82 SBAddress::GetFileAddress () const
83 {
84     if (m_opaque_ap.get())
85         return m_opaque_ap->GetFileAddress();
86     else
87         return LLDB_INVALID_ADDRESS;
88 }
89 
90 lldb::addr_t
91 SBAddress::GetLoadAddress (const SBTarget &target) const
92 {
93     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
94 
95     lldb::addr_t addr = LLDB_INVALID_ADDRESS;
96     if (m_opaque_ap.get())
97     {
98         Mutex::Locker api_locker (target->GetAPIMutex());
99         addr = m_opaque_ap->GetLoadAddress (target.get());
100     }
101 
102     if (log)
103     {
104         if (addr == LLDB_INVALID_ADDRESS)
105             log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => LLDB_INVALID_ADDRESS", target.get());
106         else
107             log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => 0x%llx", target.get(), addr);
108     }
109 
110     return addr;
111 }
112 
113 bool
114 SBAddress::OffsetAddress (addr_t offset)
115 {
116     if (m_opaque_ap.get())
117     {
118         addr_t addr_offset = m_opaque_ap->GetOffset();
119         if (addr_offset != LLDB_INVALID_ADDRESS)
120         {
121             m_opaque_ap->SetOffset(addr_offset + offset);
122             return true;
123         }
124     }
125     return false;
126 }
127 
128 lldb_private::Address *
129 SBAddress::operator->()
130 {
131     return m_opaque_ap.get();
132 }
133 
134 const lldb_private::Address *
135 SBAddress::operator->() const
136 {
137     return m_opaque_ap.get();
138 }
139 
140 lldb_private::Address &
141 SBAddress::operator*()
142 {
143     if (m_opaque_ap.get() == NULL)
144         m_opaque_ap.reset (new lldb_private::Address);
145     return *m_opaque_ap;
146 }
147 
148 const lldb_private::Address &
149 SBAddress::operator*() const
150 {
151     assert (m_opaque_ap.get());
152     return *m_opaque_ap;
153 }
154 
155 lldb_private::Address *
156 SBAddress::get ()
157 {
158     return m_opaque_ap.get();
159 }
160 
161 bool
162 SBAddress::GetDescription (SBStream &description)
163 {
164     // Call "ref()" on the stream to make sure it creates a backing stream in
165     // case there isn't one already...
166     description.ref();
167     if (m_opaque_ap.get())
168         m_opaque_ap->Dump (description.get(), NULL, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleInvalid, 4);
169     else
170         description.Printf ("No value");
171 
172     return true;
173 }
174 
175 SectionType
176 SBAddress::GetSectionType ()
177 {
178     if (m_opaque_ap.get())
179     {
180         const Section *section = m_opaque_ap->GetSection();
181         if (section)
182             return section->GetType();
183     }
184     return eSectionTypeInvalid;
185 }
186 
187 
188 SBModule
189 SBAddress::GetModule ()
190 {
191     SBModule sb_module;
192     if (m_opaque_ap.get())
193     {
194         const Module *module = m_opaque_ap->GetModule();
195         if (module)
196             *sb_module = module->GetSP();
197     }
198     return sb_module;
199 }
200 
201 
202