1 /* 2 * File: DataSource.cpp 3 * 4 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved. 5 * See included license file for license details. 6 */ 7 8 #include "DataSource.h" 9 #include "DataTarget.h" 10 #include <assert.h> 11 #include <string.h> 12 using namespace elftosb; 13 14 #pragma mark *** DataSource::PatternSegment *** 15 16 DataSource::PatternSegment::PatternSegment(DataSource & source) 17 : DataSource::Segment(source), m_pattern() 18 { 19 } 20 21 DataSource::PatternSegment::PatternSegment(DataSource & source, const SizedIntegerValue & pattern) 22 : DataSource::Segment(source), m_pattern(pattern) 23 { 24 } 25 26 DataSource::PatternSegment::PatternSegment(DataSource & source, uint8_t pattern) 27 : DataSource::Segment(source), m_pattern(static_cast<uint8_t>(pattern)) 28 { 29 } 30 31 DataSource::PatternSegment::PatternSegment(DataSource & source, uint16_t pattern) 32 : DataSource::Segment(source), m_pattern(static_cast<uint16_t>(pattern)) 33 { 34 } 35 36 DataSource::PatternSegment::PatternSegment(DataSource & source, uint32_t pattern) 37 : DataSource::Segment(source), m_pattern(static_cast<uint32_t>(pattern)) 38 { 39 } 40 41 unsigned DataSource::PatternSegment::getData(unsigned offset, unsigned maxBytes, uint8_t * buffer) 42 { 43 memset(buffer, 0, maxBytes); 44 45 return maxBytes; 46 } 47 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() 53 { 54 DataTarget * target = m_source.getTarget(); 55 if (!target) 56 { 57 return 0; 58 } 59 60 uint32_t length; 61 if (target->isBounded()) 62 { 63 length = target->getEndAddress() - target->getBeginAddress(); 64 } 65 else 66 { 67 length = m_pattern.getSize(); 68 } 69 return length; 70 } 71 72 #pragma mark *** PatternSource *** 73 74 PatternSource::PatternSource() 75 : DataSource(), DataSource::PatternSegment((DataSource&)*this) 76 { 77 } 78 79 PatternSource::PatternSource(const SizedIntegerValue & value) 80 : DataSource(), DataSource::PatternSegment((DataSource&)*this, value) 81 { 82 } 83 84 #pragma mark *** UnmappedDataSource *** 85 86 UnmappedDataSource::UnmappedDataSource() 87 : DataSource(), DataSource::Segment((DataSource&)*this), m_data(), m_length(0) 88 { 89 } 90 91 UnmappedDataSource::UnmappedDataSource(const uint8_t * data, unsigned length) 92 : DataSource(), DataSource::Segment((DataSource&)*this), m_data(), m_length(0) 93 { 94 setData(data, length); 95 } 96 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 99 //! returns. 100 void UnmappedDataSource::setData(const uint8_t * data, unsigned length) 101 { 102 m_data.safe_delete(); 103 104 uint8_t * dataCopy = new uint8_t[length]; 105 memcpy(dataCopy, data, length); 106 m_data = dataCopy; 107 m_length = length; 108 } 109 110 unsigned UnmappedDataSource::getData(unsigned offset, unsigned maxBytes, uint8_t * buffer) 111 { 112 assert(offset < m_length); 113 unsigned copyBytes = std::min<unsigned>(m_length - offset, maxBytes); 114 memcpy(buffer, m_data.get(), copyBytes); 115 return copyBytes; 116 } 117 118 #pragma mark *** MemoryImageDataSource *** 119 120 MemoryImageDataSource::MemoryImageDataSource(StExecutableImage * image) 121 : DataSource(), m_image(image) 122 { 123 // reserve enough room for all segments 124 m_segments.reserve(m_image->getRegionCount()); 125 } 126 127 MemoryImageDataSource::~MemoryImageDataSource() 128 { 129 segment_array_t::iterator it = m_segments.begin(); 130 for (; it != m_segments.end(); ++it) 131 { 132 // delete this segment if it has been created 133 if (*it) 134 { 135 delete *it; 136 } 137 } 138 } 139 140 unsigned MemoryImageDataSource::getSegmentCount() 141 { 142 return m_image->getRegionCount(); 143 } 144 145 DataSource::Segment * MemoryImageDataSource::getSegmentAt(unsigned index) 146 { 147 // return previously created segment 148 if (index < m_segments.size() && m_segments[index]) 149 { 150 return m_segments[index]; 151 } 152 153 // extend array out to this index 154 if (index >= m_segments.size() && index < m_image->getRegionCount()) 155 { 156 m_segments.resize(index + 1, NULL); 157 } 158 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) 163 { 164 newSegment = new TextSegment(*this, m_image, index); 165 } 166 else if (region.m_type == StExecutableImage::FILL_REGION) 167 { 168 newSegment = new FillSegment(*this, m_image, index); 169 } 170 171 m_segments[index] = newSegment; 172 return newSegment; 173 } 174 175 #pragma mark *** MemoryImageDataSource::TextSegment *** 176 177 MemoryImageDataSource::TextSegment::TextSegment(MemoryImageDataSource & source, StExecutableImage * image, unsigned index) 178 : DataSource::Segment(source), m_image(image), m_index(index) 179 { 180 } 181 182 unsigned MemoryImageDataSource::TextSegment::getData(unsigned offset, unsigned maxBytes, uint8_t * buffer) 183 { 184 const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index); 185 assert(region.m_type == StExecutableImage::TEXT_REGION); 186 187 unsigned copyBytes = std::min<unsigned>(region.m_length - offset, maxBytes); 188 memcpy(buffer, ®ion.m_data[offset], copyBytes); 189 190 return copyBytes; 191 } 192 193 unsigned MemoryImageDataSource::TextSegment::getLength() 194 { 195 const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index); 196 return region.m_length; 197 } 198 199 uint32_t MemoryImageDataSource::TextSegment::getBaseAddress() 200 { 201 const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index); 202 return region.m_address; 203 } 204 205 #pragma mark *** MemoryImageDataSource::FillSegment *** 206 207 MemoryImageDataSource::FillSegment::FillSegment(MemoryImageDataSource & source, StExecutableImage * image, unsigned index) 208 : DataSource::PatternSegment(source), m_image(image), m_index(index) 209 { 210 SizedIntegerValue zero(0, kWordSize); 211 setPattern(zero); 212 } 213 214 unsigned MemoryImageDataSource::FillSegment::getLength() 215 { 216 const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index); 217 return region.m_length; 218 } 219 220 uint32_t MemoryImageDataSource::FillSegment::getBaseAddress() 221 { 222 const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index); 223 return region.m_address; 224 } 225