summaryrefslogtreecommitdiffstats
path: root/common/ELFSourceFile.h
blob: c07aa56601bfe9a65d0fdbd675abdeb7c02aaa7f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/*
 * File:	ELFSourceFile.h
 *
 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
 * See included license file for license details.
 */
#if !defined(_ELFSourceFile_h_)
#define _ELFSourceFile_h_

#include "SourceFile.h"
#include "StELFFile.h"
#include "smart_ptr.h"
#include "DataSource.h"
#include "DataTarget.h"
#include "ELF.h"

namespace elftosb
{

//! Set of supported compiler toolsets.
enum elf_toolset_t
{
	kUnknownToolset,	//!< Unknown.
	kGHSToolset,		//!< Green Hills Software MULTI
	kGCCToolset,		//!< GNU GCC
	kADSToolset			//!< ARM UK RealView
};

//! Options for handling the .secinfo section in GHS-produced ELF files.
enum secinfo_clear_t
{
	// Default value for the .secinfo action.
	kSecinfoDefault,

	//! Ignore the .secinfo section if present. The standard ELF loading
	//! rules are followed.
	kSecinfoIgnore,

	//! The boot ROM clears only those SHT_NOBITS sections present in .secinfo.
	kSecinfoROMClear,
	
	//! The C startup is responsible for clearing sections. No fill commands
	//! are generated for any SHT_NOBITS sections.
	kSecinfoCStartupClear
};

/*!
 * \brief Executable and Loading Format (ELF) source file.
 */
class ELFSourceFile : public SourceFile
{
public:
	//! \brief Default constructor.
	ELFSourceFile(const std::string & path);
	
	//! \brief Destructor.
	virtual ~ELFSourceFile();
	
	//! \brief Identifies whether the stream contains an ELF file.
	static bool isELFFile(std::istream & stream);
	
	//! \name Opening and closing
	//@{
	//! \brief Opens the file.
	virtual void open();
	
	//! \brief Closes the file.
	virtual void close();
	//@}
	
	//! \name Format capabilities
	//@{
	virtual bool supportsNamedSections() const { return true; }
	virtual bool supportsNamedSymbols() const { return true; }
	//@}
	
	//! \name Data source
	//@{
	//! \brief Creates a data source from the entire file.
	virtual DataSource * createDataSource();
	
	//! \brief Creates a data source from one or more sections of the file.
	virtual DataSource * createDataSource(StringMatcher & matcher);
	//@}
	
	//! \name Entry point
	//@{
	//! \brief Returns true if an entry point was set in the file.
	virtual bool hasEntryPoint();
	
	//! \brief Returns the entry point address.
	virtual uint32_t getEntryPointAddress();
	//@}
	
	//! \name Data target
	//@{
	virtual DataTarget * createDataTargetForSection(const std::string & section);
	virtual DataTarget * createDataTargetForSymbol(const std::string & symbol);
	//@}
	
	//! \name Symbols
	//@{
	//! \brief Returns whether a symbol exists in the source file.
	virtual bool hasSymbol(const std::string & name);
	
	//! \brief Returns the value of a symbol.
	virtual uint32_t getSymbolValue(const std::string & name);
	
	//! \brief Returns the size of a symbol.
	virtual unsigned getSymbolSize(const std::string & name);
	//@}
	
	//! \name Direct ELF format access
	//@{
	//! \brief Returns the underlying StELFFile object.
	StELFFile * getELFFile() { return m_file; }
	
	//! \brief Gets information about a symbol in the ELF file.
	bool lookupSymbol(const std::string & name, Elf32_Sym & info);
	//@}

protected:
	smart_ptr<StELFFile> m_file;	//!< Parser for the ELF file.
	elf_toolset_t m_toolset;	//!< Toolset that produced the ELF file.
	secinfo_clear_t m_secinfoOption;	//!< How to deal with the .secinfo section. Ignored if the toolset is not GHS.

protected:
	//! \brief Parses the toolset option value.
	elf_toolset_t readToolsetOption();

	//! \brief Reads the secinfoClear option.
	secinfo_clear_t readSecinfoClearOption();
	
protected:
	/*!
	 * \brief A data source with ELF file sections as the contents.
	 *
	 * Each segment of this data source corresponds directly with a named section
	 * of the ELF file it represents. When the data source is created, it contains
	 * no segments. Segments are created with the addSection() method, which takes
	 * the index of an ELF section and creates a corresponding segment.
	 *
	 * Two segment subclasses are used with this data source. The first, ProgBitsSegment,
	 * is used to represent sections whose type is #SHT_PROGBITS. These sections have
	 * binary data stored in the ELF file. The second segment type is NoBitsSegment.
	 * It is used to represent sections whose type is #SHT_NOBITS. These sections have
	 * no data, but simply allocate a region of memory to be filled with zeroes.
	 * As such, the NoBitsSegment class is a subclass of DataSource::PatternSegment.
	 */
	class ELFDataSource : public DataSource
	{
	public:
		/*!
		 * \brief Represents one named #SHT_PROGBITS section within the ELF file.
		 */
		class ProgBitsSegment : public DataSource::Segment
		{
		public:
			ProgBitsSegment(ELFDataSource & source, StELFFile * elf, unsigned index);
			
			virtual unsigned getData(unsigned offset, unsigned maxBytes, uint8_t * buffer);
			virtual unsigned getLength();
		
			virtual bool hasNaturalLocation() { return true; }
			virtual uint32_t getBaseAddress();
		
		protected:
			StELFFile * m_elf;	//!< The format parser instance for this ELF file.
			unsigned m_sectionIndex;	//!< The index of the section this segment represents.
		};
		
		/*!
		 * \brief Represents one named #SHT_NOBITS section within the ELF file.
		 *
		 * This segment class is a subclass of DataSource::PatternSegment since it
		 * represents a region of memory to be filled with zeroes.
		 */
		class NoBitsSegment : public DataSource::PatternSegment
		{
		public:
			NoBitsSegment(ELFDataSource & source, StELFFile * elf, unsigned index);
			
			virtual unsigned getLength();
		
			virtual bool hasNaturalLocation() { return true; }
			virtual uint32_t getBaseAddress();
		
		protected:
			StELFFile * m_elf;	//!< The format parser instance for this ELF file.
			unsigned m_sectionIndex;	//!< The index of the section this segment represents.
		};
		
	public:
		//! \brief Default constructor.
		ELFDataSource(StELFFile * elf) : DataSource(), m_elf(elf) {}
		
		//! \brief Destructor.
		virtual ~ELFDataSource();

		//! Set the option to control .secinfo usage.
		inline void setSecinfoOption(secinfo_clear_t option) { m_secinfoOption = option; }
		
		//! \brief Adds the ELF section at position \a sectionIndex to the data source.
		void addSection(unsigned sectionIndex);
		
		//! \brief Returns the number of segments in the source.
		virtual unsigned getSegmentCount() { return (unsigned)m_segments.size(); }
		
		//! \brief Returns the segment at position \a index.
		virtual DataSource::Segment * getSegmentAt(unsigned index) { return m_segments[index]; }
		
	protected:
		StELFFile * m_elf;	//!< The ELF file parser.
		secinfo_clear_t m_secinfoOption;	//!< How to deal with the .secinfo section. Ignored if the toolset is not GHS.
		
		typedef std::vector<DataSource::Segment*> segment_vector_t;	//!< A list of segment instances.
		segment_vector_t m_segments;	//!< The segments of this data source.
	};

};

}; // namespace elftosb

#endif // _ELFSourceFile_h_