summaryrefslogtreecommitdiff
path: root/src/base/loader
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/loader')
-rw-r--r--src/base/loader/aout_object.cc96
-rw-r--r--src/base/loader/aout_object.hh58
-rw-r--r--src/base/loader/coff_sym.h519
-rw-r--r--src/base/loader/coff_symconst.h200
-rw-r--r--src/base/loader/ecoff_object.cc155
-rw-r--r--src/base/loader/ecoff_object.hh62
-rw-r--r--src/base/loader/elf_object.cc342
-rw-r--r--src/base/loader/elf_object.hh66
-rw-r--r--src/base/loader/exec_aout.h61
-rw-r--r--src/base/loader/exec_ecoff.h110
-rw-r--r--src/base/loader/object_file.cc148
-rw-r--r--src/base/loader/object_file.hh122
-rw-r--r--src/base/loader/symtab.cc139
-rw-r--r--src/base/loader/symtab.hh176
14 files changed, 2254 insertions, 0 deletions
diff --git a/src/base/loader/aout_object.cc b/src/base/loader/aout_object.cc
new file mode 100644
index 000000000..6691bd4ae
--- /dev/null
+++ b/src/base/loader/aout_object.cc
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2003-2005 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.
+ *
+ * Authors: Steve Reinhardt
+ */
+
+#include <string>
+
+#include "base/loader/aout_object.hh"
+
+#include "base/loader/symtab.hh"
+
+#include "base/trace.hh" // for DPRINTF
+
+#include "base/loader/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)) {
+ // right now this is only used for Alpha PAL code
+ return new AoutObject(fname, fd, len, data,
+ ObjectFile::Alpha, ObjectFile::UnknownOpSys);
+ }
+ else {
+ return NULL;
+ }
+}
+
+
+AoutObject::AoutObject(const string &_filename, int _fd,
+ size_t _len, uint8_t *_data,
+ Arch _arch, OpSys _opSys)
+ : ObjectFile(_filename, _fd, _len, _data, _arch, _opSys)
+{
+ execHdr = (aout_exechdr *)fileData;
+
+ entry = execHdr->entry;
+
+ text.baseAddr = N_TXTADDR(*execHdr);
+ text.size = execHdr->tsize;
+ text.fileImage = fileData + N_TXTOFF(*execHdr);
+
+ data.baseAddr = N_DATADDR(*execHdr);
+ data.size = execHdr->dsize;
+ data.fileImage = fileData + N_DATOFF(*execHdr);
+
+ bss.baseAddr = N_BSSADDR(*execHdr);
+ bss.size = execHdr->bsize;
+ bss.fileImage = NULL;
+
+ 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::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/src/base/loader/aout_object.hh b/src/base/loader/aout_object.hh
new file mode 100644
index 000000000..d180d69f3
--- /dev/null
+++ b/src/base/loader/aout_object.hh
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2003-2005 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.
+ *
+ * Authors: Steve Reinhardt
+ */
+
+#ifndef __AOUT_OBJECT_HH__
+#define __AOUT_OBJECT_HH__
+
+#include "base/loader/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,
+ Arch _arch, OpSys _opSys);
+
+ public:
+ virtual ~AoutObject() {}
+
+ 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/src/base/loader/coff_sym.h b/src/base/loader/coff_sym.h
new file mode 100644
index 000000000..4c6540395
--- /dev/null
+++ b/src/base/loader/coff_sym.h
@@ -0,0 +1,519 @@
+/*
+ * Copyright (c) 2003, 2005-2006 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.
+ *
+ * Authors: Steve Reinhardt
+ */
+
+/*
+ * 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/src/base/loader/coff_symconst.h b/src/base/loader/coff_symconst.h
new file mode 100644
index 000000000..f383c19e6
--- /dev/null
+++ b/src/base/loader/coff_symconst.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2003, 2005-2006 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.
+ *
+ * Authors: Steve Reinhardt
+ */
+
+/*
+ * 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/src/base/loader/ecoff_object.cc b/src/base/loader/ecoff_object.cc
new file mode 100644
index 000000000..134f2d98d
--- /dev/null
+++ b/src/base/loader/ecoff_object.cc
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2003-2005 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.
+ *
+ * Authors: Steve Reinhardt
+ */
+
+#include <string>
+
+#include "base/loader/ecoff_object.hh"
+#include "base/misc.hh"
+#include "base/loader/symtab.hh"
+
+#include "base/trace.hh" // for DPRINTF
+
+#include "base/loader/exec_ecoff.h"
+#include "base/loader/coff_sym.h"
+#include "base/loader/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,
+ ObjectFile::Alpha, ObjectFile::Tru64);
+ }
+ else {
+ return NULL;
+ }
+}
+
+
+EcoffObject::EcoffObject(const string &_filename, int _fd,
+ size_t _len, uint8_t *_data,
+ Arch _arch, OpSys _opSys)
+ : ObjectFile(_filename, _fd, _len, _data, _arch, _opSys)
+{
+ execHdr = (ecoff_exechdr *)fileData;
+ fileHdr = &(execHdr->f);
+ aoutHdr = &(execHdr->a);
+
+ entry = aoutHdr->entry;
+
+ text.baseAddr = aoutHdr->text_start;
+ text.size = aoutHdr->tsize;
+ text.fileImage = fileData + ECOFF_TXTOFF(execHdr);
+
+ data.baseAddr = aoutHdr->data_start;
+ data.size = aoutHdr->dsize;
+ data.fileImage = fileData + ECOFF_DATOFF(execHdr);
+
+ bss.baseAddr = aoutHdr->bss_start;
+ bss.size = aoutHdr->bsize;
+ bss.fileImage = NULL;
+
+ 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::loadGlobalSymbols(SymbolTable *symtab)
+{
+ if (!symtab)
+ return false;
+
+ if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
+ warn("loadGlobalSymbols: wrong magic on %s\n", filename);
+ return false;
+ }
+
+ ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
+ if (syms->magic != magicSym2) {
+ warn("loadGlobalSymbols: bad symbol header magic on %s\n", filename);
+ return false;
+ }
+
+ 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) {
+ warn("loadGlobalSymbols: wrong magic on %s\n", filename);
+ return false;
+ }
+
+ ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
+ if (syms->magic != magicSym2) {
+ warn("loadGlobalSymbols: bad symbol header magic on %s\n", filename);
+ return false;
+ }
+
+ 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/src/base/loader/ecoff_object.hh b/src/base/loader/ecoff_object.hh
new file mode 100644
index 000000000..05c604b2b
--- /dev/null
+++ b/src/base/loader/ecoff_object.hh
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2003-2005 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.
+ *
+ * Authors: Steve Reinhardt
+ */
+
+#ifndef __ECOFF_OBJECT_HH__
+#define __ECOFF_OBJECT_HH__
+
+#include "base/loader/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,
+ Arch _arch, OpSys _opSys);
+
+ public:
+ virtual ~EcoffObject() {}
+
+ 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/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc
new file mode 100644
index 000000000..2ca0d4f4a
--- /dev/null
+++ b/src/base/loader/elf_object.cc
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2003-2005 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.
+ *
+ * Authors: Steve Reinhardt
+ * Ali Saidi
+ */
+
+#include <string>
+
+// Because of the -Wundef flag we have to do this
+#define __LIBELF_INTERNAL__ 0
+#define __LIBELF_NEED_LINK_H 0
+#define __LIBELF_SYMBOL_VERSIONS 0
+
+#include "gelf.h"
+
+#include "base/loader/elf_object.hh"
+#include "base/misc.hh"
+
+#include "base/loader/symtab.hh"
+
+#include "base/trace.hh" // for DPRINTF
+
+#include "sim/byteswap.hh"
+
+
+using namespace std;
+
+ObjectFile *
+ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
+{
+ Elf *elf;
+ GElf_Ehdr ehdr;
+ Arch arch = UnknownArch;
+ OpSys opSys = UnknownOpSys;
+
+ // check that header matches library version
+ if (elf_version(EV_CURRENT) == EV_NONE)
+ panic("wrong elf version number!");
+
+ // get a pointer to elf structure
+ elf = elf_memory((char*)data,len);
+ // will only fail if fd is invalid
+ assert(elf != NULL);
+
+ // Check that we actually have a elf file
+ if (gelf_getehdr(elf, &ehdr) ==0) {
+ DPRINTFR(Loader, "Not ELF\n");
+ elf_end(elf);
+ return NULL;
+ } else {
+ //Detect the architecture
+ //Since we don't know how to check for alpha right now, we'll
+ //just assume if it wasn't something else and it's 64 bit, that's
+ //what it must be.
+ if (ehdr.e_machine == EM_SPARC64 ||
+ ehdr.e_machine == EM_SPARC ||
+ ehdr.e_machine == EM_SPARCV9) {
+ arch = ObjectFile::SPARC;
+ } else if (ehdr.e_machine == EM_MIPS
+ && ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
+ arch = ObjectFile::Mips;
+ } else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
+ arch = ObjectFile::Alpha;
+ } else {
+ warn("Unknown architecture: %d\n", ehdr.e_machine);
+ arch = ObjectFile::UnknownArch;
+ }
+
+ //Detect the operating system
+ switch (ehdr.e_ident[EI_OSABI])
+ {
+
+ case ELFOSABI_LINUX:
+ opSys = ObjectFile::Linux;
+ break;
+ case ELFOSABI_SOLARIS:
+ opSys = ObjectFile::Solaris;
+ break;
+ case ELFOSABI_TRU64:
+ opSys = ObjectFile::Tru64;
+ break;
+ default:
+ opSys = ObjectFile::UnknownOpSys;
+ }
+
+ //take a look at the .note.ABI section
+ //It can let us know what's what.
+ if (opSys == ObjectFile::UnknownOpSys) {
+ Elf_Scn *section;
+ GElf_Shdr shdr;
+ Elf_Data *data;
+ uint32_t osAbi;;
+ int secIdx = 1;
+
+ // Get the first section
+ section = elf_getscn(elf, secIdx);
+
+ // While there are no more sections
+ while (section != NULL && opSys == ObjectFile::UnknownOpSys) {
+ gelf_getshdr(section, &shdr);
+ if (shdr.sh_type == SHT_NOTE && !strcmp(".note.ABI-tag",
+ elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) {
+ // we have found a ABI note section
+ // Check the 5th 32bit word for OS 0 == linux, 1 == hurd,
+ // 2 == solaris, 3 == freebsd
+ data = elf_rawdata(section, NULL);
+ assert(data->d_buf);
+ if(ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
+ osAbi = htole(((uint32_t*)data->d_buf)[4]);
+ else
+ osAbi = htobe(((uint32_t*)data->d_buf)[4]);
+
+ switch(osAbi) {
+ case 0:
+ opSys = ObjectFile::Linux;
+ break;
+ case 2:
+ opSys = ObjectFile::Solaris;
+ break;
+ }
+ } // if section found
+ if (!strcmp(".SUNW_version", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name)))
+ opSys = ObjectFile::Solaris;
+ if (!strcmp(".stab.index", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name)))
+ opSys = ObjectFile::Solaris;
+
+ section = elf_getscn(elf, ++secIdx);
+ } // while sections
+ }
+
+ ElfObject * result = new ElfObject(fname, fd, len, data, arch, opSys);
+
+ //The number of headers in the file
+ result->_programHeaderCount = ehdr.e_phnum;
+ //Record the size of each entry
+ result->_programHeaderSize = ehdr.e_phentsize;
+ if(result->_programHeaderCount) //If there is a program header table
+ {
+ //Figure out the virtual address of the header table in the
+ //final memory image. We use the program headers themselves
+ //to translate from a file offset to the address in the image.
+ GElf_Phdr phdr;
+ uint64_t e_phoff = ehdr.e_phoff;
+ result->_programHeaderTable = 0;
+ for(int hdrnum = 0; hdrnum < result->_programHeaderCount; hdrnum++)
+ {
+ gelf_getphdr(elf, hdrnum, &phdr);
+ //Check if we've found the segment with the headers in it
+ if(phdr.p_offset <= e_phoff &&
+ phdr.p_offset + phdr.p_filesz > e_phoff)
+ {
+ result->_programHeaderTable = phdr.p_vaddr + e_phoff;
+ break;
+ }
+ }
+ }
+ else
+ result->_programHeaderTable = 0;
+
+
+ elf_end(elf);
+ return result;
+ }
+}
+
+
+ElfObject::ElfObject(const string &_filename, int _fd,
+ size_t _len, uint8_t *_data,
+ Arch _arch, OpSys _opSys)
+ : ObjectFile(_filename, _fd, _len, _data, _arch, _opSys)
+
+{
+ Elf *elf;
+ GElf_Ehdr ehdr;
+
+ // check that header matches library version
+ if (elf_version(EV_CURRENT) == EV_NONE)
+ panic("wrong elf version number!");
+
+ // get a pointer to elf structure
+ elf = elf_memory((char*)fileData,len);
+ // will only fail if fd is invalid
+ assert(elf != NULL);
+
+ // Check that we actually have a elf file
+ if (gelf_getehdr(elf, &ehdr) ==0) {
+ panic("Not ELF, shouldn't be here");
+ }
+
+ entry = ehdr.e_entry;
+
+
+ // initialize segment sizes to 0 in case they're not present
+ text.size = data.size = bss.size = 0;
+
+ for (int i = 0; i < ehdr.e_phnum; ++i) {
+ GElf_Phdr phdr;
+ if (gelf_getphdr(elf, i, &phdr) == 0) {
+ panic("gelf_getphdr failed for section %d", i);
+ }
+
+ // for now we don't care about non-loadable segments
+ if (!(phdr.p_type & PT_LOAD))
+ continue;
+
+ // the headers don't explicitly distinguish text from data,
+ // but empirically the text segment comes first.
+ if (text.size == 0) { // haven't seen text segment yet
+ text.baseAddr = phdr.p_vaddr;
+ text.size = phdr.p_filesz;
+ text.fileImage = fileData + phdr.p_offset;
+ // if there's any padding at the end that's not in the
+ // file, call it the bss. This happens in the "text"
+ // segment if there's only one loadable segment (as for
+ // kernel images).
+ bss.size = phdr.p_memsz - phdr.p_filesz;
+ bss.baseAddr = phdr.p_vaddr + phdr.p_filesz;
+ bss.fileImage = NULL;
+ } else if (data.size == 0) { // have text, this must be data
+ data.baseAddr = phdr.p_vaddr;
+ data.size = phdr.p_filesz;
+ data.fileImage = fileData + phdr.p_offset;
+ // if there's any padding at the end that's not in the
+ // file, call it the bss. Warn if this happens for both
+ // the text & data segments (should only have one bss).
+ if (phdr.p_memsz - phdr.p_filesz > 0 && bss.size != 0) {
+ warn("Two implied bss segments in file!\n");
+ }
+ bss.size = phdr.p_memsz - phdr.p_filesz;
+ bss.baseAddr = phdr.p_vaddr + phdr.p_filesz;
+ bss.fileImage = NULL;
+ } else {
+ warn("More than two loadable segments in ELF object.");
+ warn("Ignoring segment @ 0x%x length 0x%x.",
+ phdr.p_vaddr, phdr.p_filesz);
+ }
+ }
+
+ // should have found at least one loadable segment
+ assert(text.size != 0);
+
+ 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);
+
+ elf_end(elf);
+
+ // We will actually read the sections when we need to load them
+}
+
+
+bool
+ElfObject::loadSomeSymbols(SymbolTable *symtab, int binding)
+{
+ Elf *elf;
+ int sec_idx = 1; // there is a 0 but it is nothing, go figure
+ Elf_Scn *section;
+ GElf_Shdr shdr;
+ Elf_Data *data;
+ int count, ii;
+ bool found = false;
+ GElf_Sym sym;
+
+ if (!symtab)
+ return false;
+
+ // check that header matches library version
+ if (elf_version(EV_CURRENT) == EV_NONE)
+ panic("wrong elf version number!");
+
+ // get a pointer to elf structure
+ elf = elf_memory((char*)fileData,len);
+
+ assert(elf != NULL);
+
+ // Get the first section
+ section = elf_getscn(elf, sec_idx);
+
+ // While there are no more sections
+ while (section != NULL) {
+ gelf_getshdr(section, &shdr);
+
+ if (shdr.sh_type == SHT_SYMTAB) {
+ found = true;
+ data = elf_getdata(section, NULL);
+ count = shdr.sh_size / shdr.sh_entsize;
+ DPRINTF(Loader, "Found Symbol Table, %d symbols present\n", count);
+
+ // loop through all the symbols, only loading global ones
+ for (ii = 0; ii < count; ++ii) {
+ gelf_getsym(data, ii, &sym);
+ if (GELF_ST_BIND(sym.st_info) == binding) {
+ symtab->insert(sym.st_value,
+ elf_strptr(elf, shdr.sh_link, sym.st_name));
+ }
+ }
+ }
+ ++sec_idx;
+ section = elf_getscn(elf, sec_idx);
+ }
+
+ elf_end(elf);
+
+ return found;
+}
+
+bool
+ElfObject::loadGlobalSymbols(SymbolTable *symtab)
+{
+ return loadSomeSymbols(symtab, STB_GLOBAL);
+}
+
+bool
+ElfObject::loadLocalSymbols(SymbolTable *symtab)
+{
+ return loadSomeSymbols(symtab, STB_LOCAL);
+}
diff --git a/src/base/loader/elf_object.hh b/src/base/loader/elf_object.hh
new file mode 100644
index 000000000..9755426b4
--- /dev/null
+++ b/src/base/loader/elf_object.hh
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2003-2005 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.
+ *
+ * Authors: Steve Reinhardt
+ */
+
+#ifndef __ELF_OBJECT_HH__
+#define __ELF_OBJECT_HH__
+
+#include "base/loader/object_file.hh"
+
+class ElfObject : public ObjectFile
+{
+ protected:
+
+ //These values are provided to a linux process by the kernel, so we
+ //need to keep them around.
+ Addr _programHeaderTable;
+ uint16_t _programHeaderSize;
+ uint16_t _programHeaderCount;
+
+ /// Helper functions for loadGlobalSymbols() and loadLocalSymbols().
+ bool loadSomeSymbols(SymbolTable *symtab, int binding);
+
+ ElfObject(const std::string &_filename, int _fd,
+ size_t _len, uint8_t *_data,
+ Arch _arch, OpSys _opSys);
+
+ public:
+ virtual ~ElfObject() {}
+
+ 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);
+ Addr programHeaderTable() {return _programHeaderTable;}
+ uint16_t programHeaderSize() {return _programHeaderSize;}
+ uint16_t programHeaderCount() {return _programHeaderCount;}
+};
+
+#endif // __ELF_OBJECT_HH__
diff --git a/src/base/loader/exec_aout.h b/src/base/loader/exec_aout.h
new file mode 100644
index 000000000..eed44baee
--- /dev/null
+++ b/src/base/loader/exec_aout.h
@@ -0,0 +1,61 @@
+/*
+ * 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)
+
+//Only alpha will be able to load aout for now
+#include "arch/alpha/aout_machdep.h"
+
+#endif /* !_SYS_EXEC_AOUT_H_ */
diff --git a/src/base/loader/exec_ecoff.h b/src/base/loader/exec_ecoff.h
new file mode 100644
index 000000000..555589806
--- /dev/null
+++ b/src/base/loader/exec_ecoff.h
@@ -0,0 +1,110 @@
+/*
+ * 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_
+
+//Only alpha will be able to load ecoff files for now
+#include "arch/alpha/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_ */
diff --git a/src/base/loader/object_file.cc b/src/base/loader/object_file.cc
new file mode 100644
index 000000000..42c74d418
--- /dev/null
+++ b/src/base/loader/object_file.cc
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2002-2004 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.
+ *
+ * Authors: Nathan Binkert
+ * Steve Reinhardt
+ */
+
+#include <list>
+#include <string>
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "base/cprintf.hh"
+#include "base/loader/object_file.hh"
+#include "base/loader/symtab.hh"
+
+#include "base/loader/ecoff_object.hh"
+#include "base/loader/aout_object.hh"
+#include "base/loader/elf_object.hh"
+
+#include "mem/translating_port.hh"
+
+using namespace std;
+
+ObjectFile::ObjectFile(const string &_filename, int _fd,
+ size_t _len, uint8_t *_data,
+ Arch _arch, OpSys _opSys)
+ : filename(_filename), descriptor(_fd), fileData(_data), len(_len),
+ arch(_arch), opSys(_opSys)
+{
+}
+
+
+ObjectFile::~ObjectFile()
+{
+ close();
+}
+
+
+bool
+ObjectFile::loadSection(Section *sec, Port *memPort, Addr addrMask)
+{
+ if (sec->size != 0) {
+ Addr addr = sec->baseAddr & addrMask;
+ if (sec->fileImage) {
+ memPort->writeBlob(addr, sec->fileImage, sec->size);
+ }
+ else {
+ // no image: must be bss
+ memPort->memsetBlob(addr, 0, sec->size);
+ }
+ }
+ return true;
+}
+
+
+bool
+ObjectFile::loadSections(Port *memPort, Addr addrMask)
+{
+ return (loadSection(&text, memPort, addrMask)
+ && loadSection(&data, memPort, addrMask)
+ && loadSection(&bss, memPort, addrMask));
+}
+
+
+void
+ObjectFile::close()
+{
+ if (descriptor >= 0) {
+ ::close(descriptor);
+ descriptor = -1;
+ }
+
+ if (fileData) {
+ ::munmap(fileData, len);
+ fileData = NULL;
+ }
+}
+
+
+ObjectFile *
+createObjectFile(const string &fname)
+{
+ // open the file
+ int fd = open(fname.c_str(), O_RDONLY);
+ if (fd < 0) {
+ return NULL;
+ }
+
+ // find the length of the file by seeking to the end
+ size_t len = (size_t)lseek(fd, 0, SEEK_END);
+
+ // 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;
+ }
+
+ ObjectFile *fileObj = NULL;
+
+ // figure out what we have here
+ if ((fileObj = EcoffObject::tryFile(fname, fd, len, fileData)) != NULL) {
+ return fileObj;
+ }
+
+ if ((fileObj = AoutObject::tryFile(fname, fd, len, fileData)) != NULL) {
+ return fileObj;
+ }
+
+ if ((fileObj = ElfObject::tryFile(fname, fd, len, fileData)) != NULL) {
+ return fileObj;
+ }
+
+ // don't know what it is
+ close(fd);
+ munmap(fileData, len);
+ return NULL;
+}
diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh
new file mode 100644
index 000000000..79fa394c6
--- /dev/null
+++ b/src/base/loader/object_file.hh
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2002-2004 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.
+ *
+ * Authors: Nathan Binkert
+ * Steve Reinhardt
+ */
+
+#ifndef __OBJECT_FILE_HH__
+#define __OBJECT_FILE_HH__
+
+#include <limits>
+#include <string>
+
+#include "sim/host.hh" // for Addr
+
+class Port;
+class SymbolTable;
+
+class ObjectFile
+{
+ public:
+
+ enum Arch {
+ UnknownArch,
+ Alpha,
+ SPARC,
+ Mips
+ };
+
+ enum OpSys {
+ UnknownOpSys,
+ Tru64,
+ Linux,
+ Solaris
+ };
+
+ protected:
+ const std::string filename;
+ int descriptor;
+ uint8_t *fileData;
+ size_t len;
+
+ Arch arch;
+ OpSys opSys;
+
+ ObjectFile(const std::string &_filename, int _fd,
+ size_t _len, uint8_t *_data,
+ Arch _arch, OpSys _opSys);
+
+ public:
+ virtual ~ObjectFile();
+
+ void close();
+
+ virtual bool loadSections(Port *memPort, Addr addrMask =
+ std::numeric_limits<Addr>::max());
+ virtual bool loadGlobalSymbols(SymbolTable *symtab) = 0;
+ virtual bool loadLocalSymbols(SymbolTable *symtab) = 0;
+
+ Arch getArch() const { return arch; }
+ OpSys getOpSys() const { return opSys; }
+
+ protected:
+
+ struct Section {
+ Addr baseAddr;
+ uint8_t *fileImage;
+ size_t size;
+ };
+
+ Addr entry;
+ Addr globalPtr;
+
+ Section text;
+ Section data;
+ Section bss;
+
+ bool loadSection(Section *sec, Port *memPort, Addr addrMask);
+ void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; }
+
+ public:
+ 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; }
+
+ 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__
diff --git a/src/base/loader/symtab.cc b/src/base/loader/symtab.cc
new file mode 100644
index 000000000..3e73eb7a3
--- /dev/null
+++ b/src/base/loader/symtab.cc
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2002-2005 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.
+ *
+ * Authors: Nathan Binkert
+ */
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+#include "base/loader/symtab.hh"
+#include "base/misc.hh"
+#include "base/str.hh"
+#include "sim/host.hh"
+#include "sim/serialize.hh"
+
+using namespace std;
+
+SymbolTable *debugSymbolTable = NULL;
+
+void
+SymbolTable::clear()
+{
+ addrTable.clear();
+ symbolTable.clear();
+}
+
+bool
+SymbolTable::insert(Addr address, string symbol)
+{
+ if (symbol.empty())
+ return false;
+
+ if (!addrTable.insert(make_pair(address, symbol)).second)
+ return false;
+
+ if (!symbolTable.insert(make_pair(symbol, address)).second)
+ return false;
+
+ return true;
+}
+
+
+bool
+SymbolTable::load(const string &filename)
+{
+ string buffer;
+ ifstream file(filename.c_str());
+
+ if (!file)
+ fatal("file error: Can't open symbol table file %s\n", filename);
+
+ while (!file.eof()) {
+ getline(file, buffer);
+ if (buffer.empty())
+ continue;
+
+ int idx = buffer.find(',');
+ if (idx == string::npos)
+ return false;
+
+ string address = buffer.substr(0, idx);
+ eat_white(address);
+ if (address.empty())
+ return false;
+
+ string symbol = buffer.substr(idx + 1);
+ eat_white(symbol);
+ if (symbol.empty())
+ return false;
+
+ Addr addr;
+ if (!to_number(address, addr))
+ return false;
+
+ if (!insert(addr, symbol))
+ return false;
+ }
+
+ file.close();
+
+ return true;
+}
+
+void
+SymbolTable::serialize(const string &base, ostream &os)
+{
+ paramOut(os, base + ".size", addrTable.size());
+
+ int i = 0;
+ ATable::const_iterator p, end = addrTable.end();
+ for (p = addrTable.begin(); p != end; ++p) {
+ paramOut(os, csprintf("%s.addr_%d", base, i), p->first);
+ paramOut(os, csprintf("%s.symbol_%d", base, i), p->second);
+ ++i;
+ }
+}
+
+void
+SymbolTable::unserialize(const string &base, Checkpoint *cp,
+ const string &section)
+{
+ clear();
+ int size;
+ paramIn(cp, section, base + ".size", size);
+ for (int i = 0; i < size; ++i) {
+ Addr addr;
+ std::string symbol;
+
+ paramIn(cp, section, csprintf("%s.addr_%d", base, i), addr);
+ paramIn(cp, section, csprintf("%s.symbol_%d", base, i), symbol);
+ insert(addr, symbol);
+ }
+}
diff --git a/src/base/loader/symtab.hh b/src/base/loader/symtab.hh
new file mode 100644
index 000000000..184c0a996
--- /dev/null
+++ b/src/base/loader/symtab.hh
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2002-2005 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.
+ *
+ * Authors: Nathan Binkert
+ * Steve Reinhardt
+ */
+
+#ifndef __SYMTAB_HH__
+#define __SYMTAB_HH__
+
+#include <iosfwd>
+#include <map>
+
+#include "sim/host.hh" // for Addr
+
+class Checkpoint;
+class SymbolTable
+{
+ public:
+ typedef std::map<Addr, std::string> ATable;
+ typedef std::map<std::string, Addr> STable;
+
+ private:
+ ATable addrTable;
+ STable symbolTable;
+
+ private:
+ bool
+ upperBound(Addr addr, ATable::const_iterator &iter) const
+ {
+ // find first key *larger* than desired address
+ iter = addrTable.upper_bound(addr);
+
+ // if very first key is larger, we're out of luck
+ if (iter == addrTable.begin())
+ return false;
+
+ return true;
+ }
+
+ public:
+ SymbolTable() {}
+ SymbolTable(const std::string &file) { load(file); }
+ ~SymbolTable() {}
+
+ void clear();
+ bool insert(Addr address, std::string symbol);
+ bool load(const std::string &file);
+
+ const ATable &getAddrTable() const { return addrTable; }
+ const STable &getSymbolTable() const { return symbolTable; }
+
+ public:
+ void serialize(const std::string &base, std::ostream &os);
+ void unserialize(const std::string &base, Checkpoint *cp,
+ const std::string &section);
+
+ public:
+ bool
+ findSymbol(Addr address, std::string &symbol) const
+ {
+ ATable::const_iterator i = addrTable.find(address);
+ if (i == addrTable.end())
+ return false;
+
+ symbol = (*i).second;
+ return true;
+ }
+
+ bool
+ findAddress(const std::string &symbol, Addr &address) const
+ {
+ STable::const_iterator i = symbolTable.find(symbol);
+ if (i == symbolTable.end())
+ return false;
+
+ address = (*i).second;
+ return true;
+ }
+
+ /// Find the nearest symbol equal to or less than the supplied
+ /// address (e.g., the label for the enclosing function).
+ /// @param addr The address to look up.
+ /// @param symbol Return reference for symbol string.
+ /// @param symaddr Return reference for symbol address.
+ /// @param nextaddr Address of following symbol (for
+ /// determining valid range of symbol).
+ /// @retval True if a symbol was found.
+ bool
+ findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr,
+ Addr &nextaddr) const
+ {
+ ATable::const_iterator i;
+ if (!upperBound(addr, i))
+ return false;
+
+ nextaddr = i->first;
+ --i;
+ symaddr = i->first;
+ symbol = i->second;
+ return true;
+ }
+
+ /// Overload for findNearestSymbol() for callers who don't care
+ /// about nextaddr.
+ bool
+ findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr) const
+ {
+ ATable::const_iterator i;
+ if (!upperBound(addr, i))
+ return false;
+
+ --i;
+ symaddr = i->first;
+ symbol = i->second;
+ return true;
+ }
+
+
+ bool
+ findNearestAddr(Addr addr, Addr &symaddr, Addr &nextaddr) const
+ {
+ ATable::const_iterator i;
+ if (!upperBound(addr, i))
+ return false;
+
+ nextaddr = i->first;
+ --i;
+ symaddr = i->first;
+ return true;
+ }
+
+ bool
+ findNearestAddr(Addr addr, Addr &symaddr) const
+ {
+ ATable::const_iterator i;
+ if (!upperBound(addr, i))
+ return false;
+
+ --i;
+ symaddr = i->first;
+ return true;
+ }
+};
+
+/// Global unified debugging symbol table (for target). Conceptually
+/// there should be one of these per System object for full system,
+/// and per Process object for non-full-system, but so far one big
+/// global one has worked well enough.
+extern SymbolTable *debugSymbolTable;
+
+#endif // __SYMTAB_HH__