/*
* File: StELFFile.h
*
* Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
* See included license file for license details.
*/
#if !defined(_StELFFile_h_)
#define _StELFFile_h_
//! Variations of the ARM ELF format.
typedef enum {
eARMVariant = 1, //!< Standard ARM ELF specification.
eGHSVariant, //!< Green Hills Software variant.
eGCCVariant //!< GNU Compiler Collection variant.
} ELFVariant_t;
//! Possible ARM ELF symbol types.
typedef enum {
eUnknownSymbol,
eARMSymbol,
eThumbSymbol,
eDataSymbol
} ARMSymbolType_t;
/*!
* \brief Parser for Executable and Linking Format (ELF) files.
*
* The stream passed into the constructor needs to stay open for the life
* of the object. This is because calls to getSectionDataAtIndex() and
* getSegmentDataAtIndex() read the data directly from the input stream.
*/
class StELFFile
{
public:
typedef std::vector<Elf32_Shdr>::const_iterator const_section_iterator;
typedef std::vector<Elf32_Phdr>::const_iterator const_segment_iterator;
//! \name File format variant
//@{
//! \brief Return the ELF format variant to which this file is set.
virtual ELFVariant_t ELFVariant() { return m_elfVariant; }
//! \brief Set the ELF format variation to either #eARMVariant or #eGHSVariant.
virtual void setELFVariant(ELFVariant_t variant) { m_elfVariant = variant; }
//@}
//! \name Sections
//! Methods pertaining to the object file's sections.
//@{
//! \brief Returns the number of sections in the file.
inline unsigned getSectionCount() const { return static_cast<unsigned>(m_sectionHeaders.size()); }
//! \brief Returns a reference to section number \a inIndex.
const Elf32_Shdr & getSectionAtIndex(unsigned inIndex) const;
//! \brief Returns the index of the section with the name \a inName.
unsigned getIndexOfSectionWithName(const std::string & inName);
//! \brief Returns the data for the section.
uint8_t * getSectionDataAtIndex(unsigned inIndex);
//! \brief Returns the data for the section.
uint8_t * getSectionData(const_section_iterator inSection);
//@}
//! \name Segments
//! Methods for accessing the file's program headers for segments.
//@{
//! \brief Returns the number of segments, or program headers, in the file.
inline unsigned getSegmentCount() const { return static_cast<unsigned>(m_programHeaders.size()); }
//! \brief Returns a reference to the given segment.
const Elf32_Phdr & getSegmentAtIndex(unsigned inIndex) const;
//! \brief Returns the data of the specified segment.
uint8_t * getSegmentDataAtIndex(unsigned inIndex);
//! \brief Returns the data of the specified segment.
uint8_t * getSegmentData(const_segment_iterator inSegment);
//@}
//! \name String table
//! Methods for accessing the string tables.
//@{
//! \brief Returns a string from the file's section name string table.
std::string getSectionNameAtIndex(unsigned inIndex);
//! \brief Returns a string from any string table in the object file.
std::string getStringAtIndex(unsigned inStringTableSectionIndex, unsigned inStringIndex);
//@}
//! \name Symbol table
//! Methods for accessing the object file's symbol table. Currently only
//! a single symbol table with the section name ".symtab" is supported.
//@{
//! \brief Returns the number of symbols in the default ".symtab" symbol table.
unsigned getSymbolCount();
//! \brief Returns the symbol with index \a inIndex.
const Elf32_Sym & getSymbolAtIndex(unsigned inIndex);
//! \brief Returns the section index of the string table containing symbol names.
unsigned getSymbolNameStringTableIndex() const;
//! \brief Returns the name of the symbol described by \a inSymbol.
std::string getSymbolName(const Elf32_Sym & inSymbol);
protected:
std::istream & m_stream; //!< The source stream for the ELF file.
ELFVariant_t m_elfVariant; //!< Variant of the ARM ELF format specification.
std::string m_name; //!< File name. (optional)
Elf32_Ehdr m_header; //!< The ELF file header.
std::vector<Elf32_Shdr> m_sectionHeaders; //!< All of the section headers.
std::vector<Elf32_Phdr> m_programHeaders; //!< All of the program headers.
unsigned m_symbolTableIndex; //!< Index of ".symtab" section, or #SHN_UNDEF if not present.
/*!
* Little structure containing information about cached section data.
*/
struct SectionDataInfo
{
uint8_t * m_data; //!< Pointer to section data.
unsigned m_size; //!< Section data size in bytes.
bool m_swapped; //!< Has this section been byte swapped yet? Used for symbol table.
};
typedef std::map<unsigned, SectionDataInfo> SectionDataMap;
SectionDataMap m_sectionDataCache; //!< Cached data of sections.
//! \brief Reads a section's data either from cache or from disk.
SectionDataInfo & getCachedSectionData(unsigned inSectionIndex);
//! \brief Reads the file, section, and program headers into memory.
void readFileHeaders();