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