diff options
author | nobody <> | 2003-11-10 21:20:45 +0000 |
---|---|---|
committer | nobody <> | 2003-11-10 21:20:45 +0000 |
commit | dd13cc9a87d19f095a199544e49c73fd98bbe708 (patch) | |
tree | 4db8a7a82ceec154c97430d12ab7e8bb26fb13e8 | |
parent | bf5543d0ac6881c97433a44aea21c10b91b70701 (diff) | |
download | gdb-dd13cc9a87d19f095a199544e49c73fd98bbe708.zip gdb-dd13cc9a87d19f095a199544e49c73fd98bbe708.tar.gz gdb-dd13cc9a87d19f095a199544e49c73fd98bbe708.tar.bz2 |
This commit was manufactured by cvs2svn to create branch
'carlton_dictionary-branch'.
Cherrypick from master 2003-11-10 21:20:44 UTC Andrew Cagney <cagney@redhat.com> '2003-11-10 Andrew Cagney <cagney@redhat.com>':
gdb/amd64bsd-nat.c
gdb/amd64nbsd-nat.c
gdb/amd64nbsd-tdep.c
gdb/bfd-target.c
gdb/bfd-target.h
gdb/config/i386/nbsd64.mh
gdb/config/i386/nbsd64.mt
gdb/exec.h
gdb/glibc-tdep.c
gdb/glibc-tdep.h
gdb/i386fbsd-tdep.c
gdb/regset.h
gdb/remote-m32r-sdi.c
gdb/testsuite/gdb.arch/gdb1291.c
gdb/testsuite/gdb.arch/gdb1291.exp
gdb/testsuite/gdb.arch/gdb1431.c
gdb/testsuite/gdb.arch/gdb1431.exp
gdb/testsuite/gdb.base/gdb1056.exp
gdb/testsuite/gdb.cp/gdb1355.cc
gdb/testsuite/gdb.cp/gdb1355.exp
gdb/testsuite/gdb.threads/switch-threads.c
gdb/testsuite/gdb.threads/switch-threads.exp
include/gdb/sim-frv.h
-rw-r--r-- | gdb/amd64bsd-nat.c | 107 | ||||
-rw-r--r-- | gdb/amd64nbsd-nat.c | 68 | ||||
-rw-r--r-- | gdb/amd64nbsd-tdep.c | 129 | ||||
-rw-r--r-- | gdb/bfd-target.c | 131 | ||||
-rw-r--r-- | gdb/bfd-target.h | 39 | ||||
-rw-r--r-- | gdb/config/i386/nbsd64.mh | 7 | ||||
-rw-r--r-- | gdb/config/i386/nbsd64.mt | 2 | ||||
-rw-r--r-- | gdb/exec.h | 39 | ||||
-rw-r--r-- | gdb/glibc-tdep.c | 101 | ||||
-rw-r--r-- | gdb/glibc-tdep.h | 27 | ||||
-rw-r--r-- | gdb/i386fbsd-tdep.c | 171 | ||||
-rw-r--r-- | gdb/regset.h | 41 | ||||
-rw-r--r-- | gdb/remote-m32r-sdi.c | 1673 | ||||
-rwxr-xr-x | gdb/testsuite/gdb.arch/gdb1291.c | 44 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/gdb1291.exp | 62 | ||||
-rwxr-xr-x | gdb/testsuite/gdb.arch/gdb1431.c | 63 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/gdb1431.exp | 66 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/gdb1056.exp | 48 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/gdb1355.cc | 35 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/gdb1355.exp | 119 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/switch-threads.c | 47 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/switch-threads.exp | 52 | ||||
-rw-r--r-- | include/gdb/sim-frv.h | 53 |
23 files changed, 3124 insertions, 0 deletions
diff --git a/gdb/amd64bsd-nat.c b/gdb/amd64bsd-nat.c new file mode 100644 index 0000000..6c85f20 --- /dev/null +++ b/gdb/amd64bsd-nat.c @@ -0,0 +1,107 @@ +/* Native-dependent code for AMD64 BSD's. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "inferior.h" +#include "regcache.h" + +/* We include <signal.h> to make sure `struct fxsave64' is defined on + NetBSD, since NetBSD's <machine/reg.h> needs it. */ +#include "gdb_assert.h" +#include <signal.h> +#include <sys/types.h> +#include <sys/ptrace.h> +#include <machine/reg.h> + +#include "x86-64-tdep.h" +#include "amd64-nat.h" + + +/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this + for all registers (including the floating-point registers). */ + +void +fetch_inferior_registers (int regnum) +{ + if (regnum == -1 || amd64_native_gregset_supplies_p (regnum)) + { + struct reg regs; + + if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't get registers"); + + amd64_supply_native_gregset (current_regcache, ®s, -1); + if (regnum != -1) + return; + } + + if (regnum == -1 || regnum >= X86_64_ST0_REGNUM) + { + struct fpreg fpregs; + + if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't get floating point status"); + + x86_64_supply_fxsave (current_regcache, -1, &fpregs); + } +} + +/* Store register REGNUM back into the inferior. If REGNUM is -1, do + this for all registers (including the floating-point registers). */ + +void +store_inferior_registers (int regnum) +{ + if (regnum == -1 || amd64_native_gregset_supplies_p (regnum)) + { + struct reg regs; + + if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't get registers"); + + amd64_collect_native_gregset (current_regcache, ®s, regnum); + + if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't write registers"); + + if (regnum != -1) + return; + } + + if (regnum == -1 || regnum >= X86_64_ST0_REGNUM) + { + struct fpreg fpregs; + + if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't get floating point status"); + + x86_64_fill_fxsave ((char *) &fpregs, regnum); + + if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't write floating point status"); + } +} diff --git a/gdb/amd64nbsd-nat.c b/gdb/amd64nbsd-nat.c new file mode 100644 index 0000000..4af22fe --- /dev/null +++ b/gdb/amd64nbsd-nat.c @@ -0,0 +1,68 @@ +/* Native-dependent code for NetBSD/amd64. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" + +#include "gdb_assert.h" + +#include "x86-64-tdep.h" +#include "amd64-nat.h" + +/* Mapping between the general-purpose registers in NetBSD/amd64 + `struct reg' format and GDB's register cache layout for + NetBSD/i386. + + Note that most (if not all) NetBSD/amd64 registers are 64-bit, + while the NetBSD/i386 registers are all 32-bit, but since we're + little-endian we get away with that. */ + +/* From <machine/reg.h>. */ +static int amd64nbsd32_r_reg_offset[] = +{ + 14 * 8, /* %eax */ + 3 * 8, /* %ecx */ + 2 * 8, /* %edx */ + 13 * 8, /* %ebx */ + 24 * 8, /* %esp */ + 12 * 8, /* %ebp */ + 1 * 8, /* %esi */ + 0 * 8, /* %edi */ + 21 * 8, /* %eip */ + 23 * 8, /* %eflags */ + -1, /* %cs */ + -1, /* %ss */ + 18 * 8, /* %ds */ + 17 * 8, /* %es */ + 16 * 8, /* %fs */ + 15 * 8 /* %gs */ +}; + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_amd64nbsd_nat (void); + +void +_initialize_amd64nbsd_nat (void) +{ + amd64_native_gregset32_reg_offset = amd64nbsd32_r_reg_offset; + amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64nbsd32_r_reg_offset); + amd64_native_gregset64_reg_offset = amd64nbsd_r_reg_offset; +} diff --git a/gdb/amd64nbsd-tdep.c b/gdb/amd64nbsd-tdep.c new file mode 100644 index 0000000..5500ed1 --- /dev/null +++ b/gdb/amd64nbsd-tdep.c @@ -0,0 +1,129 @@ +/* Target-dependent code for NetBSD/amd64. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "arch-utils.h" +#include "frame.h" +#include "gdbcore.h" +#include "osabi.h" + +#include "gdb_assert.h" + +#include "nbsd-tdep.h" +#include "x86-64-tdep.h" + +/* Support for signal handlers. */ + +/* Assuming NEXT_FRAME is for a frame following a BSD sigtramp + routine, return the address of the associated sigcontext structure. */ + +static CORE_ADDR +amd64nbsd_sigcontext_addr (struct frame_info *next_frame) +{ + CORE_ADDR sp; + + /* The stack pointer points at `struct sigcontext' upon entry of a + signal trampoline. */ + sp = frame_unwind_register_unsigned (next_frame, X86_64_RSP_REGNUM); + return sp; +} + +/* NetBSD 2.0 or later. */ + +/* Mapping between the general-purpose registers in `struct reg' + format and GDB's register cache layout. */ + +/* From <machine/reg.h>. */ +int amd64nbsd_r_reg_offset[] = +{ + 14 * 8, /* %rax */ + 13 * 8, /* %rbx */ + 3 * 8, /* %rcx */ + 2 * 8, /* %rdx */ + 1 * 8, /* %rsi */ + 0 * 8, /* %rdi */ + 12 * 8, /* %rbp */ + 24 * 8, /* %rsp */ + 4 * 8, /* %r8 .. */ + 5 * 8, + 6 * 8, + 7 * 8, + 8 * 8, + 9 * 8, + 10 * 8, + 11 * 8, /* ... %r15 */ + 21 * 8, /* %rip */ + 23 * 8, /* %eflags */ + 18 * 8, /* %ds */ + 17 * 8, /* %es */ + 16 * 8, /* %fs */ + 15 * 8 /* %gs */ +}; + +static void +amd64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int *sc_reg_offset; + int i; + + /* Initialize general-purpose register set details first. */ + tdep->gregset_reg_offset = amd64nbsd_r_reg_offset; + tdep->gregset_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset); + tdep->sizeof_gregset = 26 * 8; + + x86_64_init_abi (info, gdbarch); + + tdep->jb_pc_offset = 7 * 8; + + /* NetBSD has its own convention for signal trampolines. */ + set_gdbarch_pc_in_sigtramp (gdbarch, nbsd_pc_in_sigtramp); + + /* Initialize the array with register offsets in `struct + sigcontext'. This `struct sigcontext' has an sc_mcontext member + at offset 32, and in <machine/reg.h> we have an explicit comment + saying that `struct reg' is the same as mcontext.__gregs. */ + tdep->sc_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset); + tdep->sc_reg_offset = XCALLOC (tdep->sc_num_regs, int); + for (i = 0; i < tdep->sc_num_regs; i++) + { + if (amd64nbsd_r_reg_offset[i] < 0) + tdep->sc_reg_offset[i] = -1; + else + tdep->sc_reg_offset[i] = 32 + amd64nbsd_r_reg_offset[i]; + } + + tdep->sigcontext_addr = amd64nbsd_sigcontext_addr; +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_amd64nbsd_tdep (void); + +void +_initialize_amd64nbsd_ndep (void) +{ + /* The NetBSD/amd64 native dependent code makes this assumption. */ + gdb_assert (ARRAY_SIZE (amd64nbsd_r_reg_offset) == X86_64_NUM_GREGS); + + gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, + GDB_OSABI_NETBSD_ELF, amd64nbsd_init_abi); +} diff --git a/gdb/bfd-target.c b/gdb/bfd-target.c new file mode 100644 index 0000000..ee16d85 --- /dev/null +++ b/gdb/bfd-target.c @@ -0,0 +1,131 @@ +/* Very simple "bfd" target, for GDB, the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "target.h" +#include "bfd-target.h" +#include "gdb_assert.h" +#include "gdb_string.h" + +/* Locate all mappable sections of a BFD file, filling in a target + section for each. */ + +struct section_closure +{ + struct section_table *end; +}; + +static void +add_to_section_table (struct bfd *abfd, struct bfd_section *asect, + void *closure) +{ + struct section_closure *pp = closure; + flagword aflag; + + /* NOTE: cagney/2003-10-22: Is this pruning useful? */ + aflag = bfd_get_section_flags (abfd, asect); + if (!(aflag & SEC_ALLOC)) + return; + if (bfd_section_size (abfd, asect) == 0) + return; + pp->end->bfd = abfd; + pp->end->the_bfd_section = asect; + pp->end->addr = bfd_section_vma (abfd, asect); + pp->end->endaddr = pp->end->addr + bfd_section_size (abfd, asect); + pp->end++; +} + +void +build_target_sections_from_bfd (struct target_ops *targ, struct bfd *abfd) +{ + unsigned count; + struct section_table *start; + struct section_closure cl; + + count = bfd_count_sections (abfd); + target_resize_to_sections (targ, count); + start = targ->to_sections; + cl.end = targ->to_sections; + bfd_map_over_sections (abfd, add_to_section_table, &cl); + gdb_assert (cl.end - start <= count); +} + +LONGEST +target_bfd_xfer_partial (struct target_ops *ops, + enum target_object object, + const char *annex, void *readbuf, + const void *writebuf, ULONGEST offset, LONGEST len) +{ + switch (object) + { + case TARGET_OBJECT_MEMORY: + { + struct section_table *s = target_section_by_addr (ops, offset); + if (s == NULL) + return -1; + /* If the length extends beyond the section, truncate it. Be + careful to not suffer from overflow (wish S contained a + length). */ + if ((offset - s->addr + len) > (s->endaddr - s->addr)) + len = (s->endaddr - s->addr) - (offset - s->addr); + if (readbuf != NULL + && !bfd_get_section_contents (s->bfd, s->the_bfd_section, + readbuf, offset - s->addr, len)) + return -1; +#if 1 + if (writebuf != NULL) + return -1; +#else + /* FIXME: cagney/2003-10-31: The BFD interface doesn't yet + take a const buffer. */ + if (writebuf != NULL + && !bfd_set_section_contents (s->bfd, s->the_bfd_section, + writebuf, offset - s->addr, len)) + return -1; +#endif + return len; + } + default: + return -1; + } +} + +void +target_bfd_xclose (struct target_ops *t, int quitting) +{ + bfd_close (t->to_data); + xfree (t->to_sections); + xfree (t); +} + +struct target_ops * +target_bfd_reopen (struct bfd *bfd) +{ + struct target_ops *t = XZALLOC (struct target_ops); + t->to_shortname = "bfd"; + t->to_longname = "BFD backed target"; + t->to_doc = "You should never see this"; + t->to_xfer_partial = target_bfd_xfer_partial; + t->to_xclose = target_bfd_xclose; + t->to_data = bfd; + build_target_sections_from_bfd (t, bfd); + return t; +} diff --git a/gdb/bfd-target.h b/gdb/bfd-target.h new file mode 100644 index 0000000..61a51c8 --- /dev/null +++ b/gdb/bfd-target.h @@ -0,0 +1,39 @@ +/* Very simple "bfd" target, for GDB, the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef BFD_TARGET_H +#define BFD_TARGET_H + +struct bfd; +struct target_ops; + +/* Given an existing BFD, re-open it as a "struct target_ops". On + close, it will also close the corresponding BFD (which is like + freopen and fdopen). */ +struct target_ops *target_bfd_reopen (struct bfd *bfd); + +/* Map over ABFD's sections, creating corresponding entries in the + target's section table. */ + +void build_target_sections_from_bfd (struct target_ops *targ, + struct bfd *abfd); + +#endif diff --git a/gdb/config/i386/nbsd64.mh b/gdb/config/i386/nbsd64.mh new file mode 100644 index 0000000..5acd167 --- /dev/null +++ b/gdb/config/i386/nbsd64.mh @@ -0,0 +1,7 @@ +# Host: NetBSD/amd64 + +XM_FILE= xm-i386.h + +NAT_FILE= nm-nbsd.h +# NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make. +NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o amd64-nat.o amd64bsd-nat.o amd64nbsd-nat.o diff --git a/gdb/config/i386/nbsd64.mt b/gdb/config/i386/nbsd64.mt new file mode 100644 index 0000000..6d73660 --- /dev/null +++ b/gdb/config/i386/nbsd64.mt @@ -0,0 +1,2 @@ +# Target: NetBSD/amd64 +TDEPFILES= x86-64-tdep.o amd64nbsd-tdep.o i386-tdep.o i387-tdep.o nbsd-tdep.o diff --git a/gdb/exec.h b/gdb/exec.h new file mode 100644 index 0000000..e9c2d17 --- /dev/null +++ b/gdb/exec.h @@ -0,0 +1,39 @@ +/* Work with executable files, for GDB, the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef EXEC_H +#define EXEC_H + +#include "target.h" + +struct section_table; +struct target_ops; +struct bfd; + +struct target_ops exec_ops; + +/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR. + Returns 0 if OK, 1 on error. */ + +extern int build_section_table (struct bfd *, struct section_table **, + struct section_table **); + +#endif diff --git a/gdb/glibc-tdep.c b/gdb/glibc-tdep.c new file mode 100644 index 0000000..46aa749 --- /dev/null +++ b/gdb/glibc-tdep.c @@ -0,0 +1,101 @@ +/* Target-dependent code for the GNU C Library (glibc). + + Copyright 2002, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" +#include "symtab.h" +#include "symfile.h" +#include "objfiles.h" + +#include "glibc-tdep.h" + +/* Calling functions in shared libraries. */ + +/* Find the minimal symbol named NAME, and return both the minsym + struct and its objfile. This probably ought to be in minsym.c, but + everything there is trying to deal with things like C++ and + SOFUN_ADDRESS_MAYBE_TURQUOISE, ... Since this is so simple, it may + be considered too special-purpose for general consumption. */ + +static struct minimal_symbol * +find_minsym_and_objfile (char *name, struct objfile **objfile_p) +{ + struct objfile *objfile; + + ALL_OBJFILES (objfile) + { + struct minimal_symbol *msym; + + ALL_OBJFILE_MSYMBOLS (objfile, msym) + { + if (SYMBOL_LINKAGE_NAME (msym) + && strcmp (SYMBOL_LINKAGE_NAME (msym), name) == 0) + { + *objfile_p = objfile; + return msym; + } + } + } + + return 0; +} + +/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c. + This function: + 1) decides whether a PLT has sent us into the linker to resolve + a function reference, and + 2) if so, tells us where to set a temporary breakpoint that will + trigger when the dynamic linker is done. */ + +CORE_ADDR +glibc_skip_solib_resolver (CORE_ADDR pc) +{ + /* The GNU dynamic linker is part of the GNU C library, and is used + by all GNU systems (GNU/Hurd, GNU/Linux). An unresolved PLT + entry points to "_dl_runtime_resolve", which calls "fixup" to + patch the PLT, and then passes control to the function. + + We look for the symbol `_dl_runtime_resolve', and find `fixup' in + the same objfile. If we are at the entry point of `fixup', then + we set a breakpoint at the return address (at the top of the + stack), and continue. + + It's kind of gross to do all these checks every time we're + called, since they don't change once the executable has gotten + started. But this is only a temporary hack --- upcoming versions + of GNU/Linux will provide a portable, efficient interface for + debugging programs that use shared libraries. */ + + struct objfile *objfile; + struct minimal_symbol *resolver + = find_minsym_and_objfile ("_dl_runtime_resolve", &objfile); + + if (resolver) + { + struct minimal_symbol *fixup + = lookup_minimal_symbol ("fixup", NULL, objfile); + + if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc) + return frame_pc_unwind (get_current_frame ()); + } + + return 0; +} diff --git a/gdb/glibc-tdep.h b/gdb/glibc-tdep.h new file mode 100644 index 0000000..31c77b9 --- /dev/null +++ b/gdb/glibc-tdep.h @@ -0,0 +1,27 @@ +/* Target-dependent code for the GNU C Library (glibc). + + Copyright 2002, 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef GLIBC_TDEP_H +#define GLIBC_TDEP_H + +extern CORE_ADDR glibc_skip_solib_resolver (CORE_ADDR); + +#endif /* glibc-tdep.h */ diff --git a/gdb/i386fbsd-tdep.c b/gdb/i386fbsd-tdep.c new file mode 100644 index 0000000..786de7d --- /dev/null +++ b/gdb/i386fbsd-tdep.c @@ -0,0 +1,171 @@ +/* Target-dependent code for FreeBSD/i386. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "arch-utils.h" +#include "osabi.h" + +#include "i386-tdep.h" +#include "i387-tdep.h" + +/* FreeBSD 3.0-RELEASE or later. */ + +/* From <machine/reg.h>. */ +static int i386fbsd_r_reg_offset[] = +{ + 9 * 4, 8 * 4, 7 * 4, 6 * 4, /* %eax, %ecx, %edx, %ebx */ + 15 * 4, 4 * 4, /* %esp, %ebp */ + 3 * 4, 2 * 4, /* %esi, %edi */ + 12 * 4, 14 * 4, /* %eip, %eflags */ + 13 * 4, 16 * 4, /* %cs, %ss */ + 1 * 4, 0 * 4, -1, -1 /* %ds, %es, %fs, %gs */ +}; + +CORE_ADDR i386fbsd_sigtramp_start = 0xbfbfdf20; +CORE_ADDR i386fbsd_sigtramp_end = 0xbfbfdff0; + +/* From <machine/signal.h>. */ +static int i386fbsd_sc_reg_offset[] = +{ + 8 + 14 * 4, /* %eax */ + 8 + 13 * 4, /* %ecx */ + 8 + 12 * 4, /* %edx */ + 8 + 11 * 4, /* %ebx */ + 8 + 0 * 4, /* %esp */ + 8 + 1 * 4, /* %ebp */ + 8 + 10 * 4, /* %esi */ + 8 + 9 * 4, /* %edi */ + 8 + 3 * 4, /* %eip */ + 8 + 4 * 4, /* %eflags */ + 8 + 7 * 4, /* %cs */ + 8 + 8 * 4, /* %ss */ + 8 + 6 * 4, /* %ds */ + 8 + 5 * 4, /* %es */ + 8 + 15 * 4, /* %fs */ + 8 + 16 * 4 /* %gs */ +}; + +static void +i386fbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Obviously FreeBSD is BSD-based. */ + i386bsd_init_abi (info, gdbarch); + + /* FreeBSD has a different `struct reg', and reserves some space for + its FPU emulator in `struct fpreg'. */ + tdep->gregset_reg_offset = i386fbsd_r_reg_offset; + tdep->gregset_num_regs = ARRAY_SIZE (i386fbsd_r_reg_offset); + tdep->sizeof_gregset = 18 * 4; + tdep->sizeof_fpregset = 176; + + /* FreeBSD uses -freg-struct-return by default. */ + tdep->struct_return = reg_struct_return; + + /* FreeBSD uses a different memory layout. */ + tdep->sigtramp_start = i386fbsd_sigtramp_start; + tdep->sigtramp_end = i386fbsd_sigtramp_end; + + /* FreeBSD has a more complete `struct sigcontext'. */ + tdep->sc_reg_offset = i386fbsd_sc_reg_offset; + tdep->sc_num_regs = ARRAY_SIZE (i386fbsd_sc_reg_offset); +} + +static void +i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + /* It's almost identical to FreeBSD a.out. */ + i386fbsdaout_init_abi (info, gdbarch); + + /* Except that it uses ELF. */ + i386_elf_init_abi (info, gdbarch); + + /* FreeBSD ELF uses SVR4-style shared libraries. */ + set_gdbarch_in_solib_call_trampoline (gdbarch, + generic_in_solib_call_trampoline); +} + +/* FreeBSD 4.0-RELEASE or later. */ + +/* From <machine/reg.h>. */ +static int i386fbsd4_r_reg_offset[] = +{ + 10 * 4, 9 * 4, 8 * 4, 7 * 4, /* %eax, %ecx, %edx, %ebx */ + 16 * 4, 5 * 4, /* %esp, %ebp */ + 4 * 4, 3 * 4, /* %esi, %edi */ + 13 * 4, 15 * 4, /* %eip, %eflags */ + 14 * 4, 17 * 4, /* %cs, %ss */ + 2 * 4, 1 * 4, 0 * 4, 18 * 4 /* %ds, %es, %fs, %gs */ +}; + +/* From <machine/signal.h>. */ +int i386fbsd4_sc_reg_offset[] = +{ + 20 + 11 * 4, /* %eax */ + 20 + 10 * 4, /* %ecx */ + 20 + 9 * 4, /* %edx */ + 20 + 8 * 4, /* %ebx */ + 20 + 17 * 4, /* %esp */ + 20 + 6 * 4, /* %ebp */ + 20 + 5 * 4, /* %esi */ + 20 + 4 * 4, /* %edi */ + 20 + 14 * 4, /* %eip */ + 20 + 16 * 4, /* %eflags */ + 20 + 15 * 4, /* %cs */ + 20 + 18 * 4, /* %ss */ + 20 + 3 * 4, /* %ds */ + 20 + 2 * 4, /* %es */ + 20 + 1 * 4, /* %fs */ + 20 + 0 * 4 /* %gs */ +}; + +static void +i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Inherit stuff from older releases. We assume that FreeBSD + 4.0-RELEASE always uses ELF. */ + i386fbsd_init_abi (info, gdbarch); + + /* FreeBSD 4.0 introduced a new `struct reg'. */ + tdep->gregset_reg_offset = i386fbsd4_r_reg_offset; + tdep->gregset_num_regs = ARRAY_SIZE (i386fbsd4_r_reg_offset); + tdep->sizeof_gregset = 19 * 4; + + /* FreeBSD 4.0 introduced a new `struct sigcontext'. */ + tdep->sc_reg_offset = i386fbsd4_sc_reg_offset; + tdep->sc_num_regs = ARRAY_SIZE (i386fbsd4_sc_reg_offset); +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_i386fbsd_tdep (void); + +void +_initialize_i386fbsd_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_FREEBSD_AOUT, + i386fbsdaout_init_abi); + gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_FREEBSD_ELF, + i386fbsd4_init_abi); +} diff --git a/gdb/regset.h b/gdb/regset.h new file mode 100644 index 0000000..6172f0f --- /dev/null +++ b/gdb/regset.h @@ -0,0 +1,41 @@ +/* Manage register sets. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef REGSET_H +#define REGSET_H 1 + +struct gdbarch; +struct regcache; + +/* Data structure describing a register set. */ + +struct regset +{ + /* Data pointer for private use by the methods below, presumably + providing some sort of description of the register set. */ + const void *descr; + + /* Function supplying a register set to a register cache. */ + void (*supply_regset) (const struct regset *, struct regcache *, + int, const void *, size_t); +}; + +#endif /* regset.h */ diff --git a/gdb/remote-m32r-sdi.c b/gdb/remote-m32r-sdi.c new file mode 100644 index 0000000..7f0b90c --- /dev/null +++ b/gdb/remote-m32r-sdi.c @@ -0,0 +1,1673 @@ +/* Remote debugging interface for M32R/SDI. + + Copyright 2003 Free Software Foundation, Inc. + + Contributed by Renesas Technology Co. + Written by Kei Sakamoto <sakamoto.kei@renesas.com>. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbcmd.h" +#include "gdbcore.h" +#include "inferior.h" +#include "target.h" +#include "regcache.h" +#include "gdb_string.h" +#include <ctype.h> +#include <signal.h> +#include <netinet/in.h> +#include <sys/types.h> +#include <sys/time.h> +#include <signal.h> +#include <time.h> + + +#include "serial.h" + +/* Descriptor for I/O to remote machine. */ + +static struct serial *sdi_desc = NULL; + +#define SDI_TIMEOUT 30 + + +#define SDIPORT 3232 + +static char chip_name[64]; + +static int step_mode; +static unsigned long last_pc_addr = 0xffffffff; +static unsigned char last_pc_addr_data[2]; + +static int mmu_on = 0; + +static int use_ib_breakpoints = 1; + +#define MAX_BREAKPOINTS 1024 +static int max_ib_breakpoints; +static unsigned long bp_address[MAX_BREAKPOINTS]; +static unsigned char bp_data[MAX_BREAKPOINTS][4]; +static const unsigned char ib_bp_entry_enable[] = { + 0x00, 0x00, 0x00, 0x06 +}; +static const unsigned char ib_bp_entry_disable[] = { + 0x00, 0x00, 0x00, 0x00 +}; + +/* dbt -> nop */ +static const unsigned char dbt_bp_entry[] = { + 0x10, 0xe0, 0x70, 0x00 +}; + +#define MAX_ACCESS_BREAKS 4 +static int max_access_breaks; +static unsigned long ab_address[MAX_ACCESS_BREAKS]; +static unsigned int ab_type[MAX_ACCESS_BREAKS]; +static unsigned int ab_size[MAX_ACCESS_BREAKS]; +static CORE_ADDR hit_watchpoint_addr = 0; + +static int interrupted = 0; + +/* Forward data declarations */ +extern struct target_ops m32r_ops; + + +/* Commands */ +#define SDI_OPEN 1 +#define SDI_CLOSE 2 +#define SDI_RELEASE 3 +#define SDI_READ_CPU_REG 4 +#define SDI_WRITE_CPU_REG 5 +#define SDI_READ_MEMORY 6 +#define SDI_WRITE_MEMORY 7 +#define SDI_EXEC_CPU 8 +#define SDI_STOP_CPU 9 +#define SDI_WAIT_FOR_READY 10 +#define SDI_GET_ATTR 11 +#define SDI_SET_ATTR 12 +#define SDI_STATUS 13 + +/* Attributes */ +#define SDI_ATTR_NAME 1 +#define SDI_ATTR_BRK 2 +#define SDI_ATTR_ABRK 3 +#define SDI_ATTR_CACHE 4 +#define SDI_CACHE_TYPE_M32102 0 +#define SDI_CACHE_TYPE_CHAOS 1 +#define SDI_ATTR_MEM_ACCESS 5 +#define SDI_MEM_ACCESS_DEBUG_DMA 0 +#define SDI_MEM_ACCESS_MON_CODE 1 + +/* Registers */ +#define SDI_REG_R0 0 +#define SDI_REG_R1 1 +#define SDI_REG_R2 2 +#define SDI_REG_R3 3 +#define SDI_REG_R4 4 +#define SDI_REG_R5 5 +#define SDI_REG_R6 6 +#define SDI_REG_R7 7 +#define SDI_REG_R8 8 +#define SDI_REG_R9 9 +#define SDI_REG_R10 10 +#define SDI_REG_R11 11 +#define SDI_REG_R12 12 +#define SDI_REG_FP 13 +#define SDI_REG_LR 14 +#define SDI_REG_SP 15 +#define SDI_REG_PSW 16 +#define SDI_REG_CBR 17 +#define SDI_REG_SPI 18 +#define SDI_REG_SPU 19 +#define SDI_REG_CR4 20 +#define SDI_REG_EVB 21 +#define SDI_REG_BPC 22 +#define SDI_REG_CR7 23 +#define SDI_REG_BBPSW 24 +#define SDI_REG_CR9 25 +#define SDI_REG_CR10 26 +#define SDI_REG_CR11 27 +#define SDI_REG_CR12 28 +#define SDI_REG_WR 29 +#define SDI_REG_BBPC 30 +#define SDI_REG_PBP 31 +#define SDI_REG_ACCH 32 +#define SDI_REG_ACCL 33 +#define SDI_REG_ACC1H 34 +#define SDI_REG_ACC1L 35 + + +/* Low level communication functions */ + +/* Check an ack packet from the target */ +static int +get_ack (void) +{ + int c; + + if (!sdi_desc) + return -1; + + c = serial_readchar (sdi_desc, SDI_TIMEOUT); + + if (c < 0) + return -1; + + if (c != '+') /* error */ + return -1; + + return 0; +} + +/* Send data to the target and check an ack packet */ +static int +send_data (void *buf, int len) +{ + int ret; + + if (!sdi_desc) + return -1; + + if (serial_write (sdi_desc, buf, len) != 0) + return -1; + + if (get_ack () == -1) + return -1; + + return len; +} + +/* Receive data from the target */ +static int +recv_data (void *buf, int len) +{ + int total = 0; + int c; + + if (!sdi_desc) + return -1; + + while (total < len) + { + c = serial_readchar (sdi_desc, SDI_TIMEOUT); + + if (c < 0) + return -1; + + ((unsigned char *) buf)[total++] = c; + } + + return len; +} + +/* Store unsigned long parameter on packet */ +static void +store_long_parameter (void *buf, long val) +{ + val = htonl (val); + memcpy (buf, &val, 4); +} + +/* Check if MMU is on */ +static void +check_mmu_status (void) +{ + unsigned long val; + unsigned char buf[2]; + + /* Read PC address */ + buf[0] = SDI_READ_CPU_REG; + buf[1] = SDI_REG_BPC; + if (send_data (buf, 2) == -1) + return; + recv_data (&val, 4); + val = ntohl (val); + if ((val & 0xc0000000) == 0x80000000) + { + mmu_on = 1; + return; + } + + /* Read EVB address */ + buf[0] = SDI_READ_CPU_REG; + buf[1] = SDI_REG_EVB; + if (send_data (buf, 2) == -1) + return; + recv_data (&val, 4); + val = ntohl (val); + if ((val & 0xc0000000) == 0x80000000) + { + mmu_on = 1; + return; + } + + mmu_on = 0; +} + + +/* This is called not only when we first attach, but also when the + user types "run" after having attached. */ +static void +m32r_create_inferior (char *execfile, char *args, char **env) +{ + CORE_ADDR entry_pt; + + if (args && *args) + error ("Cannot pass arguments to remote STDEBUG process"); + + if (execfile == 0 || exec_bfd == 0) + error ("No executable file specified"); + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_create_inferior(%s,%s)\n", execfile, + args); + + entry_pt = bfd_get_start_address (exec_bfd); + + /* The "process" (board) is already stopped awaiting our commands, and + the program is already downloaded. We just set its PC and go. */ + + clear_proceed_status (); + + /* Tell wait_for_inferior that we've started a new process. */ + init_wait_for_inferior (); + + /* Set up the "saved terminal modes" of the inferior + based on what modes we are starting it with. */ + target_terminal_init (); + + /* Install inferior's terminal modes. */ + target_terminal_inferior (); + + proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0); +} + +/* Open a connection to a remote debugger. + NAME is the filename used for communication. */ + +static void +m32r_open (char *args, int from_tty) +{ + struct hostent *host_ent; + struct sockaddr_in server_addr; + char *port_str, hostname[256]; + int port; + unsigned char buf[2]; + int i, n; + int yes = 1; + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_open(%d)\n", from_tty); + + target_preopen (from_tty); + + push_target (&m32r_ops); + + if (args == NULL) + sprintf (hostname, "localhost:%d", SDIPORT); + else + { + port_str = strchr (args, ':'); + if (port_str == NULL) + sprintf (hostname, "%s:%d", args, SDIPORT); + else + strcpy (hostname, args); + } + + sdi_desc = serial_open (hostname); + if (!sdi_desc) + error ("Connection refused\n"); + + if (get_ack () == -1) + error ("Cannot connect to SDI target\n"); + + buf[0] = SDI_OPEN; + if (send_data (buf, 1) == -1) + error ("Cannot connect to SDI target\n"); + + /* Get maximum number of ib breakpoints */ + buf[0] = SDI_GET_ATTR; + buf[1] = SDI_ATTR_BRK; + send_data (buf, 2); + recv_data (buf, 1); + max_ib_breakpoints = buf[0]; + if (remote_debug) + printf_filtered ("Max IB Breakpoints = %d\n", max_ib_breakpoints); + + /* Initialize breakpoints. */ + for (i = 0; i < MAX_BREAKPOINTS; i++) + bp_address[i] = 0xffffffff; + + /* Get maximum number of access breaks. */ + buf[0] = SDI_GET_ATTR; + buf[1] = SDI_ATTR_ABRK; + send_data (buf, 2); + recv_data (buf, 1); + max_access_breaks = buf[0]; + if (remote_debug) + printf_filtered ("Max Access Breaks = %d\n", max_access_breaks); + + /* Initialize access breask. */ + for (i = 0; i < MAX_ACCESS_BREAKS; i++) + ab_address[i] = 0x00000000; + + check_mmu_status (); + + /* Get the name of chip on target board. */ + buf[0] = SDI_GET_ATTR; + buf[1] = SDI_ATTR_NAME; + send_data (buf, 2); + recv_data (chip_name, 64); + + if (from_tty) + printf_filtered ("Remote %s connected to %s\n", target_shortname, + chip_name); +} + +/* Close out all files and local state before this target loses control. */ + +static void +m32r_close (int quitting) +{ + unsigned char buf[1]; + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_close(%d)\n", quitting); + + if (sdi_desc) + { + buf[0] = SDI_CLOSE; + send_data (buf, 1); + serial_close (sdi_desc); + sdi_desc = NULL; + } + + inferior_ptid = null_ptid; + return; +} + +/* Tell the remote machine to resume. */ + +static void +m32r_resume (ptid_t ptid, int step, enum target_signal sig) +{ + unsigned long pc_addr, bp_addr, ab_addr; + unsigned char buf[13]; + int i; + + if (remote_debug) + { + if (step) + fprintf_unfiltered (gdb_stdlog, "\nm32r_resume(step)\n"); + else + fprintf_unfiltered (gdb_stdlog, "\nm32r_resume(cont)\n"); + } + + check_mmu_status (); + + pc_addr = read_pc (); + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "pc <= 0x%lx\n", pc_addr); + + /* At pc address there is a parallel instruction with +2 offset, + so we have to make it a serial instruction or avoid it. */ + if (pc_addr == last_pc_addr) + { + /* Avoid a parallel nop. */ + if (last_pc_addr_data[0] == 0xf0 && last_pc_addr_data[1] == 0x00) + { + pc_addr += 2; + /* Now we can forget this instruction. */ + last_pc_addr = 0xffffffff; + } + /* Clear a parallel bit. */ + else + { + buf[0] = SDI_WRITE_MEMORY; + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + store_long_parameter (buf + 1, pc_addr); + else + store_long_parameter (buf + 1, pc_addr - 1); + store_long_parameter (buf + 5, 1); + buf[9] = last_pc_addr_data[0] & 0x7f; + send_data (buf, 10); + } + } + + /* Set PC. */ + buf[0] = SDI_WRITE_CPU_REG; + buf[1] = SDI_REG_BPC; + store_long_parameter (buf + 2, pc_addr); + send_data (buf, 6); + + /* step mode. */ + step_mode = step; + if (step) + { + /* Set PBP. */ + buf[0] = SDI_WRITE_CPU_REG; + buf[1] = SDI_REG_PBP; + store_long_parameter (buf + 2, pc_addr | 1); + send_data (buf, 6); + } + else + { + int ib_breakpoints; + + if (use_ib_breakpoints) + ib_breakpoints = max_ib_breakpoints; + else + ib_breakpoints = 0; + + /* Set ib breakpoints. */ + for (i = 0; i < ib_breakpoints; i++) + { + bp_addr = bp_address[i]; + if (bp_addr != 0xffffffff && bp_addr != pc_addr) + { + /* Set PBP. */ + buf[0] = SDI_WRITE_MEMORY; + store_long_parameter (buf + 1, 0xffff8000 + 4 * i); + store_long_parameter (buf + 5, 4); + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + buf[9] = ib_bp_entry_enable[0]; + buf[10] = ib_bp_entry_enable[1]; + buf[11] = ib_bp_entry_enable[2]; + buf[12] = ib_bp_entry_enable[3]; + } + else + { + buf[9] = ib_bp_entry_enable[3]; + buf[10] = ib_bp_entry_enable[2]; + buf[11] = ib_bp_entry_enable[1]; + buf[12] = ib_bp_entry_enable[0]; + } + send_data (buf, 13); + + buf[0] = SDI_WRITE_MEMORY; + store_long_parameter (buf + 1, 0xffff8080 + 4 * i); + store_long_parameter (buf + 5, 4); + store_unsigned_integer (buf + 9, 4, bp_addr); + send_data (buf, 13); + } + } + + /* Set dbt breakpoints. */ + for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++) + { + bp_addr = bp_address[i]; + if (bp_addr != 0xffffffff && bp_addr != pc_addr) + { + if (!mmu_on) + bp_addr &= 0x7fffffff; + + /* Write DBT instruction. */ + buf[0] = SDI_WRITE_MEMORY; + if ((bp_addr & 2) == 0 && bp_addr != (pc_addr & 0xfffffffc)) + { + store_long_parameter (buf + 1, bp_addr); + store_long_parameter (buf + 5, 4); + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + buf[9] = dbt_bp_entry[0]; + buf[10] = dbt_bp_entry[1]; + buf[11] = dbt_bp_entry[2]; + buf[12] = dbt_bp_entry[3]; + } + else + { + buf[9] = dbt_bp_entry[3]; + buf[10] = dbt_bp_entry[2]; + buf[11] = dbt_bp_entry[1]; + buf[12] = dbt_bp_entry[0]; + } + send_data (buf, 13); + } + else + { + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + store_long_parameter (buf + 1, bp_addr); + else if ((bp_addr & 2) == 0) + store_long_parameter (buf + 1, bp_addr + 2); + else + store_long_parameter (buf + 1, bp_addr - 2); + store_long_parameter (buf + 5, 2); + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + buf[9] = dbt_bp_entry[0]; + buf[10] = dbt_bp_entry[1]; + } + else + { + buf[9] = dbt_bp_entry[1]; + buf[10] = dbt_bp_entry[0]; + } + send_data (buf, 11); + } + } + } + + /* Set access breaks. */ + for (i = 0; i < max_access_breaks; i++) + { + ab_addr = ab_address[i]; + if (ab_addr != 0x00000000) + { + /* DBC register */ + buf[0] = SDI_WRITE_MEMORY; + store_long_parameter (buf + 1, 0xffff8100 + 4 * i); + store_long_parameter (buf + 5, 4); + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + buf[9] = 0x00; + buf[10] = 0x00; + buf[11] = 0x00; + switch (ab_type[i]) + { + case 0: /* write watch */ + buf[12] = 0x86; + break; + case 1: /* read watch */ + buf[12] = 0x46; + break; + case 2: /* access watch */ + buf[12] = 0x06; + break; + } + } + else + { + switch (ab_type[i]) + { + case 0: /* write watch */ + buf[9] = 0x86; + break; + case 1: /* read watch */ + buf[9] = 0x46; + break; + case 2: /* access watch */ + buf[9] = 0x06; + break; + } + buf[10] = 0x00; + buf[11] = 0x00; + buf[12] = 0x00; + } + send_data (buf, 13); + + /* DBAH register */ + buf[0] = SDI_WRITE_MEMORY; + store_long_parameter (buf + 1, 0xffff8180 + 4 * i); + store_long_parameter (buf + 5, 4); + store_unsigned_integer (buf + 9, 4, ab_addr); + send_data (buf, 13); + + /* DBAL register */ + buf[0] = SDI_WRITE_MEMORY; + store_long_parameter (buf + 1, 0xffff8200 + 4 * i); + store_long_parameter (buf + 5, 4); + store_long_parameter (buf + 9, 0xffffffff); + send_data (buf, 13); + + /* DBD register */ + buf[0] = SDI_WRITE_MEMORY; + store_long_parameter (buf + 1, 0xffff8280 + 4 * i); + store_long_parameter (buf + 5, 4); + store_long_parameter (buf + 9, 0x00000000); + send_data (buf, 13); + + /* DBDM register */ + buf[0] = SDI_WRITE_MEMORY; + store_long_parameter (buf + 1, 0xffff8300 + 4 * i); + store_long_parameter (buf + 5, 4); + store_long_parameter (buf + 9, 0x00000000); + send_data (buf, 13); + } + } + + /* Unset PBP. */ + buf[0] = SDI_WRITE_CPU_REG; + buf[1] = SDI_REG_PBP; + store_long_parameter (buf + 2, 0x00000000); + send_data (buf, 6); + } + + buf[0] = SDI_EXEC_CPU; + send_data (buf, 1); + + /* Without this, some commands which require an active target (such as kill) + won't work. This variable serves (at least) double duty as both the pid + of the target process (if it has such), and as a flag indicating that a + target is active. These functions should be split out into seperate + variables, especially since GDB will someday have a notion of debugging + several processes. */ + inferior_ptid = pid_to_ptid (32); + + return; +} + +/* Wait until the remote machine stops, then return, + storing status in STATUS just as `wait' would. */ + +static void +gdb_cntrl_c (int signo) +{ + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "interrupt\n"); + interrupted = 1; +} + +static ptid_t +m32r_wait (ptid_t ptid, struct target_waitstatus *status) +{ + static RETSIGTYPE (*prev_sigint) (); + unsigned long bp_addr, pc_addr; + long i; + unsigned char buf[13]; + unsigned long val; + int ret, c; + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_wait()\n"); + + status->kind = TARGET_WAITKIND_EXITED; + status->value.sig = 0; + + interrupted = 0; + prev_sigint = signal (SIGINT, gdb_cntrl_c); + + /* Wait for ready */ + buf[0] = SDI_WAIT_FOR_READY; + if (serial_write (sdi_desc, buf, 1) != 0) + error ("Remote connection closed"); + + while (1) + { + c = serial_readchar (sdi_desc, SDI_TIMEOUT); + if (c < 0) + error ("Remote connection closed"); + + if (c == '-') /* error */ + { + status->kind = TARGET_WAITKIND_STOPPED; + status->value.sig = TARGET_SIGNAL_HUP; + return inferior_ptid; + } + else if (c == '+') /* stopped */ + break; + + if (interrupted) + ret = serial_write (sdi_desc, "!", 1); /* packet to interrupt */ + else + ret = serial_write (sdi_desc, ".", 1); /* packet to wait */ + if (ret != 0) + error ("Remote connection closed"); + } + + status->kind = TARGET_WAITKIND_STOPPED; + if (interrupted) + status->value.sig = TARGET_SIGNAL_INT; + else + status->value.sig = TARGET_SIGNAL_TRAP; + + interrupted = 0; + signal (SIGINT, prev_sigint); + + check_mmu_status (); + + /* Recover parallel bit. */ + if (last_pc_addr != 0xffffffff) + { + buf[0] = SDI_WRITE_MEMORY; + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + store_long_parameter (buf + 1, last_pc_addr); + else + store_long_parameter (buf + 1, last_pc_addr - 1); + store_long_parameter (buf + 5, 1); + buf[9] = last_pc_addr_data[0]; + send_data (buf, 10); + last_pc_addr = 0xffffffff; + } + + /* Breakpoints are inserted only for "next" command */ + if (!step_mode) + { + int ib_breakpoints; + + if (use_ib_breakpoints) + ib_breakpoints = max_ib_breakpoints; + else + ib_breakpoints = 0; + + /* Set back pc by 2 if m32r is stopped with dbt. */ + buf[0] = SDI_READ_CPU_REG; + buf[1] = SDI_REG_BPC; + send_data (buf, 2); + recv_data (&val, 4); + pc_addr = ntohl (val) - 2; + for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++) + { + if (pc_addr == bp_address[i]) + { + buf[0] = SDI_WRITE_CPU_REG; + buf[1] = SDI_REG_BPC; + store_long_parameter (buf + 2, pc_addr); + send_data (buf, 6); + + /* If there is a parallel instruction with +2 offset at pc + address, we have to take care of it later. */ + if ((pc_addr & 0x2) != 0) + { + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + if ((bp_data[i][2] & 0x80) != 0) + { + last_pc_addr = pc_addr; + last_pc_addr_data[0] = bp_data[i][2]; + last_pc_addr_data[1] = bp_data[i][3]; + } + } + else + { + if ((bp_data[i][1] & 0x80) != 0) + { + last_pc_addr = pc_addr; + last_pc_addr_data[0] = bp_data[i][1]; + last_pc_addr_data[1] = bp_data[i][0]; + } + } + } + break; + } + } + + /* Remove ib breakpoints. */ + for (i = 0; i < ib_breakpoints; i++) + { + if (bp_address[i] != 0xffffffff) + { + buf[0] = SDI_WRITE_MEMORY; + store_long_parameter (buf + 1, 0xffff8000 + 4 * i); + store_long_parameter (buf + 5, 4); + buf[9] = ib_bp_entry_disable[0]; + buf[10] = ib_bp_entry_disable[1]; + buf[11] = ib_bp_entry_disable[2]; + buf[12] = ib_bp_entry_disable[3]; + send_data (buf, 13); + } + } + /* Remove dbt breakpoints. */ + for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++) + { + bp_addr = bp_address[i]; + if (bp_addr != 0xffffffff) + { + if (!mmu_on) + bp_addr &= 0x7fffffff; + buf[0] = SDI_WRITE_MEMORY; + store_long_parameter (buf + 1, bp_addr & 0xfffffffc); + store_long_parameter (buf + 5, 4); + buf[9] = bp_data[i][0]; + buf[10] = bp_data[i][1]; + buf[11] = bp_data[i][2]; + buf[12] = bp_data[i][3]; + send_data (buf, 13); + } + } + + /* Remove access breaks. */ + hit_watchpoint_addr = 0; + for (i = 0; i < max_access_breaks; i++) + { + if (ab_address[i] != 0x00000000) + { + buf[0] = SDI_READ_MEMORY; + store_long_parameter (buf + 1, 0xffff8100 + 4 * i); + store_long_parameter (buf + 5, 4); + serial_write (sdi_desc, buf, 9); + c = serial_readchar (sdi_desc, SDI_TIMEOUT); + if (c != '-' && recv_data (buf, 4) != -1) + { + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + if ((buf[3] & 0x1) == 0x1) + hit_watchpoint_addr = ab_address[i]; + } + else + { + if ((buf[0] & 0x1) == 0x1) + hit_watchpoint_addr = ab_address[i]; + } + } + + buf[0] = SDI_WRITE_MEMORY; + store_long_parameter (buf + 1, 0xffff8100 + 4 * i); + store_long_parameter (buf + 5, 4); + store_long_parameter (buf + 9, 0x00000000); + send_data (buf, 13); + } + } + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "pc => 0x%lx\n", pc_addr); + } + else + last_pc_addr = 0xffffffff; + + return inferior_ptid; +} + +/* Terminate the open connection to the remote debugger. + Use this when you want to detach and do something else + with your gdb. */ +static void +m32r_detach (char *args, int from_tty) +{ + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_detach(%d)\n", from_tty); + + m32r_resume (inferior_ptid, 0, 0); + + /* calls m32r_close to do the real work */ + pop_target (); + if (from_tty) + fprintf_unfiltered (gdb_stdlog, "Ending remote %s debugging\n", + target_shortname); +} + +/* Return the id of register number REGNO. */ + +static int +get_reg_id (int regno) +{ + switch (regno) + { + case 20: + return SDI_REG_BBPC; + case 21: + return SDI_REG_BPC; + case 22: + return SDI_REG_ACCL; + case 23: + return SDI_REG_ACCH; + case 24: + return SDI_REG_EVB; + } + + return regno; +} + +/* Read the remote registers into the block REGS. */ + +static void m32r_fetch_register (int); + +static void +m32r_fetch_registers (void) +{ + int regno; + + for (regno = 0; regno < NUM_REGS; regno++) + m32r_fetch_register (regno); +} + +/* Fetch register REGNO, or all registers if REGNO is -1. + Returns errno value. */ +static void +m32r_fetch_register (int regno) +{ + unsigned long val, val2, regid; + unsigned char buf[2]; + + if (regno == -1) + m32r_fetch_registers (); + else + { + char buffer[MAX_REGISTER_SIZE]; + + regid = get_reg_id (regno); + buf[0] = SDI_READ_CPU_REG; + buf[1] = regid; + send_data (buf, 2); + recv_data (&val, 4); + val = ntohl (val); + + if (regid == SDI_REG_PSW) + { + buf[0] = SDI_READ_CPU_REG; + buf[1] = SDI_REG_BBPSW; + send_data (buf, 2); + recv_data (&val2, 4); + val2 = ntohl (val2); + val = ((0x00c1 & val2) << 8) | ((0xc100 & val) >> 8); + } + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_fetch_register(%d,0x%08lx)\n", + regno, val); + + /* We got the number the register holds, but gdb expects to see a + value in the target byte ordering. */ + store_unsigned_integer (buffer, 4, val); + supply_register (regno, buffer); + } + return; +} + +/* Store the remote registers from the contents of the block REGS. */ + +static void m32r_store_register (int); + +static void +m32r_store_registers (void) +{ + int regno; + + for (regno = 0; regno < NUM_REGS; regno++) + m32r_store_register (regno); + + registers_changed (); +} + +/* Store register REGNO, or all if REGNO == 0. + Return errno value. */ +static void +m32r_store_register (int regno) +{ + int regid; + ULONGEST regval, tmp; + unsigned char buf[6]; + + if (regno == -1) + m32r_store_registers (); + else + { + regcache_cooked_read_unsigned (current_regcache, regno, ®val); + regid = get_reg_id (regno); + + if (regid == SDI_REG_PSW) + { + unsigned long psw, bbpsw; + + buf[0] = SDI_READ_CPU_REG; + buf[1] = SDI_REG_PSW; + send_data (buf, 2); + recv_data (&psw, 4); + psw = ntohl (psw); + + buf[0] = SDI_READ_CPU_REG; + buf[1] = SDI_REG_BBPSW; + send_data (buf, 2); + recv_data (&bbpsw, 4); + bbpsw = ntohl (bbpsw); + + tmp = (0x00c1 & psw) | ((0x00c1 & regval) << 8); + buf[0] = SDI_WRITE_CPU_REG; + buf[1] = SDI_REG_PSW; + store_long_parameter (buf + 2, tmp); + send_data (buf, 6); + + tmp = (0x0030 & bbpsw) | ((0xc100 & regval) >> 8); + buf[0] = SDI_WRITE_CPU_REG; + buf[1] = SDI_REG_BBPSW; + store_long_parameter (buf + 2, tmp); + send_data (buf, 6); + } + else + { + buf[0] = SDI_WRITE_CPU_REG; + buf[1] = regid; + store_long_parameter (buf + 2, regval); + send_data (buf, 6); + } + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_store_register(%d,0x%08lu)\n", + regno, (unsigned long) regval); + } +} + +/* Get ready to modify the registers array. On machines which store + individual registers, this doesn't need to do anything. On machines + which store all the registers in one fell swoop, this makes sure + that registers contains all the registers from the program being + debugged. */ + +static void +m32r_prepare_to_store (void) +{ + /* Do nothing, since we can store individual regs */ + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_prepare_to_store()\n"); +} + +static void +m32r_files_info (struct target_ops *target) +{ + char *file = "nothing"; + + if (exec_bfd) + { + file = bfd_get_filename (exec_bfd); + printf_filtered ("\tAttached to %s running program %s\n", + chip_name, file); + } +} + +/* Read/Write memory. */ +static int +m32r_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, + int write, + struct mem_attrib *attrib, struct target_ops *target) +{ + unsigned long taddr; + unsigned char buf[0x2000]; + int ret, c; + + taddr = memaddr; + + if (!mmu_on) + { + if ((taddr & 0xa0000000) == 0x80000000) + taddr &= 0x7fffffff; + } + + if (remote_debug) + { + if (write) + fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory(%08lx,%d,write)\n", + memaddr, len); + else + fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory(%08lx,%d,read)\n", + memaddr, len); + } + + if (write) + { + buf[0] = SDI_WRITE_MEMORY; + store_long_parameter (buf + 1, taddr); + store_long_parameter (buf + 5, len); + if (len < 0x1000) + { + memcpy (buf + 9, myaddr, len); + ret = send_data (buf, len + 9) - 9; + } + else + { + if (serial_write (sdi_desc, buf, 9) != 0) + { + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, + "m32r_xfer_memory() failed\n"); + return 0; + } + ret = send_data (myaddr, len); + } + } + else + { + buf[0] = SDI_READ_MEMORY; + store_long_parameter (buf + 1, taddr); + store_long_parameter (buf + 5, len); + if (serial_write (sdi_desc, buf, 9) != 0) + { + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() failed\n"); + return 0; + } + + c = serial_readchar (sdi_desc, SDI_TIMEOUT); + if (c < 0 || c == '-') + { + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() failed\n"); + return 0; + } + + ret = recv_data (myaddr, len); + } + + if (ret <= 0) + { + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() fails\n"); + return 0; + } + + return ret; +} + +static void +m32r_kill (void) +{ + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_kill()\n"); + + inferior_ptid = null_ptid; + + return; +} + +/* Clean up when a program exits. + + The program actually lives on in the remote processor's RAM, and may be + run again without a download. Don't leave it full of breakpoint + instructions. */ + +static void +m32r_mourn_inferior (void) +{ + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_mourn_inferior()\n"); + + remove_breakpoints (); + generic_mourn_inferior (); +} + +static int +m32r_insert_breakpoint (CORE_ADDR addr, char *shadow) +{ + int ib_breakpoints; + unsigned char buf[13]; + int i, c; + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_insert_breakpoint(%08lx,\"%s\")\n", + addr, shadow); + + if (use_ib_breakpoints) + ib_breakpoints = max_ib_breakpoints; + else + ib_breakpoints = 0; + + for (i = 0; i < MAX_BREAKPOINTS; i++) + { + if (bp_address[i] == 0xffffffff) + { + bp_address[i] = addr; + if (i >= ib_breakpoints) + { + buf[0] = SDI_READ_MEMORY; + if (mmu_on) + store_long_parameter (buf + 1, addr & 0xfffffffc); + else + store_long_parameter (buf + 1, addr & 0x7ffffffc); + store_long_parameter (buf + 5, 4); + serial_write (sdi_desc, buf, 9); + c = serial_readchar (sdi_desc, SDI_TIMEOUT); + if (c != '-') + recv_data (bp_data[i], 4); + } + return 0; + } + } + + error ("Too many breakpoints"); + return 1; +} + +static int +m32r_remove_breakpoint (CORE_ADDR addr, char *shadow) +{ + int i; + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_remove_breakpoint(%08lx,\"%s\")\n", + addr, shadow); + + for (i = 0; i < MAX_BREAKPOINTS; i++) + { + if (bp_address[i] == addr) + { + bp_address[i] = 0xffffffff; + break; + } + } + + return 0; +} + +static void +m32r_load (char *args, int from_tty) +{ + struct cleanup *old_chain; + asection *section; + bfd *pbfd; + bfd_vma entry; + char *filename; + int quiet; + int nostart; + time_t start_time, end_time; /* Start and end times of download */ + unsigned long data_count; /* Number of bytes transferred to memory */ + int ret; + static RETSIGTYPE (*prev_sigint) (); + + /* for direct tcp connections, we can do a fast binary download */ + quiet = 0; + nostart = 0; + filename = NULL; + + while (*args != '\000') + { + char *arg; + + while (isspace (*args)) + args++; + + arg = args; + + while ((*args != '\000') && !isspace (*args)) + args++; + + if (*args != '\000') + *args++ = '\000'; + + if (*arg != '-') + filename = arg; + else if (strncmp (arg, "-quiet", strlen (arg)) == 0) + quiet = 1; + else if (strncmp (arg, "-nostart", strlen (arg)) == 0) + nostart = 1; + else + error ("Unknown option `%s'", arg); + } + + if (!filename) + filename = get_exec_file (1); + + pbfd = bfd_openr (filename, gnutarget); + if (pbfd == NULL) + { + perror_with_name (filename); + return; + } + old_chain = make_cleanup_bfd_close (pbfd); + + if (!bfd_check_format (pbfd, bfd_object)) + error ("\"%s\" is not an object file: %s", filename, + bfd_errmsg (bfd_get_error ())); + + start_time = time (NULL); + data_count = 0; + + interrupted = 0; + prev_sigint = signal (SIGINT, gdb_cntrl_c); + + for (section = pbfd->sections; section; section = section->next) + { + if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) + { + bfd_vma section_address; + bfd_size_type section_size; + file_ptr fptr; + int n; + + section_address = bfd_section_lma (pbfd, section); + section_size = bfd_get_section_size_before_reloc (section); + + if (!mmu_on) + { + if ((section_address & 0xa0000000) == 0x80000000) + section_address &= 0x7fffffff; + } + + if (!quiet) + printf_filtered ("[Loading section %s at 0x%lx (%d bytes)]\n", + bfd_get_section_name (pbfd, section), + section_address, (int) section_size); + + fptr = 0; + + data_count += section_size; + + n = 0; + while (section_size > 0) + { + char unsigned buf[0x1000 + 9]; + int count; + + count = min (section_size, 0x1000); + + buf[0] = SDI_WRITE_MEMORY; + store_long_parameter (buf + 1, section_address); + store_long_parameter (buf + 5, count); + + bfd_get_section_contents (pbfd, section, buf + 9, fptr, count); + if (send_data (buf, count + 9) <= 0) + error ("Error while downloading %s section.", + bfd_get_section_name (pbfd, section)); + + if (!quiet) + { + printf_unfiltered ("."); + if (n++ > 60) + { + printf_unfiltered ("\n"); + n = 0; + } + gdb_flush (gdb_stdout); + } + + section_address += count; + fptr += count; + section_size -= count; + + if (interrupted) + break; + } + + if (!quiet && !interrupted) + { + printf_unfiltered ("done.\n"); + gdb_flush (gdb_stdout); + } + } + + if (interrupted) + { + printf_unfiltered ("Interrupted.\n"); + break; + } + } + + interrupted = 0; + signal (SIGINT, prev_sigint); + + end_time = time (NULL); + + /* Make the PC point at the start address */ + if (exec_bfd) + write_pc (bfd_get_start_address (exec_bfd)); + + inferior_ptid = null_ptid; /* No process now */ + + /* This is necessary because many things were based on the PC at the time + that we attached to the monitor, which is no longer valid now that we + have loaded new code (and just changed the PC). Another way to do this + might be to call normal_stop, except that the stack may not be valid, + and things would get horribly confused... */ + + clear_symtab_users (); + + if (!nostart) + { + entry = bfd_get_start_address (pbfd); + + if (!quiet) + printf_unfiltered ("[Starting %s at 0x%lx]\n", filename, entry); + } + + print_transfer_performance (gdb_stdout, data_count, 0, + end_time - start_time); + + do_cleanups (old_chain); +} + +static void +m32r_stop (void) +{ + unsigned char buf[1]; + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_stop()\n"); + + buf[0] = SDI_STOP_CPU; + send_data (buf, 1); + + return; +} + + +/* Tell whether this target can support a hardware breakpoint. + This implements the TARGET_CAN_USE_HARDWARE_WATCHPOINT macro. */ + +int +m32r_can_use_hardware_watchpoint (void) +{ + return max_access_breaks; +} + +/* Set a data watchpoint. ADDR and LEN should be obvious. TYPE is 0 + for a write watchpoint, 1 for a read watchpoint, or 2 for a read/write + watchpoint. */ + +int +m32r_set_watchpoint (CORE_ADDR addr, int len, int type) +{ + int i; + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_set_watchpoint(%08lx,%d,%d)\n", + addr, len, type); + + for (i = 0; i < MAX_ACCESS_BREAKS; i++) + { + if (ab_address[i] == 0x00000000) + { + ab_address[i] = addr; + ab_size[i] = len; + ab_type[i] = type; + return 0; + } + } + + error ("Too many watchpoints"); + return 1; +} + +int +m32r_remove_watchpoint (CORE_ADDR addr, int len, int type) +{ + int i; + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_remove_watchpoint(%08lx,%d,%d)\n", + addr, len, type); + + for (i = 0; i < MAX_ACCESS_BREAKS; i++) + { + if (ab_address[i] == addr) + { + ab_address[i] = 0x00000000; + break; + } + } + + return 0; +} + +CORE_ADDR +m32r_stopped_data_address (void) +{ + return hit_watchpoint_addr; +} + +int +m32r_stopped_by_watchpoint (void) +{ + return (hit_watchpoint_addr != 0x00000000); +} + + +static void +sdireset_command (char *args, int from_tty) +{ + unsigned char buf[1]; + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_sdireset()\n"); + + buf[0] = SDI_OPEN; + send_data (buf, 1); + + inferior_ptid = null_ptid; +} + + +static void +sdistatus_command (char *args, int from_tty) +{ + unsigned char buf[4096]; + int i, c; + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "m32r_sdireset()\n"); + + if (!sdi_desc) + return; + + buf[0] = SDI_STATUS; + send_data (buf, 1); + for (i = 0; i < 4096; i++) + { + c = serial_readchar (sdi_desc, SDI_TIMEOUT); + if (c < 0) + return; + buf[i] = c; + if (c == 0) + break; + } + + printf_filtered ("%s", buf); +} + + +static void +debug_chaos_command (char *args, int from_tty) +{ + unsigned char buf[3]; + + buf[0] = SDI_SET_ATTR; + buf[1] = SDI_ATTR_CACHE; + buf[2] = SDI_CACHE_TYPE_CHAOS; + send_data (buf, 3); +} + + +static void +use_debug_dma_command (char *args, int from_tty) +{ + unsigned char buf[3]; + + buf[0] = SDI_SET_ATTR; + buf[1] = SDI_ATTR_MEM_ACCESS; + buf[2] = SDI_MEM_ACCESS_DEBUG_DMA; + send_data (buf, 3); +} + +static void +use_mon_code_command (char *args, int from_tty) +{ + unsigned char buf[3]; + + buf[0] = SDI_SET_ATTR; + buf[1] = SDI_ATTR_MEM_ACCESS; + buf[2] = SDI_MEM_ACCESS_MON_CODE; + send_data (buf, 3); +} + + +static void +use_ib_breakpoints_command (char *args, int from_tty) +{ + use_ib_breakpoints = 1; +} + +static void +use_dbt_breakpoints_command (char *args, int from_tty) +{ + use_ib_breakpoints = 0; +} + + +/* Define the target subroutine names */ + +struct target_ops m32r_ops; + +static void +init_m32r_ops (void) +{ + m32r_ops.to_shortname = "m32rsdi"; + m32r_ops.to_longname = "Remote M32R debugging over SDI interface"; + m32r_ops.to_doc = "Use an M32R board using SDI debugging protocol."; + m32r_ops.to_open = m32r_open; + m32r_ops.to_close = m32r_close; + m32r_ops.to_detach = m32r_detach; + m32r_ops.to_resume = m32r_resume; + m32r_ops.to_wait = m32r_wait; + m32r_ops.to_fetch_registers = m32r_fetch_register; + m32r_ops.to_store_registers = m32r_store_register; + m32r_ops.to_prepare_to_store = m32r_prepare_to_store; + m32r_ops.to_xfer_memory = m32r_xfer_memory; + m32r_ops.to_files_info = m32r_files_info; + m32r_ops.to_insert_breakpoint = m32r_insert_breakpoint; + m32r_ops.to_remove_breakpoint = m32r_remove_breakpoint; + m32r_ops.to_kill = m32r_kill; + m32r_ops.to_load = m32r_load; + m32r_ops.to_create_inferior = m32r_create_inferior; + m32r_ops.to_mourn_inferior = m32r_mourn_inferior; + m32r_ops.to_stop = m32r_stop; + m32r_ops.to_stratum = process_stratum; + m32r_ops.to_has_all_memory = 1; + m32r_ops.to_has_memory = 1; + m32r_ops.to_has_stack = 1; + m32r_ops.to_has_registers = 1; + m32r_ops.to_has_execution = 1; + m32r_ops.to_magic = OPS_MAGIC; +}; + + +extern initialize_file_ftype _initialize_remote_m32r; + +void +_initialize_remote_m32r (void) +{ + int i; + + init_m32r_ops (); + + /* Initialize breakpoints. */ + for (i = 0; i < MAX_BREAKPOINTS; i++) + bp_address[i] = 0xffffffff; + + /* Initialize access breaks. */ + for (i = 0; i < MAX_ACCESS_BREAKS; i++) + ab_address[i] = 0x00000000; + + add_target (&m32r_ops); + + add_com ("sdireset", class_obscure, sdireset_command, + "Reset SDI connection."); + + add_com ("sdistatus", class_obscure, sdistatus_command, + "Show status of SDI connection."); + + add_com ("debug_chaos", class_obscure, debug_chaos_command, + "Debug M32R/Chaos."); + + add_com ("use_debug_dma", class_obscure, use_debug_dma_command, + "Use debug DMA mem access."); + add_com ("use_mon_code", class_obscure, use_mon_code_command, + "Use mon code mem access."); + + add_com ("use_ib_break", class_obscure, use_ib_breakpoints_command, + "Set breakpoints by IB break."); + add_com ("use_dbt_break", class_obscure, use_dbt_breakpoints_command, + "Set breakpoints by dbt."); +} diff --git a/gdb/testsuite/gdb.arch/gdb1291.c b/gdb/testsuite/gdb.arch/gdb1291.c new file mode 100755 index 0000000..2178f70 --- /dev/null +++ b/gdb/testsuite/gdb.arch/gdb1291.c @@ -0,0 +1,44 @@ +/* Copyright 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@gnu.org
+
+ This file is part of the gdb testsuite. */
+
+void sub (void);
+
+main()
+{
+ sub();
+}
+
+asm(".text\n"
+ " .align 5\n"
+ "sub:\n"
+ " mov.l r14,@-r15\n"
+ " mov.w .STACK2,r3\n"
+ " sub r3,r15\n"
+ " mov r15,r14\n"
+ " mov.w .STACK2,r7\n"
+ " add r7,r14\n"
+ " mov r14,r15\n"
+ " mov.l @r15+,r14\n"
+ " rts\n"
+ " nop\n"
+ " .align 1\n"
+ ".STACK2:\n"
+ " .short 260\n");
diff --git a/gdb/testsuite/gdb.arch/gdb1291.exp b/gdb/testsuite/gdb.arch/gdb1291.exp new file mode 100644 index 0000000..2c1f4cc --- /dev/null +++ b/gdb/testsuite/gdb.arch/gdb1291.exp @@ -0,0 +1,62 @@ +# Copyright 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@gnu.org + +# This file is part of the gdb testsuite. + +# Tests for PR:1291. Ensure that backtrace works properly for stack +# frames greater than 256 bytes. + +if $tracelevel { + strace $tracelevel +} + +# Test SH backtraces with >256 byte frame stack. (PR:1291) + +set prms_id 0 +set bug_id 0 + +if ![istarget "sh-*-*"] then { + verbose "Skipping SH backtrace tests." + return +} + +set testfile "gdb1291" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# +# Run to `main' where we begin our tests. +# + +if ![runto_main] then { + gdb_suppress_tests +} + +gdb_test "b sub" "Breakpoint 2*" "set breakpoint" +gdb_test "c" "Breakpoint 2*" "get to sub" +gdb_test "bt" "#0\[ \t\]*$hex \\(\\) at sh-bt.*\r\n#1\[ \t\]*$hex in main.*" \ + "backtrace in gdb1291" diff --git a/gdb/testsuite/gdb.arch/gdb1431.c b/gdb/testsuite/gdb.arch/gdb1431.c new file mode 100755 index 0000000..0041042 --- /dev/null +++ b/gdb/testsuite/gdb.arch/gdb1431.c @@ -0,0 +1,63 @@ +/* Copyright 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@gnu.org
+
+ This file is part of the gdb testsuite. */
+
+void sub1 (void);
+void sub2 (void);
+
+main()
+{
+ sub1();
+ sub2();
+}
+
+asm(".text\n"
+ " .align 5\n"
+ "sub1:\n"
+ " mov.l r14,@-r15\n"
+ " add #-128,r15\n"
+ " add #-128,r15\n"
+ " mov r15,r14\n"
+ " mov.w .STACK1,r7\n"
+ " add r7,r14\n"
+ " mov r14,r15\n"
+ " mov.l @r15+,r14\n"
+ " rts\n"
+ " nop\n"
+ " .align 1\n"
+ ".STACK1:\n"
+ " .short 256\n");
+
+asm(".text\n"
+ " .align 5\n"
+ "sub2:\n"
+ " mov.l r14,@-r15\n"
+ " mov.w .STACK2,r3\n"
+ " sub r3,r15\n"
+ " mov r15,r14\n"
+ " mov.w .STACK2,r7\n"
+ " add r7,r14\n"
+ " mov r14,r15\n"
+ " mov.l @r15+,r14\n"
+ " rts\n"
+ " nop\n"
+ " .align 1\n"
+ ".STACK2:\n"
+ " .short 260\n");
diff --git a/gdb/testsuite/gdb.arch/gdb1431.exp b/gdb/testsuite/gdb.arch/gdb1431.exp new file mode 100644 index 0000000..15bff46 --- /dev/null +++ b/gdb/testsuite/gdb.arch/gdb1431.exp @@ -0,0 +1,66 @@ +# Copyright 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@gnu.org + +# This file is part of the gdb testsuite. + +# Tests for PR:1431. Catch gdb not continuing to second function properly. + +if $tracelevel { + strace $tracelevel +} + +# Observe that the until command doesn't go all the way to sub2. + +set prms_id 0 +set bug_id 0 + +if ![istarget "sh-*-*"] then { + verbose "Skipping SH backtrace tests." + return +} + +set testfile "gdb1431" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# +# Run to `main' where we begin our tests. +# + +if ![runto_main] then { + gdb_suppress_tests +} + +gdb_test "u sub1" "sub1*" "get to sub1" +gdb_test "bt" "#0\[ \t\]*$hex \\(\\) at sh-bt.*\r\n#1\[ \t\]*$hex in main.*" \ + "backtrace in gdb1291" + +kfail "gdb/1431" "u sub2" +# This is what we would expect to be able to do: +#gdb_test "u sub2" "sub2*" "get to sub2" +#gdb_test "bt" "#0\[ \t\]*$hex \\(\\) at sh-bt.*\r\n#1\[ \t\]*$hex in main.*" \ +# "backtrace in gdb1291" diff --git a/gdb/testsuite/gdb.base/gdb1056.exp b/gdb/testsuite/gdb.base/gdb1056.exp new file mode 100644 index 0000000..623f837 --- /dev/null +++ b/gdb/testsuite/gdb.base/gdb1056.exp @@ -0,0 +1,48 @@ +# Copyright 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Test for PR gdb/1056. +# 2003-10-18 Michael Chastain <mec@shout.net> + +if $tracelevel then { + strace $tracelevel +} + +# test SIGFPE (such as division by 0) inside gdb itself + +set prms_id 0 +set bug_id 0 + +gdb_start + +# When SIGFPE happens, the operating system may restart the +# offending instruction after the signal handler returns, +# rather than proceeding to the next instruction. This happens +# on i686-pc-linux-gnu with a linux kernel. If gdb has a naive +# signal handler that just returns, then it will restart the +# broken instruction and gdb gets an endless stream of SIGFPE's +# and makes no progress. +# +# On a broken gdb this test will just time out. + +gdb_test_multiple "print 1/0" "" { + -re ".*$gdb_prompt $" { + pass "print 1/0" + } + timeout { + kfail "gdb/1056" "print 1/0" + } +} diff --git a/gdb/testsuite/gdb.cp/gdb1355.cc b/gdb/testsuite/gdb.cp/gdb1355.cc new file mode 100644 index 0000000..a53ca20 --- /dev/null +++ b/gdb/testsuite/gdb.cp/gdb1355.cc @@ -0,0 +1,35 @@ +struct mystruct +{ + int m_int; + char m_char; + long int m_long_int; + unsigned int m_unsigned_int; + long unsigned int m_long_unsigned_int; + // long long int m_long_long_int; + // long long unsigned int m_long_long_unsigned_int; + short int m_short_int; + short unsigned int m_short_unsigned_int; + unsigned char m_unsigned_char; + float m_float; + double m_double; + long double m_long_double; + // complex int m_complex_int; + // complex float m_complex_float; + // complex long double m_complex_long_double; + // wchar_t m_wchar_t; + bool m_bool; +}; + +struct mystruct s1 = +{ + 117, 'a', 118, 119, 120, + // 121, 122, + 123, 124, 'b', 125.0, 126.0, 127.0, + // complex int, complex float, complex long double, wchar_t, + true +}; + +int main () +{ + return 0; +} diff --git a/gdb/testsuite/gdb.cp/gdb1355.exp b/gdb/testsuite/gdb.cp/gdb1355.exp new file mode 100644 index 0000000..11f16d5 --- /dev/null +++ b/gdb/testsuite/gdb.cp/gdb1355.exp @@ -0,0 +1,119 @@ +# Copyright 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Tests for PR gdb/1355, which is a reference to PR gcc/12066. +# 2003-08-26 Michael Chastain <mec@shout.net> + +# This file is part of the gdb testsuite. + +set ws "\[\r\n\t \]*" +set nl "\[\r\n\]+" + +if $tracelevel then { + strace $tracelevel + } + +if { [skip_cplus_tests] } { continue } + +# +# test running programs +# +set prms_id 0 +set bug_id 0 + +set testfile "gdb1355" +set srcfile ${testfile}.cc +set binfile ${objdir}/${subdir}/${testfile} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +if [get_compiler_info ${binfile} "c++"] { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto_main] then { + perror "couldn't run to main" + continue +} + +# See http://sources.redhat.com/gdb/bugs/1355 +# See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12066 +# +# g++ -gstabs+ does not emit stabs for fundamental types. +# They get emitted later inside other types, so they have no names +# and gdb cannot handle them. + +set s_head "${ws}(struct|class) mystruct \{(${ws}public:|)" +set s_tail ".*" + +set f_i "${ws}int m_int;" +set f_c "${ws}char m_char;" +set f_li "${ws}long int m_long_int;" +set f_ui "${ws}unsigned int m_unsigned_int;" +set f_lui "${ws}long unsigned int m_long_unsigned_int;" +set f_si "${ws}short int m_short_int;" +set f_sui "${ws}short unsigned int m_short_unsigned_int;" +set f_uc "${ws}unsigned char m_unsigned_char;" +set f_f "${ws}float m_float;" +set f_d "${ws}double m_double;" +set f_ld "${ws}long double m_long_double;" +set f_b "${ws}bool m_bool;" + +set itc "<invalid type code ${decimal}>" +set bad_i "${ws}(${itc}|int) m_int;"; +set bad_c "${ws}(${itc}|char) m_char;" +set bad_li "${ws}(${itc}|long int) m_long_int;" +set bad_ui "${ws}(${itc}|unsigned int) m_unsigned_int;" +set bad_lui "${ws}(${itc}|long unsigned int) m_long_unsigned_int;" +set bad_si "${ws}(${itc}|short int) m_short_int;" +set bad_sui "${ws}(${itc}|short unsigned int) m_short_unsigned_int;" +set bad_uc "${ws}(${itc}|unsigned char) m_unsigned_char;" +set bad_f "${ws}(${itc}|float) m_float;" +set bad_d "${ws}(${itc}|double) m_double;" +set bad_ld "${ws}(${itc}|long double) m_long_double;" +set bad_b "${ws}(${itc}|bool) m_bool;" + +gdb_test_multiple "ptype s1" "ptype s1" { + -re "type = ${s_head}${f_i}${f_c}${f_li}${f_ui}${f_lui}${f_si}${f_sui}${f_uc}${f_f}${f_d}${f_ld}${f_b}${s_tail}\}$nl$gdb_prompt $" { + pass "ptype s1" + } + -re "type = ${s_head}${bad_i}${bad_c}${bad_li}${bad_ui}${bad_lui}${bad_si}${bad_sui}${bad_uc}${bad_f}${bad_d}${bad_ld}${bad_b}${s_tail}\}$nl$gdb_prompt $" { + # This happened with gcc HEAD 2003-08-20 08:00:00 UTC, -gstabs+. + kfail "gdb/1355" "ptype s1" + } +} + +gdb_test_multiple "print s1" "print s1" { + -re "$decimal = \{m_int = 117, m_char = 97 'a', m_long_int = 118, m_unsigned_int = 119, m_long_unsigned_int = 120, m_short_int = 123, m_short_unsigned_int = 124, m_unsigned_char = 98 'b', m_float = 125, m_double = 126, m_long_double = 127, m_bool = true\}$nl$gdb_prompt $" { + pass "print s1" + } + -re "$decimal = \{m_int = 117, m_char = 97 'a', m_long_int = 118, m_unsigned_int = 119, m_long_unsigned_int = 120, m_short_int = 123, m_short_unsigned_int = 124, m_unsigned_char = 98 'b', m_float = 125, m_double = 126, m_long_double = 127, m_bool = 117\}$nl$gdb_prompt $" { + # This pattern is very picky, but if more different output + # shows up, I can just add more arms. -- chastain 2003-08-26 + # + # This happened with gcc HEAD 2003-08-20 08:00:00 UTC, -gstabs+. + # Look at the value of m_bool. It looks like gdb latched onto + # random int type and then used the data at structure offset 0. + kfail "gdb/1355" "print s1" + } +} diff --git a/gdb/testsuite/gdb.threads/switch-threads.c b/gdb/testsuite/gdb.threads/switch-threads.c new file mode 100644 index 0000000..3e5a825 --- /dev/null +++ b/gdb/testsuite/gdb.threads/switch-threads.c @@ -0,0 +1,47 @@ +/* A minimal multi-threaded test case. + + Copyright 2003 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <pthread.h> + +void foo (void) +{ +} + +void *thread_func (void *arg) +{ + int x; + for (x = 0; x < 10; x++) + foo (); + return 0; +} + +int main() +{ + pthread_t thr; + void *ret; + int x; + + pthread_create (&thr, NULL, thread_func, NULL); + pthread_join (thr, &ret); + for (x = 0; x < 10; x++) + foo (); +} diff --git a/gdb/testsuite/gdb.threads/switch-threads.exp b/gdb/testsuite/gdb.threads/switch-threads.exp new file mode 100644 index 0000000..d5608cf --- /dev/null +++ b/gdb/testsuite/gdb.threads/switch-threads.exp @@ -0,0 +1,52 @@ +# Copyright (C) 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Daniel Jacobowitz <drow@mvista.com>. +# +# It tests that the correct thread is single-stepped. Prior to the +# introduction of vCont, we didn't pass enough information to remote +# multi-threaded stubs to reliably get this correct; gdbserver defaulted +# to the first thread. + +# TODO: we should also test explicitly changing threads with the "thread" +# command. + +if $tracelevel then { + strace $tracelevel +} + +set testfile "switch-threads" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +runto_main + +gdb_breakpoint thread_func +gdb_continue_to_breakpoint "continue to thread_func" +gdb_test "next" ".*foo \\(\\);" + diff --git a/include/gdb/sim-frv.h b/include/gdb/sim-frv.h new file mode 100644 index 0000000..0a1e021 --- /dev/null +++ b/include/gdb/sim-frv.h @@ -0,0 +1,53 @@ +/* This file defines the interface between the FR-V simulator and GDB. + + Copyright 2003 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#if !defined (SIM_FRV_H) +#define SIM_FRV_H + +#ifdef __cplusplus +extern "C" { // } +#endif + +enum sim_frv_regs +{ + SIM_FRV_GR0_REGNUM = 0, + SIM_FRV_GR63_REGNUM = 63, + SIM_FRV_FR0_REGNUM = 64, + SIM_FRV_FR63_REGNUM = 127, + SIM_FRV_PC_REGNUM = 128, + + /* An FR-V architecture may have up to 4096 special purpose registers + (SPRs). In order to determine a specific constant used to access + a particular SPR, one of the H_SPR_ prefixed offsets defined in + opcodes/frv-desc.h should be added to SIM_FRV_SPR0_REGNUM. So, + for example, the number that GDB uses to fetch the link register + from the simulator is (SIM_FRV_SPR0_REGNUM + H_SPR_LR). */ + SIM_FRV_SPR0_REGNUM = 129, + SIM_FRV_SPR4095_REGNUM = SIM_FRV_SPR0_REGNUM + 4095 +}; + +#ifdef __cplusplus +} +#endif + +#endif |