blob: 6d665962465819c8b8e3817d2bc16ba3af710b0f [file] [log] [blame]
Greg Clayton3e8c25f2011-09-24 00:52:29 +00001//===-- SBSection.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/SBSection.h"
11#include "lldb/API/SBStream.h"
12#include "lldb/Core/DataBuffer.h"
13#include "lldb/Core/DataExtractor.h"
14#include "lldb/Core/Log.h"
15#include "lldb/Core/Section.h"
16#include "lldb/Core/Module.h"
17
18namespace lldb_private
19{
20 // We need a section implementation to hold onto a reference to the module
21 // since if the module goes away and we have anyone still holding onto a
22 // SBSection object, we could crash.
23 class SectionImpl
24 {
25 public:
26 SectionImpl (const lldb_private::Section *section = NULL) :
27 m_module_sp (),
28 m_section (section)
29 {
30 if (section)
31 m_module_sp = section->GetModule();
32 }
33
34 SectionImpl (const SectionImpl &rhs) :
35 m_module_sp (rhs.m_module_sp),
36 m_section (rhs.m_section)
37 {
38 }
39
40 bool
41 IsValid () const
42 {
43 return m_section != NULL;
44 }
45
46 void
47 operator = (const SectionImpl &rhs)
48 {
49 m_module_sp = rhs.m_module_sp;
50 m_section = rhs.m_section;
51 }
52
53 void
54 operator =(const lldb_private::Section *section)
55 {
56 m_section = section;
57 if (section)
58 m_module_sp.reset(section->GetModule());
59 else
60 m_module_sp.reset();
61 }
62
63 const lldb_private::Section *
64 GetSection () const
65 {
66 return m_section;
67 }
68
69 Module *
70 GetModule()
71 {
72 return m_module_sp.get();
73 }
74
75 const lldb::ModuleSP &
76 GetModuleSP() const
77 {
78 return m_module_sp;
79 }
80 protected:
81 lldb::ModuleSP m_module_sp;
82 const lldb_private::Section *m_section;
83 };
84}
85
86using namespace lldb;
87using namespace lldb_private;
88
89
90SBSection::SBSection () :
91 m_opaque_ap ()
92{
93}
94
95SBSection::SBSection (const SBSection &rhs) :
96 m_opaque_ap ()
97{
98 if (rhs.IsValid())
99 m_opaque_ap.reset (new SectionImpl (*rhs.m_opaque_ap));
100}
101
102
103
104SBSection::SBSection (const lldb_private::Section *section) :
105 m_opaque_ap ()
106{
107 if (section)
108 m_opaque_ap.reset (new SectionImpl(section));
109}
110
111const SBSection &
112SBSection::operator = (const SBSection &rhs)
113{
114 if (this != &rhs && rhs.IsValid())
115 m_opaque_ap.reset (new SectionImpl(*rhs.m_opaque_ap));
116 else
117 m_opaque_ap.reset ();
118 return *this;
119}
120
121SBSection::~SBSection ()
122{
123}
124
125bool
126SBSection::IsValid () const
127{
128 return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid();
129}
130
131lldb::SBSection
132SBSection::FindSubSection (const char *sect_name)
133{
134 lldb::SBSection sb_section;
135 if (IsValid())
136 {
137 ConstString const_sect_name(sect_name);
138 sb_section.SetSection(m_opaque_ap->GetSection()->GetChildren ().FindSectionByName(const_sect_name).get());
139 }
140 return sb_section;
141}
142
143size_t
144SBSection::GetNumSubSections ()
145{
146 if (IsValid())
147 return m_opaque_ap->GetSection()->GetChildren ().GetSize();
148 return 0;
149}
150
151lldb::SBSection
152SBSection::GetSubSectionAtIndex (size_t idx)
153{
154 lldb::SBSection sb_section;
155 if (IsValid())
156 sb_section.SetSection(m_opaque_ap->GetSection()->GetChildren ().GetSectionAtIndex(idx).get());
157 return sb_section;
158}
159
160const lldb_private::Section *
161SBSection::GetSection()
162{
163 if (m_opaque_ap.get())
164 return m_opaque_ap->GetSection();
165 return NULL;
166}
167
168void
169SBSection::SetSection (const lldb_private::Section *section)
170{
171 m_opaque_ap.reset (new SectionImpl(section));
172}
173
174
175
176
177lldb::addr_t
178SBSection::GetFileAddress ()
179{
180 lldb::addr_t file_addr = LLDB_INVALID_ADDRESS;
181 if (IsValid())
182 return m_opaque_ap->GetSection()->GetFileAddress();
183 return file_addr;
184}
185
186lldb::addr_t
187SBSection::GetByteSize ()
188{
189 if (IsValid())
190 {
191 const Section *section = m_opaque_ap->GetSection();
192 if (section)
193 return section->GetByteSize();
194 }
195 return 0;
196}
197
198uint64_t
199SBSection::GetFileOffset ()
200{
201 if (IsValid())
202 {
203 const Section *section = m_opaque_ap->GetSection();
204 if (section)
205 {
206 Module *module = m_opaque_ap->GetModule();
207 if (module)
208 {
209 ObjectFile *objfile = module->GetObjectFile();
210 if (objfile)
211 return objfile->GetOffset() + section->GetFileOffset();
212 }
213 return section->GetFileOffset();
214 }
215 }
216 return 0;
217}
218
219uint64_t
220SBSection::GetFileByteSize ()
221{
222 if (IsValid())
223 {
224 const Section *section = m_opaque_ap->GetSection();
225 if (section)
226 return section->GetFileSize();
227 }
228 return 0;
229}
230
231SBData
232SBSection::GetSectionData (uint64_t offset, uint64_t size)
233{
234 SBData sb_data;
235 if (IsValid())
236 {
237 const Section *section = m_opaque_ap->GetSection();
238 if (section)
239 {
240 const uint64_t sect_file_size = section->GetFileSize();
241 if (sect_file_size > 0)
242 {
243 Module *module = m_opaque_ap->GetModule();
244 if (module)
245 {
246 ObjectFile *objfile = module->GetObjectFile();
247 if (objfile)
248 {
249 const uint64_t sect_file_offset = objfile->GetOffset() + section->GetFileOffset();
250 const uint64_t file_offset = sect_file_offset + offset;
251 uint64_t file_size = size;
252 if (file_size == UINT64_MAX)
253 {
254 file_size = section->GetByteSize();
255 if (file_size > offset)
256 file_size -= offset;
257 else
258 file_size = 0;
259 }
260 DataBufferSP data_buffer_sp (objfile->GetFileSpec().ReadFileContents (file_offset, file_size));
261 if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0)
262 {
263 DataExtractorSP data_extractor_sp (new DataExtractor (data_buffer_sp,
264 objfile->GetByteOrder(),
265 objfile->GetAddressByteSize()));
266
267 sb_data.SetOpaque (data_extractor_sp);
268 }
269 }
270 }
271 }
272 }
273 }
274 return sb_data;
275}
276
277SectionType
278SBSection::GetSectionType ()
279{
280 if (m_opaque_ap.get())
281 {
282 const Section *section = m_opaque_ap->GetSection();
283 if (section)
284 return section->GetType();
285 }
286 return eSectionTypeInvalid;
287}
288
289
290bool
291SBSection::operator == (const SBSection &rhs)
292{
293 SectionImpl *lhs_ptr = m_opaque_ap.get();
294 SectionImpl *rhs_ptr = rhs.m_opaque_ap.get();
295 if (lhs_ptr && rhs_ptr)
296 return lhs_ptr->GetSection() == rhs_ptr->GetSection();
297 return false;
298}
299
300bool
301SBSection::operator != (const SBSection &rhs)
302{
303 SectionImpl *lhs_ptr = m_opaque_ap.get();
304 SectionImpl *rhs_ptr = rhs.m_opaque_ap.get();
305 if (lhs_ptr && rhs_ptr)
306 return lhs_ptr->GetSection() != rhs_ptr->GetSection();
307 return false;
308}
309
310bool
311SBSection::GetDescription (SBStream &description)
312{
313 if (m_opaque_ap.get())
314 {
315 description.Printf ("SBSection");
316 }
317 else
318 {
319 description.Printf ("No value");
320 }
321
322 return true;
323}
324