xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Core/Section.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- Section.h -----------------------------------------------*- C++ -*-===//
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 #ifndef LLDB_CORE_SECTION_H
10 #define LLDB_CORE_SECTION_H
11 
12 #include "lldb/Core/ModuleChild.h"
13 #include "lldb/Utility/ConstString.h"
14 #include "lldb/Utility/Flags.h"
15 #include "lldb/Utility/UserID.h"
16 #include "lldb/lldb-defines.h"
17 #include "lldb/lldb-enumerations.h"
18 #include "lldb/lldb-forward.h"
19 #include "lldb/lldb-types.h"
20 #include "llvm/Support/JSON.h"
21 
22 #include <memory>
23 #include <vector>
24 
25 #include <cstddef>
26 #include <cstdint>
27 
28 namespace lldb_private {
29 class Address;
30 class DataExtractor;
31 class ObjectFile;
32 class Section;
33 class Target;
34 
35 class SectionList {
36 public:
37   typedef std::vector<lldb::SectionSP> collection;
38   typedef collection::iterator iterator;
39   typedef collection::const_iterator const_iterator;
40 
begin()41   const_iterator begin() const { return m_sections.begin(); }
end()42   const_iterator end() const { return m_sections.end(); }
begin()43   const_iterator begin() { return m_sections.begin(); }
end()44   const_iterator end() { return m_sections.end(); }
45 
46   /// Create an empty list.
47   SectionList() = default;
48 
49   SectionList &operator=(const SectionList &rhs);
50 
51   size_t AddSection(const lldb::SectionSP &section_sp);
52 
53   size_t AddUniqueSection(const lldb::SectionSP &section_sp);
54 
55   size_t FindSectionIndex(const Section *sect);
56 
57   bool ContainsSection(lldb::user_id_t sect_id) const;
58 
59   void Dump(llvm::raw_ostream &s, unsigned indent, Target *target,
60             bool show_header, uint32_t depth) const;
61 
62   lldb::SectionSP FindSectionByName(ConstString section_dstr) const;
63 
64   lldb::SectionSP FindSectionByID(lldb::user_id_t sect_id) const;
65 
66   lldb::SectionSP FindSectionByType(lldb::SectionType sect_type,
67                                     bool check_children,
68                                     size_t start_idx = 0) const;
69 
70   lldb::SectionSP
71   FindSectionContainingFileAddress(lldb::addr_t addr,
72                                    uint32_t depth = UINT32_MAX) const;
73 
74   // Get the number of sections in this list only
GetSize()75   size_t GetSize() const { return m_sections.size(); }
76 
77   // Get the number of sections in this list, and any contained child sections
78   size_t GetNumSections(uint32_t depth) const;
79 
80   bool ReplaceSection(lldb::user_id_t sect_id,
81                       const lldb::SectionSP &section_sp,
82                       uint32_t depth = UINT32_MAX);
83 
84   // Warning, this can be slow as it's removing items from a std::vector.
85   bool DeleteSection(size_t idx);
86 
87   lldb::SectionSP GetSectionAtIndex(size_t idx) const;
88 
89   size_t Slide(lldb::addr_t slide_amount, bool slide_children);
90 
Clear()91   void Clear() { m_sections.clear(); }
92 
93   /// Get the debug information size from all sections that contain debug
94   /// information. Symbol tables are not considered part of the debug
95   /// information for this call, just known sections that contain debug
96   /// information.
97   uint64_t GetDebugInfoSize() const;
98 
99 protected:
100   collection m_sections;
101 };
102 
103 struct JSONSection {
104   std::optional<lldb::user_id_t> user_id;
105   std::string name;
106   std::optional<lldb::SectionType> type;
107   std::optional<uint64_t> address;
108   std::optional<uint64_t> size;
109   std::optional<uint64_t> file_offset;
110   std::optional<uint64_t> file_size;
111   std::optional<uint64_t> log2align;
112   std::optional<uint64_t> flags;
113 
114   // Section permissions;
115   std::optional<bool> read;
116   std::optional<bool> write;
117   std::optional<bool> execute;
118 
119   std::optional<bool> fake;
120   std::optional<bool> encrypted;
121   std::optional<bool> thread_specific;
122 
123   std::vector<JSONSection> subsections;
124 };
125 
126 class Section : public std::enable_shared_from_this<Section>,
127                 public ModuleChild,
128                 public UserID,
129                 public Flags {
130 public:
131   // Create a root section (one that has no parent)
132   Section(const lldb::ModuleSP &module_sp, ObjectFile *obj_file,
133           lldb::user_id_t sect_id, ConstString name,
134           lldb::SectionType sect_type, lldb::addr_t file_vm_addr,
135           lldb::addr_t vm_size, lldb::offset_t file_offset,
136           lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
137           uint32_t target_byte_size = 1);
138 
139   // Create a section that is a child of parent_section_sp
140   Section(const lldb::SectionSP &parent_section_sp, // NULL for top level
141                                                     // sections, non-NULL for
142                                                     // child sections
143           const lldb::ModuleSP &module_sp, ObjectFile *obj_file,
144           lldb::user_id_t sect_id, ConstString name,
145           lldb::SectionType sect_type, lldb::addr_t file_vm_addr,
146           lldb::addr_t vm_size, lldb::offset_t file_offset,
147           lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
148           uint32_t target_byte_size = 1);
149 
150   ~Section();
151 
152   static int Compare(const Section &a, const Section &b);
153 
154   bool ContainsFileAddress(lldb::addr_t vm_addr) const;
155 
GetChildren()156   SectionList &GetChildren() { return m_children; }
157 
GetChildren()158   const SectionList &GetChildren() const { return m_children; }
159 
160   void Dump(llvm::raw_ostream &s, unsigned indent, Target *target,
161             uint32_t depth) const;
162 
163   void DumpName(llvm::raw_ostream &s) const;
164 
165   lldb::addr_t GetLoadBaseAddress(Target *target) const;
166 
167   bool ResolveContainedAddress(lldb::addr_t offset, Address &so_addr,
168                                bool allow_section_end = false) const;
169 
GetFileOffset()170   lldb::offset_t GetFileOffset() const { return m_file_offset; }
171 
SetFileOffset(lldb::offset_t file_offset)172   void SetFileOffset(lldb::offset_t file_offset) {
173     m_file_offset = file_offset;
174   }
175 
GetFileSize()176   lldb::offset_t GetFileSize() const { return m_file_size; }
177 
SetFileSize(lldb::offset_t file_size)178   void SetFileSize(lldb::offset_t file_size) { m_file_size = file_size; }
179 
180   lldb::addr_t GetFileAddress() const;
181 
182   bool SetFileAddress(lldb::addr_t file_addr);
183 
184   lldb::addr_t GetOffset() const;
185 
GetByteSize()186   lldb::addr_t GetByteSize() const { return m_byte_size; }
187 
SetByteSize(lldb::addr_t byte_size)188   void SetByteSize(lldb::addr_t byte_size) { m_byte_size = byte_size; }
189 
IsFake()190   bool IsFake() const { return m_fake; }
191 
SetIsFake(bool fake)192   void SetIsFake(bool fake) { m_fake = fake; }
193 
IsEncrypted()194   bool IsEncrypted() const { return m_encrypted; }
195 
SetIsEncrypted(bool b)196   void SetIsEncrypted(bool b) { m_encrypted = b; }
197 
198   bool IsDescendant(const Section *section);
199 
GetName()200   ConstString GetName() const { return m_name; }
201 
202   bool Slide(lldb::addr_t slide_amount, bool slide_children);
203 
GetType()204   lldb::SectionType GetType() const { return m_type; }
205 
206   const char *GetTypeAsCString() const;
207 
GetParent()208   lldb::SectionSP GetParent() const { return m_parent_wp.lock(); }
209 
IsThreadSpecific()210   bool IsThreadSpecific() const { return m_thread_specific; }
211 
SetIsThreadSpecific(bool b)212   void SetIsThreadSpecific(bool b) { m_thread_specific = b; }
213 
214   /// Get the permissions as OR'ed bits from lldb::Permissions
215   uint32_t GetPermissions() const;
216 
217   /// Set the permissions using bits OR'ed from lldb::Permissions
218   void SetPermissions(uint32_t permissions);
219 
GetObjectFile()220   ObjectFile *GetObjectFile() { return m_obj_file; }
GetObjectFile()221   const ObjectFile *GetObjectFile() const { return m_obj_file; }
222 
223   /// Read the section data from the object file that the section
224   /// resides in.
225   ///
226   /// \param[in] dst
227   ///     Where to place the data
228   ///
229   /// \param[in] dst_len
230   ///     How many bytes of section data to read
231   ///
232   /// \param[in] offset
233   ///     The offset in bytes within this section's data at which to
234   ///     start copying data from.
235   ///
236   /// \return
237   ///     The number of bytes read from the section, or zero if the
238   ///     section has no data or \a offset is not a valid offset
239   ///     in this section.
240   lldb::offset_t GetSectionData(void *dst, lldb::offset_t dst_len,
241                                 lldb::offset_t offset = 0);
242 
243   /// Get the shared reference to the section data from the object
244   /// file that the section resides in. No copies of the data will be
245   /// make unless the object file has been read from memory. If the
246   /// object file is on disk, it will shared the mmap data for the
247   /// entire object file.
248   ///
249   /// \param[in] data
250   ///     Where to place the data, address byte size, and byte order
251   ///
252   /// \return
253   ///     The number of bytes read from the section, or zero if the
254   ///     section has no data or \a offset is not a valid offset
255   ///     in this section.
256   lldb::offset_t GetSectionData(DataExtractor &data);
257 
GetLog2Align()258   uint32_t GetLog2Align() { return m_log2align; }
259 
SetLog2Align(uint32_t align)260   void SetLog2Align(uint32_t align) { m_log2align = align; }
261 
262   // Get the number of host bytes required to hold a target byte
GetTargetByteSize()263   uint32_t GetTargetByteSize() const { return m_target_byte_size; }
264 
IsRelocated()265   bool IsRelocated() const { return m_relocated; }
266 
SetIsRelocated(bool b)267   void SetIsRelocated(bool b) { m_relocated = b; }
268 
269   /// Returns true if this section contains debug information. Symbol tables
270   /// are not considered debug information since some symbols might contain
271   /// debug information (STABS, COFF) but not all symbols do, so to keep this
272   /// fast and simple only sections that contains only debug information should
273   /// return true.
274   bool ContainsOnlyDebugInfo() const;
275 
276 protected:
277   ObjectFile *m_obj_file;   // The object file that data for this section should
278                             // be read from
279   lldb::SectionType m_type; // The type of this section
280   lldb::SectionWP m_parent_wp; // Weak pointer to parent section
281   ConstString m_name;          // Name of this section
282   lldb::addr_t m_file_addr; // The absolute file virtual address range of this
283                             // section if m_parent == NULL,
284   // offset from parent file virtual address if m_parent != NULL
285   lldb::addr_t m_byte_size; // Size in bytes that this section will occupy in
286                             // memory at runtime
287   lldb::offset_t m_file_offset; // Object file offset (if any)
288   lldb::offset_t m_file_size;   // Object file size (can be smaller than
289                                 // m_byte_size for zero filled sections...)
290   uint32_t m_log2align;   // log_2(align) of the section (i.e. section has to be
291                           // aligned to 2^m_log2align)
292   SectionList m_children; // Child sections
293   bool m_fake : 1, // If true, then this section only can contain the address if
294                    // one of its
295       // children contains an address. This allows for gaps between the
296       // children that are contained in the address range for this section, but
297       // do not produce hits unless the children contain the address.
298       m_encrypted : 1,         // Set to true if the contents are encrypted
299       m_thread_specific : 1,   // This section is thread specific
300       m_readable : 1,          // If this section has read permissions
301       m_writable : 1,          // If this section has write permissions
302       m_executable : 1,        // If this section has executable permissions
303       m_relocated : 1;         // If this section has had relocations applied
304   uint32_t m_target_byte_size; // Some architectures have non-8-bit byte size.
305                                // This is specified as
306                                // as a multiple number of a host bytes
307 private:
308   Section(const Section &) = delete;
309   const Section &operator=(const Section &) = delete;
310 };
311 
312 } // namespace lldb_private
313 
314 namespace llvm {
315 namespace json {
316 
317 bool fromJSON(const llvm::json::Value &value,
318               lldb_private::JSONSection &section, llvm::json::Path path);
319 
320 bool fromJSON(const llvm::json::Value &value, lldb::SectionType &type,
321               llvm::json::Path path);
322 
323 } // namespace json
324 } // namespace llvm
325 
326 #endif // LLDB_CORE_SECTION_H
327