blob: 23089e44455a7ef253292310cb5798191be13f73 [file] [log] [blame]
rsc0e3cc9f2004-04-19 19:26:19 +00001/*
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 */
21
22typedef struct Fhdr Fhdr;
23typedef struct Loc Loc;
24typedef struct Mach Mach;
25typedef struct Map Map;
26typedef struct Regdesc Regdesc;
27typedef struct Regs Regs;
28typedef struct Seg Seg;
29typedef struct Symbol Symbol;
30typedef struct Symtype Symtype;
31
32typedef int (*Tracer)(Map*, Regs*, ulong, ulong, Symbol*, int);
33
34extern Mach *mach;
35extern Mach *machcpu;
36
37/*
38 * Byte-order data layout manipulation.
39 * swap.c ieee.c
40 */
41u16int beswap2(u16int u);
42u32int beswap4(u32int u);
43u64int beswap8(u64int u);
44int beieeeftoa32(char*, uint, void*);
45int beieeeftoa64(char*, uint, void*);
46int beieeeftoa80(char*, uint, void*);
47
48u16int leswap2(u16int u);
49u32int leswap4(u32int u);
50u64int leswap8(u64int u);
51int leieeeftoa32(char *a, uint n, void *v);
52int leieeeftoa64(char *a, uint n, void *v);
53int leieeeftoa80(char *a, uint n, void *v);
54
55u16int beload2(uchar*);
56u32int beload4(uchar*);
57u64int beload8(uchar*);
58
59u16int leload2(uchar*);
60u32int leload4(uchar*);
61u64int leload8(uchar*);
62
63int ieeeftoa32(char *a, uint n, u32int u);
64int ieeeftoa64(char *a, uint n, u32int h, u32int u);
65
66/*
67 * Machine-independent access to an executable image.
68 * map.c
69 */
70struct 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};
82
83struct Map
84{
85 int nseg;
86 Seg *seg;
87};
88
89struct Regs
90{
91 int (*rw)(Regs*, char*, ulong*, int);
92};
93
94typedef struct UregRegs UregRegs;
95struct UregRegs
96{
97 Regs r;
98 uchar *ureg;
99};
100int _uregrw(Regs*, char*, ulong*, int);
101
102typedef struct PidRegs PidRegs;
103struct PidRegs
104{
105 Regs r;
106 int pid;
107};
108
109Map* allocmap(void);
110int addseg(Map *map, Seg seg);
111int findseg(Map *map, char *name, char *file);
112int addrtoseg(Map *map, ulong addr, Seg *seg);
113int addrtosegafter(Map *map, ulong addr, Seg *seg);
114void removeseg(Map *map, int i);
115void freemap(Map*);
116
117int get1(Map *map, ulong addr, uchar *a, uint n);
118int get2(Map *map, ulong addr, u16int *u);
119int get4(Map *map, ulong addr, u32int *u);
120int get8(Map *map, ulong addr, u64int *u);
121
122int put1(Map *map, ulong addr, uchar *a, uint n);
123int put2(Map *map, ulong addr, u16int u);
124int put4(Map *map, ulong addr, u32int u);
125int put8(Map *map, ulong addr, u64int u);
126
127int rget(Regs*, char*, ulong*);
128int rput(Regs*, char*, ulong);
129
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).
138 *
139 * loc.c
140 */
141
142enum
143{
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};
151
152struct Loc
153{
154 uint type; /* LNONE, ... */
155 char *reg; /* LREG */
156 ulong addr; /* LADDR, CONST */
157 long offset; /* LOFFSET */
158};
159
160int lget1(Map *map, Regs *regs, Loc loc, uchar *a, uint n);
161int lget2(Map *map, Regs *regs, Loc loc, u16int *v);
162int lget4(Map *map, Regs *regs, Loc loc, u32int *v);
163int lget8(Map *map, Regs *regs, Loc loc, u64int *v);
164
165int lput1(Map *map, Regs *regs, Loc loc, uchar *a, uint n);
166int lput2(Map *map, Regs *regs, Loc loc, u16int v);
167int lput4(Map *map, Regs *regs, Loc loc, u32int v);
168int lput8(Map *map, Regs *regs, Loc loc, u64int v);
169
170Loc locnone(void);
171Loc locaddr(ulong addr);
172Loc locconst(ulong con);
173Loc locreg(char*);
174Loc locindir(char*, long);
175
176/*
177 * Executable file parsing.
178 *
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.
183 *
184 * crackadotplan9.c crackadotunix.c
185 * crackelf.c crackdwarf.c
186 */
187enum
188{
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,
201
202 /* abi types */
203 ANONE = 0,
204 APLAN9,
205 ALINUX,
206 AFREEBSD,
207 AMACH,
208 NATYPE
209};
210
211/* I wish this could be kept in stabs.h */
212struct Stab
213{
214 uchar *stabbase;
215 uint stabsize;
216 char *strbase;
217 uint strsize;
218 u16int (*e2)(uchar*);
219 u32int (*e4)(uchar*);
220};
221
222struct Fhdr
223{
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, ... */
233
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 */
rsccdf18052004-12-25 22:01:28 +0000249 char *txtfil; /* text name, for core files */
rsc0e3cc9f2004-04-19 19:26:19 +0000250 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;
254
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) */
264
265 /* file mapping */
266 int (*map)(Fhdr*, ulong, Map*, Regs**);
267
268 /* debugging symbol access; see below */
269 int (*syminit)(Fhdr*);
270 void (*symclose)(Fhdr*);
271
272 int (*pc2file)(Fhdr*, ulong, char*, uint, ulong*);
273 int (*file2pc)(Fhdr*, char*, ulong, ulong*);
274 int (*line2pc)(Fhdr*, ulong, ulong, ulong*);
275
276 int (*lookuplsym)(Fhdr*, Symbol*, char*, Symbol*);
277 int (*indexlsym)(Fhdr*, Symbol*, uint, Symbol*);
278 int (*findlsym)(Fhdr*, Symbol*, Loc, Symbol*);
279
rsccdf18052004-12-25 22:01:28 +0000280 int (*unwind)(Fhdr*, Map*, Regs*, ulong*, Symbol*);
rsc0e3cc9f2004-04-19 19:26:19 +0000281};
282
283Fhdr* crackhdr(char *file, int mode);
284void uncrackhdr(Fhdr *hdr);
285int crackelf(int fd, Fhdr *hdr);
286int crackmacho(int fd, Fhdr *hdr);
287
288int syminit(Fhdr*);
289int symdwarf(Fhdr*);
290int symelf(Fhdr*);
291int symstabs(Fhdr*);
292int symmacho(Fhdr*);
293
294int mapfile(Fhdr *fp, ulong base, Map *map, Regs **regs);
295void unmapfile(Fhdr *fp, Map *map);
296
297/*
298 * Process manipulation.
299 */
300int mapproc(int pid, Map *map, Regs **regs);
301void unmapproc(Map *map);
302int detachproc(int pid);
303int ctlproc(int pid, char *msg);
304int procnotes(int pid, char ***notes);
305char* proctextfile(int pid);
306
307/*
rsccdf18052004-12-25 22:01:28 +0000308 * Command-line debugger help
309 */
310extern Fhdr *symhdr;
311extern Fhdr *corhdr;
312extern char *symfil;
313extern char *corfil;
314extern int corpid;
315extern Regs *correg;
316extern Map *symmap;
317extern Map *cormap;
318
319int attachproc(int pid);
320int attachcore(Fhdr *hdr);
321int attachargs(int argc, char **argv, int omode);
322
323/*
rsc0e3cc9f2004-04-19 19:26:19 +0000324 * Machine descriptions.
325 *
326 * mach.c
327 * mach386.c dis386.c
328 * machsparc.c dissparc.c
329 * ...
330 */
331
332/*
333 * Register sets. The Regs are opaque, accessed by using
334 * the reglist (and really the accessor functions).
335 */
336enum
337{
338 /* must be big enough for all machine register sets */
339 REGSIZE = 256,
340
341 RINT = 0<<0,
342 RFLT = 1<<0,
343 RRDONLY = 1<<1,
344};
345
346struct Regdesc
347{
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};
353
354Regdesc* regdesc(char*);
355
356enum
357{
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};
373
374struct Mach
375{
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;
397
398 uchar bpinst[4]; /* break point instruction */
399 uint bpsize; /* size of bp instruction */
400
401 int (*foll)(Map*, Regs*, ulong, ulong*); /* follow set */
402 char* (*exc)(Map*, Regs*); /* last exception */
rsccdf18052004-12-25 22:01:28 +0000403 int (*unwind)(Map*, Regs*, ulong*, Symbol*);
rsc0e3cc9f2004-04-19 19:26:19 +0000404
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*);
412
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};
420
421Mach *machbyname(char*);
422Mach *machbytype(uint);
423
424extern Mach mach386;
425extern Mach machsparc;
426extern Mach machmips;
427extern Mach machpower;
428
429/*
430 * Debugging symbols and type information.
431 * (Not all objects include type information.)
432 *
433 * sym.c
434 */
435
436enum
437{
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};
446
447struct Symbol
448{
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 */
457
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};
474
475/* look through all currently cracked Fhdrs calling their fns */
476int pc2file(ulong pc, char *file, uint nfile, ulong *line);
477int file2pc(char *file, ulong line, ulong *addr);
478int line2pc(ulong basepc, ulong line, ulong *pc);
479int fnbound(ulong pc, ulong *bounds);
480int fileline(ulong pc, char *a, uint n);
481int pc2line(ulong pc, ulong *line);
482
483int lookupsym(char *fn, char *var, Symbol *s);
484int indexsym(uint ndx, Symbol *s);
485int findsym(Loc loc, uint class, Symbol *s);
486int findexsym(Fhdr*, uint, Symbol*);
487
488int lookuplsym(Symbol *s1, char *name, Symbol *s2);
489int indexlsym(Symbol *s1, uint ndx, Symbol *s2);
490int findlsym(Symbol *s1, Loc loc, Symbol *s);
491int symoff(char *a, uint n, ulong addr, uint class);
rsccdf18052004-12-25 22:01:28 +0000492int unwindframe(Map *map, Regs *regs, ulong *next, Symbol*);
rsc0e3cc9f2004-04-19 19:26:19 +0000493
494void _addhdr(Fhdr*);
495void _delhdr(Fhdr*);
rsc67e4fce2004-04-19 23:58:57 +0000496extern Fhdr* fhdrlist;
rsccdf18052004-12-25 22:01:28 +0000497Fhdr* findhdr(char*);
rsc0e3cc9f2004-04-19 19:26:19 +0000498
499Symbol* flookupsym(Fhdr*, char*);
500Symbol* ffindsym(Fhdr*, Loc, uint);
501Symbol* addsym(Fhdr*, Symbol*);
502
503/*
504 * Stack frame walking.
505 *
506 * frame.c
507 */
508int stacktrace(Map*, Regs*, Tracer);
509int windindex(char*);
510Loc* windreglocs(void);
511
512/*
513 * Debugger help.
514 */
515int localaddr(Map *map, Regs *regs, char *fn, char *var, ulong *val);
516int fpformat(Map *map, Regdesc *reg, char *a, uint n, uint code);
517char* _hexify(char*, ulong, int);
518int locfmt(Fmt*);
519int loccmp(Loc*, Loc*);
520int locsimplify(Map *map, Regs *regs, Loc loc, Loc *newloc);
521
rsccdf18052004-12-25 22:01:28 +0000522struct ps_prochandle
523{
524 int pid;
525};
526
rsc0e3cc9f2004-04-19 19:26:19 +0000527extern int machdebug;