ecoff_object.cc revision 2420
15882Snate@binkert.org/*
25882Snate@binkert.org * Copyright (c) 2003-2005 The Regents of The University of Michigan
35882Snate@binkert.org * All rights reserved.
45882Snate@binkert.org *
55882Snate@binkert.org * Redistribution and use in source and binary forms, with or without
65882Snate@binkert.org * modification, are permitted provided that the following conditions are
75882Snate@binkert.org * met: redistributions of source code must retain the above copyright
85882Snate@binkert.org * notice, this list of conditions and the following disclaimer;
95882Snate@binkert.org * redistributions in binary form must reproduce the above copyright
105882Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
115882Snate@binkert.org * documentation and/or other materials provided with the distribution;
125882Snate@binkert.org * neither the name of the copyright holders nor the names of its
135882Snate@binkert.org * contributors may be used to endorse or promote products derived from
145882Snate@binkert.org * this software without specific prior written permission.
155882Snate@binkert.org *
165882Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175882Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185882Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195882Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205882Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215882Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225882Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235882Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245882Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255882Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265882Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275882Snate@binkert.org */
285882Snate@binkert.org
295882Snate@binkert.org#include <string>
305882Snate@binkert.org
315882Snate@binkert.org#include "base/loader/ecoff_object.hh"
325882Snate@binkert.org#include "base/loader/symtab.hh"
335882Snate@binkert.org
348232Snate@binkert.org#include "base/trace.hh"	// for DPRINTF
358229Snate@binkert.org
368232Snate@binkert.org#include "base/loader/exec_ecoff.h"
378232Snate@binkert.org#include "base/loader/coff_sym.h"
388229Snate@binkert.org#include "base/loader/coff_symconst.h"
395882Snate@binkert.org
408232Snate@binkert.orgusing namespace std;
418232Snate@binkert.org
428232Snate@binkert.orgObjectFile *
438232Snate@binkert.orgEcoffObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
445882Snate@binkert.org{
458231Snate@binkert.org    if (((ecoff_filehdr *)data)->f_magic == ECOFF_MAGIC_ALPHA) {
468231Snate@binkert.org        // it's Alpha ECOFF
478232Snate@binkert.org        return new EcoffObject(fname, fd, len, data,
488232Snate@binkert.org                               ObjectFile::Alpha, ObjectFile::Tru64);
498232Snate@binkert.org    }
508232Snate@binkert.org    else {
518232Snate@binkert.org        return NULL;
525882Snate@binkert.org    }
538231Snate@binkert.org}
545882Snate@binkert.org
555882Snate@binkert.org
565882Snate@binkert.orgEcoffObject::EcoffObject(const string &_filename, int _fd,
575882Snate@binkert.org                         size_t _len, uint8_t *_data,
588231Snate@binkert.org                         Arch _arch, OpSys _opSys)
595882Snate@binkert.org    : ObjectFile(_filename, _fd, _len, _data, _arch, _opSys)
605882Snate@binkert.org{
618231Snate@binkert.org    execHdr = (ecoff_exechdr *)fileData;
628232Snate@binkert.org    fileHdr = &(execHdr->f);
638232Snate@binkert.org    aoutHdr = &(execHdr->a);
648232Snate@binkert.org
658232Snate@binkert.org    entry = aoutHdr->entry;
668232Snate@binkert.org
678232Snate@binkert.org    text.baseAddr = aoutHdr->text_start;
688232Snate@binkert.org    text.size = aoutHdr->tsize;
698232Snate@binkert.org    text.fileImage = fileData + ECOFF_TXTOFF(execHdr);
708232Snate@binkert.org
718232Snate@binkert.org    data.baseAddr = aoutHdr->data_start;
728232Snate@binkert.org    data.size = aoutHdr->dsize;
738232Snate@binkert.org    data.fileImage = fileData + ECOFF_DATOFF(execHdr);
748232Snate@binkert.org
758232Snate@binkert.org    bss.baseAddr = aoutHdr->bss_start;
768232Snate@binkert.org    bss.size = aoutHdr->bsize;
778232Snate@binkert.org    bss.fileImage = NULL;
788232Snate@binkert.org
798232Snate@binkert.org    DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
808232Snate@binkert.org             text.baseAddr, text.size, data.baseAddr, data.size,
818232Snate@binkert.org             bss.baseAddr, bss.size);
828232Snate@binkert.org}
838232Snate@binkert.org
848232Snate@binkert.org
858232Snate@binkert.orgbool
868232Snate@binkert.orgEcoffObject::loadGlobalSymbols(SymbolTable *symtab)
878232Snate@binkert.org{
888232Snate@binkert.org    if (!symtab)
898232Snate@binkert.org        return false;
908232Snate@binkert.org
918232Snate@binkert.org    if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
928232Snate@binkert.org        warn("loadGlobalSymbols: wrong magic on %s\n", filename);
938232Snate@binkert.org        return false;
948232Snate@binkert.org    }
958232Snate@binkert.org
968232Snate@binkert.org    ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
978232Snate@binkert.org    if (syms->magic != magicSym2) {
988232Snate@binkert.org        warn("loadGlobalSymbols: bad symbol header magic on %s\n", filename);
998232Snate@binkert.org        return false;
1008232Snate@binkert.org    }
1018232Snate@binkert.org
1028232Snate@binkert.org    ecoff_extsym *ext_syms = (ecoff_extsym *)(fileData + syms->cbExtOffset);
1038232Snate@binkert.org
1048232Snate@binkert.org    char *ext_strings = (char *)(fileData + syms->cbSsExtOffset);
1058232Snate@binkert.org    for (int i = 0; i < syms->iextMax; i++) {
1068232Snate@binkert.org        ecoff_sym *entry = &(ext_syms[i].asym);
1078232Snate@binkert.org        if (entry->iss != -1)
1088232Snate@binkert.org            symtab->insert(entry->value, ext_strings + entry->iss);
1098232Snate@binkert.org    }
1108232Snate@binkert.org
1118232Snate@binkert.org    return true;
1128232Snate@binkert.org}
1138232Snate@binkert.org
1148232Snate@binkert.orgbool
1158232Snate@binkert.orgEcoffObject::loadLocalSymbols(SymbolTable *symtab)
1168232Snate@binkert.org{
1178232Snate@binkert.org    if (!symtab)
1188232Snate@binkert.org        return false;
1198232Snate@binkert.org
1208232Snate@binkert.org    if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
1218232Snate@binkert.org        warn("loadGlobalSymbols: wrong magic on %s\n", filename);
1228232Snate@binkert.org        return false;
1238232Snate@binkert.org    }
1248232Snate@binkert.org
1258232Snate@binkert.org    ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
1268232Snate@binkert.org    if (syms->magic != magicSym2) {
1278232Snate@binkert.org        warn("loadGlobalSymbols: bad symbol header magic on %s\n", filename);
1288232Snate@binkert.org        return false;
1298232Snate@binkert.org    }
1308232Snate@binkert.org
1318232Snate@binkert.org    ecoff_sym *local_syms = (ecoff_sym *)(fileData + syms->cbSymOffset);
1328232Snate@binkert.org    char *local_strings = (char *)(fileData + syms->cbSsOffset);
1338232Snate@binkert.org    ecoff_fdr *fdesc = (ecoff_fdr *)(fileData + syms->cbFdOffset);
1348232Snate@binkert.org
1358232Snate@binkert.org    for (int i = 0; i < syms->ifdMax; i++) {
1368232Snate@binkert.org        ecoff_sym *entry = (ecoff_sym *)(local_syms + fdesc[i].isymBase);
1378232Snate@binkert.org        char *strings = (char *)(local_strings + fdesc[i].issBase);
1388232Snate@binkert.org        for (int j = 0; j < fdesc[i].csym; j++) {
1398232Snate@binkert.org            if (entry[j].st == stGlobal || entry[j].st == stProc)
1408232Snate@binkert.org                if (entry[j].iss != -1)
1418232Snate@binkert.org                    symtab->insert(entry[j].value, strings + entry[j].iss);
1428232Snate@binkert.org        }
1438232Snate@binkert.org    }
1448232Snate@binkert.org
1458232Snate@binkert.org    for (int i = 0; i < syms->isymMax; i++) {
1468232Snate@binkert.org        ecoff_sym *entry = &(local_syms[i]);
1478232Snate@binkert.org        if (entry->st == stProc)
1488232Snate@binkert.org            symtab->insert(entry->value, local_strings + entry->iss);
1498232Snate@binkert.org    }
1508232Snate@binkert.org
1518232Snate@binkert.org    return true;
1528232Snate@binkert.org}
1538232Snate@binkert.org