2    Copyright (c) 2002-2009 Tampere University.
 
    4    This file is part of TTA-Based Codesign Environment (TCE).
 
    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:
 
   13    The above copyright notice and this permission notice shall be included in
 
   14    all copies or substantial portions of the Software.
 
   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.
 
   25 * @file AOutReader.icc
 
   27 * Inline implementations of AOutReader.
 
   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
 
   33 * @note rating: yellow
 
   36#include "SectionReader.hh"
 
   37#include "InstructionElement.hh"
 
   38#include "BinaryStream.hh"
 
   42//////////////////////////////////////////////////////////////////////////
 
   44//////////////////////////////////////////////////////////////////////////
 
   47 * Returns an instance of BinaryReader.
 
   49 * Returns a.out binary reader instance, if called first time
 
   50 * also creates instance.
 
   52 * @return Binary reader instance of a.out binaries.
 
   55AOutReader::instance() {
 
   58        proto_ = new AOutReader();
 
   65 * Returns processors resource section of binary.
 
   67 * @return Processors resource table of binary.
 
   69inline ResourceSection*
 
   70AOutReader::resourceTable() const {
 
   71    return resourceTable_;
 
   75 * Returns null section of binary.
 
   77 * @return Null section of binary.
 
   80AOutReader::nullSection() const {
 
   85 * Returns debug section of binary.
 
   87 * @return Debug section of binary.
 
   90AOutReader::debugSection() const {
 
   95 * Returns string section of binary.
 
   97 * @return String section of binary.
 
  100AOutReader::stringSection() const {
 
  101    return stringSection_;
 
  105 * Returns text section of binary.
 
  107 * @return Text section of binary.
 
  110AOutReader::textSection() const {
 
  115 * Returns address space where where element reside.
 
  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.
 
  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.
 
  126AOutReader::aSpaceOfElement(SectionElement* elem) const {
 
  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);
 
  135    if (instruction != NULL) {
 
  138    } else if (chunk != NULL) {
 
  145    bool cantFindASpaceOfElement = false;
 
  146    assert(cantFindASpaceOfElement);
 
  151 * Returns element's address in TPEF representation.
 
  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.
 
  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.
 
  162AOutReader::addressOfElement(SectionElement* elem) const {
 
  163    // Section offset and identification code of destination element to find
 
  164    ReferenceManager::SectionOffsetKey elemSectionOffsetKey =
 
  165        ReferenceManager::SafePointer::sectionOffsetKeyFor(elem);
 
  167    // calculate memory address, abort if it's too big
 
  168    Word address = elemSectionOffsetKey.offset();
 
  170    if (elemSectionOffsetKey.sectionId() == AOutReader::ST_TEXT) {
 
  171        assert(address < header_.sectionSizeText());
 
  173        // code section conversion to 1 address / instruction if address
 
  174        // points to code section
 
  175        address = address / AOutReader::AOUT_INSTRUCTION_SIZE;
 
  177    } else if (elemSectionOffsetKey.sectionId() == AOutReader::ST_DATA) {
 
  178        assert(address < header_.sectionSizeData());
 
  179        address += header_.sectionSizeText();
 
  181    } else if (elemSectionOffsetKey.sectionId() == AOutReader::ST_UDATA) {
 
  182        assert(address < header_.sectionSizeUData());
 
  183        address += header_.sectionSizeText() + header_.sectionSizeData();
 
  186        bool cantFindAddressForElement = false;
 
  187        assert(cantFindAddressForElement);
 
  194 * Returns section offset of element in given memory address.
 
  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.
 
  201AOutReader::sectionOffsetOfAddress(AddressImage address) const {
 
  202    SectionOffset endOfText = header_.sectionSizeText();
 
  203    SectionOffset endOfData = endOfText + header_.sectionSizeData();
 
  204    SectionOffset endOfUData = endOfData + header_.sectionSizeUData();
 
  206    if (address < endOfText) {
 
  209    } else if (address < endOfData) {
 
  210        return address - endOfText;
 
  212    } else if (address < endOfUData) {
 
  213        return address - endOfData;
 
  216        std::string method = "AOutReader::sectionOffsetOfAddress";
 
  217        std::string msg = "Section offset out of memory image";
 
  218        throw OutOfRange(__FILE__, __LINE__, method, msg);
 
  223 * Returns header of A.out file.
 
  225 * @return File header of last read a.out binary.
 
  227inline const AOutReader::Header&
 
  228AOutReader::header() {
 
  233 * Reads section from stream.
 
  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.
 
  248AOutReader::readSection(
 
  249    BinaryStream& stream, FileOffset startPosition, Section* section,
 
  250    Length length) const {
 
  251    stream.setReadPosition(startPosition);
 
  254        SectionReader::readSection(stream, section, proto_);
 
  259 * Adds section to binary, if section has elements inside.
 
  261 * If section does not contain elements, section will be deleted.
 
  263 * @param section Section to add or delete.
 
  264 * @param bin Binary, where to add section.
 
  267AOutReader::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);
 
  281//////////////////////////////////////////////////////////////////////////
 
  283//////////////////////////////////////////////////////////////////////////
 
  287 * Sets size for data section.
 
  289 * @param size The size of the section.
 
  292AOutReader::Header::setSectionSizeData(Word size) {
 
  298 * Sets size for uninitialized data section.
 
  300 * @param size The size of the section.
 
  303AOutReader::Header::setSectionSizeUData(Word size) {
 
  304    sizes_.uData_ = size;
 
  309 * Sets size for text section.
 
  311 * @param size The size of the section.
 
  314AOutReader::Header::setSectionSizeText(Word size) {
 
  320 * Sets size symbol table sections.
 
  322 * @param size The size of the section.
 
  325AOutReader::Header::setSectionSizeSymbol(Word size) {
 
  326    sizes_.symbol_ = size;
 
  331 * Sets size for text relocation section.
 
  333 * @param size The size of the section.
 
  336AOutReader::Header::setSectionSizeTextReloc(Word size) {
 
  337    sizes_.textReloc_ = size;
 
  342 * Sets size for data relocation sections.
 
  344 * @param size The size of the section.
 
  347AOutReader::Header::setSectionSizeDataReloc(Word size) {
 
  348    sizes_.dataReloc_ = size;
 
  353 * Sets size for data relocation sections.
 
  355 * @param size The size of the section.
 
  358AOutReader::Header::setSectionSizeString(Word size) {
 
  359    sizes_.string_ = size;
 
  363 * Returns the size of the data section.
 
  365 * @return The size of the section in Bytes.
 
  368AOutReader::Header::sectionSizeData() const {
 
  374 * Returns the size of the uninitialized data section.
 
  376 * @return The size of the section in Bytes.
 
  379AOutReader::Header::sectionSizeUData() const {
 
  380    return sizes_.uData_;
 
  385 * Returns the size of the text section.
 
  387 * @return The size of the section in Bytes.
 
  390AOutReader::Header::sectionSizeText() const {
 
  396 * Returns the size of the symbol section.
 
  398 * @return The size of the section in Bytes.
 
  401AOutReader::Header::sectionSizeSymbol() const {
 
  402    return sizes_.symbol_;
 
  407 * Returns the size of the text relocation section.
 
  409 * @return The size of the section in Bytes.
 
  412AOutReader::Header::sectionSizeTextReloc() const {
 
  413    return sizes_.textReloc_;
 
  418 * Returns the size of the data relocation section.
 
  420 * @return The size of the section in Bytes.
 
  423AOutReader::Header::sectionSizeDataReloc() const {
 
  424    return sizes_.dataReloc_;
 
  429 * Returns the size of the string section.
 
  431 * @return The size of the section in Bytes.
 
  434AOutReader::Header::sectionSizeString() const {
 
  435    return sizes_.string_;