| #include <u.h> |
| #include <libc.h> |
| #include <mach.h> |
| #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; i<m->ncmd; 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; p<a+c->size; 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); |
| } |
| |