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, 123806af99SDavid du Colombier * amd64, 13bd389b36SDavid du Colombier * sparc, 143806af99SDavid du Colombier * sparc64, 157dd7cddfSDavid du Colombier * mips2 (R4000) 16375daca8SDavid du Colombier * arm 17375daca8SDavid du Colombier * power pc 18375daca8SDavid du Colombier * alpha 193e12c5d1SDavid du Colombier */ 203e12c5d1SDavid du Colombier enum 213e12c5d1SDavid du Colombier { 223e12c5d1SDavid du Colombier MMIPS, /* machine types */ 233e12c5d1SDavid du Colombier MSPARC, 243e12c5d1SDavid du Colombier M68020, 253e12c5d1SDavid du Colombier MI386, 26375daca8SDavid du Colombier MI960, /* retired */ 27375daca8SDavid du Colombier M3210, /* retired */ 287dd7cddfSDavid du Colombier MMIPS2, 297dd7cddfSDavid du Colombier NMIPS2, 30375daca8SDavid du Colombier M29000, /* retired */ 317dd7cddfSDavid du Colombier MARM, 327dd7cddfSDavid du Colombier MPOWER, 337dd7cddfSDavid du Colombier MALPHA, 343ff48bf5SDavid du Colombier NMIPS, 353806af99SDavid du Colombier MSPARC64, 363806af99SDavid du Colombier MAMD64, 377dd7cddfSDavid du Colombier /* types of executables */ 38219b2ee8SDavid du Colombier FNONE = 0, /* unidentified */ 393e12c5d1SDavid du Colombier FMIPS, /* v.out */ 403e12c5d1SDavid du Colombier FMIPSB, /* mips bootable */ 413e12c5d1SDavid du Colombier FSPARC, /* k.out */ 423e12c5d1SDavid du Colombier FSPARCB, /* Sparc bootable */ 433e12c5d1SDavid du Colombier F68020, /* 2.out */ 443e12c5d1SDavid du Colombier F68020B, /* 68020 bootable */ 453e12c5d1SDavid du Colombier FNEXTB, /* Next bootable */ 463e12c5d1SDavid du Colombier FI386, /* 8.out */ 473e12c5d1SDavid du Colombier FI386B, /* I386 bootable */ 48375daca8SDavid du Colombier FI960, /* retired */ 49375daca8SDavid du Colombier FI960B, /* retired */ 50375daca8SDavid du Colombier F3210, /* retired */ 517dd7cddfSDavid du Colombier FMIPS2BE, /* 4.out */ 52375daca8SDavid du Colombier F29000, /* retired */ 537dd7cddfSDavid du Colombier FARM, /* 5.out */ 547dd7cddfSDavid du Colombier FARMB, /* ARM bootable */ 557dd7cddfSDavid du Colombier FPOWER, /* q.out */ 567dd7cddfSDavid du Colombier FPOWERB, /* power pc bootable */ 57375daca8SDavid du Colombier FMIPS2LE, /* 0.out */ 587dd7cddfSDavid du Colombier FALPHA, /* 7.out */ 597dd7cddfSDavid du Colombier FALPHAB, /* DEC Alpha bootable */ 603ff48bf5SDavid du Colombier FMIPSLE, /* 3k little endian */ 613806af99SDavid du Colombier FSPARC64, /* u.out */ 623806af99SDavid du Colombier FAMD64, /* 6.out */ 636c0bae65SDavid du Colombier FAMD64B, /* 6.out bootable */ 643e12c5d1SDavid du Colombier 65219b2ee8SDavid du Colombier ANONE = 0, /* dissembler types */ 663e12c5d1SDavid du Colombier AMIPS, 673e12c5d1SDavid du Colombier AMIPSCO, /* native mips */ 683e12c5d1SDavid du Colombier ASPARC, 693e12c5d1SDavid du Colombier ASUNSPARC, /* native sun */ 703e12c5d1SDavid du Colombier A68020, 713e12c5d1SDavid du Colombier AI386, 723e12c5d1SDavid du Colombier AI8086, /* oh god */ 73375daca8SDavid du Colombier AI960, /* retired */ 74375daca8SDavid du Colombier A29000, /* retired */ 757dd7cddfSDavid du Colombier AARM, 767dd7cddfSDavid du Colombier APOWER, 777dd7cddfSDavid du Colombier AALPHA, 783806af99SDavid du Colombier ASPARC64, 793806af99SDavid du Colombier AAMD64, 80bd389b36SDavid du Colombier /* object file types */ 81bd389b36SDavid du Colombier Obj68020 = 0, /* .2 */ 82219b2ee8SDavid du Colombier ObjSparc, /* .k */ 83219b2ee8SDavid du Colombier ObjMips, /* .v */ 84219b2ee8SDavid du Colombier Obj386, /* .8 */ 85375daca8SDavid du Colombier Obj960, /* retired */ 86375daca8SDavid du Colombier Obj3210, /* retired */ 877dd7cddfSDavid du Colombier ObjMips2, /* .4 */ 88375daca8SDavid du Colombier Obj29000, /* retired */ 897dd7cddfSDavid du Colombier ObjArm, /* .5 */ 907dd7cddfSDavid du Colombier ObjPower, /* .q */ 917dd7cddfSDavid du Colombier ObjMips2le, /* .0 */ 927dd7cddfSDavid du Colombier ObjAlpha, /* .7 */ 933806af99SDavid du Colombier ObjSparc64, /* .u */ 943806af99SDavid du Colombier ObjAmd64, /* .6 */ 95219b2ee8SDavid du Colombier Maxobjtype, 963e12c5d1SDavid du Colombier 973e12c5d1SDavid du Colombier CNONE = 0, /* symbol table classes */ 98219b2ee8SDavid du Colombier CAUTO, 99219b2ee8SDavid du Colombier CPARAM, 100219b2ee8SDavid du Colombier CSTAB, 101219b2ee8SDavid du Colombier CTEXT, 102219b2ee8SDavid du Colombier CDATA, 103219b2ee8SDavid du Colombier CANY, /* to look for any class */ 1043e12c5d1SDavid du Colombier }; 105219b2ee8SDavid du Colombier 106219b2ee8SDavid du Colombier typedef struct Map Map; 107219b2ee8SDavid du Colombier typedef struct Symbol Symbol; 108219b2ee8SDavid du Colombier typedef struct Reglist Reglist; 109219b2ee8SDavid du Colombier typedef struct Mach Mach; 110219b2ee8SDavid du Colombier typedef struct Machdata Machdata; 111219b2ee8SDavid du Colombier 1123e12c5d1SDavid du Colombier /* 113bd389b36SDavid du Colombier * Structure to map a segment to a position in a file 1143e12c5d1SDavid du Colombier */ 115219b2ee8SDavid du Colombier struct Map { 116219b2ee8SDavid du Colombier int nsegs; /* number of segments */ 117219b2ee8SDavid du Colombier struct segment { /* per-segment map */ 1183e12c5d1SDavid du Colombier char *name; /* the segment name */ 1197dd7cddfSDavid du Colombier int fd; /* file descriptor */ 120bd389b36SDavid du Colombier int inuse; /* in use - not in use */ 121867bfcc6SDavid du Colombier int cache; /* should cache reads? */ 122*4de34a7eSDavid du Colombier uvlong b; /* base */ 123*4de34a7eSDavid du Colombier uvlong e; /* end */ 124*4de34a7eSDavid du Colombier vlong f; /* offset within file */ 125219b2ee8SDavid du Colombier } seg[1]; /* actually n of these */ 126219b2ee8SDavid du Colombier }; 1277dd7cddfSDavid du Colombier 128219b2ee8SDavid du Colombier /* 129219b2ee8SDavid du Colombier * Internal structure describing a symbol table entry 130219b2ee8SDavid du Colombier */ 131219b2ee8SDavid du Colombier struct Symbol { 132219b2ee8SDavid du Colombier void *handle; /* used internally - owning func */ 133219b2ee8SDavid du Colombier struct { 134219b2ee8SDavid du Colombier char *name; 1353806af99SDavid du Colombier vlong value; /* address or stack offset */ 136219b2ee8SDavid du Colombier char type; /* as in a.out.h */ 137219b2ee8SDavid du Colombier char class; /* as above */ 138867bfcc6SDavid du Colombier int index; /* in findlocal, globalsym, textsym */ 139219b2ee8SDavid du Colombier }; 1403e12c5d1SDavid du Colombier }; 1417dd7cddfSDavid du Colombier 1423e12c5d1SDavid du Colombier /* 1433e12c5d1SDavid du Colombier * machine register description 1443e12c5d1SDavid du Colombier */ 145219b2ee8SDavid du Colombier struct Reglist { 1463e12c5d1SDavid du Colombier char *rname; /* register name */ 1473e12c5d1SDavid du Colombier short roffs; /* offset in u-block */ 148219b2ee8SDavid du Colombier char rflags; /* INTEGER/FLOAT, WRITABLE */ 1493806af99SDavid du Colombier char rformat; /* print format: 'x', 'X', 'f', '8', '3', 'Y', 'W' */ 150219b2ee8SDavid du Colombier }; 151219b2ee8SDavid du Colombier 152219b2ee8SDavid du Colombier enum { /* bits in rflags field */ 153219b2ee8SDavid du Colombier RINT = (0<<0), 154219b2ee8SDavid du Colombier RFLT = (1<<0), 155219b2ee8SDavid du Colombier RRDONLY = (1<<1), 1563e12c5d1SDavid du Colombier }; 157375daca8SDavid du Colombier 1583e12c5d1SDavid du Colombier /* 159219b2ee8SDavid du Colombier * Machine-dependent data is stored in two structures: 160219b2ee8SDavid du Colombier * Mach - miscellaneous general parameters 161219b2ee8SDavid du Colombier * Machdata - jump vector of service functions used by debuggers 162219b2ee8SDavid du Colombier * 163375daca8SDavid du Colombier * Mach is defined in ?.c and set in executable.c 164219b2ee8SDavid du Colombier * 165375daca8SDavid du Colombier * Machdata is defined in ?db.c 166219b2ee8SDavid du Colombier * and set in the debugger startup. 1673e12c5d1SDavid du Colombier */ 1683e12c5d1SDavid du Colombier struct Mach{ 1693e12c5d1SDavid du Colombier char *name; 170219b2ee8SDavid du Colombier int mtype; /* machine type code */ 1713e12c5d1SDavid du Colombier Reglist *reglist; /* register set */ 172*4de34a7eSDavid du Colombier long regsize; /* sizeof registers in bytes */ 173*4de34a7eSDavid du Colombier long fpregsize; /* sizeof fp registers in bytes */ 174219b2ee8SDavid du Colombier char *pc; /* pc name */ 175219b2ee8SDavid du Colombier char *sp; /* sp name */ 176219b2ee8SDavid du Colombier char *link; /* link register name */ 1773e12c5d1SDavid du Colombier char *sbreg; /* static base register name */ 1783806af99SDavid du Colombier uvlong sb; /* static base register value */ 1797dd7cddfSDavid du Colombier int pgsize; /* page size */ 1803806af99SDavid du Colombier uvlong kbase; /* kernel base address */ 1813806af99SDavid du Colombier uvlong ktmask; /* ktzero = kbase & ~ktmask */ 182*4de34a7eSDavid du Colombier uvlong utop; /* user stack top */ 1837dd7cddfSDavid du Colombier int pcquant; /* quantization of pc */ 1843e12c5d1SDavid du Colombier int szaddr; /* sizeof(void*) */ 1853e12c5d1SDavid du Colombier int szreg; /* sizeof(register) */ 1863e12c5d1SDavid du Colombier int szfloat; /* sizeof(float) */ 1873e12c5d1SDavid du Colombier int szdouble; /* sizeof(double) */ 1883e12c5d1SDavid du Colombier }; 1893e12c5d1SDavid du Colombier 1903e12c5d1SDavid du Colombier extern Mach *mach; /* Current machine */ 1913e12c5d1SDavid du Colombier 192*4de34a7eSDavid du Colombier typedef uvlong (*Rgetter)(Map*, char*); 193*4de34a7eSDavid du Colombier typedef void (*Tracer)(Map*, uvlong, uvlong, Symbol*); 1943e12c5d1SDavid du Colombier 195219b2ee8SDavid du Colombier struct Machdata { /* Machine-dependent debugger support */ 1963e12c5d1SDavid du Colombier uchar bpinst[4]; /* break point instr. */ 1973e12c5d1SDavid du Colombier short bpsize; /* size of break point instr. */ 1983e12c5d1SDavid du Colombier 199*4de34a7eSDavid du Colombier ushort (*swab)(ushort); /* ushort to local byte order */ 200*4de34a7eSDavid du Colombier ulong (*swal)(ulong); /* ulong to local byte order */ 201*4de34a7eSDavid du Colombier uvlong (*swav)(uvlong); /* uvlong to local byte order */ 202*4de34a7eSDavid du Colombier int (*ctrace)(Map*, uvlong, uvlong, uvlong, Tracer); /* C traceback */ 203*4de34a7eSDavid du Colombier uvlong (*findframe)(Map*, uvlong, uvlong, uvlong, uvlong);/* frame finder */ 204219b2ee8SDavid du Colombier char* (*excep)(Map*, Rgetter); /* last exception */ 205*4de34a7eSDavid du Colombier ulong (*bpfix)(uvlong); /* breakpoint fixup */ 206219b2ee8SDavid du Colombier int (*sftos)(char*, int, void*); /* single precision float */ 207219b2ee8SDavid du Colombier int (*dftos)(char*, int, void*); /* double precision float */ 208*4de34a7eSDavid du Colombier int (*foll)(Map*, uvlong, Rgetter, uvlong*);/* follow set */ 209*4de34a7eSDavid du Colombier int (*das)(Map*, uvlong, char, char*, int); /* symbolic disassembly */ 210*4de34a7eSDavid du Colombier int (*hexinst)(Map*, uvlong, char*, int); /* hex disassembly */ 211*4de34a7eSDavid du Colombier int (*instsize)(Map*, uvlong); /* instruction size */ 2123e12c5d1SDavid du Colombier }; 2133e12c5d1SDavid du Colombier 2143e12c5d1SDavid du Colombier /* 215bd389b36SDavid du Colombier * Common a.out header describing all architectures 2163e12c5d1SDavid du Colombier */ 2173e12c5d1SDavid du Colombier typedef struct Fhdr 2183e12c5d1SDavid du Colombier { 2193e12c5d1SDavid du Colombier char *name; /* identifier of executable */ 220*4de34a7eSDavid du Colombier uchar type; /* file type - see codes above*/ 221*4de34a7eSDavid du Colombier uchar hdrsz; /* header size */ 222*4de34a7eSDavid du Colombier uchar spare[2]; 2233e12c5d1SDavid du Colombier long magic; /* magic number */ 224*4de34a7eSDavid du Colombier uvlong txtaddr; /* text address */ 225*4de34a7eSDavid du Colombier vlong txtoff; /* start of text in file */ 226*4de34a7eSDavid du Colombier uvlong dataddr; /* start of data segment */ 227*4de34a7eSDavid du Colombier vlong datoff; /* offset to data seg in file */ 228*4de34a7eSDavid du Colombier vlong symoff; /* offset of symbol table in file */ 229*4de34a7eSDavid du Colombier uvlong entry; /* entry point */ 230*4de34a7eSDavid du Colombier vlong sppcoff; /* offset of sp-pc table in file */ 231*4de34a7eSDavid du Colombier vlong lnpcoff; /* offset of line number-pc table in file */ 2323e12c5d1SDavid du Colombier long txtsz; /* text size */ 2333e12c5d1SDavid du Colombier long datsz; /* size of data seg */ 2343e12c5d1SDavid du Colombier long bsssz; /* size of bss */ 2353e12c5d1SDavid du Colombier long symsz; /* size of symbol table */ 2363e12c5d1SDavid du Colombier long sppcsz; /* size of sp-pc table */ 2373e12c5d1SDavid du Colombier long lnpcsz; /* size of line number-pc table */ 2383e12c5d1SDavid du Colombier } Fhdr; 2393e12c5d1SDavid du Colombier 240219b2ee8SDavid du Colombier extern int asstype; /* dissembler type - machdata.c */ 241219b2ee8SDavid du Colombier extern Machdata *machdata; /* jump vector - machdata.c */ 2423e12c5d1SDavid du Colombier 2437dd7cddfSDavid du Colombier Map* attachproc(int, int, int, Fhdr*); 244219b2ee8SDavid du Colombier int beieee80ftos(char*, int, void*); 245219b2ee8SDavid du Colombier int beieeesftos(char*, int, void*); 246219b2ee8SDavid du Colombier int beieeedftos(char*, int, void*); 2473e12c5d1SDavid du Colombier ushort beswab(ushort); 248*4de34a7eSDavid du Colombier ulong beswal(ulong); 249*4de34a7eSDavid du Colombier uvlong beswav(uvlong); 250*4de34a7eSDavid du Colombier uvlong ciscframe(Map*, uvlong, uvlong, uvlong, uvlong); 251*4de34a7eSDavid du Colombier int cisctrace(Map*, uvlong, uvlong, uvlong, Tracer); 252219b2ee8SDavid du Colombier int crackhdr(int fd, Fhdr*); 253*4de34a7eSDavid du Colombier uvlong file2pc(char*, long); 2543e12c5d1SDavid du Colombier int fileelem(Sym**, uchar *, char*, int); 255*4de34a7eSDavid du Colombier long fileline(char*, int, uvlong); 256bd389b36SDavid du Colombier int filesym(int, char*, int); 2573e12c5d1SDavid du Colombier int findlocal(Symbol*, char*, Symbol*); 258219b2ee8SDavid du Colombier int findseg(Map*, char*); 259*4de34a7eSDavid du Colombier int findsym(uvlong, int, Symbol *); 260*4de34a7eSDavid du Colombier int fnbound(uvlong, uvlong*); 261219b2ee8SDavid du Colombier int fpformat(Map*, Reglist*, char*, int, int); 262*4de34a7eSDavid du Colombier int get1(Map*, uvlong, uchar*, int); 263*4de34a7eSDavid du Colombier int get2(Map*, uvlong, ushort*); 264*4de34a7eSDavid du Colombier int get4(Map*, uvlong, ulong*); 265*4de34a7eSDavid du Colombier int get8(Map*, uvlong, uvlong*); 266*4de34a7eSDavid du Colombier int geta(Map*, uvlong, uvlong*); 2673e12c5d1SDavid du Colombier int getauto(Symbol*, int, int, Symbol*); 2683e12c5d1SDavid du Colombier Sym* getsym(int); 2693e12c5d1SDavid du Colombier int globalsym(Symbol *, int); 270219b2ee8SDavid du Colombier char* _hexify(char*, ulong, int); 271219b2ee8SDavid du Colombier int ieeesftos(char*, int, ulong); 272219b2ee8SDavid du Colombier int ieeedftos(char*, int, ulong, ulong); 273bd389b36SDavid du Colombier int isar(Biobuf*); 274219b2ee8SDavid du Colombier int leieee80ftos(char*, int, void*); 275219b2ee8SDavid du Colombier int leieeesftos(char*, int, void*); 276219b2ee8SDavid du Colombier int leieeedftos(char*, int, void*); 2773e12c5d1SDavid du Colombier ushort leswab(ushort); 278*4de34a7eSDavid du Colombier ulong leswal(ulong); 279*4de34a7eSDavid du Colombier uvlong leswav(uvlong); 280*4de34a7eSDavid du Colombier uvlong line2addr(long, uvlong, uvlong); 2813e12c5d1SDavid du Colombier Map* loadmap(Map*, int, Fhdr*); 282*4de34a7eSDavid du Colombier int localaddr(Map*, char*, char*, uvlong*, Rgetter); 2833e12c5d1SDavid du Colombier int localsym(Symbol*, int); 2843e12c5d1SDavid du Colombier int lookup(char*, char*, Symbol*); 2853e12c5d1SDavid du Colombier void machbytype(int); 2863e12c5d1SDavid du Colombier int machbyname(char*); 287bd389b36SDavid du Colombier int nextar(Biobuf*, int, char*); 2887dd7cddfSDavid du Colombier Map* newmap(Map*, int); 289219b2ee8SDavid du Colombier void objtraverse(void(*)(Sym*, void*), void*); 290219b2ee8SDavid du Colombier int objtype(Biobuf*, char**); 291*4de34a7eSDavid du Colombier uvlong pc2sp(uvlong); 292*4de34a7eSDavid du Colombier long pc2line(uvlong); 293*4de34a7eSDavid du Colombier int put1(Map*, uvlong, uchar*, int); 294*4de34a7eSDavid du Colombier int put2(Map*, uvlong, ushort); 295*4de34a7eSDavid du Colombier int put4(Map*, uvlong, ulong); 296*4de34a7eSDavid du Colombier int put8(Map*, uvlong, uvlong); 297*4de34a7eSDavid du Colombier int puta(Map*, uvlong, uvlong); 298*4de34a7eSDavid du Colombier int readar(Biobuf*, int, vlong, int); 299bd389b36SDavid du Colombier int readobj(Biobuf*, int); 300*4de34a7eSDavid du Colombier uvlong riscframe(Map*, uvlong, uvlong, uvlong, uvlong); 301*4de34a7eSDavid du Colombier int risctrace(Map*, uvlong, uvlong, uvlong, Tracer); 302*4de34a7eSDavid du Colombier int setmap(Map*, int, uvlong, uvlong, vlong, char*); 3033e12c5d1SDavid du Colombier Sym* symbase(long*); 3043e12c5d1SDavid du Colombier int syminit(int, Fhdr*); 305*4de34a7eSDavid du Colombier int symoff(char*, int, uvlong, int); 306*4de34a7eSDavid du Colombier void textseg(uvlong, Fhdr*); 3073e12c5d1SDavid du Colombier int textsym(Symbol*, int); 3083e12c5d1SDavid du Colombier void unusemap(Map*, int); 309