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, 147dd7cddfSDavid du Colombier * mips2 (R4000) 15375daca8SDavid du Colombier * arm 1647ad9175SDavid du Colombier * powerpc, 1747ad9175SDavid du Colombier * powerpc64 18e6dac696SDavid du Colombier * arm64 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, 33*8a34c8c5SDavid du Colombier MALPHA, /* retired */ 343ff48bf5SDavid du Colombier NMIPS, 35*8a34c8c5SDavid du Colombier MSPARC64, /* retired */ 363806af99SDavid du Colombier MAMD64, 3747ad9175SDavid du Colombier MPOWER64, 38e6dac696SDavid du Colombier MARM64, 397dd7cddfSDavid du Colombier /* types of executables */ 40219b2ee8SDavid du Colombier FNONE = 0, /* unidentified */ 413e12c5d1SDavid du Colombier FMIPS, /* v.out */ 423e12c5d1SDavid du Colombier FMIPSB, /* mips bootable */ 433e12c5d1SDavid du Colombier FSPARC, /* k.out */ 443e12c5d1SDavid du Colombier FSPARCB, /* Sparc bootable */ 453e12c5d1SDavid du Colombier F68020, /* 2.out */ 463e12c5d1SDavid du Colombier F68020B, /* 68020 bootable */ 473e12c5d1SDavid du Colombier FNEXTB, /* Next bootable */ 483e12c5d1SDavid du Colombier FI386, /* 8.out */ 493e12c5d1SDavid du Colombier FI386B, /* I386 bootable */ 50375daca8SDavid du Colombier FI960, /* retired */ 51375daca8SDavid du Colombier FI960B, /* retired */ 52375daca8SDavid du Colombier F3210, /* retired */ 537dd7cddfSDavid du Colombier FMIPS2BE, /* 4.out */ 54375daca8SDavid du Colombier F29000, /* retired */ 557dd7cddfSDavid du Colombier FARM, /* 5.out */ 567dd7cddfSDavid du Colombier FARMB, /* ARM bootable */ 577dd7cddfSDavid du Colombier FPOWER, /* q.out */ 587dd7cddfSDavid du Colombier FPOWERB, /* power pc bootable */ 59375daca8SDavid du Colombier FMIPS2LE, /* 0.out */ 60*8a34c8c5SDavid du Colombier FALPHA, /* retired */ 61*8a34c8c5SDavid du Colombier FALPHAB, /* retired DEC Alpha bootable */ 623ff48bf5SDavid du Colombier FMIPSLE, /* 3k little endian */ 63*8a34c8c5SDavid du Colombier FSPARC64, /* retired */ 643806af99SDavid du Colombier FAMD64, /* 6.out */ 656c0bae65SDavid du Colombier FAMD64B, /* 6.out bootable */ 6647ad9175SDavid du Colombier FPOWER64, /* 9.out */ 6747ad9175SDavid du Colombier FPOWER64B, /* 9.out bootable */ 68e6dac696SDavid du Colombier FARM64, /* arm64 */ 69e6dac696SDavid du Colombier FARM64B, /* arm64 bootable */ 703e12c5d1SDavid du Colombier 71219b2ee8SDavid du Colombier ANONE = 0, /* dissembler types */ 723e12c5d1SDavid du Colombier AMIPS, 733e12c5d1SDavid du Colombier AMIPSCO, /* native mips */ 743e12c5d1SDavid du Colombier ASPARC, 753e12c5d1SDavid du Colombier ASUNSPARC, /* native sun */ 763e12c5d1SDavid du Colombier A68020, 773e12c5d1SDavid du Colombier AI386, 783e12c5d1SDavid du Colombier AI8086, /* oh god */ 79375daca8SDavid du Colombier AI960, /* retired */ 80375daca8SDavid du Colombier A29000, /* retired */ 817dd7cddfSDavid du Colombier AARM, 827dd7cddfSDavid du Colombier APOWER, 83*8a34c8c5SDavid du Colombier AALPHA, /* retired */ 84*8a34c8c5SDavid du Colombier ASPARC64, /* retired */ 853806af99SDavid du Colombier AAMD64, 8647ad9175SDavid du Colombier APOWER64, 87e6dac696SDavid du Colombier AARM64, 88bd389b36SDavid du Colombier /* object file types */ 89bd389b36SDavid du Colombier Obj68020 = 0, /* .2 */ 90219b2ee8SDavid du Colombier ObjSparc, /* .k */ 91219b2ee8SDavid du Colombier ObjMips, /* .v */ 92219b2ee8SDavid du Colombier Obj386, /* .8 */ 93375daca8SDavid du Colombier Obj960, /* retired */ 94375daca8SDavid du Colombier Obj3210, /* retired */ 957dd7cddfSDavid du Colombier ObjMips2, /* .4 */ 96375daca8SDavid du Colombier Obj29000, /* retired */ 977dd7cddfSDavid du Colombier ObjArm, /* .5 */ 987dd7cddfSDavid du Colombier ObjPower, /* .q */ 997dd7cddfSDavid du Colombier ObjMips2le, /* .0 */ 100*8a34c8c5SDavid du Colombier ObjAlpha, /* retired */ 101*8a34c8c5SDavid du Colombier ObjSparc64, /* retired */ 1023806af99SDavid du Colombier ObjAmd64, /* .6 */ 10317dd33a2SDavid du Colombier ObjSpim, /* .0 */ 10447ad9175SDavid du Colombier ObjPower64, /* .9 */ 105e6dac696SDavid du Colombier ObjArm64, /* .4? */ 106219b2ee8SDavid du Colombier Maxobjtype, 1073e12c5d1SDavid du Colombier 1083e12c5d1SDavid du Colombier CNONE = 0, /* symbol table classes */ 109219b2ee8SDavid du Colombier CAUTO, 110219b2ee8SDavid du Colombier CPARAM, 111219b2ee8SDavid du Colombier CSTAB, 112219b2ee8SDavid du Colombier CTEXT, 113219b2ee8SDavid du Colombier CDATA, 114219b2ee8SDavid du Colombier CANY, /* to look for any class */ 1153e12c5d1SDavid du Colombier }; 116219b2ee8SDavid du Colombier 117219b2ee8SDavid du Colombier typedef struct Map Map; 118219b2ee8SDavid du Colombier typedef struct Symbol Symbol; 119219b2ee8SDavid du Colombier typedef struct Reglist Reglist; 120219b2ee8SDavid du Colombier typedef struct Mach Mach; 121219b2ee8SDavid du Colombier typedef struct Machdata Machdata; 122219b2ee8SDavid du Colombier 1233e12c5d1SDavid du Colombier /* 124bd389b36SDavid du Colombier * Structure to map a segment to a position in a file 1253e12c5d1SDavid du Colombier */ 126219b2ee8SDavid du Colombier struct Map { 127219b2ee8SDavid du Colombier int nsegs; /* number of segments */ 128219b2ee8SDavid du Colombier struct segment { /* per-segment map */ 1293e12c5d1SDavid du Colombier char *name; /* the segment name */ 1307dd7cddfSDavid du Colombier int fd; /* file descriptor */ 131bd389b36SDavid du Colombier int inuse; /* in use - not in use */ 132867bfcc6SDavid du Colombier int cache; /* should cache reads? */ 1334de34a7eSDavid du Colombier uvlong b; /* base */ 1344de34a7eSDavid du Colombier uvlong e; /* end */ 1354de34a7eSDavid du Colombier vlong f; /* offset within file */ 136219b2ee8SDavid du Colombier } seg[1]; /* actually n of these */ 137219b2ee8SDavid du Colombier }; 1387dd7cddfSDavid du Colombier 139219b2ee8SDavid du Colombier /* 140219b2ee8SDavid du Colombier * Internal structure describing a symbol table entry 141219b2ee8SDavid du Colombier */ 142219b2ee8SDavid du Colombier struct Symbol { 143219b2ee8SDavid du Colombier void *handle; /* used internally - owning func */ 144219b2ee8SDavid du Colombier struct { 145219b2ee8SDavid du Colombier char *name; 1463806af99SDavid du Colombier vlong value; /* address or stack offset */ 147219b2ee8SDavid du Colombier char type; /* as in a.out.h */ 148219b2ee8SDavid du Colombier char class; /* as above */ 149867bfcc6SDavid du Colombier int index; /* in findlocal, globalsym, textsym */ 150219b2ee8SDavid du Colombier }; 1513e12c5d1SDavid du Colombier }; 1527dd7cddfSDavid du Colombier 1533e12c5d1SDavid du Colombier /* 1543e12c5d1SDavid du Colombier * machine register description 1553e12c5d1SDavid du Colombier */ 156219b2ee8SDavid du Colombier struct Reglist { 1573e12c5d1SDavid du Colombier char *rname; /* register name */ 1583e12c5d1SDavid du Colombier short roffs; /* offset in u-block */ 159219b2ee8SDavid du Colombier char rflags; /* INTEGER/FLOAT, WRITABLE */ 1603806af99SDavid du Colombier char rformat; /* print format: 'x', 'X', 'f', '8', '3', 'Y', 'W' */ 161219b2ee8SDavid du Colombier }; 162219b2ee8SDavid du Colombier 163219b2ee8SDavid du Colombier enum { /* bits in rflags field */ 164219b2ee8SDavid du Colombier RINT = (0<<0), 165219b2ee8SDavid du Colombier RFLT = (1<<0), 166219b2ee8SDavid du Colombier RRDONLY = (1<<1), 1673e12c5d1SDavid du Colombier }; 168375daca8SDavid du Colombier 1693e12c5d1SDavid du Colombier /* 170219b2ee8SDavid du Colombier * Machine-dependent data is stored in two structures: 171219b2ee8SDavid du Colombier * Mach - miscellaneous general parameters 172219b2ee8SDavid du Colombier * Machdata - jump vector of service functions used by debuggers 173219b2ee8SDavid du Colombier * 174375daca8SDavid du Colombier * Mach is defined in ?.c and set in executable.c 175219b2ee8SDavid du Colombier * 176375daca8SDavid du Colombier * Machdata is defined in ?db.c 177219b2ee8SDavid du Colombier * and set in the debugger startup. 1783e12c5d1SDavid du Colombier */ 1793e12c5d1SDavid du Colombier struct Mach{ 1803e12c5d1SDavid du Colombier char *name; 181219b2ee8SDavid du Colombier int mtype; /* machine type code */ 1823e12c5d1SDavid du Colombier Reglist *reglist; /* register set */ 1834de34a7eSDavid du Colombier long regsize; /* sizeof registers in bytes */ 1844de34a7eSDavid du Colombier long fpregsize; /* sizeof fp registers in bytes */ 185219b2ee8SDavid du Colombier char *pc; /* pc name */ 186219b2ee8SDavid du Colombier char *sp; /* sp name */ 187219b2ee8SDavid du Colombier char *link; /* link register name */ 1883e12c5d1SDavid du Colombier char *sbreg; /* static base register name */ 1893806af99SDavid du Colombier uvlong sb; /* static base register value */ 1907dd7cddfSDavid du Colombier int pgsize; /* page size */ 1913806af99SDavid du Colombier uvlong kbase; /* kernel base address */ 1923806af99SDavid du Colombier uvlong ktmask; /* ktzero = kbase & ~ktmask */ 1934de34a7eSDavid du Colombier uvlong utop; /* user stack top */ 1947dd7cddfSDavid du Colombier int pcquant; /* quantization of pc */ 1953e12c5d1SDavid du Colombier int szaddr; /* sizeof(void*) */ 1963e12c5d1SDavid du Colombier int szreg; /* sizeof(register) */ 1973e12c5d1SDavid du Colombier int szfloat; /* sizeof(float) */ 1983e12c5d1SDavid du Colombier int szdouble; /* sizeof(double) */ 1993e12c5d1SDavid du Colombier }; 2003e12c5d1SDavid du Colombier 2013e12c5d1SDavid du Colombier extern Mach *mach; /* Current machine */ 2023e12c5d1SDavid du Colombier 2034de34a7eSDavid du Colombier typedef uvlong (*Rgetter)(Map*, char*); 2044de34a7eSDavid du Colombier typedef void (*Tracer)(Map*, uvlong, uvlong, Symbol*); 2053e12c5d1SDavid du Colombier 206219b2ee8SDavid du Colombier struct Machdata { /* Machine-dependent debugger support */ 2073e12c5d1SDavid du Colombier uchar bpinst[4]; /* break point instr. */ 2083e12c5d1SDavid du Colombier short bpsize; /* size of break point instr. */ 2093e12c5d1SDavid du Colombier 2104de34a7eSDavid du Colombier ushort (*swab)(ushort); /* ushort to local byte order */ 2114de34a7eSDavid du Colombier ulong (*swal)(ulong); /* ulong to local byte order */ 2124de34a7eSDavid du Colombier uvlong (*swav)(uvlong); /* uvlong to local byte order */ 2134de34a7eSDavid du Colombier int (*ctrace)(Map*, uvlong, uvlong, uvlong, Tracer); /* C traceback */ 2144de34a7eSDavid du Colombier uvlong (*findframe)(Map*, uvlong, uvlong, uvlong, uvlong);/* frame finder */ 215219b2ee8SDavid du Colombier char* (*excep)(Map*, Rgetter); /* last exception */ 2164de34a7eSDavid du Colombier ulong (*bpfix)(uvlong); /* breakpoint fixup */ 217219b2ee8SDavid du Colombier int (*sftos)(char*, int, void*); /* single precision float */ 218219b2ee8SDavid du Colombier int (*dftos)(char*, int, void*); /* double precision float */ 2194de34a7eSDavid du Colombier int (*foll)(Map*, uvlong, Rgetter, uvlong*);/* follow set */ 2204de34a7eSDavid du Colombier int (*das)(Map*, uvlong, char, char*, int); /* symbolic disassembly */ 2214de34a7eSDavid du Colombier int (*hexinst)(Map*, uvlong, char*, int); /* hex disassembly */ 2224de34a7eSDavid du Colombier int (*instsize)(Map*, uvlong); /* instruction size */ 2233e12c5d1SDavid du Colombier }; 2243e12c5d1SDavid du Colombier 2253e12c5d1SDavid du Colombier /* 226bd389b36SDavid du Colombier * Common a.out header describing all architectures 2273e12c5d1SDavid du Colombier */ 2283e12c5d1SDavid du Colombier typedef struct Fhdr 2293e12c5d1SDavid du Colombier { 2303e12c5d1SDavid du Colombier char *name; /* identifier of executable */ 2314de34a7eSDavid du Colombier uchar type; /* file type - see codes above */ 2324de34a7eSDavid du Colombier uchar hdrsz; /* header size */ 2332cca75a1SDavid du Colombier uchar _magic; /* _MAGIC() magic */ 2342cca75a1SDavid du Colombier uchar spare; 2353e12c5d1SDavid du Colombier long magic; /* magic number */ 2364de34a7eSDavid du Colombier uvlong txtaddr; /* text address */ 2374de34a7eSDavid du Colombier vlong txtoff; /* start of text in file */ 2384de34a7eSDavid du Colombier uvlong dataddr; /* start of data segment */ 2394de34a7eSDavid du Colombier vlong datoff; /* offset to data seg in file */ 2404de34a7eSDavid du Colombier vlong symoff; /* offset of symbol table in file */ 2414de34a7eSDavid du Colombier uvlong entry; /* entry point */ 2424de34a7eSDavid du Colombier vlong sppcoff; /* offset of sp-pc table in file */ 2434de34a7eSDavid du Colombier vlong lnpcoff; /* offset of line number-pc table in file */ 2443e12c5d1SDavid du Colombier long txtsz; /* text size */ 2453e12c5d1SDavid du Colombier long datsz; /* size of data seg */ 2463e12c5d1SDavid du Colombier long bsssz; /* size of bss */ 2473e12c5d1SDavid du Colombier long symsz; /* size of symbol table */ 2483e12c5d1SDavid du Colombier long sppcsz; /* size of sp-pc table */ 2493e12c5d1SDavid du Colombier long lnpcsz; /* size of line number-pc table */ 2503e12c5d1SDavid du Colombier } Fhdr; 2513e12c5d1SDavid du Colombier 252219b2ee8SDavid du Colombier extern int asstype; /* dissembler type - machdata.c */ 253219b2ee8SDavid du Colombier extern Machdata *machdata; /* jump vector - machdata.c */ 2543e12c5d1SDavid du Colombier 2557dd7cddfSDavid du Colombier Map* attachproc(int, int, int, Fhdr*); 256219b2ee8SDavid du Colombier int beieee80ftos(char*, int, void*); 257219b2ee8SDavid du Colombier int beieeesftos(char*, int, void*); 258219b2ee8SDavid du Colombier int beieeedftos(char*, int, void*); 2593e12c5d1SDavid du Colombier ushort beswab(ushort); 2604de34a7eSDavid du Colombier ulong beswal(ulong); 2614de34a7eSDavid du Colombier uvlong beswav(uvlong); 2624de34a7eSDavid du Colombier uvlong ciscframe(Map*, uvlong, uvlong, uvlong, uvlong); 2634de34a7eSDavid du Colombier int cisctrace(Map*, uvlong, uvlong, uvlong, Tracer); 264219b2ee8SDavid du Colombier int crackhdr(int fd, Fhdr*); 2654de34a7eSDavid du Colombier uvlong file2pc(char*, long); 2663e12c5d1SDavid du Colombier int fileelem(Sym**, uchar *, char*, int); 2674de34a7eSDavid du Colombier long fileline(char*, int, uvlong); 268bd389b36SDavid du Colombier int filesym(int, char*, int); 2693e12c5d1SDavid du Colombier int findlocal(Symbol*, char*, Symbol*); 270219b2ee8SDavid du Colombier int findseg(Map*, char*); 2714de34a7eSDavid du Colombier int findsym(uvlong, int, Symbol *); 2724de34a7eSDavid du Colombier int fnbound(uvlong, uvlong*); 273219b2ee8SDavid du Colombier int fpformat(Map*, Reglist*, char*, int, int); 2744de34a7eSDavid du Colombier int get1(Map*, uvlong, uchar*, int); 2754de34a7eSDavid du Colombier int get2(Map*, uvlong, ushort*); 2764de34a7eSDavid du Colombier int get4(Map*, uvlong, ulong*); 2774de34a7eSDavid du Colombier int get8(Map*, uvlong, uvlong*); 2784de34a7eSDavid du Colombier int geta(Map*, uvlong, uvlong*); 2793e12c5d1SDavid du Colombier int getauto(Symbol*, int, int, Symbol*); 2803e12c5d1SDavid du Colombier Sym* getsym(int); 2813e12c5d1SDavid du Colombier int globalsym(Symbol *, int); 282219b2ee8SDavid du Colombier char* _hexify(char*, ulong, int); 283219b2ee8SDavid du Colombier int ieeesftos(char*, int, ulong); 284219b2ee8SDavid du Colombier int ieeedftos(char*, int, ulong, ulong); 285bd389b36SDavid du Colombier int isar(Biobuf*); 286219b2ee8SDavid du Colombier int leieee80ftos(char*, int, void*); 287219b2ee8SDavid du Colombier int leieeesftos(char*, int, void*); 288219b2ee8SDavid du Colombier int leieeedftos(char*, int, void*); 2893e12c5d1SDavid du Colombier ushort leswab(ushort); 2904de34a7eSDavid du Colombier ulong leswal(ulong); 2914de34a7eSDavid du Colombier uvlong leswav(uvlong); 2924de34a7eSDavid du Colombier uvlong line2addr(long, uvlong, uvlong); 2933e12c5d1SDavid du Colombier Map* loadmap(Map*, int, Fhdr*); 2944de34a7eSDavid du Colombier int localaddr(Map*, char*, char*, uvlong*, Rgetter); 2953e12c5d1SDavid du Colombier int localsym(Symbol*, int); 2963e12c5d1SDavid du Colombier int lookup(char*, char*, Symbol*); 2973e12c5d1SDavid du Colombier void machbytype(int); 2983e12c5d1SDavid du Colombier int machbyname(char*); 299bd389b36SDavid du Colombier int nextar(Biobuf*, int, char*); 3007dd7cddfSDavid du Colombier Map* newmap(Map*, int); 301219b2ee8SDavid du Colombier void objtraverse(void(*)(Sym*, void*), void*); 302219b2ee8SDavid du Colombier int objtype(Biobuf*, char**); 3034de34a7eSDavid du Colombier uvlong pc2sp(uvlong); 3044de34a7eSDavid du Colombier long pc2line(uvlong); 3054de34a7eSDavid du Colombier int put1(Map*, uvlong, uchar*, int); 3064de34a7eSDavid du Colombier int put2(Map*, uvlong, ushort); 3074de34a7eSDavid du Colombier int put4(Map*, uvlong, ulong); 3084de34a7eSDavid du Colombier int put8(Map*, uvlong, uvlong); 3094de34a7eSDavid du Colombier int puta(Map*, uvlong, uvlong); 3104de34a7eSDavid du Colombier int readar(Biobuf*, int, vlong, int); 311bd389b36SDavid du Colombier int readobj(Biobuf*, int); 3124de34a7eSDavid du Colombier uvlong riscframe(Map*, uvlong, uvlong, uvlong, uvlong); 3134de34a7eSDavid du Colombier int risctrace(Map*, uvlong, uvlong, uvlong, Tracer); 3144de34a7eSDavid du Colombier int setmap(Map*, int, uvlong, uvlong, vlong, char*); 3153e12c5d1SDavid du Colombier Sym* symbase(long*); 3163e12c5d1SDavid du Colombier int syminit(int, Fhdr*); 3174de34a7eSDavid du Colombier int symoff(char*, int, uvlong, int); 3184de34a7eSDavid du Colombier void textseg(uvlong, Fhdr*); 3193e12c5d1SDavid du Colombier int textsym(Symbol*, int); 3203e12c5d1SDavid du Colombier void unusemap(Map*, int); 321