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::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 GetChildren()140 SectionList &GetChildren() { return m_children; } 141 GetChildren()142 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 GetFileOffset()154 lldb::offset_t GetFileOffset() const { return m_file_offset; } 155 SetFileOffset(lldb::offset_t file_offset)156 void SetFileOffset(lldb::offset_t file_offset) { 157 m_file_offset = file_offset; 158 } 159 GetFileSize()160 lldb::offset_t GetFileSize() const { return m_file_size; } 161 SetFileSize(lldb::offset_t file_size)162 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 GetByteSize()170 lldb::addr_t GetByteSize() const { return m_byte_size; } 171 SetByteSize(lldb::addr_t byte_size)172 void SetByteSize(lldb::addr_t byte_size) { m_byte_size = byte_size; } 173 IsFake()174 bool IsFake() const { return m_fake; } 175 SetIsFake(bool fake)176 void SetIsFake(bool fake) { m_fake = fake; } 177 IsEncrypted()178 bool IsEncrypted() const { return m_encrypted; } 179 SetIsEncrypted(bool b)180 void SetIsEncrypted(bool b) { m_encrypted = b; } 181 182 bool IsDescendant(const Section *section); 183 GetName()184 ConstString GetName() const { return m_name; } 185 186 bool Slide(lldb::addr_t slide_amount, bool slide_children); 187 GetType()188 lldb::SectionType GetType() const { return m_type; } 189 190 const char *GetTypeAsCString() const; 191 GetParent()192 lldb::SectionSP GetParent() const { return m_parent_wp.lock(); } 193 IsThreadSpecific()194 bool IsThreadSpecific() const { return m_thread_specific; } 195 SetIsThreadSpecific(bool b)196 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 GetObjectFile()204 ObjectFile *GetObjectFile() { return m_obj_file; } GetObjectFile()205 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 GetLog2Align()242 uint32_t GetLog2Align() { return m_log2align; } 243 SetLog2Align(uint32_t align)244 void SetLog2Align(uint32_t align) { m_log2align = align; } 245 246 // Get the number of host bytes required to hold a target byte GetTargetByteSize()247 uint32_t GetTargetByteSize() const { return m_target_byte_size; } 248 IsRelocated()249 bool IsRelocated() const { return m_relocated; } 250 SetIsRelocated(bool b)251 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 311