xref: /netbsd-src/external/bsd/elftosb/dist/common/ELFSourceFile.h (revision 993229b6fea628ff8b1fa09146c80b0cfb2768eb)
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