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
15namespace elftosb
16{
17
18// Forward declaration
19class 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 */
34class DataSource
35{
36public:
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.
47		Segment(DataSource & source) : m_source(source) {}
48
49		//! \brief Destructor.
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.
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.
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.
120		inline void setPattern(const SizedIntegerValue & newPattern) { m_pattern = newPattern; }
121
122		//! \brief Return the fill pattern for the segment.
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
133public:
134	//! \brief Default constructor.
135	DataSource() : m_target(0) {}
136
137	//! \brief Destructor.
138	virtual ~DataSource() {}
139
140	//! \name Data target
141	//@{
142	//! \brief Sets the associated data target.
143	inline void setTarget(DataTarget * target) { m_target = target; }
144
145	//! \brief Gets the associated data target.
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
158protected:
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 */
171class PatternSource : public DataSource, public DataSource::PatternSegment
172{
173public:
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.
181	virtual unsigned getSegmentCount() { return 1; }
182
183	//! \brief Returns this object, as it is its own segment.
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 */
196class UnmappedDataSource : public DataSource, public DataSource::Segment
197{
198public:
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.
209	virtual unsigned getSegmentCount() { return 1; }
210
211	//! \brief Returns this object, as it is its own segment.
212	virtual DataSource::Segment * getSegmentAt(unsigned index) { return this; }
213
214	//! \name Segment methods
215	//@{
216	//! \brief Unmapped data sources have no natural address.
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.
223	virtual unsigned getLength() { return m_length; }
224	//@}
225
226protected:
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 */
236class MemoryImageDataSource : public DataSource
237{
238public:
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
251protected:
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
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
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
290protected:
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