| // 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 */ | |
| FWINPE, /* windows PE executable */ | |
| 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; |