//===-- Section.h -----------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLDB_CORE_SECTION_H #define LLDB_CORE_SECTION_H #include "lldb/Core/ModuleChild.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Flags.h" #include "lldb/Utility/UserID.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" #include "llvm/Support/JSON.h" #include #include #include #include namespace lldb_private { class Address; class DataExtractor; class ObjectFile; class Section; class Target; class SectionList { public: typedef std::vector collection; typedef collection::iterator iterator; typedef collection::const_iterator const_iterator; const_iterator begin() const { return m_sections.begin(); } const_iterator end() const { return m_sections.end(); } const_iterator begin() { return m_sections.begin(); } const_iterator end() { return m_sections.end(); } /// Create an empty list. SectionList() = default; SectionList &operator=(const SectionList &rhs); size_t AddSection(const lldb::SectionSP §ion_sp); size_t AddUniqueSection(const lldb::SectionSP §ion_sp); size_t FindSectionIndex(const Section *sect); bool ContainsSection(lldb::user_id_t sect_id) const; void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, bool show_header, uint32_t depth) const; lldb::SectionSP FindSectionByName(ConstString section_dstr) const; lldb::SectionSP FindSectionByID(lldb::user_id_t sect_id) const; lldb::SectionSP FindSectionByType(lldb::SectionType sect_type, bool check_children, size_t start_idx = 0) const; lldb::SectionSP FindSectionContainingFileAddress(lldb::addr_t addr, uint32_t depth = UINT32_MAX) const; // Get the number of sections in this list only size_t GetSize() const { return m_sections.size(); } // Get the number of sections in this list, and any contained child sections size_t GetNumSections(uint32_t depth) const; bool ReplaceSection(lldb::user_id_t sect_id, const lldb::SectionSP §ion_sp, uint32_t depth = UINT32_MAX); // Warning, this can be slow as it's removing items from a std::vector. bool DeleteSection(size_t idx); lldb::SectionSP GetSectionAtIndex(size_t idx) const; size_t Slide(lldb::addr_t slide_amount, bool slide_children); void Clear() { m_sections.clear(); } /// Get the debug information size from all sections that contain debug /// information. Symbol tables are not considered part of the debug /// information for this call, just known sections that contain debug /// information. uint64_t GetDebugInfoSize() const; protected: collection m_sections; }; struct JSONSection { std::string name; std::optional type; std::optional address; std::optional size; }; class Section : public std::enable_shared_from_this
, public ModuleChild, public UserID, public Flags { public: // Create a root section (one that has no parent) Section(const lldb::ModuleSP &module_sp, ObjectFile *obj_file, lldb::user_id_t sect_id, ConstString name, lldb::SectionType sect_type, lldb::addr_t file_vm_addr, lldb::addr_t vm_size, lldb::offset_t file_offset, lldb::offset_t file_size, uint32_t log2align, uint32_t flags, uint32_t target_byte_size = 1); // Create a section that is a child of parent_section_sp Section(const lldb::SectionSP &parent_section_sp, // NULL for top level // sections, non-NULL for // child sections const lldb::ModuleSP &module_sp, ObjectFile *obj_file, lldb::user_id_t sect_id, ConstString name, lldb::SectionType sect_type, lldb::addr_t file_vm_addr, lldb::addr_t vm_size, lldb::offset_t file_offset, lldb::offset_t file_size, uint32_t log2align, uint32_t flags, uint32_t target_byte_size = 1); ~Section(); static int Compare(const Section &a, const Section &b); bool ContainsFileAddress(lldb::addr_t vm_addr) const; SectionList &GetChildren() { return m_children; } const SectionList &GetChildren() const { return m_children; } void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, uint32_t depth) const; void DumpName(llvm::raw_ostream &s) const; lldb::addr_t GetLoadBaseAddress(Target *target) const; bool ResolveContainedAddress(lldb::addr_t offset, Address &so_addr, bool allow_section_end = false) const; lldb::offset_t GetFileOffset() const { return m_file_offset; } void SetFileOffset(lldb::offset_t file_offset) { m_file_offset = file_offset; } lldb::offset_t GetFileSize() const { return m_file_size; } void SetFileSize(lldb::offset_t file_size) { m_file_size = file_size; } lldb::addr_t GetFileAddress() const; bool SetFileAddress(lldb::addr_t file_addr); lldb::addr_t GetOffset() const; lldb::addr_t GetByteSize() const { return m_byte_size; } void SetByteSize(lldb::addr_t byte_size) { m_byte_size = byte_size; } bool IsFake() const { return m_fake; } void SetIsFake(bool fake) { m_fake = fake; } bool IsEncrypted() const { return m_encrypted; } void SetIsEncrypted(bool b) { m_encrypted = b; } bool IsDescendant(const Section *section); ConstString GetName() const { return m_name; } bool Slide(lldb::addr_t slide_amount, bool slide_children); lldb::SectionType GetType() const { return m_type; } const char *GetTypeAsCString() const; lldb::SectionSP GetParent() const { return m_parent_wp.lock(); } bool IsThreadSpecific() const { return m_thread_specific; } void SetIsThreadSpecific(bool b) { m_thread_specific = b; } /// Get the permissions as OR'ed bits from lldb::Permissions uint32_t GetPermissions() const; /// Set the permissions using bits OR'ed from lldb::Permissions void SetPermissions(uint32_t permissions); ObjectFile *GetObjectFile() { return m_obj_file; } const ObjectFile *GetObjectFile() const { return m_obj_file; } /// Read the section data from the object file that the section /// resides in. /// /// \param[in] dst /// Where to place the data /// /// \param[in] dst_len /// How many bytes of section data to read /// /// \param[in] offset /// The offset in bytes within this section's data at which to /// start copying data from. /// /// \return /// The number of bytes read from the section, or zero if the /// section has no data or \a offset is not a valid offset /// in this section. lldb::offset_t GetSectionData(void *dst, lldb::offset_t dst_len, lldb::offset_t offset = 0); /// Get the shared reference to the section data from the object /// file that the section resides in. No copies of the data will be /// make unless the object file has been read from memory. If the /// object file is on disk, it will shared the mmap data for the /// entire object file. /// /// \param[in] data /// Where to place the data, address byte size, and byte order /// /// \return /// The number of bytes read from the section, or zero if the /// section has no data or \a offset is not a valid offset /// in this section. lldb::offset_t GetSectionData(DataExtractor &data); uint32_t GetLog2Align() { return m_log2align; } void SetLog2Align(uint32_t align) { m_log2align = align; } // Get the number of host bytes required to hold a target byte uint32_t GetTargetByteSize() const { return m_target_byte_size; } bool IsRelocated() const { return m_relocated; } void SetIsRelocated(bool b) { m_relocated = b; } /// Returns true if this section contains debug information. Symbol tables /// are not considered debug information since some symbols might contain /// debug information (STABS, COFF) but not all symbols do, so to keep this /// fast and simple only sections that contains only debug information should /// return true. bool ContainsOnlyDebugInfo() const; protected: ObjectFile *m_obj_file; // The object file that data for this section should // be read from lldb::SectionType m_type; // The type of this section lldb::SectionWP m_parent_wp; // Weak pointer to parent section ConstString m_name; // Name of this section lldb::addr_t m_file_addr; // The absolute file virtual address range of this // section if m_parent == NULL, // offset from parent file virtual address if m_parent != NULL lldb::addr_t m_byte_size; // Size in bytes that this section will occupy in // memory at runtime lldb::offset_t m_file_offset; // Object file offset (if any) lldb::offset_t m_file_size; // Object file size (can be smaller than // m_byte_size for zero filled sections...) uint32_t m_log2align; // log_2(align) of the section (i.e. section has to be // aligned to 2^m_log2align) SectionList m_children; // Child sections bool m_fake : 1, // If true, then this section only can contain the address if // one of its // children contains an address. This allows for gaps between the // children that are contained in the address range for this section, but // do not produce hits unless the children contain the address. m_encrypted : 1, // Set to true if the contents are encrypted m_thread_specific : 1, // This section is thread specific m_readable : 1, // If this section has read permissions m_writable : 1, // If this section has write permissions m_executable : 1, // If this section has executable permissions m_relocated : 1; // If this section has had relocations applied uint32_t m_target_byte_size; // Some architectures have non-8-bit byte size. // This is specified as // as a multiple number of a host bytes private: Section(const Section &) = delete; const Section &operator=(const Section &) = delete; }; } // namespace lldb_private namespace llvm { namespace json { bool fromJSON(const llvm::json::Value &value, lldb_private::JSONSection §ion, llvm::json::Path path); bool fromJSON(const llvm::json::Value &value, lldb::SectionType &type, llvm::json::Path path); } // namespace json } // namespace llvm #endif // LLDB_CORE_SECTION_H