New loader structure. Expand Nate's ObjectFile to automatically detect file formats
authorSteve Reinhardt <stever@eecs.umich.edu>
Wed, 8 Oct 2003 06:13:01 +0000 (23:13 -0700)
committerSteve Reinhardt <stever@eecs.umich.edu>
Wed, 8 Oct 2003 06:13:01 +0000 (23:13 -0700)
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

17 files changed:
arch/alpha/aout_machdep.h [new file with mode: 0644]
arch/alpha/ecoff_machdep.h [new file with mode: 0644]
base/aout_object.cc [new file with mode: 0644]
base/aout_object.hh [new file with mode: 0644]
base/coff_sym.h [new file with mode: 0644]
base/coff_symconst.h [new file with mode: 0644]
base/ecoff_object.cc [new file with mode: 0644]
base/ecoff_object.hh [new file with mode: 0644]
base/elf_object.cc [new file with mode: 0644]
base/elf_object.hh [new file with mode: 0644]
base/exec_aout.h [new file with mode: 0644]
base/exec_ecoff.h [new file with mode: 0644]
base/object_file.cc
base/object_file.hh
sim/prog.cc
sim/prog.hh
sim/system.cc

diff --git a/arch/alpha/aout_machdep.h b/arch/alpha/aout_machdep.h
new file mode 100644 (file)
index 0000000..28203a2
--- /dev/null
@@ -0,0 +1,41 @@
+/* $Id$ */
+
+#ifndef __AOUT_MACHDEP_H__
+#define __AOUT_MACHDEP_H__
+
+///
+/// Funky Alpha 64-bit a.out header used for PAL code.
+///
+struct aout_exechdr {
+    uint16_t   magic;
+    uint16_t   vstamp;
+    uint16_t   bldrev;
+    uint16_t   padcell;
+    uint64_t   tsize;          // text segment size
+    uint64_t   dsize;          // data segment size
+    uint64_t   bsize;          // bss segment size
+    uint64_t   entry;          // entry point
+    uint64_t   text_start;     // text base address
+    uint64_t   data_start;     // data base address
+    uint64_t   bss_start;      // bss base address
+    uint32_t   gprmask;
+    uint32_t   fprmask;
+    uint64_t   gp_value;
+};
+
+#define AOUT_LDPGSZ    8192
+
+#define N_GETMAGIC(ex) ((ex).magic)
+
+#define N_BADMAX
+
+#define N_TXTADDR(ex)  ((ex).text_start)
+#define N_DATADDR(ex)  ((ex).data_start)
+#define N_BSSADDR(ex)  ((ex).bss_start)
+
+#define N_TXTOFF(ex)   \
+        (N_GETMAGIC(ex) == ZMAGIC ? 0 : sizeof(struct aout_exechdr))
+
+#define N_DATOFF(ex)   N_ALIGN(ex, N_TXTOFF(ex) + (ex).tsize)
+
+#endif /* !__AOUT_MACHDEP_H__*/
diff --git a/arch/alpha/ecoff_machdep.h b/arch/alpha/ecoff_machdep.h
new file mode 100644 (file)
index 0000000..0fe4c43
--- /dev/null
@@ -0,0 +1,75 @@
+/* $Id$ */
+
+/*
+ * Taken from NetBSD arch/alpha/ecoff_machdep.h
+ */
+
+/* $NetBSD: ecoff_machdep.h,v 1.5 1999/04/27 02:32:33 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994 Adam Glass
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Adam Glass.
+ * 4. The name of the Author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL Adam Glass BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+//
+// Define COFF/ECOFF integer type sizes
+//
+typedef  int16_t coff_short;
+typedef uint16_t coff_ushort;
+typedef  int32_t coff_int;
+typedef uint32_t coff_uint;
+typedef  int64_t coff_long;
+typedef uint64_t coff_ulong;
+typedef uint64_t coff_addr;
+
+#define ECOFF_LDPGSZ 4096
+
+#define ECOFF_PAD \
+        coff_ushort    bldrev;                                 /* XXX */
+
+#define ECOFF_MACHDEP \
+        coff_uint      gprmask; \
+        coff_uint      fprmask; \
+        coff_ulong     gp_value
+
+#define ECOFF_MAGIC_ALPHA              0603
+#define ECOFF_MAGIC_NETBSD_ALPHA       0605
+#define ECOFF_BADMAG(ep)                                               \
+        ((ep)->f.f_magic != ECOFF_MAGIC_ALPHA &&                       \
+            (ep)->f.f_magic != ECOFF_MAGIC_NETBSD_ALPHA)
+
+#define ECOFF_FLAG_EXEC                        0002
+#define ECOFF_SEGMENT_ALIGNMENT(ep) \
+    (((ep)->f.f_flags & ECOFF_FLAG_EXEC) == 0 ? 8 : 16)
+
+#define        ECOFF_FLAG_OBJECT_TYPE_MASK     0x3000
+#define                ECOFF_OBJECT_TYPE_NO_SHARED     0x1000
+#define                ECOFF_OBJECT_TYPE_SHARABLE      0x2000
+#define                ECOFF_OBJECT_TYPE_CALL_SHARED   0x3000
+
diff --git a/base/aout_object.cc b/base/aout_object.cc
new file mode 100644 (file)
index 0000000..c0f43a6
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+
+#include "aout_object.hh"
+
+#include "functional_memory.hh"
+#include "symtab.hh"
+
+#include "trace.hh"    // for DPRINTF
+
+#include "exec_aout.h"
+
+using namespace std;
+
+ObjectFile *
+AoutObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
+{
+    if (!N_BADMAG(*(aout_exechdr *)data)) {
+        return new AoutObject(fname, fd, len, data);
+    }
+    else {
+        return NULL;
+    }
+}
+
+
+AoutObject::AoutObject(const string &_filename, int _fd,
+                         size_t _len, uint8_t *_data)
+    : ObjectFile(_filename, _fd, _len, _data)
+{
+    execHdr = (aout_exechdr *)fileData;
+
+    entry = execHdr->entry;
+
+    text.baseAddr = N_TXTADDR(*execHdr);
+    text.size = execHdr->tsize;
+
+    data.baseAddr = N_DATADDR(*execHdr);
+    data.size = execHdr->dsize;
+
+    bss.baseAddr = N_BSSADDR(*execHdr);
+    bss.size = execHdr->bsize;
+
+    DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
+             text.baseAddr, text.size, data.baseAddr, data.size,
+             bss.baseAddr, bss.size);
+}
+
+
+bool
+AoutObject::loadSections(FunctionalMemory *mem, bool loadPhys)
+{
+    Addr textAddr = text.baseAddr;
+    Addr dataAddr = data.baseAddr;
+
+    if (loadPhys) {
+        textAddr &= (ULL(1) << 40) - 1;
+        dataAddr &= (ULL(1) << 40) - 1;
+    }
+
+    // Since we don't really have an MMU and all memory is
+    // zero-filled, there's no need to set up the BSS segment.
+    if (text.size != 0)
+        mem->prot_write(textAddr, fileData + N_TXTOFF(*execHdr), text.size);
+    if (data.size != 0)
+        mem->prot_write(dataAddr, fileData + N_DATOFF(*execHdr), data.size);
+
+    return true;
+}
+
+
+bool
+AoutObject::loadGlobalSymbols(SymbolTable *symtab)
+{
+    // a.out symbols not supported yet
+    return false;
+}
+
+bool
+AoutObject::loadLocalSymbols(SymbolTable *symtab)
+{
+    // a.out symbols not supported yet
+    return false;
+}
diff --git a/base/aout_object.hh b/base/aout_object.hh
new file mode 100644 (file)
index 0000000..baa8904
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __AOUT_OBJECT_HH__
+#define __AOUT_OBJECT_HH__
+
+#include "object_file.hh"
+
+// forward decls: avoid including exec_aout.h here
+struct aout_exechdr;
+
+class AoutObject : public ObjectFile
+{
+  protected:
+    aout_exechdr *execHdr;
+
+    AoutObject(const std::string &_filename, int _fd,
+                size_t _len, uint8_t *_data);
+
+  public:
+    virtual ~AoutObject() {}
+
+    virtual bool loadSections(FunctionalMemory *mem,
+                              bool loadPhys = false);
+    virtual bool loadGlobalSymbols(SymbolTable *symtab);
+    virtual bool loadLocalSymbols(SymbolTable *symtab);
+
+    static ObjectFile *tryFile(const std::string &fname, int fd,
+                               size_t len, uint8_t *data);
+};
+
+#endif // __AOUT_OBJECT_HH__
diff --git a/base/coff_sym.h b/base/coff_sym.h
new file mode 100644 (file)
index 0000000..dae9d85
--- /dev/null
@@ -0,0 +1,491 @@
+/* $Id$ */
+
+/*
+ * Taken from binutils-2.14.90.0.5 include/coff/sym.h
+ */
+
+/* Declarations of internal format of MIPS ECOFF symbols.
+   Originally contributed by MIPS Computer Systems and Third Eye Software.
+   Changes contributed by Cygnus Support are in the public domain.
+
+   This file is just aggregated with the files that make up the GNU
+   release; it is not considered part of GAS, GDB, or other GNU
+   programs.  */
+
+/*
+ * |-----------------------------------------------------------|
+ * | Copyright (c) 1992, 1991, 1990 MIPS Computer Systems, Inc.|
+ * | MIPS Computer Systems, Inc. grants reproduction and use   |
+ * | rights to all parties, PROVIDED that this comment is      |
+ * | maintained in the copy.                                   |
+ * |-----------------------------------------------------------|
+ */
+#ifndef _SYM_H
+#define _SYM_H
+
+/* (C) Copyright 1984 by Third Eye Software, Inc.
+ *
+ * Third Eye Software, Inc. grants reproduction and use rights to
+ * all parties, PROVIDED that this comment is maintained in the copy.
+ *
+ * Third Eye makes no claims about the applicability of this
+ * symbol table to a particular use.
+ */
+
+/*
+ * This file contains the definition of the Third Eye Symbol Table.
+ *
+ * Symbols are assumed to be in 'encounter order' - i.e. the order that
+ * the things they represent were encountered by the compiler/assembler/loader.
+ * EXCEPT for globals! These are assumed to be bunched together,
+ * probably right after the last 'normal' symbol.  Globals ARE sorted
+ * in ascending order.
+ *
+ * -----------------------------------------------------------------------
+ * A brief word about Third Eye naming/use conventions:
+ *
+ * All arrays and index's are 0 based.
+ * All "ifooMax" values are the highest legal value PLUS ONE. This makes
+ * them good for allocating arrays, etc. All checks are "ifoo < ifooMax".
+ *
+ * "isym"      Index into the SYMbol table.
+ * "ipd"       Index into the Procedure Descriptor array.
+ * "ifd"       Index into the File Descriptor array.
+ * "iss"       Index into String Space.
+ * "cb"                Count of Bytes.
+ * "rgPd"      array whose domain is "0..ipdMax-1" and RanGe is PDR.
+ * "rgFd"      array whose domain is "0..ifdMax-1" and RanGe is FDR.
+ */
+
+
+/*
+ * Symbolic Header (HDR) structure.
+ * As long as all the pointers are set correctly,
+ * we don't care WHAT order the various sections come out in!
+ *
+ * A file produced solely for the use of CDB will probably NOT have
+ * any instructions or data areas in it, as these are available
+ * in the original.
+ */
+
+typedef struct ecoff_symhdr {
+    coff_short magic;          /* to verify validity of the table */
+    coff_short vstamp;         /* version stamp */
+    coff_int   ilineMax;       /* number of line number entries */
+    coff_int   idnMax;         /* max index into dense number table */
+    coff_int   ipdMax;         /* number of procedures */
+    coff_int   isymMax;        /* number of local symbols */
+    coff_int   ioptMax;        /* max index into optimization symbol entries */
+    coff_int   iauxMax;        /* number of auxillary symbol entries */
+    coff_int   issMax;         /* max index into local strings */
+    coff_int   issExtMax;      /* max index into external strings */
+    coff_int   ifdMax;         /* number of file descriptor entries */
+    coff_int   crfd;           /* number of relative file descriptor entries */
+    coff_int   iextMax;        /* max index into external symbols */
+    coff_addr  cbLine;         /* number of bytes for line number entries */
+    coff_addr  cbLineOffset;   /* offset to start of line number entries*/
+    coff_addr  cbDnOffset;     /* offset to start dense number table */
+    coff_addr  cbPdOffset;     /* offset to procedure descriptor table */
+    coff_addr  cbSymOffset;    /* offset to start of local symbols*/
+    coff_addr  cbOptOffset;    /* offset to optimization symbol entries */
+    coff_addr  cbAuxOffset;    /* offset to start of auxillary symbol entries*/
+    coff_addr  cbSsOffset;     /* offset to start of local strings */
+    coff_addr  cbSsExtOffset;  /* offset to start of external strings */
+    coff_addr  cbFdOffset;     /* offset to file descriptor table */
+    coff_addr  cbRfdOffset;    /* offset to relative file descriptor table */
+    coff_addr  cbExtOffset;    /* offset to start of external symbol entries*/
+    /* If you add machine dependent fields, add them here */
+} HDRR, *pHDRR;
+#define cbHDRR sizeof(HDRR)
+#define hdrNil ((pHDRR)0)
+
+/*
+ * The FDR and PDR structures speed mapping of address <-> name.
+ * They are sorted in ascending memory order and are kept in
+ * memory by CDB at runtime.
+ */
+
+/*
+ * File Descriptor
+ *
+ * There is one of these for EVERY FILE, whether compiled with
+ * full debugging symbols or not.  The name of a file should be
+ * the path name given to the compiler.         This allows the user
+ * to simply specify the names of the directories where the COMPILES
+ * were done, and we will be able to find their files.
+ * A field whose comment starts with "R - " indicates that it will be
+ * setup at runtime.
+ */
+typedef struct ecoff_fdr {
+    coff_addr  adr;            /* memory address of beginning of file */
+    coff_addr  cbLineOffset;   /* byte offset from header for this file ln's */
+    coff_addr  cbLine;         /* size of lines for this file */
+    coff_addr  cbSs;           /* number of bytes in the ss */
+    coff_int   rss;            /* file name (of source, if known) */
+    coff_int   issBase;        /* file's string space */
+    coff_int   isymBase;       /* beginning of symbols */
+    coff_int   csym;           /* count file's of symbols */
+    coff_int   ilineBase;      /* file's line symbols */
+    coff_int   cline;          /* count of file's line symbols */
+    coff_int   ioptBase;       /* file's optimization entries */
+    coff_int   copt;           /* count of file's optimization entries */
+    coff_int   ipdFirst;       /* start of procedures for this file */
+    coff_int   cpd;            /* count of procedures for this file */
+    coff_int   iauxBase;       /* file's auxiliary entries */
+    coff_int   caux;           /* count of file's auxiliary entries */
+    coff_int   rfdBase;        /* index into the file indirect table */
+    coff_int   crfd;           /* count file indirect entries */
+    unsigned lang: 5;  /* language for this file */
+    unsigned fMerge : 1;       /* whether this file can be merged */
+    unsigned fReadin : 1;      /* true if it was read in (not just created) */
+    unsigned fBigendian : 1;/* if set, was compiled on big endian machine */
+    /* aux's will be in compile host's sex */
+    unsigned glevel : 2;       /* level this file was compiled with */
+    unsigned reserved : 22;  /* reserved for future use */
+    coff_uint  reserved2;
+} FDR, *pFDR;
+#define cbFDR sizeof(FDR)
+#define fdNil ((pFDR)0)
+#define ifdNil -1
+#define ifdTemp 0
+#define ilnNil -1
+
+
+/*
+ * Procedure Descriptor
+ *
+ * There is one of these for EVERY TEXT LABEL.
+ * If a procedure is in a file with full symbols, then isym
+ * will point to the PROC symbols, else it will point to the
+ * global symbol for the label.
+ */
+
+typedef struct pdr {
+    coff_addr  adr;            /* memory address of start of procedure */
+    coff_addr  cbLineOffset;   /* byte offset for this procedure from the fd base */
+    coff_int   isym;           /* start of local symbol entries */
+    coff_int   iline;          /* start of line number entries*/
+    coff_uint  regmask;        /* save register mask */
+    coff_int   regoffset;      /* save register offset */
+    coff_int   iopt;           /* start of optimization symbol entries*/
+    coff_uint  fregmask;       /* save floating point register mask */
+    coff_int   fregoffset;     /* save floating point register offset */
+    coff_int   frameoffset;    /* frame size */
+    coff_int   lnLow;          /* lowest line in the procedure */
+    coff_int   lnHigh;         /* highest line in the procedure */
+    /* These fields are new for 64 bit ECOFF.  */
+    unsigned gp_prologue : 8; /* byte size of GP prologue */
+    unsigned gp_used : 1;      /* true if the procedure uses GP */
+    unsigned reg_frame : 1;    /* true if register frame procedure */
+    unsigned prof : 1; /* true if compiled with -pg */
+    unsigned reserved : 13;    /* reserved: must be zero */
+    unsigned localoff : 8;     /* offset of local variables from vfp */
+    coff_short framereg;       /* frame pointer register */
+    coff_short pcreg;          /* offset or reg of return pc */
+} PDR, *pPDR;
+#define cbPDR sizeof(PDR)
+#define pdNil ((pPDR) 0)
+#define ipdNil -1
+
+/*
+ * The structure of the runtime procedure descriptor created by the loader
+ * for use by the static exception system.
+ */
+/*
+ * If 0'd out because exception_info chokes Visual C++ and because there
+ * don't seem to be any references to this structure elsewhere in gdb.
+ */
+#if 0
+typedef struct runtime_pdr {
+    coff_addr  adr;            /* memory address of start of procedure */
+    coff_uint  regmask;        /* save register mask */
+    coff_int   regoffset;      /* save register offset */
+    coff_uint  fregmask;       /* save floating point register mask */
+    coff_int   fregoffset;     /* save floating point register offset */
+    coff_int   frameoffset;    /* frame size */
+    coff_ushort        framereg;       /* frame pointer register */
+    coff_ushort        pcreg;          /* offset or reg of return pc */
+    coff_int   irpss;          /* index into the runtime string table */
+    coff_uint  reserved;
+    struct exception_info *exception_info;/* pointer to exception array */
+} RPDR, *pRPDR;
+#define cbRPDR sizeof(RPDR)
+#define rpdNil ((pRPDR) 0)
+#endif
+
+/*
+ * Line Numbers
+ *
+ * Line Numbers are segregated from the normal symbols because they
+ * are [1] smaller , [2] are of no interest to your
+ * average loader, and [3] are never needed in the middle of normal
+ * scanning and therefore slow things down.
+ *
+ * By definition, the first LINER for any given procedure will have
+ * the first line of a procedure and represent the first address.
+ */
+
+typedef        coff_int LINER, *pLINER;
+#define lineNil ((pLINER)0)
+#define cbLINER sizeof(LINER)
+#define ilineNil       -1
+
+
+
+/*
+ * The Symbol Structure                (GFW, to those who Know!)
+ */
+
+typedef struct ecoff_sym {
+    coff_long  value;          /* value of symbol */
+    coff_int   iss;            /* index into String Space of name */
+    unsigned st : 6;   /* symbol type */
+    unsigned sc  : 5;  /* storage class - text, data, etc */
+    unsigned reserved : 1;     /* reserved */
+    unsigned index : 20;       /* index into sym/aux table */
+} SYMR, *pSYMR;
+#define symNil ((pSYMR)0)
+#define cbSYMR sizeof(SYMR)
+#define isymNil -1
+#define indexNil 0xfffff
+#define issNil -1
+#define issNull 0
+
+
+/* The following converts a memory resident string to an iss.
+ * This hack is recognized in SbFIss, in sym.c of the debugger.
+ */
+#define IssFSb(sb) (0x80000000 | ((coff_ulong)(sb)))
+
+/* E X T E R N A L   S Y M B O L  R E C O R D
+ *
+ *     Same as the SYMR except it contains file context to determine where
+ *     the index is.
+ */
+typedef struct ecoff_extsym {
+    SYMR       asym;           /* symbol for the external */
+    unsigned jmptbl:1; /* symbol is a jump table entry for shlibs */
+    unsigned cobol_main:1;     /* symbol is a cobol main procedure */
+    unsigned weakext:1;        /* symbol is weak external */
+    unsigned reserved:29;      /* reserved for future use */
+    coff_int ifd;              /* where the iss and index fields point into */
+} EXTR, *pEXTR;
+#define extNil ((pEXTR)0)
+#define cbEXTR sizeof(EXTR)
+
+
+/* A U X I L L A R Y   T Y P E  I N F O R M A T I O N */
+
+/*
+ * Type Information Record
+ */
+typedef struct {
+    unsigned fBitfield : 1; /* set if bit width is specified */
+    unsigned continued : 1; /* indicates additional TQ info in next AUX */
+    unsigned bt  : 6;  /* basic type */
+    unsigned tq4 : 4;
+    unsigned tq5 : 4;
+    /* ---- 16 bit boundary ---- */
+    unsigned tq0 : 4;
+    unsigned tq1 : 4;  /* 6 type qualifiers - tqPtr, etc. */
+    unsigned tq2 : 4;
+    unsigned tq3 : 4;
+} TIR, *pTIR;
+#define cbTIR sizeof(TIR)
+#define tiNil ((pTIR)0)
+#define itqMax 6
+
+/*
+ * Relative symbol record
+ *
+ * If the rfd field is 4095, the index field indexes into the global symbol
+ *     table.
+ */
+
+typedef struct {
+    unsigned   rfd : 12;    /* index into the file indirect table */
+    unsigned   index : 20; /* index int sym/aux/iss tables */
+} RNDXR, *pRNDXR;
+#define cbRNDXR sizeof(RNDXR)
+#define rndxNil ((pRNDXR)0)
+
+/* dense numbers or sometimes called block numbers are stored in this type,
+ *     a rfd of 0xffffffff is an index into the global table.
+ */
+typedef struct {
+    coff_uint  rfd;    /* index into the file table */
+    coff_uint  index;  /* index int sym/aux/iss tables */
+} DNR, *pDNR;
+#define cbDNR sizeof(DNR)
+#define dnNil ((pDNR)0)
+
+
+
+/*
+ * Auxillary information occurs only if needed.
+ * It ALWAYS occurs in this order when present.
+
+            isymMac            used by stProc only
+            TIR                        type info
+            TIR                        additional TQ info (if first TIR was not enough)
+            rndx               if (bt == btStruct,btUnion,btEnum,btSet,btRange,
+                                    btTypedef):
+                                    rsym.index == iaux for btSet or btRange
+                                    else rsym.index == isym
+            dimLow             btRange, btSet
+            dimMac             btRange, btSet
+            rndx0              As many as there are tq arrays
+            dimLow0
+            dimHigh0
+            ...
+            rndxMax-1
+            dimLowMax-1
+            dimHighMax-1
+            width in bits      if (bit field), width in bits.
+ */
+#define cAuxMax (6 + (idimMax*3))
+
+/* a union of all possible info in the AUX universe */
+typedef union {
+    TIR        ti;             /* type information record */
+    RNDXR      rndx;           /* relative index into symbol table */
+    coff_int   dnLow;          /* low dimension */
+    coff_int   dnHigh;         /* high dimension */
+    coff_int   isym;           /* symbol table index (end of proc) */
+    coff_int   iss;            /* index into string space (not used) */
+    coff_int   width;          /* width for non-default sized struc fields */
+    coff_int   count;          /* count of ranges for variant arm */
+} AUXU, *pAUXU;
+#define cbAUXU sizeof(AUXU)
+#define auxNil ((pAUXU)0)
+#define iauxNil -1
+
+
+/*
+ * Optimization symbols
+ *
+ * Optimization symbols contain some overlap information with the normal
+ * symbol table. In particular, the proc information
+ * is somewhat redundant but necessary to easily find the other information
+ * present.
+ *
+ * All of the offsets are relative to the beginning of the last otProc
+ */
+
+typedef struct {
+    unsigned ot: 8;            /* optimization type */
+    unsigned value: 24;        /* address where we are moving it to */
+    RNDXR      rndx;           /* points to a symbol or opt entry */
+    coff_ulong offset; /* relative offset this occured */
+} OPTR, *pOPTR;
+#define optNil ((pOPTR) 0)
+#define cbOPTR sizeof(OPTR)
+#define ioptNil -1
+
+/*
+ * File Indirect
+ *
+ * When a symbol is referenced across files the following procedure is used:
+ *     1) use the file index to get the File indirect entry.
+ *     2) use the file indirect entry to get the File descriptor.
+ *     3) add the sym index to the base of that file's sym table
+ *
+ */
+
+typedef coff_long RFDT, *pRFDT;
+#define cbRFDT sizeof(RFDT)
+#define rfdNil -1
+
+/*
+ * The file indirect table in the mips loader is known as an array of FITs.
+ * This is done to keep the code in the loader readable in the area where
+ * these tables are merged.  Note this is only a name change.
+ */
+typedef coff_int FIT, *pFIT;
+#define cbFIT  sizeof(FIT)
+#define ifiNil -1
+#define fiNil  ((pFIT) 0)
+
+#ifdef _LANGUAGE_PASCAL
+#define ifdNil -1
+#define ilnNil -1
+#define ipdNil -1
+#define ilineNil -1
+#define isymNil -1
+#define indexNil 16#fffff
+#define issNil -1
+#define issNull 0
+#define itqMax 6
+#define iauxNil -1
+#define ioptNil -1
+#define rfdNil -1
+#define ifiNil -1
+#endif /* _LANGUAGE_PASCAL */
+
+
+/* Dense numbers
+ *
+ * Rather than use file index, symbol index pairs to represent symbols
+ *     and globals, we use dense number so that they can be easily embeded
+ *     in intermediate code and the programs that process them can
+ *     use direct access tabls instead of hash table (which would be
+ *     necesary otherwise because of the sparse name space caused by
+ *     file index, symbol index pairs. Dense number are represented
+ *     by RNDXRs.
+ */
+
+/*
+ * The following table defines the meaning of each SYM field as
+ * a function of the "st". (scD/B == scData OR scBss)
+ *
+ * Note: the value "isymMac" is used by symbols that have the concept
+ * of enclosing a block of related information.         This value is the
+ * isym of the first symbol AFTER the end associated with the primary
+ * symbol. For example if a procedure was at isym==90 and had an
+ * isymMac==155, the associated end would be at isym==154, and the
+ * symbol at 155 would probably (although not necessarily) be the
+ * symbol for the next procedure.  This allows rapid skipping over
+ * internal information of various sorts. "stEnd"s ALWAYS have the
+ * isym of the primary symbol that started the block.
+ *
+
+ST             SC      VALUE           INDEX
+--------       ------  --------        ------
+stFile         scText  address         isymMac
+stLabel                scText  address         ---
+stGlobal       scD/B   address         iaux
+stStatic       scD/B   address         iaux
+stParam                scAbs   offset          iaux
+stLocal                scAbs   offset          iaux
+stProc         scText  address         iaux    (isymMac is first AUX)
+stStaticProc   scText  address         iaux    (isymMac is first AUX)
+
+stMember       scNil   ordinal         ---     (if member of enum)
+        (mipsread thinks the case below has a bit, not byte, offset.)
+stMember       scNil   byte offset     iaux    (if member of struct/union)
+stMember       scBits  bit offset      iaux    (bit field spec)
+
+stBlock                scText  address         isymMac (text block)
+        (the code seems to think that rather than scNil, we see scInfo for
+         the two cases below.)
+stBlock                scNil   cb              isymMac (struct/union member define)
+stBlock                scNil   cMembers        isymMac (enum member define)
+
+        (New types added by SGI to simplify things:)
+stStruct       scInfo  cb              isymMac (struct type define)
+stUnion                scInfo  cb              isymMac (union  type define)
+stEnum         scInfo  cMembers        isymMac (enum   type define)
+
+stEnd          scText  address         isymStart
+stEnd          scNil   -------         isymStart (struct/union/enum)
+
+stTypedef      scNil   -------         iaux
+stRegReloc     sc???   value           old register number
+stForward      sc???   new address     isym to original symbol
+
+stConstant     scInfo  value           --- (scalar)
+stConstant     scInfo  iss             --- (complex, e.g. string)
+
+ *
+ */
+#endif
diff --git a/base/coff_symconst.h b/base/coff_symconst.h
new file mode 100644 (file)
index 0000000..caed413
--- /dev/null
@@ -0,0 +1,172 @@
+/* $Id$ */
+
+/*
+ * Taken from binutils-2.14.90.0.5 include/coff/symconst.h
+ */
+
+/* Declarations of constants for internal format of MIPS ECOFF symbols.
+   Originally contributed by MIPS Computer Systems and Third Eye Software.
+   Changes contributed by Cygnus Support are in the public domain.
+
+   This file is just aggregated with the files that make up the GNU
+   release; it is not considered part of GAS, GDB, or other GNU
+   programs.  */
+
+/*
+ * |-----------------------------------------------------------|
+ * | Copyright (c) 1992, 1991, 1990 MIPS Computer Systems, Inc.|
+ * | MIPS Computer Systems, Inc. grants reproduction and use   |
+ * | rights to all parties, PROVIDED that this comment is      |
+ * | maintained in the copy.                                   |
+ * |-----------------------------------------------------------|
+ */
+
+/* (C) Copyright 1984 by Third Eye Software, Inc.
+ *
+ * Third Eye Software, Inc. grants reproduction and use rights to
+ * all parties, PROVIDED that this comment is maintained in the copy.
+ *
+ * Third Eye makes no claims about the applicability of this
+ * symbol table to a particular use.
+ */
+
+/* glevels for field in FDR */
+#define GLEVEL_0       2
+#define GLEVEL_1       1
+#define GLEVEL_2       0       /* for upward compat reasons. */
+#define GLEVEL_3       3
+
+/* magic number fo symheader */
+#define magicSym       0x7009
+/* The Alpha uses this value instead, for some reason.  */
+#define magicSym2      0x1992
+
+/* Language codes */
+#define langC          0
+#define langPascal     1
+#define langFortran    2
+#define        langAssembler   3       /* one Assembley inst might map to many mach */
+#define langMachine    4
+#define langNil                5
+#define langAda                6
+#define langPl1                7
+#define langCobol      8
+#define langStdc       9       /* FIXME: Collides with SGI langCplusplus */
+#define langCplusplus  9       /* FIXME: Collides with langStdc */
+#define langCplusplusV2        10      /* SGI addition */
+#define langMax                11      /* maximun allowed 32 -- 5 bits */
+
+/* The following are value definitions for the fields in the SYMR */
+
+/*
+ * Storage Classes
+ */
+
+#define scNil          0
+#define scText         1       /* text symbol */
+#define scData         2       /* initialized data symbol */
+#define scBss          3       /* un-initialized data symbol */
+#define scRegister     4       /* value of symbol is register number */
+#define scAbs          5       /* value of symbol is absolute */
+#define scUndefined    6       /* who knows? */
+#define scCdbLocal     7       /* variable's value is IN se->va.?? */
+#define scBits         8       /* this is a bit field */
+#define scCdbSystem    9       /* variable's value is IN CDB's address space */
+#define scDbx          9       /* overlap dbx internal use */
+#define scRegImage     10      /* register value saved on stack */
+#define scInfo         11      /* symbol contains debugger information */
+#define scUserStruct   12      /* address in struct user for current process */
+#define scSData                13      /* load time only small data */
+#define scSBss         14      /* load time only small common */
+#define scRData                15      /* load time only read only data */
+#define scVar          16      /* Var parameter (fortran,pascal) */
+#define scCommon       17      /* common variable */
+#define scSCommon      18      /* small common */
+#define scVarRegister  19      /* Var parameter in a register */
+#define scVariant      20      /* Variant record */
+#define scSUndefined   21      /* small undefined(external) data */
+#define scInit         22      /* .init section symbol */
+#define scBasedVar     23      /* Fortran or PL/1 ptr based var */
+#define scXData         24      /* exception handling data */
+#define scPData         25      /* Procedure section */
+#define scFini          26      /* .fini section */
+#define scRConst       27      /* .rconst section */
+#define scMax          32
+
+
+/*
+ *   Symbol Types
+ */
+
+#define stNil          0       /* Nuthin' special */
+#define stGlobal       1       /* external symbol */
+#define stStatic       2       /* static */
+#define stParam                3       /* procedure argument */
+#define stLocal                4       /* local variable */
+#define stLabel                5       /* label */
+#define stProc         6       /*     "      "  Procedure */
+#define stBlock                7       /* beginnning of block */
+#define stEnd          8       /* end (of anything) */
+#define stMember       9       /* member (of anything  - struct/union/enum */
+#define stTypedef      10      /* type definition */
+#define stFile         11      /* file name */
+#define stRegReloc     12      /* register relocation */
+#define stForward      13      /* forwarding address */
+#define stStaticProc   14      /* load time only static procs */
+#define stConstant     15      /* const */
+#define stStaParam     16      /* Fortran static parameters */
+    /* These new symbol types have been recently added to SGI machines. */
+#define stStruct       26      /* Beginning of block defining a struct type */
+#define stUnion                27      /* Beginning of block defining a union type */
+#define stEnum         28      /* Beginning of block defining an enum type */
+#define stIndirect     34      /* Indirect type specification */
+    /* Pseudo-symbols - internal to debugger */
+#define stStr          60      /* string */
+#define stNumber       61      /* pure number (ie. 4 NOR 2+2) */
+#define stExpr         62      /* 2+2 vs. 4 */
+#define stType         63      /* post-coersion SER */
+#define stMax          64
+
+/* definitions for fields in TIR */
+
+/* type qualifiers for ti.tq0 -> ti.(itqMax-1) */
+#define tqNil  0       /* bt is what you see */
+#define tqPtr  1       /* pointer */
+#define tqProc 2       /* procedure */
+#define tqArray 3      /* duh */
+#define tqFar  4       /* longer addressing - 8086/8 land */
+#define tqVol  5       /* volatile */
+#define tqConst 6      /* const */
+#define tqMax  8
+
+/* basic types as seen in ti.bt */
+#define btNil          0       /* undefined (also, enum members) */
+#define btAdr          1       /* address - integer same size as pointer */
+#define btChar         2       /* character */
+#define btUChar                3       /* unsigned character */
+#define btShort                4       /* short */
+#define btUShort       5       /* unsigned short */
+#define btInt          6       /* int */
+#define btUInt         7       /* unsigned int */
+#define btLong         8       /* long */
+#define btULong                9       /* unsigned long */
+#define btFloat                10      /* float (real) */
+#define btDouble       11      /* Double (real) */
+#define btStruct       12      /* Structure (Record) */
+#define btUnion                13      /* Union (variant) */
+#define btEnum         14      /* Enumerated */
+#define btTypedef      15      /* defined via a typedef, isymRef points */
+#define btRange                16      /* subrange of int */
+#define btSet          17      /* pascal sets */
+#define btComplex      18      /* fortran complex */
+#define btDComplex     19      /* fortran double complex */
+#define btIndirect     20      /* forward or unnamed typedef */
+#define btFixedDec     21      /* Fixed Decimal */
+#define btFloatDec     22      /* Float Decimal */
+#define btString       23      /* Varying Length Character String */
+#define btBit          24      /* Aligned Bit String */
+#define btPicture      25      /* Picture */
+#define btVoid         26      /* void */
+#define btLongLong     27      /* long long */
+#define btULongLong    28      /* unsigned long long */
+#define btMax          64
diff --git a/base/ecoff_object.cc b/base/ecoff_object.cc
new file mode 100644 (file)
index 0000000..87ad6fd
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+
+#include "ecoff_object.hh"
+
+#include "functional_memory.hh"
+#include "symtab.hh"
+
+#include "trace.hh"    // for DPRINTF
+
+#include "exec_ecoff.h"
+#include "coff_sym.h"
+#include "coff_symconst.h"
+
+using namespace std;
+
+ObjectFile *
+EcoffObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
+{
+    if (((ecoff_filehdr *)data)->f_magic == ECOFF_MAGIC_ALPHA) {
+        // it's Alpha ECOFF
+        return new EcoffObject(fname, fd, len, data);
+    }
+    else {
+        return NULL;
+    }
+}
+
+
+EcoffObject::EcoffObject(const string &_filename, int _fd,
+                         size_t _len, uint8_t *_data)
+    : ObjectFile(_filename, _fd, _len, _data)
+{
+    execHdr = (ecoff_exechdr *)fileData;
+    fileHdr = &(execHdr->f);
+    aoutHdr = &(execHdr->a);
+
+    entry = aoutHdr->entry;
+
+    text.baseAddr = aoutHdr->text_start;
+    text.size = aoutHdr->tsize;
+
+    data.baseAddr = aoutHdr->data_start;
+    data.size = aoutHdr->dsize;
+
+    bss.baseAddr = aoutHdr->bss_start;
+    bss.size = aoutHdr->bsize;
+
+    DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
+             text.baseAddr, text.size, data.baseAddr, data.size,
+             bss.baseAddr, bss.size);
+}
+
+
+bool
+EcoffObject::loadSections(FunctionalMemory *mem, bool loadPhys)
+{
+    Addr textAddr = text.baseAddr;
+    Addr dataAddr = data.baseAddr;
+
+    if (loadPhys) {
+        textAddr &= (ULL(1) << 40) - 1;
+        dataAddr &= (ULL(1) << 40) - 1;
+    }
+
+    // Since we don't really have an MMU and all memory is
+    // zero-filled, there's no need to set up the BSS segment.
+    mem->prot_write(textAddr, fileData + ECOFF_TXTOFF(execHdr), text.size);
+    mem->prot_write(dataAddr, fileData + ECOFF_DATOFF(execHdr), data.size);
+
+    return true;
+}
+
+
+bool
+EcoffObject::loadGlobalSymbols(SymbolTable *symtab)
+{
+    if (!symtab)
+        return false;
+
+    if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
+        cprintf("wrong magic\n");
+        return false;
+    }
+
+    ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
+    if (syms->magic != magicSym2) {
+        cprintf("bad symbol header magic\n");
+        exit(1);
+    }
+
+    ecoff_extsym *ext_syms = (ecoff_extsym *)(fileData + syms->cbExtOffset);
+
+    char *ext_strings = (char *)(fileData + syms->cbSsExtOffset);
+    for (int i = 0; i < syms->iextMax; i++) {
+        ecoff_sym *entry = &(ext_syms[i].asym);
+        if (entry->iss != -1)
+            symtab->insert(entry->value, ext_strings + entry->iss);
+    }
+
+    return true;
+}
+
+bool
+EcoffObject::loadLocalSymbols(SymbolTable *symtab)
+{
+    if (!symtab)
+        return false;
+
+    if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
+        cprintf("wrong magic\n");
+        return false;
+    }
+
+    ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
+    if (syms->magic != magicSym2) {
+        cprintf("bad symbol header magic\n");
+        exit(1);
+    }
+
+    ecoff_sym *local_syms = (ecoff_sym *)(fileData + syms->cbSymOffset);
+    char *local_strings = (char *)(fileData + syms->cbSsOffset);
+    ecoff_fdr *fdesc = (ecoff_fdr *)(fileData + syms->cbFdOffset);
+
+    for (int i = 0; i < syms->ifdMax; i++) {
+        ecoff_sym *entry = (ecoff_sym *)(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 == stGlobal || entry[j].st == stProc)
+                if (entry[j].iss != -1)
+                    symtab->insert(entry[j].value, strings + entry[j].iss);
+        }
+    }
+
+    for (int i = 0; i < syms->isymMax; i++) {
+        ecoff_sym *entry = &(local_syms[i]);
+        if (entry->st == stProc)
+            symtab->insert(entry->value, local_strings + entry->iss);
+    }
+
+    return true;
+}
diff --git a/base/ecoff_object.hh b/base/ecoff_object.hh
new file mode 100644 (file)
index 0000000..af757cd
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ECOFF_OBJECT_HH__
+#define __ECOFF_OBJECT_HH__
+
+#include "object_file.hh"
+
+// forward decls: avoid including exec_ecoff.h here
+struct ecoff_exechdr;
+struct ecoff_filehdr;
+struct ecoff_aouthdr;
+
+class EcoffObject : public ObjectFile
+{
+  protected:
+    ecoff_exechdr *execHdr;
+    ecoff_filehdr *fileHdr;
+    ecoff_aouthdr *aoutHdr;
+
+    EcoffObject(const std::string &_filename, int _fd,
+                size_t _len, uint8_t *_data);
+
+  public:
+    virtual ~EcoffObject() {}
+
+    virtual bool loadSections(FunctionalMemory *mem,
+                              bool loadPhys = false);
+    virtual bool loadGlobalSymbols(SymbolTable *symtab);
+    virtual bool loadLocalSymbols(SymbolTable *symtab);
+
+    static ObjectFile *tryFile(const std::string &fname, int fd,
+                               size_t len, uint8_t *data);
+};
+
+#endif // __ECOFF_OBJECT_HH__
diff --git a/base/elf_object.cc b/base/elf_object.cc
new file mode 100644 (file)
index 0000000..97f50e2
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+
+#include "elf_object.hh"
+
+#include "functional_memory.hh"
+#include "symtab.hh"
+
+#include "trace.hh"    // for DPRINTF
+
+#include "exec_elf.h"
+
+using namespace std;
+
+ObjectFile *
+ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
+{
+    if (memcmp(((Elf64_Ehdr *)data)->e_ident, ELFMAG, SELFMAG) == 0) {
+        // for now we'll assume it's a 64-bit Alpha binary
+        return new ElfObject(fname, fd, len, data);
+    }
+    else {
+        return NULL;
+    }
+}
+
+
+ElfObject::ElfObject(const string &_filename, int _fd,
+                         size_t _len, uint8_t *_data)
+    : ObjectFile(_filename, _fd, _len, _data)
+{
+    ehdr = (Elf64_Ehdr *)fileData;
+
+    entry = ehdr->e_entry;
+
+    phdr = (Elf64_Phdr *)(fileData + ehdr->e_phoff);
+    assert(sizeof(Elf64_Phdr) == ehdr->e_phentsize);
+
+    bool foundText = false;
+    bool foundData = false;
+    for (int i = 0; i < ehdr->e_phnum; ++i) {
+        Elf64_Phdr *p = &phdr[i];
+
+        // for now we don't care about non-loadable segments
+        if (!(p->p_type & PT_LOAD))
+            continue;
+
+        if (p->p_flags & PF_X) {
+            // executable: must be text
+            assert(!foundText);
+            foundText = true;
+            textPhdrIdx = i;
+            text.baseAddr = p->p_vaddr;
+            text.size = p->p_filesz;
+            assert(p->p_filesz == p->p_memsz);
+        }
+        else {
+            assert(p->p_flags & PF_R);
+            assert(!foundData);
+            foundData = true;
+            dataPhdrIdx = i;
+            data.baseAddr = p->p_vaddr;
+            data.size = p->p_filesz;
+            bss.baseAddr = data.baseAddr + data.size;
+            bss.size = p->p_memsz - p->p_filesz;
+        }
+    }
+
+    assert(foundText && foundData);
+
+    DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
+             text.baseAddr, text.size, data.baseAddr, data.size,
+             bss.baseAddr, bss.size);
+}
+
+
+bool
+ElfObject::loadSections(FunctionalMemory *mem, bool loadPhys)
+{
+    Addr textAddr = text.baseAddr;
+    Addr dataAddr = data.baseAddr;
+
+    if (loadPhys) {
+        textAddr &= (ULL(1) << 40) - 1;
+        dataAddr &= (ULL(1) << 40) - 1;
+    }
+
+    // Since we don't really have an MMU and all memory is
+    // zero-filled, there's no need to set up the BSS segment.
+    if (text.size != 0)
+        mem->prot_write(textAddr, fileData + phdr[textPhdrIdx].p_offset,
+                        text.size);
+    if (data.size != 0)
+        mem->prot_write(dataAddr, fileData + phdr[dataPhdrIdx].p_offset,
+                        data.size);
+
+    return true;
+}
+
+
+bool
+ElfObject::loadGlobalSymbols(SymbolTable *symtab)
+{
+    // symbols not supported yet
+    return false;
+}
+
+bool
+ElfObject::loadLocalSymbols(SymbolTable *symtab)
+{
+    // symbols not supported yet
+    return false;
+}
diff --git a/base/elf_object.hh b/base/elf_object.hh
new file mode 100644 (file)
index 0000000..c90f6eb
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ELF_OBJECT_HH__
+#define __ELF_OBJECT_HH__
+
+#include "object_file.hh"
+
+// forward decls: avoid including exec_elf.hh here
+struct Elf64_Ehdr;
+struct Elf64_Phdr;
+
+class ElfObject : public ObjectFile
+{
+  protected:
+    Elf64_Ehdr *ehdr;
+    Elf64_Phdr *phdr;
+
+    int textPhdrIdx;
+    int dataPhdrIdx;
+
+    ElfObject(const std::string &_filename, int _fd,
+              size_t _len, uint8_t *_data);
+
+  public:
+    virtual ~ElfObject() {}
+
+    virtual bool loadSections(FunctionalMemory *mem,
+                              bool loadPhys = false);
+    virtual bool loadGlobalSymbols(SymbolTable *symtab);
+    virtual bool loadLocalSymbols(SymbolTable *symtab);
+
+    static ObjectFile *tryFile(const std::string &fname, int fd,
+                               size_t len, uint8_t *data);
+};
+
+#endif // __ELF_OBJECT_HH__
diff --git a/base/exec_aout.h b/base/exec_aout.h
new file mode 100644 (file)
index 0000000..baed30c
--- /dev/null
@@ -0,0 +1,62 @@
+/* $Id$ */
+
+/*
+ * Taken from NetBSD sys/exec_aout.h
+ */
+
+/*     $NetBSD: exec_aout.h,v 1.29 2002/12/10 17:14:31 thorpej Exp $   */
+
+/*
+ * Copyright (c) 1993, 1994 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Christopher G. Demetriou.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_EXEC_AOUT_H_
+#define _SYS_EXEC_AOUT_H_
+
+#ifndef N_PAGSIZ
+#define        N_PAGSIZ(ex)    (AOUT_LDPGSZ)
+#endif
+
+/* a_magic */
+#define        OMAGIC          0407    /* old impure format */
+#define        NMAGIC          0410    /* read-only text */
+#define        ZMAGIC          0413    /* demand load format */
+
+#define        N_ALIGN(ex,x) \
+        (N_GETMAGIC(ex) == ZMAGIC ? \
+        ((x) + AOUT_LDPGSZ - 1) & ~(AOUT_LDPGSZ - 1) : (x))
+
+/* Valid magic number check. */
+#define        N_BADMAG(ex) \
+        (N_GETMAGIC(ex) != NMAGIC && N_GETMAGIC(ex) != OMAGIC && \
+        N_GETMAGIC(ex) != ZMAGIC)
+
+#include "aout_machdep.h"
+
+#endif /* !_SYS_EXEC_AOUT_H_ */
diff --git a/base/exec_ecoff.h b/base/exec_ecoff.h
new file mode 100644 (file)
index 0000000..8c559ab
--- /dev/null
@@ -0,0 +1,111 @@
+/* $Id$ */
+
+/*
+ * Taken from NetBSD sys/exec_ecoff.h
+ */
+
+/*     $NetBSD: exec_ecoff.h,v 1.13 2003/01/18 09:53:18 thorpej Exp $  */
+
+/*
+ * Copyright (c) 1994 Adam Glass
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Adam Glass.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef        _SYS_EXEC_ECOFF_H_
+#define        _SYS_EXEC_ECOFF_H_
+
+#include "ecoff_machdep.h"
+
+struct ecoff_filehdr {
+        coff_ushort f_magic;   /* magic number */
+        coff_ushort f_nscns;   /* # of sections */
+        coff_uint   f_timdat;  /* time and date stamp */
+        coff_ulong  f_symptr;  /* file offset of symbol table */
+        coff_uint   f_nsyms;   /* # of symbol table entries */
+        coff_ushort f_opthdr;  /* sizeof the optional header */
+        coff_ushort f_flags;   /* flags??? */
+};
+
+struct ecoff_aouthdr {
+        coff_ushort magic;
+        coff_ushort vstamp;
+        ECOFF_PAD
+        coff_ulong  tsize;
+        coff_ulong  dsize;
+        coff_ulong  bsize;
+        coff_ulong  entry;
+        coff_ulong  text_start;
+        coff_ulong  data_start;
+        coff_ulong  bss_start;
+        ECOFF_MACHDEP;
+};
+
+struct ecoff_scnhdr {          /* needed for size info */
+        char   s_name[8];      /* name */
+        coff_ulong  s_paddr;   /* physical addr? for ROMing?*/
+        coff_ulong  s_vaddr;   /* virtual addr? */
+        coff_ulong  s_size;            /* size */
+        coff_ulong  s_scnptr;  /* file offset of raw data */
+        coff_ulong  s_relptr;  /* file offset of reloc data */
+        coff_ulong  s_lnnoptr; /* file offset of line data */
+        coff_ushort s_nreloc;  /* # of relocation entries */
+        coff_ushort s_nlnno;   /* # of line entries */
+        coff_uint   s_flags;   /* flags */
+};
+
+struct ecoff_exechdr {
+        struct ecoff_filehdr f;
+        struct ecoff_aouthdr a;
+};
+
+#define ECOFF_HDR_SIZE (sizeof(struct ecoff_exechdr))
+
+#define ECOFF_OMAGIC 0407
+#define ECOFF_NMAGIC 0410
+#define ECOFF_ZMAGIC 0413
+
+#define ECOFF_ROUND(value, by) \
+        (((value) + (by) - 1) & ~((by) - 1))
+
+#define ECOFF_BLOCK_ALIGN(ep, value) \
+        ((ep)->a.magic == ECOFF_ZMAGIC ? ECOFF_ROUND((value), ECOFF_LDPGSZ) : \
+         (value))
+
+#define ECOFF_TXTOFF(ep) \
+        ((ep)->a.magic == ECOFF_ZMAGIC ? 0 : \
+         ECOFF_ROUND(ECOFF_HDR_SIZE + (ep)->f.f_nscns * \
+                     sizeof(struct ecoff_scnhdr), ECOFF_SEGMENT_ALIGNMENT(ep)))
+
+#define ECOFF_DATOFF(ep) \
+        (ECOFF_BLOCK_ALIGN((ep), ECOFF_TXTOFF(ep) + (ep)->a.tsize))
+
+#define ECOFF_SEGMENT_ALIGN(ep, value) \
+        (ECOFF_ROUND((value), ((ep)->a.magic == ECOFF_ZMAGIC ? ECOFF_LDPGSZ : \
+         ECOFF_SEGMENT_ALIGNMENT(ep))))
+
+#endif /* !_SYS_EXEC_ECOFF_H_ */
index b9542f28015babf9a894035785a127183c2c4c77..07b10b5eef4e1848448649a05fb57ed6f1cc02df 100644 (file)
 #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;
 }
index c100efc94872515747116b43cb4b30df1ab45a34..1e37b7b704be41d5387520d22a5e06ce68aa4151 100644 (file)
 #ifndef __OBJECT_FILE_HH__
 #define __OBJECT_FILE_HH__
 
-#include "ecoff.hh"
 #include "isa_traits.hh"       // for Addr
 
+class FunctionalMemory;
 class SymbolTable;
 
 class ObjectFile
 {
   protected:
-    std::string name;
+    const std::string filename;
     int descriptor;
-    uint8_t *data;
+    uint8_t *fileData;
     size_t len;
 
+    ObjectFile(const std::string &_filename, int _fd,
+               size_t _len, uint8_t *_data);
+
   public:
-    ObjectFile();
-    explicit ObjectFile(std::string file);
     virtual ~ObjectFile();
 
-    bool open(std::string file);
     void close();
 
-    virtual bool loadGlobals(SymbolTable *symtab) = 0;
-    virtual bool loadLocals(SymbolTable *symtab) = 0;
-    virtual void postOpen() = 0;
+    virtual bool loadSections(FunctionalMemory *mem,
+                              bool loadPhys = false) = 0;
+    virtual bool loadGlobalSymbols(SymbolTable *symtab) = 0;
+    virtual bool loadLocalSymbols(SymbolTable *symtab) = 0;
 
   protected:
-    Addr text_off;
-    Addr data_off;
-    Addr bss_off;
 
-    size_t text_size;
-    size_t data_size;
-    size_t bss_size;
+    struct Section {
+        Addr baseAddr;
+        size_t size;
+    };
 
-  public:
-    Addr textOffset() const { return text_off; }
-    Addr dataOffset() const { return data_off; }
-    Addr bssOffset() const { return bss_off; }
+    Addr entry;
+    Addr globalPtr;
 
-    size_t textSize() const { return text_size; }
-    size_t dataSize() const { return data_size; }
-    size_t bssSize() const { return bss_size; }
-};
-
-class EcoffObject : public ObjectFile
-{
-  protected:
-    EcoffFileHeader *exec;
-    EcoffAOutHeader *aout;
+    Section text;
+    Section data;
+    Section bss;
 
   public:
-    EcoffObject() {}
-    explicit EcoffObject(std::string file) { open(file); }
-    virtual ~EcoffObject() {}
+    Addr entryPoint() const { return entry; }
+    Addr globalPointer() const { return globalPtr; }
+
+    Addr textBase() const { return text.baseAddr; }
+    Addr dataBase() const { return data.baseAddr; }
+    Addr bssBase() const { return bss.baseAddr; }
 
-    virtual bool loadGlobals(SymbolTable *symtab);
-    virtual bool loadLocals(SymbolTable *symtab);
-    virtual void postOpen();
+    size_t textSize() const { return text.size; }
+    size_t dataSize() const { return data.size; }
+    size_t bssSize() const { return bss.size; }
 };
 
+ObjectFile *createObjectFile(const std::string &fname);
+
+
 #endif // __OBJECT_FILE_HH__
index 8615cab6884cf64e9552d59443947740a35054a9..355e8d0a1e0f2782ea49ccae3e6ac0ebe662ed29 100644 (file)
@@ -38,7 +38,7 @@
 #include "eio.hh"
 #include "thread.hh"
 #include "fake_syscall.hh"
-#include "loader.hh"
+#include "object_file.hh"
 #include "exec_context.hh"
 #include "smt.hh"
 
@@ -219,12 +219,93 @@ DEFINE_SIM_OBJECT_CLASS_NAME("Process object", Process)
 //
 ////////////////////////////////////////////////////////////////////////
 
+
+static void
+copyStringArray(vector<string> &strings, Addr array_ptr, Addr data_ptr,
+                FunctionalMemory *memory)
+{
+    for (int i = 0; i < strings.size(); ++i) {
+        memory->access(Write, array_ptr, &data_ptr, sizeof(Addr));
+        memory->writeString(data_ptr, strings[i].c_str());
+        array_ptr += sizeof(Addr);
+        data_ptr += strings[i].size() + 1;
+    }
+    // add NULL terminator
+    data_ptr = 0;
+    memory->access(Write, array_ptr, &data_ptr, sizeof(Addr));
+}
+
 LiveProcess::LiveProcess(const string &name,
                          int stdin_fd, int stdout_fd, int stderr_fd,
                          vector<string> &argv, vector<string> &envp)
     : Process(name, stdin_fd, stdout_fd, stderr_fd)
 {
-    smt_load_prog(argv, envp, init_regs, this);
+    prog_fname = argv[0];
+    ObjectFile *objFile = createObjectFile(prog_fname);
+    if (objFile == NULL) {
+        fatal("Can't load object file %s", prog_fname);
+    }
+
+    prog_entry = objFile->entryPoint();
+    text_base = objFile->textBase();
+    text_size = objFile->textSize();
+    data_base = objFile->dataBase();
+    data_size = objFile->dataSize() + objFile->bssSize();
+    brk_point = ROUND_UP(data_base + data_size, VMPageSize);
+
+    // load object file into target memory
+    objFile->loadSections(memory);
+
+    // Set up stack.  On Alpha, stack goes below text section.  This
+    // code should get moved to some architecture-specific spot.
+    stack_base = text_base - (409600+4096);
+
+    // Set pointer for next thread stack.  Reserve 8M for main stack.
+    next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+
+    // Calculate how much space we need for arg & env arrays.
+    int argv_array_size = sizeof(Addr) * (argv.size() + 1);
+    int envp_array_size = sizeof(Addr) * (envp.size() + 1);
+    int arg_data_size = 0;
+    for (int i = 0; i < argv.size(); ++i) {
+        arg_data_size += argv[i].size() + 1;
+    }
+    int env_data_size = 0;
+    for (int i = 0; i < envp.size(); ++i) {
+        env_data_size += envp[i].size() + 1;
+    }
+
+    int space_needed =
+        argv_array_size + envp_array_size + arg_data_size + env_data_size;
+    // for SimpleScalar compatibility
+    if (space_needed < 16384)
+        space_needed = 16384;
+
+    // set bottom of stack
+    stack_min = stack_base - space_needed;
+    // align it
+    stack_min &= ~7;
+    stack_size = stack_base - stack_min;
+
+    // map out initial stack contents
+    Addr argv_array_base = stack_min + sizeof(uint64_t); // room for argc
+    Addr envp_array_base = argv_array_base + argv_array_size;
+    Addr arg_data_base = envp_array_base + envp_array_size;
+    Addr env_data_base = arg_data_base + arg_data_size;
+
+    // write contents to stack
+    uint64_t argc = argv.size();
+    memory->access(Write, stack_min, &argc, sizeof(uint64_t));
+
+    copyStringArray(argv, argv_array_base, arg_data_base, memory);
+    copyStringArray(envp, envp_array_base, env_data_base, memory);
+
+    init_regs->intRegFile[ArgumentReg0] = argc;
+    init_regs->intRegFile[ArgumentReg1] = argv_array_base;
+    init_regs->intRegFile[StackPointerReg] = stack_min;
+    init_regs->intRegFile[GlobalPointerReg] = objFile->globalPointer();
+    init_regs->pc = prog_entry;
+    init_regs->npc = prog_entry + sizeof(MachInst);
 }
 
 
index a38afee145c3d921a8e21833f5857c78ed019a3f..e0439024422c019fb9baf56ab1c0231f31fdd097 100644 (file)
@@ -86,7 +86,6 @@ class Process : public SimObject
 
     Addr brk_point;            // top of the data segment
 
-    Addr environ_base;         // environment base address
     Addr stack_base;           // stack segment base (highest address)
     unsigned stack_size;       // initial stack size
     Addr stack_min;            // lowest address accessed on the stack
index 04db8b1349608fe183e7966621502a2d98565e99..0f6dce10ce9838c6382843f9ad44f4aad42a5536 100644 (file)
@@ -26,7 +26,6 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "kernel_loader.hh"
 #include "exec_context.hh"
 #include "object_file.hh"
 #include "memory_control.hh"
@@ -68,28 +67,47 @@ System::System(const std::string _name,
     kernelSymtab = new SymbolTable;
     consoleSymtab = new SymbolTable;
 
-    EcoffObject kernel(kernel_path);
-    EcoffObject console(console_path);
+    ObjectFile *kernel = createObjectFile(kernel_path);
+    if (kernel == NULL)
+        fatal("Could not load kernel file %s", kernel_path);
 
-    if (!kernel.loadGlobals(kernelSymtab))
+    ObjectFile *console = createObjectFile(console_path);
+    if (console == NULL)
+        fatal("Could not load console file %s", console_path);
+
+    if (!kernel->loadGlobalSymbols(kernelSymtab))
         panic("could not load kernel symbols\n");
 
-    if (!console.loadGlobals(consoleSymtab))
+    if (!console->loadGlobalSymbols(consoleSymtab))
         panic("could not load console symbols\n");
 
     // Load pal file
-    loadPal(palcode, physmem, PAL_BASE);
+    ObjectFile *pal = createObjectFile(palcode);
+    if (pal == NULL)
+        fatal("Could not load PALcode file %s", palcode);
+    pal->loadSections(physmem, true);
 
     // copy of initial reg file contents
     initRegs = new RegFile;
     memset(initRegs, 0, sizeof(RegFile));
 
     // Load console file
-    loadKernel(console_path, physmem);
+    console->loadSections(physmem, true);
 
     // Load kernel file
-    loadKernel(kernel_path, physmem, initRegs,
-               &kernelStart, &kernelEnd, &kernelEntry);
+    kernel->loadSections(physmem, true);
+    kernelStart = kernel->textBase();
+    kernelEnd = kernel->bssBase() + kernel->bssSize();
+    kernelEntry = kernel->entryPoint();
+
+    DPRINTF(Loader, "Kernel start = %#x\n"
+            "Kernel end   = %#x\n"
+            "Kernel entry = %#x\n",
+            kernelStart, kernelEnd, kernelEntry);
+
+    // Setup kernel boot parameters
+    initRegs->pc = 0x4001;
+    initRegs->npc = initRegs->pc + sizeof(MachInst);
 
     DPRINTF(Loader, "Kernel loaded...\n");