Combine 32 and 64 bit ELF readers.
This patch provides a generic ELF reader plugin to handle both 32 and 64 bit formats. llvm-svn: 108292
This commit is contained in:
parent
cb89a2a150
commit
f325ba9d45
|
@ -0,0 +1,302 @@
|
|||
//===-- ELFHeader.cpp ----------------------------------------- -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
|
||||
#include "ELFHeader.h"
|
||||
|
||||
using namespace elf;
|
||||
using namespace lldb;
|
||||
using namespace llvm::ELF;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Static utility functions.
|
||||
//
|
||||
// GetMaxU64 and GetMaxS64 wrap the similarly named methods from DataExtractor
|
||||
// with error handling code and provide for parsing a sequence of values.
|
||||
static bool
|
||||
GetMaxU64(const lldb_private::DataExtractor &data,
|
||||
uint32_t *offset, uint64_t *value, uint32_t byte_size)
|
||||
{
|
||||
const uint32_t saved_offset = *offset;
|
||||
*value = data.GetMaxU64(offset, byte_size);
|
||||
return *offset != saved_offset;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetMaxU64(const lldb_private::DataExtractor &data,
|
||||
uint32_t *offset, uint64_t *value, uint32_t byte_size,
|
||||
uint32_t count)
|
||||
{
|
||||
uint32_t saved_offset = *offset;
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i, ++value)
|
||||
{
|
||||
if (GetMaxU64(data, offset, value, byte_size) == false)
|
||||
{
|
||||
*offset = saved_offset;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetMaxS64(const lldb_private::DataExtractor &data,
|
||||
uint32_t *offset, int64_t *value, uint32_t byte_size)
|
||||
{
|
||||
const uint32_t saved_offset = *offset;
|
||||
*value = data.GetMaxS64(offset, byte_size);
|
||||
return *offset != saved_offset;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetMaxS64(const lldb_private::DataExtractor &data,
|
||||
uint32_t *offset, int64_t *value, uint32_t byte_size,
|
||||
uint32_t count)
|
||||
{
|
||||
uint32_t saved_offset = *offset;
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i, ++value)
|
||||
{
|
||||
if (GetMaxS64(data, offset, value, byte_size) == false)
|
||||
{
|
||||
*offset = saved_offset;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ELFHeader
|
||||
|
||||
ELFHeader::ELFHeader()
|
||||
{
|
||||
memset(this, 0, sizeof(ELFHeader));
|
||||
}
|
||||
|
||||
ByteOrder
|
||||
ELFHeader::GetByteOrder() const
|
||||
{
|
||||
if (e_ident[EI_DATA] == ELFDATA2MSB)
|
||||
return eByteOrderBig;
|
||||
if (e_ident[EI_DATA] == ELFDATA2LSB)
|
||||
return eByteOrderLittle;
|
||||
return eByteOrderInvalid;
|
||||
}
|
||||
|
||||
bool
|
||||
ELFHeader::Parse(lldb_private::DataExtractor &data, uint32_t *offset)
|
||||
{
|
||||
// Read e_ident. This provides byte order and address size info.
|
||||
if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL)
|
||||
return false;
|
||||
|
||||
const unsigned byte_size = Is32Bit() ? 4 : 8;
|
||||
data.SetByteOrder(GetByteOrder());
|
||||
data.SetAddressByteSize(byte_size);
|
||||
|
||||
// Read e_type and e_machine.
|
||||
if (data.GetU16(offset, &e_type, 2) == NULL)
|
||||
return false;
|
||||
|
||||
// Read e_version.
|
||||
if (data.GetU32(offset, &e_version, 1) == NULL)
|
||||
return false;
|
||||
|
||||
// Read e_entry, e_phoff and e_shoff.
|
||||
if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false)
|
||||
return false;
|
||||
|
||||
// Read e_flags.
|
||||
if (data.GetU32(offset, &e_flags, 1) == NULL)
|
||||
return false;
|
||||
|
||||
// Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and
|
||||
// e_shstrndx.
|
||||
if (data.GetU16(offset, &e_ehsize, 6) == NULL)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ELFHeader::MagicBytesMatch(const uint8_t *magic)
|
||||
{
|
||||
return memcmp(magic, ElfMagic, strlen(ElfMagic)) == 0;
|
||||
}
|
||||
|
||||
unsigned
|
||||
ELFHeader::AddressSizeInBytes(const uint8_t *magic)
|
||||
{
|
||||
unsigned address_size = 0;
|
||||
|
||||
switch (magic[EI_CLASS])
|
||||
{
|
||||
case ELFCLASS32:
|
||||
address_size = 4;
|
||||
break;
|
||||
|
||||
case ELFCLASS64:
|
||||
address_size = 8;
|
||||
break;
|
||||
}
|
||||
return address_size;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ELFSectionHeader
|
||||
|
||||
ELFSectionHeader::ELFSectionHeader()
|
||||
{
|
||||
memset(this, 0, sizeof(ELFSectionHeader));
|
||||
}
|
||||
|
||||
bool
|
||||
ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,
|
||||
uint32_t *offset)
|
||||
{
|
||||
const unsigned byte_size = data.GetAddressByteSize();
|
||||
|
||||
// Read sh_name and sh_type.
|
||||
if (data.GetU32(offset, &sh_name, 2) == NULL)
|
||||
return false;
|
||||
|
||||
// Read sh_flags.
|
||||
if (GetMaxU64(data, offset, &sh_flags, byte_size) == false)
|
||||
return false;
|
||||
|
||||
// Read sh_addr, sh_off and sh_size.
|
||||
if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false)
|
||||
return false;
|
||||
|
||||
// Read sh_link and sh_info.
|
||||
if (data.GetU32(offset, &sh_link, 2) == NULL)
|
||||
return false;
|
||||
|
||||
// Read sh_addralign and sh_entsize.
|
||||
if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ELFSymbol
|
||||
|
||||
ELFSymbol::ELFSymbol()
|
||||
{
|
||||
memset(this, 0, sizeof(ELFSymbol));
|
||||
}
|
||||
|
||||
bool
|
||||
ELFSymbol::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
|
||||
{
|
||||
const unsigned byte_size = data.GetAddressByteSize();
|
||||
const bool parsing_32 = byte_size == 4;
|
||||
|
||||
// Read st_name.
|
||||
if (data.GetU32(offset, &st_name, 1) == NULL)
|
||||
return false;
|
||||
|
||||
if (parsing_32)
|
||||
{
|
||||
// Read st_value and st_size.
|
||||
if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false)
|
||||
return false;
|
||||
|
||||
// Read st_info and st_other.
|
||||
if (data.GetU8(offset, &st_info, 2) == NULL)
|
||||
return false;
|
||||
|
||||
// Read st_shndx.
|
||||
if (data.GetU16(offset, &st_shndx, 1) == NULL)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read st_info and st_other.
|
||||
if (data.GetU8(offset, &st_info, 2) == NULL)
|
||||
return false;
|
||||
|
||||
// Read st_shndx.
|
||||
if (data.GetU16(offset, &st_shndx, 1) == NULL)
|
||||
return false;
|
||||
|
||||
// Read st_value and st_size.
|
||||
if (data.GetU64(offset, &st_value, 2) == NULL)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ELFProgramHeader
|
||||
|
||||
ELFProgramHeader::ELFProgramHeader()
|
||||
{
|
||||
memset(this, 0, sizeof(ELFProgramHeader));
|
||||
}
|
||||
|
||||
bool
|
||||
ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,
|
||||
uint32_t *offset)
|
||||
{
|
||||
const uint32_t byte_size = data.GetAddressByteSize();
|
||||
const bool parsing_32 = byte_size == 4;
|
||||
|
||||
// Read p_type;
|
||||
if (data.GetU32(offset, &p_type, 1) == NULL)
|
||||
return false;
|
||||
|
||||
if (parsing_32) {
|
||||
// Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz.
|
||||
if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false)
|
||||
return false;
|
||||
|
||||
// Read p_flags.
|
||||
if (data.GetU32(offset, &p_flags, 1) == NULL)
|
||||
return false;
|
||||
|
||||
// Read p_align.
|
||||
if (GetMaxU64(data, offset, &p_align, byte_size) == false)
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// Read p_flags.
|
||||
if (data.GetU32(offset, &p_flags, 1) == NULL)
|
||||
return false;
|
||||
|
||||
// Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align.
|
||||
if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ELFDynamic
|
||||
|
||||
ELFDynamic::ELFDynamic()
|
||||
{
|
||||
memset(this, 0, sizeof(ELFDynamic));
|
||||
}
|
||||
|
||||
bool
|
||||
ELFDynamic::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
|
||||
{
|
||||
const unsigned byte_size = data.GetAddressByteSize();
|
||||
return GetMaxS64(data, offset, &d_tag, byte_size, 2);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,295 @@
|
|||
//===-- 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 entrys.
|
||||
elf_half e_shentsize; ///< Size of a section header table entry.
|
||||
elf_half e_shnum; ///< Number of section header entrys.
|
||||
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;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/// Parse an ELFSectionHeader 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 ELFSectionHeader was successfully read and false
|
||||
/// otherwise.
|
||||
bool
|
||||
Parse(lldb_private::DataExtractor &data, uint32_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, uint32_t *offset);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// @class ELFProgramHeader
|
||||
/// @brief Generic representation of an ELF program header.
|
||||
struct ELFProgramHeader
|
||||
{
|
||||
elf_word p_type; ///< Type of program segement.
|
||||
elf_word p_flags; ///< Segement attibutes.
|
||||
elf_off p_offset; ///< Start of segment from begining 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; ///< Segement alignement constraint.
|
||||
|
||||
ELFProgramHeader();
|
||||
|
||||
/// Parse an ELFProgramHeader entry from the given DataExtracter starting at
|
||||
/// position \p offset. The address size of the DataExtracter 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, uint32_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 bining and type of the st_info member.
|
||||
void setBindingAndType(unsigned char binding, unsigned char type) {
|
||||
st_info = (binding << 4) + (type & 0x0F);
|
||||
}
|
||||
|
||||
/// Parse an ELFSymbol entry from the given DataExtracter starting at
|
||||
/// position \p offset. The address size of the DataExtracter 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, uint32_t *offset);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// @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 DataExtracter starting at
|
||||
/// position \p offset. The address size of the DataExtracter 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, uint32_t *offset);
|
||||
};
|
||||
|
||||
} // End namespace elf.
|
||||
|
||||
#endif // #ifndef liblldb_ELFHeader_h_
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
//===-- ObjectFileELF.h -----------------------------------------*- C++ -*-===//
|
||||
//===-- ObjectFileELF.h --------------------------------------- -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -17,12 +17,14 @@
|
|||
#include "lldb/Core/FileSpec.h"
|
||||
#include "lldb/Symbol/ObjectFile.h"
|
||||
|
||||
#include "elf.h"
|
||||
#include "ELFHeader.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// This class needs to be hidden as eventually belongs in a plugin that
|
||||
// will export the ObjectFile protocol
|
||||
//----------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
/// @class ObjectFileELF
|
||||
/// @brief Generic ELF object file reader.
|
||||
///
|
||||
/// This class provides a generic ELF (32/64 bit) reader plugin implementing the
|
||||
/// ObjectFile protocol.
|
||||
class ObjectFileELF :
|
||||
public lldb_private::ObjectFile
|
||||
{
|
||||
|
@ -43,53 +45,12 @@ public:
|
|||
GetPluginDescriptionStatic();
|
||||
|
||||
static lldb_private::ObjectFile *
|
||||
CreateInstance (lldb_private::Module* module,
|
||||
lldb::DataBufferSP& dataSP,
|
||||
const lldb_private::FileSpec* file,
|
||||
lldb::addr_t offset,
|
||||
lldb::addr_t length);
|
||||
static bool
|
||||
MagicBytesMatch (lldb::DataBufferSP& dataSP);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Member Functions
|
||||
//------------------------------------------------------------------
|
||||
ObjectFileELF (lldb_private::Module* module,
|
||||
CreateInstance(lldb_private::Module* module,
|
||||
lldb::DataBufferSP& dataSP,
|
||||
const lldb_private::FileSpec* file,
|
||||
lldb::addr_t offset,
|
||||
lldb::addr_t length);
|
||||
|
||||
virtual
|
||||
~ObjectFileELF();
|
||||
|
||||
virtual bool
|
||||
ParseHeader ();
|
||||
|
||||
virtual lldb::ByteOrder
|
||||
GetByteOrder () const;
|
||||
|
||||
virtual size_t
|
||||
GetAddressByteSize () const;
|
||||
|
||||
virtual lldb_private::Symtab *
|
||||
GetSymtab();
|
||||
|
||||
virtual lldb_private::SectionList *
|
||||
GetSectionList();
|
||||
|
||||
virtual void
|
||||
Dump (lldb_private::Stream *s);
|
||||
|
||||
virtual bool
|
||||
GetTargetTriple (lldb_private::ConstString &target_triple);
|
||||
|
||||
virtual bool
|
||||
GetUUID (lldb_private::UUID* uuid);
|
||||
|
||||
virtual uint32_t
|
||||
GetDependentModules(lldb_private::FileSpecList& files);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// PluginInterface protocol
|
||||
//------------------------------------------------------------------
|
||||
|
@ -103,95 +64,187 @@ public:
|
|||
GetPluginVersion();
|
||||
|
||||
virtual void
|
||||
GetPluginCommandHelp (const char *command, lldb_private::Stream *strm);
|
||||
GetPluginCommandHelp(const char *command, lldb_private::Stream *strm);
|
||||
|
||||
virtual lldb_private::Error
|
||||
ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm);
|
||||
ExecutePluginCommand(lldb_private::Args &command,
|
||||
lldb_private::Stream *strm);
|
||||
|
||||
virtual lldb_private::Log *
|
||||
EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command);
|
||||
EnablePluginLogging(lldb_private::Stream *strm,
|
||||
lldb_private::Args &command);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// ObjectFile Protocol.
|
||||
//------------------------------------------------------------------
|
||||
virtual
|
||||
~ObjectFileELF();
|
||||
|
||||
virtual bool
|
||||
ParseHeader();
|
||||
|
||||
protected:
|
||||
typedef std::vector<Elf32_Phdr> ProgramHeaderColl;
|
||||
virtual lldb::ByteOrder
|
||||
GetByteOrder() const;
|
||||
|
||||
virtual size_t
|
||||
GetAddressByteSize() const;
|
||||
|
||||
virtual lldb_private::Symtab *
|
||||
GetSymtab();
|
||||
|
||||
virtual lldb_private::SectionList *
|
||||
GetSectionList();
|
||||
|
||||
virtual void
|
||||
Dump(lldb_private::Stream *s);
|
||||
|
||||
virtual bool
|
||||
GetTargetTriple(lldb_private::ConstString &target_triple);
|
||||
|
||||
virtual bool
|
||||
GetUUID(lldb_private::UUID* uuid);
|
||||
|
||||
virtual uint32_t
|
||||
GetDependentModules(lldb_private::FileSpecList& files);
|
||||
|
||||
private:
|
||||
ObjectFileELF(lldb_private::Module* module,
|
||||
lldb::DataBufferSP& dataSP,
|
||||
const lldb_private::FileSpec* file,
|
||||
lldb::addr_t offset,
|
||||
lldb::addr_t length);
|
||||
|
||||
typedef std::vector<elf::ELFProgramHeader> ProgramHeaderColl;
|
||||
typedef ProgramHeaderColl::iterator ProgramHeaderCollIter;
|
||||
typedef ProgramHeaderColl::const_iterator ProgramHeaderCollConstIter;
|
||||
|
||||
typedef std::vector<Elf32_Shdr> SectionHeaderColl;
|
||||
typedef std::vector<elf::ELFSectionHeader> SectionHeaderColl;
|
||||
typedef SectionHeaderColl::iterator SectionHeaderCollIter;
|
||||
typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
|
||||
|
||||
Elf32_Ehdr m_header;
|
||||
/// Version of this reader common to all plugins based on this class.
|
||||
static const uint32_t m_plugin_version = 1;
|
||||
|
||||
/// ELF file header.
|
||||
elf::ELFHeader m_header;
|
||||
|
||||
/// Collection of program headers.
|
||||
ProgramHeaderColl m_program_headers;
|
||||
|
||||
/// Collection of section headers.
|
||||
SectionHeaderColl m_section_headers;
|
||||
|
||||
/// List of sections present in this ELF object file.
|
||||
mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
|
||||
|
||||
/// Table of all non-dynamic symbols present in this object file.
|
||||
mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
|
||||
|
||||
/// List of file specifications corresponding to the modules (shared
|
||||
/// libraries) on which this object file depends.
|
||||
mutable std::auto_ptr<lldb_private::FileSpecList> m_filespec_ap;
|
||||
|
||||
/// Data extractor holding the string table used to resolve section names.
|
||||
lldb_private::DataExtractor m_shstr_data;
|
||||
|
||||
/// Returns a 1 based index of the given section header.
|
||||
unsigned
|
||||
SectionIndex(const SectionHeaderCollIter &I);
|
||||
|
||||
/// Returns a 1 based index of the given section header.
|
||||
unsigned
|
||||
SectionIndex(const SectionHeaderCollConstIter &I) const;
|
||||
|
||||
/// Parses all section headers present in this object file and populates
|
||||
/// m_program_headers. This method will compute the header list only once.
|
||||
/// Returns the number of headers parsed.
|
||||
size_t
|
||||
ParseSections ();
|
||||
ParseProgramHeaders();
|
||||
|
||||
/// Parses all section headers present in this object file and populates
|
||||
/// m_section_headers. This method will compute the header list only once.
|
||||
/// Returns the number of headers parsed.
|
||||
size_t
|
||||
ParseSymtab (bool minimize);
|
||||
ParseSectionHeaders();
|
||||
|
||||
private:
|
||||
/// Scans the dynamic section and locates all dependent modules (shared
|
||||
/// libaries) populating m_filespec_ap. This method will compute the
|
||||
/// dependent module list only once. Returns the number of dependent
|
||||
/// modules parsed.
|
||||
size_t
|
||||
ParseDependentModules();
|
||||
|
||||
// ELF header dump routines
|
||||
static void
|
||||
DumpELFHeader (lldb_private::Stream *s,
|
||||
const Elf32_Ehdr& header);
|
||||
|
||||
static void
|
||||
DumpELFHeader_e_ident_EI_DATA (lldb_private::Stream *s,
|
||||
uint16_t ei_data);
|
||||
static void
|
||||
DumpELFHeader_e_type (lldb_private::Stream *s,
|
||||
uint16_t e_type);
|
||||
|
||||
// ELF program header dump routines
|
||||
/// Populates m_symtab_ap will all non-dynamic linker symbols. This method
|
||||
/// will parse the symbols only once. Returns the number of symbols parsed.
|
||||
void
|
||||
DumpELFProgramHeaders (lldb_private::Stream *s);
|
||||
ParseSymbolTable(lldb_private::Symtab *symbol_table,
|
||||
const elf::ELFSectionHeader &symtab_section,
|
||||
lldb::user_id_t symtab_id);
|
||||
|
||||
/// Loads the section name string table into m_shstr_data. Returns the
|
||||
/// number of bytes constituting the table.
|
||||
size_t
|
||||
GetSectionHeaderStringTable();
|
||||
|
||||
/// Utility method for looking up a section given its name. Returns the
|
||||
/// index of the corresponding section or zero if no section with the given
|
||||
/// name can be found (note that section indices are always 1 based, and so
|
||||
/// section index 0 is never valid).
|
||||
lldb::user_id_t
|
||||
GetSectionIndexByName(const char *name);
|
||||
|
||||
/// @name ELF header dump routines
|
||||
//@{
|
||||
static void
|
||||
DumpELFHeader(lldb_private::Stream *s, const elf::ELFHeader& header);
|
||||
|
||||
static void
|
||||
DumpELFProgramHeader (lldb_private::Stream *s,
|
||||
const Elf32_Phdr& ph);
|
||||
DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s,
|
||||
unsigned char ei_data);
|
||||
|
||||
static void
|
||||
DumpELFProgramHeader_p_type (lldb_private::Stream *s,
|
||||
Elf32_Word p_type);
|
||||
DumpELFHeader_e_type(lldb_private::Stream *s, elf::elf_half e_type);
|
||||
//@}
|
||||
|
||||
static void
|
||||
DumpELFProgramHeader_p_flags (lldb_private::Stream *s,
|
||||
Elf32_Word p_flags);
|
||||
|
||||
// ELF section header dump routines
|
||||
/// @name ELF program header dump routines
|
||||
//@{
|
||||
void
|
||||
DumpELFSectionHeaders (lldb_private::Stream *s);
|
||||
DumpELFProgramHeaders(lldb_private::Stream *s);
|
||||
|
||||
static void
|
||||
DumpELFSectionHeader (lldb_private::Stream *s,
|
||||
const Elf32_Shdr& sh);
|
||||
DumpELFProgramHeader(lldb_private::Stream *s,
|
||||
const elf::ELFProgramHeader &ph);
|
||||
|
||||
static void
|
||||
DumpELFSectionHeader_sh_type (lldb_private::Stream *s,
|
||||
Elf32_Word sh_type);
|
||||
DumpELFProgramHeader_p_type(lldb_private::Stream *s, elf::elf_word p_type);
|
||||
|
||||
static void
|
||||
DumpELFSectionHeader_sh_flags (lldb_private::Stream *s,
|
||||
Elf32_Word sh_flags);
|
||||
DumpELFProgramHeader_p_flags(lldb_private::Stream *s,
|
||||
elf::elf_word p_flags);
|
||||
//@}
|
||||
|
||||
size_t
|
||||
ParseProgramHeaders ();
|
||||
/// @name ELF section header dump routines
|
||||
//@{
|
||||
void
|
||||
DumpELFSectionHeaders(lldb_private::Stream *s);
|
||||
|
||||
size_t
|
||||
ParseSectionHeaders ();
|
||||
static void
|
||||
DumpELFSectionHeader(lldb_private::Stream *s,
|
||||
const elf::ELFSectionHeader& sh);
|
||||
|
||||
size_t
|
||||
GetSectionHeaderStringTable ();
|
||||
static void
|
||||
DumpELFSectionHeader_sh_type(lldb_private::Stream *s,
|
||||
elf::elf_word sh_type);
|
||||
|
||||
static void
|
||||
DumpELFSectionHeader_sh_flags(lldb_private::Stream *s,
|
||||
elf::elf_word sh_flags);
|
||||
//@}
|
||||
|
||||
/// ELF dependent module dump routine.
|
||||
void
|
||||
DumpDependentModules(lldb_private::Stream *s);
|
||||
|
||||
uint32_t
|
||||
GetSectionIndexByName (const char *name);
|
||||
};
|
||||
|
||||
#endif // #ifndef liblldb_ObjectFileELF_h_
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,209 +0,0 @@
|
|||
//===-- ObjectFileELF64.h ------------------------------------- -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_ObjectFileELF64_h_
|
||||
#define liblldb_ObjectFileELF64_h_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Core/FileSpec.h"
|
||||
#include "lldb/Symbol/ObjectFile.h"
|
||||
|
||||
#include "elf.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// This class needs to be hidden as eventually belongs in a plugin that
|
||||
// will export the ObjectFile protocol
|
||||
//----------------------------------------------------------------------
|
||||
class ObjectFileELF64 :
|
||||
public lldb_private::ObjectFile
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------
|
||||
// Static Functions
|
||||
//------------------------------------------------------------------
|
||||
static void
|
||||
Initialize();
|
||||
|
||||
static void
|
||||
Terminate();
|
||||
|
||||
static const char *
|
||||
GetPluginNameStatic();
|
||||
|
||||
static const char *
|
||||
GetPluginDescriptionStatic();
|
||||
|
||||
static lldb_private::ObjectFile *
|
||||
CreateInstance(lldb_private::Module* module,
|
||||
lldb::DataBufferSP& dataSP,
|
||||
const lldb_private::FileSpec* file,
|
||||
lldb::addr_t offset,
|
||||
lldb::addr_t length);
|
||||
|
||||
static bool
|
||||
MagicBytesMatch(lldb::DataBufferSP& dataSP);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Member Functions
|
||||
//------------------------------------------------------------------
|
||||
ObjectFileELF64(lldb_private::Module* module,
|
||||
lldb::DataBufferSP& dataSP,
|
||||
const lldb_private::FileSpec* file,
|
||||
lldb::addr_t offset,
|
||||
lldb::addr_t length);
|
||||
|
||||
virtual
|
||||
~ObjectFileELF64();
|
||||
|
||||
virtual bool
|
||||
ParseHeader();
|
||||
|
||||
virtual lldb::ByteOrder
|
||||
GetByteOrder() const;
|
||||
|
||||
virtual size_t
|
||||
GetAddressByteSize() const;
|
||||
|
||||
virtual lldb_private::Symtab *
|
||||
GetSymtab();
|
||||
|
||||
virtual lldb_private::SectionList *
|
||||
GetSectionList();
|
||||
|
||||
virtual void
|
||||
Dump(lldb_private::Stream *s);
|
||||
|
||||
virtual bool
|
||||
GetTargetTriple(lldb_private::ConstString &target_triple);
|
||||
|
||||
virtual bool
|
||||
GetUUID(lldb_private::UUID* uuid);
|
||||
|
||||
virtual uint32_t
|
||||
GetDependentModules(lldb_private::FileSpecList& files);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// PluginInterface protocol
|
||||
//------------------------------------------------------------------
|
||||
virtual const char *
|
||||
GetPluginName();
|
||||
|
||||
virtual const char *
|
||||
GetShortPluginName();
|
||||
|
||||
virtual uint32_t
|
||||
GetPluginVersion();
|
||||
|
||||
virtual void
|
||||
GetPluginCommandHelp(const char *command, lldb_private::Stream *strm);
|
||||
|
||||
virtual lldb_private::Error
|
||||
ExecutePluginCommand(lldb_private::Args &command,
|
||||
lldb_private::Stream *strm);
|
||||
|
||||
virtual lldb_private::Log *
|
||||
EnablePluginLogging(lldb_private::Stream *strm,
|
||||
lldb_private::Args &command);
|
||||
|
||||
protected:
|
||||
typedef std::vector<Elf64_Phdr> ProgramHeaderColl;
|
||||
typedef ProgramHeaderColl::iterator ProgramHeaderCollIter;
|
||||
typedef ProgramHeaderColl::const_iterator ProgramHeaderCollConstIter;
|
||||
|
||||
typedef std::vector<Elf64_Shdr> SectionHeaderColl;
|
||||
typedef SectionHeaderColl::iterator SectionHeaderCollIter;
|
||||
typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
|
||||
|
||||
Elf64_Ehdr m_header;
|
||||
ProgramHeaderColl m_program_headers;
|
||||
SectionHeaderColl m_section_headers;
|
||||
mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
|
||||
mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
|
||||
mutable std::auto_ptr<lldb_private::FileSpecList> m_filespec_ap;
|
||||
lldb_private::DataExtractor m_shstr_data;
|
||||
|
||||
size_t
|
||||
ParseSections();
|
||||
|
||||
size_t
|
||||
ParseSymtab(bool minimize);
|
||||
|
||||
private:
|
||||
// Returns the 1 based index of a section header.
|
||||
unsigned
|
||||
SectionIndex(const SectionHeaderCollIter &I);
|
||||
|
||||
unsigned
|
||||
SectionIndex(const SectionHeaderCollConstIter &I) const;
|
||||
|
||||
// ELF header dump routines
|
||||
static void
|
||||
DumpELFHeader(lldb_private::Stream *s, const Elf64_Ehdr& header);
|
||||
|
||||
static void
|
||||
DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s,
|
||||
unsigned char ei_data);
|
||||
|
||||
static void
|
||||
DumpELFHeader_e_type(lldb_private::Stream *s, Elf64_Half e_type);
|
||||
|
||||
// ELF program header dump routines
|
||||
void
|
||||
DumpELFProgramHeaders(lldb_private::Stream *s);
|
||||
|
||||
static void
|
||||
DumpELFProgramHeader(lldb_private::Stream *s, const Elf64_Phdr &ph);
|
||||
|
||||
static void
|
||||
DumpELFProgramHeader_p_type(lldb_private::Stream *s, Elf64_Word p_type);
|
||||
|
||||
static void
|
||||
DumpELFProgramHeader_p_flags(lldb_private::Stream *s, Elf64_Word p_flags);
|
||||
|
||||
// ELF section header dump routines
|
||||
void
|
||||
DumpELFSectionHeaders(lldb_private::Stream *s);
|
||||
|
||||
static void
|
||||
DumpELFSectionHeader(lldb_private::Stream *s, const Elf64_Shdr& sh);
|
||||
|
||||
static void
|
||||
DumpELFSectionHeader_sh_type(lldb_private::Stream *s, Elf64_Word sh_type);
|
||||
|
||||
static void
|
||||
DumpELFSectionHeader_sh_flags(lldb_private::Stream *s, Elf64_Word sh_flags);
|
||||
|
||||
void
|
||||
DumpDependentModules(lldb_private::Stream *s);
|
||||
|
||||
size_t
|
||||
ParseProgramHeaders();
|
||||
|
||||
size_t
|
||||
ParseSectionHeaders();
|
||||
|
||||
size_t
|
||||
ParseDependentModules();
|
||||
|
||||
void
|
||||
ParseSymbolTable(lldb_private::Symtab *symbol_table,
|
||||
const Elf64_Shdr &symtab_section,
|
||||
lldb::user_id_t symtab_id);
|
||||
|
||||
size_t
|
||||
GetSectionHeaderStringTable();
|
||||
|
||||
uint32_t
|
||||
GetSectionIndexByName(const char *name);
|
||||
};
|
||||
|
||||
#endif // #ifndef liblldb_ObjectFileELF64_h_
|
|
@ -19,7 +19,6 @@
|
|||
#include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h"
|
||||
#include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h"
|
||||
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
|
||||
#include "Plugins/ObjectFile/ELF/ObjectFileELF64.h"
|
||||
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
|
||||
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h"
|
||||
#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
|
||||
|
@ -56,7 +55,6 @@ lldb_private::Initialize ()
|
|||
DisassemblerLLVM::Initialize();
|
||||
ObjectContainerBSDArchive::Initialize();
|
||||
ObjectFileELF::Initialize();
|
||||
ObjectFileELF64::Initialize();
|
||||
SymbolVendorMacOSX::Initialize();
|
||||
SymbolFileDWARF::Initialize();
|
||||
SymbolFileDWARFDebugMap::Initialize();
|
||||
|
@ -86,7 +84,6 @@ lldb_private::Terminate ()
|
|||
DisassemblerLLVM::Terminate();
|
||||
ObjectContainerBSDArchive::Terminate();
|
||||
ObjectFileELF::Terminate();
|
||||
ObjectFileELF64::Terminate();
|
||||
SymbolVendorMacOSX::Terminate();
|
||||
SymbolFileDWARF::Terminate();
|
||||
SymbolFileDWARFDebugMap::Terminate();
|
||||
|
|
Loading…
Reference in New Issue