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> 12using namespace elftosb; 13 14#pragma mark *** DataSource::PatternSegment *** 15 16DataSource::PatternSegment::PatternSegment(DataSource & source) 17: DataSource::Segment(source), m_pattern() 18{ 19} 20 21DataSource::PatternSegment::PatternSegment(DataSource & source, const SizedIntegerValue & pattern) 22: DataSource::Segment(source), m_pattern(pattern) 23{ 24} 25 26DataSource::PatternSegment::PatternSegment(DataSource & source, uint8_t pattern) 27: DataSource::Segment(source), m_pattern(static_cast<uint8_t>(pattern)) 28{ 29} 30 31DataSource::PatternSegment::PatternSegment(DataSource & source, uint16_t pattern) 32: DataSource::Segment(source), m_pattern(static_cast<uint16_t>(pattern)) 33{ 34} 35 36DataSource::PatternSegment::PatternSegment(DataSource & source, uint32_t pattern) 37: DataSource::Segment(source), m_pattern(static_cast<uint32_t>(pattern)) 38{ 39} 40 41unsigned 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. 52unsigned 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 74PatternSource::PatternSource() 75: DataSource(), DataSource::PatternSegment((DataSource&)*this) 76{ 77} 78 79PatternSource::PatternSource(const SizedIntegerValue & value) 80: DataSource(), DataSource::PatternSegment((DataSource&)*this, value) 81{ 82} 83 84#pragma mark *** UnmappedDataSource *** 85 86UnmappedDataSource::UnmappedDataSource() 87: DataSource(), DataSource::Segment((DataSource&)*this), m_data(), m_length(0) 88{ 89} 90 91UnmappedDataSource::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. 100void 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 110unsigned 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 120MemoryImageDataSource::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 127MemoryImageDataSource::~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 140unsigned MemoryImageDataSource::getSegmentCount() 141{ 142 return m_image->getRegionCount(); 143} 144 145DataSource::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 177MemoryImageDataSource::TextSegment::TextSegment(MemoryImageDataSource & source, StExecutableImage * image, unsigned index) 178: DataSource::Segment(source), m_image(image), m_index(index) 179{ 180} 181 182unsigned 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 193unsigned MemoryImageDataSource::TextSegment::getLength() 194{ 195 const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index); 196 return region.m_length; 197} 198 199uint32_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 207MemoryImageDataSource::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 214unsigned MemoryImageDataSource::FillSegment::getLength() 215{ 216 const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index); 217 return region.m_length; 218} 219 220uint32_t MemoryImageDataSource::FillSegment::getBaseAddress() 221{ 222 const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index); 223 return region.m_address; 224} 225