diff options
Diffstat (limited to 'base')
-rw-r--r-- | base/aout_object.cc | 111 | ||||
-rw-r--r-- | base/aout_object.hh | 57 | ||||
-rw-r--r-- | base/coff_sym.h | 491 | ||||
-rw-r--r-- | base/coff_symconst.h | 172 | ||||
-rw-r--r-- | base/ecoff_object.cc | 169 | ||||
-rw-r--r-- | base/ecoff_object.hh | 61 | ||||
-rw-r--r-- | base/elf_object.cc | 140 | ||||
-rw-r--r-- | base/elf_object.hh | 62 | ||||
-rw-r--r-- | base/exec_aout.h | 62 | ||||
-rw-r--r-- | base/exec_ecoff.h | 111 | ||||
-rw-r--r-- | base/object_file.cc | 144 | ||||
-rw-r--r-- | base/object_file.hh | 66 |
12 files changed, 1510 insertions, 136 deletions
diff --git a/base/aout_object.cc b/base/aout_object.cc new file mode 100644 index 000000000..c0f43a687 --- /dev/null +++ b/base/aout_object.cc @@ -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 index 000000000..baa8904a8 --- /dev/null +++ b/base/aout_object.hh @@ -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 index 000000000..dae9d8590 --- /dev/null +++ b/base/coff_sym.h @@ -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 index 000000000..caed413c2 --- /dev/null +++ b/base/coff_symconst.h @@ -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 index 000000000..87ad6fdca --- /dev/null +++ b/base/ecoff_object.cc @@ -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 index 000000000..af757cd0e --- /dev/null +++ b/base/ecoff_object.hh @@ -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 index 000000000..97f50e289 --- /dev/null +++ b/base/elf_object.cc @@ -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 index 000000000..c90f6ebd5 --- /dev/null +++ b/base/elf_object.hh @@ -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 index 000000000..baed30c42 --- /dev/null +++ b/base/exec_aout.h @@ -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 index 000000000..8c559ab90 --- /dev/null +++ b/base/exec_ecoff.h @@ -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_ */ diff --git a/base/object_file.cc b/base/object_file.cc index b9542f280..07b10b5ee 100644 --- a/base/object_file.cc +++ b/base/object_file.cc @@ -36,138 +36,80 @@ #include <unistd.h> #include "cprintf.hh" -#include "ecoff.hh" #include "object_file.hh" #include "symtab.hh" +#include "ecoff_object.hh" +#include "aout_object.hh" +#include "elf_object.hh" + using namespace std; -ObjectFile::ObjectFile() - : descriptor(-1), data(NULL) -{} +ObjectFile::ObjectFile(const string &_filename, int _fd, + size_t _len, uint8_t *_data) + : filename(_filename), descriptor(_fd), fileData(_data), len(_len) +{ +} -ObjectFile::ObjectFile(string file) - : descriptor(-1), data(NULL) -{ open(file); } ObjectFile::~ObjectFile() -{ close(); } - -bool -ObjectFile::open(string file_name) { close(); - - name = file_name; - - descriptor = ::open(name.c_str(), O_RDONLY); - if (descriptor < 0) - return false; - - len = (size_t)::lseek(descriptor, 0, SEEK_END); - - data = (uint8_t *)::mmap(NULL, len, PROT_READ, MAP_SHARED, descriptor, 0); - if (data == MAP_FAILED) - return false; - - postOpen(); - - return true; } + void ObjectFile::close() { - if (descriptor >= 0) + if (descriptor >= 0) { ::close(descriptor); + descriptor = -1; + } - if (data) - ::munmap(data, len); + if (fileData) { + ::munmap(fileData, len); + fileData = NULL; + } } -void -EcoffObject::postOpen() -{ - exec = &(((EcoffExecHeader *)data)->f); - aout = &(((EcoffExecHeader *)data)->a); - text_off = aout->text_start; - data_off = aout->data_start; - bss_off = aout->bss_start; - - text_size = aout->tsize; - data_size = aout->dsize; - bss_size = aout->bsize; -} - -bool -EcoffObject::loadGlobals(SymbolTable *symtab) +ObjectFile * +createObjectFile(const string &fname) { - if (!symtab) - return false; - - if (exec->f_magic != ALPHAMAGIC) { - cprintf("wrong magic\n"); - return false; + // open the file + int fd = open(fname.c_str(), O_RDONLY); + if (fd < 0) { + return NULL; } - EcoffSymHeader *syms = (EcoffSymHeader *)(data + exec->f_symptr); - if (syms->magic != ECOFF_SYM_MAGIC) { - cprintf("bad symbol header magic\n"); - exit(1); - } + // find the length of the file by seeking to the end + size_t len = (size_t)lseek(fd, 0, SEEK_END); - EcoffExtSymEntry *ext_syms = - (EcoffExtSymEntry *)(data + syms->cbExtOffset); - - char *ext_strings = (char *)(data + syms->cbSsExtOffset); - for (int i = 0; i < syms->iextMax; i++) { - EcoffSymEntry *entry = &(ext_syms[i].asym); - if (entry->iss != -1) - symtab->insert(entry->value, ext_strings + entry->iss); + // mmap the whole shebang + uint8_t *fileData = + (uint8_t *)mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0); + if (fileData == MAP_FAILED) { + close(fd); + return NULL; } - return true; -} - -bool -EcoffObject::loadLocals(SymbolTable *symtab) -{ - if (!symtab) - return false; - - if (exec->f_magic != ALPHAMAGIC) { - cprintf("wrong magic\n"); - return false; - } + ObjectFile *fileObj = NULL; - EcoffSymHeader *syms = (EcoffSymHeader *)(data + exec->f_symptr); - if (syms->magic != ECOFF_SYM_MAGIC) { - cprintf("bad symbol header magic\n"); - exit(1); + // figure out what we have here + if ((fileObj = EcoffObject::tryFile(fname, fd, len, fileData)) != NULL) { + return fileObj; } - EcoffSymEntry *local_syms = (EcoffSymEntry *)(data + syms->cbSymOffset); - char *local_strings = (char *)(data + syms->cbSsOffset); - EcoffFileDesc *fdesc = (EcoffFileDesc *)(data + syms->cbFdOffset); - - for (int i = 0; i < syms->ifdMax; i++) { - EcoffSymEntry *entry = - (EcoffSymEntry *)(local_syms + fdesc[i].isymBase); - char *strings = (char *)(local_strings + fdesc[i].issBase); - for (int j = 0; j < fdesc[i].csym; j++) { - if (entry[j].st == 1 || entry[j].st == 6) - if (entry[j].iss != -1) - symtab->insert(entry[j].value, strings + entry[j].iss); - } + if ((fileObj = AoutObject::tryFile(fname, fd, len, fileData)) != NULL) { + return fileObj; } - for (int i = 0; i < syms->isymMax; i++) { - EcoffSymEntry *entry = &(local_syms[i]); - if (entry->st == 6) - if (entry->st == 1 || entry->st == 6) - symtab->insert(entry->value, local_strings + entry->iss); + if ((fileObj = ElfObject::tryFile(fname, fd, len, fileData)) != NULL) { + return fileObj; } - return true; + // don't know what it is + close(fd); + munmap(fileData, len); + return NULL; } diff --git a/base/object_file.hh b/base/object_file.hh index c100efc94..1e37b7b70 100644 --- a/base/object_file.hh +++ b/base/object_file.hh @@ -29,64 +29,60 @@ #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__ |