]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - tools/elftosb/common/StELFFile.h
merged tx6dl-devel into denx master branch
[karo-tx-uboot.git] / tools / elftosb / common / StELFFile.h
1 /*
2  * File:        StELFFile.h
3  *
4  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5  * See included license file for license details.
6  */
7 #if !defined(_StELFFile_h_)
8 #define _StELFFile_h_
9
10 #include "stdafx.h"
11 #include <string>
12 #include <vector>
13 #include <map>
14 #include <iostream>
15 #include <stdexcept>
16 #include "ELF.h"
17
18 //! Variations of the ARM ELF format.
19 typedef enum {
20         eARMVariant = 1,        //!< Standard ARM ELF specification.
21         eGHSVariant,            //!< Green Hills Software variant.
22         eGCCVariant             //!< GNU Compiler Collection variant.
23 } ELFVariant_t;
24
25 //! Possible ARM ELF symbol types.
26 typedef enum {
27         eUnknownSymbol,
28         eARMSymbol,
29         eThumbSymbol,
30         eDataSymbol
31 } ARMSymbolType_t;
32
33 /*!
34  * \brief Parser for Executable and Linking Format (ELF) files.
35  *
36  * The stream passed into the constructor needs to stay open for the life
37  * of the object. This is because calls to getSectionDataAtIndex() and
38  * getSegmentDataAtIndex() read the data directly from the input stream.
39  */
40 class StELFFile
41 {
42 public:
43         typedef std::vector<Elf32_Shdr>::const_iterator const_section_iterator;
44         typedef std::vector<Elf32_Phdr>::const_iterator const_segment_iterator;
45         
46 public:
47         //! \brief Constructor.
48         StELFFile(std::istream & inStream);
49         
50         //! \brief Destructor.
51         virtual ~StELFFile();
52         
53         //! \name File format variant
54         //@{
55         //! \brief Return the ELF format variant to which this file is set.
56         virtual ELFVariant_t ELFVariant() { return m_elfVariant; }
57         
58         //! \brief Set the ELF format variation to either #eARMVariant or #eGHSVariant.
59         virtual void setELFVariant(ELFVariant_t variant) { m_elfVariant = variant; }
60         //@}
61         
62         //! \name File name
63         //@{
64         virtual void setName(const std::string & inName) { m_name = inName; }
65         virtual std::string getName() const { return m_name; }
66         //@}
67         
68         //! \name ELF header
69         //@{
70         //! \brief Returns the ELF file header.
71         inline const Elf32_Ehdr & getFileHeader() const { return m_header; }
72         //@}
73         
74         //! \name Sections
75         //! Methods pertaining to the object file's sections.
76         //@{
77         //! \brief Returns the number of sections in the file.
78         inline unsigned getSectionCount() const { return static_cast<unsigned>(m_sectionHeaders.size()); }
79         
80         //! \brief Returns a reference to section number \a inIndex.
81         const Elf32_Shdr & getSectionAtIndex(unsigned inIndex) const;
82         
83         inline const_section_iterator getSectionBegin() const { return m_sectionHeaders.begin(); }
84         inline const_section_iterator getSectionEnd() const { return m_sectionHeaders.end(); }
85         
86         //! \brief Returns the index of the section with the name \a inName.
87         unsigned getIndexOfSectionWithName(const std::string & inName);
88         
89         //! \brief Returns the data for the section.
90         uint8_t * getSectionDataAtIndex(unsigned inIndex);
91         
92         //! \brief Returns the data for the section.
93         uint8_t * getSectionData(const_section_iterator inSection);
94         //@}
95         
96         //! \name Segments
97         //! Methods for accessing the file's program headers for segments.
98         //@{
99         //! \brief Returns the number of segments, or program headers, in the file.
100         inline unsigned getSegmentCount() const { return static_cast<unsigned>(m_programHeaders.size()); }
101         
102         //! \brief Returns a reference to the given segment.
103         const Elf32_Phdr & getSegmentAtIndex(unsigned inIndex) const;
104
105         inline const_segment_iterator getSegmentBegin() const { return m_programHeaders.begin(); }
106         inline const_segment_iterator getSegmentEnd() const { return m_programHeaders.end(); }
107         
108         //! \brief Returns the data of the specified segment.
109         uint8_t * getSegmentDataAtIndex(unsigned inIndex);
110         
111         //! \brief Returns the data of the specified segment.
112         uint8_t * getSegmentData(const_segment_iterator inSegment);
113         //@}
114         
115         //! \name String table
116         //! Methods for accessing the string tables.
117         //@{
118         //! \brief Returns a string from the file's section name string table.
119         std::string getSectionNameAtIndex(unsigned inIndex);
120         
121         //! \brief Returns a string from any string table in the object file.
122         std::string getStringAtIndex(unsigned inStringTableSectionIndex, unsigned inStringIndex);
123         //@}
124         
125         //! \name Symbol table
126         //! Methods for accessing the object file's symbol table. Currently only
127         //! a single symbol table with the section name ".symtab" is supported.
128         //@{
129         //! \brief Returns the number of symbols in the default ".symtab" symbol table.
130         unsigned getSymbolCount();
131         
132         //! \brief Returns the symbol with index \a inIndex.
133         const Elf32_Sym & getSymbolAtIndex(unsigned inIndex);
134         
135         //! \brief Returns the section index of the string table containing symbol names.
136         unsigned getSymbolNameStringTableIndex() const;
137         
138         //! \brief Returns the name of the symbol described by \a inSymbol.
139         std::string getSymbolName(const Elf32_Sym & inSymbol);
140         
141         unsigned getIndexOfSymbolAtAddress(uint32_t symbolAddress, bool strict=true);
142         
143         ARMSymbolType_t getTypeOfSymbolAtIndex(unsigned symbolIndex);
144         //@}
145         
146         //! \name Debugging
147         //@{
148         void dumpSections();
149         void dumpSymbolTable();
150         //@}
151
152 protected:
153         std::istream & m_stream;        //!< The source stream for the ELF file.
154         ELFVariant_t m_elfVariant;      //!< Variant of the ARM ELF format specification.
155         std::string m_name;                     //!< File name. (optional)
156         Elf32_Ehdr m_header;    //!< The ELF file header.
157         std::vector<Elf32_Shdr> m_sectionHeaders;       //!< All of the section headers.
158         std::vector<Elf32_Phdr> m_programHeaders;       //!< All of the program headers.
159         unsigned m_symbolTableIndex;    //!< Index of ".symtab" section, or #SHN_UNDEF if not present.
160         
161         /*!
162          * Little structure containing information about cached section data.
163          */
164         struct SectionDataInfo
165         {
166                 uint8_t * m_data;       //!< Pointer to section data.
167                 unsigned m_size;        //!< Section data size in bytes.
168                 bool m_swapped; //!< Has this section been byte swapped yet? Used for symbol table.
169         };
170         typedef std::map<unsigned, SectionDataInfo> SectionDataMap;
171         SectionDataMap m_sectionDataCache;      //!< Cached data of sections.
172         
173         //! \brief Reads a section's data either from cache or from disk.
174         SectionDataInfo & getCachedSectionData(unsigned inSectionIndex);
175         
176         //! \brief Reads the file, section, and program headers into memory.
177         void readFileHeaders();
178         
179         uint8_t * readSectionData(const Elf32_Shdr & inHeader);
180         uint8_t * readSegmentData(const Elf32_Phdr & inHeader);
181         
182         //! \brief Byte swaps the symbol table data into host endianness.
183         void byteSwapSymbolTable(const Elf32_Shdr & header, SectionDataInfo & info);
184 };
185
186 /*!
187  * \brief Simple exception thrown to indicate an error in the input ELF file format.
188  */
189 class StELFFileException : public std::runtime_error
190 {
191 public:
192         //! \brief Default constructor.
193         StELFFileException(const std::string & inMessage) : std::runtime_error(inMessage) {}
194 };
195
196 #endif // _StELFFile_h_