From e475dba424d70e99646f897fae832f87b1cf15cf Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Tue, 7 Oct 2003 23:13:01 -0700 Subject: 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 --- base/object_file.cc | 144 ++++++++++++++++------------------------------------ 1 file changed, 43 insertions(+), 101 deletions(-) (limited to 'base/object_file.cc') 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 #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; } -- cgit v1.2.3