aboutsummaryrefslogtreecommitdiff
path: root/src/libmach/machocorepower.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmach/machocorepower.c')
-rw-r--r--src/libmach/machocorepower.c173
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);
+}
+