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