13e12c5d1SDavid du Colombier /* 2*219b2ee8SDavid du Colombier * Architecture-dependent application data 33e12c5d1SDavid du Colombier */ 43e12c5d1SDavid du Colombier #include "a.out.h" 5*219b2ee8SDavid 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) 14*219b2ee8SDavid du Colombier * 3210DSP (limited) 153e12c5d1SDavid du Colombier */ 163e12c5d1SDavid du Colombier enum 173e12c5d1SDavid du Colombier { 183e12c5d1SDavid du Colombier MMIPS, /* machine types */ 193e12c5d1SDavid du Colombier MSPARC, 203e12c5d1SDavid du Colombier M68020, 213e12c5d1SDavid du Colombier MI386, 223e12c5d1SDavid du Colombier MI960, 23*219b2ee8SDavid du Colombier M3210, 243e12c5d1SDavid du Colombier /* types of exectables */ 25*219b2ee8SDavid du Colombier FNONE = 0, /* unidentified */ 263e12c5d1SDavid du Colombier FMIPS, /* v.out */ 273e12c5d1SDavid du Colombier FMIPSB, /* mips bootable */ 283e12c5d1SDavid du Colombier FSPARC, /* k.out */ 293e12c5d1SDavid du Colombier FSPARCB, /* Sparc bootable */ 303e12c5d1SDavid du Colombier F68020, /* 2.out */ 313e12c5d1SDavid du Colombier F68020B, /* 68020 bootable */ 323e12c5d1SDavid du Colombier FNEXTB, /* Next bootable */ 333e12c5d1SDavid du Colombier FI386, /* 8.out */ 343e12c5d1SDavid du Colombier FI386B, /* I386 bootable */ 353e12c5d1SDavid du Colombier FI960, /* 6.out */ 363e12c5d1SDavid du Colombier FI960B, /* I960 bootable */ 37*219b2ee8SDavid du Colombier F3210, /* x.out */ 383e12c5d1SDavid du Colombier 39*219b2ee8SDavid du Colombier ANONE = 0, /* dissembler types */ 403e12c5d1SDavid du Colombier AMIPS, 413e12c5d1SDavid du Colombier AMIPSCO, /* native mips */ 423e12c5d1SDavid du Colombier ASPARC, 433e12c5d1SDavid du Colombier ASUNSPARC, /* native sun */ 443e12c5d1SDavid du Colombier A68020, 453e12c5d1SDavid du Colombier AI386, 463e12c5d1SDavid du Colombier AI8086, /* oh god */ 473e12c5d1SDavid du Colombier AI960, 48bd389b36SDavid du Colombier /* object file types */ 49bd389b36SDavid du Colombier Obj68020 = 0, /* .2 */ 50*219b2ee8SDavid du Colombier ObjSparc, /* .k */ 51*219b2ee8SDavid du Colombier ObjMips, /* .v */ 52*219b2ee8SDavid du Colombier Obj386, /* .8 */ 53*219b2ee8SDavid du Colombier Obj960, /* .6 */ 54*219b2ee8SDavid du Colombier Obj3210, /* .x */ 55*219b2ee8SDavid du Colombier Maxobjtype, 563e12c5d1SDavid du Colombier 573e12c5d1SDavid du Colombier CNONE = 0, /* symbol table classes */ 58*219b2ee8SDavid du Colombier CAUTO, 59*219b2ee8SDavid du Colombier CPARAM, 60*219b2ee8SDavid du Colombier CSTAB, 61*219b2ee8SDavid du Colombier CTEXT, 62*219b2ee8SDavid du Colombier CDATA, 63*219b2ee8SDavid du Colombier CANY, /* to look for any class */ 643e12c5d1SDavid du Colombier }; 65*219b2ee8SDavid du Colombier 66*219b2ee8SDavid du Colombier typedef struct Map Map; 67*219b2ee8SDavid du Colombier typedef struct Symbol Symbol; 68*219b2ee8SDavid du Colombier typedef struct Reglist Reglist; 69*219b2ee8SDavid du Colombier typedef struct Mach Mach; 70*219b2ee8SDavid du Colombier typedef struct Machdata Machdata; 71*219b2ee8SDavid du Colombier 723e12c5d1SDavid du Colombier /* 73bd389b36SDavid du Colombier * Structure to map a segment to a position in a file 743e12c5d1SDavid du Colombier */ 75*219b2ee8SDavid du Colombier struct Map { 76*219b2ee8SDavid du Colombier int fd; /* file descriptor */ 77*219b2ee8SDavid du Colombier int nsegs; /* number of segments */ 78*219b2ee8SDavid du Colombier struct segment { /* per-segment map */ 793e12c5d1SDavid du Colombier char *name; /* the segment name */ 80bd389b36SDavid du Colombier int inuse; /* in use - not in use */ 813e12c5d1SDavid du Colombier ulong b; /* base */ 823e12c5d1SDavid du Colombier ulong e; /* end */ 833e12c5d1SDavid du Colombier ulong f; /* offset within file */ 84*219b2ee8SDavid du Colombier } seg[1]; /* actually n of these */ 85*219b2ee8SDavid du Colombier }; 86*219b2ee8SDavid du Colombier /* 87*219b2ee8SDavid du Colombier * Internal structure describing a symbol table entry 88*219b2ee8SDavid du Colombier */ 89*219b2ee8SDavid du Colombier 90*219b2ee8SDavid du Colombier struct Symbol { 91*219b2ee8SDavid du Colombier void *handle; /* used internally - owning func */ 92*219b2ee8SDavid du Colombier struct { 93*219b2ee8SDavid du Colombier char *name; 94*219b2ee8SDavid du Colombier long value; /* address or stack offset */ 95*219b2ee8SDavid du Colombier char type; /* as in a.out.h */ 96*219b2ee8SDavid du Colombier char class; /* as above */ 97*219b2ee8SDavid du Colombier }; 983e12c5d1SDavid du Colombier }; 993e12c5d1SDavid du Colombier /* 1003e12c5d1SDavid du Colombier * machine register description 1013e12c5d1SDavid du Colombier */ 1023e12c5d1SDavid du Colombier 103*219b2ee8SDavid du Colombier struct Reglist { 1043e12c5d1SDavid du Colombier char *rname; /* register name */ 1053e12c5d1SDavid du Colombier short roffs; /* offset in u-block */ 106*219b2ee8SDavid du Colombier char rflags; /* INTEGER/FLOAT, WRITABLE */ 107bd389b36SDavid du Colombier char rformat; /* print format: 'x', 'X', 'f', '8' */ 108*219b2ee8SDavid du Colombier ulong raddr; /* fixed-up register addr */ 109*219b2ee8SDavid du Colombier long rdelta; /* fix-up to register value */ 110*219b2ee8SDavid du Colombier }; 111*219b2ee8SDavid du Colombier 112*219b2ee8SDavid du Colombier enum { /* bits in rflags field */ 113*219b2ee8SDavid du Colombier RINT = (0<<0), 114*219b2ee8SDavid du Colombier RFLT = (1<<0), 115*219b2ee8SDavid du Colombier RRDONLY = (1<<1), 1163e12c5d1SDavid du Colombier }; 1173e12c5d1SDavid du Colombier /* 118*219b2ee8SDavid du Colombier * Machine-dependent data is stored in two structures: 119*219b2ee8SDavid du Colombier * Mach - miscellaneous general parameters 120*219b2ee8SDavid du Colombier * Machdata - jump vector of service functions used by debuggers 121*219b2ee8SDavid du Colombier * 122*219b2ee8SDavid du Colombier * Mach is defined in 2.c, v.c, k.c, 8.c, 6.c and set in executable.c 123*219b2ee8SDavid du Colombier * 124*219b2ee8SDavid du Colombier * Machdata is defined in 68020.c, mips.c, sparc.c, 386.c, and 960.c 125*219b2ee8SDavid du Colombier * and set in the debugger startup. 1263e12c5d1SDavid du Colombier */ 127*219b2ee8SDavid du Colombier 128*219b2ee8SDavid du Colombier 1293e12c5d1SDavid du Colombier struct Mach{ 1303e12c5d1SDavid du Colombier char *name; 131*219b2ee8SDavid du Colombier int mtype; /* machine type code */ 1323e12c5d1SDavid du Colombier Reglist *reglist; /* register set */ 1333e12c5d1SDavid du Colombier int minreg; /* minimum register */ 1343e12c5d1SDavid du Colombier int maxreg; /* maximum register */ 135*219b2ee8SDavid du Colombier char *pc; /* pc name */ 136*219b2ee8SDavid du Colombier char *sp; /* sp name */ 137*219b2ee8SDavid du Colombier char *link; /* link register name */ 138bd389b36SDavid du Colombier ulong retreg; /* function return register */ 1393e12c5d1SDavid du Colombier int pgsize; /* page size */ 1403e12c5d1SDavid du Colombier ulong kbase; /* kernel base address: uarea */ 1413e12c5d1SDavid du Colombier ulong ktmask; /* ktzero = kbase & ~ktmask */ 1423e12c5d1SDavid du Colombier ulong kspoff; /* offset of ksp in /proc/proc */ 1433e12c5d1SDavid du Colombier ulong kspdelta; /* correction to ksp value */ 1443e12c5d1SDavid du Colombier ulong kpcoff; /* offset of kpc in /proc/proc */ 1453e12c5d1SDavid du Colombier ulong kpcdelta; /* correction to kpc value */ 1463e12c5d1SDavid du Colombier ulong scalloff; /* offset to sys call # in ublk */ 1473e12c5d1SDavid du Colombier int pcquant; /* quantization of pc */ 1483e12c5d1SDavid du Colombier char *sbreg; /* static base register name */ 1493e12c5d1SDavid du Colombier ulong sb; /* value */ 1503e12c5d1SDavid du Colombier int szaddr; /* sizeof(void*) */ 1513e12c5d1SDavid du Colombier int szreg; /* sizeof(register) */ 1523e12c5d1SDavid du Colombier int szfloat; /* sizeof(float) */ 1533e12c5d1SDavid du Colombier int szdouble; /* sizeof(double) */ 1543e12c5d1SDavid du Colombier }; 1553e12c5d1SDavid du Colombier 1563e12c5d1SDavid du Colombier extern Mach *mach; /* Current machine */ 1573e12c5d1SDavid du Colombier 158*219b2ee8SDavid du Colombier typedef ulong (*Rgetter)(Map*, char*); 159*219b2ee8SDavid du Colombier typedef void (*Tracer)(Map*, ulong, ulong, Symbol*); 1603e12c5d1SDavid du Colombier 161*219b2ee8SDavid du Colombier struct Machdata { /* Machine-dependent debugger support */ 1623e12c5d1SDavid du Colombier uchar bpinst[4]; /* break point instr. */ 1633e12c5d1SDavid du Colombier short bpsize; /* size of break point instr. */ 1643e12c5d1SDavid du Colombier 165*219b2ee8SDavid du Colombier ushort (*swab)(ushort); /* short to local byte order */ 166*219b2ee8SDavid du Colombier long (*swal)(long); /* long to local byte order */ 167*219b2ee8SDavid du Colombier int (*ctrace)(Map*, ulong, ulong, ulong, Tracer); /* C traceback */ 168*219b2ee8SDavid du Colombier ulong (*findframe)(Map*, ulong, ulong, ulong, ulong);/* frame finder */ 169*219b2ee8SDavid du Colombier int (*ufixup)(Map*, long*); /* fixup to ublock base */ 170*219b2ee8SDavid du Colombier char* (*excep)(Map*, Rgetter); /* last exception */ 1713e12c5d1SDavid du Colombier ulong (*bpfix)(ulong); /* breakpoint fixup */ 172*219b2ee8SDavid du Colombier int (*sftos)(char*, int, void*); /* single precision float */ 173*219b2ee8SDavid du Colombier int (*dftos)(char*, int, void*); /* double precision float */ 174*219b2ee8SDavid du Colombier int (*foll)(Map*, ulong, Rgetter, ulong*); /* follow set */ 175*219b2ee8SDavid du Colombier int (*das)(Map*, ulong, char, char*, int); /* symbolic disassembly */ 176*219b2ee8SDavid du Colombier int (*hexinst)(Map*, ulong, char*, int); /* hex disassembly */ 177*219b2ee8SDavid du Colombier int (*instsize)(Map*, ulong); /* instruction size */ 1783e12c5d1SDavid du Colombier }; 1793e12c5d1SDavid du Colombier 1803e12c5d1SDavid du Colombier /* 181bd389b36SDavid du Colombier * Common a.out header describing all architectures 1823e12c5d1SDavid du Colombier */ 1833e12c5d1SDavid du Colombier typedef struct Fhdr 1843e12c5d1SDavid du Colombier { 1853e12c5d1SDavid du Colombier char *name; /* identifier of executable */ 1863e12c5d1SDavid du Colombier short type; /* file type - see codes above*/ 1873e12c5d1SDavid du Colombier short hdrsz; /* size of this header */ 1883e12c5d1SDavid du Colombier long magic; /* magic number */ 1893e12c5d1SDavid du Colombier long txtaddr; /* text address */ 1903e12c5d1SDavid du Colombier long entry; /* entry point */ 1913e12c5d1SDavid du Colombier long txtsz; /* text size */ 1923e12c5d1SDavid du Colombier long txtoff; /* start of text in file */ 1933e12c5d1SDavid du Colombier long dataddr; /* start of data segment */ 1943e12c5d1SDavid du Colombier long datsz; /* size of data seg */ 1953e12c5d1SDavid du Colombier long datoff; /* offset to data seg in file */ 1963e12c5d1SDavid du Colombier long bsssz; /* size of bss */ 1973e12c5d1SDavid du Colombier long symsz; /* size of symbol table */ 1983e12c5d1SDavid du Colombier long symoff; /* offset of symbol table in file */ 1993e12c5d1SDavid du Colombier long sppcsz; /* size of sp-pc table */ 2003e12c5d1SDavid du Colombier long sppcoff; /* offset of sp-pc table in file */ 2013e12c5d1SDavid du Colombier long lnpcsz; /* size of line number-pc table */ 2023e12c5d1SDavid du Colombier long lnpcoff; /* size of line number-pc table */ 2033e12c5d1SDavid du Colombier } Fhdr; 2043e12c5d1SDavid du Colombier 205*219b2ee8SDavid du Colombier extern int asstype; /* dissembler type - machdata.c */ 206*219b2ee8SDavid du Colombier extern Machdata *machdata; /* jump vector - machdata.c */ 2073e12c5d1SDavid du Colombier 208*219b2ee8SDavid du Colombier Map* attachremt(int, Fhdr*); 209*219b2ee8SDavid du Colombier int beieee80ftos(char*, int, void*); 210*219b2ee8SDavid du Colombier int beieeesftos(char*, int, void*); 211*219b2ee8SDavid du Colombier int beieeedftos(char*, int, void*); 2123e12c5d1SDavid du Colombier ushort beswab(ushort); 2133e12c5d1SDavid du Colombier long beswal(long); 214*219b2ee8SDavid du Colombier int cisctrace(Map*, ulong, ulong, ulong, Tracer); 215*219b2ee8SDavid du Colombier ulong ciscframe(Map*, ulong, ulong, ulong, ulong); 216*219b2ee8SDavid du Colombier int crackhdr(int fd, Fhdr*); 2173e12c5d1SDavid du Colombier long file2pc(char*, ulong); 2183e12c5d1SDavid du Colombier int fileelem(Sym**, uchar *, char*, int); 2193e12c5d1SDavid du Colombier int fileline(char*, int, ulong); 220bd389b36SDavid du Colombier int filesym(int, char*, int); 2213e12c5d1SDavid du Colombier int findlocal(Symbol*, char*, Symbol*); 222*219b2ee8SDavid du Colombier int findseg(Map*, char*); 2233e12c5d1SDavid du Colombier int findsym(long, int, Symbol *); 224*219b2ee8SDavid du Colombier int fnbound(long, ulong*); 225*219b2ee8SDavid du Colombier int fpformat(Map*, Reglist*, char*, int, int); 226*219b2ee8SDavid du Colombier int get1(Map*, ulong, uchar*, int); 227*219b2ee8SDavid du Colombier int get2(Map*, ulong, ushort*); 228*219b2ee8SDavid du Colombier int get4(Map*, ulong, long*); 2293e12c5d1SDavid du Colombier int getauto(Symbol*, int, int, Symbol*); 2303e12c5d1SDavid du Colombier Sym* getsym(int); 2313e12c5d1SDavid du Colombier int globalsym(Symbol *, int); 232*219b2ee8SDavid du Colombier char* _hexify(char*, ulong, int); 233*219b2ee8SDavid du Colombier int ieeesftos(char*, int, ulong); 234*219b2ee8SDavid du Colombier int ieeedftos(char*, int, ulong, ulong); 235bd389b36SDavid du Colombier int isar(Biobuf*); 236*219b2ee8SDavid du Colombier int leieee80ftos(char*, int, void*); 237*219b2ee8SDavid du Colombier int leieeesftos(char*, int, void*); 238*219b2ee8SDavid du Colombier int leieeedftos(char*, int, void*); 2393e12c5d1SDavid du Colombier ushort leswab(ushort); 2403e12c5d1SDavid du Colombier long leswal(long); 241bd389b36SDavid du Colombier long line2addr(ulong, ulong, ulong); 2423e12c5d1SDavid du Colombier Map* loadmap(Map*, int, Fhdr*); 243*219b2ee8SDavid du Colombier int localaddr(Map*, char*, char*, long*, Rgetter); 2443e12c5d1SDavid du Colombier int localsym(Symbol*, int); 2453e12c5d1SDavid du Colombier int lookup(char*, char*, Symbol*); 2463e12c5d1SDavid du Colombier void machbytype(int); 2473e12c5d1SDavid du Colombier int machbyname(char*); 248bd389b36SDavid du Colombier int nextar(Biobuf*, int, char*); 249*219b2ee8SDavid du Colombier Map* newmap(Map*, int, int); 250*219b2ee8SDavid du Colombier void objtraverse(void(*)(Sym*, void*), void*); 251*219b2ee8SDavid du Colombier int objtype(Biobuf*, char**); 2523e12c5d1SDavid du Colombier long pc2sp(ulong); 2533e12c5d1SDavid du Colombier long pc2line(ulong); 254*219b2ee8SDavid du Colombier int put1(Map*, ulong, uchar*, int); 255*219b2ee8SDavid du Colombier int put2(Map*, ulong, ushort); 256*219b2ee8SDavid du Colombier int put4(Map*, ulong, long); 257*219b2ee8SDavid du Colombier int readar(Biobuf*, int, int, int); 258bd389b36SDavid du Colombier int readobj(Biobuf*, int); 259*219b2ee8SDavid du Colombier ulong riscframe(Map*, ulong, ulong, ulong, ulong); 260*219b2ee8SDavid du Colombier int risctrace(Map*, ulong, ulong, ulong, Tracer); 261*219b2ee8SDavid du Colombier int setmap(Map*, ulong, ulong, ulong, char*); 2623e12c5d1SDavid du Colombier Sym* symbase(long*); 2633e12c5d1SDavid du Colombier int syminit(int, Fhdr*); 264*219b2ee8SDavid du Colombier int symoff(char*, int, long, int); 265*219b2ee8SDavid du Colombier void textseg(ulong, Fhdr*); 2663e12c5d1SDavid du Colombier int textsym(Symbol*, int); 2673e12c5d1SDavid du Colombier void unusemap(Map*, int); 268