object_file.cc revision 8706:b1838faf3bcc
1360SN/A/*
21458SN/A * Copyright (c) 2002-2004 The Regents of The University of Michigan
3360SN/A * All rights reserved.
4360SN/A *
5360SN/A * Redistribution and use in source and binary forms, with or without
6360SN/A * modification, are permitted provided that the following conditions are
7360SN/A * met: redistributions of source code must retain the above copyright
8360SN/A * notice, this list of conditions and the following disclaimer;
9360SN/A * redistributions in binary form must reproduce the above copyright
10360SN/A * notice, this list of conditions and the following disclaimer in the
11360SN/A * documentation and/or other materials provided with the distribution;
12360SN/A * neither the name of the copyright holders nor the names of its
13360SN/A * contributors may be used to endorse or promote products derived from
14360SN/A * this software without specific prior written permission.
15360SN/A *
16360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26360SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
292665Ssaidi@eecs.umich.edu *          Steve Reinhardt
30360SN/A */
31360SN/A
322093SN/A#include <sys/mman.h>
33360SN/A#include <sys/types.h>
34360SN/A#include <fcntl.h>
35360SN/A#include <unistd.h>
36360SN/A
37360SN/A#include <cstdio>
38360SN/A#include <list>
392474SN/A#include <string>
40360SN/A
416658Snate@binkert.org#include "base/loader/aout_object.hh"
422680Sktlim@umich.edu#include "base/loader/ecoff_object.hh"
431717SN/A#include "base/loader/elf_object.hh"
442474SN/A#include "base/loader/object_file.hh"
45360SN/A#include "base/loader/raw_object.hh"
466029Ssteve.reinhardt@amd.com#include "base/loader/symtab.hh"
472667Sstever@eecs.umich.edu#include "base/cprintf.hh"
48360SN/A#include "mem/port_proxy.hh"
49360SN/A
502107SN/Ausing namespace std;
51360SN/A
52360SN/AObjectFile::ObjectFile(const string &_filename, int _fd,
533114Sgblack@eecs.umich.edu                       size_t _len, uint8_t *_data,
54360SN/A                       Arch _arch, OpSys _opSys)
556702Sgblack@eecs.umich.edu    : filename(_filename), descriptor(_fd), fileData(_data), len(_len),
566701Sgblack@eecs.umich.edu      arch(_arch), opSys(_opSys)
576702Sgblack@eecs.umich.edu{
586111Ssteve.reinhardt@amd.com}
596111Ssteve.reinhardt@amd.com
606111Ssteve.reinhardt@amd.com
616701Sgblack@eecs.umich.eduObjectFile::~ObjectFile()
626701Sgblack@eecs.umich.edu{
636701Sgblack@eecs.umich.edu    close();
646701Sgblack@eecs.umich.edu}
65360SN/A
662680Sktlim@umich.edu
67360SN/Abool
682495SN/AObjectFile::loadSection(Section *sec, PortProxy* memProxy, Addr addrMask)
692680Sktlim@umich.edu{
70360SN/A    if (sec->size != 0) {
711450SN/A        Addr addr = sec->baseAddr & addrMask;
725958Sgblack@eecs.umich.edu        if (sec->fileImage) {
73360SN/A            memProxy->writeBlob(addr, sec->fileImage, sec->size);
74360SN/A        }
75360SN/A        else {
761450SN/A            // no image: must be bss
773114Sgblack@eecs.umich.edu            memProxy->memsetBlob(addr, 0, sec->size);
782680Sktlim@umich.edu        }
79360SN/A    }
801969SN/A    return true;
812484SN/A}
822484SN/A
83360SN/A
84360SN/Abool
85360SN/AObjectFile::loadSections(PortProxy* memProxy, Addr addrMask)
861450SN/A{
873114Sgblack@eecs.umich.edu    return (loadSection(&text, memProxy, addrMask)
882680Sktlim@umich.edu            && loadSection(&data, memProxy, addrMask)
89360SN/A            && loadSection(&bss, memProxy, addrMask));
906701Sgblack@eecs.umich.edu}
911969SN/A
926701Sgblack@eecs.umich.edu
93360SN/Avoid
941458SN/AObjectFile::close()
95360SN/A{
96360SN/A    if (descriptor >= 0) {
97360SN/A        ::close(descriptor);
981450SN/A        descriptor = -1;
993114Sgblack@eecs.umich.edu    }
1002680Sktlim@umich.edu
101360SN/A    if (fileData) {
1026029Ssteve.reinhardt@amd.com        ::munmap((char*)fileData, len);
1036029Ssteve.reinhardt@amd.com        fileData = NULL;
1046701Sgblack@eecs.umich.edu    }
1055958Sgblack@eecs.umich.edu}
1066701Sgblack@eecs.umich.edu
1076029Ssteve.reinhardt@amd.com
1086029Ssteve.reinhardt@amd.comObjectFile *
1096029Ssteve.reinhardt@amd.comcreateObjectFile(const string &fname, bool raw)
1102834Sksewell@umich.edu{
111360SN/A    // open the file
1121458SN/A    int fd = open(fname.c_str(), O_RDONLY);
113360SN/A    if (fd < 0) {
114360SN/A        return NULL;
115360SN/A    }
1161450SN/A
1176109Ssanchezd@stanford.edu    // find the length of the file by seeking to the end
1186109Ssanchezd@stanford.edu    size_t len = (size_t)lseek(fd, 0, SEEK_END);
1196109Ssanchezd@stanford.edu
1206109Ssanchezd@stanford.edu    // mmap the whole shebang
1216109Ssanchezd@stanford.edu    uint8_t *fileData =
1226701Sgblack@eecs.umich.edu        (uint8_t *)mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
1236109Ssanchezd@stanford.edu    if (fileData == MAP_FAILED) {
1246701Sgblack@eecs.umich.edu        close(fd);
1256109Ssanchezd@stanford.edu        return NULL;
1266109Ssanchezd@stanford.edu    }
1276109Ssanchezd@stanford.edu
1286109Ssanchezd@stanford.edu    ObjectFile *fileObj = NULL;
1296109Ssanchezd@stanford.edu
1306109Ssanchezd@stanford.edu    // figure out what we have here
1313114Sgblack@eecs.umich.edu    if ((fileObj = EcoffObject::tryFile(fname, fd, len, fileData)) != NULL) {
132360SN/A        return fileObj;
1332107SN/A    }
134360SN/A
135360SN/A    if ((fileObj = AoutObject::tryFile(fname, fd, len, fileData)) != NULL) {
136360SN/A        return fileObj;
1371450SN/A    }
1385748SSteve.Reinhardt@amd.com
139360SN/A    if ((fileObj = ElfObject::tryFile(fname, fd, len, fileData)) != NULL) {
140360SN/A        return fileObj;
1416701Sgblack@eecs.umich.edu    }
1426701Sgblack@eecs.umich.edu
1435748SSteve.Reinhardt@amd.com    if (raw)
1445748SSteve.Reinhardt@amd.com        return RawObject::tryFile(fname, fd, len, fileData);
1455748SSteve.Reinhardt@amd.com
1465748SSteve.Reinhardt@amd.com    // don't know what it is
1475748SSteve.Reinhardt@amd.com    close(fd);
1485748SSteve.Reinhardt@amd.com    munmap((char*)fileData, len);
1495748SSteve.Reinhardt@amd.com    return NULL;
1505748SSteve.Reinhardt@amd.com}
1512474SN/A