Adding gem5 source to svn.

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1819 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
friemel
2012-10-24 19:18:57 +00:00
parent f7ff71bd46
commit b41eec3f65
3222 changed files with 658579 additions and 1 deletions

View File

@ -0,0 +1,94 @@
/*
* 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/exec_aout.h"
#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "debug/Loader.hh"
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, Addr addrMask)
{
// a.out symbols not supported yet
return false;
}
bool
AoutObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask)
{
// a.out symbols not supported yet
return false;
}

View File

@ -0,0 +1,60 @@
/*
* 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, Addr addrMask =
std::numeric_limits<Addr>::max());
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max());
static ObjectFile *tryFile(const std::string &fname, int fd,
size_t len, uint8_t *data);
};
#endif // __AOUT_OBJECT_HH__

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,161 @@
/*
* 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/loader/symtab.hh"
#include "base/misc.hh"
#include "base/trace.hh"
#include "base/types.hh"
#include "debug/Loader.hh"
// Only alpha will be able to load ecoff files for now.
// base/types.hh and ecoff_machdep.h must be before the other .h files
// because they are are gathered from other code bases and require some
// typedefs from those files.
#include "arch/alpha/ecoff_machdep.h"
#include "base/loader/coff_sym.h"
#include "base/loader/coff_symconst.h"
#include "base/loader/exec_ecoff.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, Addr addrMask)
{
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, Addr addrMask)
{
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;
}

View File

@ -0,0 +1,64 @@
/*
* 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, Addr addrMask =
std::numeric_limits<Addr>::max());
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max());
static ObjectFile *tryFile(const std::string &fname, int fd,
size_t len, uint8_t *data);
};
#endif // __ECOFF_OBJECT_HH__

View File

@ -0,0 +1,476 @@
/*
* 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 <cassert>
#include <string>
#include "base/loader/elf_object.hh"
#include "base/loader/symtab.hh"
#include "base/bitfield.hh"
#include "base/misc.hh"
#include "base/trace.hh"
#include "debug/Loader.hh"
#include "sim/byteswap.hh"
#include "gelf.h"
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_ident[EI_CLASS] == ELFCLASS64)||
ehdr.e_machine == EM_SPARCV9) {
arch = ObjectFile::SPARC64;
} else if (ehdr.e_machine == EM_SPARC32PLUS ||
(ehdr.e_machine == EM_SPARC &&
ehdr.e_ident[EI_CLASS] == ELFCLASS32)) {
arch = ObjectFile::SPARC32;
} else if (ehdr.e_machine == EM_MIPS
&& ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB) {
arch = ObjectFile::Mips;
} else {
fatal("The binary you're trying to load is compiled for big "
"endian MIPS. M5\nonly supports little endian MIPS. "
"Please recompile your binary.\n");
}
} else if (ehdr.e_machine == EM_X86_64 &&
ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
arch = ObjectFile::X86_64;
} else if (ehdr.e_machine == EM_386 &&
ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
arch = ObjectFile::I386;
} else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
arch = ObjectFile::Alpha;
} else if (ehdr.e_machine == EM_ARM) {
if (bits(ehdr.e_entry, 0)) {
arch = ObjectFile::Thumb;
} else {
arch = ObjectFile::Arm;
}
} else if (ehdr.e_machine == EM_PPC &&
ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
if (ehdr.e_ident[EI_DATA] == ELFDATA2MSB) {
arch = ObjectFile::Power;
} else {
fatal("The binary you're trying to load is compiled for "
"little endian Power.\nM5 only supports big "
"endian Power. Please recompile your binary.\n");
}
} else if (ehdr.e_machine == EM_PPC64) {
fatal("The binary you're trying to load is compiled for 64-bit "
"Power. M5\n only supports 32-bit Power. Please "
"recompile your binary.\n");
} 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;
case ELFOSABI_ARM:
opSys = ObjectFile::LinuxArmOABI;
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_paddr + 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;
int secIdx = 1;
Elf_Scn *section;
GElf_Shdr shdr;
// The first address of some important sections.
Addr textSecStart = 0;
Addr dataSecStart = 0;
Addr bssSecStart = 0;
// Get the first section
section = elf_getscn(elf, secIdx);
// Find the beginning of the most interesting sections.
while (section != NULL) {
gelf_getshdr(section, &shdr);
char * secName = elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name);
if (secName) {
if (!strcmp(".text", secName)) {
textSecStart = shdr.sh_addr;
} else if (!strcmp(".data", secName)) {
dataSecStart = shdr.sh_addr;
} else if (!strcmp(".bss", secName)) {
bssSecStart = shdr.sh_addr;
}
} else {
Elf_Error errorNum = (Elf_Error)elf_errno();
if (errorNum != ELF_E_NONE) {
const char *errorMessage = elf_errmsg(errorNum);
fatal("Error from libelf: %s.\n", errorMessage);
}
}
section = elf_getscn(elf, ++secIdx);
}
// Go through all the segments in the program, record them, and scrape
// out information about the text, data, and bss areas needed by other
// code.
for (int i = 0; i < ehdr.e_phnum; ++i) {
GElf_Phdr phdr;
if (gelf_getphdr(elf, i, &phdr) == 0) {
panic("gelf_getphdr failed for segment %d.", i);
}
// for now we don't care about non-loadable segments
if (!(phdr.p_type & PT_LOAD))
continue;
// Check to see if this segment contains the bss section.
if (phdr.p_paddr <= bssSecStart &&
phdr.p_paddr + phdr.p_memsz > bssSecStart &&
phdr.p_memsz - phdr.p_filesz > 0) {
bss.baseAddr = phdr.p_paddr + phdr.p_filesz;
bss.size = phdr.p_memsz - phdr.p_filesz;
bss.fileImage = NULL;
}
// Check to see if this is the text or data segment
if (phdr.p_vaddr <= textSecStart &&
phdr.p_vaddr + phdr.p_filesz > textSecStart) {
text.baseAddr = phdr.p_paddr;
text.size = phdr.p_filesz;
text.fileImage = fileData + phdr.p_offset;
} else if (phdr.p_vaddr <= dataSecStart &&
phdr.p_vaddr + phdr.p_filesz > dataSecStart) {
data.baseAddr = phdr.p_paddr;
data.size = phdr.p_filesz;
data.fileImage = fileData + phdr.p_offset;
} else {
// If it's none of the above but is loadable,
// load the filesize worth of data
Segment extra;
extra.baseAddr = phdr.p_paddr;
extra.size = phdr.p_filesz;
extra.fileImage = fileData + phdr.p_offset;
extraSegments.push_back(extra);
}
}
// 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, Addr mask)
{
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) {
char *sym_name = elf_strptr(elf, shdr.sh_link, sym.st_name);
if (sym_name && sym_name[0] != '$') {
DPRINTF(Loader, "Symbol: %-40s value %#x\n",
sym_name, sym.st_value);
symtab->insert(sym.st_value & mask, sym_name);
}
}
}
}
++sec_idx;
section = elf_getscn(elf, sec_idx);
}
elf_end(elf);
return found;
}
bool
ElfObject::loadGlobalSymbols(SymbolTable *symtab, Addr addrMask)
{
return loadSomeSymbols(symtab, STB_GLOBAL, addrMask);
}
bool
ElfObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask)
{
return loadSomeSymbols(symtab, STB_LOCAL, addrMask);
}
bool
ElfObject::loadSections(PortProxy& memProxy, Addr addrMask)
{
if (!ObjectFile::loadSections(memProxy, addrMask))
return false;
vector<Segment>::iterator extraIt;
for (extraIt = extraSegments.begin();
extraIt != extraSegments.end(); extraIt++) {
if (!loadSection(&(*extraIt), memProxy, addrMask)) {
return false;
}
}
return true;
}
void
ElfObject::getSections()
{
Elf *elf;
int sec_idx = 1; // there is a 0 but it is nothing, go figure
Elf_Scn *section;
GElf_Shdr shdr;
GElf_Ehdr ehdr;
assert(!sectionNames.size());
// 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);
// Check that we actually have a elf file
if (gelf_getehdr(elf, &ehdr) ==0) {
panic("Not ELF, shouldn't be here");
}
// Get the first section
section = elf_getscn(elf, sec_idx);
// While there are no more sections
while (section != NULL) {
gelf_getshdr(section, &shdr);
sectionNames.insert(elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name));
section = elf_getscn(elf, ++sec_idx);
} // while sections
}
bool
ElfObject::sectionExists(string sec)
{
if (!sectionNames.size())
getSections();
return sectionNames.find(sec) != sectionNames.end();
}

View File

@ -0,0 +1,85 @@
/*
* 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 <set>
#include <vector>
#include "base/loader/object_file.hh"
class ElfObject : public ObjectFile
{
protected:
//The global definition of a "Section" is closest to elf's segments.
typedef ObjectFile::Section Segment;
//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;
std::set<std::string> sectionNames;
/// Helper functions for loadGlobalSymbols() and loadLocalSymbols().
bool loadSomeSymbols(SymbolTable *symtab, int binding, Addr mask);
ElfObject(const std::string &_filename, int _fd,
size_t _len, uint8_t *_data,
Arch _arch, OpSys _opSys);
void getSections();
bool sectionExists(std::string sec);
std::vector<Segment> extraSegments;
public:
virtual ~ElfObject() {}
bool loadSections(PortProxy& memProxy,
Addr addrMask = std::numeric_limits<Addr>::max());
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max());
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max());
virtual bool isDynamic() { return sectionExists(".interp"); }
virtual bool hasTLS() { return sectionExists(".tbss"); }
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__

View File

@ -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_ */

View File

@ -0,0 +1,107 @@
/*
* 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_
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_ */

View File

@ -0,0 +1,138 @@
/*
* Copyright (c) 2007 MIPS Technologies, Inc.
* 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: Jaidev Patwardhan
*/
#include <cctype>
#include <cstdio>
#include <list>
#include <string>
#include "base/loader/hex_file.hh"
#include "base/loader/symtab.hh"
#include "base/cprintf.hh"
#include "mem/port_proxy.hh"
using namespace std;
/*
* Load a Hex File into memory. Currently only used with MIPS
* BARE_IRON mode. A hex file consists of [Address Data] tuples that
* get directly loaded into physical memory. The address specified is
* a word address (i.e., to get the byte address, shift left by 2) The
* data is a full 32-bit hex value.
*/
HexFile::HexFile(const string _filename)
: filename(_filename)
{
fp = fopen(filename.c_str(), "r");
if (fp == NULL)
panic("Unable to open %s\n", filename.c_str());
}
HexFile::~HexFile()
{
}
bool
HexFile::loadSections(PortProxy& memProxy)
{
char Line[64];
Addr MemAddr;
uint32_t Data;
while (!feof(fp)) {
char *ret = fgets(Line, sizeof(Line), fp);
if (!ret)
panic("malformed file");
parseLine(Line, &MemAddr, &Data);
if (MemAddr != 0) {
// Now, write to memory
memProxy.writeBlob(MemAddr << 2, (uint8_t *)&Data, sizeof(Data));
}
}
return true;
}
void
HexFile::parseLine(char *Str, Addr *A, uint32_t *D)
{
int i = 0;
bool Flag = false;
*A = 0;
*D = 0;
int Digit = 0;
unsigned Number = 0;
/* Skip white spaces */
while (Str[i] != '\0' && Str[i]==' ')
i++;
/* Ok, we're at some character...process things */
while (Str[i] != '\0') {
if (Str[i] >= '0' && Str[i] <= '9') {
Digit = Str[i] - '0';
} else if (Str[i] >= 'a' && Str[i] <= 'f') {
Digit = Str[i] - 'a' + 10;
} else if (Str[i] >= 'A' && Str[i] <= 'F') {
Digit=Str[i]-'A'+10;
} else if (Str[i] == ' ' || Str[i] == '\n') {
if (Number == 0)
return;
if (Flag == false) {
*A = Number;
Number = 0;
Flag = true;
} else {
*D = Number;
return;
}
} else {
// Ok, we've encountered a non-hex character, cannot be a
// valid line, skip and return 0's
*A = 0;
*D = 0;
return;
}
Number <<= 4;
Number += Digit;
i++;
}
if (Flag != true) {
*A = 0;
*D = 0;
} else {
*D = Number;
}
}
void
HexFile::close()
{
fclose(fp);
}

View File

@ -0,0 +1,58 @@
/*
* 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: Jaidev Patwardhan
*/
#ifndef __BASE_LOADER_HEX_FILE_HH__
#define __BASE_LOADER_HEX_FILE_HH__
#include <cstdio>
#include <limits>
#include <string>
#include "base/types.hh"
class PortProxy;
class HexFile
{
protected:
const std::string filename;
FILE *fp;
void parseLine(char *, Addr *, uint32_t *);
public:
HexFile(const std::string _filename);
virtual ~HexFile();
void close();
bool loadSections(PortProxy& memProxy);
};
#endif // __BASE_LOADER_HEX_FILE_HH__

View File

@ -0,0 +1,150 @@
/*
* 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 <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstdio>
#include <list>
#include <string>
#include "base/loader/aout_object.hh"
#include "base/loader/ecoff_object.hh"
#include "base/loader/elf_object.hh"
#include "base/loader/object_file.hh"
#include "base/loader/raw_object.hh"
#include "base/loader/symtab.hh"
#include "base/cprintf.hh"
#include "mem/port_proxy.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, PortProxy& memProxy, Addr addrMask)
{
if (sec->size != 0) {
Addr addr = sec->baseAddr & addrMask;
if (sec->fileImage) {
memProxy.writeBlob(addr, sec->fileImage, sec->size);
}
else {
// no image: must be bss
memProxy.memsetBlob(addr, 0, sec->size);
}
}
return true;
}
bool
ObjectFile::loadSections(PortProxy& memProxy, Addr addrMask)
{
return (loadSection(&text, memProxy, addrMask)
&& loadSection(&data, memProxy, addrMask)
&& loadSection(&bss, memProxy, addrMask));
}
void
ObjectFile::close()
{
if (descriptor >= 0) {
::close(descriptor);
descriptor = -1;
}
if (fileData) {
::munmap((char*)fileData, len);
fileData = NULL;
}
}
ObjectFile *
createObjectFile(const string &fname, bool raw)
{
// 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;
}
if (raw)
return RawObject::tryFile(fname, fd, len, fileData);
// don't know what it is
close(fd);
munmap((char*)fileData, len);
return NULL;
}

View File

@ -0,0 +1,136 @@
/*
* 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 "base/types.hh"
class PortProxy;
class SymbolTable;
class ObjectFile
{
public:
enum Arch {
UnknownArch,
Alpha,
SPARC64,
SPARC32,
Mips,
X86_64,
I386,
Arm,
Thumb,
Power
};
enum OpSys {
UnknownOpSys,
Tru64,
Linux,
Solaris,
LinuxArmOABI
};
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(PortProxy& memProxy, Addr addrMask =
std::numeric_limits<Addr>::max());
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max()) = 0;
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max()) = 0;
virtual bool isDynamic() { return false; }
virtual bool hasTLS() { return false; }
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, PortProxy& memProxy, 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; }
void setTextBase(Addr a) { text.baseAddr = a; }
};
ObjectFile *createObjectFile(const std::string &fname, bool raw = false);
#endif // __OBJECT_FILE_HH__

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 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
*/
#include "base/loader/raw_object.hh"
#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "debug/Loader.hh"
ObjectFile *
RawObject::tryFile(const std::string &fname, int fd, size_t len, uint8_t *data)
{
return new RawObject(fname, fd, len, data, ObjectFile::UnknownArch,
ObjectFile::UnknownOpSys);
}
RawObject::RawObject(const std::string &_filename, int _fd, size_t _len,
uint8_t *_data, Arch _arch, OpSys _opSys)
: ObjectFile(_filename, _fd, _len, _data, _arch, _opSys)
{
text.baseAddr = 0;
text.size = len;
text.fileImage = fileData;
data.baseAddr = 0;
data.size = 0;
data.fileImage = NULL;
bss.baseAddr = 0;
bss.size = 0;
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
RawObject::loadGlobalSymbols(SymbolTable *symtab, Addr addrMask)
{
/* int fnameStart = filename.rfind('/',filename.size()) + 1;
int extStart = filename.rfind('.',filename.size());
symtab->insert(text.baseAddr & addrMask, filename.substr(fnameStart,
extStart-fnameStart) + "_start");*/
return true;
}
bool
RawObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask)
{
/* int fnameStart = filename.rfind('/',filename.size()) + 1;
int extStart = filename.rfind('.',filename.size());
symtab->insert(text.baseAddr & addrMask, filename.substr(fnameStart,
extStart-fnameStart) + "_start");*/
return true;
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 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: Ali Saidi
*/
#ifndef __BASE_LOADER_RAW_OBJECT_HH__
#define __BASE_LOADER_RAW_OBJECT_HH__
#include "base/loader/object_file.hh"
class RawObject: public ObjectFile
{
protected:
RawObject(const std::string &_filename, int _fd, size_t _len,
uint8_t *_data, Arch _arch, OpSys _opSys);
public:
virtual ~RawObject() {}
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max());
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max());
static ObjectFile *tryFile(const std::string &fname, int fd, size_t len,
uint8_t *data);
};
#endif // __BASE_LOADER_RAW_OBJECT_HH__

View File

@ -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 <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "base/loader/symtab.hh"
#include "base/misc.hh"
#include "base/str.hh"
#include "base/types.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;
string::size_type 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);
}
}

View File

@ -0,0 +1,177 @@
/*
* 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 <string>
#include "base/types.hh"
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__