// 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 */ typedef struct Exec Exec; struct Exec { int32 magic; /* magic number */ int32 text; /* size of text segment */ int32 data; /* size of initialized data */ int32 bss; /* size of uninitialized data */ int32 syms; /* size of symbol table */ int32 entry; /* entry point */ int32 spsz; /* size of pc/sp offset table */ int32 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; vlong gotype; int sequence; // order in file }; /* * 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; typedef struct Seg Seg; typedef int Maprw(Map *m, Seg *s, uvlong addr, void *v, uint n, int isread); struct Seg { 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 */ Maprw *rw; /* read/write fn for seg */ }; /* * Structure to map a segment to data */ struct Map { int pid; int tid; int nsegs; /* number of segments */ Seg 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 */ int32 regsize; /* sizeof registers in bytes */ int32 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 */ uint32 (*swal)(uint32); /* uint32 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 */ uint32 (*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; int32 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 */ int32 txtsz; /* text size */ int32 datsz; /* size of data seg */ int32 bsssz; /* size of bss */ int32 symsz; /* size of symbol table */ int32 sppcsz; /* size of sp-pc table */ int32 lnpcsz; /* size of line number-pc table */ } Fhdr; extern int asstype; /* dissembler type - machdata.c */ extern Machdata *machdata; /* jump vector - machdata.c */ int beieee80ftos(char*, int, void*); int beieeesftos(char*, int, void*); int beieeedftos(char*, int, void*); ushort beswab(ushort); uint32 beswal(uint32); 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*, int32); int fileelem(Sym**, uchar *, char*, int); int32 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, uint32*); 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*, uint32, int); int ieeesftos(char*, int, uint32); int ieeedftos(char*, int, uint32, uint32); int isar(Biobuf*); int leieee80ftos(char*, int, void*); int leieeesftos(char*, int, void*); int leieeedftos(char*, int, void*); ushort leswab(ushort); uint32 leswal(uint32); uvlong leswav(uvlong); uvlong line2addr(int32, 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); int32 pc2line(uvlong); int put1(Map*, uvlong, uchar*, int); int put2(Map*, uvlong, ushort); int put4(Map*, uvlong, uint32); 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*, Maprw *rw); Sym* symbase(int32*); int syminit(int, Fhdr*); int symoff(char*, int, uvlong, int); void textseg(uvlong, Fhdr*); int textsym(Symbol*, int); void unusemap(Map*, int); Map* attachproc(int pid, Fhdr *fp); int ctlproc(int pid, char *msg); void detachproc(Map *m); int procnotes(int pid, char ***pnotes); char* proctextfile(int pid); int procthreadpids(int pid, int *tid, int ntid); char* procstatus(int); Maprw fdrw;