/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Core/Section.h
Line | Count | Source (jump to first uncovered line) |
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 | | |
41 | 15.8k | const_iterator begin() const { return m_sections.begin(); } |
42 | 15.8k | const_iterator end() const { return m_sections.end(); } |
43 | 0 | const_iterator begin() { return m_sections.begin(); } |
44 | 0 | const_iterator end() { return m_sections.end(); } |
45 | | |
46 | | /// Create an empty list. |
47 | 2.34M | SectionList() = default; |
48 | | |
49 | | SectionList &operator=(const SectionList &rhs); |
50 | | |
51 | | size_t AddSection(const lldb::SectionSP §ion_sp); |
52 | | |
53 | | size_t AddUniqueSection(const lldb::SectionSP §ion_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 |
75 | 2.15M | 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 §ion_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 | | |
91 | 0 | 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::string name; |
105 | | std::optional<lldb::SectionType> type; |
106 | | std::optional<uint64_t> address; |
107 | | std::optional<uint64_t> size; |
108 | | }; |
109 | | |
110 | | class Section : public std::enable_shared_from_this<Section>, |
111 | | public ModuleChild, |
112 | | public UserID, |
113 | | public Flags { |
114 | | public: |
115 | | // Create a root section (one that has no parent) |
116 | | Section(const lldb::ModuleSP &module_sp, ObjectFile *obj_file, |
117 | | lldb::user_id_t sect_id, ConstString name, |
118 | | lldb::SectionType sect_type, lldb::addr_t file_vm_addr, |
119 | | lldb::addr_t vm_size, lldb::offset_t file_offset, |
120 | | lldb::offset_t file_size, uint32_t log2align, uint32_t flags, |
121 | | uint32_t target_byte_size = 1); |
122 | | |
123 | | // Create a section that is a child of parent_section_sp |
124 | | Section(const lldb::SectionSP &parent_section_sp, // NULL for top level |
125 | | // sections, non-NULL for |
126 | | // child sections |
127 | | const lldb::ModuleSP &module_sp, ObjectFile *obj_file, |
128 | | lldb::user_id_t sect_id, ConstString name, |
129 | | lldb::SectionType sect_type, lldb::addr_t file_vm_addr, |
130 | | lldb::addr_t vm_size, lldb::offset_t file_offset, |
131 | | lldb::offset_t file_size, uint32_t log2align, uint32_t flags, |
132 | | uint32_t target_byte_size = 1); |
133 | | |
134 | | ~Section(); |
135 | | |
136 | | static int Compare(const Section &a, const Section &b); |
137 | | |
138 | | bool ContainsFileAddress(lldb::addr_t vm_addr) const; |
139 | | |
140 | 81.4M | SectionList &GetChildren() { return m_children; } |
141 | | |
142 | 2.55k | const SectionList &GetChildren() const { return m_children; } |
143 | | |
144 | | void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, |
145 | | uint32_t depth) const; |
146 | | |
147 | | void DumpName(llvm::raw_ostream &s) const; |
148 | | |
149 | | lldb::addr_t GetLoadBaseAddress(Target *target) const; |
150 | | |
151 | | bool ResolveContainedAddress(lldb::addr_t offset, Address &so_addr, |
152 | | bool allow_section_end = false) const; |
153 | | |
154 | 413k | lldb::offset_t GetFileOffset() const { return m_file_offset; } |
155 | | |
156 | 11.2k | void SetFileOffset(lldb::offset_t file_offset) { |
157 | 11.2k | m_file_offset = file_offset; |
158 | 11.2k | } |
159 | | |
160 | 447k | lldb::offset_t GetFileSize() const { return m_file_size; } |
161 | | |
162 | 11.2k | void SetFileSize(lldb::offset_t file_size) { m_file_size = file_size; } |
163 | | |
164 | | lldb::addr_t GetFileAddress() const; |
165 | | |
166 | | bool SetFileAddress(lldb::addr_t file_addr); |
167 | | |
168 | | lldb::addr_t GetOffset() const; |
169 | | |
170 | 167M | lldb::addr_t GetByteSize() const { return m_byte_size; } |
171 | | |
172 | 11.2k | void SetByteSize(lldb::addr_t byte_size) { m_byte_size = byte_size; } |
173 | | |
174 | 23.4M | bool IsFake() const { return m_fake; } |
175 | | |
176 | 3.91k | void SetIsFake(bool fake) { m_fake = fake; } |
177 | | |
178 | 254k | bool IsEncrypted() const { return m_encrypted; } |
179 | | |
180 | 1.98M | void SetIsEncrypted(bool b) { m_encrypted = b; } |
181 | | |
182 | | bool IsDescendant(const Section *section); |
183 | | |
184 | 54.1M | ConstString GetName() const { return m_name; } |
185 | | |
186 | | bool Slide(lldb::addr_t slide_amount, bool slide_children); |
187 | | |
188 | 116M | lldb::SectionType GetType() const { return m_type; } |
189 | | |
190 | | const char *GetTypeAsCString() const; |
191 | | |
192 | 1.28G | lldb::SectionSP GetParent() const { return m_parent_wp.lock(); } |
193 | | |
194 | 78.6M | bool IsThreadSpecific() const { return m_thread_specific; } |
195 | | |
196 | 72.2k | void SetIsThreadSpecific(bool b) { m_thread_specific = b; } |
197 | | |
198 | | /// Get the permissions as OR'ed bits from lldb::Permissions |
199 | | uint32_t GetPermissions() const; |
200 | | |
201 | | /// Set the permissions using bits OR'ed from lldb::Permissions |
202 | | void SetPermissions(uint32_t permissions); |
203 | | |
204 | 272k | ObjectFile *GetObjectFile() { return m_obj_file; } |
205 | 0 | const ObjectFile *GetObjectFile() const { return m_obj_file; } |
206 | | |
207 | | /// Read the section data from the object file that the section |
208 | | /// resides in. |
209 | | /// |
210 | | /// \param[in] dst |
211 | | /// Where to place the data |
212 | | /// |
213 | | /// \param[in] dst_len |
214 | | /// How many bytes of section data to read |
215 | | /// |
216 | | /// \param[in] offset |
217 | | /// The offset in bytes within this section's data at which to |
218 | | /// start copying data from. |
219 | | /// |
220 | | /// \return |
221 | | /// The number of bytes read from the section, or zero if the |
222 | | /// section has no data or \a offset is not a valid offset |
223 | | /// in this section. |
224 | | lldb::offset_t GetSectionData(void *dst, lldb::offset_t dst_len, |
225 | | lldb::offset_t offset = 0); |
226 | | |
227 | | /// Get the shared reference to the section data from the object |
228 | | /// file that the section resides in. No copies of the data will be |
229 | | /// make unless the object file has been read from memory. If the |
230 | | /// object file is on disk, it will shared the mmap data for the |
231 | | /// entire object file. |
232 | | /// |
233 | | /// \param[in] data |
234 | | /// Where to place the data, address byte size, and byte order |
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(DataExtractor &data); |
241 | | |
242 | 2 | uint32_t GetLog2Align() { return m_log2align; } |
243 | | |
244 | 0 | void SetLog2Align(uint32_t align) { m_log2align = align; } |
245 | | |
246 | | // Get the number of host bytes required to hold a target byte |
247 | 236k | uint32_t GetTargetByteSize() const { return m_target_byte_size; } |
248 | | |
249 | 269k | bool IsRelocated() const { return m_relocated; } |
250 | | |
251 | 1.64k | void SetIsRelocated(bool b) { m_relocated = b; } |
252 | | |
253 | | /// Returns true if this section contains debug information. Symbol tables |
254 | | /// are not considered debug information since some symbols might contain |
255 | | /// debug information (STABS, COFF) but not all symbols do, so to keep this |
256 | | /// fast and simple only sections that contains only debug information should |
257 | | /// return true. |
258 | | bool ContainsOnlyDebugInfo() const; |
259 | | |
260 | | protected: |
261 | | ObjectFile *m_obj_file; // The object file that data for this section should |
262 | | // be read from |
263 | | lldb::SectionType m_type; // The type of this section |
264 | | lldb::SectionWP m_parent_wp; // Weak pointer to parent section |
265 | | ConstString m_name; // Name of this section |
266 | | lldb::addr_t m_file_addr; // The absolute file virtual address range of this |
267 | | // section if m_parent == NULL, |
268 | | // offset from parent file virtual address if m_parent != NULL |
269 | | lldb::addr_t m_byte_size; // Size in bytes that this section will occupy in |
270 | | // memory at runtime |
271 | | lldb::offset_t m_file_offset; // Object file offset (if any) |
272 | | lldb::offset_t m_file_size; // Object file size (can be smaller than |
273 | | // m_byte_size for zero filled sections...) |
274 | | uint32_t m_log2align; // log_2(align) of the section (i.e. section has to be |
275 | | // aligned to 2^m_log2align) |
276 | | SectionList m_children; // Child sections |
277 | | bool m_fake : 1, // If true, then this section only can contain the address if |
278 | | // one of its |
279 | | // children contains an address. This allows for gaps between the |
280 | | // children that are contained in the address range for this section, but |
281 | | // do not produce hits unless the children contain the address. |
282 | | m_encrypted : 1, // Set to true if the contents are encrypted |
283 | | m_thread_specific : 1, // This section is thread specific |
284 | | m_readable : 1, // If this section has read permissions |
285 | | m_writable : 1, // If this section has write permissions |
286 | | m_executable : 1, // If this section has executable permissions |
287 | | m_relocated : 1; // If this section has had relocations applied |
288 | | uint32_t m_target_byte_size; // Some architectures have non-8-bit byte size. |
289 | | // This is specified as |
290 | | // as a multiple number of a host bytes |
291 | | private: |
292 | | Section(const Section &) = delete; |
293 | | const Section &operator=(const Section &) = delete; |
294 | | }; |
295 | | |
296 | | } // namespace lldb_private |
297 | | |
298 | | namespace llvm { |
299 | | namespace json { |
300 | | |
301 | | bool fromJSON(const llvm::json::Value &value, |
302 | | lldb_private::JSONSection §ion, llvm::json::Path path); |
303 | | |
304 | | bool fromJSON(const llvm::json::Value &value, lldb::SectionType &type, |
305 | | llvm::json::Path path); |
306 | | |
307 | | } // namespace json |
308 | | } // namespace llvm |
309 | | |
310 | | #endif // LLDB_CORE_SECTION_H |