xref: /netbsd-src/external/bsd/elftosb/dist/common/DataSource.h (revision 993229b6fea628ff8b1fa09146c80b0cfb2768eb)
1 /*
2  * File:	DataSource.h
3  *
4  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5  * See included license file for license details.
6  */
7 #if !defined(_DataSource_h_)
8 #define _DataSource_h_
9 
10 #include <vector>
11 #include "Value.h"
12 #include "smart_ptr.h"
13 #include "StExecutableImage.h"
14 
15 namespace elftosb
16 {
17 
18 // Forward declaration
19 class DataTarget;
20 
21 /*!
22  * \brief Abstract base class for data sources.
23  *
24  * Data sources represent any sort of data that can be placed or loaded
25  * into a target region. Sources may be a single blob of data read from
26  * a file or may consist of many segments.
27  *
28  * The three most important features of data sources are:
29  * - Sources may be multi-segmented.
30  * - Sources and/or segments can have a "natural" or default target location.
31  * - The target for a source may be taken into consideration when the source
32  *		describes itself.
33  */
34 class DataSource
35 {
36 public:
37 	/*!
38 	 * \brief Discrete, contiguous part of the source's data.
39 	 *
40 	 * This class is purely abstract and subclasses of DataSource are expected
41 	 * to subclass it to implement a segment particular to their needs.
42 	 */
43 	class Segment
44 	{
45 	public:
46 		//! \brief Default constructor.
Segment(DataSource & source)47 		Segment(DataSource & source) : m_source(source) {}
48 
49 		//! \brief Destructor.
~Segment()50 		virtual ~Segment() {}
51 
52 		//! \brief Gets all or a portion of the segment's data.
53 		//!
54 		//! The data is copied into \a buffer. Up to \a maxBytes bytes may be
55 		//! copied, so \a buffer must be at least that large.
56 		//!
57 		//! \param offset Index of the first byte to start copying from.
58 		//! \param maxBytes The maximum number of bytes that can be returned. \a buffer
59 		//!		must be at least this large.
60 		//! \param buffer Pointer to buffer where the data is copied.
61 		//! \return The number of bytes copied into \a buffer.
62 		virtual unsigned getData(unsigned offset, unsigned maxBytes, uint8_t * buffer)=0;
63 
64 		//! \brief Gets the length of the segment's data.
65 		virtual unsigned getLength()=0;
66 
67 		//! \brief Returns whether the segment has an associated address.
68 		virtual bool hasNaturalLocation()=0;
69 
70 		//! \brief Returns the address associated with the segment.
getBaseAddress()71 		virtual uint32_t getBaseAddress() { return 0; }
72 
73 	protected:
74 		DataSource & m_source;	//!< The data source to which this segment belongs.
75 	};
76 
77 	/*!
78 	 * \brief This is a special type of segment containing a repeating pattern.
79 	 *
80 	 * By default the segment doesn't have a specific length or data. The length depends
81 	 * on the target's address range. And the data is just the pattern, repeated
82 	 * many times. In addition, pattern segments do not have a natural location.
83 	 *
84 	 * Calling code should look for instances of PatternSegment and handle them
85 	 * as special cases that can be optimized.
86 	 */
87 	class PatternSegment : public Segment
88 	{
89 	public:
90 		//! \brief Default constructor.
91 		PatternSegment(DataSource & source);
92 
93 		//! \brief Constructor taking a fill pattern.
94 		PatternSegment(DataSource & source, const SizedIntegerValue & pattern);
95 
96 		//! \brief Constructor taking a byte fill pattern.
97 		PatternSegment(DataSource & source, uint8_t pattern);
98 
99 		//! \brief Constructor taking a half-word fill pattern.
100 		PatternSegment(DataSource & source, uint16_t pattern);
101 
102 		//! \brief Constructor taking a word fill pattern.
103 		PatternSegment(DataSource & source, uint32_t pattern);
104 
105 		//! \name Segment methods
106 		//@{
107 		//! \brief Pattern segments have no natural address.
hasNaturalLocation()108 		virtual bool hasNaturalLocation() { return false; }
109 
110 		//! \brief Performs a pattern fill into the \a buffer.
111 		virtual unsigned getData(unsigned offset, unsigned maxBytes, uint8_t * buffer);
112 
113 		//! \brief Returns a length based on the data target's address range.
114 		virtual unsigned getLength();
115 		//@}
116 
117 		//! \name Pattern accessors
118 		//@{
119 		//! \brief Assigns a new fill pattern.
setPattern(const SizedIntegerValue & newPattern)120 		inline void setPattern(const SizedIntegerValue & newPattern) { m_pattern = newPattern; }
121 
122 		//! \brief Return the fill pattern for the segment.
getPattern()123 		inline SizedIntegerValue & getPattern() { return m_pattern; }
124 
125 		//! \brief Assignment operator, sets the pattern value and length.
126 		PatternSegment & operator = (const SizedIntegerValue & value) { m_pattern = value; return *this; }
127 		//@}
128 
129 	protected:
130 		SizedIntegerValue m_pattern;	//!< The fill pattern.
131 	};
132 
133 public:
134 	//! \brief Default constructor.
DataSource()135 	DataSource() : m_target(0) {}
136 
137 	//! \brief Destructor.
~DataSource()138 	virtual ~DataSource() {}
139 
140 	//! \name Data target
141 	//@{
142 	//! \brief Sets the associated data target.
setTarget(DataTarget * target)143 	inline void setTarget(DataTarget * target) { m_target = target; }
144 
145 	//! \brief Gets the associated data target.
getTarget()146 	inline DataTarget * getTarget() const { return m_target; }
147 	//@}
148 
149 	//! \name Segments
150 	//@{
151 	//! \brief Returns the number of segments in this data source.
152 	virtual unsigned getSegmentCount()=0;
153 
154 	//! \brief Returns segment number \a index of the data source.
155 	virtual Segment * getSegmentAt(unsigned index)=0;
156 	//@}
157 
158 protected:
159 	DataTarget * m_target;	//!< Corresponding target for this source.
160 };
161 
162 /*!
163  * \brief Data source for a repeating pattern.
164  *
165  * The pattern is represented by a SizedIntegerValue object. Thus the pattern
166  * can be either byte, half-word, or word sized.
167  *
168  * This data source has only one segment, and the PatternSource instance acts
169  * as its own single segment.
170  */
171 class PatternSource : public DataSource, public DataSource::PatternSegment
172 {
173 public:
174 	//! \brief Default constructor.
175 	PatternSource();
176 
177 	//! \brief Constructor taking the pattern value.
178 	PatternSource(const SizedIntegerValue & value);
179 
180 	//! \brief There is only one segment.
getSegmentCount()181 	virtual unsigned getSegmentCount() { return 1; }
182 
183 	//! \brief Returns this object, as it is its own segment.
getSegmentAt(unsigned index)184 	virtual DataSource::Segment * getSegmentAt(unsigned index) { return this; }
185 
186 	//! \brief Assignment operator, sets the pattern value and length.
187 	PatternSource & operator = (const SizedIntegerValue & value) { setPattern(value); return *this; }
188 };
189 
190 /*!
191  * \brief Data source for data that is not memory mapped (has no natural address).
192  *
193  * This data source can only manage a single block of data, which has no
194  * associated address. It acts as its own Segment.
195  */
196 class UnmappedDataSource : public DataSource, public DataSource::Segment
197 {
198 public:
199 	//! \brief Default constructor.
200 	UnmappedDataSource();
201 
202 	//! \brief Constructor taking the data, which is copied.
203 	UnmappedDataSource(const uint8_t * data, unsigned length);
204 
205 	//! \brief Sets the source's data.
206 	void setData(const uint8_t * data, unsigned length);
207 
208 	//! \brief There is only one segment.
getSegmentCount()209 	virtual unsigned getSegmentCount() { return 1; }
210 
211 	//! \brief Returns this object, as it is its own segment.
getSegmentAt(unsigned index)212 	virtual DataSource::Segment * getSegmentAt(unsigned index) { return this; }
213 
214 	//! \name Segment methods
215 	//@{
216 	//! \brief Unmapped data sources have no natural address.
hasNaturalLocation()217 	virtual bool hasNaturalLocation() { return false; }
218 
219 	//! \brief Copies a portion of the data into \a buffer.
220 	virtual unsigned getData(unsigned offset, unsigned maxBytes, uint8_t * buffer);
221 
222 	//! \brief Returns the number of bytes of data managed by the source.
getLength()223 	virtual unsigned getLength() { return m_length; }
224 	//@}
225 
226 protected:
227 	smart_array_ptr<uint8_t> m_data;	//!< The data.
228 	unsigned m_length;	//!< Byte count of the data.
229 };
230 
231 /*!
232  * \brief Data source that takes its data from an executable image.
233  *
234  * \see StExecutableImage
235  */
236 class MemoryImageDataSource : public DataSource
237 {
238 public:
239 	//! \brief Default constructor.
240 	MemoryImageDataSource(StExecutableImage * image);
241 
242 	//! \brief Destructor.
243 	virtual ~MemoryImageDataSource();
244 
245 	//! \brief Returns the number of memory regions in the image.
246 	virtual unsigned getSegmentCount();
247 
248 	//! \brief Returns the data source segment at position \a index.
249 	virtual DataSource::Segment * getSegmentAt(unsigned index);
250 
251 protected:
252 	/*!
253 	 * \brief Segment corresponding to a text region of the executable image.
254 	 */
255 	class TextSegment : public DataSource::Segment
256 	{
257 	public:
258 		//! \brief Default constructor
259 		TextSegment(MemoryImageDataSource & source, StExecutableImage * image, unsigned index);
260 
261 		virtual unsigned getData(unsigned offset, unsigned maxBytes, uint8_t * buffer);
262 		virtual unsigned getLength();
263 
hasNaturalLocation()264 		virtual bool hasNaturalLocation() { return true; }
265 		virtual uint32_t getBaseAddress();
266 
267 	protected:
268 		StExecutableImage * m_image;	//!< Coalesced image of the file.
269 		unsigned m_index;	//!< Record index.
270 	};
271 
272 	/*!
273 	 * \brief Segment corresponding to a fill region of the executable image.
274 	 */
275 	class FillSegment : public DataSource::PatternSegment
276 	{
277 	public:
278 		FillSegment(MemoryImageDataSource & source, StExecutableImage * image, unsigned index);
279 
280 		virtual unsigned getLength();
281 
hasNaturalLocation()282 		virtual bool hasNaturalLocation() { return true; }
283 		virtual uint32_t getBaseAddress();
284 
285 	protected:
286 		StExecutableImage * m_image;	//!< Coalesced image of the file.
287 		unsigned m_index;	//!< Record index.
288 	};
289 
290 protected:
291 	StExecutableImage * m_image;	//!< The memory image that is the data source.
292 
293 	typedef std::vector<DataSource::Segment*> segment_array_t;	//!< An array of segments.
294 	segment_array_t m_segments;	//!< The array of Segment instances.
295 };
296 
297 }; // namespace elftosb
298 
299 #endif // _DataSource_h_
300