diff options
Diffstat (limited to 'src/libmach/machocorepower.c')
-rw-r--r-- | src/libmach/machocorepower.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/src/libmach/machocorepower.c b/src/libmach/machocorepower.c new file mode 100644 index 00000000..0eb3761d --- /dev/null +++ b/src/libmach/machocorepower.c @@ -0,0 +1,173 @@ +#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); +} + |