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 §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 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 §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 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 §ion, 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