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 
20 using namespace lldb;
21 using namespace lldb_private;
22 
23 
24 SBSection::SBSection () :
25     m_opaque_wp ()
26 {
27 }
28 
29 SBSection::SBSection (const SBSection &rhs) :
30     m_opaque_wp (rhs.m_opaque_wp)
31 {
32 }
33 
34 
35 
36 SBSection::SBSection (const lldb::SectionSP &section_sp) :
37     m_opaque_wp () // Don't init with section_sp otherwise this will throw if section_sp doesn't contain a valid Section *
38 {
39     if (section_sp)
40         m_opaque_wp = section_sp;
41 }
42 
43 const SBSection &
44 SBSection::operator = (const SBSection &rhs)
45 {
46     m_opaque_wp = rhs.m_opaque_wp;
47     return *this;
48 }
49 
50 SBSection::~SBSection ()
51 {
52 }
53 
54 bool
55 SBSection::IsValid () const
56 {
57     SectionSP section_sp (GetSP());
58     return section_sp && section_sp->GetModule().get() != NULL;
59 }
60 
61 const char *
62 SBSection::GetName ()
63 {
64     SectionSP section_sp (GetSP());
65     if (section_sp)
66         return section_sp->GetName().GetCString();
67     return NULL;
68 }
69 
70 
71 lldb::SBSection
72 SBSection::FindSubSection (const char *sect_name)
73 {
74     lldb::SBSection sb_section;
75     if (sect_name)
76     {
77         SectionSP section_sp (GetSP());
78         if (section_sp)
79         {
80             ConstString const_sect_name(sect_name);
81             sb_section.SetSP(section_sp->GetChildren ().FindSectionByName(const_sect_name));
82         }
83     }
84     return sb_section;
85 }
86 
87 size_t
88 SBSection::GetNumSubSections ()
89 {
90     SectionSP section_sp (GetSP());
91     if (section_sp)
92         return section_sp->GetChildren ().GetSize();
93     return 0;
94 }
95 
96 lldb::SBSection
97 SBSection::GetSubSectionAtIndex (size_t idx)
98 {
99     lldb::SBSection sb_section;
100     SectionSP section_sp (GetSP());
101     if (section_sp)
102         sb_section.SetSP (section_sp->GetChildren ().GetSectionAtIndex(idx));
103     return sb_section;
104 }
105 
106 lldb::SectionSP
107 SBSection::GetSP() const
108 {
109     return m_opaque_wp.lock();
110 }
111 
112 void
113 SBSection::SetSP(const lldb::SectionSP &section_sp)
114 {
115     m_opaque_wp = section_sp;
116 }
117 
118 lldb::addr_t
119 SBSection::GetFileAddress ()
120 {
121     lldb::addr_t file_addr = LLDB_INVALID_ADDRESS;
122     SectionSP section_sp (GetSP());
123     if (section_sp)
124         return section_sp->GetFileAddress();
125     return file_addr;
126 }
127 
128 lldb::addr_t
129 SBSection::GetByteSize ()
130 {
131     SectionSP section_sp (GetSP());
132     if (section_sp)
133         return section_sp->GetByteSize();
134     return 0;
135 }
136 
137 uint64_t
138 SBSection::GetFileOffset ()
139 {
140     SectionSP section_sp (GetSP());
141     if (section_sp)
142     {
143         ModuleSP module_sp (section_sp->GetModule());
144         if (module_sp)
145         {
146             ObjectFile *objfile = module_sp->GetObjectFile();
147             if (objfile)
148                 return objfile->GetOffset() + section_sp->GetFileOffset();
149         }
150     }
151     return UINT64_MAX;
152 }
153 
154 uint64_t
155 SBSection::GetFileByteSize ()
156 {
157     SectionSP section_sp (GetSP());
158     if (section_sp)
159         return section_sp->GetFileSize();
160     return 0;
161 }
162 
163 SBData
164 SBSection::GetSectionData ()
165 {
166     return GetSectionData (0, UINT64_MAX);
167 }
168 
169 SBData
170 SBSection::GetSectionData (uint64_t offset, uint64_t size)
171 {
172     SBData sb_data;
173     SectionSP section_sp (GetSP());
174     if (section_sp)
175     {
176         const uint64_t sect_file_size = section_sp->GetFileSize();
177         if (sect_file_size > 0)
178         {
179             ModuleSP module_sp (section_sp->GetModule());
180             if (module_sp)
181             {
182                 ObjectFile *objfile = module_sp->GetObjectFile();
183                 if (objfile)
184                 {
185                     const uint64_t sect_file_offset = objfile->GetOffset() + section_sp->GetFileOffset();
186                     const uint64_t file_offset = sect_file_offset + offset;
187                     uint64_t file_size = size;
188                     if (file_size == UINT64_MAX)
189                     {
190                         file_size = section_sp->GetByteSize();
191                         if (file_size > offset)
192                             file_size -= offset;
193                         else
194                             file_size = 0;
195                     }
196                     DataBufferSP data_buffer_sp (objfile->GetFileSpec().ReadFileContents (file_offset, file_size));
197                     if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0)
198                     {
199                         DataExtractorSP data_extractor_sp (new DataExtractor (data_buffer_sp,
200                                                                               objfile->GetByteOrder(),
201                                                                               objfile->GetAddressByteSize()));
202 
203                         sb_data.SetOpaque (data_extractor_sp);
204                     }
205                 }
206             }
207         }
208     }
209     return sb_data;
210 }
211 
212 SectionType
213 SBSection::GetSectionType ()
214 {
215     SectionSP section_sp (GetSP());
216     if (section_sp.get())
217         return section_sp->GetType();
218     return eSectionTypeInvalid;
219 }
220 
221 
222 bool
223 SBSection::operator == (const SBSection &rhs)
224 {
225     SectionSP lhs_section_sp (GetSP());
226     SectionSP rhs_section_sp (rhs.GetSP());
227     if (lhs_section_sp && rhs_section_sp)
228         return lhs_section_sp == rhs_section_sp;
229     return false;
230 }
231 
232 bool
233 SBSection::operator != (const SBSection &rhs)
234 {
235     SectionSP lhs_section_sp (GetSP());
236     SectionSP rhs_section_sp (rhs.GetSP());
237     return lhs_section_sp != rhs_section_sp;
238 }
239 
240 bool
241 SBSection::GetDescription (SBStream &description)
242 {
243     Stream &strm = description.ref();
244 
245     SectionSP section_sp (GetSP());
246     if (section_sp)
247     {
248         const addr_t file_addr = section_sp->GetFileAddress();
249         strm.Printf ("[0x%16.16llx-0x%16.16llx) ", file_addr, file_addr + section_sp->GetByteSize());
250         section_sp->DumpName(&strm);
251     }
252     else
253     {
254         strm.PutCString ("No value");
255     }
256 
257     return true;
258 }
259 
260