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