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 char *txtfil; /* text name, for core files */
250 void *elf; /* handle to elf image */
251 void *dwarf; /* handle to dwarf image */
252 void *macho; /* handle to mach-o image */
253 struct Stab stabs;
255 /* private */
256 Symbol *sym; /* cached list of symbols */
257 Symbol **byname;
258 uint nsym;
259 Symbol *esym; /* elf symbols */
260 Symbol **ebyname;
261 uint nesym;
262 ulong base; /* base address for relocatables */
263 Fhdr *next; /* link to next fhdr (internal) */
265 /* file mapping */
266 int (*map)(Fhdr*, ulong, Map*, Regs**);
268 /* debugging symbol access; see below */
269 int (*syminit)(Fhdr*);
270 void (*symclose)(Fhdr*);
272 int (*pc2file)(Fhdr*, ulong, char*, uint, ulong*);
273 int (*file2pc)(Fhdr*, char*, ulong, ulong*);
274 int (*line2pc)(Fhdr*, ulong, ulong, ulong*);
276 int (*lookuplsym)(Fhdr*, Symbol*, char*, Symbol*);
277 int (*indexlsym)(Fhdr*, Symbol*, uint, Symbol*);
278 int (*findlsym)(Fhdr*, Symbol*, Loc, Symbol*);
280 int (*unwind)(Fhdr*, Map*, Regs*, ulong*, Symbol*);
281 };
283 Fhdr* crackhdr(char *file, int mode);
284 void uncrackhdr(Fhdr *hdr);
285 int crackelf(int fd, Fhdr *hdr);
286 int crackmacho(int fd, Fhdr *hdr);
288 int syminit(Fhdr*);
289 int symdwarf(Fhdr*);
290 int symelf(Fhdr*);
291 int symstabs(Fhdr*);
292 int symmacho(Fhdr*);
294 int mapfile(Fhdr *fp, ulong base, Map *map, Regs **regs);
295 void unmapfile(Fhdr *fp, Map *map);
297 /*
298 * Process manipulation.
299 */
300 int mapproc(int pid, Map *map, Regs **regs);
301 void unmapproc(Map *map);
302 int detachproc(int pid);
303 int ctlproc(int pid, char *msg);
304 int procnotes(int pid, char ***notes);
305 char* proctextfile(int pid);
307 /*
308 * Command-line debugger help
309 */
310 extern Fhdr *symhdr;
311 extern Fhdr *corhdr;
312 extern char *symfil;
313 extern char *corfil;
314 extern int corpid;
315 extern Regs *correg;
316 extern Map *symmap;
317 extern Map *cormap;
319 int attachproc(int pid);
320 int attachcore(Fhdr *hdr);
321 int attachargs(int argc, char **argv, int omode);
323 /*
324 * Machine descriptions.
326 * mach.c
327 * mach386.c dis386.c
328 * machsparc.c dissparc.c
329 * ...
330 */
332 /*
333 * Register sets. The Regs are opaque, accessed by using
334 * the reglist (and really the accessor functions).
335 */
336 enum
338 /* must be big enough for all machine register sets */
339 REGSIZE = 256,
341 RINT = 0<<0,
342 RFLT = 1<<0,
343 RRDONLY = 1<<1,
344 };
346 struct Regdesc
348 char *name; /* register name */
349 uint offset; /* offset in b */
350 uint flags; /* RINT/RFLT/RRDONLY */
351 uint format; /* print format: 'x', 'X', 'f', 'z', 'Z' */
352 };
354 Regdesc* regdesc(char*);
356 enum
358 /* machine types */
359 MNONE,
360 MMIPS, /* MIPS R3000 */
361 MSPARC, /* SUN SPARC */
362 M68000, /* Motorola 68000 */
363 M386, /* Intel 32-bit x86*/
364 M960, /* Intel 960 */
365 M3210, /* AT&T 3210 DSP */
366 MMIPS2, /* MIPS R4000 */
367 M29000, /* AMD 29000 */
368 MARM, /* ARM */
369 MPOWER, /* PowerPC */
370 MALPHA, /* DEC/Compaq Alpha */
371 NMTYPE
372 };
374 struct Mach
376 char *name; /* "386", ... */
377 uint type; /* M386, ... */
378 Regdesc *reglist; /* register set */
379 uint regsize; /* size of register set in bytes */
380 uint fpregsize; /* size of fp register set in bytes */
381 char *pc; /* name of program counter */
382 char *sp; /* name of stack pointer */
383 char *fp; /* name of frame pointer */
384 char *link; /* name of link register */
385 char *sbreg; /* name of static base */
386 ulong sb; /* value of static base */
387 uint pgsize; /* page size */
388 ulong kbase; /* kernel base address for Plan 9 */
389 ulong ktmask; /* ktzero = kbase & ~ktmask */
390 uint pcquant; /* pc quantum */
391 uint szaddr; /* size of pointer in bytes */
392 uint szreg; /* size of integer register */
393 uint szfloat; /* size of float */
394 uint szdouble; /* size of double */
395 char** windreg; /* unwinding registers */
396 uint nwindreg;
398 uchar bpinst[4]; /* break point instruction */
399 uint bpsize; /* size of bp instruction */
401 int (*foll)(Map*, Regs*, ulong, ulong*); /* follow set */
402 char* (*exc)(Map*, Regs*); /* last exception */
403 int (*unwind)(Map*, Regs*, ulong*, Symbol*);
405 /* cvt to local byte order */
406 u16int (*swap2)(u16int);
407 u32int (*swap4)(u32int);
408 u64int (*swap8)(u64int);
409 int (*ftoa32)(char*, uint, void*);
410 int (*ftoa64)(char*, uint, void*);
411 int (*ftoa80)(char*, uint, void*);
413 /* disassembly */
414 int (*das)(Map*, ulong, char, char*, int); /* symbolic */
415 int (*kendas)(Map*, ulong, char, char*, int); /* symbolic */
416 int (*codas)(Map*, ulong, char, char*, int);
417 int (*hexinst)(Map*, ulong, char*, int); /* hex */
418 int (*instsize)(Map*, ulong); /* instruction size */
419 };
421 Mach *machbyname(char*);
422 Mach *machbytype(uint);
424 extern Mach mach386;
425 extern Mach machsparc;
426 extern Mach machmips;
427 extern Mach machpower;
429 /*
430 * Debugging symbols and type information.
431 * (Not all objects include type information.)
433 * sym.c
434 */
436 enum
438 /* symbol table classes */
439 CNONE,
440 CAUTO, /* stack variable */
441 CPARAM, /* function parameter */
442 CTEXT, /* text segment */
443 CDATA, /* data segment */
444 CANY,
445 };
447 struct Symbol
449 char *name; /* name of symbol */
450 /* Symtype *typedesc; /* type info, if any */
451 Loc loc; /* location of symbol */
452 Loc hiloc; /* location of end of symbol */
453 char class; /* CAUTO, ... */
454 char type; /* type letter from a.out.h */
455 Fhdr *fhdr; /* where did this come from? */
456 uint index; /* in by-address list */
458 /* private use by various symbol implementations */
459 union {
460 struct {
461 uint unit;
462 uint uoff;
463 } dwarf;
464 struct {
465 uint i;
466 uint locals;
467 char *dir;
468 char *file;
469 char frameptr;
470 uint framesize;
471 } stabs;
472 } u;
473 };
475 /* look through all currently cracked Fhdrs calling their fns */
476 int pc2file(ulong pc, char *file, uint nfile, ulong *line);
477 int file2pc(char *file, ulong line, ulong *addr);
478 int line2pc(ulong basepc, ulong line, ulong *pc);
479 int fnbound(ulong pc, ulong *bounds);
480 int fileline(ulong pc, char *a, uint n);
481 int pc2line(ulong pc, ulong *line);
483 int lookupsym(char *fn, char *var, Symbol *s);
484 int indexsym(uint ndx, Symbol *s);
485 int findsym(Loc loc, uint class, Symbol *s);
486 int findexsym(Fhdr*, uint, Symbol*);
488 int lookuplsym(Symbol *s1, char *name, Symbol *s2);
489 int indexlsym(Symbol *s1, uint ndx, Symbol *s2);
490 int findlsym(Symbol *s1, Loc loc, Symbol *s);
491 int symoff(char *a, uint n, ulong addr, uint class);
492 int unwindframe(Map *map, Regs *regs, ulong *next, Symbol*);
494 void _addhdr(Fhdr*);
495 void _delhdr(Fhdr*);
496 extern Fhdr* fhdrlist;
497 Fhdr* findhdr(char*);
499 Symbol* flookupsym(Fhdr*, char*);
500 Symbol* ffindsym(Fhdr*, Loc, uint);
501 Symbol* addsym(Fhdr*, Symbol*);
503 /*
504 * Stack frame walking.
506 * frame.c
507 */
508 int stacktrace(Map*, Regs*, Tracer);
509 int windindex(char*);
510 Loc* windreglocs(void);
512 /*
513 * Debugger help.
514 */
515 int localaddr(Map *map, Regs *regs, char *fn, char *var, ulong *val);
516 int fpformat(Map *map, Regdesc *reg, char *a, uint n, uint code);
517 char* _hexify(char*, ulong, int);
518 int locfmt(Fmt*);
519 int loccmp(Loc*, Loc*);
520 int locsimplify(Map *map, Regs *regs, Loc loc, Loc *newloc);
522 struct ps_prochandle
524 int pid;
525 };
527 extern int machdebug;