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