Merge zizzer:/bk/m5 into isabel.reinhardt.house:/z/stever/bk/m5
--HG-- extra : convert_revision : a0f7a0793b4c413b8c004633707b1a992f79e8d1
This commit is contained in:
commit
bd360b6b97
17 changed files with 1747 additions and 159 deletions
41
arch/alpha/aout_machdep.h
Normal file
41
arch/alpha/aout_machdep.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#ifndef __AOUT_MACHDEP_H__
|
||||||
|
#define __AOUT_MACHDEP_H__
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Funky Alpha 64-bit a.out header used for PAL code.
|
||||||
|
///
|
||||||
|
struct aout_exechdr {
|
||||||
|
uint16_t magic;
|
||||||
|
uint16_t vstamp;
|
||||||
|
uint16_t bldrev;
|
||||||
|
uint16_t padcell;
|
||||||
|
uint64_t tsize; // text segment size
|
||||||
|
uint64_t dsize; // data segment size
|
||||||
|
uint64_t bsize; // bss segment size
|
||||||
|
uint64_t entry; // entry point
|
||||||
|
uint64_t text_start; // text base address
|
||||||
|
uint64_t data_start; // data base address
|
||||||
|
uint64_t bss_start; // bss base address
|
||||||
|
uint32_t gprmask;
|
||||||
|
uint32_t fprmask;
|
||||||
|
uint64_t gp_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define AOUT_LDPGSZ 8192
|
||||||
|
|
||||||
|
#define N_GETMAGIC(ex) ((ex).magic)
|
||||||
|
|
||||||
|
#define N_BADMAX
|
||||||
|
|
||||||
|
#define N_TXTADDR(ex) ((ex).text_start)
|
||||||
|
#define N_DATADDR(ex) ((ex).data_start)
|
||||||
|
#define N_BSSADDR(ex) ((ex).bss_start)
|
||||||
|
|
||||||
|
#define N_TXTOFF(ex) \
|
||||||
|
(N_GETMAGIC(ex) == ZMAGIC ? 0 : sizeof(struct aout_exechdr))
|
||||||
|
|
||||||
|
#define N_DATOFF(ex) N_ALIGN(ex, N_TXTOFF(ex) + (ex).tsize)
|
||||||
|
|
||||||
|
#endif /* !__AOUT_MACHDEP_H__*/
|
75
arch/alpha/ecoff_machdep.h
Normal file
75
arch/alpha/ecoff_machdep.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Taken from NetBSD arch/alpha/ecoff_machdep.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $NetBSD: ecoff_machdep.h,v 1.5 1999/04/27 02:32:33 cgd Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1994 Adam Glass
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by Adam Glass.
|
||||||
|
* 4. The name of the Author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL Adam Glass BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define COFF/ECOFF integer type sizes
|
||||||
|
//
|
||||||
|
typedef int16_t coff_short;
|
||||||
|
typedef uint16_t coff_ushort;
|
||||||
|
typedef int32_t coff_int;
|
||||||
|
typedef uint32_t coff_uint;
|
||||||
|
typedef int64_t coff_long;
|
||||||
|
typedef uint64_t coff_ulong;
|
||||||
|
typedef uint64_t coff_addr;
|
||||||
|
|
||||||
|
#define ECOFF_LDPGSZ 4096
|
||||||
|
|
||||||
|
#define ECOFF_PAD \
|
||||||
|
coff_ushort bldrev; /* XXX */
|
||||||
|
|
||||||
|
#define ECOFF_MACHDEP \
|
||||||
|
coff_uint gprmask; \
|
||||||
|
coff_uint fprmask; \
|
||||||
|
coff_ulong gp_value
|
||||||
|
|
||||||
|
#define ECOFF_MAGIC_ALPHA 0603
|
||||||
|
#define ECOFF_MAGIC_NETBSD_ALPHA 0605
|
||||||
|
#define ECOFF_BADMAG(ep) \
|
||||||
|
((ep)->f.f_magic != ECOFF_MAGIC_ALPHA && \
|
||||||
|
(ep)->f.f_magic != ECOFF_MAGIC_NETBSD_ALPHA)
|
||||||
|
|
||||||
|
#define ECOFF_FLAG_EXEC 0002
|
||||||
|
#define ECOFF_SEGMENT_ALIGNMENT(ep) \
|
||||||
|
(((ep)->f.f_flags & ECOFF_FLAG_EXEC) == 0 ? 8 : 16)
|
||||||
|
|
||||||
|
#define ECOFF_FLAG_OBJECT_TYPE_MASK 0x3000
|
||||||
|
#define ECOFF_OBJECT_TYPE_NO_SHARED 0x1000
|
||||||
|
#define ECOFF_OBJECT_TYPE_SHARABLE 0x2000
|
||||||
|
#define ECOFF_OBJECT_TYPE_CALL_SHARED 0x3000
|
||||||
|
|
111
base/aout_object.cc
Normal file
111
base/aout_object.cc
Normal file
|
@ -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;
|
||||||
|
}
|
57
base/aout_object.hh
Normal file
57
base/aout_object.hh
Normal file
|
@ -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__
|
491
base/coff_sym.h
Normal file
491
base/coff_sym.h
Normal file
|
@ -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
|
172
base/coff_symconst.h
Normal file
172
base/coff_symconst.h
Normal file
|
@ -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
|
169
base/ecoff_object.cc
Normal file
169
base/ecoff_object.cc
Normal file
|
@ -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;
|
||||||
|
}
|
61
base/ecoff_object.hh
Normal file
61
base/ecoff_object.hh
Normal file
|
@ -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__
|
140
base/elf_object.cc
Normal file
140
base/elf_object.cc
Normal file
|
@ -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;
|
||||||
|
}
|
62
base/elf_object.hh
Normal file
62
base/elf_object.hh
Normal file
|
@ -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__
|
62
base/exec_aout.h
Normal file
62
base/exec_aout.h
Normal file
|
@ -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_ */
|
111
base/exec_ecoff.h
Normal file
111
base/exec_ecoff.h
Normal file
|
@ -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_ */
|
|
@ -36,138 +36,80 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "cprintf.hh"
|
#include "cprintf.hh"
|
||||||
#include "ecoff.hh"
|
|
||||||
#include "object_file.hh"
|
#include "object_file.hh"
|
||||||
#include "symtab.hh"
|
#include "symtab.hh"
|
||||||
|
|
||||||
|
#include "ecoff_object.hh"
|
||||||
|
#include "aout_object.hh"
|
||||||
|
#include "elf_object.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
ObjectFile::ObjectFile()
|
ObjectFile::ObjectFile(const string &_filename, int _fd,
|
||||||
: descriptor(-1), data(NULL)
|
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()
|
ObjectFile::~ObjectFile()
|
||||||
{ close(); }
|
|
||||||
|
|
||||||
bool
|
|
||||||
ObjectFile::open(string file_name)
|
|
||||||
{
|
{
|
||||||
close();
|
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
|
void
|
||||||
ObjectFile::close()
|
ObjectFile::close()
|
||||||
{
|
{
|
||||||
if (descriptor >= 0)
|
if (descriptor >= 0) {
|
||||||
::close(descriptor);
|
::close(descriptor);
|
||||||
|
descriptor = -1;
|
||||||
if (data)
|
|
||||||
::munmap(data, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
if (fileData) {
|
||||||
EcoffObject::postOpen()
|
::munmap(fileData, len);
|
||||||
|
fileData = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ObjectFile *
|
||||||
|
createObjectFile(const string &fname)
|
||||||
{
|
{
|
||||||
exec = &(((EcoffExecHeader *)data)->f);
|
// open the file
|
||||||
aout = &(((EcoffExecHeader *)data)->a);
|
int fd = open(fname.c_str(), O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
text_off = aout->text_start;
|
return NULL;
|
||||||
data_off = aout->data_start;
|
|
||||||
bss_off = aout->bss_start;
|
|
||||||
|
|
||||||
text_size = aout->tsize;
|
|
||||||
data_size = aout->dsize;
|
|
||||||
bss_size = aout->bsize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
// find the length of the file by seeking to the end
|
||||||
EcoffObject::loadGlobals(SymbolTable *symtab)
|
size_t len = (size_t)lseek(fd, 0, SEEK_END);
|
||||||
{
|
|
||||||
if (!symtab)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (exec->f_magic != ALPHAMAGIC) {
|
// mmap the whole shebang
|
||||||
cprintf("wrong magic\n");
|
uint8_t *fileData =
|
||||||
return false;
|
(uint8_t *)mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
|
if (fileData == MAP_FAILED) {
|
||||||
|
close(fd);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
EcoffSymHeader *syms = (EcoffSymHeader *)(data + exec->f_symptr);
|
ObjectFile *fileObj = NULL;
|
||||||
if (syms->magic != ECOFF_SYM_MAGIC) {
|
|
||||||
cprintf("bad symbol header magic\n");
|
// figure out what we have here
|
||||||
exit(1);
|
if ((fileObj = EcoffObject::tryFile(fname, fd, len, fileData)) != NULL) {
|
||||||
|
return fileObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
EcoffExtSymEntry *ext_syms =
|
if ((fileObj = AoutObject::tryFile(fname, fd, len, fileData)) != NULL) {
|
||||||
(EcoffExtSymEntry *)(data + syms->cbExtOffset);
|
return fileObj;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
if ((fileObj = ElfObject::tryFile(fname, fd, len, fileData)) != NULL) {
|
||||||
|
return fileObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
// don't know what it is
|
||||||
EcoffObject::loadLocals(SymbolTable *symtab)
|
close(fd);
|
||||||
{
|
munmap(fileData, len);
|
||||||
if (!symtab)
|
return NULL;
|
||||||
return false;
|
|
||||||
|
|
||||||
if (exec->f_magic != ALPHAMAGIC) {
|
|
||||||
cprintf("wrong magic\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
EcoffSymHeader *syms = (EcoffSymHeader *)(data + exec->f_symptr);
|
|
||||||
if (syms->magic != ECOFF_SYM_MAGIC) {
|
|
||||||
cprintf("bad symbol header magic\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,64 +29,60 @@
|
||||||
#ifndef __OBJECT_FILE_HH__
|
#ifndef __OBJECT_FILE_HH__
|
||||||
#define __OBJECT_FILE_HH__
|
#define __OBJECT_FILE_HH__
|
||||||
|
|
||||||
#include "ecoff.hh"
|
|
||||||
#include "isa_traits.hh" // for Addr
|
#include "isa_traits.hh" // for Addr
|
||||||
|
|
||||||
|
class FunctionalMemory;
|
||||||
class SymbolTable;
|
class SymbolTable;
|
||||||
|
|
||||||
class ObjectFile
|
class ObjectFile
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
std::string name;
|
const std::string filename;
|
||||||
int descriptor;
|
int descriptor;
|
||||||
uint8_t *data;
|
uint8_t *fileData;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
ObjectFile(const std::string &_filename, int _fd,
|
||||||
|
size_t _len, uint8_t *_data);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ObjectFile();
|
|
||||||
explicit ObjectFile(std::string file);
|
|
||||||
virtual ~ObjectFile();
|
virtual ~ObjectFile();
|
||||||
|
|
||||||
bool open(std::string file);
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
virtual bool loadGlobals(SymbolTable *symtab) = 0;
|
virtual bool loadSections(FunctionalMemory *mem,
|
||||||
virtual bool loadLocals(SymbolTable *symtab) = 0;
|
bool loadPhys = false) = 0;
|
||||||
virtual void postOpen() = 0;
|
virtual bool loadGlobalSymbols(SymbolTable *symtab) = 0;
|
||||||
|
virtual bool loadLocalSymbols(SymbolTable *symtab) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Addr text_off;
|
|
||||||
Addr data_off;
|
|
||||||
Addr bss_off;
|
|
||||||
|
|
||||||
size_t text_size;
|
struct Section {
|
||||||
size_t data_size;
|
Addr baseAddr;
|
||||||
size_t bss_size;
|
size_t size;
|
||||||
|
|
||||||
public:
|
|
||||||
Addr textOffset() const { return text_off; }
|
|
||||||
Addr dataOffset() const { return data_off; }
|
|
||||||
Addr bssOffset() const { return bss_off; }
|
|
||||||
|
|
||||||
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
|
Addr entry;
|
||||||
{
|
Addr globalPtr;
|
||||||
protected:
|
|
||||||
EcoffFileHeader *exec;
|
Section text;
|
||||||
EcoffAOutHeader *aout;
|
Section data;
|
||||||
|
Section bss;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EcoffObject() {}
|
Addr entryPoint() const { return entry; }
|
||||||
explicit EcoffObject(std::string file) { open(file); }
|
Addr globalPointer() const { return globalPtr; }
|
||||||
virtual ~EcoffObject() {}
|
|
||||||
|
|
||||||
virtual bool loadGlobals(SymbolTable *symtab);
|
Addr textBase() const { return text.baseAddr; }
|
||||||
virtual bool loadLocals(SymbolTable *symtab);
|
Addr dataBase() const { return data.baseAddr; }
|
||||||
virtual void postOpen();
|
Addr bssBase() const { return bss.baseAddr; }
|
||||||
|
|
||||||
|
size_t textSize() const { return text.size; }
|
||||||
|
size_t dataSize() const { return data.size; }
|
||||||
|
size_t bssSize() const { return bss.size; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ObjectFile *createObjectFile(const std::string &fname);
|
||||||
|
|
||||||
|
|
||||||
#endif // __OBJECT_FILE_HH__
|
#endif // __OBJECT_FILE_HH__
|
||||||
|
|
85
sim/prog.cc
85
sim/prog.cc
|
@ -38,7 +38,7 @@
|
||||||
#include "eio.hh"
|
#include "eio.hh"
|
||||||
#include "thread.hh"
|
#include "thread.hh"
|
||||||
#include "fake_syscall.hh"
|
#include "fake_syscall.hh"
|
||||||
#include "loader.hh"
|
#include "object_file.hh"
|
||||||
#include "exec_context.hh"
|
#include "exec_context.hh"
|
||||||
#include "smt.hh"
|
#include "smt.hh"
|
||||||
|
|
||||||
|
@ -219,12 +219,93 @@ DEFINE_SIM_OBJECT_CLASS_NAME("Process object", Process)
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
copyStringArray(vector<string> &strings, Addr array_ptr, Addr data_ptr,
|
||||||
|
FunctionalMemory *memory)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < strings.size(); ++i) {
|
||||||
|
memory->access(Write, array_ptr, &data_ptr, sizeof(Addr));
|
||||||
|
memory->writeString(data_ptr, strings[i].c_str());
|
||||||
|
array_ptr += sizeof(Addr);
|
||||||
|
data_ptr += strings[i].size() + 1;
|
||||||
|
}
|
||||||
|
// add NULL terminator
|
||||||
|
data_ptr = 0;
|
||||||
|
memory->access(Write, array_ptr, &data_ptr, sizeof(Addr));
|
||||||
|
}
|
||||||
|
|
||||||
LiveProcess::LiveProcess(const string &name,
|
LiveProcess::LiveProcess(const string &name,
|
||||||
int stdin_fd, int stdout_fd, int stderr_fd,
|
int stdin_fd, int stdout_fd, int stderr_fd,
|
||||||
vector<string> &argv, vector<string> &envp)
|
vector<string> &argv, vector<string> &envp)
|
||||||
: Process(name, stdin_fd, stdout_fd, stderr_fd)
|
: Process(name, stdin_fd, stdout_fd, stderr_fd)
|
||||||
{
|
{
|
||||||
smt_load_prog(argv, envp, init_regs, this);
|
prog_fname = argv[0];
|
||||||
|
ObjectFile *objFile = createObjectFile(prog_fname);
|
||||||
|
if (objFile == NULL) {
|
||||||
|
fatal("Can't load object file %s", prog_fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
prog_entry = objFile->entryPoint();
|
||||||
|
text_base = objFile->textBase();
|
||||||
|
text_size = objFile->textSize();
|
||||||
|
data_base = objFile->dataBase();
|
||||||
|
data_size = objFile->dataSize() + objFile->bssSize();
|
||||||
|
brk_point = ROUND_UP(data_base + data_size, VMPageSize);
|
||||||
|
|
||||||
|
// load object file into target memory
|
||||||
|
objFile->loadSections(memory);
|
||||||
|
|
||||||
|
// Set up stack. On Alpha, stack goes below text section. This
|
||||||
|
// code should get moved to some architecture-specific spot.
|
||||||
|
stack_base = text_base - (409600+4096);
|
||||||
|
|
||||||
|
// Set pointer for next thread stack. Reserve 8M for main stack.
|
||||||
|
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
|
||||||
|
|
||||||
|
// Calculate how much space we need for arg & env arrays.
|
||||||
|
int argv_array_size = sizeof(Addr) * (argv.size() + 1);
|
||||||
|
int envp_array_size = sizeof(Addr) * (envp.size() + 1);
|
||||||
|
int arg_data_size = 0;
|
||||||
|
for (int i = 0; i < argv.size(); ++i) {
|
||||||
|
arg_data_size += argv[i].size() + 1;
|
||||||
|
}
|
||||||
|
int env_data_size = 0;
|
||||||
|
for (int i = 0; i < envp.size(); ++i) {
|
||||||
|
env_data_size += envp[i].size() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int space_needed =
|
||||||
|
argv_array_size + envp_array_size + arg_data_size + env_data_size;
|
||||||
|
// for SimpleScalar compatibility
|
||||||
|
if (space_needed < 16384)
|
||||||
|
space_needed = 16384;
|
||||||
|
|
||||||
|
// set bottom of stack
|
||||||
|
stack_min = stack_base - space_needed;
|
||||||
|
// align it
|
||||||
|
stack_min &= ~7;
|
||||||
|
stack_size = stack_base - stack_min;
|
||||||
|
|
||||||
|
// map out initial stack contents
|
||||||
|
Addr argv_array_base = stack_min + sizeof(uint64_t); // room for argc
|
||||||
|
Addr envp_array_base = argv_array_base + argv_array_size;
|
||||||
|
Addr arg_data_base = envp_array_base + envp_array_size;
|
||||||
|
Addr env_data_base = arg_data_base + arg_data_size;
|
||||||
|
|
||||||
|
// write contents to stack
|
||||||
|
uint64_t argc = argv.size();
|
||||||
|
memory->access(Write, stack_min, &argc, sizeof(uint64_t));
|
||||||
|
|
||||||
|
copyStringArray(argv, argv_array_base, arg_data_base, memory);
|
||||||
|
copyStringArray(envp, envp_array_base, env_data_base, memory);
|
||||||
|
|
||||||
|
init_regs->intRegFile[ArgumentReg0] = argc;
|
||||||
|
init_regs->intRegFile[ArgumentReg1] = argv_array_base;
|
||||||
|
init_regs->intRegFile[StackPointerReg] = stack_min;
|
||||||
|
init_regs->intRegFile[GlobalPointerReg] = objFile->globalPointer();
|
||||||
|
init_regs->pc = prog_entry;
|
||||||
|
init_regs->npc = prog_entry + sizeof(MachInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,6 @@ class Process : public SimObject
|
||||||
|
|
||||||
Addr brk_point; // top of the data segment
|
Addr brk_point; // top of the data segment
|
||||||
|
|
||||||
Addr environ_base; // environment base address
|
|
||||||
Addr stack_base; // stack segment base (highest address)
|
Addr stack_base; // stack segment base (highest address)
|
||||||
unsigned stack_size; // initial stack size
|
unsigned stack_size; // initial stack size
|
||||||
Addr stack_min; // lowest address accessed on the stack
|
Addr stack_min; // lowest address accessed on the stack
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel_loader.hh"
|
|
||||||
#include "exec_context.hh"
|
#include "exec_context.hh"
|
||||||
#include "object_file.hh"
|
#include "object_file.hh"
|
||||||
#include "memory_control.hh"
|
#include "memory_control.hh"
|
||||||
|
@ -68,28 +67,47 @@ System::System(const std::string _name,
|
||||||
kernelSymtab = new SymbolTable;
|
kernelSymtab = new SymbolTable;
|
||||||
consoleSymtab = new SymbolTable;
|
consoleSymtab = new SymbolTable;
|
||||||
|
|
||||||
EcoffObject kernel(kernel_path);
|
ObjectFile *kernel = createObjectFile(kernel_path);
|
||||||
EcoffObject console(console_path);
|
if (kernel == NULL)
|
||||||
|
fatal("Could not load kernel file %s", kernel_path);
|
||||||
|
|
||||||
if (!kernel.loadGlobals(kernelSymtab))
|
ObjectFile *console = createObjectFile(console_path);
|
||||||
|
if (console == NULL)
|
||||||
|
fatal("Could not load console file %s", console_path);
|
||||||
|
|
||||||
|
if (!kernel->loadGlobalSymbols(kernelSymtab))
|
||||||
panic("could not load kernel symbols\n");
|
panic("could not load kernel symbols\n");
|
||||||
|
|
||||||
if (!console.loadGlobals(consoleSymtab))
|
if (!console->loadGlobalSymbols(consoleSymtab))
|
||||||
panic("could not load console symbols\n");
|
panic("could not load console symbols\n");
|
||||||
|
|
||||||
// Load pal file
|
// Load pal file
|
||||||
loadPal(palcode, physmem, PAL_BASE);
|
ObjectFile *pal = createObjectFile(palcode);
|
||||||
|
if (pal == NULL)
|
||||||
|
fatal("Could not load PALcode file %s", palcode);
|
||||||
|
pal->loadSections(physmem, true);
|
||||||
|
|
||||||
// copy of initial reg file contents
|
// copy of initial reg file contents
|
||||||
initRegs = new RegFile;
|
initRegs = new RegFile;
|
||||||
memset(initRegs, 0, sizeof(RegFile));
|
memset(initRegs, 0, sizeof(RegFile));
|
||||||
|
|
||||||
// Load console file
|
// Load console file
|
||||||
loadKernel(console_path, physmem);
|
console->loadSections(physmem, true);
|
||||||
|
|
||||||
// Load kernel file
|
// Load kernel file
|
||||||
loadKernel(kernel_path, physmem, initRegs,
|
kernel->loadSections(physmem, true);
|
||||||
&kernelStart, &kernelEnd, &kernelEntry);
|
kernelStart = kernel->textBase();
|
||||||
|
kernelEnd = kernel->bssBase() + kernel->bssSize();
|
||||||
|
kernelEntry = kernel->entryPoint();
|
||||||
|
|
||||||
|
DPRINTF(Loader, "Kernel start = %#x\n"
|
||||||
|
"Kernel end = %#x\n"
|
||||||
|
"Kernel entry = %#x\n",
|
||||||
|
kernelStart, kernelEnd, kernelEntry);
|
||||||
|
|
||||||
|
// Setup kernel boot parameters
|
||||||
|
initRegs->pc = 0x4001;
|
||||||
|
initRegs->npc = initRegs->pc + sizeof(MachInst);
|
||||||
|
|
||||||
DPRINTF(Loader, "Kernel loaded...\n");
|
DPRINTF(Loader, "Kernel loaded...\n");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue