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