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