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