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