blob: af2bb7896a5bc9caff0a6e699368909d91fa8f7a [file] [log] [blame]
//===-- 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 <memory>
#include <vector>
#include <stddef.h>
#include <stdint.h>
namespace lldb_private {
class Address;
class DataExtractor;
class ObjectFile;
class Section;
class Target;
class SectionList {
public:
typedef std::vector<lldb::SectionSP> 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 &section_sp);
size_t AddUniqueSection(const lldb::SectionSP &section_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 &section_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(); }
protected:
collection m_sections;
};
class Section : public std::enable_shared_from_this<Section>,
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; }
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
#endif // LLDB_CORE_SECTION_H