* Makefile.in (TARGET_FLAGS_TO_PASS): Pass down LD_FOR_TARGET and
[deliverable/binutils-gdb.git] / gdb / nlm / ppc.c
1 #include <nwdfs.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <time.h>
6 #include <nwconio.h>
7 #include <nwadv.h>
8 #include <nwdbgapi.h>
9 #include <errno.h>
10 #include <nwthread.h>
11 #include "ppc.h"
12
13 extern char *mem2hex (void *mem, char *buf, int count, int may_fault);
14 extern char *hex2mem (char *buf, void *mem, int count, int may_fault);
15 extern int computeSignal (int exceptionVector);
16
17 void
18 flush_i_cache (void)
19 {
20 }
21
22 /* Get the registers out of the frame information. */
23
24 void
25 frame_to_registers (frame, regs)
26 struct StackFrame *frame;
27 char *regs;
28 {
29 mem2hex (&frame->ExceptionState.CsavedRegs, &regs[GP0_REGNUM * 4 * 2], 4 * 32, 0);
30
31 mem2hex (&frame->ExceptionState.CSavedFPRegs, &regs[FP0_REGNUM * 4 * 2], 4 * 32, 0);
32
33 mem2hex (&frame->ExceptionPC, &regs[PC_REGNUM * 4 * 2], 4 * 1, 0);
34
35 mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, &regs[CR_REGNUM * 4 * 2], 4 * 1, 0);
36 mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, &regs[LR_REGNUM * 4 * 2], 4 * 1, 0);
37 mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, &regs[CTR_REGNUM * 4 * 2], 4 * 1, 0);
38 mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, &regs[XER_REGNUM * 4 * 2], 4 * 1, 0);
39 mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, &regs[MQ_REGNUM * 4 * 2], 4 * 1, 0);
40 }
41
42 /* Put the registers back into the frame information. */
43
44 void
45 registers_to_frame (regs, frame)
46 char *regs;
47 struct StackFrame *frame;
48 {
49 hex2mem (&regs[GP0_REGNUM * 4 * 2], &frame->ExceptionState.CsavedRegs, 4 * 32, 0);
50
51 hex2mem (&regs[FP0_REGNUM * 4 * 2], &frame->ExceptionState.CSavedFPRegs, 4 * 32, 0);
52
53 hex2mem (&regs[PC_REGNUM * 4 * 2], &frame->ExceptionPC, 4 * 1, 0);
54
55 hex2mem (&regs[CR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, 4 * 1, 0);
56 hex2mem (&regs[LR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, 4 * 1, 0);
57 hex2mem (&regs[CTR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, 4 * 1, 0);
58 hex2mem (&regs[XER_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, 4 * 1, 0);
59 hex2mem (&regs[MQ_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, 4 * 1, 0);
60 }
61
62 extern int ReadByteAltDebugger (char* addr, char *theByte);
63
64 extern int WriteByteAltDebugger (char* addr, char theByte);
65
66 extern volatile int mem_err;
67
68 int
69 get_char (addr)
70 char *addr;
71 {
72 char c;
73
74 if (!ReadByteAltDebugger (addr, &c))
75 mem_err = 1;
76
77 return c;
78 }
79
80 void
81 set_char (addr, val)
82 char *addr;
83 int val;
84 {
85 if (!WriteByteAltDebugger (addr, val))
86 mem_err = 1;
87 }
88
89 int
90 mem_write (dst, src, len)
91 char *dst, *src;
92 int len;
93 {
94 while (len-- && !mem_err)
95 set_char (dst++, *src++);
96
97 return mem_err;
98 }
99
100 union inst
101 {
102 LONG l;
103
104 struct
105 {
106 union
107 {
108 struct /* Unconditional branch */
109 {
110 unsigned opcode : 6; /* 18 */
111 signed li : 24;
112 unsigned aa : 1;
113 unsigned lk : 1;
114 } b;
115 struct /* Conditional branch */
116 {
117 unsigned opcode : 6; /* 16 */
118 unsigned bo : 5;
119 unsigned bi : 5;
120 signed bd : 14;
121 unsigned aa : 1;
122 unsigned lk : 1;
123 } bc;
124 struct /* Conditional branch to ctr or lr reg */
125 {
126 unsigned opcode : 6; /* 19 */
127 unsigned bo : 5;
128 unsigned bi : 5;
129 unsigned type : 15; /* 528 = ctr, 16 = lr */
130 unsigned lk : 1;
131 } bclr;
132 } variant;
133 } inst;
134 };
135
136 static LONG saved_inst;
137 static char *saved_inst_pc = 0;
138 static LONG saved_target_inst;
139 static char *saved_target_inst_pc = 0;
140
141 void
142 set_step_traps (frame)
143 struct StackFrame *frame;
144 {
145 union inst inst;
146 char *target;
147 int opcode;
148 int ra, rb;
149 char *pc = (char *)frame->ExceptionPC;
150
151 inst.l = *(LONG *)pc;
152
153 opcode = inst.inst.variant.b.opcode;
154
155 switch (opcode)
156 {
157 case 18: /* Unconditional branch */
158 target = (char *)(inst.inst.variant.b.li << 2);
159
160 if (!inst.inst.variant.b.aa) /* Relative? */
161 target += (long)pc;
162
163 break;
164 case 16: /* Conditional branch */
165 target = (char *)(inst.inst.variant.bc.bd << 2);
166
167 if (!inst.inst.variant.bc.aa) /* Relative? */
168 target += (long)pc;
169
170 break;
171 case 19: /* Cond. branch via ctr or lr reg */
172 switch (inst.inst.variant.bclr.type)
173 {
174 case 528: /* ctr */
175 target = (char *)frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR;
176 break;
177 case 16: /* lr */
178 target = (char *)frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR;
179 break;
180 default:
181 target = pc;
182 }
183 break;
184 default:
185 target = pc;
186 }
187
188 saved_inst = *(LONG *)pc;
189 mem_write (pc, breakpoint_insn, BREAKPOINT_SIZE);
190 saved_inst_pc = pc;
191
192 if (target != pc)
193 {
194 saved_target_inst = *(LONG *)target;
195 mem_write (target, breakpoint_insn, BREAKPOINT_SIZE);
196 saved_target_inst_pc = target;
197 }
198 }
199
200 /* Remove step breakpoints. Returns non-zero if pc was at a step breakpoint,
201 zero otherwise. This routine works even if there were no step breakpoints
202 set. */
203
204 int
205 clear_step_traps (frame)
206 struct StackFrame *frame;
207 {
208 int retcode;
209 char *pc = (char *)frame->ExceptionPC;
210
211 if (saved_inst_pc == pc || saved_target_inst_pc == pc)
212 retcode = 1;
213 else
214 retcode = 0;
215
216 if (saved_inst_pc)
217 {
218 mem_write (saved_inst_pc, saved_inst, BREAKPOINT_SIZE);
219 saved_inst_pc = 0;
220 }
221
222 if (saved_target_inst_pc)
223 {
224 mem_write (saved_target_inst_pc, saved_target_inst, BREAKPOINT_SIZE);
225 saved_target_inst_pc = 0;
226 }
227
228 return retcode;
229 }
230
231 void
232 do_status (ptr, frame)
233 char *ptr;
234 struct StackFrame *frame;
235 {
236 int sigval;
237
238 sigval = computeSignal (frame->ExceptionNumber);
239
240 sprintf (ptr, "T%02x", sigval);
241 ptr += 3;
242
243 sprintf (ptr, "%02x:", PC_REGNUM);
244 ptr = mem2hex (&frame->ExceptionPC, ptr + 3, 4, 0);
245 *ptr++ = ';';
246
247 sprintf (ptr, "%02x:", SP_REGNUM);
248 ptr = mem2hex (&frame->ExceptionState.CsavedRegs[SP_REGNUM], ptr + 3, 4, 0);
249 *ptr++ = ';';
250
251 sprintf (ptr, "%02x:", LR_REGNUM);
252 ptr = mem2hex (&frame->ExceptionState.CsavedRegs[LR_REGNUM], ptr + 3, 4, 0);
253 *ptr++ = ';';
254
255 *ptr = '\000';
256 }
257
258 /*
259 * strtol : convert a string to long.
260 *
261 * Andy Wilson, 2-Oct-89.
262 */
263
264 /* FIXME: It'd be nice to configure around these, but the include files are too
265 painful. These macros should at least be more portable than hardwired hex
266 constants. */
267
268 #define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */
269 #define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF */
270 #define LONG_MIN ((long)(~LONG_MAX)) /* 0x80000000 */
271
272 extern int errno;
273
274 unsigned long strtoul(const char *s, char **ptr, int base);
275
276 long
277 strtol(s, ptr, base)
278 const char *s; char **ptr; int base;
279 {
280 int minus=0;
281 unsigned long tmp;
282 const char *start=s;
283 char *eptr;
284
285 if (s==NULL)
286 {
287 errno = ERANGE;
288 if (!ptr)
289 *ptr = (char *)start;
290 return 0L;
291 }
292 while (isspace(*s))
293 s++;
294 if (*s == '-') {
295 s++;
296 minus = 1;
297 }
298 else if (*s == '+')
299 s++;
300
301 /*
302 * let strtoul do the hard work.
303 */
304 tmp = strtoul(s, &eptr, base);
305 if (ptr != NULL)
306 *ptr = (char *)((eptr==s) ? (char *)start : eptr);
307 if (tmp > (minus ? - (unsigned long) LONG_MIN : (unsigned long) LONG_MAX))
308 {
309 errno = ERANGE;
310 return (minus ? LONG_MIN : LONG_MAX);
311 }
312 return (minus ? (long) -tmp : (long) tmp);
313 }
314
315 /*
316 * strtol : convert a string to long.
317 *
318 * Andy Wilson, 2-Oct-89.
319 */
320
321 #ifndef ULONG_MAX
322 #define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */
323 #endif
324
325 extern int errno;
326
327 unsigned long
328 strtoul(s, ptr, base)
329 const char *s; char **ptr; int base;
330 {
331 unsigned long total = 0;
332 unsigned digit;
333 const char *start=s;
334 int did_conversion=0;
335 int overflow = 0;
336 int negate = 0;
337 unsigned long maxdiv, maxrem;
338
339 if (s==NULL)
340 {
341 errno = ERANGE;
342 if (!ptr)
343 *ptr = (char *)start;
344 return 0L;
345 }
346
347 while (isspace(*s))
348 s++;
349 if (*s == '+')
350 s++;
351 else if (*s == '-')
352 s++, negate = 1;
353 if (base==0 || base==16) /* the 'base==16' is for handling 0x */
354 {
355 int tmp;
356
357 /*
358 * try to infer base from the string
359 */
360 if (*s != '0')
361 tmp = 10; /* doesn't start with 0 - assume decimal */
362 else if (s[1] == 'X' || s[1] == 'x')
363 tmp = 16, s += 2; /* starts with 0x or 0X - hence hex */
364 else
365 tmp = 8; /* starts with 0 - hence octal */
366 if (base==0)
367 base = (int)tmp;
368 }
369
370 maxdiv = ULONG_MAX / base;
371 maxrem = ULONG_MAX % base;
372
373 while ((digit = *s) != '\0')
374 {
375 if (digit >= '0' && digit < ('0'+base))
376 digit -= '0';
377 else
378 if (base > 10)
379 {
380 if (digit >= 'a' && digit < ('a'+(base-10)))
381 digit = digit - 'a' + 10;
382 else if (digit >= 'A' && digit < ('A'+(base-10)))
383 digit = digit - 'A' + 10;
384 else
385 break;
386 }
387 else
388 break;
389 did_conversion = 1;
390 if (total > maxdiv
391 || (total == maxdiv && digit > maxrem))
392 overflow = 1;
393 total = (total * base) + digit;
394 s++;
395 }
396 if (overflow)
397 {
398 errno = ERANGE;
399 if (ptr != NULL)
400 *ptr = (char *)s;
401 return (ULONG_MAX);
402 }
403 if (ptr != NULL)
404 *ptr = (char *) ((did_conversion) ? (char *)s : (char *)start);
405 return negate ? -total : total;
406 }
407
408 void _exit (int foo) __attribute__ ((noreturn));
409
410 void
411 exit (int foo)
412 {
413 _exit (foo);
414 }
This page took 0.039893 seconds and 5 git commands to generate.