Home | History | Annotate | Line # | Download | only in common
      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.
     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 
    133 public:
    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 
    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.
    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  */
    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.
    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 
    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 
    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 
    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