123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- /*
- * Architecture-dependent application data
- */
- #include "elf.h"
- /*
- * Supported architectures:
- * mips,
- * 68020,
- * i386,
- * amd64,
- * sparc,
- * mips2 (R4000)
- * arm
- * powerpc,
- * powerpc64
- * arm64
- */
- enum
- {
- MMIPS, /* machine types */
- MSPARC,
- M68020,
- MI386,
- MI960, /* retired */
- M3210, /* retired */
- MMIPS2,
- NMIPS2,
- M29000, /* retired */
- MARM,
- MPOWER,
- MALPHA, /* retired */
- NMIPS,
- MSPARC64, /* retired */
- MAMD64,
- MPOWER64,
- MARM64,
- /* types of executables */
- FNONE = 0, /* unidentified */
- FMIPS, /* v.out */
- FMIPSB, /* mips bootable */
- FSPARC, /* k.out */
- FSPARCB, /* Sparc bootable */
- F68020, /* 2.out */
- F68020B, /* 68020 bootable */
- FNEXTB, /* Next bootable */
- FI386, /* 8.out */
- FI386B, /* I386 bootable */
- FI960, /* retired */
- FI960B, /* retired */
- F3210, /* retired */
- FMIPS2BE, /* 4.out */
- F29000, /* retired */
- FARM, /* 5.out */
- FARMB, /* ARM bootable */
- FPOWER, /* q.out */
- FPOWERB, /* power pc bootable */
- FMIPS2LE, /* 0.out */
- FALPHA, /* retired */
- FALPHAB, /* retired DEC Alpha bootable */
- FMIPSLE, /* 3k little endian */
- FSPARC64, /* retired */
- FAMD64, /* 6.out */
- FAMD64B, /* 6.out bootable */
- FPOWER64, /* 9.out */
- FPOWER64B, /* 9.out bootable */
- FARM64, /* arm64 */
- FARM64B, /* arm64 bootable */
- ANONE = 0, /* dissembler types */
- AMIPS,
- AMIPSCO, /* native mips */
- ASPARC,
- ASUNSPARC, /* native sun */
- A68020,
- AI386,
- AI8086, /* oh god */
- AI960, /* retired */
- A29000, /* retired */
- AARM,
- APOWER,
- AALPHA, /* retired */
- ASPARC64, /* retired */
- AAMD64,
- APOWER64,
- AARM64,
- /* object file types */
- Obj68020 = 0, /* .2 */
- ObjSparc, /* .k */
- ObjMips, /* .v */
- Obj386, /* .8 */
- Obj960, /* retired */
- Obj3210, /* retired */
- ObjMips2, /* .4 */
- Obj29000, /* retired */
- ObjArm, /* .5 */
- ObjPower, /* .q */
- ObjMips2le, /* .0 */
- ObjAlpha, /* retired */
- ObjSparc64, /* retired */
- ObjAmd64, /* .6 */
- ObjSpim, /* .0 */
- ObjPower64, /* .9 */
- ObjArm64, /* .4? */
- Maxobjtype,
- CNONE = 0, /* symbol table classes */
- CAUTO,
- CPARAM,
- CSTAB,
- CTEXT,
- CDATA,
- CANY, /* to look for any class */
- };
- typedef struct Map Map;
- typedef struct Symbol Symbol;
- typedef struct Reglist Reglist;
- typedef struct Mach Mach;
- typedef struct Machdata Machdata;
- /*
- * Structure to map a segment to a position in a file
- */
- struct Map {
- int nsegs; /* number of segments */
- struct segment { /* per-segment map */
- char *name; /* the segment name */
- int fd; /* file descriptor */
- int inuse; /* in use - not in use */
- int cache; /* should cache reads? */
- uint64_t b; /* base */
- uint64_t e; /* end */
- int64_t f; /* offset within file */
- } seg[1]; /* actually n of these */
- };
- /*
- * Internal structure describing a symbol table entry
- */
- struct Symbol {
- void *handle; /* used internally - owning func */
- struct {
- char *name;
- int64_t value; /* address or stack offset */
- char type; /* as in a.out.h */
- char class; /* as above */
- int index; /* in findlocal, globalsym, textsym */
- };
- };
- /*
- * machine register description
- */
- struct Reglist {
- char *rname; /* register name */
- int16_t roffs; /* offset in u-block */
- char rflags; /* INTEGER/FLOAT, WRITABLE */
- char rformat; /* print format: 'x', 'X', 'f', '8', '3', 'Y', 'W' */
- };
- enum { /* bits in rflags field */
- RINT = (0<<0),
- RFLT = (1<<0),
- RRDONLY = (1<<1),
- };
- /*
- * Machine-dependent data is stored in two structures:
- * Mach - miscellaneous general parameters
- * Machdata - jump vector of service functions used by debuggers
- *
- * Mach is defined in ?.c and set in executable.c
- *
- * Machdata is defined in ?db.c
- * and set in the debugger startup.
- */
- struct Mach{
- char *name;
- int mtype; /* machine type code */
- Reglist *reglist; /* register set */
- int32_t regsize; /* sizeof registers in bytes */
- int32_t fpregsize; /* sizeof fp registers in bytes */
- char *pc; /* pc name */
- char *sp; /* sp name */
- char *link; /* link register name */
- char *sbreg; /* static base register name */
- uint64_t sb; /* static base register value */
- int pgsize; /* page size */
- uint64_t kbase; /* kernel base address */
- uint64_t ktmask; /* ktzero = kbase & ~ktmask */
- uint64_t utop; /* user stack top */
- int pcquant; /* quantization of pc */
- int szaddr; /* sizeof(void*) */
- int szreg; /* sizeof(register) */
- int szfloat; /* sizeof(float) */
- int szdouble; /* sizeof(double) */
- };
- extern Mach *mach; /* Current machine */
- typedef uint64_t (*Rgetter)(Map*, char*);
- typedef void (*Tracer)(Map*, uint64_t, uint64_t, Symbol*);
- struct Machdata { /* Machine-dependent debugger support */
- uint8_t bpinst[4]; /* break point instr. */
- int16_t bpsize; /* size of break point instr. */
- uint16_t (*swab)(uint16_t); /* ushort to local byte order */
- uint32_t (*swal)(uint32_t); /* ulong to local byte order */
- uint64_t (*swav)(uint64_t); /* uvlong to local byte order */
- int (*ctrace)(Map*, uint64_t, uint64_t, uint64_t, Tracer); /* C traceback */
- uint64_t (*findframe)(Map*, uint64_t, uint64_t, uint64_t,
- uint64_t); /* frame finder */
- char* (*excep)(Map*, Rgetter); /* last exception */
- uint32_t (*bpfix)(uint64_t); /* breakpoint fixup */
- int (*sftos)(char*, int, void*); /* single precision float */
- int (*dftos)(char*, int, void*); /* double precision float */
- int (*foll)(Map*, uint64_t, Rgetter, uint64_t*); /* follow set */
- int (*das)(Map*, uint64_t, char, char*, int); /* symbolic disassembly */
- int (*hexinst)(Map*, uint64_t, char*, int); /* hex disassembly */
- int (*instsize)(Map*, uint64_t); /* instruction size */
- };
- /*
- * Common executable header describing all architectures
- */
- typedef struct Fhdr
- {
- char *name; /* identifier of executable */
- uint8_t type; /* file type - see codes above */
- uint8_t hdrsz; /* header size */
- uint8_t spare;
- int32_t magic; /* magic number */
- uint64_t txtaddr; /* text address */
- int64_t txtoff; /* start of text in file */
- uint64_t dataddr; /* start of data segment */
- int64_t datoff; /* offset to data seg in file */
- int64_t symoff; /* offset of symbol table in file */
- uint64_t entry; /* entry point */
- int64_t sppcoff; /* offset of sp-pc table in file */
- int64_t lnpcoff; /* offset of line number-pc table in file */
- int32_t txtsz; /* text size */
- int32_t datsz; /* size of data seg */
- int32_t bsssz; /* size of bss */
- int32_t symsz; /* size of symbol table */
- int32_t sppcsz; /* size of sp-pc table */
- int32_t lnpcsz; /* size of line number-pc table */
- // TODO work out which of the above are no longer useful
- // and which should be uint64
- int8_t bigendian; /* big endian or not */
- uint64_t stroff; /* strtab offset in file */
- uint64_t strsz; /* size of strtab seg */
- uint16_t bssidx; /* index of bss section */
- uint16_t dbglineidx; /* index of debug_line section */
- } Fhdr;
- extern int asstype; /* dissembler type - machdata.c */
- extern Machdata *machdata; /* jump vector - machdata.c */
- Map* attachproc(int, int, int, Fhdr*);
- int beieee80ftos(char*, int, void*);
- int beieeesftos(char*, int, void*);
- int beieeedftos(char*, int, void*);
- uint16_t beswab(uint16_t);
- uint32_t beswal(uint32_t);
- uint64_t beswav(uint64_t);
- uint64_t ciscframe(Map*, uint64_t, uint64_t, uint64_t, uint64_t);
- int cisctrace(Map*, uint64_t, uint64_t, uint64_t, Tracer);
- int crackhdr(int fd, Fhdr*);
- uint64_t file2pc(char*, int32_t);
- int fileelem(Sym**, uint8_t *, char*, int);
- int32_t fileline(char*, int, uint64_t);
- int filesym(int, char*, int);
- int findlocal(Symbol*, char*, Symbol*);
- int findseg(Map*, char*);
- int findsym(uint64_t, int, Symbol *);
- int fnbound(uint64_t, uint64_t*);
- int fpformat(Map*, Reglist*, char*, int, int);
- int get1(Map*, uint64_t, uint8_t*, int);
- int get2(Map*, uint64_t, uint16_t*);
- int get4(Map*, uint64_t, uint32_t*);
- int get8(Map*, uint64_t, uint64_t*);
- int geta(Map*, uint64_t, uint64_t*);
- int getauto(Symbol*, int, int, Symbol*);
- Sym* getsym(int);
- int globalsym(Symbol *, int);
- char* _hexify(char*, uint32_t, int);
- int ieeesftos(char*, int, uint32_t);
- int ieeedftos(char*, int, uint32_t, uint32_t);
- int isar(Biobuf*);
- int leieee80ftos(char*, int, void*);
- int leieeesftos(char*, int, void*);
- int leieeedftos(char*, int, void*);
- uint16_t leswab(uint16_t);
- uint32_t leswal(uint32_t);
- uint64_t leswav(uint64_t);
- uint64_t line2addr(int32_t, uint64_t, uint64_t);
- Map* loadmap(Map*, int, Fhdr*);
- int localaddr(Map*, char*, char*, uint64_t*, Rgetter);
- int localsym(Symbol*, int);
- int lookup(char*, char*, Symbol*);
- void machbytype(int);
- int machbyname(char*);
- int nextar(Biobuf*, int, char*);
- Map* newmap(Map*, int);
- void objtraverse(void(*)(Sym*, void*), void*);
- int objtype(Biobuf*, char**);
- uint64_t pc2sp(uint64_t);
- int32_t pc2line(uint64_t);
- int put1(Map*, uint64_t, uint8_t*, int);
- int put2(Map*, uint64_t, uint16_t);
- int put4(Map*, uint64_t, uint32_t);
- int put8(Map*, uint64_t, uint64_t);
- int puta(Map*, uint64_t, uint64_t);
- int readar(Biobuf*, int, int64_t, int);
- int readobj(Biobuf*, int);
- uint64_t riscframe(Map*, uint64_t, uint64_t, uint64_t, uint64_t);
- int risctrace(Map*, uint64_t, uint64_t, uint64_t, Tracer);
- int setmap(Map*, int, uint64_t, uint64_t, int64_t, char*);
- Sym* symbase(int32_t*);
- int syminit(int, Fhdr*);
- int symoff(char*, int, uint64_t, int);
- void textseg(uint64_t, Fhdr*);
- int textsym(Symbol*, int);
- void unusemap(Map*, int);
|