machocorepower.c (2533B)
1 #include <u.h> 2 #include <libc.h> 3 #include <mach.h> 4 #include "macho.h" 5 #include "uregpower.h" 6 7 enum 8 { 9 ThreadState = 1, 10 FloatState, 11 ExceptionState, 12 VectorState, 13 ThreadState64, 14 ExceptionState64, 15 ThreadStateNone 16 }; 17 18 typedef struct Lreg Lreg; 19 typedef struct Lflt Lflt; 20 typedef struct Lexc Lexc; 21 22 struct Lreg 23 { 24 u32int srr0; 25 u32int srr1; 26 u32int r0; 27 u32int r1; 28 u32int r2; 29 u32int r3; 30 u32int r4; 31 u32int r5; 32 u32int r6; 33 u32int r7; 34 u32int r8; 35 u32int r9; 36 u32int r10; 37 u32int r11; 38 u32int r12; 39 u32int r13; 40 u32int r14; 41 u32int r15; 42 u32int r16; 43 u32int r17; 44 u32int r18; 45 u32int r19; 46 u32int r20; 47 u32int r21; 48 u32int r22; 49 u32int r23; 50 u32int r24; 51 u32int r25; 52 u32int r26; 53 u32int r27; 54 u32int r28; 55 u32int r29; 56 u32int r30; 57 u32int r31; 58 59 u32int cr; 60 u32int xer; 61 u32int lr; 62 u32int ctr; 63 u32int mq; 64 65 u32int vrsave; 66 }; 67 68 struct Lflt 69 { 70 u32int fpregs[32*2]; /* 32 doubles */ 71 u32int fpscr[2]; 72 73 }; 74 75 struct Lexc 76 { 77 u32int dar; 78 u32int dsisr; 79 u32int exception; 80 u32int pad0; 81 u32int pad1[4]; 82 }; 83 84 static void 85 lreg2ureg(Lreg *l, Ureg *u) 86 { 87 u->pc = l->srr0; 88 u->srr1 = l->srr1; 89 u->lr = l->lr; 90 u->cr = l->cr; 91 u->xer = l->xer; 92 u->ctr = l->ctr; 93 u->vrsave = l->vrsave; 94 memmove(&u->r0, &l->r0, 32*4); 95 } 96 97 static void 98 lexc2ureg(Lexc *l, Ureg *u) 99 { 100 u->cause = l->exception; 101 u->dar = l->dar; 102 u->dsisr = l->dsisr; 103 } 104 105 static uchar* 106 load(int fd, ulong off, int size) 107 { 108 uchar *a; 109 110 a = malloc(size); 111 if(a == nil) 112 return nil; 113 if(seek(fd, off, 0) < 0 || readn(fd, a, size) != size){ 114 free(a); 115 return nil; 116 } 117 return a; 118 } 119 120 int 121 coreregsmachopower(Macho *m, uchar **up) 122 { 123 int i, havereg, haveexc; 124 uchar *a, *p, *nextp; 125 Ureg *u; 126 ulong flavor, count; 127 MachoCmd *c; 128 129 *up = nil; 130 for(i=0; i<m->ncmd; i++) 131 if(m->cmd[i].type == MachoCmdThread) 132 break; 133 if(i == m->ncmd){ 134 werrstr("no registers found"); 135 return -1; 136 } 137 138 c = &m->cmd[i]; 139 a = load(m->fd, c->off, c->size); 140 if(a == nil) 141 return -1; 142 143 if((u = mallocz(sizeof(Ureg), 1)) == nil){ 144 free(a); 145 return -1; 146 } 147 148 havereg = haveexc = 0; 149 for(p=a+8; p<a+c->size; p=nextp){ 150 flavor = m->e4(p); 151 count = m->e4(p+4); 152 nextp = p+8+count*4; 153 if(flavor == ThreadState && count*4 == sizeof(Lreg)){ 154 havereg = 1; 155 lreg2ureg((Lreg*)(p+8), u); 156 } 157 if(flavor == ExceptionState && count*4 == sizeof(Lexc)){ 158 haveexc = 1; 159 lexc2ureg((Lexc*)(p+8), u); 160 } 161 } 162 free(a); 163 if(!havereg){ 164 werrstr("no registers found"); 165 free(u); 166 return -1; 167 } 168 if(!haveexc) 169 fprint(2, "warning: no exception state in core file registers\n"); 170 *up = (uchar*)u; 171 return sizeof(*u); 172 }