Blob


1 /*
2 * Architecture-dependent application data.
3 *
4 * The code assumes that ulong is big enough to hold
5 * an address on any system of interest as well as any
6 * register. Debugging 64-bit code on 32-bit machines
7 * will be interesting.
8 *
9 * Supported architectures:
10 *
11 * MIPS R3000
12 * Motorola 68020
13 * Intel 386
14 * SPARC
15 * PowerPC (limited)
16 * ARM (limited)
17 * Intel 960 (limited)
18 * AT&T 3210 DSP (limited)
19 * MIPS2 (R4000)
20 */
22 typedef struct Fhdr Fhdr;
23 typedef struct Loc Loc;
24 typedef struct Mach Mach;
25 typedef struct Map Map;
26 typedef struct Regdesc Regdesc;
27 typedef struct Regs Regs;
28 typedef struct Seg Seg;
29 typedef struct Symbol Symbol;
30 typedef struct Symtype Symtype;
32 typedef int (*Tracer)(Map*, Regs*, ulong, ulong, Symbol*, int);
34 extern Mach *mach;
35 extern Mach *machcpu;
37 /*
38 * Byte-order data layout manipulation.
39 * swap.c ieee.c
40 */
41 u16int beswap2(u16int u);
42 u32int beswap4(u32int u);
43 u64int beswap8(u64int u);
44 int beieeeftoa32(char*, uint, void*);
45 int beieeeftoa64(char*, uint, void*);
46 int beieeeftoa80(char*, uint, void*);
48 u16int leswap2(u16int u);
49 u32int leswap4(u32int u);
50 u64int leswap8(u64int u);
51 int leieeeftoa32(char *a, uint n, void *v);
52 int leieeeftoa64(char *a, uint n, void *v);
53 int leieeeftoa80(char *a, uint n, void *v);
55 u16int beload2(uchar*);
56 u32int beload4(uchar*);
57 u64int beload8(uchar*);
59 u16int leload2(uchar*);
60 u32int leload4(uchar*);
61 u64int leload8(uchar*);
63 int ieeeftoa32(char *a, uint n, u32int u);
64 int ieeeftoa64(char *a, uint n, u32int h, u32int u);
66 /*
67 * Machine-independent access to an executable image.
68 * map.c
69 */
70 struct Seg
71 {
72 char *name;
73 char *file;
74 uchar *p;
75 int fd;
76 int pid;
77 ulong base;
78 ulong size;
79 ulong offset;
80 int (*rw)(Map*, Seg*, ulong, void*, uint, int);
81 };
83 struct Map
84 {
85 int nseg;
86 Seg *seg;
87 };
89 struct Regs
90 {
91 int (*rw)(Regs*, char*, ulong*, int);
92 };
94 typedef struct UregRegs UregRegs;
95 struct UregRegs
96 {
97 Regs r;
98 uchar *ureg;
99 };
100 int _uregrw(Regs*, char*, ulong*, int);
102 typedef struct PidRegs PidRegs;
103 struct PidRegs
105 Regs r;
106 int pid;
107 };
109 Map* allocmap(void);
110 int addseg(Map *map, Seg seg);
111 int findseg(Map *map, char *name, char *file);
112 int addrtoseg(Map *map, ulong addr, Seg *seg);
113 int addrtosegafter(Map *map, ulong addr, Seg *seg);
114 void removeseg(Map *map, int i);
115 void freemap(Map*);
117 int get1(Map *map, ulong addr, uchar *a, uint n);
118 int get2(Map *map, ulong addr, u16int *u);
119 int get4(Map *map, ulong addr, u32int *u);
120 int get8(Map *map, ulong addr, u64int *u);
122 int put1(Map *map, ulong addr, uchar *a, uint n);
123 int put2(Map *map, ulong addr, u16int u);
124 int put4(Map *map, ulong addr, u32int u);
125 int put8(Map *map, ulong addr, u64int u);
127 int rget(Regs*, char*, ulong*);
128 int rput(Regs*, char*, ulong);
130 /*
131 * A location is either a memory address or a register.
132 * It is useful to be able to specify constant values that
133 * originate from outside the register set and memory,
134 * hence LCONST. If the register values are known, then
135 * we can dispense with LOFFSET, but it's useful to be able
136 * to look up local symbols (via findlsym) with locations
137 * like 8(BP).
139 * loc.c
140 */
142 enum
144 /* location type */
145 LNONE,
146 LREG, /* register */
147 LADDR, /* absolute address */
148 LCONST, /* constant (an anonymous readonly location) */
149 LOFFSET, /* dereference offset + register ptr */
150 };
152 struct Loc
154 uint type; /* LNONE, ... */
155 char *reg; /* LREG */
156 ulong addr; /* LADDR, CONST */
157 long offset; /* LOFFSET */
158 };
160 int lget1(Map *map, Regs *regs, Loc loc, uchar *a, uint n);
161 int lget2(Map *map, Regs *regs, Loc loc, u16int *v);
162 int lget4(Map *map, Regs *regs, Loc loc, u32int *v);
163 int lget8(Map *map, Regs *regs, Loc loc, u64int *v);
165 int lput1(Map *map, Regs *regs, Loc loc, uchar *a, uint n);
166 int lput2(Map *map, Regs *regs, Loc loc, u16int v);
167 int lput4(Map *map, Regs *regs, Loc loc, u32int v);
168 int lput8(Map *map, Regs *regs, Loc loc, u64int v);
170 Loc locnone(void);
171 Loc locaddr(ulong addr);
172 Loc locconst(ulong con);
173 Loc locreg(char*);
174 Loc locindir(char*, long);
176 /*
177 * Executable file parsing.
179 * An Fhdr represents an open file image.
180 * The contents are a grab bag of constants used for the
181 * various file types. Not all elements are used by all
182 * file types.
184 * crackadotplan9.c crackadotunix.c
185 * crackelf.c crackdwarf.c
186 */
187 enum
189 /* file types */
190 FNONE,
191 FEXEC, /* executable image */
192 FLIB, /* library */
193 FOBJ, /* object file */
194 FRELOC, /* relocatable executable */
195 FSHLIB, /* shared library */
196 FSHOBJ, /* shared object */
197 FCORE, /* core dump */
198 FBOOT, /* bootable image */
199 FKERNEL, /* kernel image */
200 NFTYPE,
202 /* abi types */
203 ANONE = 0,
204 APLAN9,
205 ALINUX,
206 AFREEBSD,
207 AMACH,
208 NATYPE
209 };
211 /* I wish this could be kept in stabs.h */
212 struct Stab
214 uchar *stabbase;
215 uint stabsize;
216 char *strbase;
217 uint strsize;
218 u16int (*e2)(uchar*);
219 u32int (*e4)(uchar*);
220 };
222 struct Fhdr
224 int fd; /* file descriptor */
225 char *filename; /* file name */
226 Mach *mach; /* machine */
227 char *mname; /* 386, power, ... */
228 uint mtype; /* machine type M386, ... */
229 char *fname; /* core, executable, boot image, ... */
230 uint ftype; /* file type FCORE, ... */
231 char *aname; /* abi name */
232 uint atype; /* abi type ALINUX, ... */
234 ulong magic; /* magic number */
235 ulong txtaddr; /* text address */
236 ulong entry; /* entry point */
237 ulong txtsz; /* text size */
238 ulong txtoff; /* text offset in file */
239 ulong dataddr; /* data address */
240 ulong datsz; /* data size */
241 ulong datoff; /* data offset in file */
242 ulong bsssz; /* bss size */
243 ulong symsz; /* symbol table size */
244 ulong symoff; /* symbol table offset in file */
245 ulong sppcsz; /* size of sp-pc table */
246 ulong sppcoff; /* offset of sp-pc table in file */
247 ulong lnpcsz; /* size of line number-pc table */
248 ulong lnpcoff; /* size of line number-pc table */
249 void *elf; /* handle to elf image */
250 void *dwarf; /* handle to dwarf image */
251 void *macho; /* handle to mach-o image */
252 struct Stab stabs;
254 /* private */
255 Symbol *sym; /* cached list of symbols */
256 Symbol **byname;
257 uint nsym;
258 Symbol *esym; /* elf symbols */
259 Symbol **ebyname;
260 uint nesym;
261 ulong base; /* base address for relocatables */
262 Fhdr *next; /* link to next fhdr (internal) */
264 /* file mapping */
265 int (*map)(Fhdr*, ulong, Map*, Regs**);
267 /* debugging symbol access; see below */
268 int (*syminit)(Fhdr*);
269 void (*symclose)(Fhdr*);
271 int (*pc2file)(Fhdr*, ulong, char*, uint, ulong*);
272 int (*file2pc)(Fhdr*, char*, ulong, ulong*);
273 int (*line2pc)(Fhdr*, ulong, ulong, ulong*);
275 int (*lookuplsym)(Fhdr*, Symbol*, char*, Symbol*);
276 int (*indexlsym)(Fhdr*, Symbol*, uint, Symbol*);
277 int (*findlsym)(Fhdr*, Symbol*, Loc, Symbol*);
279 int (*unwind)(Fhdr*, Map*, Regs*, ulong*);
280 };
282 Fhdr* crackhdr(char *file, int mode);
283 void uncrackhdr(Fhdr *hdr);
284 int crackelf(int fd, Fhdr *hdr);
285 int crackmacho(int fd, Fhdr *hdr);
287 int syminit(Fhdr*);
288 int symdwarf(Fhdr*);
289 int symelf(Fhdr*);
290 int symstabs(Fhdr*);
291 int symmacho(Fhdr*);
293 int mapfile(Fhdr *fp, ulong base, Map *map, Regs **regs);
294 void unmapfile(Fhdr *fp, Map *map);
296 /*
297 * Process manipulation.
298 */
299 int mapproc(int pid, Map *map, Regs **regs);
300 void unmapproc(Map *map);
301 int detachproc(int pid);
302 int ctlproc(int pid, char *msg);
303 int procnotes(int pid, char ***notes);
304 char* proctextfile(int pid);
306 /*
307 * Machine descriptions.
309 * mach.c
310 * mach386.c dis386.c
311 * machsparc.c dissparc.c
312 * ...
313 */
315 /*
316 * Register sets. The Regs are opaque, accessed by using
317 * the reglist (and really the accessor functions).
318 */
319 enum
321 /* must be big enough for all machine register sets */
322 REGSIZE = 256,
324 RINT = 0<<0,
325 RFLT = 1<<0,
326 RRDONLY = 1<<1,
327 };
329 struct Regdesc
331 char *name; /* register name */
332 uint offset; /* offset in b */
333 uint flags; /* RINT/RFLT/RRDONLY */
334 uint format; /* print format: 'x', 'X', 'f', 'z', 'Z' */
335 };
337 Regdesc* regdesc(char*);
339 enum
341 /* machine types */
342 MNONE,
343 MMIPS, /* MIPS R3000 */
344 MSPARC, /* SUN SPARC */
345 M68000, /* Motorola 68000 */
346 M386, /* Intel 32-bit x86*/
347 M960, /* Intel 960 */
348 M3210, /* AT&T 3210 DSP */
349 MMIPS2, /* MIPS R4000 */
350 M29000, /* AMD 29000 */
351 MARM, /* ARM */
352 MPOWER, /* PowerPC */
353 MALPHA, /* DEC/Compaq Alpha */
354 NMTYPE
355 };
357 struct Mach
359 char *name; /* "386", ... */
360 uint type; /* M386, ... */
361 Regdesc *reglist; /* register set */
362 uint regsize; /* size of register set in bytes */
363 uint fpregsize; /* size of fp register set in bytes */
364 char *pc; /* name of program counter */
365 char *sp; /* name of stack pointer */
366 char *fp; /* name of frame pointer */
367 char *link; /* name of link register */
368 char *sbreg; /* name of static base */
369 ulong sb; /* value of static base */
370 uint pgsize; /* page size */
371 ulong kbase; /* kernel base address for Plan 9 */
372 ulong ktmask; /* ktzero = kbase & ~ktmask */
373 uint pcquant; /* pc quantum */
374 uint szaddr; /* size of pointer in bytes */
375 uint szreg; /* size of integer register */
376 uint szfloat; /* size of float */
377 uint szdouble; /* size of double */
378 char** windreg; /* unwinding registers */
379 uint nwindreg;
381 uchar bpinst[4]; /* break point instruction */
382 uint bpsize; /* size of bp instruction */
384 int (*foll)(Map*, Regs*, ulong, ulong*); /* follow set */
385 char* (*exc)(Map*, Regs*); /* last exception */
386 int (*unwind)(Map*, Regs*, ulong*);
388 /* cvt to local byte order */
389 u16int (*swap2)(u16int);
390 u32int (*swap4)(u32int);
391 u64int (*swap8)(u64int);
392 int (*ftoa32)(char*, uint, void*);
393 int (*ftoa64)(char*, uint, void*);
394 int (*ftoa80)(char*, uint, void*);
396 /* disassembly */
397 int (*das)(Map*, ulong, char, char*, int); /* symbolic */
398 int (*kendas)(Map*, ulong, char, char*, int); /* symbolic */
399 int (*codas)(Map*, ulong, char, char*, int);
400 int (*hexinst)(Map*, ulong, char*, int); /* hex */
401 int (*instsize)(Map*, ulong); /* instruction size */
402 };
404 Mach *machbyname(char*);
405 Mach *machbytype(uint);
407 extern Mach mach386;
408 extern Mach machsparc;
409 extern Mach machmips;
410 extern Mach machpower;
412 /*
413 * Debugging symbols and type information.
414 * (Not all objects include type information.)
416 * sym.c
417 */
419 enum
421 /* symbol table classes */
422 CNONE,
423 CAUTO, /* stack variable */
424 CPARAM, /* function parameter */
425 CTEXT, /* text segment */
426 CDATA, /* data segment */
427 CANY,
428 };
430 struct Symbol
432 char *name; /* name of symbol */
433 /* Symtype *typedesc; /* type info, if any */
434 Loc loc; /* location of symbol */
435 Loc hiloc; /* location of end of symbol */
436 char class; /* CAUTO, ... */
437 char type; /* type letter from a.out.h */
438 Fhdr *fhdr; /* where did this come from? */
439 uint index; /* in by-address list */
441 /* private use by various symbol implementations */
442 union {
443 struct {
444 uint unit;
445 uint uoff;
446 } dwarf;
447 struct {
448 uint i;
449 uint locals;
450 char *dir;
451 char *file;
452 char frameptr;
453 uint framesize;
454 } stabs;
455 } u;
456 };
458 /* look through all currently cracked Fhdrs calling their fns */
459 int pc2file(ulong pc, char *file, uint nfile, ulong *line);
460 int file2pc(char *file, ulong line, ulong *addr);
461 int line2pc(ulong basepc, ulong line, ulong *pc);
462 int fnbound(ulong pc, ulong *bounds);
463 int fileline(ulong pc, char *a, uint n);
464 int pc2line(ulong pc, ulong *line);
466 int lookupsym(char *fn, char *var, Symbol *s);
467 int indexsym(uint ndx, Symbol *s);
468 int findsym(Loc loc, uint class, Symbol *s);
469 int findexsym(Fhdr*, uint, Symbol*);
471 int lookuplsym(Symbol *s1, char *name, Symbol *s2);
472 int indexlsym(Symbol *s1, uint ndx, Symbol *s2);
473 int findlsym(Symbol *s1, Loc loc, Symbol *s);
474 int symoff(char *a, uint n, ulong addr, uint class);
475 int unwindframe(Map *map, Regs *regs, ulong *next);
477 void _addhdr(Fhdr*);
478 void _delhdr(Fhdr*);
479 extern Fhdr* fhdrlist;
481 Symbol* flookupsym(Fhdr*, char*);
482 Symbol* ffindsym(Fhdr*, Loc, uint);
483 Symbol* addsym(Fhdr*, Symbol*);
485 /*
486 * Stack frame walking.
488 * frame.c
489 */
490 int stacktrace(Map*, Regs*, Tracer);
491 int windindex(char*);
492 Loc* windreglocs(void);
494 /*
495 * Debugger help.
496 */
497 int localaddr(Map *map, Regs *regs, char *fn, char *var, ulong *val);
498 int fpformat(Map *map, Regdesc *reg, char *a, uint n, uint code);
499 char* _hexify(char*, ulong, int);
500 int locfmt(Fmt*);
501 int loccmp(Loc*, Loc*);
502 int locsimplify(Map *map, Regs *regs, Loc loc, Loc *newloc);
504 extern int machdebug;