1 //===-- 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/Module.h"
16 #include "lldb/Core/Section.h"
17 #include "lldb/Core/StreamString.h"
18 
19 namespace 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 
87 using namespace lldb;
88 using namespace lldb_private;
89 
90 
91 SBSection::SBSection () :
92     m_opaque_ap ()
93 {
94 }
95 
96 SBSection::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 
105 SBSection::SBSection (const lldb_private::Section *section) :
106     m_opaque_ap ()
107 {
108     if (section)
109         m_opaque_ap.reset (new SectionImpl(section));
110 }
111 
112 const SBSection &
113 SBSection::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 
122 SBSection::~SBSection ()
123 {
124 }
125 
126 bool
127 SBSection::IsValid () const
128 {
129     return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid();
130 }
131 
132 const char *
133 SBSection::GetName ()
134 {
135     if (IsValid())
136         return m_opaque_ap->GetSection()->GetName().GetCString();
137     return NULL;
138 }
139 
140 
141 lldb::SBSection
142 SBSection::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 
153 size_t
154 SBSection::GetNumSubSections ()
155 {
156     if (IsValid())
157         return m_opaque_ap->GetSection()->GetChildren ().GetSize();
158     return 0;
159 }
160 
161 lldb::SBSection
162 SBSection::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 
170 const lldb_private::Section *
171 SBSection::GetSection()
172 {
173     if (m_opaque_ap.get())
174         return m_opaque_ap->GetSection();
175     return NULL;
176 }
177 
178 void
179 SBSection::SetSection (const lldb_private::Section *section)
180 {
181     m_opaque_ap.reset (new SectionImpl(section));
182 }
183 
184 
185 
186 
187 lldb::addr_t
188 SBSection::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 
196 lldb::addr_t
197 SBSection::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 
208 uint64_t
209 SBSection::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 
229 uint64_t
230 SBSection::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 
241 SBData
242 SBSection::GetSectionData ()
243 {
244     return GetSectionData (0, UINT64_MAX);
245 }
246 
247 SBData
248 SBSection::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 
293 SectionType
294 SBSection::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 
306 bool
307 SBSection::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 
316 bool
317 SBSection::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 
326 bool
327 SBSection::GetDescription (SBStream &description)
328 {
329     if (IsValid())
330     {
331         const Section *section = m_opaque_ap->GetSection();
332         const addr_t file_addr = section->GetFileAddress();
333         description.Printf ("[0x%16.16llx-0x%16.16llx) ", file_addr, file_addr + section->GetByteSize());
334         section->DumpName(description.get());
335     }
336     else
337     {
338         description.Printf ("No value");
339     }
340 
341     return true;
342 }
343 
344