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