aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/mach.h504
1 files changed, 504 insertions, 0 deletions
diff --git a/include/mach.h b/include/mach.h
new file mode 100644
index 00000000..2a1b168a
--- /dev/null
+++ b/include/mach.h
@@ -0,0 +1,504 @@
+/*
+ * Architecture-dependent application data.
+ *
+ * The code assumes that ulong is big enough to hold
+ * an address on any system of interest as well as any
+ * register. Debugging 64-bit code on 32-bit machines
+ * will be interesting.
+ *
+ * Supported architectures:
+ *
+ * MIPS R3000
+ * Motorola 68020
+ * Intel 386
+ * SPARC
+ * PowerPC (limited)
+ * ARM (limited)
+ * Intel 960 (limited)
+ * AT&T 3210 DSP (limited)
+ * MIPS2 (R4000)
+ */
+
+typedef struct Fhdr Fhdr;
+typedef struct Loc Loc;
+typedef struct Mach Mach;
+typedef struct Map Map;
+typedef struct Regdesc Regdesc;
+typedef struct Regs Regs;
+typedef struct Seg Seg;
+typedef struct Symbol Symbol;
+typedef struct Symtype Symtype;
+
+typedef int (*Tracer)(Map*, Regs*, ulong, ulong, Symbol*, int);
+
+extern Mach *mach;
+extern Mach *machcpu;
+
+/*
+ * Byte-order data layout manipulation.
+ * swap.c ieee.c
+ */
+u16int beswap2(u16int u);
+u32int beswap4(u32int u);
+u64int beswap8(u64int u);
+int beieeeftoa32(char*, uint, void*);
+int beieeeftoa64(char*, uint, void*);
+int beieeeftoa80(char*, uint, void*);
+
+u16int leswap2(u16int u);
+u32int leswap4(u32int u);
+u64int leswap8(u64int u);
+int leieeeftoa32(char *a, uint n, void *v);
+int leieeeftoa64(char *a, uint n, void *v);
+int leieeeftoa80(char *a, uint n, void *v);
+
+u16int beload2(uchar*);
+u32int beload4(uchar*);
+u64int beload8(uchar*);
+
+u16int leload2(uchar*);
+u32int leload4(uchar*);
+u64int leload8(uchar*);
+
+int ieeeftoa32(char *a, uint n, u32int u);
+int ieeeftoa64(char *a, uint n, u32int h, u32int u);
+
+/*
+ * Machine-independent access to an executable image.
+ * map.c
+ */
+struct Seg
+{
+ char *name;
+ char *file;
+ uchar *p;
+ int fd;
+ int pid;
+ ulong base;
+ ulong size;
+ ulong offset;
+ int (*rw)(Map*, Seg*, ulong, void*, uint, int);
+};
+
+struct Map
+{
+ int nseg;
+ Seg *seg;
+};
+
+struct Regs
+{
+ int (*rw)(Regs*, char*, ulong*, int);
+};
+
+typedef struct UregRegs UregRegs;
+struct UregRegs
+{
+ Regs r;
+ uchar *ureg;
+};
+int _uregrw(Regs*, char*, ulong*, int);
+
+typedef struct PidRegs PidRegs;
+struct PidRegs
+{
+ Regs r;
+ int pid;
+};
+
+Map* allocmap(void);
+int addseg(Map *map, Seg seg);
+int findseg(Map *map, char *name, char *file);
+int addrtoseg(Map *map, ulong addr, Seg *seg);
+int addrtosegafter(Map *map, ulong addr, Seg *seg);
+void removeseg(Map *map, int i);
+void freemap(Map*);
+
+int get1(Map *map, ulong addr, uchar *a, uint n);
+int get2(Map *map, ulong addr, u16int *u);
+int get4(Map *map, ulong addr, u32int *u);
+int get8(Map *map, ulong addr, u64int *u);
+
+int put1(Map *map, ulong addr, uchar *a, uint n);
+int put2(Map *map, ulong addr, u16int u);
+int put4(Map *map, ulong addr, u32int u);
+int put8(Map *map, ulong addr, u64int u);
+
+int rget(Regs*, char*, ulong*);
+int rput(Regs*, char*, ulong);
+
+/*
+ * A location is either a memory address or a register.
+ * It is useful to be able to specify constant values that
+ * originate from outside the register set and memory,
+ * hence LCONST. If the register values are known, then
+ * we can dispense with LOFFSET, but it's useful to be able
+ * to look up local symbols (via findlsym) with locations
+ * like 8(BP).
+ *
+ * loc.c
+ */
+
+enum
+{
+ /* location type */
+ LNONE,
+ LREG, /* register */
+ LADDR, /* absolute address */
+ LCONST, /* constant (an anonymous readonly location) */
+ LOFFSET, /* dereference offset + register ptr */
+};
+
+struct Loc
+{
+ uint type; /* LNONE, ... */
+ char *reg; /* LREG */
+ ulong addr; /* LADDR, CONST */
+ long offset; /* LOFFSET */
+};
+
+int lget1(Map *map, Regs *regs, Loc loc, uchar *a, uint n);
+int lget2(Map *map, Regs *regs, Loc loc, u16int *v);
+int lget4(Map *map, Regs *regs, Loc loc, u32int *v);
+int lget8(Map *map, Regs *regs, Loc loc, u64int *v);
+
+int lput1(Map *map, Regs *regs, Loc loc, uchar *a, uint n);
+int lput2(Map *map, Regs *regs, Loc loc, u16int v);
+int lput4(Map *map, Regs *regs, Loc loc, u32int v);
+int lput8(Map *map, Regs *regs, Loc loc, u64int v);
+
+Loc locnone(void);
+Loc locaddr(ulong addr);
+Loc locconst(ulong con);
+Loc locreg(char*);
+Loc locindir(char*, long);
+
+/*
+ * Executable file parsing.
+ *
+ * An Fhdr represents an open file image.
+ * The contents are a grab bag of constants used for the
+ * various file types. Not all elements are used by all
+ * file types.
+ *
+ * crackadotplan9.c crackadotunix.c
+ * crackelf.c crackdwarf.c
+ */
+enum
+{
+ /* file types */
+ FNONE,
+ FEXEC, /* executable image */
+ FLIB, /* library */
+ FOBJ, /* object file */
+ FRELOC, /* relocatable executable */
+ FSHLIB, /* shared library */
+ FSHOBJ, /* shared object */
+ FCORE, /* core dump */
+ FBOOT, /* bootable image */
+ FKERNEL, /* kernel image */
+ NFTYPE,
+
+ /* abi types */
+ ANONE = 0,
+ APLAN9,
+ ALINUX,
+ AFREEBSD,
+ AMACH,
+ NATYPE
+};
+
+/* I wish this could be kept in stabs.h */
+struct Stab
+{
+ uchar *stabbase;
+ uint stabsize;
+ char *strbase;
+ uint strsize;
+ u16int (*e2)(uchar*);
+ u32int (*e4)(uchar*);
+};
+
+struct Fhdr
+{
+ int fd; /* file descriptor */
+ char *filename; /* file name */
+ Mach *mach; /* machine */
+ char *mname; /* 386, power, ... */
+ uint mtype; /* machine type M386, ... */
+ char *fname; /* core, executable, boot image, ... */
+ uint ftype; /* file type FCORE, ... */
+ char *aname; /* abi name */
+ uint atype; /* abi type ALINUX, ... */
+
+ ulong magic; /* magic number */
+ ulong txtaddr; /* text address */
+ ulong entry; /* entry point */
+ ulong txtsz; /* text size */
+ ulong txtoff; /* text offset in file */
+ ulong dataddr; /* data address */
+ ulong datsz; /* data size */
+ ulong datoff; /* data offset in file */
+ ulong bsssz; /* bss size */
+ ulong symsz; /* symbol table size */
+ ulong symoff; /* symbol table offset in file */
+ ulong sppcsz; /* size of sp-pc table */
+ ulong sppcoff; /* offset of sp-pc table in file */
+ ulong lnpcsz; /* size of line number-pc table */
+ ulong lnpcoff; /* size of line number-pc table */
+ void *elf; /* handle to elf image */
+ void *dwarf; /* handle to dwarf image */
+ void *macho; /* handle to mach-o image */
+ struct Stab stabs;
+
+ /* private */
+ Symbol *sym; /* cached list of symbols */
+ Symbol **byname;
+ uint nsym;
+ Symbol *esym; /* elf symbols */
+ Symbol **ebyname;
+ uint nesym;
+ ulong base; /* base address for relocatables */
+ Fhdr *next; /* link to next fhdr (internal) */
+
+ /* file mapping */
+ int (*map)(Fhdr*, ulong, Map*, Regs**);
+
+ /* debugging symbol access; see below */
+ int (*syminit)(Fhdr*);
+ void (*symclose)(Fhdr*);
+
+ int (*pc2file)(Fhdr*, ulong, char*, uint, ulong*);
+ int (*file2pc)(Fhdr*, char*, ulong, ulong*);
+ int (*line2pc)(Fhdr*, ulong, ulong, ulong*);
+
+ int (*lookuplsym)(Fhdr*, Symbol*, char*, Symbol*);
+ int (*indexlsym)(Fhdr*, Symbol*, uint, Symbol*);
+ int (*findlsym)(Fhdr*, Symbol*, Loc, Symbol*);
+
+ int (*unwind)(Fhdr*, Map*, Regs*, ulong*);
+};
+
+Fhdr* crackhdr(char *file, int mode);
+void uncrackhdr(Fhdr *hdr);
+int crackelf(int fd, Fhdr *hdr);
+int crackmacho(int fd, Fhdr *hdr);
+
+int syminit(Fhdr*);
+int symdwarf(Fhdr*);
+int symelf(Fhdr*);
+int symstabs(Fhdr*);
+int symmacho(Fhdr*);
+
+int mapfile(Fhdr *fp, ulong base, Map *map, Regs **regs);
+void unmapfile(Fhdr *fp, Map *map);
+
+/*
+ * Process manipulation.
+ */
+int mapproc(int pid, Map *map, Regs **regs);
+void unmapproc(Map *map);
+int detachproc(int pid);
+int ctlproc(int pid, char *msg);
+int procnotes(int pid, char ***notes);
+char* proctextfile(int pid);
+
+/*
+ * Machine descriptions.
+ *
+ * mach.c
+ * mach386.c dis386.c
+ * machsparc.c dissparc.c
+ * ...
+ */
+
+/*
+ * Register sets. The Regs are opaque, accessed by using
+ * the reglist (and really the accessor functions).
+ */
+enum
+{
+ /* must be big enough for all machine register sets */
+ REGSIZE = 256,
+
+ RINT = 0<<0,
+ RFLT = 1<<0,
+ RRDONLY = 1<<1,
+};
+
+struct Regdesc
+{
+ char *name; /* register name */
+ uint offset; /* offset in b */
+ uint flags; /* RINT/RFLT/RRDONLY */
+ uint format; /* print format: 'x', 'X', 'f', 'z', 'Z' */
+};
+
+Regdesc* regdesc(char*);
+
+enum
+{
+ /* machine types */
+ MNONE,
+ MMIPS, /* MIPS R3000 */
+ MSPARC, /* SUN SPARC */
+ M68000, /* Motorola 68000 */
+ M386, /* Intel 32-bit x86*/
+ M960, /* Intel 960 */
+ M3210, /* AT&T 3210 DSP */
+ MMIPS2, /* MIPS R4000 */
+ M29000, /* AMD 29000 */
+ MARM, /* ARM */
+ MPOWER, /* PowerPC */
+ MALPHA, /* DEC/Compaq Alpha */
+ NMTYPE
+};
+
+struct Mach
+{
+ char *name; /* "386", ... */
+ uint type; /* M386, ... */
+ Regdesc *reglist; /* register set */
+ uint regsize; /* size of register set in bytes */
+ uint fpregsize; /* size of fp register set in bytes */
+ char *pc; /* name of program counter */
+ char *sp; /* name of stack pointer */
+ char *fp; /* name of frame pointer */
+ char *link; /* name of link register */
+ char *sbreg; /* name of static base */
+ ulong sb; /* value of static base */
+ uint pgsize; /* page size */
+ ulong kbase; /* kernel base address for Plan 9 */
+ ulong ktmask; /* ktzero = kbase & ~ktmask */
+ uint pcquant; /* pc quantum */
+ uint szaddr; /* size of pointer in bytes */
+ uint szreg; /* size of integer register */
+ uint szfloat; /* size of float */
+ uint szdouble; /* size of double */
+ char** windreg; /* unwinding registers */
+ uint nwindreg;
+
+ uchar bpinst[4]; /* break point instruction */
+ uint bpsize; /* size of bp instruction */
+
+ int (*foll)(Map*, Regs*, ulong, ulong*); /* follow set */
+ char* (*exc)(Map*, Regs*); /* last exception */
+ int (*unwind)(Map*, Regs*, ulong*);
+
+ /* cvt to local byte order */
+ u16int (*swap2)(u16int);
+ u32int (*swap4)(u32int);
+ u64int (*swap8)(u64int);
+ int (*ftoa32)(char*, uint, void*);
+ int (*ftoa64)(char*, uint, void*);
+ int (*ftoa80)(char*, uint, void*);
+
+ /* disassembly */
+ int (*das)(Map*, ulong, char, char*, int); /* symbolic */
+ int (*kendas)(Map*, ulong, char, char*, int); /* symbolic */
+ int (*codas)(Map*, ulong, char, char*, int);
+ int (*hexinst)(Map*, ulong, char*, int); /* hex */
+ int (*instsize)(Map*, ulong); /* instruction size */
+};
+
+Mach *machbyname(char*);
+Mach *machbytype(uint);
+
+extern Mach mach386;
+extern Mach machsparc;
+extern Mach machmips;
+extern Mach machpower;
+
+/*
+ * Debugging symbols and type information.
+ * (Not all objects include type information.)
+ *
+ * sym.c
+ */
+
+enum
+{
+ /* symbol table classes */
+ CNONE,
+ CAUTO, /* stack variable */
+ CPARAM, /* function parameter */
+ CTEXT, /* text segment */
+ CDATA, /* data segment */
+ CANY,
+};
+
+struct Symbol
+{
+ char *name; /* name of symbol */
+ /* Symtype *typedesc; /* type info, if any */
+ Loc loc; /* location of symbol */
+ Loc hiloc; /* location of end of symbol */
+ char class; /* CAUTO, ... */
+ char type; /* type letter from a.out.h */
+ Fhdr *fhdr; /* where did this come from? */
+ uint index; /* in by-address list */
+
+ /* private use by various symbol implementations */
+ union {
+ struct {
+ uint unit;
+ uint uoff;
+ } dwarf;
+ struct {
+ uint i;
+ uint locals;
+ char *dir;
+ char *file;
+ char frameptr;
+ uint framesize;
+ } stabs;
+ } u;
+};
+
+/* look through all currently cracked Fhdrs calling their fns */
+int pc2file(ulong pc, char *file, uint nfile, ulong *line);
+int file2pc(char *file, ulong line, ulong *addr);
+int line2pc(ulong basepc, ulong line, ulong *pc);
+int fnbound(ulong pc, ulong *bounds);
+int fileline(ulong pc, char *a, uint n);
+int pc2line(ulong pc, ulong *line);
+
+int lookupsym(char *fn, char *var, Symbol *s);
+int indexsym(uint ndx, Symbol *s);
+int findsym(Loc loc, uint class, Symbol *s);
+int findexsym(Fhdr*, uint, Symbol*);
+
+int lookuplsym(Symbol *s1, char *name, Symbol *s2);
+int indexlsym(Symbol *s1, uint ndx, Symbol *s2);
+int findlsym(Symbol *s1, Loc loc, Symbol *s);
+int symoff(char *a, uint n, ulong addr, uint class);
+int unwindframe(Map *map, Regs *regs, ulong *next);
+
+void _addhdr(Fhdr*);
+void _delhdr(Fhdr*);
+Fhdr* fhdrlist;
+
+Symbol* flookupsym(Fhdr*, char*);
+Symbol* ffindsym(Fhdr*, Loc, uint);
+Symbol* addsym(Fhdr*, Symbol*);
+
+/*
+ * Stack frame walking.
+ *
+ * frame.c
+ */
+int stacktrace(Map*, Regs*, Tracer);
+int windindex(char*);
+Loc* windreglocs(void);
+
+/*
+ * Debugger help.
+ */
+int localaddr(Map *map, Regs *regs, char *fn, char *var, ulong *val);
+int fpformat(Map *map, Regdesc *reg, char *a, uint n, uint code);
+char* _hexify(char*, ulong, int);
+int locfmt(Fmt*);
+int loccmp(Loc*, Loc*);
+int locsimplify(Map *map, Regs *regs, Loc loc, Loc *newloc);
+
+extern int machdebug;