1 /*
2  * File:  ELFSourceFile.h
3  *
4  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5  * See included license file for license details.
6  */
7 #if !defined(_ELFSourceFile_h_)
8 #define _ELFSourceFile_h_
9 
10 #include "SourceFile.h"
11 #include "StELFFile.h"
12 #include "smart_ptr.h"
13 #include "DataSource.h"
14 #include "DataTarget.h"
15 #include "ELF.h"
16 
17 namespace elftosb
18 {
19 
20 //! Set of supported compiler toolsets.
21 enum elf_toolset_t
22 {
23           kUnknownToolset,    //!< Unknown.
24           kGHSToolset,                  //!< Green Hills Software MULTI
25           kGCCToolset,                  //!< GNU GCC
26           kADSToolset                             //!< ARM UK RealView
27 };
28 
29 //! Options for handling the .secinfo section in GHS-produced ELF files.
30 enum secinfo_clear_t
31 {
32           // Default value for the .secinfo action.
33           kSecinfoDefault,
34 
35           //! Ignore the .secinfo section if present. The standard ELF loading
36           //! rules are followed.
37           kSecinfoIgnore,
38 
39           //! The boot ROM clears only those SHT_NOBITS sections present in .secinfo.
40           kSecinfoROMClear,
41 
42           //! The C startup is responsible for clearing sections. No fill commands
43           //! are generated for any SHT_NOBITS sections.
44           kSecinfoCStartupClear
45 };
46 
47 /*!
48  * \brief Executable and Loading Format (ELF) source file.
49  */
50 class ELFSourceFile : public SourceFile
51 {
52 public:
53           //! \brief Default constructor.
54           ELFSourceFile(const std::string & path);
55 
56           //! \brief Destructor.
57           virtual ~ELFSourceFile();
58 
59           //! \brief Identifies whether the stream contains an ELF file.
60           static bool isELFFile(std::istream & stream);
61 
62           //! \name Opening and closing
63           //@{
64           //! \brief Opens the file.
65           virtual void open();
66 
67           //! \brief Closes the file.
68           virtual void close();
69           //@}
70 
71           //! \name Format capabilities
72           //@{
supportsNamedSections()73           virtual bool supportsNamedSections() const { return true; }
supportsNamedSymbols()74           virtual bool supportsNamedSymbols() const { return true; }
75           //@}
76 
77           //! \name Data source
78           //@{
79           //! \brief Creates a data source from the entire file.
80           virtual DataSource * createDataSource();
81 
82           //! \brief Creates a data source from one or more sections of the file.
83           virtual DataSource * createDataSource(StringMatcher & matcher);
84           //@}
85 
86           //! \name Entry point
87           //@{
88           //! \brief Returns true if an entry point was set in the file.
89           virtual bool hasEntryPoint();
90 
91           //! \brief Returns the entry point address.
92           virtual uint32_t getEntryPointAddress();
93           //@}
94 
95           //! \name Data target
96           //@{
97           virtual DataTarget * createDataTargetForSection(const std::string & section);
98           virtual DataTarget * createDataTargetForSymbol(const std::string & symbol);
99           //@}
100 
101           //! \name Symbols
102           //@{
103           //! \brief Returns whether a symbol exists in the source file.
104           virtual bool hasSymbol(const std::string & name);
105 
106           //! \brief Returns the value of a symbol.
107           virtual uint32_t getSymbolValue(const std::string & name);
108 
109           //! \brief Returns the size of a symbol.
110           virtual unsigned getSymbolSize(const std::string & name);
111           //@}
112 
113           //! \name Direct ELF format access
114           //@{
115           //! \brief Returns the underlying StELFFile object.
getELFFile()116           StELFFile * getELFFile() { return m_file; }
117 
118           //! \brief Gets information about a symbol in the ELF file.
119           bool lookupSymbol(const std::string & name, Elf32_Sym & info);
120           //@}
121 
122 protected:
123           smart_ptr<StELFFile> m_file;  //!< Parser for the ELF file.
124           elf_toolset_t m_toolset;      //!< Toolset that produced the ELF file.
125           secinfo_clear_t m_secinfoOption;        //!< How to deal with the .secinfo section. Ignored if the toolset is not GHS.
126 
127 protected:
128           //! \brief Parses the toolset option value.
129           elf_toolset_t readToolsetOption();
130 
131           //! \brief Reads the secinfoClear option.
132           secinfo_clear_t readSecinfoClearOption();
133 
134 protected:
135           /*!
136            * \brief A data source with ELF file sections as the contents.
137            *
138            * Each segment of this data source corresponds directly with a named section
139            * of the ELF file it represents. When the data source is created, it contains
140            * no segments. Segments are created with the addSection() method, which takes
141            * the index of an ELF section and creates a corresponding segment.
142            *
143            * Two segment subclasses are used with this data source. The first, ProgBitsSegment,
144            * is used to represent sections whose type is #SHT_PROGBITS. These sections have
145            * binary data stored in the ELF file. The second segment type is NoBitsSegment.
146            * It is used to represent sections whose type is #SHT_NOBITS. These sections have
147            * no data, but simply allocate a region of memory to be filled with zeroes.
148            * As such, the NoBitsSegment class is a subclass of DataSource::PatternSegment.
149            */
150           class ELFDataSource : public DataSource
151           {
152           public:
153                     /*!
154                      * \brief Represents one named #SHT_PROGBITS section within the ELF file.
155                      */
156                     class ProgBitsSegment : public DataSource::Segment
157                     {
158                     public:
159                               ProgBitsSegment(ELFDataSource & source, StELFFile * elf, unsigned index);
160 
161                               virtual unsigned getData(unsigned offset, unsigned maxBytes, uint8_t * buffer);
162                               virtual unsigned getLength();
163 
hasNaturalLocation()164                               virtual bool hasNaturalLocation() { return true; }
165                               virtual uint32_t getBaseAddress();
166 
167                     protected:
168                               StELFFile * m_elf;  //!< The format parser instance for this ELF file.
169                               unsigned m_sectionIndex;      //!< The index of the section this segment represents.
170                     };
171 
172                     /*!
173                      * \brief Represents one named #SHT_NOBITS section within the ELF file.
174                      *
175                      * This segment class is a subclass of DataSource::PatternSegment since it
176                      * represents a region of memory to be filled with zeroes.
177                      */
178                     class NoBitsSegment : public DataSource::PatternSegment
179                     {
180                     public:
181                               NoBitsSegment(ELFDataSource & source, StELFFile * elf, unsigned index);
182 
183                               virtual unsigned getLength();
184 
hasNaturalLocation()185                               virtual bool hasNaturalLocation() { return true; }
186                               virtual uint32_t getBaseAddress();
187 
188                     protected:
189                               StELFFile * m_elf;  //!< The format parser instance for this ELF file.
190                               unsigned m_sectionIndex;      //!< The index of the section this segment represents.
191                     };
192 
193           public:
194                     //! \brief Default constructor.
ELFDataSource(StELFFile * elf)195                     ELFDataSource(StELFFile * elf) : DataSource(), m_elf(elf) {}
196 
197                     //! \brief Destructor.
198                     virtual ~ELFDataSource();
199 
200                     //! Set the option to control .secinfo usage.
setSecinfoOption(secinfo_clear_t option)201                     inline void setSecinfoOption(secinfo_clear_t option) { m_secinfoOption = option; }
202 
203                     //! \brief Adds the ELF section at position \a sectionIndex to the data source.
204                     void addSection(unsigned sectionIndex);
205 
206                     //! \brief Returns the number of segments in the source.
getSegmentCount()207                     virtual unsigned getSegmentCount() { return (unsigned)m_segments.size(); }
208 
209                     //! \brief Returns the segment at position \a index.
getSegmentAt(unsigned index)210                     virtual DataSource::Segment * getSegmentAt(unsigned index) { return m_segments[index]; }
211 
212           protected:
213                     StELFFile * m_elf;  //!< The ELF file parser.
214                     secinfo_clear_t m_secinfoOption;        //!< How to deal with the .secinfo section. Ignored if the toolset is not GHS.
215 
216                     typedef std::vector<DataSource::Segment*> segment_vector_t; //!< A list of segment instances.
217                     segment_vector_t m_segments;  //!< The segments of this data source.
218           };
219 
220 };
221 
222 }; // namespace elftosb
223 
224 #endif // _ELFSourceFile_h_
225