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