You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
395 lines
14 KiB
395 lines
14 KiB
//===-- ELFHeader.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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
/// \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 LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H
|
|
#define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_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 // LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H
|