summaryrefslogtreecommitdiffstats
path: root/source/Plugins/ObjectFile/ELF/ELFHeader.h
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/ObjectFile/ELF/ELFHeader.h')
-rw-r--r--source/Plugins/ObjectFile/ELF/ELFHeader.h433
1 files changed, 433 insertions, 0 deletions
diff --git a/source/Plugins/ObjectFile/ELF/ELFHeader.h b/source/Plugins/ObjectFile/ELF/ELFHeader.h
new file mode 100644
index 0000000..aa2c16b
--- /dev/null
+++ b/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_
OpenPOWER on IntegriCloud