mirror of
https://github.com/golang/go
synced 2024-11-21 19:14:44 -07:00
Add 6db
SVN=122505
This commit is contained in:
parent
ef61a4cb1e
commit
ed5e39a66d
169
include/bootexec.h
Normal file
169
include/bootexec.h
Normal file
@ -0,0 +1,169 @@
|
||||
// Inferno libmach/bootexec.h
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/bootexec.h
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
struct coffsect
|
||||
{
|
||||
char name[8];
|
||||
ulong phys;
|
||||
ulong virt;
|
||||
ulong size;
|
||||
ulong fptr;
|
||||
ulong fptrreloc;
|
||||
ulong fptrlineno;
|
||||
ulong nrelocnlineno;
|
||||
ulong flags;
|
||||
};
|
||||
|
||||
/*
|
||||
* proprietary exec headers, needed to bootstrap various machines
|
||||
*/
|
||||
struct mipsexec
|
||||
{
|
||||
short mmagic; /* (0x160) mips magic number */
|
||||
short nscns; /* (unused) number of sections */
|
||||
long timdat; /* (unused) time & date stamp */
|
||||
long symptr; /* offset to symbol table */
|
||||
long nsyms; /* size of symbol table */
|
||||
short opthdr; /* (0x38) sizeof(optional hdr) */
|
||||
short pcszs; /* flags */
|
||||
short amagic; /* see above */
|
||||
short vstamp; /* version stamp */
|
||||
long tsize; /* text size in bytes */
|
||||
long dsize; /* initialized data */
|
||||
long bsize; /* uninitialized data */
|
||||
long mentry; /* entry pt. */
|
||||
long text_start; /* base of text used for this file */
|
||||
long data_start; /* base of data used for this file */
|
||||
long bss_start; /* base of bss used for this file */
|
||||
long gprmask; /* general purpose register mask */
|
||||
union{
|
||||
long cprmask[4]; /* co-processor register masks */
|
||||
long pcsize;
|
||||
};
|
||||
long gp_value; /* the gp value used for this object */
|
||||
};
|
||||
|
||||
struct mips4kexec
|
||||
{
|
||||
struct mipsexec h;
|
||||
struct coffsect itexts;
|
||||
struct coffsect idatas;
|
||||
struct coffsect ibsss;
|
||||
};
|
||||
|
||||
struct sparcexec
|
||||
{
|
||||
short sjunk; /* dynamic bit and version number */
|
||||
short smagic; /* 0407 */
|
||||
ulong stext;
|
||||
ulong sdata;
|
||||
ulong sbss;
|
||||
ulong ssyms;
|
||||
ulong sentry;
|
||||
ulong strsize;
|
||||
ulong sdrsize;
|
||||
};
|
||||
|
||||
struct nextexec
|
||||
{
|
||||
/* UNUSED
|
||||
struct nexthdr{
|
||||
ulong nmagic;
|
||||
ulong ncputype;
|
||||
ulong ncpusubtype;
|
||||
ulong nfiletype;
|
||||
ulong ncmds;
|
||||
ulong nsizeofcmds;
|
||||
ulong nflags;
|
||||
};
|
||||
|
||||
struct nextcmd{
|
||||
ulong cmd;
|
||||
ulong cmdsize;
|
||||
uchar segname[16];
|
||||
ulong vmaddr;
|
||||
ulong vmsize;
|
||||
ulong fileoff;
|
||||
ulong filesize;
|
||||
ulong maxprot;
|
||||
ulong initprot;
|
||||
ulong nsects;
|
||||
ulong flags;
|
||||
}textc;
|
||||
struct nextsect{
|
||||
char sectname[16];
|
||||
char segname[16];
|
||||
ulong addr;
|
||||
ulong size;
|
||||
ulong offset;
|
||||
ulong align;
|
||||
ulong reloff;
|
||||
ulong nreloc;
|
||||
ulong flags;
|
||||
ulong reserved1;
|
||||
ulong reserved2;
|
||||
}texts;
|
||||
struct nextcmd datac;
|
||||
struct nextsect datas;
|
||||
struct nextsect bsss;
|
||||
struct nextsym{
|
||||
ulong cmd;
|
||||
ulong cmdsize;
|
||||
ulong symoff;
|
||||
ulong nsyms;
|
||||
ulong spoff;
|
||||
ulong pcoff;
|
||||
}symc;
|
||||
*/
|
||||
};
|
||||
|
||||
struct i386exec
|
||||
{
|
||||
/* UNUSED
|
||||
struct i386coff{
|
||||
ulong isectmagic;
|
||||
ulong itime;
|
||||
ulong isyms;
|
||||
ulong insyms;
|
||||
ulong iflags;
|
||||
};
|
||||
struct i386hdr{
|
||||
ulong imagic;
|
||||
ulong itextsize;
|
||||
ulong idatasize;
|
||||
ulong ibsssize;
|
||||
ulong ientry;
|
||||
ulong itextstart;
|
||||
ulong idatastart;
|
||||
};
|
||||
struct coffsect itexts;
|
||||
struct coffsect idatas;
|
||||
struct coffsect ibsss;
|
||||
struct coffsect icomments;
|
||||
*/
|
||||
};
|
403
include/mach_amd64.h
Normal file
403
include/mach_amd64.h
Normal file
@ -0,0 +1,403 @@
|
||||
// Inferno libmach/a.out.h and libmach/mach.h
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/a.out.h
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/mach.h
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
/*
|
||||
* Architecture-dependent application data
|
||||
* This is just Plan 9's mach.h, tweaked to support only amd64 for now.
|
||||
*/
|
||||
/*
|
||||
* Start of Plan 9 a.out.h
|
||||
* Don't use system a.out; instead just lay in the Plan 9 one for now.
|
||||
*/
|
||||
/*
|
||||
#include "a.out.h"
|
||||
*/
|
||||
|
||||
typedef struct Exec Exec;
|
||||
struct Exec
|
||||
{
|
||||
long magic; /* magic number */
|
||||
long text; /* size of text segment */
|
||||
long data; /* size of initialized data */
|
||||
long bss; /* size of uninitialized data */
|
||||
long syms; /* size of symbol table */
|
||||
long entry; /* entry point */
|
||||
long spsz; /* size of pc/sp offset table */
|
||||
long pcsz; /* size of pc/line number table */
|
||||
};
|
||||
|
||||
#define HDR_MAGIC 0x00008000 /* header expansion */
|
||||
|
||||
#define _MAGIC(f, b) ((f)|((((4*(b))+0)*(b))+7))
|
||||
#define A_MAGIC _MAGIC(0, 8) /* 68020 */
|
||||
#define I_MAGIC _MAGIC(0, 11) /* intel 386 */
|
||||
#define J_MAGIC _MAGIC(0, 12) /* intel 960 (retired) */
|
||||
#define K_MAGIC _MAGIC(0, 13) /* sparc */
|
||||
#define V_MAGIC _MAGIC(0, 16) /* mips 3000 BE */
|
||||
#define X_MAGIC _MAGIC(0, 17) /* att dsp 3210 (retired) */
|
||||
#define M_MAGIC _MAGIC(0, 18) /* mips 4000 BE */
|
||||
#define D_MAGIC _MAGIC(0, 19) /* amd 29000 (retired) */
|
||||
#define E_MAGIC _MAGIC(0, 20) /* arm */
|
||||
#define Q_MAGIC _MAGIC(0, 21) /* powerpc */
|
||||
#define N_MAGIC _MAGIC(0, 22) /* mips 4000 LE */
|
||||
#define L_MAGIC _MAGIC(0, 23) /* dec alpha */
|
||||
#define P_MAGIC _MAGIC(0, 24) /* mips 3000 LE */
|
||||
#define U_MAGIC _MAGIC(0, 25) /* sparc64 */
|
||||
#define S_MAGIC _MAGIC(HDR_MAGIC, 26) /* amd64 */
|
||||
#define T_MAGIC _MAGIC(HDR_MAGIC, 27) /* powerpc64 */
|
||||
|
||||
#define MIN_MAGIC 8
|
||||
#define MAX_MAGIC 27 /* <= 90 */
|
||||
|
||||
#define DYN_MAGIC 0x80000000 /* dlm */
|
||||
|
||||
typedef struct Sym Sym;
|
||||
struct Sym
|
||||
{
|
||||
vlong value;
|
||||
uint sig;
|
||||
char type;
|
||||
char *name;
|
||||
};
|
||||
/*
|
||||
* End of Plan 9 a.out.h
|
||||
* Don't use system a.out; instead just lay in the Plan 9 one for now.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Supported architectures:
|
||||
* mips,
|
||||
* 68020,
|
||||
* i386,
|
||||
* amd64,
|
||||
* sparc,
|
||||
* sparc64,
|
||||
* mips2 (R4000)
|
||||
* arm
|
||||
* powerpc,
|
||||
* powerpc64
|
||||
* alpha
|
||||
*/
|
||||
enum
|
||||
{
|
||||
MMIPS, /* machine types */
|
||||
MSPARC,
|
||||
M68020,
|
||||
MI386,
|
||||
MI960, /* retired */
|
||||
M3210, /* retired */
|
||||
MMIPS2,
|
||||
NMIPS2,
|
||||
M29000, /* retired */
|
||||
MARM,
|
||||
MPOWER,
|
||||
MALPHA,
|
||||
NMIPS,
|
||||
MSPARC64,
|
||||
MAMD64,
|
||||
MPOWER64,
|
||||
/* types of executables */
|
||||
FNONE = 0, /* unidentified */
|
||||
FMIPS, /* v.out */
|
||||
FMIPSB, /* mips bootable */
|
||||
FSPARC, /* k.out */
|
||||
FSPARCB, /* Sparc bootable */
|
||||
F68020, /* 2.out */
|
||||
F68020B, /* 68020 bootable */
|
||||
FNEXTB, /* Next bootable */
|
||||
FI386, /* 8.out */
|
||||
FI386B, /* I386 bootable */
|
||||
FI960, /* retired */
|
||||
FI960B, /* retired */
|
||||
F3210, /* retired */
|
||||
FMIPS2BE, /* 4.out */
|
||||
F29000, /* retired */
|
||||
FARM, /* 5.out */
|
||||
FARMB, /* ARM bootable */
|
||||
FPOWER, /* q.out */
|
||||
FPOWERB, /* power pc bootable */
|
||||
FMIPS2LE, /* 0.out */
|
||||
FALPHA, /* 7.out */
|
||||
FALPHAB, /* DEC Alpha bootable */
|
||||
FMIPSLE, /* 3k little endian */
|
||||
FSPARC64, /* u.out */
|
||||
FAMD64, /* 6.out */
|
||||
FAMD64B, /* 6.out bootable */
|
||||
FPOWER64, /* 9.out */
|
||||
FPOWER64B, /* 9.out bootable */
|
||||
|
||||
ANONE = 0, /* dissembler types */
|
||||
AMIPS,
|
||||
AMIPSCO, /* native mips */
|
||||
ASPARC,
|
||||
ASUNSPARC, /* native sun */
|
||||
A68020,
|
||||
AI386,
|
||||
AI8086, /* oh god */
|
||||
AI960, /* retired */
|
||||
A29000, /* retired */
|
||||
AARM,
|
||||
APOWER,
|
||||
AALPHA,
|
||||
ASPARC64,
|
||||
AAMD64,
|
||||
APOWER64,
|
||||
/* object file types */
|
||||
Obj68020 = 0, /* .2 */
|
||||
ObjSparc, /* .k */
|
||||
ObjMips, /* .v */
|
||||
Obj386, /* .8 */
|
||||
Obj960, /* retired */
|
||||
Obj3210, /* retired */
|
||||
ObjMips2, /* .4 */
|
||||
Obj29000, /* retired */
|
||||
ObjArm, /* .5 */
|
||||
ObjPower, /* .q */
|
||||
ObjMips2le, /* .0 */
|
||||
ObjAlpha, /* .7 */
|
||||
ObjSparc64, /* .u */
|
||||
ObjAmd64, /* .6 */
|
||||
ObjSpim, /* .0 */
|
||||
ObjPower64, /* .9 */
|
||||
Maxobjtype,
|
||||
|
||||
CNONE = 0, /* symbol table classes */
|
||||
CAUTO,
|
||||
CPARAM,
|
||||
CSTAB,
|
||||
CTEXT,
|
||||
CDATA,
|
||||
CANY, /* to look for any class */
|
||||
};
|
||||
|
||||
typedef struct Map Map;
|
||||
typedef struct Symbol Symbol;
|
||||
typedef struct Reglist Reglist;
|
||||
typedef struct Mach Mach;
|
||||
typedef struct Machdata Machdata;
|
||||
|
||||
/*
|
||||
* Structure to map a segment to a position in a file
|
||||
*/
|
||||
struct Map {
|
||||
int nsegs; /* number of segments */
|
||||
struct segment { /* per-segment map */
|
||||
char *name; /* the segment name */
|
||||
int fd; /* file descriptor */
|
||||
int inuse; /* in use - not in use */
|
||||
int cache; /* should cache reads? */
|
||||
uvlong b; /* base */
|
||||
uvlong e; /* end */
|
||||
vlong f; /* offset within file */
|
||||
} seg[1]; /* actually n of these */
|
||||
};
|
||||
|
||||
/*
|
||||
* Internal structure describing a symbol table entry
|
||||
*/
|
||||
struct Symbol {
|
||||
void *handle; /* used internally - owning func */
|
||||
struct {
|
||||
char *name;
|
||||
vlong value; /* address or stack offset */
|
||||
char type; /* as in a.out.h */
|
||||
char class; /* as above */
|
||||
int index; /* in findlocal, globalsym, textsym */
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* machine register description
|
||||
*/
|
||||
struct Reglist {
|
||||
char *rname; /* register name */
|
||||
short roffs; /* offset in u-block */
|
||||
char rflags; /* INTEGER/FLOAT, WRITABLE */
|
||||
char rformat; /* print format: 'x', 'X', 'f', '8', '3', 'Y', 'W' */
|
||||
};
|
||||
|
||||
enum { /* bits in rflags field */
|
||||
RINT = (0<<0),
|
||||
RFLT = (1<<0),
|
||||
RRDONLY = (1<<1),
|
||||
};
|
||||
|
||||
/*
|
||||
* Machine-dependent data is stored in two structures:
|
||||
* Mach - miscellaneous general parameters
|
||||
* Machdata - jump vector of service functions used by debuggers
|
||||
*
|
||||
* Mach is defined in ?.c and set in executable.c
|
||||
*
|
||||
* Machdata is defined in ?db.c
|
||||
* and set in the debugger startup.
|
||||
*/
|
||||
struct Mach{
|
||||
char *name;
|
||||
int mtype; /* machine type code */
|
||||
Reglist *reglist; /* register set */
|
||||
long regsize; /* sizeof registers in bytes */
|
||||
long fpregsize; /* sizeof fp registers in bytes */
|
||||
char *pc; /* pc name */
|
||||
char *sp; /* sp name */
|
||||
char *link; /* link register name */
|
||||
char *sbreg; /* static base register name */
|
||||
uvlong sb; /* static base register value */
|
||||
int pgsize; /* page size */
|
||||
uvlong kbase; /* kernel base address */
|
||||
uvlong ktmask; /* ktzero = kbase & ~ktmask */
|
||||
uvlong utop; /* user stack top */
|
||||
int pcquant; /* quantization of pc */
|
||||
int szaddr; /* sizeof(void*) */
|
||||
int szreg; /* sizeof(register) */
|
||||
int szfloat; /* sizeof(float) */
|
||||
int szdouble; /* sizeof(double) */
|
||||
};
|
||||
|
||||
extern Mach *mach; /* Current machine */
|
||||
|
||||
typedef uvlong (*Rgetter)(Map*, char*);
|
||||
typedef void (*Tracer)(Map*, uvlong, uvlong, Symbol*);
|
||||
|
||||
struct Machdata { /* Machine-dependent debugger support */
|
||||
uchar bpinst[4]; /* break point instr. */
|
||||
short bpsize; /* size of break point instr. */
|
||||
|
||||
ushort (*swab)(ushort); /* ushort to local byte order */
|
||||
ulong (*swal)(ulong); /* ulong to local byte order */
|
||||
uvlong (*swav)(uvlong); /* uvlong to local byte order */
|
||||
int (*ctrace)(Map*, uvlong, uvlong, uvlong, Tracer); /* C traceback */
|
||||
uvlong (*findframe)(Map*, uvlong, uvlong, uvlong, uvlong);/* frame finder */
|
||||
char* (*excep)(Map*, Rgetter); /* last exception */
|
||||
ulong (*bpfix)(uvlong); /* breakpoint fixup */
|
||||
int (*sftos)(char*, int, void*); /* single precision float */
|
||||
int (*dftos)(char*, int, void*); /* double precision float */
|
||||
int (*foll)(Map*, uvlong, Rgetter, uvlong*);/* follow set */
|
||||
int (*das)(Map*, uvlong, char, char*, int); /* symbolic disassembly */
|
||||
int (*hexinst)(Map*, uvlong, char*, int); /* hex disassembly */
|
||||
int (*instsize)(Map*, uvlong); /* instruction size */
|
||||
};
|
||||
|
||||
/*
|
||||
* Common a.out header describing all architectures
|
||||
*/
|
||||
typedef struct Fhdr
|
||||
{
|
||||
char *name; /* identifier of executable */
|
||||
uchar type; /* file type - see codes above */
|
||||
uchar hdrsz; /* header size */
|
||||
uchar _magic; /* _MAGIC() magic */
|
||||
uchar spare;
|
||||
long magic; /* magic number */
|
||||
uvlong txtaddr; /* text address */
|
||||
vlong txtoff; /* start of text in file */
|
||||
uvlong dataddr; /* start of data segment */
|
||||
vlong datoff; /* offset to data seg in file */
|
||||
vlong symoff; /* offset of symbol table in file */
|
||||
uvlong entry; /* entry point */
|
||||
vlong sppcoff; /* offset of sp-pc table in file */
|
||||
vlong lnpcoff; /* offset of line number-pc table in file */
|
||||
long txtsz; /* text size */
|
||||
long datsz; /* size of data seg */
|
||||
long bsssz; /* size of bss */
|
||||
long symsz; /* size of symbol table */
|
||||
long sppcsz; /* size of sp-pc table */
|
||||
long lnpcsz; /* size of line number-pc table */
|
||||
} Fhdr;
|
||||
|
||||
extern int asstype; /* dissembler type - machdata.c */
|
||||
extern Machdata *machdata; /* jump vector - machdata.c */
|
||||
|
||||
Map* attachproc(int, int, int, Fhdr*);
|
||||
int beieee80ftos(char*, int, void*);
|
||||
int beieeesftos(char*, int, void*);
|
||||
int beieeedftos(char*, int, void*);
|
||||
ushort beswab(ushort);
|
||||
ulong beswal(ulong);
|
||||
uvlong beswav(uvlong);
|
||||
uvlong ciscframe(Map*, uvlong, uvlong, uvlong, uvlong);
|
||||
int cisctrace(Map*, uvlong, uvlong, uvlong, Tracer);
|
||||
int crackhdr(int fd, Fhdr*);
|
||||
uvlong file2pc(char*, long);
|
||||
int fileelem(Sym**, uchar *, char*, int);
|
||||
long fileline(char*, int, uvlong);
|
||||
int filesym(int, char*, int);
|
||||
int findlocal(Symbol*, char*, Symbol*);
|
||||
int findseg(Map*, char*);
|
||||
int findsym(uvlong, int, Symbol *);
|
||||
int fnbound(uvlong, uvlong*);
|
||||
int fpformat(Map*, Reglist*, char*, int, int);
|
||||
int get1(Map*, uvlong, uchar*, int);
|
||||
int get2(Map*, uvlong, ushort*);
|
||||
int get4(Map*, uvlong, ulong*);
|
||||
int get8(Map*, uvlong, uvlong*);
|
||||
int geta(Map*, uvlong, uvlong*);
|
||||
int getauto(Symbol*, int, int, Symbol*);
|
||||
Sym* getsym(int);
|
||||
int globalsym(Symbol *, int);
|
||||
char* _hexify(char*, ulong, int);
|
||||
int ieeesftos(char*, int, ulong);
|
||||
int ieeedftos(char*, int, ulong, ulong);
|
||||
int isar(Biobuf*);
|
||||
int leieee80ftos(char*, int, void*);
|
||||
int leieeesftos(char*, int, void*);
|
||||
int leieeedftos(char*, int, void*);
|
||||
ushort leswab(ushort);
|
||||
ulong leswal(ulong);
|
||||
uvlong leswav(uvlong);
|
||||
uvlong line2addr(long, uvlong, uvlong);
|
||||
Map* loadmap(Map*, int, Fhdr*);
|
||||
int localaddr(Map*, char*, char*, uvlong*, Rgetter);
|
||||
int localsym(Symbol*, int);
|
||||
int lookup(char*, char*, Symbol*);
|
||||
void machbytype(int);
|
||||
int machbyname(char*);
|
||||
int nextar(Biobuf*, int, char*);
|
||||
Map* newmap(Map*, int);
|
||||
void objtraverse(void(*)(Sym*, void*), void*);
|
||||
int objtype(Biobuf*, char**);
|
||||
uvlong pc2sp(uvlong);
|
||||
long pc2line(uvlong);
|
||||
int put1(Map*, uvlong, uchar*, int);
|
||||
int put2(Map*, uvlong, ushort);
|
||||
int put4(Map*, uvlong, ulong);
|
||||
int put8(Map*, uvlong, uvlong);
|
||||
int puta(Map*, uvlong, uvlong);
|
||||
int readar(Biobuf*, int, vlong, int);
|
||||
int readobj(Biobuf*, int);
|
||||
uvlong riscframe(Map*, uvlong, uvlong, uvlong, uvlong);
|
||||
int risctrace(Map*, uvlong, uvlong, uvlong, Tracer);
|
||||
int setmap(Map*, int, uvlong, uvlong, vlong, char*);
|
||||
Sym* symbase(long*);
|
||||
int syminit(int, Fhdr*);
|
||||
int symoff(char*, int, uvlong, int);
|
||||
void textseg(uvlong, Fhdr*);
|
||||
int textsym(Symbol*, int);
|
||||
void unusemap(Map*, int);
|
58
include/ureg_amd64.h
Normal file
58
include/ureg_amd64.h
Normal file
@ -0,0 +1,58 @@
|
||||
// Inferno utils/libmach/ureg6.h
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/ureg6.h
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
struct Ureg {
|
||||
u64int ax;
|
||||
u64int bx;
|
||||
u64int cx;
|
||||
u64int dx;
|
||||
u64int si;
|
||||
u64int di;
|
||||
u64int bp;
|
||||
u64int r8;
|
||||
u64int r9;
|
||||
u64int r10;
|
||||
u64int r11;
|
||||
u64int r12;
|
||||
u64int r13;
|
||||
u64int r14;
|
||||
u64int r15;
|
||||
|
||||
u16int ds;
|
||||
u16int es;
|
||||
u16int fs;
|
||||
u16int gs;
|
||||
|
||||
u64int type;
|
||||
u64int error; /* error code (or zero) */
|
||||
u64int ip; /* pc */
|
||||
u64int cs; /* old context */
|
||||
u64int flags; /* old flags */
|
||||
u64int sp; /* sp */
|
||||
u64int ss; /* old stack segment */
|
||||
};
|
53
include/ureg_x86.h
Normal file
53
include/ureg_x86.h
Normal file
@ -0,0 +1,53 @@
|
||||
// Inferno utils/libmach/ureg8.h
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/ureg8.h
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
struct Ureg
|
||||
{
|
||||
ulong di; /* general registers */
|
||||
ulong si; /* ... */
|
||||
ulong bp; /* ... */
|
||||
ulong nsp;
|
||||
ulong bx; /* ... */
|
||||
ulong dx; /* ... */
|
||||
ulong cx; /* ... */
|
||||
ulong ax; /* ... */
|
||||
ulong gs; /* data segments */
|
||||
ulong fs; /* ... */
|
||||
ulong es; /* ... */
|
||||
ulong ds; /* ... */
|
||||
ulong trap; /* trap type */
|
||||
ulong ecode; /* error code (or zero) */
|
||||
ulong pc; /* pc */
|
||||
ulong cs; /* old context */
|
||||
ulong flags; /* old flags */
|
||||
union {
|
||||
ulong usp;
|
||||
ulong sp;
|
||||
};
|
||||
ulong ss; /* old stack segment */
|
||||
};
|
@ -40,3 +40,8 @@ echo; echo; echo %%%% making 6g %%%%; echo
|
||||
cd 6g
|
||||
make install
|
||||
cd ..
|
||||
|
||||
echo; echo; echo %%%% making db %%%%; echo
|
||||
cd db
|
||||
make install
|
||||
cd ..
|
||||
|
145
src/libmachamd64/6.c
Normal file
145
src/libmachamd64/6.c
Normal file
@ -0,0 +1,145 @@
|
||||
// Inferno libmach/6.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/6.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
/*
|
||||
* amd64 definition
|
||||
*/
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include "ureg_amd64.h"
|
||||
#include <mach_amd64.h>
|
||||
|
||||
#define REGOFF(x) offsetof(struct Ureg, x)
|
||||
|
||||
#define REGSIZE sizeof(struct Ureg)
|
||||
#define FP_CTLS(x) (REGSIZE+2*(x))
|
||||
#define FP_CTL(x) (REGSIZE+4*(x))
|
||||
#define FP_REG(x) (FP_CTL(8)+16*(x))
|
||||
#define XM_REG(x) (FP_CTL(8)+8*16+16*(x))
|
||||
|
||||
#define FPREGSIZE 512 /* TO DO? currently only 0x1A0 used */
|
||||
|
||||
Reglist amd64reglist[] = {
|
||||
{"AX", REGOFF(ax), RINT, 'Y'},
|
||||
{"BX", REGOFF(bx), RINT, 'Y'},
|
||||
{"CX", REGOFF(cx), RINT, 'Y'},
|
||||
{"DX", REGOFF(dx), RINT, 'Y'},
|
||||
{"SI", REGOFF(si), RINT, 'Y'},
|
||||
{"DI", REGOFF(di), RINT, 'Y'},
|
||||
{"BP", REGOFF(bp), RINT, 'Y'},
|
||||
{"R8", REGOFF(r8), RINT, 'Y'},
|
||||
{"R9", REGOFF(r9), RINT, 'Y'},
|
||||
{"R10", REGOFF(r10), RINT, 'Y'},
|
||||
{"R11", REGOFF(r11), RINT, 'Y'},
|
||||
{"R12", REGOFF(r12), RINT, 'Y'},
|
||||
{"R13", REGOFF(r13), RINT, 'Y'},
|
||||
{"R14", REGOFF(r14), RINT, 'Y'},
|
||||
{"R15", REGOFF(r15), RINT, 'Y'},
|
||||
{"DS", REGOFF(ds), RINT, 'x'},
|
||||
{"ES", REGOFF(es), RINT, 'x'},
|
||||
{"FS", REGOFF(fs), RINT, 'x'},
|
||||
{"GS", REGOFF(gs), RINT, 'x'},
|
||||
{"TYPE", REGOFF(type), RINT, 'Y'},
|
||||
{"TRAP", REGOFF(type), RINT, 'Y'}, /* alias for acid */
|
||||
{"ERROR", REGOFF(error), RINT, 'Y'},
|
||||
{"IP", REGOFF(ip), RINT, 'Y'},
|
||||
{"PC", REGOFF(ip), RINT, 'Y'}, /* alias for acid */
|
||||
{"CS", REGOFF(cs), RINT, 'Y'},
|
||||
{"FLAGS", REGOFF(flags), RINT, 'Y'},
|
||||
{"SP", REGOFF(sp), RINT, 'Y'},
|
||||
{"SS", REGOFF(ss), RINT, 'Y'},
|
||||
|
||||
{"FCW", FP_CTLS(0), RFLT, 'x'},
|
||||
{"FSW", FP_CTLS(1), RFLT, 'x'},
|
||||
{"FTW", FP_CTLS(2), RFLT, 'b'},
|
||||
{"FOP", FP_CTLS(3), RFLT, 'x'},
|
||||
{"RIP", FP_CTL(2), RFLT, 'Y'},
|
||||
{"RDP", FP_CTL(4), RFLT, 'Y'},
|
||||
{"MXCSR", FP_CTL(6), RFLT, 'X'},
|
||||
{"MXCSRMASK", FP_CTL(7), RFLT, 'X'},
|
||||
{"M0", FP_REG(0), RFLT, 'F'}, /* assumes double */
|
||||
{"M1", FP_REG(1), RFLT, 'F'},
|
||||
{"M2", FP_REG(2), RFLT, 'F'},
|
||||
{"M3", FP_REG(3), RFLT, 'F'},
|
||||
{"M4", FP_REG(4), RFLT, 'F'},
|
||||
{"M5", FP_REG(5), RFLT, 'F'},
|
||||
{"M6", FP_REG(6), RFLT, 'F'},
|
||||
{"M7", FP_REG(7), RFLT, 'F'},
|
||||
{"X0", XM_REG(0), RFLT, 'F'}, /* assumes double */
|
||||
{"X1", XM_REG(1), RFLT, 'F'},
|
||||
{"X2", XM_REG(2), RFLT, 'F'},
|
||||
{"X3", XM_REG(3), RFLT, 'F'},
|
||||
{"X4", XM_REG(4), RFLT, 'F'},
|
||||
{"X5", XM_REG(5), RFLT, 'F'},
|
||||
{"X6", XM_REG(6), RFLT, 'F'},
|
||||
{"X7", XM_REG(7), RFLT, 'F'},
|
||||
{"X8", XM_REG(8), RFLT, 'F'},
|
||||
{"X9", XM_REG(9), RFLT, 'F'},
|
||||
{"X10", XM_REG(10), RFLT, 'F'},
|
||||
{"X11", XM_REG(11), RFLT, 'F'},
|
||||
{"X12", XM_REG(12), RFLT, 'F'},
|
||||
{"X13", XM_REG(13), RFLT, 'F'},
|
||||
{"X14", XM_REG(14), RFLT, 'F'},
|
||||
{"X15", XM_REG(15), RFLT, 'F'},
|
||||
{"X16", XM_REG(16), RFLT, 'F'},
|
||||
/*
|
||||
{"F0", FP_REG(7), RFLT, '3'},
|
||||
{"F1", FP_REG(6), RFLT, '3'},
|
||||
{"F2", FP_REG(5), RFLT, '3'},
|
||||
{"F3", FP_REG(4), RFLT, '3'},
|
||||
{"F4", FP_REG(3), RFLT, '3'},
|
||||
{"F5", FP_REG(2), RFLT, '3'},
|
||||
{"F6", FP_REG(1), RFLT, '3'},
|
||||
{"F7", FP_REG(0), RFLT, '3'},
|
||||
*/
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
Mach mamd64=
|
||||
{
|
||||
"amd64",
|
||||
MAMD64, /* machine type */
|
||||
amd64reglist, /* register list */
|
||||
REGSIZE, /* size of registers in bytes */
|
||||
FPREGSIZE, /* size of fp registers in bytes */
|
||||
"PC", /* name of PC */
|
||||
"SP", /* name of SP */
|
||||
0, /* link register */
|
||||
"setSB", /* static base register name (bogus anyways) */
|
||||
0, /* static base register value */
|
||||
0x1000, /* page size */
|
||||
0xFFFFFFFF80110000ULL, /* kernel base */
|
||||
0xFFFF800000000000ULL, /* kernel text mask */
|
||||
0x00007FFFFFFFF000ULL, /* user stack top */
|
||||
1, /* quantization of pc */
|
||||
8, /* szaddr */
|
||||
4, /* szreg */
|
||||
4, /* szfloat */
|
||||
8, /* szdouble */
|
||||
};
|
175
src/libmachamd64/6obj.c
Normal file
175
src/libmachamd64/6obj.c
Normal file
@ -0,0 +1,175 @@
|
||||
// Inferno libmach/6obj.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/6obj.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
/*
|
||||
* 6obj.c - identify and parse an amd64 object file
|
||||
*/
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <mach_amd64.h>
|
||||
#include "../cmd/6l/6.out.h"
|
||||
#include "obj.h"
|
||||
|
||||
typedef struct Addr Addr;
|
||||
struct Addr
|
||||
{
|
||||
char sym;
|
||||
char flags;
|
||||
};
|
||||
static Addr addr(Biobuf*);
|
||||
static char type2char(int);
|
||||
static void skip(Biobuf*, int);
|
||||
|
||||
int
|
||||
_is6(char *t)
|
||||
{
|
||||
uchar *s = (uchar*)t;
|
||||
|
||||
return s[0] == (ANAME&0xff) /* aslo = ANAME */
|
||||
&& s[1] == ((ANAME>>8)&0xff)
|
||||
&& s[2] == D_FILE /* type */
|
||||
&& s[3] == 1 /* sym */
|
||||
&& s[4] == '<'; /* name of file */
|
||||
}
|
||||
|
||||
int
|
||||
_read6(Biobuf *bp, Prog* p)
|
||||
{
|
||||
int as, n, c;
|
||||
Addr a;
|
||||
|
||||
as = Bgetc(bp); /* as(low) */
|
||||
if(as < 0)
|
||||
return 0;
|
||||
c = Bgetc(bp); /* as(high) */
|
||||
if(c < 0)
|
||||
return 0;
|
||||
as |= ((c & 0xff) << 8);
|
||||
p->kind = aNone;
|
||||
p->sig = 0;
|
||||
if(as == ANAME || as == ASIGNAME){
|
||||
if(as == ASIGNAME){
|
||||
Bread(bp, &p->sig, 4);
|
||||
p->sig = leswal(p->sig);
|
||||
}
|
||||
p->kind = aName;
|
||||
p->type = type2char(Bgetc(bp)); /* type */
|
||||
p->sym = Bgetc(bp); /* sym */
|
||||
n = 0;
|
||||
for(;;) {
|
||||
as = Bgetc(bp);
|
||||
if(as < 0)
|
||||
return 0;
|
||||
n++;
|
||||
if(as == 0)
|
||||
break;
|
||||
}
|
||||
p->id = malloc(n);
|
||||
if(p->id == 0)
|
||||
return 0;
|
||||
Bseek(bp, -n, 1);
|
||||
if(Bread(bp, p->id, n) != n)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
if(as == ATEXT)
|
||||
p->kind = aText;
|
||||
if(as == AGLOBL)
|
||||
p->kind = aData;
|
||||
skip(bp, 4); /* lineno(4) */
|
||||
a = addr(bp);
|
||||
addr(bp);
|
||||
if(!(a.flags & T_SYM))
|
||||
p->kind = aNone;
|
||||
p->sym = a.sym;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static Addr
|
||||
addr(Biobuf *bp)
|
||||
{
|
||||
Addr a;
|
||||
int t;
|
||||
long l;
|
||||
vlong off;
|
||||
|
||||
off = 0;
|
||||
a.sym = -1;
|
||||
a.flags = Bgetc(bp); /* flags */
|
||||
if(a.flags & T_INDEX)
|
||||
skip(bp, 2);
|
||||
if(a.flags & T_OFFSET){
|
||||
l = Bgetc(bp);
|
||||
l |= Bgetc(bp) << 8;
|
||||
l |= Bgetc(bp) << 16;
|
||||
l |= Bgetc(bp) << 24;
|
||||
off = l;
|
||||
if(a.flags & T_64){
|
||||
l = Bgetc(bp);
|
||||
l |= Bgetc(bp) << 8;
|
||||
l |= Bgetc(bp) << 16;
|
||||
l |= Bgetc(bp) << 24;
|
||||
off = ((vlong)l << 32) | (off & 0xFFFFFFFF);
|
||||
}
|
||||
if(off < 0)
|
||||
off = -off;
|
||||
}
|
||||
if(a.flags & T_SYM)
|
||||
a.sym = Bgetc(bp);
|
||||
if(a.flags & T_FCONST)
|
||||
skip(bp, 8);
|
||||
else
|
||||
if(a.flags & T_SCONST)
|
||||
skip(bp, NSNAME);
|
||||
if(a.flags & T_TYPE) {
|
||||
t = Bgetc(bp);
|
||||
if(a.sym > 0 && (t==D_PARAM || t==D_AUTO))
|
||||
_offset(a.sym, off);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
static char
|
||||
type2char(int t)
|
||||
{
|
||||
switch(t){
|
||||
case D_EXTERN: return 'U';
|
||||
case D_STATIC: return 'b';
|
||||
case D_AUTO: return 'a';
|
||||
case D_PARAM: return 'p';
|
||||
default: return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
skip(Biobuf *bp, int n)
|
||||
{
|
||||
while (n-- > 0)
|
||||
Bgetc(bp);
|
||||
}
|
107
src/libmachamd64/8.c
Normal file
107
src/libmachamd64/8.c
Normal file
@ -0,0 +1,107 @@
|
||||
// Inferno libmach/8.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/8.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
/*
|
||||
* 386 definition
|
||||
*/
|
||||
#include <u.h>
|
||||
#include <bio.h>
|
||||
#include <ureg_x86.h>
|
||||
#include <mach_amd64.h>
|
||||
|
||||
#define REGOFF(x) (ulong)(&((struct Ureg *) 0)->x)
|
||||
|
||||
#define PC REGOFF(pc)
|
||||
#define SP REGOFF(sp)
|
||||
#define AX REGOFF(ax)
|
||||
|
||||
#define REGSIZE sizeof(struct Ureg)
|
||||
#define FP_CTL(x) (REGSIZE+4*(x))
|
||||
#define FP_REG(x) (FP_CTL(7)+10*(x))
|
||||
#define FPREGSIZE (7*4+8*10)
|
||||
|
||||
Reglist i386reglist[] = {
|
||||
{"DI", REGOFF(di), RINT, 'X'},
|
||||
{"SI", REGOFF(si), RINT, 'X'},
|
||||
{"BP", REGOFF(bp), RINT, 'X'},
|
||||
{"BX", REGOFF(bx), RINT, 'X'},
|
||||
{"DX", REGOFF(dx), RINT, 'X'},
|
||||
{"CX", REGOFF(cx), RINT, 'X'},
|
||||
{"AX", REGOFF(ax), RINT, 'X'},
|
||||
{"GS", REGOFF(gs), RINT, 'X'},
|
||||
{"FS", REGOFF(fs), RINT, 'X'},
|
||||
{"ES", REGOFF(es), RINT, 'X'},
|
||||
{"DS", REGOFF(ds), RINT, 'X'},
|
||||
{"TRAP", REGOFF(trap), RINT, 'X'},
|
||||
{"ECODE", REGOFF(ecode), RINT, 'X'},
|
||||
{"PC", PC, RINT, 'X'},
|
||||
{"CS", REGOFF(cs), RINT, 'X'},
|
||||
{"EFLAGS", REGOFF(flags), RINT, 'X'},
|
||||
{"SP", SP, RINT, 'X'},
|
||||
{"SS", REGOFF(ss), RINT, 'X'},
|
||||
|
||||
{"E0", FP_CTL(0), RFLT, 'X'},
|
||||
{"E1", FP_CTL(1), RFLT, 'X'},
|
||||
{"E2", FP_CTL(2), RFLT, 'X'},
|
||||
{"E3", FP_CTL(3), RFLT, 'X'},
|
||||
{"E4", FP_CTL(4), RFLT, 'X'},
|
||||
{"E5", FP_CTL(5), RFLT, 'X'},
|
||||
{"E6", FP_CTL(6), RFLT, 'X'},
|
||||
{"F0", FP_REG(0), RFLT, '3'},
|
||||
{"F1", FP_REG(1), RFLT, '3'},
|
||||
{"F2", FP_REG(2), RFLT, '3'},
|
||||
{"F3", FP_REG(3), RFLT, '3'},
|
||||
{"F4", FP_REG(4), RFLT, '3'},
|
||||
{"F5", FP_REG(5), RFLT, '3'},
|
||||
{"F6", FP_REG(6), RFLT, '3'},
|
||||
{"F7", FP_REG(7), RFLT, '3'},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
Mach mi386 =
|
||||
{
|
||||
"386",
|
||||
MI386, /* machine type */
|
||||
i386reglist, /* register list */
|
||||
REGSIZE, /* size of registers in bytes */
|
||||
FPREGSIZE, /* size of fp registers in bytes */
|
||||
"PC", /* name of PC */
|
||||
"SP", /* name of SP */
|
||||
0, /* link register */
|
||||
"setSB", /* static base register name (bogus anyways) */
|
||||
0, /* static base register value */
|
||||
0x1000, /* page size */
|
||||
0x80100000ULL, /* kernel base */
|
||||
0xF0000000ULL, /* kernel text mask */
|
||||
0x7FFFFFFFULL, /* user stack top */
|
||||
1, /* quantization of pc */
|
||||
4, /* szaddr */
|
||||
4, /* szreg */
|
||||
4, /* szfloat */
|
||||
8, /* szdouble */
|
||||
};
|
2204
src/libmachamd64/8db.c
Normal file
2204
src/libmachamd64/8db.c
Normal file
File diff suppressed because it is too large
Load Diff
84
src/libmachamd64/Makefile
Normal file
84
src/libmachamd64/Makefile
Normal file
@ -0,0 +1,84 @@
|
||||
# Derived from Inferno libmach/mkfile
|
||||
# http://code.google.com/p/inferno-os/source/browse/utils/libmach/mkfile
|
||||
#
|
||||
# Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
# Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
# Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
# Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
# Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
# Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
CFLAGS=-I$(GOROOT)/include
|
||||
O=o
|
||||
|
||||
LIB=libmach_amd64.a
|
||||
OFILES=\
|
||||
executable.$O\
|
||||
map.$O\
|
||||
obj.$O\
|
||||
swap.$O\
|
||||
sym.$O\
|
||||
access.$O\
|
||||
machdata.$O\
|
||||
setmach.$O\
|
||||
6.$O\
|
||||
8.$O\
|
||||
8db.$O\
|
||||
6obj.$O\
|
||||
# v.$O\
|
||||
# k.$O\
|
||||
# u.$O\
|
||||
# q.$O\
|
||||
# 0.$O\
|
||||
# 2.$O\
|
||||
# 5.$O\
|
||||
# 7.$O\
|
||||
# 9.$O\
|
||||
# vdb.$O\
|
||||
# kdb.$O\
|
||||
# udb.$O\
|
||||
# qdb.$O\
|
||||
# 2db.$O\
|
||||
# 5db.$O\
|
||||
# 7db.$O\
|
||||
# vobj.$O\
|
||||
# kobj.$O\
|
||||
# uobj.$O\
|
||||
# 2obj.$O\
|
||||
# 5obj.$O\
|
||||
# 7obj.$O\
|
||||
# 8obj.$O\
|
||||
# 9obj.$O\
|
||||
# qobj.$O\
|
||||
# vcodas.$O\
|
||||
|
||||
HFILES=$(GOROOT)/include/mach_amd64.h elf.h obj.h
|
||||
|
||||
install: $(LIB)
|
||||
cp $(LIB) $(GOROOT)/lib
|
||||
|
||||
$(LIB): $(OFILES)
|
||||
ar rsc $(LIB) $(OFILES)
|
||||
|
||||
$(OFILES): $(HFILES)
|
||||
|
||||
clean:
|
||||
rm -f $(OFILES) $(LIB)
|
300
src/libmachamd64/access.c
Normal file
300
src/libmachamd64/access.c
Normal file
@ -0,0 +1,300 @@
|
||||
// Inferno libmach/access.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/access.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
/*
|
||||
* functions to read and write an executable or file image
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <mach_amd64.h>
|
||||
|
||||
static int mget(Map*, uvlong, void*, int);
|
||||
static int mput(Map*, uvlong, void*, int);
|
||||
static struct segment* reloc(Map*, uvlong, vlong*);
|
||||
|
||||
/*
|
||||
* routines to get/put various types
|
||||
*/
|
||||
int
|
||||
geta(Map *map, uvlong addr, uvlong *x)
|
||||
{
|
||||
ulong l;
|
||||
uvlong vl;
|
||||
|
||||
if (mach->szaddr == 8){
|
||||
if (get8(map, addr, &vl) < 0)
|
||||
return -1;
|
||||
*x = vl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (get4(map, addr, &l) < 0)
|
||||
return -1;
|
||||
*x = l;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
get8(Map *map, uvlong addr, uvlong *x)
|
||||
{
|
||||
if (!map) {
|
||||
werrstr("get8: invalid map");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (map->nsegs == 1 && map->seg[0].fd < 0) {
|
||||
*x = addr;
|
||||
return 1;
|
||||
}
|
||||
if (mget(map, addr, x, 8) < 0)
|
||||
return -1;
|
||||
*x = machdata->swav(*x);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
get4(Map *map, uvlong addr, ulong *x)
|
||||
{
|
||||
if (!map) {
|
||||
werrstr("get4: invalid map");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (map->nsegs == 1 && map->seg[0].fd < 0) {
|
||||
*x = addr;
|
||||
return 1;
|
||||
}
|
||||
if (mget(map, addr, x, 4) < 0)
|
||||
return -1;
|
||||
*x = machdata->swal(*x);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
get2(Map *map, uvlong addr, ushort *x)
|
||||
{
|
||||
if (!map) {
|
||||
werrstr("get2: invalid map");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (map->nsegs == 1 && map->seg[0].fd < 0) {
|
||||
*x = addr;
|
||||
return 1;
|
||||
}
|
||||
if (mget(map, addr, x, 2) < 0)
|
||||
return -1;
|
||||
*x = machdata->swab(*x);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
get1(Map *map, uvlong addr, uchar *x, int size)
|
||||
{
|
||||
uchar *cp;
|
||||
|
||||
if (!map) {
|
||||
werrstr("get1: invalid map");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (map->nsegs == 1 && map->seg[0].fd < 0) {
|
||||
cp = (uchar*)&addr;
|
||||
while (cp < (uchar*)(&addr+1) && size-- > 0)
|
||||
*x++ = *cp++;
|
||||
while (size-- > 0)
|
||||
*x++ = 0;
|
||||
} else
|
||||
return mget(map, addr, x, size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
puta(Map *map, uvlong addr, uvlong v)
|
||||
{
|
||||
if (mach->szaddr == 8)
|
||||
return put8(map, addr, v);
|
||||
|
||||
return put4(map, addr, v);
|
||||
}
|
||||
|
||||
int
|
||||
put8(Map *map, uvlong addr, uvlong v)
|
||||
{
|
||||
if (!map) {
|
||||
werrstr("put8: invalid map");
|
||||
return -1;
|
||||
}
|
||||
v = machdata->swav(v);
|
||||
return mput(map, addr, &v, 8);
|
||||
}
|
||||
|
||||
int
|
||||
put4(Map *map, uvlong addr, ulong v)
|
||||
{
|
||||
if (!map) {
|
||||
werrstr("put4: invalid map");
|
||||
return -1;
|
||||
}
|
||||
v = machdata->swal(v);
|
||||
return mput(map, addr, &v, 4);
|
||||
}
|
||||
|
||||
int
|
||||
put2(Map *map, uvlong addr, ushort v)
|
||||
{
|
||||
if (!map) {
|
||||
werrstr("put2: invalid map");
|
||||
return -1;
|
||||
}
|
||||
v = machdata->swab(v);
|
||||
return mput(map, addr, &v, 2);
|
||||
}
|
||||
|
||||
int
|
||||
put1(Map *map, uvlong addr, uchar *v, int size)
|
||||
{
|
||||
if (!map) {
|
||||
werrstr("put1: invalid map");
|
||||
return -1;
|
||||
}
|
||||
return mput(map, addr, v, size);
|
||||
}
|
||||
|
||||
static int
|
||||
spread(struct segment *s, void *buf, int n, uvlong off)
|
||||
{
|
||||
uvlong base;
|
||||
|
||||
static struct {
|
||||
struct segment *s;
|
||||
char a[8192];
|
||||
uvlong off;
|
||||
} cache;
|
||||
|
||||
if(s->cache){
|
||||
base = off&~(sizeof cache.a-1);
|
||||
if(cache.s != s || cache.off != base){
|
||||
cache.off = ~0;
|
||||
if(seek(s->fd, base, 0) >= 0
|
||||
&& readn(s->fd, cache.a, sizeof cache.a) == sizeof cache.a){
|
||||
cache.s = s;
|
||||
cache.off = base;
|
||||
}
|
||||
}
|
||||
if(cache.s == s && cache.off == base){
|
||||
off &= sizeof cache.a-1;
|
||||
if(off+n > sizeof cache.a)
|
||||
n = sizeof cache.a - off;
|
||||
memmove(buf, cache.a+off, n);
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
return pread(s->fd, buf, n, off);
|
||||
}
|
||||
|
||||
static int
|
||||
mget(Map *map, uvlong addr, void *buf, int size)
|
||||
{
|
||||
uvlong off;
|
||||
int i, j, k;
|
||||
struct segment *s;
|
||||
|
||||
s = reloc(map, addr, (vlong*)&off);
|
||||
if (!s)
|
||||
return -1;
|
||||
if (s->fd < 0) {
|
||||
werrstr("unreadable map");
|
||||
return -1;
|
||||
}
|
||||
for (i = j = 0; i < 2; i++) { /* in case read crosses page */
|
||||
k = spread(s, buf, size-j, off+j);
|
||||
if (k < 0) {
|
||||
werrstr("can't read address %llux: %r", addr);
|
||||
return -1;
|
||||
}
|
||||
j += k;
|
||||
if (j == size)
|
||||
return j;
|
||||
}
|
||||
werrstr("partial read at address %llux (size %d j %d)", addr, size, j);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
mput(Map *map, uvlong addr, void *buf, int size)
|
||||
{
|
||||
vlong off;
|
||||
int i, j, k;
|
||||
struct segment *s;
|
||||
|
||||
s = reloc(map, addr, &off);
|
||||
if (!s)
|
||||
return -1;
|
||||
if (s->fd < 0) {
|
||||
werrstr("unwritable map");
|
||||
return -1;
|
||||
}
|
||||
|
||||
seek(s->fd, off, 0);
|
||||
for (i = j = 0; i < 2; i++) { /* in case read crosses page */
|
||||
k = write(s->fd, buf, size-j);
|
||||
if (k < 0) {
|
||||
werrstr("can't write address %llux: %r", addr);
|
||||
return -1;
|
||||
}
|
||||
j += k;
|
||||
if (j == size)
|
||||
return j;
|
||||
}
|
||||
werrstr("partial write at address %llux", addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert address to file offset; returns nonzero if ok
|
||||
*/
|
||||
static struct segment*
|
||||
reloc(Map *map, uvlong addr, vlong *offp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < map->nsegs; i++) {
|
||||
if (map->seg[i].inuse)
|
||||
if (map->seg[i].b <= addr && addr < map->seg[i].e) {
|
||||
*offp = addr + map->seg[i].f - map->seg[i].b;
|
||||
return &map->seg[i];
|
||||
}
|
||||
}
|
||||
werrstr("can't translate address %llux", addr);
|
||||
return 0;
|
||||
}
|
182
src/libmachamd64/elf.h
Normal file
182
src/libmachamd64/elf.h
Normal file
@ -0,0 +1,182 @@
|
||||
// Inferno libmach/elf.h
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/elf.h
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
/*
|
||||
* Definitions needed for accessing ELF headers.
|
||||
* 32-bit and 64-bit structs differ.
|
||||
*/
|
||||
typedef struct {
|
||||
uchar ident[16]; /* ident bytes */
|
||||
ushort type; /* file type */
|
||||
ushort machine; /* target machine */
|
||||
int version; /* file version */
|
||||
ulong elfentry; /* start address */
|
||||
ulong phoff; /* phdr file offset */
|
||||
ulong shoff; /* shdr file offset */
|
||||
int flags; /* file flags */
|
||||
ushort ehsize; /* sizeof ehdr */
|
||||
ushort phentsize; /* sizeof phdr */
|
||||
ushort phnum; /* number phdrs */
|
||||
ushort shentsize; /* sizeof shdr */
|
||||
ushort shnum; /* number shdrs */
|
||||
ushort shstrndx; /* shdr string index */
|
||||
} Ehdr32;
|
||||
|
||||
typedef struct {
|
||||
uchar ident[16]; /* ident bytes */
|
||||
ushort type; /* file type */
|
||||
ushort machine; /* target machine */
|
||||
int version; /* file version */
|
||||
uvlong elfentry; /* start address */
|
||||
uvlong phoff; /* phdr file offset */
|
||||
uvlong shoff; /* shdr file offset */
|
||||
int flags; /* file flags */
|
||||
ushort ehsize; /* sizeof ehdr */
|
||||
ushort phentsize; /* sizeof phdr */
|
||||
ushort phnum; /* number phdrs */
|
||||
ushort shentsize; /* sizeof shdr */
|
||||
ushort shnum; /* number shdrs */
|
||||
ushort shstrndx; /* shdr string index */
|
||||
} Ehdr64;
|
||||
|
||||
typedef struct {
|
||||
int type; /* entry type */
|
||||
ulong offset; /* file offset */
|
||||
ulong vaddr; /* virtual address */
|
||||
ulong paddr; /* physical address */
|
||||
int filesz; /* file size */
|
||||
ulong memsz; /* memory size */
|
||||
int flags; /* entry flags */
|
||||
int align; /* memory/file alignment */
|
||||
} Phdr32;
|
||||
|
||||
typedef struct {
|
||||
int type; /* entry type */
|
||||
int flags; /* entry flags */
|
||||
uvlong offset; /* file offset */
|
||||
uvlong vaddr; /* virtual address */
|
||||
uvlong paddr; /* physical address */
|
||||
uvlong filesz; /* file size */
|
||||
uvlong memsz; /* memory size */
|
||||
uvlong align; /* memory/file alignment */
|
||||
} Phdr64;
|
||||
|
||||
typedef struct {
|
||||
ulong name; /* section name */
|
||||
ulong type; /* SHT_... */
|
||||
ulong flags; /* SHF_... */
|
||||
ulong addr; /* virtual address */
|
||||
ulong offset; /* file offset */
|
||||
ulong size; /* section size */
|
||||
ulong link; /* misc info */
|
||||
ulong info; /* misc info */
|
||||
ulong addralign; /* memory alignment */
|
||||
ulong entsize; /* entry size if table */
|
||||
} Shdr32;
|
||||
|
||||
typedef struct {
|
||||
ulong name; /* section name */
|
||||
ulong type; /* SHT_... */
|
||||
uvlong flags; /* SHF_... */
|
||||
uvlong addr; /* virtual address */
|
||||
uvlong offset; /* file offset */
|
||||
uvlong size; /* section size */
|
||||
ulong link; /* misc info */
|
||||
ulong info; /* misc info */
|
||||
uvlong addralign; /* memory alignment */
|
||||
uvlong entsize; /* entry size if table */
|
||||
} Shdr64;
|
||||
|
||||
enum {
|
||||
/* Ehdr codes */
|
||||
MAG0 = 0, /* ident[] indexes */
|
||||
MAG1 = 1,
|
||||
MAG2 = 2,
|
||||
MAG3 = 3,
|
||||
CLASS = 4,
|
||||
DATA = 5,
|
||||
VERSION = 6,
|
||||
|
||||
ELFCLASSNONE = 0, /* ident[CLASS] */
|
||||
ELFCLASS32 = 1,
|
||||
ELFCLASS64 = 2,
|
||||
ELFCLASSNUM = 3,
|
||||
|
||||
ELFDATANONE = 0, /* ident[DATA] */
|
||||
ELFDATA2LSB = 1,
|
||||
ELFDATA2MSB = 2,
|
||||
ELFDATANUM = 3,
|
||||
|
||||
NOETYPE = 0, /* type */
|
||||
REL = 1,
|
||||
EXEC = 2,
|
||||
DYN = 3,
|
||||
CORE = 4,
|
||||
|
||||
NONE = 0, /* machine */
|
||||
M32 = 1, /* AT&T WE 32100 */
|
||||
SPARC = 2, /* Sun SPARC */
|
||||
I386 = 3, /* Intel 80386 */
|
||||
M68K = 4, /* Motorola 68000 */
|
||||
M88K = 5, /* Motorola 88000 */
|
||||
I486 = 6, /* Intel 80486 */
|
||||
I860 = 7, /* Intel i860 */
|
||||
MIPS = 8, /* Mips R2000 */
|
||||
S370 = 9, /* Amdhal */
|
||||
SPARC64 = 18, /* Sun SPARC v9 */
|
||||
POWER = 20, /* PowerPC */
|
||||
ARM = 40, /* ARM */
|
||||
AMD64 = 62, /* Amd64 */
|
||||
|
||||
NO_VERSION = 0, /* version, ident[VERSION] */
|
||||
CURRENT = 1,
|
||||
|
||||
/* Phdr Codes */
|
||||
NOPTYPE = 0, /* type */
|
||||
LOAD = 1,
|
||||
DYNAMIC = 2,
|
||||
INTERP = 3,
|
||||
NOTE = 4,
|
||||
SHLIB = 5,
|
||||
PHDR = 6,
|
||||
|
||||
R = 0x4, /* flags */
|
||||
W = 0x2,
|
||||
X = 0x1,
|
||||
|
||||
/* Shdr Codes */
|
||||
Progbits = 1, /* section types */
|
||||
Strtab = 3,
|
||||
Nobits = 8,
|
||||
|
||||
Swrite = 1, /* section attributes */
|
||||
Salloc = 2,
|
||||
Sexec = 4,
|
||||
};
|
||||
|
||||
#define ELF_MAG ((0x7f<<24) | ('E'<<16) | ('L'<<8) | 'F')
|
963
src/libmachamd64/executable.c
Normal file
963
src/libmachamd64/executable.c
Normal file
@ -0,0 +1,963 @@
|
||||
// Inferno libmach/executable.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/executable.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <bootexec.h>
|
||||
#include <mach_amd64.h>
|
||||
#include "elf.h"
|
||||
|
||||
/*
|
||||
* All a.out header types. The dummy entry allows canonical
|
||||
* processing of the union as a sequence of longs
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
union{
|
||||
/*struct { */
|
||||
Exec exechdr; /* a.out.h */
|
||||
/* uvlong hdr[1];*/
|
||||
/*};*/
|
||||
Ehdr32 elfhdr32; /* elf.h */
|
||||
Ehdr64 elfhdr64; /* elf.h */
|
||||
struct mipsexec mips; /* bootexec.h */
|
||||
struct mips4kexec mipsk4; /* bootexec.h */
|
||||
struct sparcexec sparc; /* bootexec.h */
|
||||
struct nextexec next; /* bootexec.h */
|
||||
} e;
|
||||
long dummy; /* padding to ensure extra long */
|
||||
} ExecHdr;
|
||||
|
||||
static int nextboot(int, Fhdr*, ExecHdr*);
|
||||
static int sparcboot(int, Fhdr*, ExecHdr*);
|
||||
static int mipsboot(int, Fhdr*, ExecHdr*);
|
||||
static int mips4kboot(int, Fhdr*, ExecHdr*);
|
||||
static int common(int, Fhdr*, ExecHdr*);
|
||||
static int commonllp64(int, Fhdr*, ExecHdr*);
|
||||
static int adotout(int, Fhdr*, ExecHdr*);
|
||||
static int elfdotout(int, Fhdr*, ExecHdr*);
|
||||
static int armdotout(int, Fhdr*, ExecHdr*);
|
||||
static void setsym(Fhdr*, long, long, long, vlong);
|
||||
static void setdata(Fhdr*, uvlong, long, vlong, long);
|
||||
static void settext(Fhdr*, uvlong, uvlong, long, vlong);
|
||||
static void hswal(void*, int, ulong(*)(ulong));
|
||||
static uvlong _round(uvlong, ulong);
|
||||
|
||||
/*
|
||||
* definition of per-executable file type structures
|
||||
*/
|
||||
|
||||
typedef struct Exectable{
|
||||
long magic; /* big-endian magic number of file */
|
||||
char *name; /* executable identifier */
|
||||
char *dlmname; /* dynamically loadable module identifier */
|
||||
uchar type; /* Internal code */
|
||||
uchar _magic; /* _MAGIC() magic */
|
||||
Mach *mach; /* Per-machine data */
|
||||
long hsize; /* header size */
|
||||
ulong (*swal)(ulong); /* beswal or leswal */
|
||||
int (*hparse)(int, Fhdr*, ExecHdr*);
|
||||
} ExecTable;
|
||||
|
||||
extern Mach mmips;
|
||||
extern Mach mmips2le;
|
||||
extern Mach mmips2be;
|
||||
extern Mach msparc;
|
||||
extern Mach msparc64;
|
||||
extern Mach m68020;
|
||||
extern Mach mi386;
|
||||
extern Mach mamd64;
|
||||
extern Mach marm;
|
||||
extern Mach mpower;
|
||||
extern Mach mpower64;
|
||||
extern Mach malpha;
|
||||
|
||||
/* BUG: FIX THESE WHEN NEEDED */
|
||||
Mach mmips;
|
||||
Mach mmips2le;
|
||||
Mach mmips2be;
|
||||
Mach msparc;
|
||||
Mach msparc64;
|
||||
Mach m68020;
|
||||
Mach marm;
|
||||
Mach mpower;
|
||||
Mach mpower64;
|
||||
Mach malpha;
|
||||
|
||||
ExecTable exectab[] =
|
||||
{
|
||||
{ V_MAGIC, /* Mips v.out */
|
||||
"mips plan 9 executable BE",
|
||||
"mips plan 9 dlm BE",
|
||||
FMIPS,
|
||||
1,
|
||||
&mmips,
|
||||
sizeof(Exec),
|
||||
beswal,
|
||||
adotout },
|
||||
{ P_MAGIC, /* Mips 0.out (r3k le) */
|
||||
"mips plan 9 executable LE",
|
||||
"mips plan 9 dlm LE",
|
||||
FMIPSLE,
|
||||
1,
|
||||
&mmips,
|
||||
sizeof(Exec),
|
||||
beswal,
|
||||
adotout },
|
||||
{ M_MAGIC, /* Mips 4.out */
|
||||
"mips 4k plan 9 executable BE",
|
||||
"mips 4k plan 9 dlm BE",
|
||||
FMIPS2BE,
|
||||
1,
|
||||
&mmips2be,
|
||||
sizeof(Exec),
|
||||
beswal,
|
||||
adotout },
|
||||
{ N_MAGIC, /* Mips 0.out */
|
||||
"mips 4k plan 9 executable LE",
|
||||
"mips 4k plan 9 dlm LE",
|
||||
FMIPS2LE,
|
||||
1,
|
||||
&mmips2le,
|
||||
sizeof(Exec),
|
||||
beswal,
|
||||
adotout },
|
||||
{ 0x160<<16, /* Mips boot image */
|
||||
"mips plan 9 boot image",
|
||||
nil,
|
||||
FMIPSB,
|
||||
0,
|
||||
&mmips,
|
||||
sizeof(struct mipsexec),
|
||||
beswal,
|
||||
mipsboot },
|
||||
{ (0x160<<16)|3, /* Mips boot image */
|
||||
"mips 4k plan 9 boot image",
|
||||
nil,
|
||||
FMIPSB,
|
||||
0,
|
||||
&mmips2be,
|
||||
sizeof(struct mips4kexec),
|
||||
beswal,
|
||||
mips4kboot },
|
||||
{ K_MAGIC, /* Sparc k.out */
|
||||
"sparc plan 9 executable",
|
||||
"sparc plan 9 dlm",
|
||||
FSPARC,
|
||||
1,
|
||||
&msparc,
|
||||
sizeof(Exec),
|
||||
beswal,
|
||||
adotout },
|
||||
{ 0x01030107, /* Sparc boot image */
|
||||
"sparc plan 9 boot image",
|
||||
nil,
|
||||
FSPARCB,
|
||||
0,
|
||||
&msparc,
|
||||
sizeof(struct sparcexec),
|
||||
beswal,
|
||||
sparcboot },
|
||||
{ U_MAGIC, /* Sparc64 u.out */
|
||||
"sparc64 plan 9 executable",
|
||||
"sparc64 plan 9 dlm",
|
||||
FSPARC64,
|
||||
1,
|
||||
&msparc64,
|
||||
sizeof(Exec),
|
||||
beswal,
|
||||
adotout },
|
||||
{ A_MAGIC, /* 68020 2.out & boot image */
|
||||
"68020 plan 9 executable",
|
||||
"68020 plan 9 dlm",
|
||||
F68020,
|
||||
1,
|
||||
&m68020,
|
||||
sizeof(Exec),
|
||||
beswal,
|
||||
common },
|
||||
{ 0xFEEDFACE, /* Next boot image */
|
||||
"next plan 9 boot image",
|
||||
nil,
|
||||
FNEXTB,
|
||||
0,
|
||||
&m68020,
|
||||
sizeof(struct nextexec),
|
||||
beswal,
|
||||
nextboot },
|
||||
{ I_MAGIC, /* I386 8.out & boot image */
|
||||
"386 plan 9 executable",
|
||||
"386 plan 9 dlm",
|
||||
FI386,
|
||||
1,
|
||||
&mi386,
|
||||
sizeof(Exec),
|
||||
beswal,
|
||||
common },
|
||||
{ S_MAGIC, /* amd64 6.out & boot image */
|
||||
"amd64 plan 9 executable",
|
||||
"amd64 plan 9 dlm",
|
||||
FAMD64,
|
||||
1,
|
||||
&mamd64,
|
||||
sizeof(Exec)+8,
|
||||
nil,
|
||||
commonllp64 },
|
||||
{ Q_MAGIC, /* PowerPC q.out & boot image */
|
||||
"power plan 9 executable",
|
||||
"power plan 9 dlm",
|
||||
FPOWER,
|
||||
1,
|
||||
&mpower,
|
||||
sizeof(Exec),
|
||||
beswal,
|
||||
common },
|
||||
{ T_MAGIC, /* power64 9.out & boot image */
|
||||
"power64 plan 9 executable",
|
||||
"power64 plan 9 dlm",
|
||||
FPOWER64,
|
||||
1,
|
||||
&mpower64,
|
||||
sizeof(Exec)+8,
|
||||
nil,
|
||||
commonllp64 },
|
||||
{ ELF_MAG, /* any elf32 or elf64 */
|
||||
"elf executable",
|
||||
nil,
|
||||
FNONE,
|
||||
0,
|
||||
&mi386,
|
||||
sizeof(Ehdr64),
|
||||
nil,
|
||||
elfdotout },
|
||||
{ E_MAGIC, /* Arm 5.out and boot image */
|
||||
"arm plan 9 executable",
|
||||
"arm plan 9 dlm",
|
||||
FARM,
|
||||
1,
|
||||
&marm,
|
||||
sizeof(Exec),
|
||||
beswal,
|
||||
common },
|
||||
{ (143<<16)|0413, /* (Free|Net)BSD Arm */
|
||||
"arm *bsd executable",
|
||||
nil,
|
||||
FARM,
|
||||
0,
|
||||
&marm,
|
||||
sizeof(Exec),
|
||||
leswal,
|
||||
armdotout },
|
||||
{ L_MAGIC, /* alpha 7.out */
|
||||
"alpha plan 9 executable",
|
||||
"alpha plan 9 dlm",
|
||||
FALPHA,
|
||||
1,
|
||||
&malpha,
|
||||
sizeof(Exec),
|
||||
beswal,
|
||||
common },
|
||||
{ 0x0700e0c3, /* alpha boot image */
|
||||
"alpha plan 9 boot image",
|
||||
nil,
|
||||
FALPHA,
|
||||
0,
|
||||
&malpha,
|
||||
sizeof(Exec),
|
||||
beswal,
|
||||
common },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
Mach *mach = &mi386; /* Global current machine table */
|
||||
|
||||
static ExecTable*
|
||||
couldbe4k(ExecTable *mp)
|
||||
{
|
||||
Dir *d;
|
||||
ExecTable *f;
|
||||
|
||||
if((d=dirstat("/proc/1/regs")) == nil)
|
||||
return mp;
|
||||
if(d->length < 32*8){ /* R3000 */
|
||||
free(d);
|
||||
return mp;
|
||||
}
|
||||
free(d);
|
||||
for (f = exectab; f->magic; f++)
|
||||
if(f->magic == M_MAGIC) {
|
||||
f->name = "mips plan 9 executable on mips2 kernel";
|
||||
return f;
|
||||
}
|
||||
return mp;
|
||||
}
|
||||
|
||||
int
|
||||
crackhdr(int fd, Fhdr *fp)
|
||||
{
|
||||
ExecTable *mp;
|
||||
ExecHdr d;
|
||||
int nb, ret;
|
||||
ulong magic;
|
||||
|
||||
fp->type = FNONE;
|
||||
nb = read(fd, (char *)&d.e, sizeof(d.e));
|
||||
if (nb <= 0)
|
||||
return 0;
|
||||
|
||||
ret = 0;
|
||||
magic = beswal(d.e.exechdr.magic); /* big-endian */
|
||||
for (mp = exectab; mp->magic; mp++) {
|
||||
if (nb < mp->hsize)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* The magic number has morphed into something
|
||||
* with fields (the straw was DYN_MAGIC) so now
|
||||
* a flag is needed in Fhdr to distinguish _MAGIC()
|
||||
* magic numbers from foreign magic numbers.
|
||||
*
|
||||
* This code is creaking a bit and if it has to
|
||||
* be modified/extended much more it's probably
|
||||
* time to step back and redo it all.
|
||||
*/
|
||||
if(mp->_magic){
|
||||
if(mp->magic != (magic & ~DYN_MAGIC))
|
||||
continue;
|
||||
|
||||
if(mp->magic == V_MAGIC)
|
||||
mp = couldbe4k(mp);
|
||||
|
||||
if ((magic & DYN_MAGIC) && mp->dlmname != nil)
|
||||
fp->name = mp->dlmname;
|
||||
else
|
||||
fp->name = mp->name;
|
||||
}
|
||||
else{
|
||||
if(mp->magic != magic)
|
||||
continue;
|
||||
fp->name = mp->name;
|
||||
}
|
||||
fp->type = mp->type;
|
||||
fp->hdrsz = mp->hsize; /* will be zero on bootables */
|
||||
fp->_magic = mp->_magic;
|
||||
fp->magic = magic;
|
||||
|
||||
mach = mp->mach;
|
||||
if(mp->swal != nil)
|
||||
hswal(&d, sizeof(d.e)/sizeof(ulong), mp->swal);
|
||||
ret = mp->hparse(fd, fp, &d);
|
||||
seek(fd, mp->hsize, 0); /* seek to end of header */
|
||||
break;
|
||||
}
|
||||
if(mp->magic == 0)
|
||||
werrstr("unknown header type");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert header to canonical form
|
||||
*/
|
||||
static void
|
||||
hswal(void *v, int n, ulong (*swap)(ulong))
|
||||
{
|
||||
ulong *ulp;
|
||||
|
||||
for(ulp = v; n--; ulp++)
|
||||
*ulp = (*swap)(*ulp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Crack a normal a.out-type header
|
||||
*/
|
||||
static int
|
||||
adotout(int fd, Fhdr *fp, ExecHdr *hp)
|
||||
{
|
||||
long pgsize;
|
||||
|
||||
USED(fd);
|
||||
pgsize = mach->pgsize;
|
||||
settext(fp, hp->e.exechdr.entry, pgsize+sizeof(Exec),
|
||||
hp->e.exechdr.text, sizeof(Exec));
|
||||
setdata(fp, _round(pgsize+fp->txtsz+sizeof(Exec), pgsize),
|
||||
hp->e.exechdr.data, fp->txtsz+sizeof(Exec), hp->e.exechdr.bss);
|
||||
setsym(fp, hp->e.exechdr.syms, hp->e.exechdr.spsz, hp->e.exechdr.pcsz, fp->datoff+fp->datsz);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
commonboot(Fhdr *fp)
|
||||
{
|
||||
if (!(fp->entry & mach->ktmask))
|
||||
return;
|
||||
|
||||
switch(fp->type) { /* boot image */
|
||||
case F68020:
|
||||
fp->type = F68020B;
|
||||
fp->name = "68020 plan 9 boot image";
|
||||
break;
|
||||
case FI386:
|
||||
fp->type = FI386B;
|
||||
fp->txtaddr = (u32int)fp->entry;
|
||||
fp->name = "386 plan 9 boot image";
|
||||
fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
|
||||
break;
|
||||
case FARM:
|
||||
fp->type = FARMB;
|
||||
fp->txtaddr = (u32int)fp->entry;
|
||||
fp->name = "ARM plan 9 boot image";
|
||||
fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
|
||||
return;
|
||||
case FALPHA:
|
||||
fp->type = FALPHAB;
|
||||
fp->txtaddr = (u32int)fp->entry;
|
||||
fp->name = "alpha plan 9 boot image";
|
||||
fp->dataddr = fp->txtaddr+fp->txtsz;
|
||||
break;
|
||||
case FPOWER:
|
||||
fp->type = FPOWERB;
|
||||
fp->txtaddr = (u32int)fp->entry;
|
||||
fp->name = "power plan 9 boot image";
|
||||
fp->dataddr = fp->txtaddr+fp->txtsz;
|
||||
break;
|
||||
case FAMD64:
|
||||
fp->type = FAMD64B;
|
||||
fp->txtaddr = fp->entry;
|
||||
fp->name = "amd64 plan 9 boot image";
|
||||
fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
fp->hdrsz = 0; /* header stripped */
|
||||
}
|
||||
|
||||
/*
|
||||
* _MAGIC() style headers and
|
||||
* alpha plan9-style bootable images for axp "headerless" boot
|
||||
*
|
||||
*/
|
||||
static int
|
||||
common(int fd, Fhdr *fp, ExecHdr *hp)
|
||||
{
|
||||
adotout(fd, fp, hp);
|
||||
if(hp->e.exechdr.magic & DYN_MAGIC) {
|
||||
fp->txtaddr = 0;
|
||||
fp->dataddr = fp->txtsz;
|
||||
return 1;
|
||||
}
|
||||
commonboot(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
commonllp64(int unused, Fhdr *fp, ExecHdr *hp)
|
||||
{
|
||||
long pgsize;
|
||||
uvlong entry;
|
||||
|
||||
hswal(&hp->e, sizeof(Exec)/sizeof(long), beswal);
|
||||
if(!(hp->e.exechdr.magic & HDR_MAGIC))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* There can be more magic here if the
|
||||
* header ever needs more expansion.
|
||||
* For now just catch use of any of the
|
||||
* unused bits.
|
||||
*/
|
||||
if((hp->e.exechdr.magic & ~DYN_MAGIC)>>16)
|
||||
return 0;
|
||||
entry = beswav(*(uvlong*)&hp->e.exechdr);
|
||||
|
||||
pgsize = mach->pgsize;
|
||||
settext(fp, entry, pgsize+fp->hdrsz, hp->e.exechdr.text, fp->hdrsz);
|
||||
setdata(fp, _round(pgsize+fp->txtsz+fp->hdrsz, pgsize),
|
||||
hp->e.exechdr.data, fp->txtsz+fp->hdrsz, hp->e.exechdr.bss);
|
||||
setsym(fp, hp->e.exechdr.syms, hp->e.exechdr.spsz, hp->e.exechdr.pcsz, fp->datoff+fp->datsz);
|
||||
|
||||
if(hp->e.exechdr.magic & DYN_MAGIC) {
|
||||
fp->txtaddr = 0;
|
||||
fp->dataddr = fp->txtsz;
|
||||
return 1;
|
||||
}
|
||||
commonboot(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* mips bootable image.
|
||||
*/
|
||||
static int
|
||||
mipsboot(int fd, Fhdr *fp, ExecHdr *hp)
|
||||
{
|
||||
abort();
|
||||
#ifdef unused
|
||||
USED(fd);
|
||||
fp->type = FMIPSB;
|
||||
switch(hp->e.exechdr.amagic) {
|
||||
default:
|
||||
case 0407: /* some kind of mips */
|
||||
settext(fp, (u32int)hp->e.mentry, (u32int)hp->e.text_start,
|
||||
hp->e.tsize, sizeof(struct mipsexec)+4);
|
||||
setdata(fp, (u32int)hp->e.data_start, hp->e.dsize,
|
||||
fp->txtoff+hp->e.tsize, hp->e.bsize);
|
||||
break;
|
||||
case 0413: /* some kind of mips */
|
||||
settext(fp, (u32int)hp->e.mentry, (u32int)hp->e.text_start,
|
||||
hp->e.tsize, 0);
|
||||
setdata(fp, (u32int)hp->e.data_start, hp->e.dsize,
|
||||
hp->e.tsize, hp->e.bsize);
|
||||
break;
|
||||
}
|
||||
setsym(fp, hp->e.nsyms, 0, hp->e.pcsize, hp->e.symptr);
|
||||
fp->hdrsz = 0; /* header stripped */
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* mips4k bootable image.
|
||||
*/
|
||||
static int
|
||||
mips4kboot(int fd, Fhdr *fp, ExecHdr *hp)
|
||||
{
|
||||
abort();
|
||||
#ifdef unused
|
||||
USED(fd);
|
||||
fp->type = FMIPSB;
|
||||
switch(hp->e.h.amagic) {
|
||||
default:
|
||||
case 0407: /* some kind of mips */
|
||||
settext(fp, (u32int)hp->e.h.mentry, (u32int)hp->e.h.text_start,
|
||||
hp->e.h.tsize, sizeof(struct mips4kexec));
|
||||
setdata(fp, (u32int)hp->e.h.data_start, hp->e.h.dsize,
|
||||
fp->txtoff+hp->e.h.tsize, hp->e.h.bsize);
|
||||
break;
|
||||
case 0413: /* some kind of mips */
|
||||
settext(fp, (u32int)hp->e.h.mentry, (u32int)hp->e.h.text_start,
|
||||
hp->e.h.tsize, 0);
|
||||
setdata(fp, (u32int)hp->e.h.data_start, hp->e.h.dsize,
|
||||
hp->e.h.tsize, hp->e.h.bsize);
|
||||
break;
|
||||
}
|
||||
setsym(fp, hp->e.h.nsyms, 0, hp->e.h.pcsize, hp->e.h.symptr);
|
||||
fp->hdrsz = 0; /* header stripped */
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sparc bootable image
|
||||
*/
|
||||
static int
|
||||
sparcboot(int fd, Fhdr *fp, ExecHdr *hp)
|
||||
{
|
||||
abort();
|
||||
#ifdef unused
|
||||
USED(fd);
|
||||
fp->type = FSPARCB;
|
||||
settext(fp, hp->e.sentry, hp->e.sentry, hp->e.stext,
|
||||
sizeof(struct sparcexec));
|
||||
setdata(fp, hp->e.sentry+hp->e.stext, hp->e.sdata,
|
||||
fp->txtoff+hp->e.stext, hp->e.sbss);
|
||||
setsym(fp, hp->e.ssyms, 0, hp->e.sdrsize, fp->datoff+hp->e.sdata);
|
||||
fp->hdrsz = 0; /* header stripped */
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* next bootable image
|
||||
*/
|
||||
static int
|
||||
nextboot(int fd, Fhdr *fp, ExecHdr *hp)
|
||||
{
|
||||
abort();
|
||||
#ifdef unused
|
||||
USED(fd);
|
||||
fp->type = FNEXTB;
|
||||
settext(fp, hp->e.textc.vmaddr, hp->e.textc.vmaddr,
|
||||
hp->e.texts.size, hp->e.texts.offset);
|
||||
setdata(fp, hp->e.datac.vmaddr, hp->e.datas.size,
|
||||
hp->e.datas.offset, hp->e.bsss.size);
|
||||
setsym(fp, hp->e.symc.nsyms, hp->e.symc.spoff, hp->e.symc.pcoff,
|
||||
hp->e.symc.symoff);
|
||||
fp->hdrsz = 0; /* header stripped */
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Elf32 and Elf64 binaries.
|
||||
*/
|
||||
static int
|
||||
elf64dotout(int fd, Fhdr *fp, ExecHdr *hp)
|
||||
{
|
||||
|
||||
uvlong (*swav)(uvlong);
|
||||
ulong (*swal)(ulong);
|
||||
ushort (*swab)(ushort);
|
||||
Ehdr64 *ep;
|
||||
Phdr64 *ph;
|
||||
int i, it, id, is, phsz;
|
||||
|
||||
/* bitswap the header according to the DATA format */
|
||||
ep = &hp->e.elfhdr64;
|
||||
if(ep->ident[CLASS] != ELFCLASS64) {
|
||||
werrstr("bad ELF class - not 32 bit or 64 bit");
|
||||
return 0;
|
||||
}
|
||||
if(ep->ident[DATA] == ELFDATA2LSB) {
|
||||
swab = leswab;
|
||||
swal = leswal;
|
||||
swav = leswav;
|
||||
} else if(ep->ident[DATA] == ELFDATA2MSB) {
|
||||
swab = beswab;
|
||||
swal = beswal;
|
||||
swav = beswav;
|
||||
} else {
|
||||
werrstr("bad ELF encoding - not big or little endian");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ep->type = swab(ep->type);
|
||||
ep->machine = swab(ep->machine);
|
||||
ep->version = swal(ep->version);
|
||||
ep->elfentry = swal(ep->elfentry);
|
||||
print("entry: 0x%x\n", ep->elfentry);
|
||||
ep->phoff = swav(ep->phoff);
|
||||
ep->shoff = swav(ep->shoff);
|
||||
ep->flags = swav(ep->flags);
|
||||
ep->ehsize = swab(ep->ehsize);
|
||||
ep->phentsize = swab(ep->phentsize);
|
||||
ep->phnum = swab(ep->phnum);
|
||||
ep->shentsize = swab(ep->shentsize);
|
||||
ep->shnum = swab(ep->shnum);
|
||||
ep->shstrndx = swab(ep->shstrndx);
|
||||
if(ep->type != EXEC || ep->version != CURRENT)
|
||||
return 0;
|
||||
|
||||
/* we could definitely support a lot more machines here */
|
||||
fp->magic = ELF_MAG;
|
||||
fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15;
|
||||
switch(ep->machine) {
|
||||
case I386:
|
||||
mach = &mi386;
|
||||
fp->type = FI386;
|
||||
break;
|
||||
case MIPS:
|
||||
mach = &mmips;
|
||||
fp->type = FMIPS;
|
||||
break;
|
||||
case SPARC64:
|
||||
mach = &msparc64;
|
||||
fp->type = FSPARC64;
|
||||
break;
|
||||
case POWER:
|
||||
mach = &mpower;
|
||||
fp->type = FPOWER;
|
||||
break;
|
||||
case AMD64:
|
||||
mach = &mamd64;
|
||||
fp->type = FAMD64;
|
||||
break;
|
||||
case ARM:
|
||||
mach = &marm;
|
||||
fp->type = FARM;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(ep->phentsize != sizeof(Phdr64)) {
|
||||
werrstr("bad ELF header size");
|
||||
return 0;
|
||||
}
|
||||
phsz = sizeof(Phdr64)*ep->phnum;
|
||||
ph = malloc(phsz);
|
||||
if(!ph)
|
||||
return 0;
|
||||
seek(fd, ep->phoff, 0);
|
||||
if(read(fd, ph, phsz) < 0) {
|
||||
free(ph);
|
||||
return 0;
|
||||
}
|
||||
hswal(ph, phsz/sizeof(ulong), swal);
|
||||
|
||||
/* find text, data and symbols and install them */
|
||||
it = id = is = -1;
|
||||
for(i = 0; i < ep->phnum; i++) {
|
||||
if(ph[i].type == LOAD
|
||||
&& (ph[i].flags & (R|X)) == (R|X) && it == -1)
|
||||
it = i;
|
||||
else if(ph[i].type == LOAD
|
||||
&& (ph[i].flags & (R|W)) == (R|W) && id == -1)
|
||||
id = i;
|
||||
else if(ph[i].type == NOPTYPE && is == -1)
|
||||
is = i;
|
||||
}
|
||||
if(it == -1 || id == -1) {
|
||||
/*
|
||||
* The SPARC64 boot image is something of an ELF hack.
|
||||
* Text+Data+BSS are represented by ph[0]. Symbols
|
||||
* are represented by ph[1]:
|
||||
*
|
||||
* filesz, memsz, vaddr, paddr, off
|
||||
* ph[0] : txtsz+datsz, txtsz+datsz+bsssz, txtaddr-KZERO, datasize, txtoff
|
||||
* ph[1] : symsz, lcsz, 0, 0, symoff
|
||||
*/
|
||||
if(ep->machine == SPARC64 && ep->phnum == 2) {
|
||||
ulong txtaddr, txtsz, dataddr, bsssz;
|
||||
|
||||
txtaddr = ph[0].vaddr | 0x80000000;
|
||||
txtsz = ph[0].filesz - ph[0].paddr;
|
||||
dataddr = txtaddr + txtsz;
|
||||
bsssz = ph[0].memsz - ph[0].filesz;
|
||||
settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, ph[0].offset);
|
||||
setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz, bsssz);
|
||||
setsym(fp, ph[1].filesz, 0, ph[1].memsz, ph[1].offset);
|
||||
free(ph);
|
||||
return 1;
|
||||
}
|
||||
|
||||
werrstr("No TEXT or DATA sections");
|
||||
free(ph);
|
||||
return 0;
|
||||
}
|
||||
|
||||
settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset);
|
||||
setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - ph[id].filesz);
|
||||
if(is != -1)
|
||||
setsym(fp, ph[is].filesz, 0, ph[is].memsz, ph[is].offset);
|
||||
free(ph);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
elfdotout(int fd, Fhdr *fp, ExecHdr *hp)
|
||||
{
|
||||
|
||||
ulong (*swal)(ulong);
|
||||
ushort (*swab)(ushort);
|
||||
Ehdr32 *ep;
|
||||
Phdr32 *ph;
|
||||
int i, it, id, is, phsz;
|
||||
|
||||
/* bitswap the header according to the DATA format */
|
||||
ep = &hp->e.elfhdr32;
|
||||
if(ep->ident[CLASS] != ELFCLASS32) {
|
||||
return elf64dotout(fd, fp, hp);
|
||||
}
|
||||
if(ep->ident[DATA] == ELFDATA2LSB) {
|
||||
swab = leswab;
|
||||
swal = leswal;
|
||||
} else if(ep->ident[DATA] == ELFDATA2MSB) {
|
||||
swab = beswab;
|
||||
swal = beswal;
|
||||
} else {
|
||||
werrstr("bad ELF encoding - not big or little endian");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ep->type = swab(ep->type);
|
||||
ep->machine = swab(ep->machine);
|
||||
ep->version = swal(ep->version);
|
||||
ep->elfentry = swal(ep->elfentry);
|
||||
ep->phoff = swal(ep->phoff);
|
||||
ep->shoff = swal(ep->shoff);
|
||||
ep->flags = swal(ep->flags);
|
||||
ep->ehsize = swab(ep->ehsize);
|
||||
ep->phentsize = swab(ep->phentsize);
|
||||
ep->phnum = swab(ep->phnum);
|
||||
ep->shentsize = swab(ep->shentsize);
|
||||
ep->shnum = swab(ep->shnum);
|
||||
ep->shstrndx = swab(ep->shstrndx);
|
||||
if(ep->type != EXEC || ep->version != CURRENT)
|
||||
return 0;
|
||||
|
||||
/* we could definitely support a lot more machines here */
|
||||
fp->magic = ELF_MAG;
|
||||
fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15;
|
||||
switch(ep->machine) {
|
||||
case I386:
|
||||
mach = &mi386;
|
||||
fp->type = FI386;
|
||||
break;
|
||||
case MIPS:
|
||||
mach = &mmips;
|
||||
fp->type = FMIPS;
|
||||
break;
|
||||
case SPARC64:
|
||||
mach = &msparc64;
|
||||
fp->type = FSPARC64;
|
||||
break;
|
||||
case POWER:
|
||||
mach = &mpower;
|
||||
fp->type = FPOWER;
|
||||
break;
|
||||
case AMD64:
|
||||
mach = &mamd64;
|
||||
fp->type = FAMD64;
|
||||
break;
|
||||
case ARM:
|
||||
mach = &marm;
|
||||
fp->type = FARM;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(ep->phentsize != sizeof(Phdr32)) {
|
||||
werrstr("bad ELF header size");
|
||||
return 0;
|
||||
}
|
||||
phsz = sizeof(Phdr32)*ep->phnum;
|
||||
ph = malloc(phsz);
|
||||
if(!ph)
|
||||
return 0;
|
||||
seek(fd, ep->phoff, 0);
|
||||
if(read(fd, ph, phsz) < 0) {
|
||||
free(ph);
|
||||
return 0;
|
||||
}
|
||||
hswal(ph, phsz/sizeof(ulong), swal);
|
||||
|
||||
/* find text, data and symbols and install them */
|
||||
it = id = is = -1;
|
||||
for(i = 0; i < ep->phnum; i++) {
|
||||
if(ph[i].type == LOAD
|
||||
&& (ph[i].flags & (R|X)) == (R|X) && it == -1)
|
||||
it = i;
|
||||
else if(ph[i].type == LOAD
|
||||
&& (ph[i].flags & (R|W)) == (R|W) && id == -1)
|
||||
id = i;
|
||||
else if(ph[i].type == NOPTYPE && is == -1)
|
||||
is = i;
|
||||
}
|
||||
if(it == -1 || id == -1) {
|
||||
/*
|
||||
* The SPARC64 boot image is something of an ELF hack.
|
||||
* Text+Data+BSS are represented by ph[0]. Symbols
|
||||
* are represented by ph[1]:
|
||||
*
|
||||
* filesz, memsz, vaddr, paddr, off
|
||||
* ph[0] : txtsz+datsz, txtsz+datsz+bsssz, txtaddr-KZERO, datasize, txtoff
|
||||
* ph[1] : symsz, lcsz, 0, 0, symoff
|
||||
*/
|
||||
if(ep->machine == SPARC64 && ep->phnum == 2) {
|
||||
ulong txtaddr, txtsz, dataddr, bsssz;
|
||||
|
||||
txtaddr = ph[0].vaddr | 0x80000000;
|
||||
txtsz = ph[0].filesz - ph[0].paddr;
|
||||
dataddr = txtaddr + txtsz;
|
||||
bsssz = ph[0].memsz - ph[0].filesz;
|
||||
settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, ph[0].offset);
|
||||
setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz, bsssz);
|
||||
setsym(fp, ph[1].filesz, 0, ph[1].memsz, ph[1].offset);
|
||||
free(ph);
|
||||
return 1;
|
||||
}
|
||||
|
||||
werrstr("No TEXT or DATA sections");
|
||||
free(ph);
|
||||
return 0;
|
||||
}
|
||||
|
||||
settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset);
|
||||
setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - ph[id].filesz);
|
||||
if(is != -1)
|
||||
setsym(fp, ph[is].filesz, 0, ph[is].memsz, ph[is].offset);
|
||||
free(ph);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* (Free|Net)BSD ARM header.
|
||||
*/
|
||||
static int
|
||||
armdotout(int fd, Fhdr *fp, ExecHdr *hp)
|
||||
{
|
||||
uvlong kbase;
|
||||
|
||||
USED(fd);
|
||||
settext(fp, hp->e.exechdr.entry, sizeof(Exec), hp->e.exechdr.text, sizeof(Exec));
|
||||
setdata(fp, fp->txtsz, hp->e.exechdr.data, fp->txtsz, hp->e.exechdr.bss);
|
||||
setsym(fp, hp->e.exechdr.syms, hp->e.exechdr.spsz, hp->e.exechdr.pcsz, fp->datoff+fp->datsz);
|
||||
|
||||
kbase = 0xF0000000;
|
||||
if ((fp->entry & kbase) == kbase) { /* Boot image */
|
||||
fp->txtaddr = kbase+sizeof(Exec);
|
||||
fp->name = "ARM *BSD boot image";
|
||||
fp->hdrsz = 0; /* header stripped */
|
||||
fp->dataddr = kbase+fp->txtsz;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
settext(Fhdr *fp, uvlong e, uvlong a, long s, vlong off)
|
||||
{
|
||||
fp->txtaddr = a;
|
||||
fp->entry = e;
|
||||
fp->txtsz = s;
|
||||
fp->txtoff = off;
|
||||
}
|
||||
|
||||
static void
|
||||
setdata(Fhdr *fp, uvlong a, long s, vlong off, long bss)
|
||||
{
|
||||
fp->dataddr = a;
|
||||
fp->datsz = s;
|
||||
fp->datoff = off;
|
||||
fp->bsssz = bss;
|
||||
}
|
||||
|
||||
static void
|
||||
setsym(Fhdr *fp, long symsz, long sppcsz, long lnpcsz, vlong symoff)
|
||||
{
|
||||
fp->symsz = symsz;
|
||||
fp->symoff = symoff;
|
||||
fp->sppcsz = sppcsz;
|
||||
fp->sppcoff = fp->symoff+fp->symsz;
|
||||
fp->lnpcsz = lnpcsz;
|
||||
fp->lnpcoff = fp->sppcoff+fp->sppcsz;
|
||||
}
|
||||
|
||||
|
||||
static uvlong
|
||||
_round(uvlong a, ulong b)
|
||||
{
|
||||
uvlong w;
|
||||
|
||||
w = (a/b)*b;
|
||||
if (a!=w)
|
||||
w += b;
|
||||
return(w);
|
||||
}
|
477
src/libmachamd64/machdata.c
Normal file
477
src/libmachamd64/machdata.c
Normal file
@ -0,0 +1,477 @@
|
||||
// Inferno libmach/machdata.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/machdata.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
/*
|
||||
* Debugger utilities shared by at least two architectures
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <mach_amd64.h>
|
||||
|
||||
#define STARTSYM "_main"
|
||||
#define PROFSYM "_mainp"
|
||||
#define FRAMENAME ".frame"
|
||||
|
||||
extern Machdata mipsmach;
|
||||
|
||||
int asstype = AMIPS; /* disassembler type */
|
||||
Machdata *machdata; /* machine-dependent functions */
|
||||
|
||||
int
|
||||
localaddr(Map *map, char *fn, char *var, uvlong *r, Rgetter rget)
|
||||
{
|
||||
Symbol s;
|
||||
uvlong fp, pc, sp, link;
|
||||
|
||||
if (!lookup(fn, 0, &s)) {
|
||||
werrstr("function not found");
|
||||
return -1;
|
||||
}
|
||||
pc = rget(map, mach->pc);
|
||||
sp = rget(map, mach->sp);
|
||||
if(mach->link)
|
||||
link = rget(map, mach->link);
|
||||
else
|
||||
link = 0;
|
||||
fp = machdata->findframe(map, s.value, pc, sp, link);
|
||||
if (fp == 0) {
|
||||
werrstr("stack frame not found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!var || !var[0]) {
|
||||
*r = fp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (findlocal(&s, var, &s) == 0) {
|
||||
werrstr("local variable not found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (s.class) {
|
||||
case CAUTO:
|
||||
*r = fp - s.value;
|
||||
break;
|
||||
case CPARAM: /* assume address size is stack width */
|
||||
*r = fp + s.value + mach->szaddr;
|
||||
break;
|
||||
default:
|
||||
werrstr("local variable not found: %d", s.class);
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print value v as s.name[+offset] if possible, or just v.
|
||||
*/
|
||||
int
|
||||
symoff(char *buf, int n, uvlong v, int space)
|
||||
{
|
||||
Symbol s;
|
||||
int r;
|
||||
long delta;
|
||||
|
||||
r = delta = 0; /* to shut compiler up */
|
||||
if (v) {
|
||||
r = findsym(v, space, &s);
|
||||
if (r)
|
||||
delta = v-s.value;
|
||||
if (delta < 0)
|
||||
delta = -delta;
|
||||
}
|
||||
if (v == 0 || r == 0)
|
||||
return snprint(buf, n, "%llux", v);
|
||||
if (s.type != 't' && s.type != 'T' && delta >= 4096)
|
||||
return snprint(buf, n, "%llux", v);
|
||||
else if (delta)
|
||||
return snprint(buf, n, "%s+%lux", s.name, delta);
|
||||
else
|
||||
return snprint(buf, n, "%s", s.name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Format floating point registers
|
||||
*
|
||||
* Register codes in format field:
|
||||
* 'X' - print as 32-bit hexadecimal value
|
||||
* 'F' - 64-bit double register when modif == 'F'; else 32-bit single reg
|
||||
* 'f' - 32-bit ieee float
|
||||
* '8' - big endian 80-bit ieee extended float
|
||||
* '3' - little endian 80-bit ieee extended float with hole in bytes 8&9
|
||||
*/
|
||||
int
|
||||
fpformat(Map *map, Reglist *rp, char *buf, int n, int modif)
|
||||
{
|
||||
char reg[12];
|
||||
ulong r;
|
||||
|
||||
switch(rp->rformat)
|
||||
{
|
||||
case 'X':
|
||||
if (get4(map, rp->roffs, &r) < 0)
|
||||
return -1;
|
||||
snprint(buf, n, "%lux", r);
|
||||
break;
|
||||
case 'F': /* first reg of double reg pair */
|
||||
if (modif == 'F')
|
||||
if ((rp->rformat=='F') || (((rp+1)->rflags&RFLT) && (rp+1)->rformat == 'f')) {
|
||||
if (get1(map, rp->roffs, (uchar *)reg, 8) < 0)
|
||||
return -1;
|
||||
machdata->dftos(buf, n, reg);
|
||||
if (rp->rformat == 'F')
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
/* treat it like 'f' */
|
||||
if (get1(map, rp->roffs, (uchar *)reg, 4) < 0)
|
||||
return -1;
|
||||
machdata->sftos(buf, n, reg);
|
||||
break;
|
||||
case 'f': /* 32 bit float */
|
||||
if (get1(map, rp->roffs, (uchar *)reg, 4) < 0)
|
||||
return -1;
|
||||
machdata->sftos(buf, n, reg);
|
||||
break;
|
||||
case '3': /* little endian ieee 80 with hole in bytes 8&9 */
|
||||
if (get1(map, rp->roffs, (uchar *)reg, 10) < 0)
|
||||
return -1;
|
||||
memmove(reg+10, reg+8, 2); /* open hole */
|
||||
memset(reg+8, 0, 2); /* fill it */
|
||||
leieee80ftos(buf, n, reg);
|
||||
break;
|
||||
case '8': /* big-endian ieee 80 */
|
||||
if (get1(map, rp->roffs, (uchar *)reg, 10) < 0)
|
||||
return -1;
|
||||
beieee80ftos(buf, n, reg);
|
||||
break;
|
||||
default: /* unknown */
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *
|
||||
_hexify(char *buf, ulong p, int zeros)
|
||||
{
|
||||
ulong d;
|
||||
|
||||
d = p/16;
|
||||
if(d)
|
||||
buf = _hexify(buf, d, zeros-1);
|
||||
else
|
||||
while(zeros--)
|
||||
*buf++ = '0';
|
||||
*buf++ = "0123456789abcdef"[p&0x0f];
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* These routines assume that if the number is representable
|
||||
* in IEEE floating point, it will be representable in the native
|
||||
* double format. Naive but workable, probably.
|
||||
*/
|
||||
int
|
||||
ieeedftos(char *buf, int n, ulong h, ulong l)
|
||||
{
|
||||
double fr;
|
||||
int exp;
|
||||
|
||||
if (n <= 0)
|
||||
return 0;
|
||||
|
||||
|
||||
if(h & (1L<<31)){
|
||||
*buf++ = '-';
|
||||
h &= ~(1L<<31);
|
||||
}else
|
||||
*buf++ = ' ';
|
||||
n--;
|
||||
if(l == 0 && h == 0)
|
||||
return snprint(buf, n, "0.");
|
||||
exp = (h>>20) & ((1L<<11)-1L);
|
||||
if(exp == 0)
|
||||
return snprint(buf, n, "DeN(%.8lux%.8lux)", h, l);
|
||||
if(exp == ((1L<<11)-1L)){
|
||||
if(l==0 && (h&((1L<<20)-1L)) == 0)
|
||||
return snprint(buf, n, "Inf");
|
||||
else
|
||||
return snprint(buf, n, "NaN(%.8lux%.8lux)", h&((1L<<20)-1L), l);
|
||||
}
|
||||
exp -= (1L<<10) - 2L;
|
||||
fr = l & ((1L<<16)-1L);
|
||||
fr /= 1L<<16;
|
||||
fr += (l>>16) & ((1L<<16)-1L);
|
||||
fr /= 1L<<16;
|
||||
fr += (h & (1L<<20)-1L) | (1L<<20);
|
||||
fr /= 1L<<21;
|
||||
fr = ldexp(fr, exp);
|
||||
return snprint(buf, n, "%.18g", fr);
|
||||
}
|
||||
|
||||
int
|
||||
ieeesftos(char *buf, int n, ulong h)
|
||||
{
|
||||
double fr;
|
||||
int exp;
|
||||
|
||||
if (n <= 0)
|
||||
return 0;
|
||||
|
||||
if(h & (1L<<31)){
|
||||
*buf++ = '-';
|
||||
h &= ~(1L<<31);
|
||||
}else
|
||||
*buf++ = ' ';
|
||||
n--;
|
||||
if(h == 0)
|
||||
return snprint(buf, n, "0.");
|
||||
exp = (h>>23) & ((1L<<8)-1L);
|
||||
if(exp == 0)
|
||||
return snprint(buf, n, "DeN(%.8lux)", h);
|
||||
if(exp == ((1L<<8)-1L)){
|
||||
if((h&((1L<<23)-1L)) == 0)
|
||||
return snprint(buf, n, "Inf");
|
||||
else
|
||||
return snprint(buf, n, "NaN(%.8lux)", h&((1L<<23)-1L));
|
||||
}
|
||||
exp -= (1L<<7) - 2L;
|
||||
fr = (h & ((1L<<23)-1L)) | (1L<<23);
|
||||
fr /= 1L<<24;
|
||||
fr = ldexp(fr, exp);
|
||||
return snprint(buf, n, "%.9g", fr);
|
||||
}
|
||||
|
||||
int
|
||||
beieeesftos(char *buf, int n, void *s)
|
||||
{
|
||||
return ieeesftos(buf, n, beswal(*(ulong*)s));
|
||||
}
|
||||
|
||||
int
|
||||
beieeedftos(char *buf, int n, void *s)
|
||||
{
|
||||
return ieeedftos(buf, n, beswal(*(ulong*)s), beswal(((ulong*)(s))[1]));
|
||||
}
|
||||
|
||||
int
|
||||
leieeesftos(char *buf, int n, void *s)
|
||||
{
|
||||
return ieeesftos(buf, n, leswal(*(ulong*)s));
|
||||
}
|
||||
|
||||
int
|
||||
leieeedftos(char *buf, int n, void *s)
|
||||
{
|
||||
return ieeedftos(buf, n, leswal(((ulong*)(s))[1]), leswal(*(ulong*)s));
|
||||
}
|
||||
|
||||
/* packed in 12 bytes, with s[2]==s[3]==0; mantissa starts at s[4]*/
|
||||
int
|
||||
beieee80ftos(char *buf, int n, void *s)
|
||||
{
|
||||
uchar *reg = (uchar*)s;
|
||||
int i;
|
||||
ulong x;
|
||||
uchar ieee[8+8]; /* room for slop */
|
||||
uchar *p, *q;
|
||||
|
||||
memset(ieee, 0, sizeof(ieee));
|
||||
/* sign */
|
||||
if(reg[0] & 0x80)
|
||||
ieee[0] |= 0x80;
|
||||
|
||||
/* exponent */
|
||||
x = ((reg[0]&0x7F)<<8) | reg[1];
|
||||
if(x == 0) /* number is ±0 */
|
||||
goto done;
|
||||
if(x == 0x7FFF){
|
||||
if(memcmp(reg+4, ieee+1, 8) == 0){ /* infinity */
|
||||
x = 2047;
|
||||
}else{ /* NaN */
|
||||
x = 2047;
|
||||
ieee[7] = 0x1; /* make sure */
|
||||
}
|
||||
ieee[0] |= x>>4;
|
||||
ieee[1] |= (x&0xF)<<4;
|
||||
goto done;
|
||||
}
|
||||
x -= 0x3FFF; /* exponent bias */
|
||||
x += 1023;
|
||||
if(x >= (1<<11) || ((reg[4]&0x80)==0 && x!=0))
|
||||
return snprint(buf, n, "not in range");
|
||||
ieee[0] |= x>>4;
|
||||
ieee[1] |= (x&0xF)<<4;
|
||||
|
||||
/* mantissa */
|
||||
p = reg+4;
|
||||
q = ieee+1;
|
||||
for(i=0; i<56; i+=8, p++, q++){ /* move one byte */
|
||||
x = (p[0]&0x7F) << 1;
|
||||
if(p[1] & 0x80)
|
||||
x |= 1;
|
||||
q[0] |= x>>4;
|
||||
q[1] |= (x&0xF)<<4;
|
||||
}
|
||||
done:
|
||||
return beieeedftos(buf, n, (void*)ieee);
|
||||
}
|
||||
|
||||
int
|
||||
leieee80ftos(char *buf, int n, void *s)
|
||||
{
|
||||
int i;
|
||||
char *cp;
|
||||
char b[12];
|
||||
|
||||
cp = (char*) s;
|
||||
for(i=0; i<12; i++)
|
||||
b[11-i] = *cp++;
|
||||
return beieee80ftos(buf, n, b);
|
||||
}
|
||||
|
||||
int
|
||||
cisctrace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
|
||||
{
|
||||
Symbol s;
|
||||
int found, i;
|
||||
uvlong opc, moved;
|
||||
|
||||
USED(link);
|
||||
i = 0;
|
||||
opc = 0;
|
||||
while(pc && opc != pc) {
|
||||
moved = pc2sp(pc);
|
||||
if (moved == ~0)
|
||||
break;
|
||||
found = findsym(pc, CTEXT, &s);
|
||||
if (!found)
|
||||
break;
|
||||
if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)
|
||||
break;
|
||||
|
||||
sp += moved;
|
||||
opc = pc;
|
||||
if (geta(map, sp, &pc) < 0)
|
||||
break;
|
||||
(*trace)(map, pc, sp, &s);
|
||||
sp += mach->szaddr; /*assumes address size = stack width*/
|
||||
if(++i > 40)
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
risctrace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
|
||||
{
|
||||
int i;
|
||||
Symbol s, f;
|
||||
uvlong oldpc;
|
||||
|
||||
i = 0;
|
||||
while(findsym(pc, CTEXT, &s)) {
|
||||
if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)
|
||||
break;
|
||||
|
||||
if(pc == s.value) /* at first instruction */
|
||||
f.value = 0;
|
||||
else if(findlocal(&s, FRAMENAME, &f) == 0)
|
||||
break;
|
||||
|
||||
oldpc = pc;
|
||||
if(s.type == 'L' || s.type == 'l' || pc <= s.value+mach->pcquant)
|
||||
pc = link;
|
||||
else
|
||||
if (geta(map, sp, &pc) < 0)
|
||||
break;
|
||||
|
||||
if(pc == 0 || (pc == oldpc && f.value == 0))
|
||||
break;
|
||||
|
||||
sp += f.value;
|
||||
(*trace)(map, pc-8, sp, &s);
|
||||
|
||||
if(++i > 40)
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
uvlong
|
||||
ciscframe(Map *map, uvlong addr, uvlong pc, uvlong sp, uvlong link)
|
||||
{
|
||||
Symbol s;
|
||||
uvlong moved;
|
||||
|
||||
USED(link);
|
||||
for(;;) {
|
||||
moved = pc2sp(pc);
|
||||
if (moved == ~0)
|
||||
break;
|
||||
sp += moved;
|
||||
findsym(pc, CTEXT, &s);
|
||||
if (addr == s.value)
|
||||
return sp;
|
||||
if (geta(map, sp, &pc) < 0)
|
||||
break;
|
||||
sp += mach->szaddr; /*assumes sizeof(addr) = stack width*/
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uvlong
|
||||
riscframe(Map *map, uvlong addr, uvlong pc, uvlong sp, uvlong link)
|
||||
{
|
||||
Symbol s, f;
|
||||
|
||||
while (findsym(pc, CTEXT, &s)) {
|
||||
if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)
|
||||
break;
|
||||
|
||||
if(pc == s.value) /* at first instruction */
|
||||
f.value = 0;
|
||||
else
|
||||
if(findlocal(&s, FRAMENAME, &f) == 0)
|
||||
break;
|
||||
|
||||
sp += f.value;
|
||||
if (s.value == addr)
|
||||
return sp;
|
||||
|
||||
if (s.type == 'L' || s.type == 'l' || pc-s.value <= mach->szaddr*2)
|
||||
pc = link;
|
||||
else
|
||||
if (geta(map, sp-f.value, &pc) < 0)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
205
src/libmachamd64/map.c
Normal file
205
src/libmachamd64/map.c
Normal file
@ -0,0 +1,205 @@
|
||||
// Derived from Inferno libmach/map.c and
|
||||
// Plan 9 from User Space src/libmach/map.c
|
||||
//
|
||||
// http://code.swtch.com/plan9port/src/tip/src/libmach/map.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/map.c
|
||||
//
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2001-2007 Russ Cox.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
/*
|
||||
* file map routines
|
||||
*/
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <mach_amd64.h>
|
||||
|
||||
Map *
|
||||
newmap(Map *map, int n)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = sizeof(Map)+(n-1)*sizeof(struct segment);
|
||||
if (map == 0)
|
||||
map = malloc(size);
|
||||
else
|
||||
map = realloc(map, size);
|
||||
if (map == 0) {
|
||||
werrstr("out of memory: %r");
|
||||
return 0;
|
||||
}
|
||||
memset(map, 0, size);
|
||||
map->nsegs = n;
|
||||
return map;
|
||||
}
|
||||
|
||||
int
|
||||
setmap(Map *map, int fd, uvlong b, uvlong e, vlong f, char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (map == 0)
|
||||
return 0;
|
||||
for (i = 0; i < map->nsegs; i++)
|
||||
if (!map->seg[i].inuse)
|
||||
break;
|
||||
if (i >= map->nsegs)
|
||||
return 0;
|
||||
map->seg[i].b = b;
|
||||
map->seg[i].e = e;
|
||||
map->seg[i].f = f;
|
||||
map->seg[i].inuse = 1;
|
||||
map->seg[i].name = name;
|
||||
map->seg[i].fd = fd;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uvlong
|
||||
stacktop(int pid)
|
||||
{
|
||||
char buf[64];
|
||||
int fd;
|
||||
int n;
|
||||
char *cp;
|
||||
|
||||
snprint(buf, sizeof(buf), "/proc/%d/segment", pid);
|
||||
fd = open(buf, 0);
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
n = read(fd, buf, sizeof(buf)-1);
|
||||
close(fd);
|
||||
buf[n] = 0;
|
||||
if (strncmp(buf, "Stack", 5))
|
||||
return 0;
|
||||
for (cp = buf+5; *cp && *cp == ' '; cp++)
|
||||
;
|
||||
if (!*cp)
|
||||
return 0;
|
||||
cp = strchr(cp, ' ');
|
||||
if (!cp)
|
||||
return 0;
|
||||
while (*cp && *cp == ' ')
|
||||
cp++;
|
||||
if (!*cp)
|
||||
return 0;
|
||||
return strtoull(cp, 0, 16);
|
||||
}
|
||||
|
||||
Map*
|
||||
attachproc(int pid, int kflag, int corefd, Fhdr *fp)
|
||||
{
|
||||
char buf[64], *regs;
|
||||
int fd;
|
||||
Map *map;
|
||||
uvlong n;
|
||||
int mode;
|
||||
|
||||
map = newmap(0, 4);
|
||||
if (!map)
|
||||
return 0;
|
||||
if(kflag) {
|
||||
regs = "kregs";
|
||||
mode = OREAD;
|
||||
} else {
|
||||
regs = "regs";
|
||||
mode = ORDWR;
|
||||
}
|
||||
if (mach->regsize) {
|
||||
sprint(buf, "/proc/%d/%s", pid, regs);
|
||||
fd = open(buf, mode);
|
||||
if(fd < 0) {
|
||||
free(map);
|
||||
return 0;
|
||||
}
|
||||
setmap(map, fd, 0, mach->regsize, 0, "regs");
|
||||
}
|
||||
if (mach->fpregsize) {
|
||||
sprint(buf, "/proc/%d/fpregs", pid);
|
||||
fd = open(buf, mode);
|
||||
if(fd < 0) {
|
||||
close(map->seg[0].fd);
|
||||
free(map);
|
||||
return 0;
|
||||
}
|
||||
setmap(map, fd, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs");
|
||||
}
|
||||
setmap(map, corefd, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "text");
|
||||
if(kflag || fp->dataddr >= mach->utop) {
|
||||
setmap(map, corefd, fp->dataddr, ~0, fp->dataddr, "data");
|
||||
return map;
|
||||
}
|
||||
n = stacktop(pid);
|
||||
if (n == 0) {
|
||||
setmap(map, corefd, fp->dataddr, mach->utop, fp->dataddr, "data");
|
||||
return map;
|
||||
}
|
||||
setmap(map, corefd, fp->dataddr, n, fp->dataddr, "data");
|
||||
return map;
|
||||
}
|
||||
|
||||
int
|
||||
findseg(Map *map, char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!map)
|
||||
return -1;
|
||||
for (i = 0; i < map->nsegs; i++)
|
||||
if (map->seg[i].inuse && !strcmp(map->seg[i].name, name))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
unusemap(Map *map, int i)
|
||||
{
|
||||
if (map != 0 && 0 <= i && i < map->nsegs)
|
||||
map->seg[i].inuse = 0;
|
||||
}
|
||||
|
||||
Map*
|
||||
loadmap(Map *map, int fd, Fhdr *fp)
|
||||
{
|
||||
map = newmap(map, 2);
|
||||
if (map == 0)
|
||||
return 0;
|
||||
|
||||
map->seg[0].b = fp->txtaddr;
|
||||
map->seg[0].e = fp->txtaddr+fp->txtsz;
|
||||
map->seg[0].f = fp->txtoff;
|
||||
map->seg[0].fd = fd;
|
||||
map->seg[0].inuse = 1;
|
||||
map->seg[0].name = "text";
|
||||
map->seg[1].b = fp->dataddr;
|
||||
map->seg[1].e = fp->dataddr+fp->datsz;
|
||||
map->seg[1].f = fp->datoff;
|
||||
map->seg[1].fd = fd;
|
||||
map->seg[1].inuse = 1;
|
||||
map->seg[1].name = "data";
|
||||
return map;
|
||||
}
|
356
src/libmachamd64/obj.c
Normal file
356
src/libmachamd64/obj.c
Normal file
@ -0,0 +1,356 @@
|
||||
// Inferno libmach/obj.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/obj.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
/*
|
||||
* obj.c
|
||||
* routines universal to all object files
|
||||
*/
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <ar.h>
|
||||
#include <mach_amd64.h>
|
||||
#include "obj.h"
|
||||
|
||||
#define islocal(t) ((t)=='a' || (t)=='p')
|
||||
|
||||
enum
|
||||
{
|
||||
NNAMES = 50,
|
||||
MAXIS = 8, /* max length to determine if a file is a .? file */
|
||||
MAXOFF = 0x7fffffff, /* larger than any possible local offset */
|
||||
NHASH = 1024, /* must be power of two */
|
||||
HASHMUL = 79L,
|
||||
};
|
||||
|
||||
int _is2(char*), /* in [$OS].c */
|
||||
_is5(char*),
|
||||
_is6(char*),
|
||||
_is7(char*),
|
||||
_is8(char*),
|
||||
_is9(char*),
|
||||
_isk(char*),
|
||||
_isq(char*),
|
||||
_isv(char*),
|
||||
_isu(char*),
|
||||
_read2(Biobuf*, Prog*),
|
||||
_read5(Biobuf*, Prog*),
|
||||
_read6(Biobuf*, Prog*),
|
||||
_read7(Biobuf*, Prog*),
|
||||
_read8(Biobuf*, Prog*),
|
||||
_read9(Biobuf*, Prog*),
|
||||
_readk(Biobuf*, Prog*),
|
||||
_readq(Biobuf*, Prog*),
|
||||
_readv(Biobuf*, Prog*),
|
||||
_readu(Biobuf*, Prog*);
|
||||
|
||||
typedef struct Obj Obj;
|
||||
typedef struct Symtab Symtab;
|
||||
|
||||
struct Obj /* functions to handle each intermediate (.$O) file */
|
||||
{
|
||||
char *name; /* name of each $O file */
|
||||
int (*is)(char*); /* test for each type of $O file */
|
||||
int (*read)(Biobuf*, Prog*); /* read for each type of $O file*/
|
||||
};
|
||||
|
||||
static Obj obj[] =
|
||||
{ /* functions to identify and parse each type of obj */
|
||||
[Obj68020] "68020 .2", _is2, _read2,
|
||||
[ObjAmd64] "amd64 .6", _is6, _read6,
|
||||
[ObjArm] "arm .5", _is5, _read5,
|
||||
[ObjAlpha] "alpha .7", _is7, _read7,
|
||||
[Obj386] "386 .8", _is8, _read8,
|
||||
[ObjSparc] "sparc .k", _isk, _readk,
|
||||
[ObjPower] "power .q", _isq, _readq,
|
||||
[ObjMips] "mips .v", _isv, _readv,
|
||||
[ObjSparc64] "sparc64 .u", _isu, _readu,
|
||||
[ObjPower64] "power64 .9", _is9, _read9,
|
||||
[Maxobjtype] 0, 0
|
||||
};
|
||||
|
||||
struct Symtab
|
||||
{
|
||||
struct Sym s;
|
||||
struct Symtab *next;
|
||||
};
|
||||
|
||||
static Symtab *hash[NHASH];
|
||||
static Sym *names[NNAMES]; /* working set of active names */
|
||||
|
||||
static int processprog(Prog*,int); /* decode each symbol reference */
|
||||
static void objreset(void);
|
||||
static void objlookup(int, char *, int, uint);
|
||||
static void objupdate(int, int);
|
||||
|
||||
int
|
||||
objtype(Biobuf *bp, char **name)
|
||||
{
|
||||
int i;
|
||||
char buf[MAXIS];
|
||||
|
||||
if(Bread(bp, buf, MAXIS) < MAXIS)
|
||||
return -1;
|
||||
Bseek(bp, -MAXIS, 1);
|
||||
for (i = 0; i < Maxobjtype; i++) {
|
||||
if (obj[i].is && (*obj[i].is)(buf)) {
|
||||
if (name)
|
||||
*name = obj[i].name;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
isar(Biobuf *bp)
|
||||
{
|
||||
int n;
|
||||
char magbuf[SARMAG];
|
||||
|
||||
n = Bread(bp, magbuf, SARMAG);
|
||||
if(n == SARMAG && strncmp(magbuf, ARMAG, SARMAG) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* determine what kind of object file this is and process it.
|
||||
* return whether or not this was a recognized intermediate file.
|
||||
*/
|
||||
int
|
||||
readobj(Biobuf *bp, int objtype)
|
||||
{
|
||||
Prog p;
|
||||
|
||||
if (objtype < 0 || objtype >= Maxobjtype || obj[objtype].is == 0)
|
||||
return 1;
|
||||
objreset();
|
||||
while ((*obj[objtype].read)(bp, &p))
|
||||
if (!processprog(&p, 1))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
readar(Biobuf *bp, int objtype, vlong end, int doautos)
|
||||
{
|
||||
Prog p;
|
||||
|
||||
if (objtype < 0 || objtype >= Maxobjtype || obj[objtype].is == 0)
|
||||
return 1;
|
||||
objreset();
|
||||
while ((*obj[objtype].read)(bp, &p) && Boffset(bp) < end)
|
||||
if (!processprog(&p, doautos))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* decode a symbol reference or definition
|
||||
*/
|
||||
static int
|
||||
processprog(Prog *p, int doautos)
|
||||
{
|
||||
if(p->kind == aNone)
|
||||
return 1;
|
||||
if(p->sym < 0 || p->sym >= NNAMES)
|
||||
return 0;
|
||||
switch(p->kind)
|
||||
{
|
||||
case aName:
|
||||
if (!doautos)
|
||||
if(p->type != 'U' && p->type != 'b')
|
||||
break;
|
||||
objlookup(p->sym, p->id, p->type, p->sig);
|
||||
break;
|
||||
case aText:
|
||||
objupdate(p->sym, 'T');
|
||||
break;
|
||||
case aData:
|
||||
objupdate(p->sym, 'D');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* find the entry for s in the symbol array.
|
||||
* make a new entry if it is not already there.
|
||||
*/
|
||||
static void
|
||||
objlookup(int id, char *name, int type, uint sig)
|
||||
{
|
||||
long h;
|
||||
char *cp;
|
||||
Sym *s;
|
||||
Symtab *sp;
|
||||
|
||||
s = names[id];
|
||||
if(s && strcmp(s->name, name) == 0) {
|
||||
s->type = type;
|
||||
s->sig = sig;
|
||||
return;
|
||||
}
|
||||
|
||||
h = *name;
|
||||
for(cp = name+1; *cp; h += *cp++)
|
||||
h *= HASHMUL;
|
||||
if(h < 0)
|
||||
h = ~h;
|
||||
h &= (NHASH-1);
|
||||
if (type == 'U' || type == 'b' || islocal(type)) {
|
||||
for(sp = hash[h]; sp; sp = sp->next)
|
||||
if(strcmp(sp->s.name, name) == 0) {
|
||||
switch(sp->s.type) {
|
||||
case 'T':
|
||||
case 'D':
|
||||
case 'U':
|
||||
if (type == 'U') {
|
||||
names[id] = &sp->s;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
case 'd':
|
||||
case 'b':
|
||||
if (type == 'b') {
|
||||
names[id] = &sp->s;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
case 'p':
|
||||
if (islocal(type)) {
|
||||
names[id] = &sp->s;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
sp = malloc(sizeof(Symtab));
|
||||
sp->s.name = name;
|
||||
sp->s.type = type;
|
||||
sp->s.sig = sig;
|
||||
sp->s.value = islocal(type) ? MAXOFF : 0;
|
||||
names[id] = &sp->s;
|
||||
sp->next = hash[h];
|
||||
hash[h] = sp;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* traverse the symbol lists
|
||||
*/
|
||||
void
|
||||
objtraverse(void (*fn)(Sym*, void*), void *pointer)
|
||||
{
|
||||
int i;
|
||||
Symtab *s;
|
||||
|
||||
for(i = 0; i < NHASH; i++)
|
||||
for(s = hash[i]; s; s = s->next)
|
||||
(*fn)(&s->s, pointer);
|
||||
}
|
||||
|
||||
/*
|
||||
* update the offset information for a 'a' or 'p' symbol in an intermediate file
|
||||
*/
|
||||
void
|
||||
_offset(int id, vlong off)
|
||||
{
|
||||
Sym *s;
|
||||
|
||||
s = names[id];
|
||||
if (s && s->name[0] && islocal(s->type) && s->value > off)
|
||||
s->value = off;
|
||||
}
|
||||
|
||||
/*
|
||||
* update the type of a global text or data symbol
|
||||
*/
|
||||
static void
|
||||
objupdate(int id, int type)
|
||||
{
|
||||
Sym *s;
|
||||
|
||||
s = names[id];
|
||||
if (s && s->name[0])
|
||||
if (s->type == 'U')
|
||||
s->type = type;
|
||||
else if (s->type == 'b')
|
||||
s->type = tolower(type);
|
||||
}
|
||||
|
||||
/*
|
||||
* look for the next file in an archive
|
||||
*/
|
||||
int
|
||||
nextar(Biobuf *bp, int offset, char *buf)
|
||||
{
|
||||
struct ar_hdr a;
|
||||
int i, r;
|
||||
long arsize;
|
||||
|
||||
if (offset&01)
|
||||
offset++;
|
||||
Bseek(bp, offset, 0);
|
||||
r = Bread(bp, &a, SAR_HDR);
|
||||
if(r != SAR_HDR)
|
||||
return 0;
|
||||
if(strncmp(a.fmag, ARFMAG, sizeof(a.fmag)))
|
||||
return -1;
|
||||
for(i=0; i<sizeof(a.name) && i<SARNAME && a.name[i] != ' '; i++)
|
||||
buf[i] = a.name[i];
|
||||
buf[i] = 0;
|
||||
arsize = strtol(a.size, 0, 0);
|
||||
if (arsize&1)
|
||||
arsize++;
|
||||
return arsize + SAR_HDR;
|
||||
}
|
||||
|
||||
static void
|
||||
objreset(void)
|
||||
{
|
||||
int i;
|
||||
Symtab *s, *n;
|
||||
|
||||
for(i = 0; i < NHASH; i++) {
|
||||
for(s = hash[i]; s; s = n) {
|
||||
n = s->next;
|
||||
free(s->s.name);
|
||||
free(s);
|
||||
}
|
||||
hash[i] = 0;
|
||||
}
|
||||
memset(names, 0, sizeof names);
|
||||
}
|
53
src/libmachamd64/obj.h
Normal file
53
src/libmachamd64/obj.h
Normal file
@ -0,0 +1,53 @@
|
||||
// Inferno libmach/obj.h
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/obj.h
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
/*
|
||||
* obj.h -- defs for dealing with object files
|
||||
*/
|
||||
|
||||
typedef enum Kind /* variable defs and references in obj */
|
||||
{
|
||||
aNone, /* we don't care about this prog */
|
||||
aName, /* introduces a name */
|
||||
aText, /* starts a function */
|
||||
aData, /* references to a global object */
|
||||
} Kind;
|
||||
|
||||
typedef struct Prog Prog;
|
||||
|
||||
struct Prog /* info from .$O files */
|
||||
{
|
||||
Kind kind; /* what kind of symbol */
|
||||
char type; /* type of the symbol: ie, 'T', 'a', etc. */
|
||||
char sym; /* index of symbol's name */
|
||||
char *id; /* name for the symbol, if it introduces one */
|
||||
uint sig; /* type signature for symbol */
|
||||
};
|
||||
|
||||
#define UNKNOWN '?'
|
||||
void _offset(int, vlong);
|
203
src/libmachamd64/setmach.c
Normal file
203
src/libmachamd64/setmach.c
Normal file
@ -0,0 +1,203 @@
|
||||
// Inferno libmach/setmach.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/setmach.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <mach_amd64.h>
|
||||
/* table for selecting machine-dependent parameters */
|
||||
|
||||
typedef struct machtab Machtab;
|
||||
|
||||
struct machtab
|
||||
{
|
||||
char *name; /* machine name */
|
||||
short type; /* executable type */
|
||||
short boottype; /* bootable type */
|
||||
int asstype; /* disassembler code */
|
||||
Mach *mach; /* machine description */
|
||||
Machdata *machdata; /* machine functions */
|
||||
};
|
||||
|
||||
/*
|
||||
extern Mach mmips, msparc, m68020, mi386, mamd64,
|
||||
marm, mmips2be, mmips2le, mpower, mpower64, malpha, msparc64;
|
||||
extern Machdata mipsmach, sparcmach, m68020mach, i386mach,
|
||||
armmach, mipsmach2le, powermach, alphamach, sparc64mach;
|
||||
*/
|
||||
extern Mach mi386, mamd64;
|
||||
extern Machdata i386mach;
|
||||
|
||||
/*
|
||||
* machine selection table. machines with native disassemblers should
|
||||
* follow the plan 9 variant in the table; native modes are selectable
|
||||
* only by name.
|
||||
*/
|
||||
Machtab machines[] =
|
||||
{
|
||||
{ "386", /*plan 9 386*/
|
||||
FI386,
|
||||
FI386B,
|
||||
AI386,
|
||||
&mi386,
|
||||
&i386mach, },
|
||||
{ "amd64", /*amd64*/
|
||||
FAMD64,
|
||||
FAMD64B,
|
||||
AAMD64,
|
||||
&mamd64,
|
||||
&i386mach, },
|
||||
#ifdef unused
|
||||
{ "68020", /*68020*/
|
||||
F68020,
|
||||
F68020B,
|
||||
A68020,
|
||||
&m68020,
|
||||
&m68020mach, },
|
||||
{ "68020", /*Next 68040 bootable*/
|
||||
F68020,
|
||||
FNEXTB,
|
||||
A68020,
|
||||
&m68020,
|
||||
&m68020mach, },
|
||||
{ "mips2LE", /*plan 9 mips2 little endian*/
|
||||
FMIPS2LE,
|
||||
0,
|
||||
AMIPS,
|
||||
&mmips2le,
|
||||
&mipsmach2le, },
|
||||
{ "mips", /*plan 9 mips*/
|
||||
FMIPS,
|
||||
FMIPSB,
|
||||
AMIPS,
|
||||
&mmips,
|
||||
&mipsmach, },
|
||||
{ "mips2", /*plan 9 mips2*/
|
||||
FMIPS2BE,
|
||||
FMIPSB,
|
||||
AMIPS,
|
||||
&mmips2be,
|
||||
&mipsmach, }, /* shares debuggers with native mips */
|
||||
{ "mipsco", /*native mips - must follow plan 9*/
|
||||
FMIPS,
|
||||
FMIPSB,
|
||||
AMIPSCO,
|
||||
&mmips,
|
||||
&mipsmach, },
|
||||
{ "sparc", /*plan 9 sparc */
|
||||
FSPARC,
|
||||
FSPARCB,
|
||||
ASPARC,
|
||||
&msparc,
|
||||
&sparcmach, },
|
||||
{ "sunsparc", /*native sparc - must follow plan 9*/
|
||||
FSPARC,
|
||||
FSPARCB,
|
||||
ASUNSPARC,
|
||||
&msparc,
|
||||
&sparcmach, },
|
||||
{ "86", /*8086 - a peach of a machine*/
|
||||
FI386,
|
||||
FI386B,
|
||||
AI8086,
|
||||
&mi386,
|
||||
&i386mach, },
|
||||
{ "arm", /*ARM*/
|
||||
FARM,
|
||||
FARMB,
|
||||
AARM,
|
||||
&marm,
|
||||
&armmach, },
|
||||
{ "power", /*PowerPC*/
|
||||
FPOWER,
|
||||
FPOWERB,
|
||||
APOWER,
|
||||
&mpower,
|
||||
&powermach, },
|
||||
{ "power64", /*PowerPC*/
|
||||
FPOWER64,
|
||||
FPOWER64B,
|
||||
APOWER64,
|
||||
&mpower64,
|
||||
&powermach, },
|
||||
{ "alpha", /*Alpha*/
|
||||
FALPHA,
|
||||
FALPHAB,
|
||||
AALPHA,
|
||||
&malpha,
|
||||
&alphamach, },
|
||||
{ "sparc64", /*plan 9 sparc64 */
|
||||
FSPARC64,
|
||||
FSPARCB, /* XXX? */
|
||||
ASPARC64,
|
||||
&msparc64,
|
||||
&sparc64mach, },
|
||||
#endif
|
||||
{ 0 }, /*the terminator*/
|
||||
};
|
||||
|
||||
/*
|
||||
* select a machine by executable file type
|
||||
*/
|
||||
void
|
||||
machbytype(int type)
|
||||
{
|
||||
Machtab *mp;
|
||||
|
||||
for (mp = machines; mp->name; mp++){
|
||||
if (mp->type == type || mp->boottype == type) {
|
||||
asstype = mp->asstype;
|
||||
machdata = mp->machdata;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* select a machine by name
|
||||
*/
|
||||
int
|
||||
machbyname(char *name)
|
||||
{
|
||||
Machtab *mp;
|
||||
|
||||
if (!name) {
|
||||
asstype = AAMD64;
|
||||
machdata = &i386mach;
|
||||
mach = &mamd64;
|
||||
return 1;
|
||||
}
|
||||
for (mp = machines; mp->name; mp++){
|
||||
if (strcmp(mp->name, name) == 0) {
|
||||
asstype = mp->asstype;
|
||||
machdata = mp->machdata;
|
||||
mach = mp->mach;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
107
src/libmachamd64/swap.c
Normal file
107
src/libmachamd64/swap.c
Normal file
@ -0,0 +1,107 @@
|
||||
// Inferno libmach/swap.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/swap.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc.
|
||||
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited.
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include <u.h>
|
||||
|
||||
/*
|
||||
* big-endian short
|
||||
*/
|
||||
ushort
|
||||
beswab(ushort s)
|
||||
{
|
||||
uchar *p;
|
||||
|
||||
p = (uchar*)&s;
|
||||
return (p[0]<<8) | p[1];
|
||||
}
|
||||
|
||||
/*
|
||||
* big-endian long
|
||||
*/
|
||||
ulong
|
||||
beswal(ulong l)
|
||||
{
|
||||
uchar *p;
|
||||
|
||||
p = (uchar*)&l;
|
||||
return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
|
||||
}
|
||||
|
||||
/*
|
||||
* big-endian vlong
|
||||
*/
|
||||
uvlong
|
||||
beswav(uvlong v)
|
||||
{
|
||||
uchar *p;
|
||||
|
||||
p = (uchar*)&v;
|
||||
return ((uvlong)p[0]<<56) | ((uvlong)p[1]<<48) | ((uvlong)p[2]<<40)
|
||||
| ((uvlong)p[3]<<32) | ((uvlong)p[4]<<24)
|
||||
| ((uvlong)p[5]<<16) | ((uvlong)p[6]<<8)
|
||||
| (uvlong)p[7];
|
||||
}
|
||||
|
||||
/*
|
||||
* little-endian short
|
||||
*/
|
||||
ushort
|
||||
leswab(ushort s)
|
||||
{
|
||||
uchar *p;
|
||||
|
||||
p = (uchar*)&s;
|
||||
return (p[1]<<8) | p[0];
|
||||
}
|
||||
|
||||
/*
|
||||
* little-endian long
|
||||
*/
|
||||
ulong
|
||||
leswal(ulong l)
|
||||
{
|
||||
uchar *p;
|
||||
|
||||
p = (uchar*)&l;
|
||||
return (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0];
|
||||
}
|
||||
|
||||
/*
|
||||
* little-endian vlong
|
||||
*/
|
||||
uvlong
|
||||
leswav(uvlong v)
|
||||
{
|
||||
uchar *p;
|
||||
|
||||
p = (uchar*)&v;
|
||||
return ((uvlong)p[7]<<56) | ((uvlong)p[6]<<48) | ((uvlong)p[5]<<40)
|
||||
| ((uvlong)p[4]<<32) | ((uvlong)p[3]<<24)
|
||||
| ((uvlong)p[2]<<16) | ((uvlong)p[1]<<8)
|
||||
| (uvlong)p[0];
|
||||
}
|
1402
src/libmachamd64/sym.c
Normal file
1402
src/libmachamd64/sym.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
for i in lib9 libbio
|
||||
for i in lib9 libbio libmach_amd64
|
||||
do
|
||||
cd $i
|
||||
make install
|
||||
|
Loading…
Reference in New Issue
Block a user