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