blob: 978a88df86692f37f9f0f0088a1ddf1b5daef41a [file] [log] [blame]
rsc1a0954a2005-01-04 21:18:08 +00001#ifndef _MACH_H_
2#define _MACH_H_ 1
3#if defined(__cplusplus)
4extern "C" {
5#endif
6
7AUTOLIB(mach)
8
rsc0e3cc9f2004-04-19 19:26:19 +00009/*
10 * Architecture-dependent application data.
11 *
12 * The code assumes that ulong is big enough to hold
13 * an address on any system of interest as well as any
14 * register. Debugging 64-bit code on 32-bit machines
15 * will be interesting.
16 *
17 * Supported architectures:
18 *
19 * MIPS R3000
20 * Motorola 68020
21 * Intel 386
22 * SPARC
23 * PowerPC (limited)
24 * ARM (limited)
25 * Intel 960 (limited)
26 * AT&T 3210 DSP (limited)
27 * MIPS2 (R4000)
28 */
29
30typedef struct Fhdr Fhdr;
31typedef struct Loc Loc;
32typedef struct Mach Mach;
33typedef struct Map Map;
34typedef struct Regdesc Regdesc;
35typedef struct Regs Regs;
36typedef struct Seg Seg;
37typedef struct Symbol Symbol;
38typedef struct Symtype Symtype;
39
40typedef int (*Tracer)(Map*, Regs*, ulong, ulong, Symbol*, int);
41
42extern Mach *mach;
43extern Mach *machcpu;
44
45/*
46 * Byte-order data layout manipulation.
47 * swap.c ieee.c
48 */
49u16int beswap2(u16int u);
50u32int beswap4(u32int u);
51u64int beswap8(u64int u);
52int beieeeftoa32(char*, uint, void*);
53int beieeeftoa64(char*, uint, void*);
54int beieeeftoa80(char*, uint, void*);
55
56u16int leswap2(u16int u);
57u32int leswap4(u32int u);
58u64int leswap8(u64int u);
59int leieeeftoa32(char *a, uint n, void *v);
60int leieeeftoa64(char *a, uint n, void *v);
61int leieeeftoa80(char *a, uint n, void *v);
62
63u16int beload2(uchar*);
64u32int beload4(uchar*);
65u64int beload8(uchar*);
66
67u16int leload2(uchar*);
68u32int leload4(uchar*);
69u64int leload8(uchar*);
70
71int ieeeftoa32(char *a, uint n, u32int u);
72int ieeeftoa64(char *a, uint n, u32int h, u32int u);
73
74/*
75 * Machine-independent access to an executable image.
76 * map.c
77 */
78struct Seg
79{
80 char *name;
81 char *file;
82 uchar *p;
83 int fd;
84 int pid;
85 ulong base;
86 ulong size;
87 ulong offset;
88 int (*rw)(Map*, Seg*, ulong, void*, uint, int);
89};
90
91struct Map
92{
93 int nseg;
94 Seg *seg;
95};
96
97struct Regs
98{
99 int (*rw)(Regs*, char*, ulong*, int);
100};
101
102typedef struct UregRegs UregRegs;
103struct UregRegs
104{
105 Regs r;
106 uchar *ureg;
107};
108int _uregrw(Regs*, char*, ulong*, int);
109
110typedef struct PidRegs PidRegs;
111struct PidRegs
112{
113 Regs r;
114 int pid;
115};
116
117Map* allocmap(void);
118int addseg(Map *map, Seg seg);
119int findseg(Map *map, char *name, char *file);
120int addrtoseg(Map *map, ulong addr, Seg *seg);
121int addrtosegafter(Map *map, ulong addr, Seg *seg);
122void removeseg(Map *map, int i);
123void freemap(Map*);
124
125int get1(Map *map, ulong addr, uchar *a, uint n);
126int get2(Map *map, ulong addr, u16int *u);
127int get4(Map *map, ulong addr, u32int *u);
128int get8(Map *map, ulong addr, u64int *u);
129
130int put1(Map *map, ulong addr, uchar *a, uint n);
131int put2(Map *map, ulong addr, u16int u);
132int put4(Map *map, ulong addr, u32int u);
133int put8(Map *map, ulong addr, u64int u);
134
135int rget(Regs*, char*, ulong*);
136int rput(Regs*, char*, ulong);
137
138/*
139 * A location is either a memory address or a register.
140 * It is useful to be able to specify constant values that
141 * originate from outside the register set and memory,
142 * hence LCONST. If the register values are known, then
143 * we can dispense with LOFFSET, but it's useful to be able
144 * to look up local symbols (via findlsym) with locations
145 * like 8(BP).
146 *
147 * loc.c
148 */
149
150enum
151{
152 /* location type */
153 LNONE,
154 LREG, /* register */
155 LADDR, /* absolute address */
156 LCONST, /* constant (an anonymous readonly location) */
rsccbeb0b22006-04-01 19:24:03 +0000157 LOFFSET /* dereference offset + register ptr */
rsc0e3cc9f2004-04-19 19:26:19 +0000158};
159
160struct Loc
161{
162 uint type; /* LNONE, ... */
163 char *reg; /* LREG */
164 ulong addr; /* LADDR, CONST */
165 long offset; /* LOFFSET */
166};
167
168int lget1(Map *map, Regs *regs, Loc loc, uchar *a, uint n);
169int lget2(Map *map, Regs *regs, Loc loc, u16int *v);
170int lget4(Map *map, Regs *regs, Loc loc, u32int *v);
171int lget8(Map *map, Regs *regs, Loc loc, u64int *v);
172
173int lput1(Map *map, Regs *regs, Loc loc, uchar *a, uint n);
174int lput2(Map *map, Regs *regs, Loc loc, u16int v);
175int lput4(Map *map, Regs *regs, Loc loc, u32int v);
176int lput8(Map *map, Regs *regs, Loc loc, u64int v);
177
178Loc locnone(void);
179Loc locaddr(ulong addr);
180Loc locconst(ulong con);
181Loc locreg(char*);
182Loc locindir(char*, long);
183
184/*
185 * Executable file parsing.
186 *
187 * An Fhdr represents an open file image.
188 * The contents are a grab bag of constants used for the
189 * various file types. Not all elements are used by all
190 * file types.
191 *
192 * crackadotplan9.c crackadotunix.c
193 * crackelf.c crackdwarf.c
194 */
195enum
196{
197 /* file types */
198 FNONE,
199 FEXEC, /* executable image */
200 FLIB, /* library */
201 FOBJ, /* object file */
202 FRELOC, /* relocatable executable */
203 FSHLIB, /* shared library */
204 FSHOBJ, /* shared object */
205 FCORE, /* core dump */
206 FBOOT, /* bootable image */
207 FKERNEL, /* kernel image */
208 NFTYPE,
209
210 /* abi types */
211 ANONE = 0,
212 APLAN9,
213 ALINUX,
214 AFREEBSD,
215 AMACH,
216 NATYPE
217};
218
219/* I wish this could be kept in stabs.h */
220struct Stab
221{
222 uchar *stabbase;
223 uint stabsize;
224 char *strbase;
225 uint strsize;
226 u16int (*e2)(uchar*);
227 u32int (*e4)(uchar*);
228};
229
230struct Fhdr
231{
232 int fd; /* file descriptor */
233 char *filename; /* file name */
234 Mach *mach; /* machine */
235 char *mname; /* 386, power, ... */
236 uint mtype; /* machine type M386, ... */
237 char *fname; /* core, executable, boot image, ... */
238 uint ftype; /* file type FCORE, ... */
239 char *aname; /* abi name */
240 uint atype; /* abi type ALINUX, ... */
241
242 ulong magic; /* magic number */
243 ulong txtaddr; /* text address */
244 ulong entry; /* entry point */
245 ulong txtsz; /* text size */
246 ulong txtoff; /* text offset in file */
247 ulong dataddr; /* data address */
248 ulong datsz; /* data size */
249 ulong datoff; /* data offset in file */
250 ulong bsssz; /* bss size */
251 ulong symsz; /* symbol table size */
252 ulong symoff; /* symbol table offset in file */
253 ulong sppcsz; /* size of sp-pc table */
254 ulong sppcoff; /* offset of sp-pc table in file */
255 ulong lnpcsz; /* size of line number-pc table */
256 ulong lnpcoff; /* size of line number-pc table */
257 void *elf; /* handle to elf image */
258 void *dwarf; /* handle to dwarf image */
259 void *macho; /* handle to mach-o image */
260 struct Stab stabs;
rsc28125cb2005-01-23 22:33:25 +0000261 uint pid; /* for core files */
262 char *prog; /* program name, for core files */
263 char *cmdline; /* command-line that produced core */
264 struct { /* thread state for core files */
265 uint id;
266 void *ureg;
267 } *thread;
268 uint nthread;
rsc0e3cc9f2004-04-19 19:26:19 +0000269
270 /* private */
271 Symbol *sym; /* cached list of symbols */
272 Symbol **byname;
rsc72dd4492005-11-29 19:01:25 +0000273 Symbol **byxname;
rsc0e3cc9f2004-04-19 19:26:19 +0000274 uint nsym;
275 Symbol *esym; /* elf symbols */
rsc0e3cc9f2004-04-19 19:26:19 +0000276 uint nesym;
277 ulong base; /* base address for relocatables */
278 Fhdr *next; /* link to next fhdr (internal) */
279
280 /* file mapping */
281 int (*map)(Fhdr*, ulong, Map*, Regs**);
282
283 /* debugging symbol access; see below */
284 int (*syminit)(Fhdr*);
285 void (*symclose)(Fhdr*);
286
287 int (*pc2file)(Fhdr*, ulong, char*, uint, ulong*);
288 int (*file2pc)(Fhdr*, char*, ulong, ulong*);
289 int (*line2pc)(Fhdr*, ulong, ulong, ulong*);
290
291 int (*lookuplsym)(Fhdr*, Symbol*, char*, Symbol*);
292 int (*indexlsym)(Fhdr*, Symbol*, uint, Symbol*);
293 int (*findlsym)(Fhdr*, Symbol*, Loc, Symbol*);
294
rsccdf18052004-12-25 22:01:28 +0000295 int (*unwind)(Fhdr*, Map*, Regs*, ulong*, Symbol*);
rsc0e3cc9f2004-04-19 19:26:19 +0000296};
297
298Fhdr* crackhdr(char *file, int mode);
299void uncrackhdr(Fhdr *hdr);
300int crackelf(int fd, Fhdr *hdr);
301int crackmacho(int fd, Fhdr *hdr);
rsc28125cb2005-01-23 22:33:25 +0000302Regs* coreregs(Fhdr*, uint);
rsc0e3cc9f2004-04-19 19:26:19 +0000303
rsc8b549a62005-01-07 20:45:11 +0000304int symopen(Fhdr*);
rsc0e3cc9f2004-04-19 19:26:19 +0000305int symdwarf(Fhdr*);
306int symelf(Fhdr*);
307int symstabs(Fhdr*);
308int symmacho(Fhdr*);
rsc8b549a62005-01-07 20:45:11 +0000309void symclose(Fhdr*);
rsc0e3cc9f2004-04-19 19:26:19 +0000310
311int mapfile(Fhdr *fp, ulong base, Map *map, Regs **regs);
312void unmapfile(Fhdr *fp, Map *map);
313
314/*
315 * Process manipulation.
316 */
317int mapproc(int pid, Map *map, Regs **regs);
318void unmapproc(Map *map);
319int detachproc(int pid);
320int ctlproc(int pid, char *msg);
321int procnotes(int pid, char ***notes);
322char* proctextfile(int pid);
323
324/*
rsccdf18052004-12-25 22:01:28 +0000325 * Command-line debugger help
326 */
327extern Fhdr *symhdr;
328extern Fhdr *corhdr;
329extern char *symfil;
330extern char *corfil;
331extern int corpid;
332extern Regs *correg;
333extern Map *symmap;
334extern Map *cormap;
335
336int attachproc(int pid);
337int attachcore(Fhdr *hdr);
rsc28125cb2005-01-23 22:33:25 +0000338int attachargs(int argc, char **argv, int omode, int);
339int attachdynamic(int);
rsccdf18052004-12-25 22:01:28 +0000340/*
rsc0e3cc9f2004-04-19 19:26:19 +0000341 * Machine descriptions.
342 *
343 * mach.c
344 * mach386.c dis386.c
345 * machsparc.c dissparc.c
346 * ...
347 */
348
349/*
350 * Register sets. The Regs are opaque, accessed by using
351 * the reglist (and really the accessor functions).
352 */
353enum
354{
355 /* must be big enough for all machine register sets */
356 REGSIZE = 256,
357
358 RINT = 0<<0,
359 RFLT = 1<<0,
rsccbeb0b22006-04-01 19:24:03 +0000360 RRDONLY = 1<<1
rsc0e3cc9f2004-04-19 19:26:19 +0000361};
362
363struct Regdesc
364{
365 char *name; /* register name */
366 uint offset; /* offset in b */
367 uint flags; /* RINT/RFLT/RRDONLY */
368 uint format; /* print format: 'x', 'X', 'f', 'z', 'Z' */
369};
370
rsc0e3cc9f2004-04-19 19:26:19 +0000371enum
372{
373 /* machine types */
374 MNONE,
375 MMIPS, /* MIPS R3000 */
376 MSPARC, /* SUN SPARC */
377 M68000, /* Motorola 68000 */
378 M386, /* Intel 32-bit x86*/
379 M960, /* Intel 960 */
380 M3210, /* AT&T 3210 DSP */
381 MMIPS2, /* MIPS R4000 */
382 M29000, /* AMD 29000 */
383 MARM, /* ARM */
384 MPOWER, /* PowerPC */
385 MALPHA, /* DEC/Compaq Alpha */
386 NMTYPE
387};
388
389struct Mach
390{
391 char *name; /* "386", ... */
392 uint type; /* M386, ... */
393 Regdesc *reglist; /* register set */
394 uint regsize; /* size of register set in bytes */
395 uint fpregsize; /* size of fp register set in bytes */
396 char *pc; /* name of program counter */
397 char *sp; /* name of stack pointer */
398 char *fp; /* name of frame pointer */
399 char *link; /* name of link register */
400 char *sbreg; /* name of static base */
401 ulong sb; /* value of static base */
402 uint pgsize; /* page size */
403 ulong kbase; /* kernel base address for Plan 9 */
404 ulong ktmask; /* ktzero = kbase & ~ktmask */
405 uint pcquant; /* pc quantum */
406 uint szaddr; /* size of pointer in bytes */
407 uint szreg; /* size of integer register */
408 uint szfloat; /* size of float */
409 uint szdouble; /* size of double */
410 char** windreg; /* unwinding registers */
411 uint nwindreg;
412
413 uchar bpinst[4]; /* break point instruction */
414 uint bpsize; /* size of bp instruction */
415
416 int (*foll)(Map*, Regs*, ulong, ulong*); /* follow set */
417 char* (*exc)(Map*, Regs*); /* last exception */
rsccdf18052004-12-25 22:01:28 +0000418 int (*unwind)(Map*, Regs*, ulong*, Symbol*);
rsc0e3cc9f2004-04-19 19:26:19 +0000419
420 /* cvt to local byte order */
421 u16int (*swap2)(u16int);
422 u32int (*swap4)(u32int);
423 u64int (*swap8)(u64int);
424 int (*ftoa32)(char*, uint, void*);
425 int (*ftoa64)(char*, uint, void*);
426 int (*ftoa80)(char*, uint, void*);
427
428 /* disassembly */
429 int (*das)(Map*, ulong, char, char*, int); /* symbolic */
430 int (*kendas)(Map*, ulong, char, char*, int); /* symbolic */
431 int (*codas)(Map*, ulong, char, char*, int);
432 int (*hexinst)(Map*, ulong, char*, int); /* hex */
433 int (*instsize)(Map*, ulong); /* instruction size */
434};
435
436Mach *machbyname(char*);
437Mach *machbytype(uint);
438
439extern Mach mach386;
440extern Mach machsparc;
441extern Mach machmips;
442extern Mach machpower;
443
444/*
445 * Debugging symbols and type information.
446 * (Not all objects include type information.)
447 *
448 * sym.c
449 */
450
451enum
452{
453 /* symbol table classes */
454 CNONE,
455 CAUTO, /* stack variable */
456 CPARAM, /* function parameter */
457 CTEXT, /* text segment */
458 CDATA, /* data segment */
rsccbeb0b22006-04-01 19:24:03 +0000459 CANY
rsc0e3cc9f2004-04-19 19:26:19 +0000460};
461
462struct Symbol
463{
464 char *name; /* name of symbol */
rsc72dd4492005-11-29 19:01:25 +0000465 char *xname; /* demangled name */
466
rsc0e3cc9f2004-04-19 19:26:19 +0000467 /* Symtype *typedesc; /* type info, if any */
468 Loc loc; /* location of symbol */
469 Loc hiloc; /* location of end of symbol */
470 char class; /* CAUTO, ... */
471 char type; /* type letter from a.out.h */
472 Fhdr *fhdr; /* where did this come from? */
473 uint index; /* in by-address list */
474
475 /* private use by various symbol implementations */
476 union {
477 struct {
478 uint unit;
479 uint uoff;
480 } dwarf;
481 struct {
482 uint i;
483 uint locals;
484 char *dir;
485 char *file;
rsc1c171e32005-07-19 18:00:07 +0000486 schar frameptr;
rsc0e3cc9f2004-04-19 19:26:19 +0000487 uint framesize;
488 } stabs;
489 } u;
rsc72dd4492005-11-29 19:01:25 +0000490
491 void *aux; /* for use by client */
rsc0e3cc9f2004-04-19 19:26:19 +0000492};
493
494/* look through all currently cracked Fhdrs calling their fns */
495int pc2file(ulong pc, char *file, uint nfile, ulong *line);
496int file2pc(char *file, ulong line, ulong *addr);
497int line2pc(ulong basepc, ulong line, ulong *pc);
498int fnbound(ulong pc, ulong *bounds);
499int fileline(ulong pc, char *a, uint n);
500int pc2line(ulong pc, ulong *line);
501
502int lookupsym(char *fn, char *var, Symbol *s);
503int indexsym(uint ndx, Symbol *s);
504int findsym(Loc loc, uint class, Symbol *s);
505int findexsym(Fhdr*, uint, Symbol*);
506
507int lookuplsym(Symbol *s1, char *name, Symbol *s2);
508int indexlsym(Symbol *s1, uint ndx, Symbol *s2);
509int findlsym(Symbol *s1, Loc loc, Symbol *s);
510int symoff(char *a, uint n, ulong addr, uint class);
rsccdf18052004-12-25 22:01:28 +0000511int unwindframe(Map *map, Regs *regs, ulong *next, Symbol*);
rsc0e3cc9f2004-04-19 19:26:19 +0000512
513void _addhdr(Fhdr*);
514void _delhdr(Fhdr*);
rsc67e4fce2004-04-19 23:58:57 +0000515extern Fhdr* fhdrlist;
rsccdf18052004-12-25 22:01:28 +0000516Fhdr* findhdr(char*);
rsc0e3cc9f2004-04-19 19:26:19 +0000517
518Symbol* flookupsym(Fhdr*, char*);
519Symbol* ffindsym(Fhdr*, Loc, uint);
rsc1a0954a2005-01-04 21:18:08 +0000520Symbol* _addsym(Fhdr*, Symbol*);
rsc0e3cc9f2004-04-19 19:26:19 +0000521
rsc88c60622005-11-28 00:40:16 +0000522char* demangle(char*, char*, int);
523char* demanglegcc3(char*, char*);
524char* demanglegcc2(char*, char*);
rsc0e3cc9f2004-04-19 19:26:19 +0000525/*
526 * Stack frame walking.
527 *
528 * frame.c
529 */
530int stacktrace(Map*, Regs*, Tracer);
531int windindex(char*);
532Loc* windreglocs(void);
533
534/*
535 * Debugger help.
536 */
537int localaddr(Map *map, Regs *regs, char *fn, char *var, ulong *val);
538int fpformat(Map *map, Regdesc *reg, char *a, uint n, uint code);
539char* _hexify(char*, ulong, int);
540int locfmt(Fmt*);
541int loccmp(Loc*, Loc*);
542int locsimplify(Map *map, Regs *regs, Loc loc, Loc *newloc);
rsc042aca72005-01-07 04:01:14 +0000543Regdesc* regdesc(char*);
rsc0e3cc9f2004-04-19 19:26:19 +0000544
rsc0e3cc9f2004-04-19 19:26:19 +0000545extern int machdebug;
rsc1a0954a2005-01-04 21:18:08 +0000546#if defined(__cplusplus)
547}
548#endif
549#endif