Add KBOOT.
This commit is contained in:
244
apps/elftosb/common/DataSource.cpp
Normal file
244
apps/elftosb/common/DataSource.cpp
Normal file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* File: DataSource.cpp
|
||||
*
|
||||
* Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
|
||||
* See included license file for license details.
|
||||
*/
|
||||
|
||||
#include "DataSource.h"
|
||||
#include "DataTarget.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace elftosb;
|
||||
|
||||
#pragma mark *** DataSource::PatternSegment ***
|
||||
|
||||
DataSource::PatternSegment::PatternSegment(DataSource &source)
|
||||
: DataSource::Segment(source)
|
||||
, m_pattern()
|
||||
{
|
||||
}
|
||||
|
||||
DataSource::PatternSegment::PatternSegment(DataSource &source, const SizedIntegerValue &pattern)
|
||||
: DataSource::Segment(source)
|
||||
, m_pattern(pattern)
|
||||
{
|
||||
}
|
||||
|
||||
DataSource::PatternSegment::PatternSegment(DataSource &source, uint8_t pattern)
|
||||
: DataSource::Segment(source)
|
||||
, m_pattern(static_cast<uint8_t>(pattern))
|
||||
{
|
||||
}
|
||||
|
||||
DataSource::PatternSegment::PatternSegment(DataSource &source, uint16_t pattern)
|
||||
: DataSource::Segment(source)
|
||||
, m_pattern(static_cast<uint16_t>(pattern))
|
||||
{
|
||||
}
|
||||
|
||||
DataSource::PatternSegment::PatternSegment(DataSource &source, uint32_t pattern)
|
||||
: DataSource::Segment(source)
|
||||
, m_pattern(static_cast<uint32_t>(pattern))
|
||||
{
|
||||
}
|
||||
|
||||
unsigned DataSource::PatternSegment::getData(unsigned offset, unsigned maxBytes, uint8_t *buffer)
|
||||
{
|
||||
memset(buffer, 0, maxBytes);
|
||||
|
||||
return maxBytes;
|
||||
}
|
||||
|
||||
//! The pattern segment's length is a function of the data target. If the
|
||||
//! target is bounded, then the segment's length is simply the target's
|
||||
//! length. Otherwise, if no target has been set or the target is unbounded,
|
||||
//! then the length returned is 0.
|
||||
unsigned DataSource::PatternSegment::getLength()
|
||||
{
|
||||
DataTarget *target = m_source.getTarget();
|
||||
if (!target)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t length;
|
||||
if (target->isBounded())
|
||||
{
|
||||
length = target->getEndAddress() - target->getBeginAddress();
|
||||
}
|
||||
else
|
||||
{
|
||||
length = m_pattern.getSize();
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
#pragma mark *** PatternSource ***
|
||||
|
||||
PatternSource::PatternSource()
|
||||
: DataSource()
|
||||
, DataSource::PatternSegment((DataSource &)*this)
|
||||
{
|
||||
}
|
||||
|
||||
PatternSource::PatternSource(const SizedIntegerValue &value)
|
||||
: DataSource()
|
||||
, DataSource::PatternSegment((DataSource &)*this, value)
|
||||
{
|
||||
}
|
||||
|
||||
#pragma mark *** UnmappedDataSource ***
|
||||
|
||||
UnmappedDataSource::UnmappedDataSource()
|
||||
: DataSource()
|
||||
, DataSource::Segment((DataSource &)*this)
|
||||
, m_data()
|
||||
, m_length(0)
|
||||
{
|
||||
}
|
||||
|
||||
UnmappedDataSource::UnmappedDataSource(const uint8_t *data, unsigned length)
|
||||
: DataSource()
|
||||
, DataSource::Segment((DataSource &)*this)
|
||||
, m_data()
|
||||
, m_length(0)
|
||||
{
|
||||
setData(data, length);
|
||||
}
|
||||
|
||||
//! Makes a copy of \a data that is freed when the data source is
|
||||
//! destroyed. The caller does not have to maintain \a data after this call
|
||||
//! returns.
|
||||
void UnmappedDataSource::setData(const uint8_t *data, unsigned length)
|
||||
{
|
||||
m_data.safe_delete();
|
||||
|
||||
uint8_t *dataCopy = new uint8_t[length];
|
||||
memcpy(dataCopy, data, length);
|
||||
m_data = dataCopy;
|
||||
m_length = length;
|
||||
}
|
||||
|
||||
unsigned UnmappedDataSource::getData(unsigned offset, unsigned maxBytes, uint8_t *buffer)
|
||||
{
|
||||
assert(offset < m_length);
|
||||
unsigned copyBytes = std::min<unsigned>(m_length - offset, maxBytes);
|
||||
memcpy(buffer, m_data.get(), copyBytes);
|
||||
return copyBytes;
|
||||
}
|
||||
|
||||
#pragma mark *** MemoryImageDataSource ***
|
||||
|
||||
MemoryImageDataSource::MemoryImageDataSource(StExecutableImage *image)
|
||||
: DataSource()
|
||||
, m_image(image)
|
||||
{
|
||||
// reserve enough room for all segments
|
||||
m_segments.reserve(m_image->getRegionCount());
|
||||
}
|
||||
|
||||
MemoryImageDataSource::~MemoryImageDataSource()
|
||||
{
|
||||
segment_array_t::iterator it = m_segments.begin();
|
||||
for (; it != m_segments.end(); ++it)
|
||||
{
|
||||
// delete this segment if it has been created
|
||||
if (*it)
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned MemoryImageDataSource::getSegmentCount()
|
||||
{
|
||||
return m_image->getRegionCount();
|
||||
}
|
||||
|
||||
DataSource::Segment *MemoryImageDataSource::getSegmentAt(unsigned index)
|
||||
{
|
||||
// return previously created segment
|
||||
if (index < m_segments.size() && m_segments[index])
|
||||
{
|
||||
return m_segments[index];
|
||||
}
|
||||
|
||||
// extend array out to this index
|
||||
if (index >= m_segments.size() && index < m_image->getRegionCount())
|
||||
{
|
||||
m_segments.resize(index + 1, NULL);
|
||||
}
|
||||
|
||||
// create the new segment object
|
||||
DataSource::Segment *newSegment;
|
||||
const StExecutableImage::MemoryRegion ®ion = m_image->getRegionAtIndex(index);
|
||||
if (region.m_type == StExecutableImage::TEXT_REGION)
|
||||
{
|
||||
newSegment = new TextSegment(*this, m_image, index);
|
||||
}
|
||||
else if (region.m_type == StExecutableImage::FILL_REGION)
|
||||
{
|
||||
newSegment = new FillSegment(*this, m_image, index);
|
||||
}
|
||||
|
||||
m_segments[index] = newSegment;
|
||||
return newSegment;
|
||||
}
|
||||
|
||||
#pragma mark *** MemoryImageDataSource::TextSegment ***
|
||||
|
||||
MemoryImageDataSource::TextSegment::TextSegment(MemoryImageDataSource &source, StExecutableImage *image, unsigned index)
|
||||
: DataSource::Segment(source)
|
||||
, m_image(image)
|
||||
, m_index(index)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned MemoryImageDataSource::TextSegment::getData(unsigned offset, unsigned maxBytes, uint8_t *buffer)
|
||||
{
|
||||
const StExecutableImage::MemoryRegion ®ion = m_image->getRegionAtIndex(m_index);
|
||||
assert(region.m_type == StExecutableImage::TEXT_REGION);
|
||||
|
||||
unsigned copyBytes = std::min<unsigned>(region.m_length - offset, maxBytes);
|
||||
memcpy(buffer, ®ion.m_data[offset], copyBytes);
|
||||
|
||||
return copyBytes;
|
||||
}
|
||||
|
||||
unsigned MemoryImageDataSource::TextSegment::getLength()
|
||||
{
|
||||
const StExecutableImage::MemoryRegion ®ion = m_image->getRegionAtIndex(m_index);
|
||||
return region.m_length;
|
||||
}
|
||||
|
||||
uint32_t MemoryImageDataSource::TextSegment::getBaseAddress()
|
||||
{
|
||||
const StExecutableImage::MemoryRegion ®ion = m_image->getRegionAtIndex(m_index);
|
||||
return region.m_address;
|
||||
}
|
||||
|
||||
#pragma mark *** MemoryImageDataSource::FillSegment ***
|
||||
|
||||
MemoryImageDataSource::FillSegment::FillSegment(MemoryImageDataSource &source, StExecutableImage *image, unsigned index)
|
||||
: DataSource::PatternSegment(source)
|
||||
, m_image(image)
|
||||
, m_index(index)
|
||||
{
|
||||
SizedIntegerValue zero(0, kWordSize);
|
||||
setPattern(zero);
|
||||
}
|
||||
|
||||
unsigned MemoryImageDataSource::FillSegment::getLength()
|
||||
{
|
||||
const StExecutableImage::MemoryRegion ®ion = m_image->getRegionAtIndex(m_index);
|
||||
return region.m_length;
|
||||
}
|
||||
|
||||
uint32_t MemoryImageDataSource::FillSegment::getBaseAddress()
|
||||
{
|
||||
const StExecutableImage::MemoryRegion ®ion = m_image->getRegionAtIndex(m_index);
|
||||
return region.m_address;
|
||||
}
|
||||
Reference in New Issue
Block a user