OpenASIP  2.0
AOutReader.icc
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.icc
26  *
27  * Inline implementations of AOutReader.
28  *
29  * @author Jussi Nykänen 2003 (nykanen-no.spam-cs.tut.fi)
30  * @author Mikael Lepistö 18.12.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 "SectionReader.hh"
37 #include "InstructionElement.hh"
38 #include "BinaryStream.hh"
39 
40 namespace TPEF {
41 
42 //////////////////////////////////////////////////////////////////////////
43 /// AOutReader class
44 //////////////////////////////////////////////////////////////////////////
45 
46 /**
47  * Returns an instance of BinaryReader.
48  *
49  * Returns a.out binary reader instance, if called first time
50  * also creates instance.
51  *
52  * @return Binary reader instance of a.out binaries.
53  */
54 inline BinaryReader*
55 AOutReader::instance() {
56 
57  if (proto_ == NULL) {
58  proto_ = new AOutReader();
59  }
60 
61  return proto_;
62 }
63 
64 /**
65  * Returns processors resource section of binary.
66  *
67  * @return Processors resource table of binary.
68  */
69 inline ResourceSection*
70 AOutReader::resourceTable() const {
71  return resourceTable_;
72 }
73 
74 /**
75  * Returns null section of binary.
76  *
77  * @return Null section of binary.
78  */
79 inline NullSection*
80 AOutReader::nullSection() const {
81  return nullSection_;
82 }
83 
84 /**
85  * Returns debug section of binary.
86  *
87  * @return Debug section of binary.
88  */
89 inline DebugSection*
90 AOutReader::debugSection() const {
91  return debugSection_;
92 }
93 
94 /**
95  * Returns string section of binary.
96  *
97  * @return String section of binary.
98  */
99 inline StringSection*
100 AOutReader::stringSection() const {
101  return stringSection_;
102 }
103 
104 /**
105  * Returns text section of binary.
106  *
107  * @return Text section of binary.
108  */
109 inline CodeSection*
110 AOutReader::textSection() const {
111  return textSection_;
112 }
113 
114 /**
115  * Returns address space where where element reside.
116  *
117  * Memory map of a.out starts from instruction memory (text section) and
118  * continues by initialized data section. Finally uninitialized data
119  * (bss sectin) is found after initialized data.
120  *
121  * @param elem Element whose address space is returned.
122  * @return Address space where element resides.
123  * @exception OutOfRange If requested element is outside sections.
124  */
125 inline ASpaceElement*
126 AOutReader::aSpaceOfElement(SectionElement* elem) const {
127  if (elem == NULL) {
128  return undefASpace_;
129  }
130 
131  // Check if we need to return code or data address space
132  InstructionElement *instruction = dynamic_cast<InstructionElement*>(elem);
133  Chunk *chunk = dynamic_cast<Chunk*>(elem);
134 
135  if (instruction != NULL) {
136  return codeASpace_;
137 
138  } else if (chunk != NULL) {
139  return dataASpace_;
140 
141  } else {
142  assert(false);
143  }
144 
145  bool cantFindASpaceOfElement = false;
146  assert(cantFindASpaceOfElement);
147  return NULL;
148 }
149 
150 /**
151  * Returns element's address in TPEF representation.
152  *
153  * In generated TPEF we have one instruction or MAU per address.
154  * Code section starts from 0x00 and after that is normal data
155  * section and uninitialised data is the last one.
156  *
157  * @param elem Element whose address is returned.
158  * @return Address where element resides in memory image.
159  * @exception OutOfRange If requested element is outside sections.
160  */
161 inline AddressImage
162 AOutReader::addressOfElement(SectionElement* elem) const {
163  // Section offset and identification code of destination element to find
164  ReferenceManager::SectionOffsetKey elemSectionOffsetKey =
165  ReferenceManager::SafePointer::sectionOffsetKeyFor(elem);
166 
167  // calculate memory address, abort if it's too big
168  Word address = elemSectionOffsetKey.offset();
169 
170  if (elemSectionOffsetKey.sectionId() == AOutReader::ST_TEXT) {
171  assert(address < header_.sectionSizeText());
172 
173  // code section conversion to 1 address / instruction if address
174  // points to code section
175  address = address / AOutReader::AOUT_INSTRUCTION_SIZE;
176 
177  } else if (elemSectionOffsetKey.sectionId() == AOutReader::ST_DATA) {
178  assert(address < header_.sectionSizeData());
179  address += header_.sectionSizeText();
180 
181  } else if (elemSectionOffsetKey.sectionId() == AOutReader::ST_UDATA) {
182  assert(address < header_.sectionSizeUData());
183  address += header_.sectionSizeText() + header_.sectionSizeData();
184 
185  } else {
186  bool cantFindAddressForElement = false;
187  assert(cantFindAddressForElement);
188  }
189 
190  return address;
191 }
192 
193 /**
194  * Returns section offset of element in given memory address.
195  *
196  * @param address Memory address of object.
197  * @return The section offset of same object.
198  * @exception OutOfRange If address in not in binary file.
199  */
200 inline SectionOffset
201 AOutReader::sectionOffsetOfAddress(AddressImage address) const {
202  SectionOffset endOfText = header_.sectionSizeText();
203  SectionOffset endOfData = endOfText + header_.sectionSizeData();
204  SectionOffset endOfUData = endOfData + header_.sectionSizeUData();
205 
206  if (address < endOfText) {
207  return address;
208 
209  } else if (address < endOfData) {
210  return address - endOfText;
211 
212  } else if (address < endOfUData) {
213  return address - endOfData;
214 
215  } else {
216  std::string method = "AOutReader::sectionOffsetOfAddress";
217  std::string msg = "Section offset out of memory image";
218  throw OutOfRange(__FILE__, __LINE__, method, msg);
219  }
220 }
221 
222 /**
223  * Returns header of A.out file.
224  *
225  * @return File header of last read a.out binary.
226  */
227 inline const AOutReader::Header&
228 AOutReader::header() {
229  return header_;
230 }
231 
232 /**
233  * Reads section from stream.
234  *
235  * @param stream The stream to be read from.
236  * @param startPosition Position where reading begin.
237  * @param section The section to which data is stored.
238  * @param length The length of section.
239  * @exception InstanceNotFound If section reader for reading wasn't found.
240  * @exception UnreachableStream If reading of section fails.
241  * @exception KeyAlreadyExists Key was in use when trying to register object.
242  * @exception EndOfFile If end of file were reached while it shouldn't.
243  * @exception OutOfRange Some of read values were out of range.
244  * @exception WrongSubclass Some class couldn't do what it was asked for.
245  * @exception UnexpectedValue If there was unexpected value when reading.
246  */
247 inline void
248 AOutReader::readSection(
249  BinaryStream& stream, FileOffset startPosition, Section* section,
250  Length length) const {
251  stream.setReadPosition(startPosition);
252 
253  if (length > 0) {
254  SectionReader::readSection(stream, section, proto_);
255  }
256 }
257 
258 /**
259  * Adds section to binary, if section has elements inside.
260  *
261  * If section does not contain elements, section will be deleted.
262  *
263  * @param section Section to add or delete.
264  * @param bin Binary, where to add section.
265  */
266 inline void
267 AOutReader::addOrDeleteSection(Section* section, Binary* bin) const {
268  // if section is not empty
269  assert(section != NULL);
270  if (((section)->isChunkable() &&
271  dynamic_cast<RawSection*>(section)->length() > 0) ||
272  (!section->isChunkable() &&
273  section->elementCount() != 0)) {
274  bin->addSection(section);
275  } else {
276  delete section;
277  section = NULL;
278  }
279 }
280 
281 //////////////////////////////////////////////////////////////////////////
282 /// Header class
283 //////////////////////////////////////////////////////////////////////////
284 
285 
286 /**
287  * Sets size for data section.
288  *
289  * @param size The size of the section.
290  */
291 inline void
292 AOutReader::Header::setSectionSizeData(Word size) {
293  sizes_.data_ = size;
294 }
295 
296 
297 /**
298  * Sets size for uninitialized data section.
299  *
300  * @param size The size of the section.
301  */
302 inline void
303 AOutReader::Header::setSectionSizeUData(Word size) {
304  sizes_.uData_ = size;
305 }
306 
307 
308 /**
309  * Sets size for text section.
310  *
311  * @param size The size of the section.
312  */
313 inline void
314 AOutReader::Header::setSectionSizeText(Word size) {
315  sizes_.text_ = size;
316 }
317 
318 
319 /**
320  * Sets size symbol table sections.
321  *
322  * @param size The size of the section.
323  */
324 inline void
325 AOutReader::Header::setSectionSizeSymbol(Word size) {
326  sizes_.symbol_ = size;
327 }
328 
329 
330 /**
331  * Sets size for text relocation section.
332  *
333  * @param size The size of the section.
334  */
335 inline void
336 AOutReader::Header::setSectionSizeTextReloc(Word size) {
337  sizes_.textReloc_ = size;
338 }
339 
340 
341 /**
342  * Sets size for data relocation sections.
343  *
344  * @param size The size of the section.
345  */
346 inline void
347 AOutReader::Header::setSectionSizeDataReloc(Word size) {
348  sizes_.dataReloc_ = size;
349 }
350 
351 
352 /**
353  * Sets size for data relocation sections.
354  *
355  * @param size The size of the section.
356  */
357 inline void
358 AOutReader::Header::setSectionSizeString(Word size) {
359  sizes_.string_ = size;
360 }
361 
362 /**
363  * Returns the size of the data section.
364  *
365  * @return The size of the section in Bytes.
366  */
367 inline Word
368 AOutReader::Header::sectionSizeData() const {
369  return sizes_.data_;
370 }
371 
372 
373 /**
374  * Returns the size of the uninitialized data section.
375  *
376  * @return The size of the section in Bytes.
377  */
378 inline Word
379 AOutReader::Header::sectionSizeUData() const {
380  return sizes_.uData_;
381 }
382 
383 
384 /**
385  * Returns the size of the text section.
386  *
387  * @return The size of the section in Bytes.
388  */
389 inline Word
390 AOutReader::Header::sectionSizeText() const {
391  return sizes_.text_;
392 }
393 
394 
395 /**
396  * Returns the size of the symbol section.
397  *
398  * @return The size of the section in Bytes.
399  */
400 inline Word
401 AOutReader::Header::sectionSizeSymbol() const {
402  return sizes_.symbol_;
403 }
404 
405 
406 /**
407  * Returns the size of the text relocation section.
408  *
409  * @return The size of the section in Bytes.
410  */
411 inline Word
412 AOutReader::Header::sectionSizeTextReloc() const {
413  return sizes_.textReloc_;
414 }
415 
416 
417 /**
418  * Returns the size of the data relocation section.
419  *
420  * @return The size of the section in Bytes.
421  */
422 inline Word
423 AOutReader::Header::sectionSizeDataReloc() const {
424  return sizes_.dataReloc_;
425 }
426 
427 
428 /**
429  * Returns the size of the string section.
430  *
431  * @return The size of the section in Bytes.
432  */
433 inline Word
434 AOutReader::Header::sectionSizeString() const {
435  return sizes_.string_;
436 }
437 
438 }