180814287SRaphael Isemann //===-- SBSection.cpp -----------------------------------------------------===//
2cac9c5f9SGreg Clayton //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cac9c5f9SGreg Clayton //
7cac9c5f9SGreg Clayton //===----------------------------------------------------------------------===//
8cac9c5f9SGreg Clayton 
9cac9c5f9SGreg Clayton #include "lldb/API/SBSection.h"
10*d51402acSJonas Devlieghere #include "lldb/Utility/ReproducerInstrumentation.h"
11cac9c5f9SGreg Clayton #include "lldb/API/SBStream.h"
12fed39aa6SGreg Clayton #include "lldb/API/SBTarget.h"
13cac9c5f9SGreg Clayton #include "lldb/Core/Module.h"
14d9dc52dcSGreg Clayton #include "lldb/Core/Section.h"
151f746071SGreg Clayton #include "lldb/Symbol/ObjectFile.h"
16666cc0b2SZachary Turner #include "lldb/Utility/DataBuffer.h"
17666cc0b2SZachary Turner #include "lldb/Utility/DataExtractor.h"
18bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
19cac9c5f9SGreg Clayton 
20cac9c5f9SGreg Clayton using namespace lldb;
21cac9c5f9SGreg Clayton using namespace lldb_private;
22cac9c5f9SGreg Clayton 
23a3436f73SKazu Hirata SBSection::SBSection() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBSection); }
24cac9c5f9SGreg Clayton 
25baf5664fSJonas Devlieghere SBSection::SBSection(const SBSection &rhs) : m_opaque_wp(rhs.m_opaque_wp) {
26baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBSection, (const lldb::SBSection &), rhs);
27baf5664fSJonas Devlieghere }
28cac9c5f9SGreg Clayton 
29a3436f73SKazu Hirata SBSection::SBSection(const lldb::SectionSP &section_sp) {
30a3436f73SKazu Hirata   // Don't init with section_sp otherwise this will throw if
31b9c1b51eSKate Stone   // section_sp doesn't contain a valid Section *
32e72dfb32SGreg Clayton   if (section_sp)
33e72dfb32SGreg Clayton     m_opaque_wp = section_sp;
34cac9c5f9SGreg Clayton }
35cac9c5f9SGreg Clayton 
36b9c1b51eSKate Stone const SBSection &SBSection::operator=(const SBSection &rhs) {
37baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(const lldb::SBSection &,
38baf5664fSJonas Devlieghere                      SBSection, operator=,(const lldb::SBSection &), rhs);
39baf5664fSJonas Devlieghere 
40e72dfb32SGreg Clayton   m_opaque_wp = rhs.m_opaque_wp;
41306809f2SJonas Devlieghere   return LLDB_RECORD_RESULT(*this);
42cac9c5f9SGreg Clayton }
43cac9c5f9SGreg Clayton 
44866b7a65SJonas Devlieghere SBSection::~SBSection() = default;
45cac9c5f9SGreg Clayton 
46b9c1b51eSKate Stone bool SBSection::IsValid() const {
47baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBSection, IsValid);
487f5237bcSPavel Labath   return this->operator bool();
497f5237bcSPavel Labath }
507f5237bcSPavel Labath SBSection::operator bool() const {
517f5237bcSPavel Labath   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBSection, operator bool);
52baf5664fSJonas Devlieghere 
53e72dfb32SGreg Clayton   SectionSP section_sp(GetSP());
54248a1305SKonrad Kleine   return section_sp && section_sp->GetModule().get() != nullptr;
55cac9c5f9SGreg Clayton }
56cac9c5f9SGreg Clayton 
57b9c1b51eSKate Stone const char *SBSection::GetName() {
58baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBSection, GetName);
59baf5664fSJonas Devlieghere 
60e72dfb32SGreg Clayton   SectionSP section_sp(GetSP());
61e72dfb32SGreg Clayton   if (section_sp)
62e72dfb32SGreg Clayton     return section_sp->GetName().GetCString();
63248a1305SKonrad Kleine   return nullptr;
64f644ddf4SGreg Clayton }
65f644ddf4SGreg Clayton 
66b9c1b51eSKate Stone lldb::SBSection SBSection::GetParent() {
67baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBSection, SBSection, GetParent);
68baf5664fSJonas Devlieghere 
691d4c5406SGreg Clayton   lldb::SBSection sb_section;
701d4c5406SGreg Clayton   SectionSP section_sp(GetSP());
71b9c1b51eSKate Stone   if (section_sp) {
721d4c5406SGreg Clayton     SectionSP parent_section_sp(section_sp->GetParent());
731d4c5406SGreg Clayton     if (parent_section_sp)
741d4c5406SGreg Clayton       sb_section.SetSP(parent_section_sp);
751d4c5406SGreg Clayton   }
76baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_section);
771d4c5406SGreg Clayton }
781d4c5406SGreg Clayton 
79b9c1b51eSKate Stone lldb::SBSection SBSection::FindSubSection(const char *sect_name) {
80baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBSection, SBSection, FindSubSection, (const char *),
81baf5664fSJonas Devlieghere                      sect_name);
82baf5664fSJonas Devlieghere 
83cac9c5f9SGreg Clayton   lldb::SBSection sb_section;
84b9c1b51eSKate Stone   if (sect_name) {
85e72dfb32SGreg Clayton     SectionSP section_sp(GetSP());
86b9c1b51eSKate Stone     if (section_sp) {
87cac9c5f9SGreg Clayton       ConstString const_sect_name(sect_name);
88b9c1b51eSKate Stone       sb_section.SetSP(
89b9c1b51eSKate Stone           section_sp->GetChildren().FindSectionByName(const_sect_name));
90e72dfb32SGreg Clayton     }
91cac9c5f9SGreg Clayton   }
92baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_section);
93cac9c5f9SGreg Clayton }
94cac9c5f9SGreg Clayton 
95b9c1b51eSKate Stone size_t SBSection::GetNumSubSections() {
96baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(size_t, SBSection, GetNumSubSections);
97baf5664fSJonas Devlieghere 
98e72dfb32SGreg Clayton   SectionSP section_sp(GetSP());
99e72dfb32SGreg Clayton   if (section_sp)
100e72dfb32SGreg Clayton     return section_sp->GetChildren().GetSize();
101cac9c5f9SGreg Clayton   return 0;
102cac9c5f9SGreg Clayton }
103cac9c5f9SGreg Clayton 
104b9c1b51eSKate Stone lldb::SBSection SBSection::GetSubSectionAtIndex(size_t idx) {
105baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBSection, SBSection, GetSubSectionAtIndex, (size_t),
106baf5664fSJonas Devlieghere                      idx);
107baf5664fSJonas Devlieghere 
108cac9c5f9SGreg Clayton   lldb::SBSection sb_section;
109e72dfb32SGreg Clayton   SectionSP section_sp(GetSP());
110e72dfb32SGreg Clayton   if (section_sp)
111e72dfb32SGreg Clayton     sb_section.SetSP(section_sp->GetChildren().GetSectionAtIndex(idx));
112baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_section);
113cac9c5f9SGreg Clayton }
114cac9c5f9SGreg Clayton 
115b9c1b51eSKate Stone lldb::SectionSP SBSection::GetSP() const { return m_opaque_wp.lock(); }
116cac9c5f9SGreg Clayton 
117b9c1b51eSKate Stone void SBSection::SetSP(const lldb::SectionSP &section_sp) {
118e72dfb32SGreg Clayton   m_opaque_wp = section_sp;
119cac9c5f9SGreg Clayton }
120cac9c5f9SGreg Clayton 
121b9c1b51eSKate Stone lldb::addr_t SBSection::GetFileAddress() {
122baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBSection, GetFileAddress);
123baf5664fSJonas Devlieghere 
124cac9c5f9SGreg Clayton   lldb::addr_t file_addr = LLDB_INVALID_ADDRESS;
125e72dfb32SGreg Clayton   SectionSP section_sp(GetSP());
126e72dfb32SGreg Clayton   if (section_sp)
127e72dfb32SGreg Clayton     return section_sp->GetFileAddress();
128cac9c5f9SGreg Clayton   return file_addr;
129cac9c5f9SGreg Clayton }
130cac9c5f9SGreg Clayton 
131b9c1b51eSKate Stone lldb::addr_t SBSection::GetLoadAddress(lldb::SBTarget &sb_target) {
132baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::addr_t, SBSection, GetLoadAddress,
133baf5664fSJonas Devlieghere                      (lldb::SBTarget &), sb_target);
134baf5664fSJonas Devlieghere 
135fed39aa6SGreg Clayton   TargetSP target_sp(sb_target.GetSP());
136b9c1b51eSKate Stone   if (target_sp) {
137fed39aa6SGreg Clayton     SectionSP section_sp(GetSP());
138fed39aa6SGreg Clayton     if (section_sp)
139fed39aa6SGreg Clayton       return section_sp->GetLoadBaseAddress(target_sp.get());
140fed39aa6SGreg Clayton   }
141fed39aa6SGreg Clayton   return LLDB_INVALID_ADDRESS;
142fed39aa6SGreg Clayton }
143fed39aa6SGreg Clayton 
144b9c1b51eSKate Stone lldb::addr_t SBSection::GetByteSize() {
145baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBSection, GetByteSize);
146baf5664fSJonas Devlieghere 
147e72dfb32SGreg Clayton   SectionSP section_sp(GetSP());
148e72dfb32SGreg Clayton   if (section_sp)
149e72dfb32SGreg Clayton     return section_sp->GetByteSize();
150cac9c5f9SGreg Clayton   return 0;
151cac9c5f9SGreg Clayton }
152cac9c5f9SGreg Clayton 
153b9c1b51eSKate Stone uint64_t SBSection::GetFileOffset() {
154baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint64_t, SBSection, GetFileOffset);
155baf5664fSJonas Devlieghere 
156e72dfb32SGreg Clayton   SectionSP section_sp(GetSP());
157b9c1b51eSKate Stone   if (section_sp) {
158e72dfb32SGreg Clayton     ModuleSP module_sp(section_sp->GetModule());
159b9c1b51eSKate Stone     if (module_sp) {
160e72dfb32SGreg Clayton       ObjectFile *objfile = module_sp->GetObjectFile();
161cac9c5f9SGreg Clayton       if (objfile)
1625ce9c565SGreg Clayton         return objfile->GetFileOffset() + section_sp->GetFileOffset();
163cac9c5f9SGreg Clayton     }
164cac9c5f9SGreg Clayton   }
165e72dfb32SGreg Clayton   return UINT64_MAX;
166cac9c5f9SGreg Clayton }
167cac9c5f9SGreg Clayton 
168b9c1b51eSKate Stone uint64_t SBSection::GetFileByteSize() {
169baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint64_t, SBSection, GetFileByteSize);
170baf5664fSJonas Devlieghere 
171e72dfb32SGreg Clayton   SectionSP section_sp(GetSP());
172e72dfb32SGreg Clayton   if (section_sp)
173e72dfb32SGreg Clayton     return section_sp->GetFileSize();
174cac9c5f9SGreg Clayton   return 0;
175cac9c5f9SGreg Clayton }
176cac9c5f9SGreg Clayton 
177baf5664fSJonas Devlieghere SBData SBSection::GetSectionData() {
178baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBData, SBSection, GetSectionData);
179baf5664fSJonas Devlieghere 
180baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(GetSectionData(0, UINT64_MAX));
181baf5664fSJonas Devlieghere }
182d9dc52dcSGreg Clayton 
183b9c1b51eSKate Stone SBData SBSection::GetSectionData(uint64_t offset, uint64_t size) {
184baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBData, SBSection, GetSectionData,
185baf5664fSJonas Devlieghere                      (uint64_t, uint64_t), offset, size);
186baf5664fSJonas Devlieghere 
187cac9c5f9SGreg Clayton   SBData sb_data;
188e72dfb32SGreg Clayton   SectionSP section_sp(GetSP());
189b9c1b51eSKate Stone   if (section_sp) {
190e72dfb32SGreg Clayton     const uint64_t sect_file_size = section_sp->GetFileSize();
191b9c1b51eSKate Stone     if (sect_file_size > 0) {
192e72dfb32SGreg Clayton       ModuleSP module_sp(section_sp->GetModule());
193b9c1b51eSKate Stone       if (module_sp) {
194e72dfb32SGreg Clayton         ObjectFile *objfile = module_sp->GetObjectFile();
195b9c1b51eSKate Stone         if (objfile) {
196b9c1b51eSKate Stone           const uint64_t sect_file_offset =
197b9c1b51eSKate Stone               objfile->GetFileOffset() + section_sp->GetFileOffset();
198cac9c5f9SGreg Clayton           const uint64_t file_offset = sect_file_offset + offset;
199cac9c5f9SGreg Clayton           uint64_t file_size = size;
200b9c1b51eSKate Stone           if (file_size == UINT64_MAX) {
201e72dfb32SGreg Clayton             file_size = section_sp->GetByteSize();
202cac9c5f9SGreg Clayton             if (file_size > offset)
203cac9c5f9SGreg Clayton               file_size -= offset;
204cac9c5f9SGreg Clayton             else
205cac9c5f9SGreg Clayton               file_size = 0;
206cac9c5f9SGreg Clayton           }
20787e403aaSJonas Devlieghere           auto data_buffer_sp = FileSystem::Instance().CreateDataBuffer(
2087f6a7a37SZachary Turner               objfile->GetFileSpec().GetPath(), file_size, file_offset);
209b9c1b51eSKate Stone           if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0) {
210b9c1b51eSKate Stone             DataExtractorSP data_extractor_sp(
211b9c1b51eSKate Stone                 new DataExtractor(data_buffer_sp, objfile->GetByteOrder(),
212cac9c5f9SGreg Clayton                                   objfile->GetAddressByteSize()));
213cac9c5f9SGreg Clayton 
214cac9c5f9SGreg Clayton             sb_data.SetOpaque(data_extractor_sp);
215cac9c5f9SGreg Clayton           }
216cac9c5f9SGreg Clayton         }
217cac9c5f9SGreg Clayton       }
218cac9c5f9SGreg Clayton     }
219cac9c5f9SGreg Clayton   }
220baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_data);
221cac9c5f9SGreg Clayton }
222cac9c5f9SGreg Clayton 
223b9c1b51eSKate Stone SectionType SBSection::GetSectionType() {
224baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SectionType, SBSection, GetSectionType);
225baf5664fSJonas Devlieghere 
226e72dfb32SGreg Clayton   SectionSP section_sp(GetSP());
227e72dfb32SGreg Clayton   if (section_sp.get())
228e72dfb32SGreg Clayton     return section_sp->GetType();
229cac9c5f9SGreg Clayton   return eSectionTypeInvalid;
230cac9c5f9SGreg Clayton }
231cac9c5f9SGreg Clayton 
232baf5664fSJonas Devlieghere uint32_t SBSection::GetPermissions() const {
233baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBSection, GetPermissions);
234baf5664fSJonas Devlieghere 
2353c7f0709SAbhishek Aggarwal   SectionSP section_sp(GetSP());
2363c7f0709SAbhishek Aggarwal   if (section_sp)
2373c7f0709SAbhishek Aggarwal     return section_sp->GetPermissions();
2383c7f0709SAbhishek Aggarwal   return 0;
2393c7f0709SAbhishek Aggarwal }
2403c7f0709SAbhishek Aggarwal 
241b9c1b51eSKate Stone uint32_t SBSection::GetTargetByteSize() {
242baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBSection, GetTargetByteSize);
243baf5664fSJonas Devlieghere 
244c928de3eSMatthew Gardiner   SectionSP section_sp(GetSP());
245c928de3eSMatthew Gardiner   if (section_sp.get())
246c928de3eSMatthew Gardiner     return section_sp->GetTargetByteSize();
247c928de3eSMatthew Gardiner   return 0;
248c928de3eSMatthew Gardiner }
249cac9c5f9SGreg Clayton 
250b9c1b51eSKate Stone bool SBSection::operator==(const SBSection &rhs) {
251baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBSection, operator==,(const lldb::SBSection &),
252baf5664fSJonas Devlieghere                      rhs);
253baf5664fSJonas Devlieghere 
254e72dfb32SGreg Clayton   SectionSP lhs_section_sp(GetSP());
255e72dfb32SGreg Clayton   SectionSP rhs_section_sp(rhs.GetSP());
256e72dfb32SGreg Clayton   if (lhs_section_sp && rhs_section_sp)
257e72dfb32SGreg Clayton     return lhs_section_sp == rhs_section_sp;
258cac9c5f9SGreg Clayton   return false;
259cac9c5f9SGreg Clayton }
260cac9c5f9SGreg Clayton 
261b9c1b51eSKate Stone bool SBSection::operator!=(const SBSection &rhs) {
262baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBSection, operator!=,(const lldb::SBSection &),
263baf5664fSJonas Devlieghere                      rhs);
264baf5664fSJonas Devlieghere 
265e72dfb32SGreg Clayton   SectionSP lhs_section_sp(GetSP());
266e72dfb32SGreg Clayton   SectionSP rhs_section_sp(rhs.GetSP());
267e72dfb32SGreg Clayton   return lhs_section_sp != rhs_section_sp;
268cac9c5f9SGreg Clayton }
269cac9c5f9SGreg Clayton 
270b9c1b51eSKate Stone bool SBSection::GetDescription(SBStream &description) {
271baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBSection, GetDescription, (lldb::SBStream &),
272baf5664fSJonas Devlieghere                      description);
273baf5664fSJonas Devlieghere 
274da7bc7d0SGreg Clayton   Stream &strm = description.ref();
275da7bc7d0SGreg Clayton 
276e72dfb32SGreg Clayton   SectionSP section_sp(GetSP());
277b9c1b51eSKate Stone   if (section_sp) {
278e72dfb32SGreg Clayton     const addr_t file_addr = section_sp->GetFileAddress();
279b9c1b51eSKate Stone     strm.Printf("[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") ", file_addr,
280b9c1b51eSKate Stone                 file_addr + section_sp->GetByteSize());
2813a168297SPavel Labath     section_sp->DumpName(strm.AsRawOstream());
282b9c1b51eSKate Stone   } else {
283da7bc7d0SGreg Clayton     strm.PutCString("No value");
284cac9c5f9SGreg Clayton   }
285cac9c5f9SGreg Clayton 
286cac9c5f9SGreg Clayton   return true;
287cac9c5f9SGreg Clayton }
288