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 19*ce95e1b3SDavid du Colombier * riscv 20*ce95e1b3SDavid du Colombier * riscv64 213e12c5d1SDavid du Colombier */ 223e12c5d1SDavid du Colombier enum 233e12c5d1SDavid du Colombier { 243e12c5d1SDavid du Colombier MMIPS, /* machine types */ 253e12c5d1SDavid du Colombier MSPARC, 263e12c5d1SDavid du Colombier M68020, 273e12c5d1SDavid du Colombier MI386, 28375daca8SDavid du Colombier MI960, /* retired */ 29375daca8SDavid du Colombier M3210, /* retired */ 307dd7cddfSDavid du Colombier MMIPS2, 317dd7cddfSDavid du Colombier NMIPS2, 32375daca8SDavid du Colombier M29000, /* retired */ 337dd7cddfSDavid du Colombier MARM, 347dd7cddfSDavid du Colombier MPOWER, 358a34c8c5SDavid du Colombier MALPHA, /* retired */ 363ff48bf5SDavid du Colombier NMIPS, 378a34c8c5SDavid du Colombier MSPARC64, /* retired */ 383806af99SDavid du Colombier MAMD64, 3947ad9175SDavid du Colombier MPOWER64, 40e6dac696SDavid du Colombier MARM64, 41*ce95e1b3SDavid du Colombier MRISCV, 42*ce95e1b3SDavid du Colombier MRISCV64, 437dd7cddfSDavid du Colombier /* types of executables */ 44219b2ee8SDavid du Colombier FNONE = 0, /* unidentified */ 453e12c5d1SDavid du Colombier FMIPS, /* v.out */ 463e12c5d1SDavid du Colombier FMIPSB, /* mips bootable */ 473e12c5d1SDavid du Colombier FSPARC, /* k.out */ 483e12c5d1SDavid du Colombier FSPARCB, /* Sparc bootable */ 493e12c5d1SDavid du Colombier F68020, /* 2.out */ 503e12c5d1SDavid du Colombier F68020B, /* 68020 bootable */ 513e12c5d1SDavid du Colombier FNEXTB, /* Next bootable */ 523e12c5d1SDavid du Colombier FI386, /* 8.out */ 533e12c5d1SDavid du Colombier FI386B, /* I386 bootable */ 54375daca8SDavid du Colombier FI960, /* retired */ 55375daca8SDavid du Colombier FI960B, /* retired */ 56375daca8SDavid du Colombier F3210, /* retired */ 577dd7cddfSDavid du Colombier FMIPS2BE, /* 4.out */ 58375daca8SDavid du Colombier F29000, /* retired */ 597dd7cddfSDavid du Colombier FARM, /* 5.out */ 607dd7cddfSDavid du Colombier FARMB, /* ARM bootable */ 617dd7cddfSDavid du Colombier FPOWER, /* q.out */ 627dd7cddfSDavid du Colombier FPOWERB, /* power pc bootable */ 63375daca8SDavid du Colombier FMIPS2LE, /* 0.out */ 648a34c8c5SDavid du Colombier FALPHA, /* retired */ 658a34c8c5SDavid du Colombier FALPHAB, /* retired DEC Alpha bootable */ 663ff48bf5SDavid du Colombier FMIPSLE, /* 3k little endian */ 678a34c8c5SDavid du Colombier FSPARC64, /* retired */ 683806af99SDavid du Colombier FAMD64, /* 6.out */ 696c0bae65SDavid du Colombier FAMD64B, /* 6.out bootable */ 7047ad9175SDavid du Colombier FPOWER64, /* 9.out */ 7147ad9175SDavid du Colombier FPOWER64B, /* 9.out bootable */ 72e6dac696SDavid du Colombier FARM64, /* arm64 */ 73e6dac696SDavid du Colombier FARM64B, /* arm64 bootable */ 74*ce95e1b3SDavid du Colombier FRISCV, /* riscv */ 75*ce95e1b3SDavid du Colombier FRISCVB, /* riscv bootable */ 76*ce95e1b3SDavid du Colombier FRISCV64, /* riscv64 */ 77*ce95e1b3SDavid du Colombier FRISCV64B, /* riscv64 bootable */ 783e12c5d1SDavid du Colombier 79219b2ee8SDavid du Colombier ANONE = 0, /* dissembler types */ 803e12c5d1SDavid du Colombier AMIPS, 813e12c5d1SDavid du Colombier AMIPSCO, /* native mips */ 823e12c5d1SDavid du Colombier ASPARC, 833e12c5d1SDavid du Colombier ASUNSPARC, /* native sun */ 843e12c5d1SDavid du Colombier A68020, 853e12c5d1SDavid du Colombier AI386, 863e12c5d1SDavid du Colombier AI8086, /* oh god */ 87375daca8SDavid du Colombier AI960, /* retired */ 88375daca8SDavid du Colombier A29000, /* retired */ 897dd7cddfSDavid du Colombier AARM, 907dd7cddfSDavid du Colombier APOWER, 918a34c8c5SDavid du Colombier AALPHA, /* retired */ 928a34c8c5SDavid du Colombier ASPARC64, /* retired */ 933806af99SDavid du Colombier AAMD64, 9447ad9175SDavid du Colombier APOWER64, 95e6dac696SDavid du Colombier AARM64, 96*ce95e1b3SDavid du Colombier ARISCV, 97*ce95e1b3SDavid du Colombier ARISCV64, 98bd389b36SDavid du Colombier /* object file types */ 99bd389b36SDavid du Colombier Obj68020 = 0, /* .2 */ 100219b2ee8SDavid du Colombier ObjSparc, /* .k */ 101219b2ee8SDavid du Colombier ObjMips, /* .v */ 102219b2ee8SDavid du Colombier Obj386, /* .8 */ 103375daca8SDavid du Colombier Obj960, /* retired */ 104375daca8SDavid du Colombier Obj3210, /* retired */ 1057dd7cddfSDavid du Colombier ObjMips2, /* .4 */ 106375daca8SDavid du Colombier Obj29000, /* retired */ 1077dd7cddfSDavid du Colombier ObjArm, /* .5 */ 1087dd7cddfSDavid du Colombier ObjPower, /* .q */ 1097dd7cddfSDavid du Colombier ObjMips2le, /* .0 */ 1108a34c8c5SDavid du Colombier ObjAlpha, /* retired */ 1118a34c8c5SDavid du Colombier ObjSparc64, /* retired */ 1123806af99SDavid du Colombier ObjAmd64, /* .6 */ 11317dd33a2SDavid du Colombier ObjSpim, /* .0 */ 11447ad9175SDavid du Colombier ObjPower64, /* .9 */ 115e6dac696SDavid du Colombier ObjArm64, /* .4? */ 116*ce95e1b3SDavid du Colombier ObjRiscv, /* .i */ 117*ce95e1b3SDavid du Colombier ObjRiscv64, /* .j */ 118219b2ee8SDavid du Colombier Maxobjtype, 1193e12c5d1SDavid du Colombier 1203e12c5d1SDavid du Colombier CNONE = 0, /* symbol table classes */ 121219b2ee8SDavid du Colombier CAUTO, 122219b2ee8SDavid du Colombier CPARAM, 123219b2ee8SDavid du Colombier CSTAB, 124219b2ee8SDavid du Colombier CTEXT, 125219b2ee8SDavid du Colombier CDATA, 126219b2ee8SDavid du Colombier CANY, /* to look for any class */ 1273e12c5d1SDavid du Colombier }; 128219b2ee8SDavid du Colombier 129219b2ee8SDavid du Colombier typedef struct Map Map; 130219b2ee8SDavid du Colombier typedef struct Symbol Symbol; 131219b2ee8SDavid du Colombier typedef struct Reglist Reglist; 132219b2ee8SDavid du Colombier typedef struct Mach Mach; 133219b2ee8SDavid du Colombier typedef struct Machdata Machdata; 134219b2ee8SDavid du Colombier 1353e12c5d1SDavid du Colombier /* 136bd389b36SDavid du Colombier * Structure to map a segment to a position in a file 1373e12c5d1SDavid du Colombier */ 138219b2ee8SDavid du Colombier struct Map { 139219b2ee8SDavid du Colombier int nsegs; /* number of segments */ 140219b2ee8SDavid du Colombier struct segment { /* per-segment map */ 1413e12c5d1SDavid du Colombier char *name; /* the segment name */ 1427dd7cddfSDavid du Colombier int fd; /* file descriptor */ 143bd389b36SDavid du Colombier int inuse; /* in use - not in use */ 144867bfcc6SDavid du Colombier int cache; /* should cache reads? */ 1454de34a7eSDavid du Colombier uvlong b; /* base */ 1464de34a7eSDavid du Colombier uvlong e; /* end */ 1474de34a7eSDavid du Colombier vlong f; /* offset within file */ 148219b2ee8SDavid du Colombier } seg[1]; /* actually n of these */ 149219b2ee8SDavid du Colombier }; 1507dd7cddfSDavid du Colombier 151219b2ee8SDavid du Colombier /* 152219b2ee8SDavid du Colombier * Internal structure describing a symbol table entry 153219b2ee8SDavid du Colombier */ 154219b2ee8SDavid du Colombier struct Symbol { 155219b2ee8SDavid du Colombier void *handle; /* used internally - owning func */ 156219b2ee8SDavid du Colombier struct { 157219b2ee8SDavid du Colombier char *name; 1583806af99SDavid du Colombier vlong value; /* address or stack offset */ 159219b2ee8SDavid du Colombier char type; /* as in a.out.h */ 160219b2ee8SDavid du Colombier char class; /* as above */ 161867bfcc6SDavid du Colombier int index; /* in findlocal, globalsym, textsym */ 162219b2ee8SDavid du Colombier }; 1633e12c5d1SDavid du Colombier }; 1647dd7cddfSDavid du Colombier 1653e12c5d1SDavid du Colombier /* 1663e12c5d1SDavid du Colombier * machine register description 1673e12c5d1SDavid du Colombier */ 168219b2ee8SDavid du Colombier struct Reglist { 1693e12c5d1SDavid du Colombier char *rname; /* register name */ 1703e12c5d1SDavid du Colombier short roffs; /* offset in u-block */ 171219b2ee8SDavid du Colombier char rflags; /* INTEGER/FLOAT, WRITABLE */ 1723806af99SDavid du Colombier char rformat; /* print format: 'x', 'X', 'f', '8', '3', 'Y', 'W' */ 173219b2ee8SDavid du Colombier }; 174219b2ee8SDavid du Colombier 175219b2ee8SDavid du Colombier enum { /* bits in rflags field */ 176219b2ee8SDavid du Colombier RINT = (0<<0), 177219b2ee8SDavid du Colombier RFLT = (1<<0), 178219b2ee8SDavid du Colombier RRDONLY = (1<<1), 1793e12c5d1SDavid du Colombier }; 180375daca8SDavid du Colombier 1813e12c5d1SDavid du Colombier /* 182219b2ee8SDavid du Colombier * Machine-dependent data is stored in two structures: 183219b2ee8SDavid du Colombier * Mach - miscellaneous general parameters 184219b2ee8SDavid du Colombier * Machdata - jump vector of service functions used by debuggers 185219b2ee8SDavid du Colombier * 186375daca8SDavid du Colombier * Mach is defined in ?.c and set in executable.c 187219b2ee8SDavid du Colombier * 188375daca8SDavid du Colombier * Machdata is defined in ?db.c 189219b2ee8SDavid du Colombier * and set in the debugger startup. 1903e12c5d1SDavid du Colombier */ 1913e12c5d1SDavid du Colombier struct Mach{ 1923e12c5d1SDavid du Colombier char *name; 193219b2ee8SDavid du Colombier int mtype; /* machine type code */ 1943e12c5d1SDavid du Colombier Reglist *reglist; /* register set */ 1954de34a7eSDavid du Colombier long regsize; /* sizeof registers in bytes */ 1964de34a7eSDavid du Colombier long fpregsize; /* sizeof fp registers in bytes */ 197219b2ee8SDavid du Colombier char *pc; /* pc name */ 198219b2ee8SDavid du Colombier char *sp; /* sp name */ 199219b2ee8SDavid du Colombier char *link; /* link register name */ 2003e12c5d1SDavid du Colombier char *sbreg; /* static base register name */ 2013806af99SDavid du Colombier uvlong sb; /* static base register value */ 2027dd7cddfSDavid du Colombier int pgsize; /* page size */ 2033806af99SDavid du Colombier uvlong kbase; /* kernel base address */ 2043806af99SDavid du Colombier uvlong ktmask; /* ktzero = kbase & ~ktmask */ 2054de34a7eSDavid du Colombier uvlong utop; /* user stack top */ 2067dd7cddfSDavid du Colombier int pcquant; /* quantization of pc */ 2073e12c5d1SDavid du Colombier int szaddr; /* sizeof(void*) */ 2083e12c5d1SDavid du Colombier int szreg; /* sizeof(register) */ 2093e12c5d1SDavid du Colombier int szfloat; /* sizeof(float) */ 2103e12c5d1SDavid du Colombier int szdouble; /* sizeof(double) */ 2113e12c5d1SDavid du Colombier }; 2123e12c5d1SDavid du Colombier 2133e12c5d1SDavid du Colombier extern Mach *mach; /* Current machine */ 2143e12c5d1SDavid du Colombier 2154de34a7eSDavid du Colombier typedef uvlong (*Rgetter)(Map*, char*); 2164de34a7eSDavid du Colombier typedef void (*Tracer)(Map*, uvlong, uvlong, Symbol*); 2173e12c5d1SDavid du Colombier 218219b2ee8SDavid du Colombier struct Machdata { /* Machine-dependent debugger support */ 2193e12c5d1SDavid du Colombier uchar bpinst[4]; /* break point instr. */ 2203e12c5d1SDavid du Colombier short bpsize; /* size of break point instr. */ 2213e12c5d1SDavid du Colombier 2224de34a7eSDavid du Colombier ushort (*swab)(ushort); /* ushort to local byte order */ 2234de34a7eSDavid du Colombier ulong (*swal)(ulong); /* ulong to local byte order */ 2244de34a7eSDavid du Colombier uvlong (*swav)(uvlong); /* uvlong to local byte order */ 2254de34a7eSDavid du Colombier int (*ctrace)(Map*, uvlong, uvlong, uvlong, Tracer); /* C traceback */ 2264de34a7eSDavid du Colombier uvlong (*findframe)(Map*, uvlong, uvlong, uvlong, uvlong);/* frame finder */ 227219b2ee8SDavid du Colombier char* (*excep)(Map*, Rgetter); /* last exception */ 2284de34a7eSDavid du Colombier ulong (*bpfix)(uvlong); /* breakpoint fixup */ 229219b2ee8SDavid du Colombier int (*sftos)(char*, int, void*); /* single precision float */ 230219b2ee8SDavid du Colombier int (*dftos)(char*, int, void*); /* double precision float */ 2314de34a7eSDavid du Colombier int (*foll)(Map*, uvlong, Rgetter, uvlong*);/* follow set */ 2324de34a7eSDavid du Colombier int (*das)(Map*, uvlong, char, char*, int); /* symbolic disassembly */ 2334de34a7eSDavid du Colombier int (*hexinst)(Map*, uvlong, char*, int); /* hex disassembly */ 2344de34a7eSDavid du Colombier int (*instsize)(Map*, uvlong); /* instruction size */ 2353e12c5d1SDavid du Colombier }; 2363e12c5d1SDavid du Colombier 2373e12c5d1SDavid du Colombier /* 238bd389b36SDavid du Colombier * Common a.out header describing all architectures 2393e12c5d1SDavid du Colombier */ 2403e12c5d1SDavid du Colombier typedef struct Fhdr 2413e12c5d1SDavid du Colombier { 2423e12c5d1SDavid du Colombier char *name; /* identifier of executable */ 2434de34a7eSDavid du Colombier uchar type; /* file type - see codes above */ 2444de34a7eSDavid du Colombier uchar hdrsz; /* header size */ 2452cca75a1SDavid du Colombier uchar _magic; /* _MAGIC() magic */ 2462cca75a1SDavid du Colombier uchar spare; 2473e12c5d1SDavid du Colombier long magic; /* magic number */ 2484de34a7eSDavid du Colombier uvlong txtaddr; /* text address */ 2494de34a7eSDavid du Colombier vlong txtoff; /* start of text in file */ 2504de34a7eSDavid du Colombier uvlong dataddr; /* start of data segment */ 2514de34a7eSDavid du Colombier vlong datoff; /* offset to data seg in file */ 2524de34a7eSDavid du Colombier vlong symoff; /* offset of symbol table in file */ 2534de34a7eSDavid du Colombier uvlong entry; /* entry point */ 2544de34a7eSDavid du Colombier vlong sppcoff; /* offset of sp-pc table in file */ 2554de34a7eSDavid du Colombier vlong lnpcoff; /* offset of line number-pc table in file */ 2563e12c5d1SDavid du Colombier long txtsz; /* text size */ 2573e12c5d1SDavid du Colombier long datsz; /* size of data seg */ 2583e12c5d1SDavid du Colombier long bsssz; /* size of bss */ 2593e12c5d1SDavid du Colombier long symsz; /* size of symbol table */ 2603e12c5d1SDavid du Colombier long sppcsz; /* size of sp-pc table */ 2613e12c5d1SDavid du Colombier long lnpcsz; /* size of line number-pc table */ 2623e12c5d1SDavid du Colombier } Fhdr; 2633e12c5d1SDavid du Colombier 264219b2ee8SDavid du Colombier extern int asstype; /* dissembler type - machdata.c */ 265219b2ee8SDavid du Colombier extern Machdata *machdata; /* jump vector - machdata.c */ 2663e12c5d1SDavid du Colombier 2677dd7cddfSDavid du Colombier Map* attachproc(int, int, int, Fhdr*); 268219b2ee8SDavid du Colombier int beieee80ftos(char*, int, void*); 269219b2ee8SDavid du Colombier int beieeesftos(char*, int, void*); 270219b2ee8SDavid du Colombier int beieeedftos(char*, int, void*); 2713e12c5d1SDavid du Colombier ushort beswab(ushort); 2724de34a7eSDavid du Colombier ulong beswal(ulong); 2734de34a7eSDavid du Colombier uvlong beswav(uvlong); 2744de34a7eSDavid du Colombier uvlong ciscframe(Map*, uvlong, uvlong, uvlong, uvlong); 2754de34a7eSDavid du Colombier int cisctrace(Map*, uvlong, uvlong, uvlong, Tracer); 276219b2ee8SDavid du Colombier int crackhdr(int fd, Fhdr*); 2774de34a7eSDavid du Colombier uvlong file2pc(char*, long); 2783e12c5d1SDavid du Colombier int fileelem(Sym**, uchar *, char*, int); 2794de34a7eSDavid du Colombier long fileline(char*, int, uvlong); 280bd389b36SDavid du Colombier int filesym(int, char*, int); 2813e12c5d1SDavid du Colombier int findlocal(Symbol*, char*, Symbol*); 282219b2ee8SDavid du Colombier int findseg(Map*, char*); 2834de34a7eSDavid du Colombier int findsym(uvlong, int, Symbol *); 2844de34a7eSDavid du Colombier int fnbound(uvlong, uvlong*); 285219b2ee8SDavid du Colombier int fpformat(Map*, Reglist*, char*, int, int); 2864de34a7eSDavid du Colombier int get1(Map*, uvlong, uchar*, int); 2874de34a7eSDavid du Colombier int get2(Map*, uvlong, ushort*); 2884de34a7eSDavid du Colombier int get4(Map*, uvlong, ulong*); 2894de34a7eSDavid du Colombier int get8(Map*, uvlong, uvlong*); 2904de34a7eSDavid du Colombier int geta(Map*, uvlong, uvlong*); 2913e12c5d1SDavid du Colombier int getauto(Symbol*, int, int, Symbol*); 2923e12c5d1SDavid du Colombier Sym* getsym(int); 2933e12c5d1SDavid du Colombier int globalsym(Symbol *, int); 294219b2ee8SDavid du Colombier char* _hexify(char*, ulong, int); 295219b2ee8SDavid du Colombier int ieeesftos(char*, int, ulong); 296219b2ee8SDavid du Colombier int ieeedftos(char*, int, ulong, ulong); 297bd389b36SDavid du Colombier int isar(Biobuf*); 298219b2ee8SDavid du Colombier int leieee80ftos(char*, int, void*); 299219b2ee8SDavid du Colombier int leieeesftos(char*, int, void*); 300219b2ee8SDavid du Colombier int leieeedftos(char*, int, void*); 3013e12c5d1SDavid du Colombier ushort leswab(ushort); 3024de34a7eSDavid du Colombier ulong leswal(ulong); 3034de34a7eSDavid du Colombier uvlong leswav(uvlong); 3044de34a7eSDavid du Colombier uvlong line2addr(long, uvlong, uvlong); 3053e12c5d1SDavid du Colombier Map* loadmap(Map*, int, Fhdr*); 3064de34a7eSDavid du Colombier int localaddr(Map*, char*, char*, uvlong*, Rgetter); 3073e12c5d1SDavid du Colombier int localsym(Symbol*, int); 3083e12c5d1SDavid du Colombier int lookup(char*, char*, Symbol*); 3093e12c5d1SDavid du Colombier void machbytype(int); 3103e12c5d1SDavid du Colombier int machbyname(char*); 311bd389b36SDavid du Colombier int nextar(Biobuf*, int, char*); 3127dd7cddfSDavid du Colombier Map* newmap(Map*, int); 313219b2ee8SDavid du Colombier void objtraverse(void(*)(Sym*, void*), void*); 314219b2ee8SDavid du Colombier int objtype(Biobuf*, char**); 3154de34a7eSDavid du Colombier uvlong pc2sp(uvlong); 3164de34a7eSDavid du Colombier long pc2line(uvlong); 3174de34a7eSDavid du Colombier int put1(Map*, uvlong, uchar*, int); 3184de34a7eSDavid du Colombier int put2(Map*, uvlong, ushort); 3194de34a7eSDavid du Colombier int put4(Map*, uvlong, ulong); 3204de34a7eSDavid du Colombier int put8(Map*, uvlong, uvlong); 3214de34a7eSDavid du Colombier int puta(Map*, uvlong, uvlong); 3224de34a7eSDavid du Colombier int readar(Biobuf*, int, vlong, int); 323bd389b36SDavid du Colombier int readobj(Biobuf*, int); 3244de34a7eSDavid du Colombier uvlong riscframe(Map*, uvlong, uvlong, uvlong, uvlong); 3254de34a7eSDavid du Colombier int risctrace(Map*, uvlong, uvlong, uvlong, Tracer); 3264de34a7eSDavid du Colombier int setmap(Map*, int, uvlong, uvlong, vlong, char*); 3273e12c5d1SDavid du Colombier Sym* symbase(long*); 3283e12c5d1SDavid du Colombier int syminit(int, Fhdr*); 3294de34a7eSDavid du Colombier int symoff(char*, int, uvlong, int); 3304de34a7eSDavid du Colombier void textseg(uvlong, Fhdr*); 3313e12c5d1SDavid du Colombier int textsym(Symbol*, int); 3323e12c5d1SDavid du Colombier void unusemap(Map*, int); 333