OpenASIP  2.0
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"
47 #include "AOutTextSectionReader.hh"
48 #include "ImmediateElement.hh"
49 #include "Swapper.hh"
50 
51 namespace TPEF {
52 
53 using std::string;
54 
55 using ReferenceManager::SectionOffsetKey;
56 using ReferenceManager::SectionIndexKey;
57 using ReferenceManager::SafePointer;
58 
59 AOutRelocationSectionReader AOutRelocationSectionReader::proto_;
61 
62 /**
63  * Constructor.
64  *
65  * Registers itself to AOutSectionReader.
66  */
69 
71 }
72 
73 /**
74  * Destructor.
75  */
77 }
78 
79 /**
80  * Returns the type of section that reader can read.
81  *
82  * @return The type of section that reader can read.
83  */
86  return Section::ST_RELOC;
87 }
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  */
101 void
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  */
157 void
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  */
223 void
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:
304  return RelocElement::RT_SELF;
305  case NO_RELOC:
306  return RelocElement::RT_NOREL;
307  default: {
308  bool unknownAOutRelocationType = false;
309  assert(unknownAOutRelocationType);
310  }
311  }
312 
313  // to prevent compile warnings
314  return RelocElement::RT_NOREL;
315 }
316 
317 }
TPEF::SectionId
HalfWord SectionId
Type for storing binary file section ids.
Definition: TPEFBaseType.hh:43
TPEF::BinaryStream::readPosition
unsigned int readPosition()
Definition: BinaryStream.cc:561
TPEF::AOutTextSectionReader::OFFSET_TO_IMMEDIATE_VALUE
static const int OFFSET_TO_IMMEDIATE_VALUE
Definition: AOutTextSectionReader.hh:51
AOutRelocationSectionReader.hh
TPEF::Section::type
virtual SectionType type() const =0
Returns SectioType of actual section instance.
TPEF::BinaryStream
Definition: BinaryStream.hh:59
TPEF::ImmediateElement::setWord
void setWord(Word aValue)
SafePointer.hh
TPEF::DataSection
Definition: DataSection.hh:52
TPEF::ImmediateElement
Definition: ImmediateElement.hh:49
TPEF::AOutRelocationSectionReader::RELOCATION_TYPE_MASK
static const Byte RELOCATION_TYPE_MASK
Mask for extracting relocation type.
Definition: AOutRelocationSectionReader.hh:94
TPEF::RelocSection::referencedSection
Section * referencedSection() const
Byte
unsigned char Byte
Definition: BaseType.hh:116
TPEF::ReferenceManager::SectionIndexKey
Definition: ReferenceKey.hh:65
TPEF::AOutReader::addressOfElement
AddressImage addressOfElement(SectionElement *elem) const
ImmediateElement.hh
TPEF::RelocSection
Definition: RelocSection.hh:47
TPEF::Section
Definition: Section.hh:64
TPEF::AOutRelocationSectionReader::initializeRelocElement
void initializeRelocElement(BinaryStream &stream, RelocElement *elem, SectionId refSectionID, AOutReader *reader) const
Definition: AOutRelocationSectionReader.cc:158
TPEF::AOutRelocationSectionReader::aOutToTPEFRelocType
RelocElement::RelocType aOutToTPEFRelocType(RelocType aOutRelocType) const
Definition: AOutRelocationSectionReader.cc:295
AOutSymbolSectionReader.hh
TPEF::Section::element
SectionElement * element(Word index) const
assert
#define assert(condition)
Definition: Application.hh:86
TPEF::Section::addElement
virtual void addElement(SectionElement *element)
Definition: Section.cc:133
TPEF::AOutRelocationSectionReader::type
virtual Section::SectionType type() const
Definition: AOutRelocationSectionReader.cc:85
RelocSection.hh
TPEF::AOutRelocationSectionReader::RELOC_16
@ RELOC_16
2 bytes relocation
Definition: AOutRelocationSectionReader.hh:70
TPEF::Section::ST_DATA
@ ST_DATA
Initialized data section.
Definition: Section.hh:80
TPEF::AOutReader
Definition: AOutReader.hh:54
TPEF::RelocElement::setType
void setType(RelocType aType)
TPEF::AOutSectionReader::parent
virtual BinaryReader * parent() const
Definition: AOutSectionReader.cc:57
TPEF::RelocElement::RT_SELF
@ RT_SELF
Absolute address, relocate relative to address self.
Definition: RelocElement.hh:58
WrongSubclass
Definition: Exception.hh:336
TPEF::AOutRelocationSectionReader::RelocType
RelocType
Definition: AOutRelocationSectionReader.hh:68
TPEF::RelocElement::setSize
void setSize(Byte aSize)
SectionReader.hh
TPEF::RelocElement::destination
SectionElement * destination() const
__func__
#define __func__
Definition: Application.hh:67
TPEF::AOutRelocationSectionReader::readData
virtual void readData(BinaryStream &stream, Section *section) const
Definition: AOutRelocationSectionReader.cc:102
TPEF::FileOffset
Word FileOffset
Type for storing absolute file offsets.
Definition: TPEFBaseType.hh:52
RelocElement.hh
TPEF::AOutRelocationSectionReader::finalize
virtual void finalize(Section *section) const
Definition: AOutRelocationSectionReader.cc:224
TPEF::RelocElement::setSymbol
void setSymbol(SymbolElement *aSymbol)
TPEF::SectionReader::registerSectionReader
static void registerSectionReader(const SectionReader *sReader)
Definition: SectionReader.cc:145
DataSection.hh
TPEF::RelocElement::setLocation
void setLocation(SectionElement *aLocation)
TPEF::AOutRelocationSectionReader::AOutRelocationSectionReader
AOutRelocationSectionReader()
Definition: AOutRelocationSectionReader.cc:67
TPEF::AOutReader::ST_TEXT
@ ST_TEXT
Text section.
Definition: AOutReader.hh:116
TPEF::AOutReader::aSpaceOfElement
ASpaceElement * aSpaceOfElement(SectionElement *elem) const
TPEF::RelocElement
Definition: RelocElement.hh:51
AddressImage
UInt32 AddressImage
Type for storing addresses to memory image.
Definition: BaseType.hh:179
TPEF::AOutRelocationSectionReader::proto_
static AOutRelocationSectionReader proto_
Class-wide (unique) prototype instance of AOutRelocationSectionReader registered into SectionReader.
Definition: AOutRelocationSectionReader.hh:91
TPEF::RelocElement::RT_NOREL
@ RT_NOREL
No relocation.
Definition: RelocElement.hh:57
TPEF::AOutReader::header
static const Header & header()
TPEF::AOutReader::Header::sectionSizeTextReloc
Word sectionSizeTextReloc() const
TPEF::Chunk::offset
SectionOffset offset() const
TPEF::AOutRelocationSectionReader::checkIfExtern
bool checkIfExtern(Word word) const
Swapper.hh
AOutReader.hh
BYTE_BITWIDTH
const Byte BYTE_BITWIDTH
Definition: BaseType.hh:136
TPEF::AOutReader::sectionOffsetOfAddress
SectionOffset sectionOffsetOfAddress(AddressImage address) const
TPEF::AOutSectionReader
Definition: AOutSectionReader.hh:45
TPEF::AOutRelocationSectionReader::~AOutRelocationSectionReader
virtual ~AOutRelocationSectionReader()
Definition: AOutRelocationSectionReader.cc:76
AOutTextSectionReader.hh
TPEF::AOutReader::Header::sectionSizeDataReloc
Word sectionSizeDataReloc() const
TPEF::Section::ST_RELOC
@ ST_RELOC
Relocation section.
Definition: Section.hh:74
TPEF::AOutReader::ST_SYMBOL
@ ST_SYMBOL
Symbol table.
Definition: AOutReader.hh:119
TPEF::ReferenceManager::SectionOffsetKey
Definition: ReferenceKey.hh:93
TPEF::RelocElement::setASpace
void setASpace(ASpaceElement *anASpace)
TPEF::Section::SectionType
SectionType
Definition: Section.hh:69
TPEF::DataSection::length
virtual Word length() const
Definition: DataSection.cc:210
TPEF::AOutRelocationSectionReader::RELOC_8
@ RELOC_8
1 byte relocation
Definition: AOutRelocationSectionReader.hh:69
TPEF::RelocElement::RelocType
RelocType
Definition: RelocElement.hh:56
TPEF::RelocElement::setDestination
void setDestination(SectionElement *aDestination)
TPEFBaseType.hh
TPEF::AOutRelocationSectionReader::NO_RELOC
@ NO_RELOC
no relocation
Definition: AOutRelocationSectionReader.hh:72
TPEF::RelocElement::location
SectionElement * location() const
TPEF::Section::isCodeSection
virtual bool isCodeSection() const
Definition: Section.hh:143
ReferenceKey.hh
TPEF::BinaryStream::readWord
Word readWord()
Definition: BinaryStream.cc:187
TPEF::AOutReader::ST_DATA
@ ST_DATA
Data section.
Definition: AOutReader.hh:117
TPEF::RawSection::chunkToMAUIndex
virtual Word chunkToMAUIndex(const Chunk *chunk) const
Definition: Section.cc:341
TPEF::Chunk
Definition: Chunk.hh:45
CodeSection.hh
TPEF::DataSection::writeValue
virtual void writeValue(Word index, Word numOfMAUs, unsigned long value)
Definition: DataSection.cc:250
TPEF::Section::elementCount
Word elementCount() const
TPEF
Definition: Assembler.hh:43
TPEF::AOutRelocationSectionReader::RELOC_32
@ RELOC_32
4 bytes relocation
Definition: AOutRelocationSectionReader.hh:71