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     DataExtractor section_data;
186     section_sp->GetSectionData(section_data);
187     sb_data.SetOpaque(
188         std::make_shared<DataExtractor>(section_data, offset, size));
189   }
190   return sb_data;
191 }
192 
193 SectionType SBSection::GetSectionType() {
194   LLDB_INSTRUMENT_VA(this);
195 
196   SectionSP section_sp(GetSP());
197   if (section_sp.get())
198     return section_sp->GetType();
199   return eSectionTypeInvalid;
200 }
201 
202 uint32_t SBSection::GetPermissions() const {
203   LLDB_INSTRUMENT_VA(this);
204 
205   SectionSP section_sp(GetSP());
206   if (section_sp)
207     return section_sp->GetPermissions();
208   return 0;
209 }
210 
211 uint32_t SBSection::GetTargetByteSize() {
212   LLDB_INSTRUMENT_VA(this);
213 
214   SectionSP section_sp(GetSP());
215   if (section_sp.get())
216     return section_sp->GetTargetByteSize();
217   return 0;
218 }
219 
220 uint32_t SBSection::GetAlignment() {
221   LLDB_INSTRUMENT_VA(this);
222 
223   SectionSP section_sp(GetSP());
224   if (section_sp.get())
225     return (1 << section_sp->GetLog2Align());
226   return 0;
227 }
228 
229 bool SBSection::operator==(const SBSection &rhs) {
230   LLDB_INSTRUMENT_VA(this, rhs);
231 
232   SectionSP lhs_section_sp(GetSP());
233   SectionSP rhs_section_sp(rhs.GetSP());
234   if (lhs_section_sp && rhs_section_sp)
235     return lhs_section_sp == rhs_section_sp;
236   return false;
237 }
238 
239 bool SBSection::operator!=(const SBSection &rhs) {
240   LLDB_INSTRUMENT_VA(this, rhs);
241 
242   SectionSP lhs_section_sp(GetSP());
243   SectionSP rhs_section_sp(rhs.GetSP());
244   return lhs_section_sp != rhs_section_sp;
245 }
246 
247 bool SBSection::GetDescription(SBStream &description) {
248   LLDB_INSTRUMENT_VA(this, description);
249 
250   Stream &strm = description.ref();
251 
252   SectionSP section_sp(GetSP());
253   if (section_sp) {
254     const addr_t file_addr = section_sp->GetFileAddress();
255     strm.Printf("[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") ", file_addr,
256                 file_addr + section_sp->GetByteSize());
257     section_sp->DumpName(strm.AsRawOstream());
258   } else {
259     strm.PutCString("No value");
260   }
261 
262   return true;
263 }
264