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 liblldb_Section_h_
10#define liblldb_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 <stddef.h>
25#include <stdint.h>
26
27namespace lldb_private {
28class Address;
29class DataExtractor;
30class ObjectFile;
31class Section;
32class Stream;
33class Target;
34
35class SectionList {
36public:
37  typedef std::vector<lldb::SectionSP> collection;
38  typedef collection::iterator iterator;
39  typedef collection::const_iterator const_iterator;
40
41  const_iterator begin() const { return m_sections.begin(); }
42  const_iterator end() const { return m_sections.end(); }
43  const_iterator begin() { return m_sections.begin(); }
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(Stream *s, Target *target, 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
92protected:
93  collection m_sections;
94};
95
96class Section : public std::enable_shared_from_this<Section>,
97                public ModuleChild,
98                public UserID,
99                public Flags {
100public:
101  // Create a root section (one that has no parent)
102  Section(const lldb::ModuleSP &module_sp, ObjectFile *obj_file,
103          lldb::user_id_t sect_id, ConstString name,
104          lldb::SectionType sect_type, lldb::addr_t file_vm_addr,
105          lldb::addr_t vm_size, lldb::offset_t file_offset,
106          lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
107          uint32_t target_byte_size = 1);
108
109  // Create a section that is a child of parent_section_sp
110  Section(const lldb::SectionSP &parent_section_sp, // NULL for top level
111                                                    // sections, non-NULL for
112                                                    // child sections
113          const lldb::ModuleSP &module_sp, ObjectFile *obj_file,
114          lldb::user_id_t sect_id, ConstString name,
115          lldb::SectionType sect_type, lldb::addr_t file_vm_addr,
116          lldb::addr_t vm_size, lldb::offset_t file_offset,
117          lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
118          uint32_t target_byte_size = 1);
119
120  ~Section();
121
122  static int Compare(const Section &a, const Section &b);
123
124  bool ContainsFileAddress(lldb::addr_t vm_addr) const;
125
126  SectionList &GetChildren() { return m_children; }
127
128  const SectionList &GetChildren() const { return m_children; }
129
130  void Dump(Stream *s, Target *target, uint32_t depth) const;
131
132  void DumpName(Stream *s) const;
133
134  lldb::addr_t GetLoadBaseAddress(Target *target) const;
135
136  bool ResolveContainedAddress(lldb::addr_t offset, Address &so_addr,
137                               bool allow_section_end = false) const;
138
139  lldb::offset_t GetFileOffset() const { return m_file_offset; }
140
141  void SetFileOffset(lldb::offset_t file_offset) {
142    m_file_offset = file_offset;
143  }
144
145  lldb::offset_t GetFileSize() const { return m_file_size; }
146
147  void SetFileSize(lldb::offset_t file_size) { m_file_size = file_size; }
148
149  lldb::addr_t GetFileAddress() const;
150
151  bool SetFileAddress(lldb::addr_t file_addr);
152
153  lldb::addr_t GetOffset() const;
154
155  lldb::addr_t GetByteSize() const { return m_byte_size; }
156
157  void SetByteSize(lldb::addr_t byte_size) { m_byte_size = byte_size; }
158
159  bool IsFake() const { return m_fake; }
160
161  void SetIsFake(bool fake) { m_fake = fake; }
162
163  bool IsEncrypted() const { return m_encrypted; }
164
165  void SetIsEncrypted(bool b) { m_encrypted = b; }
166
167  bool IsDescendant(const Section *section);
168
169  ConstString GetName() const { return m_name; }
170
171  bool Slide(lldb::addr_t slide_amount, bool slide_children);
172
173  lldb::SectionType GetType() const { return m_type; }
174
175  const char *GetTypeAsCString() const;
176
177  lldb::SectionSP GetParent() const { return m_parent_wp.lock(); }
178
179  bool IsThreadSpecific() const { return m_thread_specific; }
180
181  void SetIsThreadSpecific(bool b) { m_thread_specific = b; }
182
183  /// Get the permissions as OR'ed bits from lldb::Permissions
184  uint32_t GetPermissions() const;
185
186  /// Set the permissions using bits OR'ed from lldb::Permissions
187  void SetPermissions(uint32_t permissions);
188
189  ObjectFile *GetObjectFile() { return m_obj_file; }
190  const ObjectFile *GetObjectFile() const { return m_obj_file; }
191
192  /// Read the section data from the object file that the section
193  /// resides in.
194  ///
195  /// \param[in] dst
196  ///     Where to place the data
197  ///
198  /// \param[in] dst_len
199  ///     How many bytes of section data to read
200  ///
201  /// \param[in] offset
202  ///     The offset in bytes within this section's data at which to
203  ///     start copying data from.
204  ///
205  /// \return
206  ///     The number of bytes read from the section, or zero if the
207  ///     section has no data or \a offset is not a valid offset
208  ///     in this section.
209  lldb::offset_t GetSectionData(void *dst, lldb::offset_t dst_len,
210                                lldb::offset_t offset = 0);
211
212  /// Get the shared reference to the section data from the object
213  /// file that the section resides in. No copies of the data will be
214  /// make unless the object file has been read from memory. If the
215  /// object file is on disk, it will shared the mmap data for the
216  /// entire object file.
217  ///
218  /// \param[in] data
219  ///     Where to place the data, address byte size, and byte order
220  ///
221  /// \return
222  ///     The number of bytes read from the section, or zero if the
223  ///     section has no data or \a offset is not a valid offset
224  ///     in this section.
225  lldb::offset_t GetSectionData(DataExtractor &data);
226
227  uint32_t GetLog2Align() { return m_log2align; }
228
229  void SetLog2Align(uint32_t align) { m_log2align = align; }
230
231  // Get the number of host bytes required to hold a target byte
232  uint32_t GetTargetByteSize() const { return m_target_byte_size; }
233
234  bool IsRelocated() const { return m_relocated; }
235
236  void SetIsRelocated(bool b) { m_relocated = b; }
237
238protected:
239  ObjectFile *m_obj_file;   // The object file that data for this section should
240                            // be read from
241  lldb::SectionType m_type; // The type of this section
242  lldb::SectionWP m_parent_wp; // Weak pointer to parent section
243  ConstString m_name;          // Name of this section
244  lldb::addr_t m_file_addr; // The absolute file virtual address range of this
245                            // section if m_parent == NULL,
246  // offset from parent file virtual address if m_parent != NULL
247  lldb::addr_t m_byte_size; // Size in bytes that this section will occupy in
248                            // memory at runtime
249  lldb::offset_t m_file_offset; // Object file offset (if any)
250  lldb::offset_t m_file_size;   // Object file size (can be smaller than
251                                // m_byte_size for zero filled sections...)
252  uint32_t m_log2align;   // log_2(align) of the section (i.e. section has to be
253                          // aligned to 2^m_log2align)
254  SectionList m_children; // Child sections
255  bool m_fake : 1, // If true, then this section only can contain the address if
256                   // one of its
257      // children contains an address. This allows for gaps between the
258      // children that are contained in the address range for this section, but
259      // do not produce hits unless the children contain the address.
260      m_encrypted : 1,         // Set to true if the contents are encrypted
261      m_thread_specific : 1,   // This section is thread specific
262      m_readable : 1,          // If this section has read permissions
263      m_writable : 1,          // If this section has write permissions
264      m_executable : 1,        // If this section has executable permissions
265      m_relocated : 1;         // If this section has had relocations applied
266  uint32_t m_target_byte_size; // Some architectures have non-8-bit byte size.
267                               // This is specified as
268                               // as a multiple number of a host bytes
269private:
270  DISALLOW_COPY_AND_ASSIGN(Section);
271};
272
273} // namespace lldb_private
274
275#endif // liblldb_Section_h_
276