aboutsummaryrefslogtreecommitdiff
path: root/gdb/nlm/ppc.c
diff options
context:
space:
mode:
authorStu Grossman <grossman@cygnus>1994-08-18 06:32:55 +0000
committerStu Grossman <grossman@cygnus>1994-08-18 06:32:55 +0000
commitb7da24943dbe07851c083336f4c352e6e2e41d74 (patch)
treea4e317f709103fd5840b842e74f8a6aee753e05d /gdb/nlm/ppc.c
parent8c074d7ada27e4eecda9fa92c79e5bc5cf23f77b (diff)
downloadgdb-b7da24943dbe07851c083336f4c352e6e2e41d74.zip
gdb-b7da24943dbe07851c083336f4c352e6e2e41d74.tar.gz
gdb-b7da24943dbe07851c083336f4c352e6e2e41d74.tar.bz2
* Makefile.in (TARGET_FLAGS_TO_PASS): Pass down LD_FOR_TARGET and
NLMCONV_FOR_TARGET. (SUBDIRS): Add nlm target. * configure.in (powerpc-*-netware*): Automatically configure nlm subdir. * nlm/Makefile.in: Add {CC NLMCONV LD}_FOR_TARGET. Remove alpha specific stuff. Make things more configurable. * nlm/configure.in: Add powerpc-*-netware* target. Use gdbserve.mt/cpu.c/cpu.h for target stuff. Get rid of tm/xm/nm.h files. * nlm/gdbserve.c: Move Alpha specific stuff into other files. Remove lots of architecture-specific stuff. * nlm/gdbserve.def: Add new imports. * nlm/ppc.c, nlm/ppc.h: New files that contain PowerPC specific code. * nlm/prelude.c: Don't include libhooks.h, get rid of call to register library. * nlm/prelude.o: What was this doing here?
Diffstat (limited to 'gdb/nlm/ppc.c')
-rw-r--r--gdb/nlm/ppc.c414
1 files changed, 414 insertions, 0 deletions
diff --git a/gdb/nlm/ppc.c b/gdb/nlm/ppc.c
new file mode 100644
index 0000000..a683d69
--- /dev/null
+++ b/gdb/nlm/ppc.c
@@ -0,0 +1,414 @@
+#include <nwdfs.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <nwconio.h>
+#include <nwadv.h>
+#include <nwdbgapi.h>
+#include <errno.h>
+#include <nwthread.h>
+#include "ppc.h"
+
+extern char *mem2hex (void *mem, char *buf, int count, int may_fault);
+extern char *hex2mem (char *buf, void *mem, int count, int may_fault);
+extern int computeSignal (int exceptionVector);
+
+void
+flush_i_cache (void)
+{
+}
+
+/* Get the registers out of the frame information. */
+
+void
+frame_to_registers (frame, regs)
+ struct StackFrame *frame;
+ char *regs;
+{
+ mem2hex (&frame->ExceptionState.CsavedRegs, &regs[GP0_REGNUM * 4 * 2], 4 * 32, 0);
+
+ mem2hex (&frame->ExceptionState.CSavedFPRegs, &regs[FP0_REGNUM * 4 * 2], 4 * 32, 0);
+
+ mem2hex (&frame->ExceptionPC, &regs[PC_REGNUM * 4 * 2], 4 * 1, 0);
+
+ mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, &regs[CR_REGNUM * 4 * 2], 4 * 1, 0);
+ mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, &regs[LR_REGNUM * 4 * 2], 4 * 1, 0);
+ mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, &regs[CTR_REGNUM * 4 * 2], 4 * 1, 0);
+ mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, &regs[XER_REGNUM * 4 * 2], 4 * 1, 0);
+ mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, &regs[MQ_REGNUM * 4 * 2], 4 * 1, 0);
+}
+
+/* Put the registers back into the frame information. */
+
+void
+registers_to_frame (regs, frame)
+ char *regs;
+ struct StackFrame *frame;
+{
+ hex2mem (&regs[GP0_REGNUM * 4 * 2], &frame->ExceptionState.CsavedRegs, 4 * 32, 0);
+
+ hex2mem (&regs[FP0_REGNUM * 4 * 2], &frame->ExceptionState.CSavedFPRegs, 4 * 32, 0);
+
+ hex2mem (&regs[PC_REGNUM * 4 * 2], &frame->ExceptionPC, 4 * 1, 0);
+
+ hex2mem (&regs[CR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, 4 * 1, 0);
+ hex2mem (&regs[LR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, 4 * 1, 0);
+ hex2mem (&regs[CTR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, 4 * 1, 0);
+ hex2mem (&regs[XER_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, 4 * 1, 0);
+ hex2mem (&regs[MQ_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, 4 * 1, 0);
+}
+
+extern int ReadByteAltDebugger (char* addr, char *theByte);
+
+extern int WriteByteAltDebugger (char* addr, char theByte);
+
+extern volatile int mem_err;
+
+int
+get_char (addr)
+ char *addr;
+{
+ char c;
+
+ if (!ReadByteAltDebugger (addr, &c))
+ mem_err = 1;
+
+ return c;
+}
+
+void
+set_char (addr, val)
+ char *addr;
+ int val;
+{
+ if (!WriteByteAltDebugger (addr, val))
+ mem_err = 1;
+}
+
+int
+mem_write (dst, src, len)
+ char *dst, *src;
+ int len;
+{
+ while (len-- && !mem_err)
+ set_char (dst++, *src++);
+
+ return mem_err;
+}
+
+union inst
+{
+ LONG l;
+
+ struct
+ {
+ union
+ {
+ struct /* Unconditional branch */
+ {
+ unsigned opcode : 6; /* 18 */
+ signed li : 24;
+ unsigned aa : 1;
+ unsigned lk : 1;
+ } b;
+ struct /* Conditional branch */
+ {
+ unsigned opcode : 6; /* 16 */
+ unsigned bo : 5;
+ unsigned bi : 5;
+ signed bd : 14;
+ unsigned aa : 1;
+ unsigned lk : 1;
+ } bc;
+ struct /* Conditional branch to ctr or lr reg */
+ {
+ unsigned opcode : 6; /* 19 */
+ unsigned bo : 5;
+ unsigned bi : 5;
+ unsigned type : 15; /* 528 = ctr, 16 = lr */
+ unsigned lk : 1;
+ } bclr;
+ } variant;
+ } inst;
+};
+
+static LONG saved_inst;
+static char *saved_inst_pc = 0;
+static LONG saved_target_inst;
+static char *saved_target_inst_pc = 0;
+
+void
+set_step_traps (frame)
+ struct StackFrame *frame;
+{
+ union inst inst;
+ char *target;
+ int opcode;
+ int ra, rb;
+ char *pc = (char *)frame->ExceptionPC;
+
+ inst.l = *(LONG *)pc;
+
+ opcode = inst.inst.variant.b.opcode;
+
+ switch (opcode)
+ {
+ case 18: /* Unconditional branch */
+ target = (char *)(inst.inst.variant.b.li << 2);
+
+ if (!inst.inst.variant.b.aa) /* Relative? */
+ target += (long)pc;
+
+ break;
+ case 16: /* Conditional branch */
+ target = (char *)(inst.inst.variant.bc.bd << 2);
+
+ if (!inst.inst.variant.bc.aa) /* Relative? */
+ target += (long)pc;
+
+ break;
+ case 19: /* Cond. branch via ctr or lr reg */
+ switch (inst.inst.variant.bclr.type)
+ {
+ case 528: /* ctr */
+ target = (char *)frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR;
+ break;
+ case 16: /* lr */
+ target = (char *)frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR;
+ break;
+ default:
+ target = pc;
+ }
+ break;
+ default:
+ target = pc;
+ }
+
+ saved_inst = *(LONG *)pc;
+ mem_write (pc, breakpoint_insn, BREAKPOINT_SIZE);
+ saved_inst_pc = pc;
+
+ if (target != pc)
+ {
+ saved_target_inst = *(LONG *)target;
+ mem_write (target, breakpoint_insn, BREAKPOINT_SIZE);
+ saved_target_inst_pc = target;
+ }
+}
+
+/* Remove step breakpoints. Returns non-zero if pc was at a step breakpoint,
+ zero otherwise. This routine works even if there were no step breakpoints
+ set. */
+
+int
+clear_step_traps (frame)
+ struct StackFrame *frame;
+{
+ int retcode;
+ char *pc = (char *)frame->ExceptionPC;
+
+ if (saved_inst_pc == pc || saved_target_inst_pc == pc)
+ retcode = 1;
+ else
+ retcode = 0;
+
+ if (saved_inst_pc)
+ {
+ mem_write (saved_inst_pc, saved_inst, BREAKPOINT_SIZE);
+ saved_inst_pc = 0;
+ }
+
+ if (saved_target_inst_pc)
+ {
+ mem_write (saved_target_inst_pc, saved_target_inst, BREAKPOINT_SIZE);
+ saved_target_inst_pc = 0;
+ }
+
+ return retcode;
+}
+
+void
+do_status (ptr, frame)
+ char *ptr;
+ struct StackFrame *frame;
+{
+ int sigval;
+
+ sigval = computeSignal (frame->ExceptionNumber);
+
+ sprintf (ptr, "T%02x", sigval);
+ ptr += 3;
+
+ sprintf (ptr, "%02x:", PC_REGNUM);
+ ptr = mem2hex (&frame->ExceptionPC, ptr + 3, 4, 0);
+ *ptr++ = ';';
+
+ sprintf (ptr, "%02x:", SP_REGNUM);
+ ptr = mem2hex (&frame->ExceptionState.CsavedRegs[SP_REGNUM], ptr + 3, 4, 0);
+ *ptr++ = ';';
+
+ sprintf (ptr, "%02x:", LR_REGNUM);
+ ptr = mem2hex (&frame->ExceptionState.CsavedRegs[LR_REGNUM], ptr + 3, 4, 0);
+ *ptr++ = ';';
+
+ *ptr = '\000';
+}
+
+/*
+ * strtol : convert a string to long.
+ *
+ * Andy Wilson, 2-Oct-89.
+ */
+
+/* FIXME: It'd be nice to configure around these, but the include files are too
+ painful. These macros should at least be more portable than hardwired hex
+ constants. */
+
+#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */
+#define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF */
+#define LONG_MIN ((long)(~LONG_MAX)) /* 0x80000000 */
+
+extern int errno;
+
+unsigned long strtoul(const char *s, char **ptr, int base);
+
+long
+strtol(s, ptr, base)
+ const char *s; char **ptr; int base;
+{
+ int minus=0;
+ unsigned long tmp;
+ const char *start=s;
+ char *eptr;
+
+ if (s==NULL)
+ {
+ errno = ERANGE;
+ if (!ptr)
+ *ptr = (char *)start;
+ return 0L;
+ }
+ while (isspace(*s))
+ s++;
+ if (*s == '-') {
+ s++;
+ minus = 1;
+ }
+ else if (*s == '+')
+ s++;
+
+ /*
+ * let strtoul do the hard work.
+ */
+ tmp = strtoul(s, &eptr, base);
+ if (ptr != NULL)
+ *ptr = (char *)((eptr==s) ? (char *)start : eptr);
+ if (tmp > (minus ? - (unsigned long) LONG_MIN : (unsigned long) LONG_MAX))
+ {
+ errno = ERANGE;
+ return (minus ? LONG_MIN : LONG_MAX);
+ }
+ return (minus ? (long) -tmp : (long) tmp);
+}
+
+/*
+ * strtol : convert a string to long.
+ *
+ * Andy Wilson, 2-Oct-89.
+ */
+
+#ifndef ULONG_MAX
+#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */
+#endif
+
+extern int errno;
+
+unsigned long
+strtoul(s, ptr, base)
+ const char *s; char **ptr; int base;
+{
+ unsigned long total = 0;
+ unsigned digit;
+ const char *start=s;
+ int did_conversion=0;
+ int overflow = 0;
+ int negate = 0;
+ unsigned long maxdiv, maxrem;
+
+ if (s==NULL)
+ {
+ errno = ERANGE;
+ if (!ptr)
+ *ptr = (char *)start;
+ return 0L;
+ }
+
+ while (isspace(*s))
+ s++;
+ if (*s == '+')
+ s++;
+ else if (*s == '-')
+ s++, negate = 1;
+ if (base==0 || base==16) /* the 'base==16' is for handling 0x */
+ {
+ int tmp;
+
+ /*
+ * try to infer base from the string
+ */
+ if (*s != '0')
+ tmp = 10; /* doesn't start with 0 - assume decimal */
+ else if (s[1] == 'X' || s[1] == 'x')
+ tmp = 16, s += 2; /* starts with 0x or 0X - hence hex */
+ else
+ tmp = 8; /* starts with 0 - hence octal */
+ if (base==0)
+ base = (int)tmp;
+ }
+
+ maxdiv = ULONG_MAX / base;
+ maxrem = ULONG_MAX % base;
+
+ while ((digit = *s) != '\0')
+ {
+ if (digit >= '0' && digit < ('0'+base))
+ digit -= '0';
+ else
+ if (base > 10)
+ {
+ if (digit >= 'a' && digit < ('a'+(base-10)))
+ digit = digit - 'a' + 10;
+ else if (digit >= 'A' && digit < ('A'+(base-10)))
+ digit = digit - 'A' + 10;
+ else
+ break;
+ }
+ else
+ break;
+ did_conversion = 1;
+ if (total > maxdiv
+ || (total == maxdiv && digit > maxrem))
+ overflow = 1;
+ total = (total * base) + digit;
+ s++;
+ }
+ if (overflow)
+ {
+ errno = ERANGE;
+ if (ptr != NULL)
+ *ptr = (char *)s;
+ return (ULONG_MAX);
+ }
+ if (ptr != NULL)
+ *ptr = (char *) ((did_conversion) ? (char *)s : (char *)start);
+ return negate ? -total : total;
+}
+
+void _exit (int foo) __attribute__ ((noreturn));
+
+void
+exit (int foo)
+{
+ _exit (foo);
+}