| //===-- 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 |
| /// 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/BinaryFormat/ELF.h" |
| |
| #include "lldb/lldb-enumerations.h" |
| #include "lldb/lldb-types.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 |
| /// 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_hdr; ///< Number of program header entries. |
| elf_half e_shentsize; ///< Size of a section header table entry. |
| elf_half e_shnum_hdr; ///< Number of section header entries. |
| elf_half e_shstrndx_hdr; ///< String table section index. |
| |
| // In some cases these numbers do not fit in 16 bits and they are |
| // stored outside of the header in section #0. Here are the actual |
| // values. |
| elf_word e_phnum; ///< Number of program header entries. |
| elf_word e_shnum; ///< Number of section header entries. |
| elf_word 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; |
| |
| //-------------------------------------------------------------------------- |
| /// Check if there should be header extension in section header #0 |
| /// |
| /// @return |
| /// True if parsing the ELFHeader requires reading header extension |
| /// and false otherwise. |
| bool HasHeaderExtension() 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); |
| |
| private: |
| |
| //-------------------------------------------------------------------------- |
| /// Parse an ELFHeader header extension entry. This method is called by |
| /// Parse(). |
| /// |
| /// @param[in] data |
| /// The DataExtractor to read from. |
| void ParseHeaderExtension(lldb_private::DataExtractor &data); |
| }; |
| |
| //------------------------------------------------------------------------------ |
| /// @class ELFSectionHeader |
| /// 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 |
| /// 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 |
| /// 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 |
| /// 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 |
| /// 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 |
| /// relocation. |
| static unsigned RelocSymbol32(const ELFRel &rel) { return rel.r_info >> 8; } |
| |
| /// Returns the symbol index when the given entry represents a 64-bit |
| /// relocation. |
| static unsigned RelocSymbol64(const ELFRel &rel) { return rel.r_info >> 32; } |
| }; |
| |
| //------------------------------------------------------------------------------ |
| /// @class ELFRela |
| /// 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 |
| /// relocation. |
| static unsigned RelocSymbol32(const ELFRela &rela) { |
| return rela.r_info >> 8; |
| } |
| |
| /// Returns the symbol index when the given entry represents a 64-bit |
| /// relocation. |
| static unsigned RelocSymbol64(const ELFRela &rela) { |
| return rela.r_info >> 32; |
| } |
| }; |
| |
| } // End namespace elf. |
| |
| #endif // #ifndef liblldb_ELFHeader_h_ |