diff options
author | Steve Reinhardt <stever@eecs.umich.edu> | 2003-10-07 23:13:01 -0700 |
---|---|---|
committer | Steve Reinhardt <stever@eecs.umich.edu> | 2003-10-07 23:13:01 -0700 |
commit | e475dba424d70e99646f897fae832f87b1cf15cf (patch) | |
tree | 04acc02acfc77419aaf80a26e03b4ccf742838cc /base/object_file.cc | |
parent | 998d2914db377d5236d6241e3c839af1728c36e7 (diff) | |
download | gem5-e475dba424d70e99646f897fae832f87b1cf15cf.tar.xz |
New loader structure. Expand Nate's ObjectFile to automatically detect file formats
and generate an appropriate child object, which knows how to load its text & data into memory
(and symbols, for ecoff only at this point). Ecoff format supports Tru64 binaries, kernel, and
console. A.out format is used by PAL code. Elf support is there and appears to work for
Alpha/Linux binaries, but awaits a Linux syscall emulation layer before further testing.
arch/alpha/ecoff_machdep.h:
base/coff_sym.h:
base/coff_symconst.h:
base/exec_ecoff.h:
Add Id string & provenance comment, clean up types
base/object_file.cc:
base/object_file.hh:
Add auto format detection and text/data loading.
sim/prog.cc:
Moved binary loading & stack setup here (was in arch/alpha/loader.cc). Some of this is
platform-dependent, but I think most of it is not. We'll factor out the platform-dependent
parts when the need arises.
sim/prog.hh:
Get rid of unused environ_base field.
sim/system.cc:
Use new ObjectFile loader structure for console, kernel, & palcode.
--HG--
extra : convert_revision : 8eae509bf71cf204bc3ec78c68699cfd01baed97
Diffstat (limited to 'base/object_file.cc')
-rw-r--r-- | base/object_file.cc | 144 |
1 files changed, 43 insertions, 101 deletions
diff --git a/base/object_file.cc b/base/object_file.cc index b9542f280..07b10b5ee 100644 --- a/base/object_file.cc +++ b/base/object_file.cc @@ -36,138 +36,80 @@ #include <unistd.h> #include "cprintf.hh" -#include "ecoff.hh" #include "object_file.hh" #include "symtab.hh" +#include "ecoff_object.hh" +#include "aout_object.hh" +#include "elf_object.hh" + using namespace std; -ObjectFile::ObjectFile() - : descriptor(-1), data(NULL) -{} +ObjectFile::ObjectFile(const string &_filename, int _fd, + size_t _len, uint8_t *_data) + : filename(_filename), descriptor(_fd), fileData(_data), len(_len) +{ +} -ObjectFile::ObjectFile(string file) - : descriptor(-1), data(NULL) -{ open(file); } ObjectFile::~ObjectFile() -{ close(); } - -bool -ObjectFile::open(string file_name) { close(); - - name = file_name; - - descriptor = ::open(name.c_str(), O_RDONLY); - if (descriptor < 0) - return false; - - len = (size_t)::lseek(descriptor, 0, SEEK_END); - - data = (uint8_t *)::mmap(NULL, len, PROT_READ, MAP_SHARED, descriptor, 0); - if (data == MAP_FAILED) - return false; - - postOpen(); - - return true; } + void ObjectFile::close() { - if (descriptor >= 0) + if (descriptor >= 0) { ::close(descriptor); + descriptor = -1; + } - if (data) - ::munmap(data, len); + if (fileData) { + ::munmap(fileData, len); + fileData = NULL; + } } -void -EcoffObject::postOpen() -{ - exec = &(((EcoffExecHeader *)data)->f); - aout = &(((EcoffExecHeader *)data)->a); - text_off = aout->text_start; - data_off = aout->data_start; - bss_off = aout->bss_start; - - text_size = aout->tsize; - data_size = aout->dsize; - bss_size = aout->bsize; -} - -bool -EcoffObject::loadGlobals(SymbolTable *symtab) +ObjectFile * +createObjectFile(const string &fname) { - if (!symtab) - return false; - - if (exec->f_magic != ALPHAMAGIC) { - cprintf("wrong magic\n"); - return false; + // open the file + int fd = open(fname.c_str(), O_RDONLY); + if (fd < 0) { + return NULL; } - EcoffSymHeader *syms = (EcoffSymHeader *)(data + exec->f_symptr); - if (syms->magic != ECOFF_SYM_MAGIC) { - cprintf("bad symbol header magic\n"); - exit(1); - } + // find the length of the file by seeking to the end + size_t len = (size_t)lseek(fd, 0, SEEK_END); - EcoffExtSymEntry *ext_syms = - (EcoffExtSymEntry *)(data + syms->cbExtOffset); - - char *ext_strings = (char *)(data + syms->cbSsExtOffset); - for (int i = 0; i < syms->iextMax; i++) { - EcoffSymEntry *entry = &(ext_syms[i].asym); - if (entry->iss != -1) - symtab->insert(entry->value, ext_strings + entry->iss); + // mmap the whole shebang + uint8_t *fileData = + (uint8_t *)mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0); + if (fileData == MAP_FAILED) { + close(fd); + return NULL; } - return true; -} - -bool -EcoffObject::loadLocals(SymbolTable *symtab) -{ - if (!symtab) - return false; - - if (exec->f_magic != ALPHAMAGIC) { - cprintf("wrong magic\n"); - return false; - } + ObjectFile *fileObj = NULL; - EcoffSymHeader *syms = (EcoffSymHeader *)(data + exec->f_symptr); - if (syms->magic != ECOFF_SYM_MAGIC) { - cprintf("bad symbol header magic\n"); - exit(1); + // figure out what we have here + if ((fileObj = EcoffObject::tryFile(fname, fd, len, fileData)) != NULL) { + return fileObj; } - EcoffSymEntry *local_syms = (EcoffSymEntry *)(data + syms->cbSymOffset); - char *local_strings = (char *)(data + syms->cbSsOffset); - EcoffFileDesc *fdesc = (EcoffFileDesc *)(data + syms->cbFdOffset); - - for (int i = 0; i < syms->ifdMax; i++) { - EcoffSymEntry *entry = - (EcoffSymEntry *)(local_syms + fdesc[i].isymBase); - char *strings = (char *)(local_strings + fdesc[i].issBase); - for (int j = 0; j < fdesc[i].csym; j++) { - if (entry[j].st == 1 || entry[j].st == 6) - if (entry[j].iss != -1) - symtab->insert(entry[j].value, strings + entry[j].iss); - } + if ((fileObj = AoutObject::tryFile(fname, fd, len, fileData)) != NULL) { + return fileObj; } - for (int i = 0; i < syms->isymMax; i++) { - EcoffSymEntry *entry = &(local_syms[i]); - if (entry->st == 6) - if (entry->st == 1 || entry->st == 6) - symtab->insert(entry->value, local_strings + entry->iss); + if ((fileObj = ElfObject::tryFile(fname, fd, len, fileData)) != NULL) { + return fileObj; } - return true; + // don't know what it is + close(fd); + munmap(fileData, len); + return NULL; } |