diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h')
-rw-r--r-- | contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h | 433 |
1 files changed, 433 insertions, 0 deletions
diff --git a/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h new file mode 100644 index 0000000..aa2c16b --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h @@ -0,0 +1,433 @@ +//===-- ELFHeader.h ------------------------------------------- -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// @file +/// @brief Generic structures and typedefs for ELF files. +/// +/// This file provides definitions for the various entities comprising an ELF +/// file. The structures are generic in the sense that they do not correspond +/// to the exact binary layout of an ELF, but can be used to hold the +/// information present in both 32 and 64 bit variants of the format. Each +/// entity provides a \c Parse method which is capable of transparently reading +/// both 32 and 64 bit instances of the object. +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ELFHeader_h_ +#define liblldb_ELFHeader_h_ + +#include "llvm/Support/ELF.h" + +#include "lldb/lldb-enumerations.h" + +namespace lldb_private +{ +class DataExtractor; +} // End namespace lldb_private. + +namespace elf +{ + +//------------------------------------------------------------------------------ +/// @name ELF type definitions. +/// +/// Types used to represent the various components of ELF structures. All types +/// are signed or unsigned integral types wide enough to hold values from both +/// 32 and 64 bit ELF variants. +//@{ +typedef uint64_t elf_addr; +typedef uint64_t elf_off; +typedef uint16_t elf_half; +typedef uint32_t elf_word; +typedef int32_t elf_sword; +typedef uint64_t elf_size; +typedef uint64_t elf_xword; +typedef int64_t elf_sxword; +//@} + +//------------------------------------------------------------------------------ +/// @class ELFHeader +/// @brief Generic representation of an ELF file header. +/// +/// This object is used to identify the general attributes on an ELF file and to +/// locate additional sections within the file. +struct ELFHeader +{ + unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification. + elf_addr e_entry; ///< Virtual address program entry point. + elf_off e_phoff; ///< File offset of program header table. + elf_off e_shoff; ///< File offset of section header table. + elf_word e_flags; ///< Processor specific flags. + elf_word e_version; ///< Version of object file (always 1). + elf_half e_type; ///< Object file type. + elf_half e_machine; ///< Target architecture. + elf_half e_ehsize; ///< Byte size of the ELF header. + elf_half e_phentsize; ///< Size of a program header table entry. + elf_half e_phnum; ///< Number of program header entries. + elf_half e_shentsize; ///< Size of a section header table entry. + elf_half e_shnum; ///< Number of section header entries. + elf_half e_shstrndx; ///< String table section index. + + ELFHeader(); + + //-------------------------------------------------------------------------- + /// Returns true if this is a 32 bit ELF file header. + /// + /// @return + /// True if this is a 32 bit ELF file header. + bool Is32Bit() const { + return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32; + } + + //-------------------------------------------------------------------------- + /// Returns true if this is a 64 bit ELF file header. + /// + /// @return + /// True if this is a 64 bit ELF file header. + bool Is64Bit() const { + return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64; + } + + //-------------------------------------------------------------------------- + /// The byte order of this ELF file header. + /// + /// @return + /// The byte order of this ELF file as described by the header. + lldb::ByteOrder + GetByteOrder() const; + + //-------------------------------------------------------------------------- + /// The jump slot relocation type of this ELF. + unsigned + GetRelocationJumpSlotType() const; + + //-------------------------------------------------------------------------- + /// Parse an ELFHeader entry starting at position \p offset and + /// update the data extractor with the address size and byte order + /// attributes as defined by the header. + /// + /// @param[in,out] data + /// The DataExtractor to read from. Updated with the address size and + /// byte order attributes appropriate to this header. + /// + /// @param[in,out] offset + /// Pointer to an offset in the data. On return the offset will be + /// advanced by the number of bytes read. + /// + /// @return + /// True if the ELFHeader was successfully read and false + /// otherwise. + bool + Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset); + + //-------------------------------------------------------------------------- + /// Examines at most EI_NIDENT bytes starting from the given pointer and + /// determines if the magic ELF identification exists. + /// + /// @return + /// True if the given sequence of bytes identifies an ELF file. + static bool + MagicBytesMatch(const uint8_t *magic); + + //-------------------------------------------------------------------------- + /// Examines at most EI_NIDENT bytes starting from the given address and + /// determines the address size of the underlying ELF file. This function + /// should only be called on an pointer for which MagicBytesMatch returns + /// true. + /// + /// @return + /// The number of bytes forming an address in the ELF file (either 4 or + /// 8), else zero if the address size could not be determined. + static unsigned + AddressSizeInBytes(const uint8_t *magic); +}; + +//------------------------------------------------------------------------------ +/// @class ELFSectionHeader +/// @brief Generic representation of an ELF section header. +struct ELFSectionHeader +{ + elf_word sh_name; ///< Section name string index. + elf_word sh_type; ///< Section type. + elf_xword sh_flags; ///< Section attributes. + elf_addr sh_addr; ///< Virtual address of the section in memory. + elf_off sh_offset; ///< Start of section from beginning of file. + elf_xword sh_size; ///< Number of bytes occupied in the file. + elf_word sh_link; ///< Index of associated section. + elf_word sh_info; ///< Extra section info (overloaded). + elf_xword sh_addralign; ///< Power of two alignment constraint. + elf_xword sh_entsize; ///< Byte size of each section entry. + + ELFSectionHeader(); + + //-------------------------------------------------------------------------- + /// Parse an ELFSectionHeader entry from the given DataExtracter starting at + /// position \p offset. + /// + /// @param[in] data + /// The DataExtractor to read from. The address size of the extractor + /// determines if a 32 or 64 bit object should be read. + /// + /// @param[in,out] offset + /// Pointer to an offset in the data. On return the offset will be + /// advanced by the number of bytes read. + /// + /// @return + /// True if the ELFSectionHeader was successfully read and false + /// otherwise. + bool + Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); +}; + +//------------------------------------------------------------------------------ +/// @class ELFProgramHeader +/// @brief Generic representation of an ELF program header. +struct ELFProgramHeader +{ + elf_word p_type; ///< Type of program segment. + elf_word p_flags; ///< Segment attributes. + elf_off p_offset; ///< Start of segment from beginning of file. + elf_addr p_vaddr; ///< Virtual address of segment in memory. + elf_addr p_paddr; ///< Physical address (for non-VM systems). + elf_xword p_filesz; ///< Byte size of the segment in file. + elf_xword p_memsz; ///< Byte size of the segment in memory. + elf_xword p_align; ///< Segment alignment constraint. + + ELFProgramHeader(); + + /// Parse an ELFProgramHeader entry from the given DataExtractor starting at + /// position \p offset. The address size of the DataExtractor determines if + /// a 32 or 64 bit object is to be parsed. + /// + /// @param[in] data + /// The DataExtractor to read from. The address size of the extractor + /// determines if a 32 or 64 bit object should be read. + /// + /// @param[in,out] offset + /// Pointer to an offset in the data. On return the offset will be + /// advanced by the number of bytes read. + /// + /// @return + /// True if the ELFProgramHeader was successfully read and false + /// otherwise. + bool + Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); +}; + +//------------------------------------------------------------------------------ +/// @class ELFSymbol +/// @brief Represents a symbol within an ELF symbol table. +struct ELFSymbol +{ + elf_addr st_value; ///< Absolute or relocatable address. + elf_xword st_size; ///< Size of the symbol or zero. + elf_word st_name; ///< Symbol name string index. + unsigned char st_info; ///< Symbol type and binding attributes. + unsigned char st_other; ///< Reserved for future use. + elf_half st_shndx; ///< Section to which this symbol applies. + + ELFSymbol(); + + /// Returns the binding attribute of the st_info member. + unsigned char getBinding() const { return st_info >> 4; } + + /// Returns the type attribute of the st_info member. + unsigned char getType() const { return st_info & 0x0F; } + + /// Sets the binding and type of the st_info member. + void setBindingAndType(unsigned char binding, unsigned char type) { + st_info = (binding << 4) + (type & 0x0F); + } + + static const char * + bindingToCString(unsigned char binding); + + static const char * + typeToCString(unsigned char type); + + static const char * + sectionIndexToCString(elf_half shndx, + const lldb_private::SectionList *section_list); + + /// Parse an ELFSymbol entry from the given DataExtractor starting at + /// position \p offset. The address size of the DataExtractor determines if + /// a 32 or 64 bit object is to be parsed. + /// + /// @param[in] data + /// The DataExtractor to read from. The address size of the extractor + /// determines if a 32 or 64 bit object should be read. + /// + /// @param[in,out] offset + /// Pointer to an offset in the data. On return the offset will be + /// advanced by the number of bytes read. + /// + /// @return + /// True if the ELFSymbol was successfully read and false otherwise. + bool + Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); + + void + Dump (lldb_private::Stream *s, + uint32_t idx, + const lldb_private::DataExtractor *strtab_data, + const lldb_private::SectionList *section_list); +}; + +//------------------------------------------------------------------------------ +/// @class ELFDynamic +/// @brief Represents an entry in an ELF dynamic table. +struct ELFDynamic +{ + elf_sxword d_tag; ///< Type of dynamic table entry. + union + { + elf_xword d_val; ///< Integer value of the table entry. + elf_addr d_ptr; ///< Pointer value of the table entry. + }; + + ELFDynamic(); + + /// Parse an ELFDynamic entry from the given DataExtractor starting at + /// position \p offset. The address size of the DataExtractor determines if + /// a 32 or 64 bit object is to be parsed. + /// + /// @param[in] data + /// The DataExtractor to read from. The address size of the extractor + /// determines if a 32 or 64 bit object should be read. + /// + /// @param[in,out] offset + /// Pointer to an offset in the data. On return the offset will be + /// advanced by the number of bytes read. + /// + /// @return + /// True if the ELFDynamic entry was successfully read and false + /// otherwise. + bool + Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); +}; + +//------------------------------------------------------------------------------ +/// @class ELFRel +/// @brief Represents a relocation entry with an implicit addend. +struct ELFRel +{ + elf_addr r_offset; ///< Address of reference. + elf_xword r_info; ///< symbol index and type of relocation. + + ELFRel(); + + /// Parse an ELFRel entry from the given DataExtractor starting at position + /// \p offset. The address size of the DataExtractor determines if a 32 or + /// 64 bit object is to be parsed. + /// + /// @param[in] data + /// The DataExtractor to read from. The address size of the extractor + /// determines if a 32 or 64 bit object should be read. + /// + /// @param[in,out] offset + /// Pointer to an offset in the data. On return the offset will be + /// advanced by the number of bytes read. + /// + /// @return + /// True if the ELFRel entry was successfully read and false otherwise. + bool + Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); + + /// Returns the type when the given entry represents a 32-bit relocation. + static unsigned + RelocType32(const ELFRel &rel) + { + return rel.r_info & 0x0ff; + } + + /// Returns the type when the given entry represents a 64-bit relocation. + static unsigned + RelocType64(const ELFRel &rel) + { + return rel.r_info & 0xffffffff; + } + + /// Returns the symbol index when the given entry represents a 32-bit + /// reloction. + static unsigned + RelocSymbol32(const ELFRel &rel) + { + return rel.r_info >> 8; + } + + /// Returns the symbol index when the given entry represents a 64-bit + /// reloction. + static unsigned + RelocSymbol64(const ELFRel &rel) + { + return rel.r_info >> 32; + } +}; + +//------------------------------------------------------------------------------ +/// @class ELFRela +/// @brief Represents a relocation entry with an explicit addend. +struct ELFRela +{ + elf_addr r_offset; ///< Address of reference. + elf_xword r_info; ///< Symbol index and type of relocation. + elf_sxword r_addend; ///< Constant part of expression. + + ELFRela(); + + /// Parse an ELFRela entry from the given DataExtractor starting at position + /// \p offset. The address size of the DataExtractor determines if a 32 or + /// 64 bit object is to be parsed. + /// + /// @param[in] data + /// The DataExtractor to read from. The address size of the extractor + /// determines if a 32 or 64 bit object should be read. + /// + /// @param[in,out] offset + /// Pointer to an offset in the data. On return the offset will be + /// advanced by the number of bytes read. + /// + /// @return + /// True if the ELFRela entry was successfully read and false otherwise. + bool + Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); + + /// Returns the type when the given entry represents a 32-bit relocation. + static unsigned + RelocType32(const ELFRela &rela) + { + return rela.r_info & 0x0ff; + } + + /// Returns the type when the given entry represents a 64-bit relocation. + static unsigned + RelocType64(const ELFRela &rela) + { + return rela.r_info & 0xffffffff; + } + + /// Returns the symbol index when the given entry represents a 32-bit + /// reloction. + static unsigned + RelocSymbol32(const ELFRela &rela) + { + return rela.r_info >> 8; + } + + /// Returns the symbol index when the given entry represents a 64-bit + /// reloction. + static unsigned + RelocSymbol64(const ELFRela &rela) + { + return rela.r_info >> 32; + } +}; + +} // End namespace elf. + +#endif // #ifndef liblldb_ELFHeader_h_ |