4 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5 * See included license file for license details.
8 #include "DataSource.h"
9 #include "DataTarget.h"
12 using namespace elftosb;
14 #pragma mark *** DataSource::PatternSegment ***
16 DataSource::PatternSegment::PatternSegment(DataSource & source)
17 : DataSource::Segment(source), m_pattern()
21 DataSource::PatternSegment::PatternSegment(DataSource & source, const SizedIntegerValue & pattern)
22 : DataSource::Segment(source), m_pattern(pattern)
26 DataSource::PatternSegment::PatternSegment(DataSource & source, uint8_t pattern)
27 : DataSource::Segment(source), m_pattern(static_cast<uint8_t>(pattern))
31 DataSource::PatternSegment::PatternSegment(DataSource & source, uint16_t pattern)
32 : DataSource::Segment(source), m_pattern(static_cast<uint16_t>(pattern))
36 DataSource::PatternSegment::PatternSegment(DataSource & source, uint32_t pattern)
37 : DataSource::Segment(source), m_pattern(static_cast<uint32_t>(pattern))
41 unsigned DataSource::PatternSegment::getData(unsigned offset, unsigned maxBytes, uint8_t * buffer)
43 memset(buffer, 0, maxBytes);
48 //! The pattern segment's length is a function of the data target. If the
49 //! target is bounded, then the segment's length is simply the target's
50 //! length. Otherwise, if no target has been set or the target is unbounded,
51 //! then the length returned is 0.
52 unsigned DataSource::PatternSegment::getLength()
54 DataTarget * target = m_source.getTarget();
61 if (target->isBounded())
63 length = target->getEndAddress() - target->getBeginAddress();
67 length = m_pattern.getSize();
72 #pragma mark *** PatternSource ***
74 PatternSource::PatternSource()
75 : DataSource(), DataSource::PatternSegment((DataSource&)*this)
79 PatternSource::PatternSource(const SizedIntegerValue & value)
80 : DataSource(), DataSource::PatternSegment((DataSource&)*this, value)
84 #pragma mark *** UnmappedDataSource ***
86 UnmappedDataSource::UnmappedDataSource()
87 : DataSource(), DataSource::Segment((DataSource&)*this), m_data(), m_length(0)
91 UnmappedDataSource::UnmappedDataSource(const uint8_t * data, unsigned length)
92 : DataSource(), DataSource::Segment((DataSource&)*this), m_data(), m_length(0)
94 setData(data, length);
97 //! Makes a copy of \a data that is freed when the data source is
98 //! destroyed. The caller does not have to maintain \a data after this call
100 void UnmappedDataSource::setData(const uint8_t * data, unsigned length)
102 m_data.safe_delete();
104 uint8_t * dataCopy = new uint8_t[length];
105 memcpy(dataCopy, data, length);
110 unsigned UnmappedDataSource::getData(unsigned offset, unsigned maxBytes, uint8_t * buffer)
112 assert(offset < m_length);
113 unsigned copyBytes = std::min<unsigned>(m_length - offset, maxBytes);
114 memcpy(buffer, m_data.get(), copyBytes);
118 #pragma mark *** MemoryImageDataSource ***
120 MemoryImageDataSource::MemoryImageDataSource(StExecutableImage * image)
121 : DataSource(), m_image(image)
123 // reserve enough room for all segments
124 m_segments.reserve(m_image->getRegionCount());
127 MemoryImageDataSource::~MemoryImageDataSource()
129 segment_array_t::iterator it = m_segments.begin();
130 for (; it != m_segments.end(); ++it)
132 // delete this segment if it has been created
140 unsigned MemoryImageDataSource::getSegmentCount()
142 return m_image->getRegionCount();
145 DataSource::Segment * MemoryImageDataSource::getSegmentAt(unsigned index)
147 // return previously created segment
148 if (index < m_segments.size() && m_segments[index])
150 return m_segments[index];
153 // extend array out to this index
154 if (index >= m_segments.size() && index < m_image->getRegionCount())
156 m_segments.resize(index + 1, NULL);
159 // create the new segment object
160 DataSource::Segment * newSegment;
161 const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(index);
162 if (region.m_type == StExecutableImage::TEXT_REGION)
164 newSegment = new TextSegment(*this, m_image, index);
166 else if (region.m_type == StExecutableImage::FILL_REGION)
168 newSegment = new FillSegment(*this, m_image, index);
171 m_segments[index] = newSegment;
175 #pragma mark *** MemoryImageDataSource::TextSegment ***
177 MemoryImageDataSource::TextSegment::TextSegment(MemoryImageDataSource & source, StExecutableImage * image, unsigned index)
178 : DataSource::Segment(source), m_image(image), m_index(index)
182 unsigned MemoryImageDataSource::TextSegment::getData(unsigned offset, unsigned maxBytes, uint8_t * buffer)
184 const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index);
185 assert(region.m_type == StExecutableImage::TEXT_REGION);
187 unsigned copyBytes = std::min<unsigned>(region.m_length - offset, maxBytes);
188 memcpy(buffer, ®ion.m_data[offset], copyBytes);
193 unsigned MemoryImageDataSource::TextSegment::getLength()
195 const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index);
196 return region.m_length;
199 uint32_t MemoryImageDataSource::TextSegment::getBaseAddress()
201 const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index);
202 return region.m_address;
205 #pragma mark *** MemoryImageDataSource::FillSegment ***
207 MemoryImageDataSource::FillSegment::FillSegment(MemoryImageDataSource & source, StExecutableImage * image, unsigned index)
208 : DataSource::PatternSegment(source), m_image(image), m_index(index)
210 SizedIntegerValue zero(0, kWordSize);
214 unsigned MemoryImageDataSource::FillSegment::getLength()
216 const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index);
217 return region.m_length;
220 uint32_t MemoryImageDataSource::FillSegment::getBaseAddress()
222 const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index);
223 return region.m_address;