OpenASIP 2.2
Loading...
Searching...
No Matches
TPEFRelocSectionReader.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 TPEFRelocSectionReader.cc
26 *
27 * Definition of TPEFRelocSectionReader class.
28 *
29 * @author Mikael Lepistö 2003 (tmlepist-no.spam-cs.tut.fi)
30 *
31 * @note rating: yellow
32 */
33
34#include <cmath> // ceil()
35
36#include "boost/format.hpp"
37
39#include "SafePointer.hh"
40#include "Exception.hh"
41#include "ReferenceKey.hh"
42#include "SectionReader.hh"
43#include "TPEFBaseType.hh"
44#include "BinaryStream.hh"
45#include "RelocSection.hh"
46#include "RelocElement.hh"
47#include "ImmediateElement.hh"
48
49#include "TPEFHeaders.hh"
50#include "ASpaceSection.hh"
51#include "CodeSection.hh"
52#include "DataSection.hh"
53#include "LEDataSection.hh"
54
55#include "TPEFBaseType.hh"
56#include "Locator.hh"
57
58#include "Swapper.hh"
59
60#include "MathTools.hh"
61
62namespace TPEF {
63
64using ReferenceManager::SafePointer;
65using ReferenceManager::SectionKey;
66using ReferenceManager::SectionIndexKey;
67using ReferenceManager::SectionOffsetKey;
68
69TPEFRelocSectionReader TPEFRelocSectionReader::proto_;
71
72/**
73 * Constructor.
74 *
75 * Registers itself to SectionReader.
76 */
80
81/**
82 * Destructor.
83 */
86
87/**
88 * Returns the type of section which the reader can read.
89 *
90 * @return The type of section which reader can read.
91 */
96
97/**
98 * Reads section data from TPEF binary file.
99 *
100 * @param stream Stream to be read from.
101 * @param section Section where the information is to be stored.
102 * @exception UnreachableStream If reading of section fails.
103 * @exception KeyAlreadyExists Key was in use when trying to register object.
104 * @exception EndOfFile If end of file were reached while it shouldn't.
105 * @exception OutOfRange Some of read values were out of range.
106 * @exception WrongSubclass Some class couldn't do what it was asked for.
107 * @exception UnexpectedValue Ift here was unexpected value when reading.
108 */
109void
111 // base classes implementation must be called with these.
112 TPEFSectionReader::readData(stream, section);
113
114 RelocSection* relocSection = dynamic_cast<RelocSection*>(section);
115 assert(relocSection != NULL);
116
117 // check that link section is defined properly
118 assert(header().linkId != 0);
119
120 if (!section->noBits()) {
121
122 // store start of first element
123 SectionOffset elementStart = header().bodyOffset;
124 SectionIndex id = 0;
125
126 while (elementStart + header().elementSize <=
127 header().bodyOffset + header().bodyLength) {
128
129 RelocElement *elem = new RelocElement();
130
131 SectionIndexKey sectionIndexKey(header().sectionId, id);
132 SafePointer::addObjectReference(sectionIndexKey, elem);
133
134 // r_offset is source element section offset
135 Word rOffset = stream.readWord();
136 SectionOffsetKey sKey(refSectionId_, rOffset);
137 elem->setLocation(CREATE_SAFEPOINTER(sKey));
138
139 // r_symbol
140 Word rSymbol = stream.readWord();
141 SectionIndexKey indexKey(header().linkId, rSymbol);
142 elem->setSymbol(CREATE_SAFEPOINTER(indexKey));
143
144 // r_type
145 Byte rType = stream.readByte();
146 elem->setType(
147 static_cast<RelocElement::RelocType>(
149
150 elem->setChunked(rType & TPEFHeaders::STF_CHUNK);
151
152 // r_asp
153 Byte rASP = stream.readByte();
154 SectionIndexKey aSpaceIndexKey(
155 dynamic_cast<TPEFReader*>(parent())->aSpaceId(), rASP);
156 elem->setASpace(CREATE_SAFEPOINTER(aSpaceIndexKey));
157
158 // r_size
159 elem->setSize(stream.readByte());
160
161 // r_bitpos skipped for now
162 elem->setBitOffset(stream.readByte());
163
164 section->addElement(elem);
165
166 elementStart += header().elementSize;
167 stream.setReadPosition(elementStart);
168
169 id++;
170 }
171 }
172}
173
174/**
175 * Finalizer method for TPEF relocation sections.
176 *
177 * Resolves destination fields of relocation elements.
178 *
179 * @param section Section to finalize.
180 */
181void
183
184 Section *refSection =
185 dynamic_cast<RelocSection*>(section)->referencedSection();
186
187 TPEFReader* tpefReader = dynamic_cast<TPEFReader*>(parent());
188
189 for (Word i = 0; i < section->elementCount(); i++) {
190
191 RelocElement *elem =
192 dynamic_cast<RelocElement*>(section->element(i));
193
194 assert(elem->location() != NULL);
195
196 // file offset of destination element to find
197 AddressImage address = 0;
198
199 // should we dig up code or data section
200 if (refSection->isCodeSection()) {
201
202 // value of immediate element, is an address to that element,
203 // which to immediate refers
204 ImmediateElement *imm =
205 dynamic_cast<ImmediateElement*>(elem->location());
206
207 // relocation must have Immediate or Chunk element as location
208 assert(imm != NULL);
209 assert(imm->length() <= sizeof(address));
210
211 // read destination address of relocation
212 unsigned int neededBits = MathTools::requiredBits(imm->word());
213 if (neededBits > elem->size()) {
214 throw OutOfRange(
215 __FILE__, __LINE__, __func__,
216 (boost::format(
217 "Destination address width %d of relocation is "
218 "bigger than the field size %d.")
219 % neededBits % elem->size()).str());
220 }
221
222 address = imm->word();
223
224
225 } else if (refSection->type() == Section::ST_DATA) {
226
227 try {
228 DataSection *dataSect =
229 dynamic_cast<DataSection*>(refSection);
230
231 int startIndex =
232 dataSect->chunkToMAUIndex(
233 dynamic_cast<Chunk*>(elem->location()));
234
235 int mauSize = dataSect->aSpace()->MAU();
236
237 // BE
238 for (int i = 0; i < elem->size() / mauSize; i++) {
239 address = address << mauSize;
240 address = address | dataSect->MAU(startIndex+i);
241 }
242
243 } catch (const OutOfRange &e) {
244 bool requestedChunkWasOutOfRange = false;
245 assert(requestedChunkWasOutOfRange);
246 }
247
248 } else if (refSection->type() == Section::ST_LEDATA) {
249
250 try {
251 LEDataSection *dataSect =
252 dynamic_cast<LEDataSection*>(refSection);
253
254 int startIndex =
255 dataSect->chunkToMAUIndex(
256 dynamic_cast<Chunk*>(elem->location()));
257
258 int mauSize = dataSect->aSpace()->MAU();
259
260 // LE
261 for (int i = 0; i < elem->size() / mauSize; i++) {
262 address |= (dataSect->MAU(startIndex+i) << (mauSize*i));
263 }
264
265 } catch (const OutOfRange &e) {
266 bool requestedChunkWasOutOfRange = false;
267 assert(requestedChunkWasOutOfRange);
268 }
269
270
271
272 } else {
273 bool referencedSectionMustBeEitherCodeOrData = false;
274 assert(referencedSectionMustBeEitherCodeOrData);
275 }
276
277 // if unresolved relocation leave destination to undefined
278 if (tpefReader->aSpaceSection()->isUndefined(elem->aSpace())) {
279 continue;
280 }
281
282 // absolute address depending on relocation type and value
283 AddressImage absoluteAddress =
284 Locator::absoluteAddress(address, elem->type());
285
286 // here we need to resolve section of section referenced
287 // by value of location
288 Section *destSection =
289 tpefReader->sectionOfAddress(elem->aSpace(), absoluteAddress);
290
291 assert(destSection != NULL);
292
293 // do the magic!
294
295 // find section identification code
296 SectionId destSectionId =
298
299 SectionOffset sectOffsetOfElement;
300
301 // if code section check instructionsize and encoding from
302 // refSection...
303 if (destSection->isCodeSection()) {
304 CodeSection *codeSection =
305 dynamic_cast<CodeSection*>(destSection);
306
307 // find instruction number of absolute address
308 Word instructionNumber =
309 absoluteAddress - codeSection->startingAddress();
310
311 // every index is stored for every instruction element that is
312 // start of instruction
313 SectionIndexKey sectIndexKey(destSectionId, instructionNumber);
314 elem->setDestination(CREATE_SAFEPOINTER(sectIndexKey));
315
316 } else {
317
318 Word mauInBytes =
319 static_cast<Word>(
320 ceil(static_cast<double>(elem->aSpace()->MAU()) /
321 static_cast<double>(BYTE_BITWIDTH)));
322
323 // else find just section offset
324 sectOffsetOfElement =
325 (absoluteAddress - destSection->startingAddress()) *
326 mauInBytes;
327
328 SectionOffsetKey sectOffKey(destSectionId, sectOffsetOfElement);
329 elem->setDestination(CREATE_SAFEPOINTER(sectOffKey));
330 }
331 }
332}
333
334/**
335 * Reads info field of section header.
336 *
337 * Read position of stream will be moved 4 bytes forward.
338 *
339 * @param stream Stream where from info word is read.
340 * @param section Reloc section whose info field is read.
341 */
342void
344 Section* sect) const {
345
346 // referenced section identifier is in first 2 bytes of info field
347 refSectionId_ = stream.readHalfWord();
348
349 if (refSectionId_ != 0) {
351 dynamic_cast<RelocSection*>(sect)->setReferencedSection(
352 CREATE_SAFEPOINTER(sKey));
353 } else {
354 bool referencedSectionOfRelocationMustNotBeNullSection = false;
355 assert(referencedSectionOfRelocationMustNotBeNullSection);
356 }
357
358 // skip rest 2 of 4 bytes
359 stream.readHalfWord();
360}
361
362}
#define __func__
#define assert(condition)
UInt32 AddressImage
Type for storing addresses to memory image.
Definition BaseType.hh:179
const Byte BYTE_BITWIDTH
Definition BaseType.hh:136
unsigned char Byte
Definition BaseType.hh:116
static int requiredBits(unsigned long int number)
Byte MAU() const
bool isUndefined(ASpaceElement *aSpace) const
void setReadPosition(unsigned int position)
HalfWord readHalfWord()
virtual MinimumAddressableUnit MAU(Word index) const
unsigned int length() const
static AddressImage absoluteAddress(AddressImage relocationValue, RelocElement::RelocType relocType)
Definition Locator.cc:46
virtual Word chunkToMAUIndex(const Chunk *chunk) const
Definition Section.cc:341
static void addObjectReference(SectionIndexKey key, const SafePointable *obj)
static SectionKey sectionKeyFor(const SafePointable *obj)
void setASpace(ASpaceElement *anASpace)
void setLocation(SectionElement *aLocation)
ASpaceElement * aSpace() const
void setBitOffset(Byte anOffset)
RelocType type() const
void setSize(Byte aSize)
void setSymbol(SymbolElement *aSymbol)
void setChunked(bool isChunked)
void setType(RelocType aType)
SectionElement * location() const
void setDestination(SectionElement *aDestination)
Byte size() const
static void registerSectionReader(const SectionReader *sReader)
AddressImage startingAddress() const
virtual void addElement(SectionElement *element)
Definition Section.cc:133
@ ST_DATA
Initialized data section.
Definition Section.hh:80
@ ST_LEDATA
Initialized little endian data section.
Definition Section.hh:82
@ ST_RELOC
Relocation section.
Definition Section.hh:74
bool noBits() const
SectionElement * element(Word index) const
virtual bool isCodeSection() const
Definition Section.hh:143
Word elementCount() const
virtual SectionType type() const =0
Returns SectioType of actual section instance.
ASpaceElement * aSpace() const
ASpaceSection * aSpaceSection() const
Section * sectionOfAddress(const ASpaceElement *aSpaceId, AddressImage address) const
void readInfo(BinaryStream &stream, Section *sect) const
static SectionId refSectionId_
Section id of last referenced section.
static TPEFRelocSectionReader proto_
Prototype instance of TPEFRelocSectionReader to be registered to SectionReader.
virtual void finalize(Section *section) const
virtual Section::SectionType type() const
virtual void readData(BinaryStream &stream, Section *section) const
virtual BinaryReader * parent() const
virtual void readData(BinaryStream &stream, Section *section) const
static const Header & header()
@ STF_RELOCATION_TYPE_MASK
Mask for getting reloc type.
@ STF_CHUNK
Relocation applied to chunk(1) or complete address(0).
HalfWord SectionId
Type for storing binary file section ids.
Word SectionIndex
Type for storing section indexes.
Word SectionOffset
Type for storing offsets relative to a given base offset value.