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