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