]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - tools/elftosb/common/DataSource.h
merged tx6dl-devel into denx master branch
[karo-tx-uboot.git] / tools / elftosb / common / DataSource.h
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_