#include #include #include #include "macho.h" #include "uregpower.h" enum { ThreadState = 1, FloatState, ExceptionState, VectorState, ThreadState64, ExceptionState64, ThreadStateNone }; typedef struct Lreg Lreg; typedef struct Lflt Lflt; typedef struct Lexc Lexc; struct Lreg { u32int srr0; u32int srr1; u32int r0; u32int r1; u32int r2; u32int r3; u32int r4; u32int r5; u32int r6; u32int r7; u32int r8; u32int r9; u32int r10; u32int r11; u32int r12; u32int r13; u32int r14; u32int r15; u32int r16; u32int r17; u32int r18; u32int r19; u32int r20; u32int r21; u32int r22; u32int r23; u32int r24; u32int r25; u32int r26; u32int r27; u32int r28; u32int r29; u32int r30; u32int r31; u32int cr; u32int xer; u32int lr; u32int ctr; u32int mq; u32int vrsave; }; struct Lflt { u32int fpregs[32*2]; /* 32 doubles */ u32int fpscr[2]; }; struct Lexc { u32int dar; u32int dsisr; u32int exception; u32int pad0; u32int pad1[4]; }; static void lreg2ureg(Lreg *l, Ureg *u) { u->pc = l->srr0; u->srr1 = l->srr1; u->lr = l->lr; u->cr = l->cr; u->xer = l->xer; u->ctr = l->ctr; u->vrsave = l->vrsave; memmove(&u->r0, &l->r0, 32*4); } static void lexc2ureg(Lexc *l, Ureg *u) { u->cause = l->exception; u->dar = l->dar; u->dsisr = l->dsisr; } static uchar* load(int fd, ulong off, int size) { uchar *a; a = malloc(size); if(a == nil) return nil; if(seek(fd, off, 0) < 0 || readn(fd, a, size) != size){ free(a); return nil; } return a; } int coreregsmachopower(Macho *m, uchar **up) { int i, havereg, haveexc; uchar *a, *p, *nextp; Ureg *u; ulong flavor, count; MachoCmd *c; *up = nil; for(i=0; incmd; i++) if(m->cmd[i].type == MachoCmdThread) break; if(i == m->ncmd){ werrstr("no registers found"); return -1; } c = &m->cmd[i]; a = load(m->fd, c->off, c->size); if(a == nil) return -1; if((u = mallocz(sizeof(Ureg), 1)) == nil){ free(a); return -1; } havereg = haveexc = 0; for(p=a+8; psize; p=nextp){ flavor = m->e4(p); count = m->e4(p+4); nextp = p+8+count*4; if(flavor == ThreadState && count*4 == sizeof(Lreg)){ havereg = 1; lreg2ureg((Lreg*)(p+8), u); } if(flavor == ExceptionState && count*4 == sizeof(Lexc)){ haveexc = 1; lexc2ureg((Lexc*)(p+8), u); } } free(a); if(!havereg){ werrstr("no registers found"); free(u); return -1; } if(!haveexc) fprint(2, "warning: no exception state in core file registers\n"); *up = (uchar*)u; return sizeof(*u); }