OpenASIP  2.0
TPEFSectionWriter.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 TPEFSectionWriter.cc
26  *
27  * Definitions of TPEFSectionWriter class.
28  *
29  * @author Mikael Lepistö 2003 (tmlepist-no.spam-cs.tut.fi)
30  *
31  * @note rating: yellow
32  */
33 
34 #include <list>
35 
36 #include "TPEFSectionWriter.hh"
37 #include "SectionOffsetReplacer.hh"
38 #include "SectionWriter.hh"
39 #include "BinaryWriter.hh"
40 #include "TPEFWriter.hh"
41 #include "SafePointer.hh"
42 #include "ReferenceKey.hh"
43 #include "SectionSizeReplacer.hh"
44 #include "DataSection.hh"
45 #include "FileOffsetReplacer.hh"
46 #include "SectionElement.hh"
47 #include "StringSection.hh"
48 #include "SectionIdReplacer.hh"
49 #include "SectionIndexReplacer.hh"
50 #include "RelocSection.hh"
51 #include "BinaryStream.hh"
52 
53 namespace TPEF {
54 
55 using std::list;
56 using ReferenceManager::SafePointer;
57 using ReferenceManager::SectionKey;
58 using ReferenceManager::FileOffsetKey;
59 
60 /**
61  * Constructor.
62  */
64 }
65 
66 /**
67  * Destructor.
68  */
70 }
71 
72 /**
73  * Returns binary writer which for section writers are created.
74  *
75  * @return Binary writer which for section writers are created.
76  */
77 const BinaryWriter&
79  return TPEFWriter::instance();
80 }
81 
82 /**
83  * Writes section's header into stream.
84  *
85  * @param stream Stream where to write.
86  * @param sect Section to be written.
87  */
88 void
90  BinaryStream& stream,
91  const Section* sect) const {
92 
93  // inform reference manager about the section
94  SectionOffset sectionOffset = stream.writePosition();
95 
96  // getSectionId must be overridden for special section identifiers
97  // like NullSection's
98  SectionId id = getSectionId();
99 
100  // create reference keys for section class
102  SafePointer::addObjectReference(FileOffsetKey(sectionOffset), sect);
103 
104  // start writing header fields
105  stream.setWritePosition(sectionOffset + TPEFHeaders::SH_NAME);
106  Chunk* name = sect->name();
107 
108  if (name != NULL) {
109  SectionOffsetReplacer nameReplacer(name);
110  nameReplacer.resolve();
111  } else {
112  stream.writeWord(0);
113  }
114 
115  stream.setWritePosition(sectionOffset + TPEFHeaders::SH_TYPE);
116  stream.writeByte(sect->type());
117 
118  stream.setWritePosition(sectionOffset + TPEFHeaders::SH_FLAGS);
119  stream.writeByte(sect->flags());
120 
121  stream.setWritePosition(sectionOffset + TPEFHeaders::SH_ADDR);
122 
123  if (sect->isProgramSection()) {
124  stream.writeWord(sect->startingAddress());
125  } else {
126  stream.writeWord(0);
127  }
128 
129  // offset of the section data
130  stream.setWritePosition(sectionOffset + TPEFHeaders::SH_OFFSET);
131  writeBodyStartOffset(stream, sect);
132 
133  // size of the section
134  stream.setWritePosition(sectionOffset + TPEFHeaders::SH_SIZE);
135  writeSize(stream, sect);
136 
137  // section identification code
138  stream.setWritePosition(sectionOffset + TPEFHeaders::SH_ID);
139  stream.writeHalfWord(id);
140 
141 
142  stream.setWritePosition(sectionOffset + TPEFHeaders::SH_ASPACE);
143  if (sect->aSpace() != NULL) {
144  // section address space identifier
145  SectionIndexReplacer indexReplacer(sect->aSpace(), sizeof(Byte));
146  indexReplacer.resolve();
147  } else {
148  bool addressSpaceCantBeNull = false;
149  assert(addressSpaceCantBeNull);
150  }
151 
152  stream.setWritePosition(sectionOffset + TPEFHeaders::SH_PADDING);
153  stream.writeByte(0);
154 
155  stream.setWritePosition(sectionOffset + TPEFHeaders::SH_LINK);
156  Section* linkSect = sect->link();
157 
158  if (linkSect != NULL) {
159  SectionIdReplacer linkReplacer(linkSect);
160  linkReplacer.resolve();
161  } else {
162  stream.writeHalfWord(0);
163  }
164 
165  // by deafult info field is not used.
166  stream.setWritePosition(sectionOffset + TPEFHeaders::SH_INFO);
167  writeInfo(stream, sect);
168 
169  // section elements size is asked from actual section writer
170  stream.setWritePosition(sectionOffset + TPEFHeaders::SH_ENTSIZE);
171 
172  // check that if element size is zero then vLen flag is set or
173  // section is null section
174  assert((elementSize(sect) == 0) ==
175  (sect->vLen() || (sect->type() == Section::ST_NULL)));
176  stream.writeWord(elementSize(sect));
177 
178  // create keys for section elements if nobits flag is set.
179  if (sect->noBits()) {
180  createKeys(sect);
181  }
182 }
183 
184 /**
185  * Empty default implementation of method.
186  *
187  * This is used if Section does not contain any data part.
188  *
189  * @param stream Where to write.
190  * @param sect Data to write.
191  */
192 void
194  const Section* /*sect*/) const {
195 }
196 
197 /**
198  * Returns fixed element size of section.
199  *
200  * @param sect Data to write.
201  * @return Element size of section.
202  */
203 Word
204 TPEFSectionWriter::elementSize(const Section* /*sect*/) const {
205  return 0;
206 }
207 
208 /**
209  * Writes section size field in to stream.
210  *
211  * Default implementation, which uses replacer class to write
212  * size.
213  *
214  * @param stream Stream, where to write.
215  * @param sect Section which size to write.
216  */
217 void
219  const Section* sect) const {
220  SectionSizeReplacer replacer(sect);
221  replacer.resolve();
222 }
223 
224 /**
225  * Writes section info field into stream.
226  *
227  * Default implementation writes, there zero word.
228  *
229  * @param stream Stream where to write.
230  * @param sect Section which info field to write.
231  */
232 void
234  const Section* /*sect*/) const {
235  stream.writeWord(0);
236 }
237 
238 /**
239  * Writes Section's data area offset into stream.
240  *
241  * @param stream Stream where to write.
242  * @param sect Section which data's offset to write.
243  */
244 void
246  const Section* sect) const {
247 
248  if (sect->noBits()) {
249  stream.writeWord(0);
250 
251  } else {
252  if (sect->isChunkable()) {
253  FileOffsetReplacer replacer(sect->chunk(0));
254  replacer.resolve();
255  } else {
256  FileOffsetReplacer replacer(sect->element(0));
257  replacer.resolve();
258  }
259  }
260 }
261 
262 /**
263  * Get section identification code for the section.
264  *
265  * @return Valid section identification code.
266  */
267 SectionId
270 }
271 
272 /**
273  * Fall through method for creating reference keys.
274  *
275  * This method is used for those sections, whose elements can be
276  * referred, but there is no section body stored in TPEF binary
277  * (if section has no bits flag set, then this method is invoked
278  * instead writeData).
279  *
280  * Empty implementation for sections that don't need keys created if
281  * section do not have body.
282  *
283  * @param sect Section which for keys will be created.
284  */
285 void
286 TPEFSectionWriter::createKeys(const Section* /*sect*/) const {
287 }
288 
289 }
TPEF::SectionId
HalfWord SectionId
Type for storing binary file section ids.
Definition: TPEFBaseType.hh:43
TPEF::TPEFHeaders::SH_LINK
@ SH_LINK
Section identifier link.
Definition: TPEFHeaders.hh:88
TPEF::BinaryStream::writeHalfWord
void writeHalfWord(HalfWord halfword)
Definition: BinaryStream.cc:336
SectionSizeReplacer.hh
TPEF::Section::isChunkable
virtual bool isChunkable() const
Definition: Section.cc:157
TPEF::TPEFSectionWriter::parent
virtual const BinaryWriter & parent() const
Definition: TPEFSectionWriter.cc:78
TPEF::TPEFSectionWriter::createKeys
virtual void createKeys(const Section *sect) const
Definition: TPEFSectionWriter.cc:286
TPEF::Section::chunk
virtual Chunk * chunk(SectionOffset offset) const
Definition: Section.cc:169
TPEF::Section::vLen
bool vLen() const
SectionOffsetReplacer.hh
TPEF::Section::aSpace
ASpaceElement * aSpace() const
TPEF::SectionSizeReplacer
Definition: SectionSizeReplacer.hh:50
SectionIdReplacer.hh
TPEF::TPEFHeaders::SH_TYPE
@ SH_TYPE
Type of section.
Definition: TPEFHeaders.hh:80
SectionWriter.hh
TPEF::TPEFHeaders::SH_OFFSET
@ SH_OFFSET
Offset to section data.
Definition: TPEFHeaders.hh:83
TPEF::BinaryStream::writeWord
void writeWord(Word word)
Definition: BinaryStream.cc:368
TPEF::Section::type
virtual SectionType type() const =0
Returns SectioType of actual section instance.
TPEF::BinaryStream
Definition: BinaryStream.hh:59
TPEF::BinaryStream::writePosition
unsigned int writePosition()
Definition: BinaryStream.cc:592
SafePointer.hh
TPEF::TPEFHeaders::SH_ASPACE
@ SH_ASPACE
Section address space identifier.
Definition: TPEFHeaders.hh:86
TPEF::TPEFHeaders::SH_INFO
@ SH_INFO
Section specific information, usually zero.
Definition: TPEFHeaders.hh:89
StringSection.hh
Byte
unsigned char Byte
Definition: BaseType.hh:116
TPEF::ReferenceManager::SafePointer::addObjectReference
static void addObjectReference(SectionIndexKey key, const SafePointable *obj)
Definition: SafePointer.cc:306
TPEF::FileOffsetReplacer
Definition: FileOffsetReplacer.hh:48
TPEF::ValueReplacer::resolve
void resolve()
Definition: ValueReplacer.cc:90
TPEF::Section
Definition: Section.hh:64
TPEF::TPEFHeaders::SH_PADDING
@ SH_PADDING
Padding, must be zero.
Definition: TPEFHeaders.hh:87
TPEF::TPEFSectionWriter::actualWriteData
virtual void actualWriteData(BinaryStream &stream, const Section *sect) const
Definition: TPEFSectionWriter.cc:193
TPEF::TPEFSectionWriter::writeBodyStartOffset
void writeBodyStartOffset(BinaryStream &stream, const Section *sect) const
Definition: TPEFSectionWriter.cc:245
TPEF::Section::link
Section * link() const
TPEF::Section::element
SectionElement * element(Word index) const
assert
#define assert(condition)
Definition: Application.hh:86
TPEF::TPEFHeaders::SH_ENTSIZE
@ SH_ENTSIZE
Size of section elements (if fixed size).
Definition: TPEFHeaders.hh:90
TPEF::SectionOffsetReplacer
Definition: SectionOffsetReplacer.hh:47
TPEF::TPEFSectionWriter::~TPEFSectionWriter
virtual ~TPEFSectionWriter()
Definition: TPEFSectionWriter.cc:69
RelocSection.hh
TPEF::BinaryStream::setWritePosition
void setWritePosition(unsigned int position)
Definition: BinaryStream.cc:689
TPEF::TPEFHeaders::SH_ID
@ SH_ID
Section identification code.
Definition: TPEFHeaders.hh:85
TPEF::TPEFWriter::instance
static const BinaryWriter & instance()
Definition: TPEFWriter.cc:70
FileOffsetReplacer.hh
DataSection.hh
BinaryWriter.hh
TPEF::BinaryStream::writeByte
void writeByte(Byte byte)
Definition: BinaryStream.cc:310
TPEFSectionWriter.hh
TPEF::Section::noBits
bool noBits() const
TPEF::TPEFSectionWriter::writeInfo
virtual void writeInfo(BinaryStream &stream, const Section *sect) const
Definition: TPEFSectionWriter.cc:233
TPEF::SectionIdReplacer
Definition: SectionIdReplacer.hh:47
TPEF::TPEFHeaders::SH_SIZE
@ SH_SIZE
Size of section data.
Definition: TPEFHeaders.hh:84
TPEF::SectionOffset
Word SectionOffset
Type for storing offsets relative to a given base offset value.
Definition: TPEFBaseType.hh:49
TPEF::ReferenceManager::SectionKey
Definition: ReferenceKey.hh:145
TPEF::Section::name
Chunk * name() const
TPEF::SectionWriter
Definition: SectionWriter.hh:58
TPEF::ReferenceManager::FileOffsetKey
Definition: ReferenceKey.hh:121
SectionElement.hh
SectionIndexReplacer.hh
TPEF::Section::flags
Byte flags() const
TPEF::TPEFHeaders::SH_ADDR
@ SH_ADDR
Starting memory address of program section.
Definition: TPEFHeaders.hh:82
BinaryStream.hh
TPEF::TPEFHeaders::SH_FLAGS
@ SH_FLAGS
Flags of section.
Definition: TPEFHeaders.hh:81
TPEF::SectionIndexReplacer
Definition: SectionIndexReplacer.hh:48
TPEFWriter.hh
TPEF::TPEFHeaders::SH_NAME
@ SH_NAME
Section offset to name.
Definition: TPEFHeaders.hh:79
TPEF::TPEFSectionWriter::getSectionId
virtual SectionId getSectionId() const
Definition: TPEFSectionWriter.cc:268
TPEF::Section::isProgramSection
bool isProgramSection() const
TPEF::Section::ST_NULL
@ ST_NULL
NULL Section.
Definition: Section.hh:70
TPEF::TPEFSectionWriter::writeSize
virtual void writeSize(BinaryStream &stream, const Section *sect) const
Definition: TPEFSectionWriter.cc:218
TPEF::TPEFSectionWriter::actualWriteHeader
virtual void actualWriteHeader(BinaryStream &stream, const Section *sect) const
Definition: TPEFSectionWriter.cc:89
ReferenceKey.hh
TPEF::Section::startingAddress
AddressImage startingAddress() const
TPEF::Chunk
Definition: Chunk.hh:45
TPEF::SectionWriter::getUniqueSectionId
static SectionId getUniqueSectionId()
Definition: SectionWriter.cc:172
TPEF::BinaryWriter
Definition: BinaryWriter.hh:50
TPEF
Definition: Assembler.hh:43
TPEF::TPEFSectionWriter::elementSize
virtual Word elementSize(const Section *section) const
Definition: TPEFSectionWriter.cc:204
TPEF::TPEFSectionWriter::TPEFSectionWriter
TPEFSectionWriter()
Definition: TPEFSectionWriter.cc:63