blob: 0eb3761d18d65922d4d8510bc7024ff93db31016 [file] [log] [blame]
rsca84cbb22004-04-19 19:29:25 +00001#include <u.h>
2#include <libc.h>
3#include <mach.h>
4#include "macho.h"
5#include "uregpower.h"
6
7enum
8{
9 ThreadState = 1,
10 FloatState,
11 ExceptionState,
12 VectorState,
13 ThreadState64,
14 ExceptionState64,
15 ThreadStateNone,
16};
17
18typedef struct Lreg Lreg;
19typedef struct Lflt Lflt;
20typedef struct Lexc Lexc;
21
22struct 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
68struct Lflt
69{
70 u32int fpregs[32*2]; /* 32 doubles */
71 u32int fpscr[2];
72
73};
74
75struct Lexc
76{
77 u32int dar;
78 u32int dsisr;
79 u32int exception;
80 u32int pad0;
81 u32int pad1[4];
82};
83
84static void
85lreg2ureg(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
97static void
98lexc2ureg(Lexc *l, Ureg *u)
99{
100 u->cause = l->exception;
101 u->dar = l->dar;
102 u->dsisr = l->dsisr;
103}
104
105static uchar*
106load(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
120int
121coreregsmachopower(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}
173