OpenASIP 2.2
Loading...
Searching...
No Matches
AOutReader.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 AOutReader.cc
26 *
27 * Implementation of class AOutReader.
28 *
29 * @author Jussi Nykänen 2003 (nykanen-no.spam-cs.tut.fi)
30 * @author Mikael Lepistö 2003 (tmlepist-no.spam-cs.tut.fi)
31 * @note reviewed 7 October 2003 by jn, ml, tr, ll
32 *
33 * @note rating: yellow
34 */
35
36#include <cassert>
37
38#include "ASpaceSection.hh"
39#include "ASpaceElement.hh"
40#include "AOutReader.hh"
42#include "Section.hh"
43#include "RelocSection.hh"
44#include "SectionReader.hh"
45#include "SafePointer.hh"
46#include "ReferenceKey.hh"
47#include "CodeSection.hh"
48#include "ResourceSection.hh"
49#include "NullSection.hh"
50#include "DebugSection.hh"
51#include "CodeSection.hh"
52
53namespace TPEF {
54
55using ReferenceManager::SectionKey;
56using ReferenceManager::SectionOffsetKey;
57using ReferenceManager::SafePointer;
58
59//////////////////////////////////////////////////////////////////////////
60/// AOutReader class
61//////////////////////////////////////////////////////////////////////////
62
63
64AOutReader* AOutReader::proto_ = NULL;
65ResourceSection* AOutReader::resourceTable_ = NULL;
66NullSection* AOutReader::nullSection_ = NULL;
67DebugSection* AOutReader::debugSection_ = NULL;
68StringSection* AOutReader::stringSection_ = NULL;
69CodeSection* AOutReader::textSection_ = NULL;
70
71AOutReader::Header AOutReader::header_;
72
73const HalfWord AOutReader::OMAGIC = 0x0107;
74const Byte AOutReader::FILE_HEADER_SIZE = 8 * sizeof(Word);
75
80const char* AOutReader::AOUT_CODE_ASPACE_NAME = "universal_instructions";
81const char* AOutReader::AOUT_DATA_ASPACE_NAME = "universal_data";
82
83const Word AOutReader::INT_REGISTERS = 1024;
84const Word AOutReader::FP_REGISTERS = 1024;
85const Word AOutReader::BOOL_REGISTERS = 1;
86
87const Word
89const Word
90AOutReader::FIRST_FP_REGISTER = FIRST_INT_REGISTER + INT_REGISTERS;
91const Word
92AOutReader::FIRST_BOOL_REGISTER = FIRST_FP_REGISTER + FP_REGISTERS;
93const Word
94AOutReader::FIRST_FU_REGISTER = FIRST_BOOL_REGISTER + BOOL_REGISTERS;
95
96/**
97 * Constructor.
98 *
99 * Creates Header and registers itself to BinaryReader.
100 */
102 codeASpace_(NULL), dataASpace_(NULL) {
103
105}
106
107/**
108 * Destructor.
109 */
111
112 if (proto_ != NULL) {
113 auto proto = proto_;
114 proto_ = NULL;
115 delete proto;
116 }
117}
118
119/**
120 * Does the actual work of reading binary file from stream.
121 *
122 * Reads a.out binary file and creates valid TPEF object hierarchy out of it.
123 *
124 * @param stream Stream to be read from.
125 * @return Pointer to the Binary object created.
126 * @exception UnreachableStream If reading of section fails.
127 * @exception KeyAlreadyExists Key was in use when trying to register object.
128 * @exception EndOfFile If end of file were reached while it shouldn't.
129 * @exception OutOfRange Some of read values were out of range.
130 * @exception WrongSubclass Some class couldn't do what it was asked for.
131 * @exception UnexpectedValue If there was unexpected value when reading.
132 */
133Binary*
135 Binary* newBin = NULL;
136 newBin = new Binary();
137
138 // read section sizes and other file header data
139 readHeader(stream);
140
141 // create all a.out sections and
143 dynamic_cast<NullSection*>(
146
147 textSection_ = dynamic_cast<CodeSection*>(
149
150 DataSection* dataSection = dynamic_cast<DataSection*>(
152
153 UDataSection* uDataSection = dynamic_cast<UDataSection*>(
155
156 stringSection_ = dynamic_cast<StringSection*>(
159
161
162 RelocSection* textRelocSection = dynamic_cast<RelocSection*>(
164
165 RelocSection* dataRelocSection = dynamic_cast<RelocSection*>(
167
168 debugSection_ = dynamic_cast<DebugSection*>(
171
172
173 // create TPEF needed sections (NullSection and ASpaceSection)
174 // and processors resource table
175 resourceTable_ = dynamic_cast<ResourceSection*>
177
178 ASpaceSection* aSpaceSection = dynamic_cast<ASpaceSection*>(
180
181 newBin->setStrings(stringSection_);
182 SectionOffsetKey nullString(ST_STRING, 0);
183
185
190
195
196 aSpaceSection->setUndefinedASpace(undefASpace_);
197 aSpaceSection->addElement(undefASpace_);
198 aSpaceSection->addElement(codeASpace_);
199 aSpaceSection->addElement(dataASpace_);
200 aSpaceSection->setLink(stringSection_);
201
202 // set addresses and address spaces
203
204 // code section starts from address zero
208
209 // after that comes data section
210 dataSection->setASpace(dataASpace_);
212 dataSection->setLink(nullSection_);
213
214 // and at last uninitilized data section after that
215 uDataSection->setASpace(dataASpace_);
216 uDataSection->setStartingAddress(
218 uDataSection->setLink(nullSection_);
219
220 // undefined address spaces for all aux sections
223 aSpaceSection->setASpace(undefASpace_);
225 symbolTable->setASpace(undefASpace_);
226 textRelocSection->setASpace(undefASpace_);
227 dataRelocSection->setASpace(undefASpace_);
228
231
232 FileOffset textSection_Start = stream.readPosition();
233
234 FileOffset dataSectionStart =
235 textSection_Start + header_.sectionSizeText();
236
237 FileOffset textRelocationTableStart =
238 dataSectionStart + header_.sectionSizeData();
239
240 FileOffset dataRelocationTableStart =
241 textRelocationTableStart + header_.sectionSizeTextReloc();
242
243 FileOffset symbolTableStart =
244 dataRelocationTableStart + header_.sectionSizeDataReloc();
245
246 FileOffset stringTableStart =
247 symbolTableStart + header_.sectionSizeSymbol();
248
249 // reading sections and creating reference keys
251 uDataSection->setDataLength(header_.sectionSizeUData());
252
254 readSection(stream, stringTableStart, stringSection_,
256
258 readSection(stream, textSection_Start,
260
262 readSection(stream, dataSectionStart,
263 dataSection, header_.sectionSizeData());
264
266 symbolTable->setLink(stringSection_);
267 readSection(stream, symbolTableStart,
268 symbolTable, header_.sectionSizeSymbol());
269
270 // relocation sections are not referenced anywhere by SectionId
271 textRelocSection->setLink(symbolTable);
272 textRelocSection->setReferencedSection(textSection_);
273 readSection(stream, textRelocationTableStart,
274 textRelocSection, header_.sectionSizeTextReloc());
275
276 dataRelocSection->setLink(symbolTable);
277 dataRelocSection->setReferencedSection(dataSection);
278 readSection(stream, dataRelocationTableStart,
279 dataRelocSection, header_.sectionSizeDataReloc());
280
281 // add sections necessary sections and sections that contained elements
282 newBin->addSection(nullSection_);
283 newBin->addSection(aSpaceSection);
284
285 // set names for sections and address spaces
286 symbolTable->setName(stringSection_->string2Chunk("Symbols"));
288 stringSection_->string2Chunk("Universal resources"));
289 dataSection->setName(stringSection_->string2Chunk("Initialized data"));
291 aSpaceSection->setName(stringSection_->string2Chunk("Address spaces"));
293 uDataSection->setName(stringSection_->string2Chunk("Uninitilized data"));
294 textRelocSection->setName(
295 stringSection_->string2Chunk("Relocated immediates"));
296 dataRelocSection->setName(stringSection_->string2Chunk("Relocated data"));
299
303
305 addOrDeleteSection(textRelocSection, newBin);
306 addOrDeleteSection(symbolTable, newBin);
307 addOrDeleteSection(dataSection, newBin);
308 addOrDeleteSection(dataRelocSection, newBin);
309 addOrDeleteSection(uDataSection, newBin);
312
313 // there should be always at least one starting zero
315 newBin->addSection(stringSection_);
316
317 // can't be sure about these, but external clients will fix
318 // values if needed
319 newBin->setType(Binary::FT_OBJSEQ);
321
322 return newBin;
323}
324
325/**
326 * Checks whether AOutReader can read from the given stream.
327 *
328 * The test simply consists of checking that file size is at least the size
329 * of a.out header. Then it checks whether the third and fourth Byte of
330 * stream match the magic number of a.out files. Only 'old impure format'
331 * files (not read-only text and not page-aligned for on demand load) are
332 * accepted.
333 *
334 * This method does not modify the stream position.
335 *
336 * @param stream The stream to test.
337 * @return True if stream contains data in a.out format, false otherwise.
338 * @exception UnreachableStream If there occurs an exception with stream.
339 */
340bool
342 unsigned long startPos = stream.readPosition();
343
344 try {
345 if (stream.sizeOfFile() < FILE_HEADER_SIZE) {
346 return false;
347 } else {
348 stream.readHalfWord();
349 Word magic = stream.readHalfWord();
350
351 stream.setReadPosition(startPos);
352
353 if(magic == OMAGIC) {
354 return true;
355 } else {
356 return false;
357 }
358 }
359
360 } catch (EndOfFile& e) {
361 stream.setReadPosition(startPos);
362 return false;
363 }
364}
365
366/**
367 * Reads file header from the stream and stores it to a specific object.
368 *
369 * @param stream Stream to be read from.
370 * @exception UnreachableStream If there occurs a problem with stream.
371 * @exception EndOfFile If end of file were reached where it shouldn't.
372 */
373void
375 // test magic number again just in case...
376 stream.readHalfWord();
377 assert(stream.readHalfWord() == OMAGIC);
378
383
384 // virtual address of the entry point of the program is ignored
385 assert(stream.readWord() == 0);
386
389
390 SectionOffset currentPosition = stream.readPosition();
391
392 // calculate the size of string table
393 SectionOffset beginOfStrTable = currentPosition +
397
399 beginOfStrTable);
400}
401
402//////////////////////////////////////////////////////////////////////////
403/// Header class
404//////////////////////////////////////////////////////////////////////////
405
406
407/**
408 * Constructor
409 */
412
413
414/**
415 * Destructor
416 */
419
420}
#define assert(condition)
unsigned char Byte
Definition BaseType.hh:116
Word sectionSizeText() const
void setSectionSizeSymbol(Word size)
void setSectionSizeData(Word size)
Word sectionSizeDataReloc() const
Word sectionSizeData() const
void setSectionSizeDataReloc(Word size)
void setSectionSizeTextReloc(Word size)
void setSectionSizeString(Word size)
void setSectionSizeText(Word size)
Word sectionSizeUData() const
void setSectionSizeUData(Word size)
Word sectionSizeSymbol() const
Word sectionSizeTextReloc() const
Word sectionSizeString() const
static const HalfWord OMAGIC
Move a.out format identifier.
static Header header_
Header of a.out file.
virtual Binary * readData(BinaryStream &stream) const
static const Word FIRST_INT_REGISTER
Index of the first integer register in a.out.
static const Byte AOUT_WORD_ALIGN
Aligment of address space.
static const Byte AOUT_WORD_SIZE
Word size of address space.
static ResourceSection * resourceTable_
void addOrDeleteSection(Section *section, Binary *binary) const
static const char * AOUT_CODE_ASPACE_NAME
Name of universal machines code address space.
void readHeader(BinaryStream &stream) const
virtual bool isMyStreamType(BinaryStream &stream) const
static const Word INT_REGISTERS
Number of integer registers.
@ ST_SYMBOL
Symbol table.
@ ST_UDATA
Uninitialized data section.
@ ST_STRING
String table.
@ ST_DATA
Data section.
@ ST_TEXT
Text section.
static const char * AOUT_DATA_ASPACE_NAME
Name of universal machines data address space.
static NullSection * nullSection_
ASpaceElement * codeASpace_
Address space of text section.
ASpaceElement * undefASpace_
Undefined address space.
static CodeSection * textSection_
static const Word FP_REGISTERS
Number of floating-point registers.
void readSection(BinaryStream &stream, FileOffset startPosition, Section *section, Length length) const
ASpaceElement * dataASpace_
Address space of data sections.
static StringSection * stringSection_
static const Byte FILE_HEADER_SIZE
Size of file header.
static DebugSection * debugSection_
static const Word FIRST_BOOL_REGISTER
Index of the first Boolean register.
static const Word BOOL_REGISTERS
Number of Boolean registers.
static const Byte AOUT_INSTRUCTION_SIZE
Size of one instruction in a.out file.
virtual ~AOutReader()
static const Word FIRST_FU_REGISTER
Index of the first function unit register.
static const Word FIRST_FP_REGISTER
Index of the first floating-point register.
static AOutReader * proto_
Prototype instance of AOutReader registered into BinaryReader.
static const Byte AOUT_BITS_PER_MAU
Minimum addressable word of address space.
void setName(const ReferenceManager::SafePointer *aName)
void setAlign(Byte aAlign)
void setMAU(Byte aMAU)
void setWordSize(Byte aWordSize)
void setUndefinedASpace(ASpaceElement *aSpace)
static void registerBinaryReader(BinaryReader *reader)
void setReadPosition(unsigned int position)
unsigned int readPosition()
unsigned int sizeOfFile()
HalfWord readHalfWord()
void addSection(Section *section)
void setArch(FileArchitecture arch)
@ FT_OBJSEQ
Sequential TTA object code.
Definition Binary.hh:56
@ FA_TTA_TUT
New TTA template.
Definition Binary.hh:70
void setType(FileType type)
void setStrings(StringSection *strTable)
virtual Word length() const
virtual void setDataLength(Word length)
Definition Section.cc:253
static void addObjectReference(SectionIndexKey key, const SafePointable *obj)
void setReferencedSection(Section *section)
static Section * createSection(SectionType type)
Definition Section.cc:91
virtual void addElement(SectionElement *element)
Definition Section.cc:133
@ ST_SYMTAB
Symbol table.
Definition Section.hh:72
@ ST_DATA
Initialized data section.
Definition Section.hh:80
@ ST_STRTAB
String table.
Definition Section.hh:71
@ ST_ADDRSP
Address space section.
Definition Section.hh:77
@ ST_UDATA
Uninitialized data section.
Definition Section.hh:81
@ ST_NULL
NULL Section.
Definition Section.hh:70
@ ST_CODE
Text section.
Definition Section.hh:79
@ ST_RELOC
Relocation section.
Definition Section.hh:74
@ ST_MR
Machine resources section.
Definition Section.hh:78
@ ST_DEBUG
Debug section.
Definition Section.hh:73
void setStartingAddress(AddressImage address)
void setLink(const ReferenceManager::SafePointer *aLink)
void setASpace(const ReferenceManager::SafePointer *addrSpace)
void setName(const ReferenceManager::SafePointer *sectionName)
Chunk * string2Chunk(const std::string &str)
Word SectionOffset
Type for storing offsets relative to a given base offset value.
Word FileOffset
Type for storing absolute file offsets.