OpenASIP 2.2
Loading...
Searching...
No Matches
TPEFReader.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file TPEFReader.cc
26 *
27 * Definitions of class TPEFReader.
28 *
29 * @author Mikael Lepistö 2003 (tmlepist-no.spam-cs.tut.fi)
30 *
31 * @note rating: yellow
32 */
33
34#include <list>
35#include <cmath>
36
37#include "TPEFReader.hh"
38#include "Section.hh"
39#include "TPEFBaseType.hh"
40#include "SafePointer.hh"
41#include "ReferenceKey.hh"
42#include "SectionReader.hh"
43#include "CodeSection.hh"
44#include "BinaryStream.hh"
45#include "Binary.hh"
46#include "ASpaceSection.hh"
47#include "TPEFHeaders.hh"
48
49namespace TPEF {
50
51using std::list;
52using ReferenceManager::SafePointer;
53
54using ReferenceManager::FileOffsetKey;
55using ReferenceManager::SectionOffsetKey;
56using ReferenceManager::SectionKey;
57using ReferenceManager::SectionIndexKey;
58
59TPEFReader* TPEFReader::proto_ = NULL;
60
61/**
62 * Constructor.
63 *
64 * Creates Header and registers itself to BinaryReader.
65 */
66TPEFReader::TPEFReader() : BinaryReader(), aSpaceId_(0), strTableId_(0) {
68}
69
70/**
71 * Destructor.
72 */
74 if (proto_ != NULL) {
75 auto proto = proto_;
76 proto_ = NULL;
77 delete proto;
78 }
79}
80
81/**
82 * Does the actual work of reading binary file from stream.
83 *
84 * @param stream Stream to be read from.
85 * @return Pointer to the Binary object created.
86 * @exception UnreachableStream If reading of section fails.
87 * @exception KeyAlreadyExists Key was in use whent rying to register object.
88 * @exception EndOfFile If end of file were reached while it shouldn't.
89 * @exception OutOfRange Some of read values were out of range.
90 * @exception WrongSubclass Some class couldn't do what it was asked for.
91 * @exception UnexpectedValue If there was unexpected value when reading.
92 */
93Binary*
95 binary_ = new Binary();
96 sectionSizes_.clear();
97
98 // let's read file header stuff
99 FileOffset startOffset = stream.readPosition();
100
101 // read file format identifier (including TPEF version number)
102 stream.setReadPosition(startOffset + TPEFHeaders::FH_ID);
103 for (Word i = 0; i < TPEFHeaders::FH_ID_SIZE; i++) {
104 // TPEF version number is located in the 9th Byte of FH_ID header
105 if (i == 8) {
107 static_cast<TPEFHeaders::TPEFVersion>(stream.readByte());
108 stream.setTPEFVersion(version);
109 binary_->setTPEFVersion(version);
110 } else {
111 stream.readByte();
112 }
113 }
114
115 stream.setReadPosition(startOffset + TPEFHeaders::FH_ARCH);
117 static_cast<Binary::FileArchitecture>(stream.readByte()));
118
119 stream.setReadPosition(startOffset + TPEFHeaders::FH_TYPE);
121 static_cast<Binary::FileType>(stream.readByte()));
122
123 stream.setReadPosition(startOffset + TPEFHeaders::FH_SHOFF);
124 FileOffset offsetToHeader = stream.readWord();
125
126 // skip size of file header
127
128 stream.setReadPosition(startOffset + TPEFHeaders::FH_SHSIZE);
129 HalfWord sectionHeaderSize = stream.readHalfWord();
130
131 stream.setReadPosition(startOffset + TPEFHeaders::FH_SHNUM);
132 HalfWord sectionHeaderCount = stream.readHalfWord();
133
134 // string table of section names
135 stream.setReadPosition(startOffset + TPEFHeaders::FH_SHSTRTAB);
136 Word stringTableFileOffset = stream.readWord();
137
138 if (stringTableFileOffset != 0) {
139 FileOffsetKey fKey(stringTableFileOffset);
140 binary_->setStrings(CREATE_SAFEPOINTER(fKey));
141 } else {
143 }
144
145 // get identification code of string table section of binary
146 if (stringTableFileOffset != 0) {
147 stream.setReadPosition(stringTableFileOffset + TPEFHeaders::SH_ID);
148 SectionId stringTableSectionId = stream.readHalfWord();
149 strTableId_ = stringTableSectionId;
150 } else {
151 strTableId_ = 0;
152 }
153
154 // get identification code of address space section of binary
155 SectionId aSpaceSectionId = 0;
156 bool programSectionWasFound = false;
157 for (Word i = offsetToHeader;
158 i < offsetToHeader + (sectionHeaderCount*sectionHeaderSize);
159 i += sectionHeaderSize) {
160
161 // go to start of section header
163
164 Section::SectionType sectionTypeToCheck =
165 static_cast<Section::SectionType>(stream.readByte());
166
167 // if section is ASpaceSection
168 if (sectionTypeToCheck == Section::ST_ADDRSP) {
169 bool brokenBinaryMoreThanOneASpaceSection =
170 (aSpaceSectionId == 0);
171 assert(brokenBinaryMoreThanOneASpaceSection);
172
174 aSpaceSectionId = stream.readHalfWord();
175
176 } else if(Section::isProgramSection(sectionTypeToCheck)) {
177 programSectionWasFound = true;
178 }
179 }
180
181 // there must be address space
182 assert(aSpaceSectionId != 0);
183 aSpaceId_ = aSpaceSectionId;
184
185 // let's do some serious section-reading...
186 for (HalfWord i = 0; i < sectionHeaderCount; i++) {
187
188 stream.setReadPosition(offsetToHeader + TPEFHeaders::SH_TYPE);
189
191 static_cast<Section::SectionType>(stream.readByte()));
192
193 FileOffsetKey sectionFileOffsetKey(offsetToHeader);
194 SafePointer::addObjectReference(sectionFileOffsetKey, sect);
195
196 stream.setReadPosition(offsetToHeader);
197
198 SectionReader::readSection(stream, sect, proto_);
199
200 // next header
201 offsetToHeader += sectionHeaderSize;
202 binary_->addSection(sect);
203 }
204
205 // NOTE: This check might be better to do in Binary classes addSection
206 // method. Because it's Binary classes job to prevent illegal
207 // section set. This check only prevents adding too many of these
208 // section while reading.
209
210 // make sure that binary has needed sctions and do not have too many
211 // resource or address space sections
216 programSectionWasFound == false));
217
218 return binary_;
219}
220
221/**
222 * Checks if this reader is capable of reading the given stream.
223 *
224 * This method does not modify the stream pointer.
225 *
226 * @param stream The stream to test.
227 * @return True if stream contains data in expected format, false otherwise.
228 * @exception UnreachableStream If there occurs an exception with stream.
229 */
230bool
232 unsigned long startPos = stream.readPosition();
233
234 try {
235 if (stream.readByte() == 0x7f &&
236 stream.readByte() == 'T' &&
237 stream.readByte() == 'T' &&
238 stream.readByte() == 'A' &&
239 stream.readByte() == '-' &&
240 stream.readByte() == 'P' &&
241 stream.readByte() == 'F' &&
242 stream.readByte() == 0x00) {
243
244 stream.setReadPosition(startPos);
245 return true;
246 }
247 } catch (EndOfFile& e) {
248 stream.setReadPosition(startPos);
249 return false;
250 }
251
252 stream.setReadPosition(startPos);
253 return false;
254}
255
256/**
257 * Returns instance of reader.
258 *
259 * @return Instance used for reading.
260 */
263 if (proto_ == NULL) {
264 proto_ = new TPEFReader();
265 }
266 return proto_;
267}
268
269/**
270 * Resolves, which section is in given address in last read binary file.
271 *
272 * @param aSpace Address space in which section resides in memory image.
273 * @param address Address whose section is resolved.
274 * @return Section to which given offset refers.
275 */
276Section*
278 const ASpaceElement* aSpace,
279 AddressImage address) const {
280
281 assert(binary_ != NULL);
282
283 for (Word i = 0; i < binary_->sectionCount(); i++) {
284
285 Section *sect = binary_->section(i);
286
287 // if section have same aSpace that in parameter
288 if (sect->aSpace() == aSpace) {
289
290 Word lastSectionAddress = sect->startingAddress();
291
292 if (sect->isCodeSection()) {
293 lastSectionAddress +=
294 dynamic_cast<CodeSection*>(sect)->instructionCount();
295
296 } else {
297 lastSectionAddress +=
298 dynamic_cast<RawSection*>(sect)->lengthInMAUs();
299 }
300
301 // test if address is inside base + sh_size
302 if (address < lastSectionAddress &&
303 address >= sect->startingAddress()) {
304
305 return sect;
306 }
307 }
308 }
309
310 return NULL;
311}
312
313/**
314 * Stores size of a section as bytes.
315 *
316 * @param sect Section whose size is stored.
317 * @param length Section data size in addresses.
318 */
319void
320TPEFReader::addSectionSize(const Section* sect, Word length) {
321 sectionSizes_[sect] = length;
322}
323
324/**
325 * Returns the identification code of the address space table section.
326 *
327 * @return Identification code of the address space table section.
328 */
331 return aSpaceId_;
332}
333
334/**
335 * Returns the identification code of string table section that contains the
336 * names of the sections.
337 *
338 * @return Identification code of a string table section.
339 */
344
345/**
346 * Returns address space of file if already read.
347 *
348 * @return Address space of binary. NULL if there is no ASpace.
349 */
352 for (unsigned int i = 0; i < binary_->sectionCount(); i++) {
353 if (binary_->section(i)->type() == Section::ST_ADDRSP) {
354 return dynamic_cast<ASpaceSection*>(binary_->section(i));
355 }
356 }
357 return NULL;
358}
359
360}
#define assert(condition)
UInt32 AddressImage
Type for storing addresses to memory image.
Definition BaseType.hh:179
static void registerBinaryReader(BinaryReader *reader)
void setReadPosition(unsigned int position)
unsigned int readPosition()
void setTPEFVersion(TPEFHeaders::TPEFVersion version)
HalfWord readHalfWord()
void addSection(Section *section)
void setArch(FileArchitecture arch)
Word sectionCount() const
Section * section(Word index) const
void setType(FileType type)
void setTPEFVersion(TPEFHeaders::TPEFVersion version)
void setStrings(StringSection *strTable)
static void addObjectReference(SectionIndexKey key, const SafePointable *obj)
static const SafePointer null
The default SafePointer that is used in null references.
static void readSection(BinaryStream &stream, Section *section, BinaryReader *reader)
static Section * createSection(SectionType type)
Definition Section.cc:91
AddressImage startingAddress() const
bool isProgramSection() const
@ ST_ADDRSP
Address space section.
Definition Section.hh:77
@ ST_NULL
NULL Section.
Definition Section.hh:70
@ ST_MR
Machine resources section.
Definition Section.hh:78
virtual bool isCodeSection() const
Definition Section.hh:143
virtual SectionType type() const =0
Returns SectioType of actual section instance.
ASpaceElement * aSpace() const
void addSectionSize(const Section *sect, Word length)
virtual bool isMyStreamType(BinaryStream &stream) const
Binary * binary_
Last or currently read binary.
Definition TPEFReader.hh:90
std::map< const Section *, Word > sectionSizes_
Cache of sizes in addresses of read sections.
Definition TPEFReader.hh:97
SectionId aSpaceId()
ASpaceSection * aSpaceSection() const
SectionId strTableId()
SectionId aSpaceId_
Identification code of address space section (there is only one at maximum).
Definition TPEFReader.hh:93
static TPEFReader * proto_
Prototype instance registered into BinaryReader.
Definition TPEFReader.hh:87
SectionId strTableId_
Identification code of string table containing section name strings.
Definition TPEFReader.hh:95
virtual Binary * readData(BinaryStream &stream) const
Definition TPEFReader.cc:94
virtual ~TPEFReader()
Definition TPEFReader.cc:73
static BinaryReader * instance()
Section * sectionOfAddress(const ASpaceElement *aSpaceId, AddressImage address) const
@ FH_ARCH
Architecture template.
@ FH_SHSIZE
Size of section header entry.
@ FH_SHSTRTAB
Offset to header of string table.
@ FH_ID
File identification code.
@ FH_SHNUM
Number of section headers.
@ FH_SHOFF
Offset to first section header.
@ FH_TYPE
Type of TTA program.
@ SH_ID
Section identification code.
@ SH_TYPE
Type of section.
const Byte FH_ID_SIZE
Size of file identification code.
HalfWord SectionId
Type for storing binary file section ids.
Word FileOffset
Type for storing absolute file offsets.