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