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