OpenASIP 2.2
Loading...
Searching...
No Matches
AOutRelocationSectionReader.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 AOutRelocationSectionReader.cc
26 *
27 * Implementation of AOutRelocationSectionReader class.
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
37#include "RelocElement.hh"
38#include "ReferenceKey.hh"
39#include "SafePointer.hh"
40#include "AOutReader.hh"
41#include "TPEFBaseType.hh"
42#include "RelocSection.hh"
43#include "CodeSection.hh"
44#include "DataSection.hh"
45#include "SectionReader.hh"
48#include "ImmediateElement.hh"
49#include "Swapper.hh"
50
51namespace TPEF {
52
53using std::string;
54
55using ReferenceManager::SectionOffsetKey;
56using ReferenceManager::SectionIndexKey;
57using ReferenceManager::SafePointer;
58
59AOutRelocationSectionReader AOutRelocationSectionReader::proto_;
61
62/**
63 * Constructor.
64 *
65 * Registers itself to AOutSectionReader.
66 */
72
73/**
74 * Destructor.
75 */
78
79/**
80 * Returns the type of section that reader can read.
81 *
82 * @return The type of section that reader can read.
83 */
88
89/**
90 * Reads relocation sections from a.out binary file.
91 *
92 * @param stream The stream to be read from.
93 * @param section Section where to information is stored.
94 * @exception UnreachableStream If reading of section fails.
95 * @exception KeyAlreadyExists Key was in use when trying to register object.
96 * @exception EndOfFile If end of file were reached while it shouldn't.
97 * @exception OutOfRange Some of read values were out of range.
98 * @exception WrongSubclass Some class couldn't do what it was asked for.
99 * @exception UnexpectedValue If there was unexpected value when reading.
100 */
101void
103 BinaryStream& stream, Section* section) const {
104 FileOffset offset = stream.readPosition();
105
106 AOutReader* aOutReader = dynamic_cast<AOutReader*>(parent());
107 assert(aOutReader != NULL);
108
109 // find out whether this is for reading text relocation or data
110 // relocation
111 RelocSection* relocSection = dynamic_cast<RelocSection*>(section);
112 assert(relocSection != NULL);
113
114 const Section* refSection = relocSection->referencedSection();
115 assert(refSection != NULL);
116
117 SectionId refSectionID;
118
119 Word length = 0;
120 if (refSection->isCodeSection()) {
121 refSectionID = AOutReader::ST_TEXT;
122 length = aOutReader->header().sectionSizeTextReloc();
123
124 } else if (refSection->type() == Section::ST_DATA) {
125 refSectionID = AOutReader::ST_DATA;
126 length = aOutReader->header().sectionSizeDataReloc();
127
128 } else {
129 string msg = "Relocating something else than text or data section";
130 throw WrongSubclass(__FILE__, __LINE__, __func__, msg);
131 }
132
133 // all relocation information is read; to offset 'offset+length'
134 for (; stream.readPosition() < offset + length;) {
135
136 // create and read a new relocation element
137 RelocElement* elem = new RelocElement();
138 initializeRelocElement(stream, elem, refSectionID, aOutReader);
139
140 relocSection->addElement(elem);
141 }
142}
143
144/**
145 * Initializes one RelocElement object with correct values.
146 *
147 * @param stream The stream to be read from.
148 * @param elem Element to be initialized.
149 * @param refSectionID Identification code of the section that holds
150 * relocation source.
151 * @param reader The base reader for a.out.
152 * @exception UnexpectedValue If extern bit is not zero, or if relocation
153 * target is not text or data section.
154 * @exception UnreachableStream If stream can't be read.
155 * @exception OutOfRange Section offset of an address is invalid.
156 */
157void
159 BinaryStream& stream, RelocElement* elem, SectionId refSectionID,
160 AOutReader* reader) const {
161 Word r_address = stream.readWord();
162
163 // if referenced section is text section fix r_address to point
164 // starting element of instruction
165 // (r_address pointed in the middle of move to immediate value before)
166 if (refSectionID == AOutReader::ST_TEXT) {
168 }
169
170 SectionOffsetKey sKey = SectionOffsetKey(refSectionID, r_address);
171 elem->setLocation(CREATE_SAFEPOINTER(sKey));
172
173 Word secondWord = stream.readWord();
174
175 Word r_symbolnum = (secondWord >> BYTE_BITWIDTH);
176
177 // addend is value that is stored in element in location pointed by
178 // r_address
179 AddressImage r_addend = stream.readWord();
180
181 // It seems that extern flag and addend field is used to tell does
182 // relocation have symbol or section index in symbolnum field.
183 // If there is symbol it means that relocation is unresolved.
184
185 // NOTE: above doesn't work if there is relocation to the
186 // first instruction of program in this case secondWord seems to
187 // be always 1026...
188 if (r_addend == 0 && checkIfExtern(secondWord) && secondWord != 1026) {
189 SectionIndexKey indexKey(AOutReader::ST_SYMBOL, r_symbolnum + 1);
190 elem->setSymbol(CREATE_SAFEPOINTER(indexKey));
191
192 } else {
193 // if we are here r_symbolnum is a section id, not a symbol index
195 elem->setSymbol(CREATE_SAFEPOINTER(undefSym));
196
197 Word r_offset = reader->sectionOffsetOfAddress(r_addend);
198
199 SectionOffsetKey offKey =
200 SectionOffsetKey(r_symbolnum, r_offset);
201
202 elem->setDestination(CREATE_SAFEPOINTER(offKey));
203 }
204
205 // convert and set relocation type
206 RelocType r_type =
207 static_cast<RelocType>(secondWord & RELOCATION_TYPE_MASK);
208
209 elem->setType(aOutToTPEFRelocType(r_type));
210
211 elem->setSize(sizeof(Word)*BYTE_BITWIDTH);
212}
213
214/**
215 * Finalizer method for AOut relocation sections.
216 *
217 * Fixes values of elements pointed by location(), MOVE linker does not
218 * update values of elements referred from relocation. Also sets address
219 * spaces for relocation elements.
220 *
221 * @param section Section to finalize.
222 */
223void
225
226 Section *refSection =
227 dynamic_cast<RelocSection*>(section)->referencedSection();
228
229 AOutReader *aOutReader = dynamic_cast<AOutReader*>(parent());
230 assert(aOutReader != NULL);
231
232 for (Word i = 0;
233 i != section->elementCount();
234 i++) {
235
236 RelocElement *elem = dynamic_cast<RelocElement*>(section->element(i));
237
238 // address space of section where element is or undef aSpace
239 elem->setASpace(
240 dynamic_cast<AOutReader*>
241 (parent())->aSpaceOfElement(elem->destination()));
242
243 // relocation is unresolved.
244 if (elem->destination() == NULL) continue;
245
246 AddressImage destAddress =
247 aOutReader->addressOfElement(elem->destination());
248
249 // fix value of immediate or chunk
250 if (refSection->isCodeSection()) {
251
252 // value of immediate element, is file offset to
253 // that element, which to immediate refers
254 ImmediateElement *imm =
255 dynamic_cast<ImmediateElement*>(elem->location());
256
257 // relocation must have Immediate or Chunk element as location
258 assert(imm != NULL);
259
260 // fix the address value
261 imm->setWord(destAddress);
262
263 } else if (refSection->type() == Section::ST_DATA) {
264 Chunk* dataChunk = dynamic_cast<Chunk*>(elem->location());
265 DataSection* dataSection = dynamic_cast<DataSection*>(refSection);
266
267 // check that section is long enough
268 if (dataChunk->offset() + sizeof(destAddress) >
269 dataSection->length()) {
270 bool requestedChunkWasOutOfRange = false;
271 assert(requestedChunkWasOutOfRange);
272 }
273
274 // fix address of chunk
275 Word mauIndex = dataSection->chunkToMAUIndex(dataChunk);
276
277 dataSection->writeValue(
278 mauIndex, 4, static_cast<unsigned long>(destAddress));
279
280 } else {
281 bool referencedSectionMustBeEitherCodeOrData = false;
282 assert(referencedSectionMustBeEitherCodeOrData);
283 }
284 }
285}
286
287/**
288 * Converts a.out relocation type into TPEF relocation.
289 *
290 * @param aOutRelocType Identification code of the relocation type to convert
291 * to TPEF format.
292 * @return TPEF relocation type.
293 */
296 RelocType aOutRelocType) const {
297
298 // NOTE: check this conversion.
299
300 switch (aOutRelocType) {
301 case RELOC_8:
302 case RELOC_16:
303 case RELOC_32:
305 case NO_RELOC:
307 default: {
308 bool unknownAOutRelocationType = false;
309 assert(unknownAOutRelocationType);
310 }
311 }
312
313 // to prevent compile warnings
315}
316
317}
#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
Word sectionSizeDataReloc() const
Word sectionSizeTextReloc() const
AddressImage addressOfElement(SectionElement *elem) const
@ ST_SYMBOL
Symbol table.
@ ST_DATA
Data section.
@ ST_TEXT
Text section.
SectionOffset sectionOffsetOfAddress(AddressImage address) const
ASpaceElement * aSpaceOfElement(SectionElement *elem) const
static const Header & header()
static AOutRelocationSectionReader proto_
Class-wide (unique) prototype instance of AOutRelocationSectionReader registered into SectionReader.
static const Byte RELOCATION_TYPE_MASK
Mask for extracting relocation type.
virtual void finalize(Section *section) const
virtual Section::SectionType type() const
bool checkIfExtern(Word word) const
virtual void readData(BinaryStream &stream, Section *section) const
RelocElement::RelocType aOutToTPEFRelocType(RelocType aOutRelocType) const
void initializeRelocElement(BinaryStream &stream, RelocElement *elem, SectionId refSectionID, AOutReader *reader) const
virtual BinaryReader * parent() const
unsigned int readPosition()
SectionOffset offset() const
virtual Word length() const
virtual void writeValue(Word index, Word numOfMAUs, unsigned long value)
void setWord(Word aValue)
virtual Word chunkToMAUIndex(const Chunk *chunk) const
Definition Section.cc:341
SectionElement * destination() const
void setASpace(ASpaceElement *anASpace)
void setLocation(SectionElement *aLocation)
void setSize(Byte aSize)
void setSymbol(SymbolElement *aSymbol)
void setType(RelocType aType)
@ RT_SELF
Absolute address, relocate relative to address self.
@ RT_NOREL
No relocation.
SectionElement * location() const
void setDestination(SectionElement *aDestination)
Section * referencedSection() const
static void registerSectionReader(const SectionReader *sReader)
virtual void addElement(SectionElement *element)
Definition Section.cc:133
@ ST_DATA
Initialized data section.
Definition Section.hh:80
@ ST_RELOC
Relocation section.
Definition Section.hh:74
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.
HalfWord SectionId
Type for storing binary file section ids.
Word FileOffset
Type for storing absolute file offsets.