13e12c5d1SDavid du Colombier /* 2219b2ee8SDavid du Colombier * Architecture-dependent application data 33e12c5d1SDavid du Colombier */ 43e12c5d1SDavid du Colombier #include "a.out.h" 5219b2ee8SDavid du Colombier #pragma src "/sys/src/libmach" 63e12c5d1SDavid du Colombier #pragma lib "libmach.a" 73e12c5d1SDavid du Colombier /* 8bd389b36SDavid du Colombier * Supported architectures: 9bd389b36SDavid du Colombier * mips, 10bd389b36SDavid du Colombier * 68020, 11bd389b36SDavid du Colombier * i386, 12bd389b36SDavid du Colombier * sparc, 13bd389b36SDavid du Colombier * i960 (limited) 14219b2ee8SDavid du Colombier * 3210DSP (limited) 15*7dd7cddfSDavid du Colombier * mips2 (R4000) 16*7dd7cddfSDavid du Colombier * arm (limited) 17*7dd7cddfSDavid du Colombier * power pc (limited) 183e12c5d1SDavid du Colombier */ 193e12c5d1SDavid du Colombier enum 203e12c5d1SDavid du Colombier { 213e12c5d1SDavid du Colombier MMIPS, /* machine types */ 223e12c5d1SDavid du Colombier MSPARC, 233e12c5d1SDavid du Colombier M68020, 243e12c5d1SDavid du Colombier MI386, 253e12c5d1SDavid du Colombier MI960, 26219b2ee8SDavid du Colombier M3210, 27*7dd7cddfSDavid du Colombier MMIPS2, 28*7dd7cddfSDavid du Colombier NMIPS2, 29*7dd7cddfSDavid du Colombier M29000, 30*7dd7cddfSDavid du Colombier MARM, 31*7dd7cddfSDavid du Colombier MPOWER, 32*7dd7cddfSDavid du Colombier MALPHA, 33*7dd7cddfSDavid du Colombier /* types of executables */ 34219b2ee8SDavid du Colombier FNONE = 0, /* unidentified */ 353e12c5d1SDavid du Colombier FMIPS, /* v.out */ 363e12c5d1SDavid du Colombier FMIPSB, /* mips bootable */ 373e12c5d1SDavid du Colombier FSPARC, /* k.out */ 383e12c5d1SDavid du Colombier FSPARCB, /* Sparc bootable */ 393e12c5d1SDavid du Colombier F68020, /* 2.out */ 403e12c5d1SDavid du Colombier F68020B, /* 68020 bootable */ 413e12c5d1SDavid du Colombier FNEXTB, /* Next bootable */ 423e12c5d1SDavid du Colombier FI386, /* 8.out */ 433e12c5d1SDavid du Colombier FI386B, /* I386 bootable */ 443e12c5d1SDavid du Colombier FI960, /* 6.out */ 453e12c5d1SDavid du Colombier FI960B, /* I960 bootable */ 46219b2ee8SDavid du Colombier F3210, /* x.out */ 47*7dd7cddfSDavid du Colombier FMIPS2BE, /* 4.out */ 48*7dd7cddfSDavid du Colombier F29000, /* 9.out */ 49*7dd7cddfSDavid du Colombier FARM, /* 5.out */ 50*7dd7cddfSDavid du Colombier FARMB, /* ARM bootable */ 51*7dd7cddfSDavid du Colombier FPOWER, /* q.out */ 52*7dd7cddfSDavid du Colombier FPOWERB, /* power pc bootable */ 53*7dd7cddfSDavid du Colombier FMIPS2LE, /* 4k little endian */ 54*7dd7cddfSDavid du Colombier FALPHA, /* 7.out */ 55*7dd7cddfSDavid du Colombier FALPHAB, /* DEC Alpha bootable */ 563e12c5d1SDavid du Colombier 57219b2ee8SDavid du Colombier ANONE = 0, /* dissembler types */ 583e12c5d1SDavid du Colombier AMIPS, 593e12c5d1SDavid du Colombier AMIPSCO, /* native mips */ 603e12c5d1SDavid du Colombier ASPARC, 613e12c5d1SDavid du Colombier ASUNSPARC, /* native sun */ 623e12c5d1SDavid du Colombier A68020, 633e12c5d1SDavid du Colombier AI386, 643e12c5d1SDavid du Colombier AI8086, /* oh god */ 653e12c5d1SDavid du Colombier AI960, 66*7dd7cddfSDavid du Colombier A29000, 67*7dd7cddfSDavid du Colombier AARM, 68*7dd7cddfSDavid du Colombier APOWER, 69*7dd7cddfSDavid du Colombier AALPHA, 70bd389b36SDavid du Colombier /* object file types */ 71bd389b36SDavid du Colombier Obj68020 = 0, /* .2 */ 72219b2ee8SDavid du Colombier ObjSparc, /* .k */ 73219b2ee8SDavid du Colombier ObjMips, /* .v */ 74219b2ee8SDavid du Colombier Obj386, /* .8 */ 75219b2ee8SDavid du Colombier Obj960, /* .6 */ 76219b2ee8SDavid du Colombier Obj3210, /* .x */ 77*7dd7cddfSDavid du Colombier ObjMips2, /* .4 */ 78*7dd7cddfSDavid du Colombier Obj29000, /* .9 */ 79*7dd7cddfSDavid du Colombier ObjArm, /* .5 */ 80*7dd7cddfSDavid du Colombier ObjPower, /* .q */ 81*7dd7cddfSDavid du Colombier ObjMips2le, /* .0 */ 82*7dd7cddfSDavid du Colombier ObjAlpha, /* .7 */ 83219b2ee8SDavid du Colombier Maxobjtype, 843e12c5d1SDavid du Colombier 853e12c5d1SDavid du Colombier CNONE = 0, /* symbol table classes */ 86219b2ee8SDavid du Colombier CAUTO, 87219b2ee8SDavid du Colombier CPARAM, 88219b2ee8SDavid du Colombier CSTAB, 89219b2ee8SDavid du Colombier CTEXT, 90219b2ee8SDavid du Colombier CDATA, 91219b2ee8SDavid du Colombier CANY, /* to look for any class */ 923e12c5d1SDavid du Colombier }; 93219b2ee8SDavid du Colombier 94219b2ee8SDavid du Colombier typedef struct Map Map; 95219b2ee8SDavid du Colombier typedef struct Symbol Symbol; 96219b2ee8SDavid du Colombier typedef struct Reglist Reglist; 97219b2ee8SDavid du Colombier typedef struct Mach Mach; 98219b2ee8SDavid du Colombier typedef struct Machdata Machdata; 99219b2ee8SDavid du Colombier 1003e12c5d1SDavid du Colombier /* 101bd389b36SDavid du Colombier * Structure to map a segment to a position in a file 1023e12c5d1SDavid du Colombier */ 103219b2ee8SDavid du Colombier struct Map { 104219b2ee8SDavid du Colombier int nsegs; /* number of segments */ 105219b2ee8SDavid du Colombier struct segment { /* per-segment map */ 1063e12c5d1SDavid du Colombier char *name; /* the segment name */ 107*7dd7cddfSDavid du Colombier int fd; /* file descriptor */ 108bd389b36SDavid du Colombier int inuse; /* in use - not in use */ 1093e12c5d1SDavid du Colombier ulong b; /* base */ 1103e12c5d1SDavid du Colombier ulong e; /* end */ 1113e12c5d1SDavid du Colombier ulong f; /* offset within file */ 112219b2ee8SDavid du Colombier } seg[1]; /* actually n of these */ 113219b2ee8SDavid du Colombier }; 114*7dd7cddfSDavid du Colombier 115219b2ee8SDavid du Colombier /* 116219b2ee8SDavid du Colombier * Internal structure describing a symbol table entry 117219b2ee8SDavid du Colombier */ 118219b2ee8SDavid du Colombier struct Symbol { 119219b2ee8SDavid du Colombier void *handle; /* used internally - owning func */ 120219b2ee8SDavid du Colombier struct { 121219b2ee8SDavid du Colombier char *name; 122219b2ee8SDavid du Colombier long value; /* address or stack offset */ 123219b2ee8SDavid du Colombier char type; /* as in a.out.h */ 124219b2ee8SDavid du Colombier char class; /* as above */ 125219b2ee8SDavid du Colombier }; 1263e12c5d1SDavid du Colombier }; 127*7dd7cddfSDavid du Colombier 1283e12c5d1SDavid du Colombier /* 1293e12c5d1SDavid du Colombier * machine register description 1303e12c5d1SDavid du Colombier */ 131219b2ee8SDavid du Colombier struct Reglist { 1323e12c5d1SDavid du Colombier char *rname; /* register name */ 1333e12c5d1SDavid du Colombier short roffs; /* offset in u-block */ 134219b2ee8SDavid du Colombier char rflags; /* INTEGER/FLOAT, WRITABLE */ 135bd389b36SDavid du Colombier char rformat; /* print format: 'x', 'X', 'f', '8' */ 136219b2ee8SDavid du Colombier }; 137219b2ee8SDavid du Colombier 138219b2ee8SDavid du Colombier enum { /* bits in rflags field */ 139219b2ee8SDavid du Colombier RINT = (0<<0), 140219b2ee8SDavid du Colombier RFLT = (1<<0), 141219b2ee8SDavid du Colombier RRDONLY = (1<<1), 1423e12c5d1SDavid du Colombier }; 1433e12c5d1SDavid du Colombier /* 144219b2ee8SDavid du Colombier * Machine-dependent data is stored in two structures: 145219b2ee8SDavid du Colombier * Mach - miscellaneous general parameters 146219b2ee8SDavid du Colombier * Machdata - jump vector of service functions used by debuggers 147219b2ee8SDavid du Colombier * 148*7dd7cddfSDavid du Colombier * Mach is defined in 2.c, 4.c, v.c, k.c, 8.c, 6.c and set in executable.c 149219b2ee8SDavid du Colombier * 150*7dd7cddfSDavid du Colombier * Machdata is defined in 2db.c, 4db.c, vdb.c, kdb.c, 8db.c, and 6db.c 151219b2ee8SDavid du Colombier * and set in the debugger startup. 1523e12c5d1SDavid du Colombier */ 153219b2ee8SDavid du Colombier 154219b2ee8SDavid du Colombier 1553e12c5d1SDavid du Colombier struct Mach{ 1563e12c5d1SDavid du Colombier char *name; 157219b2ee8SDavid du Colombier int mtype; /* machine type code */ 1583e12c5d1SDavid du Colombier Reglist *reglist; /* register set */ 159*7dd7cddfSDavid du Colombier ulong regsize; /* sizeof registers in bytes*/ 160*7dd7cddfSDavid du Colombier ulong fpregsize; /* sizeof fp registers in bytes*/ 161219b2ee8SDavid du Colombier char *pc; /* pc name */ 162219b2ee8SDavid du Colombier char *sp; /* sp name */ 163219b2ee8SDavid du Colombier char *link; /* link register name */ 1643e12c5d1SDavid du Colombier char *sbreg; /* static base register name */ 165*7dd7cddfSDavid du Colombier ulong sb; /* static base register value */ 166*7dd7cddfSDavid du Colombier int pgsize; /* page size */ 167*7dd7cddfSDavid du Colombier ulong kbase; /* kernel base address */ 168*7dd7cddfSDavid du Colombier ulong ktmask; /* ktzero = kbase & ~ktmask */ 169*7dd7cddfSDavid du Colombier int pcquant; /* quantization of pc */ 1703e12c5d1SDavid du Colombier int szaddr; /* sizeof(void*) */ 1713e12c5d1SDavid du Colombier int szreg; /* sizeof(register) */ 1723e12c5d1SDavid du Colombier int szfloat; /* sizeof(float) */ 1733e12c5d1SDavid du Colombier int szdouble; /* sizeof(double) */ 1743e12c5d1SDavid du Colombier }; 1753e12c5d1SDavid du Colombier 1763e12c5d1SDavid du Colombier extern Mach *mach; /* Current machine */ 1773e12c5d1SDavid du Colombier 178*7dd7cddfSDavid du Colombier typedef vlong (*Rgetter)(Map*, char*); 179219b2ee8SDavid du Colombier typedef void (*Tracer)(Map*, ulong, ulong, Symbol*); 1803e12c5d1SDavid du Colombier 181219b2ee8SDavid du Colombier struct Machdata { /* Machine-dependent debugger support */ 1823e12c5d1SDavid du Colombier uchar bpinst[4]; /* break point instr. */ 1833e12c5d1SDavid du Colombier short bpsize; /* size of break point instr. */ 1843e12c5d1SDavid du Colombier 185219b2ee8SDavid du Colombier ushort (*swab)(ushort); /* short to local byte order */ 186219b2ee8SDavid du Colombier long (*swal)(long); /* long to local byte order */ 187*7dd7cddfSDavid du Colombier vlong (*swav)(vlong); /* vlong to local byte order */ 188219b2ee8SDavid du Colombier int (*ctrace)(Map*, ulong, ulong, ulong, Tracer); /* C traceback */ 189219b2ee8SDavid du Colombier ulong (*findframe)(Map*, ulong, ulong, ulong, ulong);/* frame finder */ 190219b2ee8SDavid du Colombier char* (*excep)(Map*, Rgetter); /* last exception */ 1913e12c5d1SDavid du Colombier ulong (*bpfix)(ulong); /* breakpoint fixup */ 192219b2ee8SDavid du Colombier int (*sftos)(char*, int, void*); /* single precision float */ 193219b2ee8SDavid du Colombier int (*dftos)(char*, int, void*); /* double precision float */ 194219b2ee8SDavid du Colombier int (*foll)(Map*, ulong, Rgetter, ulong*); /* follow set */ 195219b2ee8SDavid du Colombier int (*das)(Map*, ulong, char, char*, int); /* symbolic disassembly */ 196219b2ee8SDavid du Colombier int (*hexinst)(Map*, ulong, char*, int); /* hex disassembly */ 197219b2ee8SDavid du Colombier int (*instsize)(Map*, ulong); /* instruction size */ 1983e12c5d1SDavid du Colombier }; 1993e12c5d1SDavid du Colombier 2003e12c5d1SDavid du Colombier /* 201bd389b36SDavid du Colombier * Common a.out header describing all architectures 2023e12c5d1SDavid du Colombier */ 2033e12c5d1SDavid du Colombier typedef struct Fhdr 2043e12c5d1SDavid du Colombier { 2053e12c5d1SDavid du Colombier char *name; /* identifier of executable */ 2063e12c5d1SDavid du Colombier short type; /* file type - see codes above*/ 2073e12c5d1SDavid du Colombier short hdrsz; /* size of this header */ 2083e12c5d1SDavid du Colombier long magic; /* magic number */ 2093e12c5d1SDavid du Colombier long txtaddr; /* text address */ 2103e12c5d1SDavid du Colombier long entry; /* entry point */ 2113e12c5d1SDavid du Colombier long txtsz; /* text size */ 2123e12c5d1SDavid du Colombier long txtoff; /* start of text in file */ 2133e12c5d1SDavid du Colombier long dataddr; /* start of data segment */ 2143e12c5d1SDavid du Colombier long datsz; /* size of data seg */ 2153e12c5d1SDavid du Colombier long datoff; /* offset to data seg in file */ 2163e12c5d1SDavid du Colombier long bsssz; /* size of bss */ 2173e12c5d1SDavid du Colombier long symsz; /* size of symbol table */ 2183e12c5d1SDavid du Colombier long symoff; /* offset of symbol table in file */ 2193e12c5d1SDavid du Colombier long sppcsz; /* size of sp-pc table */ 2203e12c5d1SDavid du Colombier long sppcoff; /* offset of sp-pc table in file */ 2213e12c5d1SDavid du Colombier long lnpcsz; /* size of line number-pc table */ 2223e12c5d1SDavid du Colombier long lnpcoff; /* size of line number-pc table */ 2233e12c5d1SDavid du Colombier } Fhdr; 2243e12c5d1SDavid du Colombier 225219b2ee8SDavid du Colombier extern int asstype; /* dissembler type - machdata.c */ 226219b2ee8SDavid du Colombier extern Machdata *machdata; /* jump vector - machdata.c */ 2273e12c5d1SDavid du Colombier 228*7dd7cddfSDavid du Colombier Map* attachproc(int, int, int, Fhdr*); 229219b2ee8SDavid du Colombier int beieee80ftos(char*, int, void*); 230219b2ee8SDavid du Colombier int beieeesftos(char*, int, void*); 231219b2ee8SDavid du Colombier int beieeedftos(char*, int, void*); 2323e12c5d1SDavid du Colombier ushort beswab(ushort); 2333e12c5d1SDavid du Colombier long beswal(long); 234*7dd7cddfSDavid du Colombier vlong beswav(vlong); 235219b2ee8SDavid du Colombier int cisctrace(Map*, ulong, ulong, ulong, Tracer); 236219b2ee8SDavid du Colombier ulong ciscframe(Map*, ulong, ulong, ulong, ulong); 237219b2ee8SDavid du Colombier int crackhdr(int fd, Fhdr*); 2383e12c5d1SDavid du Colombier long file2pc(char*, ulong); 2393e12c5d1SDavid du Colombier int fileelem(Sym**, uchar *, char*, int); 2403e12c5d1SDavid du Colombier int fileline(char*, int, ulong); 241bd389b36SDavid du Colombier int filesym(int, char*, int); 2423e12c5d1SDavid du Colombier int findlocal(Symbol*, char*, Symbol*); 243219b2ee8SDavid du Colombier int findseg(Map*, char*); 2443e12c5d1SDavid du Colombier int findsym(long, int, Symbol *); 245219b2ee8SDavid du Colombier int fnbound(long, ulong*); 246219b2ee8SDavid du Colombier int fpformat(Map*, Reglist*, char*, int, int); 247219b2ee8SDavid du Colombier int get1(Map*, ulong, uchar*, int); 248219b2ee8SDavid du Colombier int get2(Map*, ulong, ushort*); 249219b2ee8SDavid du Colombier int get4(Map*, ulong, long*); 250*7dd7cddfSDavid du Colombier int get8(Map*, ulong, vlong*); 2513e12c5d1SDavid du Colombier int getauto(Symbol*, int, int, Symbol*); 2523e12c5d1SDavid du Colombier Sym* getsym(int); 2533e12c5d1SDavid du Colombier int globalsym(Symbol *, int); 254219b2ee8SDavid du Colombier char* _hexify(char*, ulong, int); 255219b2ee8SDavid du Colombier int ieeesftos(char*, int, ulong); 256219b2ee8SDavid du Colombier int ieeedftos(char*, int, ulong, ulong); 257bd389b36SDavid du Colombier int isar(Biobuf*); 258219b2ee8SDavid du Colombier int leieee80ftos(char*, int, void*); 259219b2ee8SDavid du Colombier int leieeesftos(char*, int, void*); 260219b2ee8SDavid du Colombier int leieeedftos(char*, int, void*); 2613e12c5d1SDavid du Colombier ushort leswab(ushort); 2623e12c5d1SDavid du Colombier long leswal(long); 263*7dd7cddfSDavid du Colombier vlong leswav(vlong); 264bd389b36SDavid du Colombier long line2addr(ulong, ulong, ulong); 2653e12c5d1SDavid du Colombier Map* loadmap(Map*, int, Fhdr*); 266219b2ee8SDavid du Colombier int localaddr(Map*, char*, char*, long*, Rgetter); 2673e12c5d1SDavid du Colombier int localsym(Symbol*, int); 2683e12c5d1SDavid du Colombier int lookup(char*, char*, Symbol*); 2693e12c5d1SDavid du Colombier void machbytype(int); 2703e12c5d1SDavid du Colombier int machbyname(char*); 271bd389b36SDavid du Colombier int nextar(Biobuf*, int, char*); 272*7dd7cddfSDavid du Colombier Map* newmap(Map*, int); 273219b2ee8SDavid du Colombier void objtraverse(void(*)(Sym*, void*), void*); 274219b2ee8SDavid du Colombier int objtype(Biobuf*, char**); 2753e12c5d1SDavid du Colombier long pc2sp(ulong); 2763e12c5d1SDavid du Colombier long pc2line(ulong); 277219b2ee8SDavid du Colombier int put1(Map*, ulong, uchar*, int); 278219b2ee8SDavid du Colombier int put2(Map*, ulong, ushort); 279219b2ee8SDavid du Colombier int put4(Map*, ulong, long); 280*7dd7cddfSDavid du Colombier int put8(Map*, ulong, vlong); 281219b2ee8SDavid du Colombier int readar(Biobuf*, int, int, int); 282bd389b36SDavid du Colombier int readobj(Biobuf*, int); 283219b2ee8SDavid du Colombier ulong riscframe(Map*, ulong, ulong, ulong, ulong); 284219b2ee8SDavid du Colombier int risctrace(Map*, ulong, ulong, ulong, Tracer); 285*7dd7cddfSDavid du Colombier int setmap(Map*, int, ulong, ulong, ulong, char*); 2863e12c5d1SDavid du Colombier Sym* symbase(long*); 2873e12c5d1SDavid du Colombier int syminit(int, Fhdr*); 288219b2ee8SDavid du Colombier int symoff(char*, int, long, int); 289219b2ee8SDavid du Colombier void textseg(ulong, Fhdr*); 2903e12c5d1SDavid du Colombier int textsym(Symbol*, int); 2913e12c5d1SDavid du Colombier void unusemap(Map*, int); 292