1 //===-- SBSection.cpp -----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/API/SBSection.h"
10 #include "SBReproducerPrivate.h"
11 #include "lldb/API/SBStream.h"
12 #include "lldb/API/SBTarget.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/Section.h"
15 #include "lldb/Symbol/ObjectFile.h"
16 #include "lldb/Utility/DataBuffer.h"
17 #include "lldb/Utility/DataExtractor.h"
18 #include "lldb/Utility/StreamString.h"
19 
20 using namespace lldb;
21 using namespace lldb_private;
22 
SBSection()23 SBSection::SBSection() : m_opaque_wp() {
24   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBSection);
25 }
26 
SBSection(const SBSection & rhs)27 SBSection::SBSection(const SBSection &rhs) : m_opaque_wp(rhs.m_opaque_wp) {
28   LLDB_RECORD_CONSTRUCTOR(SBSection, (const lldb::SBSection &), rhs);
29 }
30 
SBSection(const lldb::SectionSP & section_sp)31 SBSection::SBSection(const lldb::SectionSP &section_sp)
32     : m_opaque_wp() // Don't init with section_sp otherwise this will throw if
33                     // section_sp doesn't contain a valid Section *
34 {
35   if (section_sp)
36     m_opaque_wp = section_sp;
37 }
38 
operator =(const SBSection & rhs)39 const SBSection &SBSection::operator=(const SBSection &rhs) {
40   LLDB_RECORD_METHOD(const lldb::SBSection &,
41                      SBSection, operator=,(const lldb::SBSection &), rhs);
42 
43   m_opaque_wp = rhs.m_opaque_wp;
44   return LLDB_RECORD_RESULT(*this);
45 }
46 
47 SBSection::~SBSection() = default;
48 
IsValid() const49 bool SBSection::IsValid() const {
50   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBSection, IsValid);
51   return this->operator bool();
52 }
operator bool() const53 SBSection::operator bool() const {
54   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBSection, operator bool);
55 
56   SectionSP section_sp(GetSP());
57   return section_sp && section_sp->GetModule().get() != nullptr;
58 }
59 
GetName()60 const char *SBSection::GetName() {
61   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBSection, GetName);
62 
63   SectionSP section_sp(GetSP());
64   if (section_sp)
65     return section_sp->GetName().GetCString();
66   return nullptr;
67 }
68 
GetParent()69 lldb::SBSection SBSection::GetParent() {
70   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBSection, SBSection, GetParent);
71 
72   lldb::SBSection sb_section;
73   SectionSP section_sp(GetSP());
74   if (section_sp) {
75     SectionSP parent_section_sp(section_sp->GetParent());
76     if (parent_section_sp)
77       sb_section.SetSP(parent_section_sp);
78   }
79   return LLDB_RECORD_RESULT(sb_section);
80 }
81 
FindSubSection(const char * sect_name)82 lldb::SBSection SBSection::FindSubSection(const char *sect_name) {
83   LLDB_RECORD_METHOD(lldb::SBSection, SBSection, FindSubSection, (const char *),
84                      sect_name);
85 
86   lldb::SBSection sb_section;
87   if (sect_name) {
88     SectionSP section_sp(GetSP());
89     if (section_sp) {
90       ConstString const_sect_name(sect_name);
91       sb_section.SetSP(
92           section_sp->GetChildren().FindSectionByName(const_sect_name));
93     }
94   }
95   return LLDB_RECORD_RESULT(sb_section);
96 }
97 
GetNumSubSections()98 size_t SBSection::GetNumSubSections() {
99   LLDB_RECORD_METHOD_NO_ARGS(size_t, SBSection, GetNumSubSections);
100 
101   SectionSP section_sp(GetSP());
102   if (section_sp)
103     return section_sp->GetChildren().GetSize();
104   return 0;
105 }
106 
GetSubSectionAtIndex(size_t idx)107 lldb::SBSection SBSection::GetSubSectionAtIndex(size_t idx) {
108   LLDB_RECORD_METHOD(lldb::SBSection, SBSection, GetSubSectionAtIndex, (size_t),
109                      idx);
110 
111   lldb::SBSection sb_section;
112   SectionSP section_sp(GetSP());
113   if (section_sp)
114     sb_section.SetSP(section_sp->GetChildren().GetSectionAtIndex(idx));
115   return LLDB_RECORD_RESULT(sb_section);
116 }
117 
GetSP() const118 lldb::SectionSP SBSection::GetSP() const { return m_opaque_wp.lock(); }
119 
SetSP(const lldb::SectionSP & section_sp)120 void SBSection::SetSP(const lldb::SectionSP &section_sp) {
121   m_opaque_wp = section_sp;
122 }
123 
GetFileAddress()124 lldb::addr_t SBSection::GetFileAddress() {
125   LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBSection, GetFileAddress);
126 
127   lldb::addr_t file_addr = LLDB_INVALID_ADDRESS;
128   SectionSP section_sp(GetSP());
129   if (section_sp)
130     return section_sp->GetFileAddress();
131   return file_addr;
132 }
133 
GetLoadAddress(lldb::SBTarget & sb_target)134 lldb::addr_t SBSection::GetLoadAddress(lldb::SBTarget &sb_target) {
135   LLDB_RECORD_METHOD(lldb::addr_t, SBSection, GetLoadAddress,
136                      (lldb::SBTarget &), sb_target);
137 
138   TargetSP target_sp(sb_target.GetSP());
139   if (target_sp) {
140     SectionSP section_sp(GetSP());
141     if (section_sp)
142       return section_sp->GetLoadBaseAddress(target_sp.get());
143   }
144   return LLDB_INVALID_ADDRESS;
145 }
146 
GetByteSize()147 lldb::addr_t SBSection::GetByteSize() {
148   LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBSection, GetByteSize);
149 
150   SectionSP section_sp(GetSP());
151   if (section_sp)
152     return section_sp->GetByteSize();
153   return 0;
154 }
155 
GetFileOffset()156 uint64_t SBSection::GetFileOffset() {
157   LLDB_RECORD_METHOD_NO_ARGS(uint64_t, SBSection, GetFileOffset);
158 
159   SectionSP section_sp(GetSP());
160   if (section_sp) {
161     ModuleSP module_sp(section_sp->GetModule());
162     if (module_sp) {
163       ObjectFile *objfile = module_sp->GetObjectFile();
164       if (objfile)
165         return objfile->GetFileOffset() + section_sp->GetFileOffset();
166     }
167   }
168   return UINT64_MAX;
169 }
170 
GetFileByteSize()171 uint64_t SBSection::GetFileByteSize() {
172   LLDB_RECORD_METHOD_NO_ARGS(uint64_t, SBSection, GetFileByteSize);
173 
174   SectionSP section_sp(GetSP());
175   if (section_sp)
176     return section_sp->GetFileSize();
177   return 0;
178 }
179 
GetSectionData()180 SBData SBSection::GetSectionData() {
181   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBData, SBSection, GetSectionData);
182 
183   return LLDB_RECORD_RESULT(GetSectionData(0, UINT64_MAX));
184 }
185 
GetSectionData(uint64_t offset,uint64_t size)186 SBData SBSection::GetSectionData(uint64_t offset, uint64_t size) {
187   LLDB_RECORD_METHOD(lldb::SBData, SBSection, GetSectionData,
188                      (uint64_t, uint64_t), offset, size);
189 
190   SBData sb_data;
191   SectionSP section_sp(GetSP());
192   if (section_sp) {
193     const uint64_t sect_file_size = section_sp->GetFileSize();
194     if (sect_file_size > 0) {
195       ModuleSP module_sp(section_sp->GetModule());
196       if (module_sp) {
197         ObjectFile *objfile = module_sp->GetObjectFile();
198         if (objfile) {
199           const uint64_t sect_file_offset =
200               objfile->GetFileOffset() + section_sp->GetFileOffset();
201           const uint64_t file_offset = sect_file_offset + offset;
202           uint64_t file_size = size;
203           if (file_size == UINT64_MAX) {
204             file_size = section_sp->GetByteSize();
205             if (file_size > offset)
206               file_size -= offset;
207             else
208               file_size = 0;
209           }
210           auto data_buffer_sp = FileSystem::Instance().CreateDataBuffer(
211               objfile->GetFileSpec().GetPath(), file_size, file_offset);
212           if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0) {
213             DataExtractorSP data_extractor_sp(
214                 new DataExtractor(data_buffer_sp, objfile->GetByteOrder(),
215                                   objfile->GetAddressByteSize()));
216 
217             sb_data.SetOpaque(data_extractor_sp);
218           }
219         }
220       }
221     }
222   }
223   return LLDB_RECORD_RESULT(sb_data);
224 }
225 
GetSectionType()226 SectionType SBSection::GetSectionType() {
227   LLDB_RECORD_METHOD_NO_ARGS(lldb::SectionType, SBSection, GetSectionType);
228 
229   SectionSP section_sp(GetSP());
230   if (section_sp.get())
231     return section_sp->GetType();
232   return eSectionTypeInvalid;
233 }
234 
GetPermissions() const235 uint32_t SBSection::GetPermissions() const {
236   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBSection, GetPermissions);
237 
238   SectionSP section_sp(GetSP());
239   if (section_sp)
240     return section_sp->GetPermissions();
241   return 0;
242 }
243 
GetTargetByteSize()244 uint32_t SBSection::GetTargetByteSize() {
245   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBSection, GetTargetByteSize);
246 
247   SectionSP section_sp(GetSP());
248   if (section_sp.get())
249     return section_sp->GetTargetByteSize();
250   return 0;
251 }
252 
operator ==(const SBSection & rhs)253 bool SBSection::operator==(const SBSection &rhs) {
254   LLDB_RECORD_METHOD(bool, SBSection, operator==,(const lldb::SBSection &),
255                      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 
operator !=(const SBSection & rhs)264 bool SBSection::operator!=(const SBSection &rhs) {
265   LLDB_RECORD_METHOD(bool, SBSection, operator!=,(const lldb::SBSection &),
266                      rhs);
267 
268   SectionSP lhs_section_sp(GetSP());
269   SectionSP rhs_section_sp(rhs.GetSP());
270   return lhs_section_sp != rhs_section_sp;
271 }
272 
GetDescription(SBStream & description)273 bool SBSection::GetDescription(SBStream &description) {
274   LLDB_RECORD_METHOD(bool, SBSection, GetDescription, (lldb::SBStream &),
275                      description);
276 
277   Stream &strm = description.ref();
278 
279   SectionSP section_sp(GetSP());
280   if (section_sp) {
281     const addr_t file_addr = section_sp->GetFileAddress();
282     strm.Printf("[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") ", file_addr,
283                 file_addr + section_sp->GetByteSize());
284     section_sp->DumpName(strm.AsRawOstream());
285   } else {
286     strm.PutCString("No value");
287   }
288 
289   return true;
290 }
291 
292 namespace lldb_private {
293 namespace repro {
294 
295 template <>
RegisterMethods(Registry & R)296 void RegisterMethods<SBSection>(Registry &R) {
297   LLDB_REGISTER_CONSTRUCTOR(SBSection, ());
298   LLDB_REGISTER_CONSTRUCTOR(SBSection, (const lldb::SBSection &));
299   LLDB_REGISTER_METHOD(const lldb::SBSection &,
300                        SBSection, operator=,(const lldb::SBSection &));
301   LLDB_REGISTER_METHOD_CONST(bool, SBSection, IsValid, ());
302   LLDB_REGISTER_METHOD_CONST(bool, SBSection, operator bool, ());
303   LLDB_REGISTER_METHOD(const char *, SBSection, GetName, ());
304   LLDB_REGISTER_METHOD(lldb::SBSection, SBSection, GetParent, ());
305   LLDB_REGISTER_METHOD(lldb::SBSection, SBSection, FindSubSection,
306                        (const char *));
307   LLDB_REGISTER_METHOD(size_t, SBSection, GetNumSubSections, ());
308   LLDB_REGISTER_METHOD(lldb::SBSection, SBSection, GetSubSectionAtIndex,
309                        (size_t));
310   LLDB_REGISTER_METHOD(lldb::addr_t, SBSection, GetFileAddress, ());
311   LLDB_REGISTER_METHOD(lldb::addr_t, SBSection, GetLoadAddress,
312                        (lldb::SBTarget &));
313   LLDB_REGISTER_METHOD(lldb::addr_t, SBSection, GetByteSize, ());
314   LLDB_REGISTER_METHOD(uint64_t, SBSection, GetFileOffset, ());
315   LLDB_REGISTER_METHOD(uint64_t, SBSection, GetFileByteSize, ());
316   LLDB_REGISTER_METHOD(lldb::SBData, SBSection, GetSectionData, ());
317   LLDB_REGISTER_METHOD(lldb::SBData, SBSection, GetSectionData,
318                        (uint64_t, uint64_t));
319   LLDB_REGISTER_METHOD(lldb::SectionType, SBSection, GetSectionType, ());
320   LLDB_REGISTER_METHOD_CONST(uint32_t, SBSection, GetPermissions, ());
321   LLDB_REGISTER_METHOD(uint32_t, SBSection, GetTargetByteSize, ());
322   LLDB_REGISTER_METHOD(bool, SBSection, operator==,(const lldb::SBSection &));
323   LLDB_REGISTER_METHOD(bool, SBSection, operator!=,(const lldb::SBSection &));
324   LLDB_REGISTER_METHOD(bool, SBSection, GetDescription, (lldb::SBStream &));
325 }
326 
327 }
328 }
329