blob: 2636dd021362301a7d06a6ab5aa09b1c5e7fafb1 [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
Greg Clayton980c7502011-09-24 01:37:21 +0000131const char *
132SBSection::GetName ()
133{
134 if (IsValid())
135 return m_opaque_ap->GetSection()->GetName().GetCString();
136 return NULL;
137}
138
139
Greg Clayton3e8c25f2011-09-24 00:52:29 +0000140lldb::SBSection
141SBSection::FindSubSection (const char *sect_name)
142{
143 lldb::SBSection sb_section;
144 if (IsValid())
145 {
146 ConstString const_sect_name(sect_name);
147 sb_section.SetSection(m_opaque_ap->GetSection()->GetChildren ().FindSectionByName(const_sect_name).get());
148 }
149 return sb_section;
150}
151
152size_t
153SBSection::GetNumSubSections ()
154{
155 if (IsValid())
156 return m_opaque_ap->GetSection()->GetChildren ().GetSize();
157 return 0;
158}
159
160lldb::SBSection
161SBSection::GetSubSectionAtIndex (size_t idx)
162{
163 lldb::SBSection sb_section;
164 if (IsValid())
165 sb_section.SetSection(m_opaque_ap->GetSection()->GetChildren ().GetSectionAtIndex(idx).get());
166 return sb_section;
167}
168
169const lldb_private::Section *
170SBSection::GetSection()
171{
172 if (m_opaque_ap.get())
173 return m_opaque_ap->GetSection();
174 return NULL;
175}
176
177void
178SBSection::SetSection (const lldb_private::Section *section)
179{
180 m_opaque_ap.reset (new SectionImpl(section));
181}
182
183
184
185
186lldb::addr_t
187SBSection::GetFileAddress ()
188{
189 lldb::addr_t file_addr = LLDB_INVALID_ADDRESS;
190 if (IsValid())
191 return m_opaque_ap->GetSection()->GetFileAddress();
192 return file_addr;
193}
194
195lldb::addr_t
196SBSection::GetByteSize ()
197{
198 if (IsValid())
199 {
200 const Section *section = m_opaque_ap->GetSection();
201 if (section)
202 return section->GetByteSize();
203 }
204 return 0;
205}
206
207uint64_t
208SBSection::GetFileOffset ()
209{
210 if (IsValid())
211 {
212 const Section *section = m_opaque_ap->GetSection();
213 if (section)
214 {
215 Module *module = m_opaque_ap->GetModule();
216 if (module)
217 {
218 ObjectFile *objfile = module->GetObjectFile();
219 if (objfile)
220 return objfile->GetOffset() + section->GetFileOffset();
221 }
222 return section->GetFileOffset();
223 }
224 }
225 return 0;
226}
227
228uint64_t
229SBSection::GetFileByteSize ()
230{
231 if (IsValid())
232 {
233 const Section *section = m_opaque_ap->GetSection();
234 if (section)
235 return section->GetFileSize();
236 }
237 return 0;
238}
239
240SBData
241SBSection::GetSectionData (uint64_t offset, uint64_t size)
242{
243 SBData sb_data;
244 if (IsValid())
245 {
246 const Section *section = m_opaque_ap->GetSection();
247 if (section)
248 {
249 const uint64_t sect_file_size = section->GetFileSize();
250 if (sect_file_size > 0)
251 {
252 Module *module = m_opaque_ap->GetModule();
253 if (module)
254 {
255 ObjectFile *objfile = module->GetObjectFile();
256 if (objfile)
257 {
258 const uint64_t sect_file_offset = objfile->GetOffset() + section->GetFileOffset();
259 const uint64_t file_offset = sect_file_offset + offset;
260 uint64_t file_size = size;
261 if (file_size == UINT64_MAX)
262 {
263 file_size = section->GetByteSize();
264 if (file_size > offset)
265 file_size -= offset;
266 else
267 file_size = 0;
268 }
269 DataBufferSP data_buffer_sp (objfile->GetFileSpec().ReadFileContents (file_offset, file_size));
270 if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0)
271 {
272 DataExtractorSP data_extractor_sp (new DataExtractor (data_buffer_sp,
273 objfile->GetByteOrder(),
274 objfile->GetAddressByteSize()));
275
276 sb_data.SetOpaque (data_extractor_sp);
277 }
278 }
279 }
280 }
281 }
282 }
283 return sb_data;
284}
285
286SectionType
287SBSection::GetSectionType ()
288{
289 if (m_opaque_ap.get())
290 {
291 const Section *section = m_opaque_ap->GetSection();
292 if (section)
293 return section->GetType();
294 }
295 return eSectionTypeInvalid;
296}
297
298
299bool
300SBSection::operator == (const SBSection &rhs)
301{
302 SectionImpl *lhs_ptr = m_opaque_ap.get();
303 SectionImpl *rhs_ptr = rhs.m_opaque_ap.get();
304 if (lhs_ptr && rhs_ptr)
305 return lhs_ptr->GetSection() == rhs_ptr->GetSection();
306 return false;
307}
308
309bool
310SBSection::operator != (const SBSection &rhs)
311{
312 SectionImpl *lhs_ptr = m_opaque_ap.get();
313 SectionImpl *rhs_ptr = rhs.m_opaque_ap.get();
314 if (lhs_ptr && rhs_ptr)
315 return lhs_ptr->GetSection() != rhs_ptr->GetSection();
316 return false;
317}
318
319bool
320SBSection::GetDescription (SBStream &description)
321{
322 if (m_opaque_ap.get())
323 {
324 description.Printf ("SBSection");
325 }
326 else
327 {
328 description.Printf ("No value");
329 }
330
331 return true;
332}
333