gdb: add our changes
authorSimon Schubert <corecode@dragonflybsd.org>
Mon, 19 Oct 2009 11:21:34 +0000 (13:21 +0200)
committerSimon Schubert <corecode@dragonflybsd.org>
Tue, 20 Oct 2009 22:49:34 +0000 (00:49 +0200)
17 files changed:
contrib/gdb-7/bfd/config.bfd
contrib/gdb-7/gdb/amd64-tdep.h
contrib/gdb-7/gdb/amd64dfly-nat.c [new file with mode: 0644]
contrib/gdb-7/gdb/amd64dfly-tdep.c [new file with mode: 0644]
contrib/gdb-7/gdb/charset.c
contrib/gdb-7/gdb/configure.host
contrib/gdb-7/gdb/configure.tgt
contrib/gdb-7/gdb/defs.h
contrib/gdb-7/gdb/i386-tdep.h
contrib/gdb-7/gdb/i386bsd-nat.c
contrib/gdb-7/gdb/i386dfly-nat.c [new file with mode: 0644]
contrib/gdb-7/gdb/i386dfly-tdep.c [new file with mode: 0644]
contrib/gdb-7/gdb/i386fbsd-tdep.c
contrib/gdb-7/gdb/osabi.c
contrib/gdb-7/gdb/tui/tui-io.c
contrib/gdb-7/include/elf/common.h
contrib/gdb-7/include/libiberty.h

index e340251..c46b628 100644 (file)
@@ -560,7 +560,7 @@ case "${targ}" in
     targ_selvecs=i386bsd_vec
     targ_underscore=yes
     ;;
-  i[3-7]86-*-freebsd* | i[3-7]86-*-kfreebsd*-gnu | i[3-7]86-*-dragonfly*)
+  i[3-7]86-*-freebsd* | i[3-7]86-*-kfreebsd*-gnu)
     targ_defvec=bfd_elf32_i386_freebsd_vec
     targ_selvecs="bfd_elf32_i386_vec i386pei_vec i386coff_vec"
     targ64_selvecs="bfd_elf64_x86_64_freebsd_vec bfd_elf64_x86_64_vec x86_64pei_vec bfd_elf64_l1om_vec bfd_elf64_l1om_freebsd_vec"
@@ -589,6 +589,11 @@ case "${targ}" in
     targ_defvec=bfd_elf32_i386_vec
     targ_selvecs=i386netbsd_vec
     ;;
+  i[3-7]86-*-dragonfly*)
+    targ_defvec=bfd_elf32_i386_vec
+    targ_selvecs="bfd_elf32_i386_vec"
+    targ64_selvecs="bfd_elf64_x86_64_vec bfd_elf64_l1om_vec"
+    ;;
   i[3-7]86-*-netware*)
     targ_defvec=bfd_elf32_i386_vec
     targ_selvecs="nlm32_i386_vec i386coff_vec i386aout_vec"
@@ -630,6 +635,11 @@ case "${targ}" in
     targ_selvecs="bfd_elf32_i386_vec i386netbsd_vec i386coff_vec i386pei_vec x86_64pei_vec bfd_elf64_l1om_vec"
     want64=true
     ;;
+  x86_64-*-dragonfly*)
+    targ_defvec=bfd_elf64_x86_64_vec
+    targ_selvecs="bfd_elf32_i386_vec bfd_elf64_x86_64_vec bfd_elf64_l1om_vec"
+    want64=true
+    ;;
   x86_64-*-linux-*)
     targ_defvec=bfd_elf64_x86_64_vec
     targ_selvecs="bfd_elf32_i386_vec i386linux_vec i386pei_vec x86_64pei_vec bfd_elf64_l1om_vec"
index 121d225..0a48c63 100644 (file)
@@ -111,4 +111,9 @@ extern CORE_ADDR amd64fbsd_sigtramp_start_addr;
 extern CORE_ADDR amd64fbsd_sigtramp_end_addr;
 extern int amd64fbsd_sc_reg_offset[];
 
+/* Variables exported from amd64dfly-tdep.c.  */
+extern CORE_ADDR amd64dfly_sigtramp_start_addr;
+extern CORE_ADDR amd64dfly_sigtramp_end_addr;
+extern int amd64dfly_sc_reg_offset[];
+
 #endif /* amd64-tdep.h */
diff --git a/contrib/gdb-7/gdb/amd64dfly-nat.c b/contrib/gdb-7/gdb/amd64dfly-nat.c
new file mode 100644 (file)
index 0000000..5d5d3d4
--- /dev/null
@@ -0,0 +1,189 @@
+/* Native-dependent code for DragonFly/amd64.
+
+   Copyright (C) 2003, 2004, 2007, 2008, 2009 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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+
+#include "gdb_assert.h"
+#include <signal.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/sysctl.h>
+#include <machine/reg.h>
+
+#include "fbsd-nat.h"
+#include "amd64-tdep.h"
+#include "amd64-nat.h"
+\f
+
+/* Offset in `struct reg' where MEMBER is stored.  */
+#define REG_OFFSET(member) offsetof (struct reg, member)
+
+/* At amd64dfly64_r_reg_offset[REGNUM] you'll find the offset in
+   `struct reg' location where the GDB register REGNUM is stored.
+   Unsupported registers are marked with `-1'.  */
+static int amd64dfly64_r_reg_offset[] =
+{
+  REG_OFFSET (r_rax),
+  REG_OFFSET (r_rbx),
+  REG_OFFSET (r_rcx),
+  REG_OFFSET (r_rdx),
+  REG_OFFSET (r_rsi),
+  REG_OFFSET (r_rdi),
+  REG_OFFSET (r_rbp),
+  REG_OFFSET (r_rsp),
+  REG_OFFSET (r_r8),
+  REG_OFFSET (r_r9),
+  REG_OFFSET (r_r10),
+  REG_OFFSET (r_r11),
+  REG_OFFSET (r_r12),
+  REG_OFFSET (r_r13),
+  REG_OFFSET (r_r14),
+  REG_OFFSET (r_r15),
+  REG_OFFSET (r_rip),
+  REG_OFFSET (r_rflags),
+  REG_OFFSET (r_cs),
+  REG_OFFSET (r_ss),
+  -1,
+  -1,
+  -1,
+  -1
+};
+\f
+
+/* Mapping between the general-purpose registers in DragonFly/amd64
+   `struct reg' format and GDB's register cache layout for
+   DragonFly/i386.
+
+   Note that most DragonFly/amd64 registers are 64-bit, while the
+   DragonFly/i386 registers are all 32-bit, but since we're
+   little-endian we get away with that.  */
+
+/* From <machine/reg.h>.  */
+static int amd64dfly32_r_reg_offset[I386_NUM_GREGS] =
+{
+  14 * 8, 13 * 8,              /* %eax, %ecx */
+  12 * 8, 11 * 8,              /* %edx, %ebx */
+  20 * 8, 10 * 8,              /* %esp, %ebp */
+  9 * 8, 8 * 8,                        /* %esi, %edi */
+  17 * 8, 19 * 8,              /* %eip, %eflags */
+  18 * 8, 21 * 8,              /* %cs, %ss */
+  -1, -1, -1, -1               /* %ds, %es, %fs, %gs */
+};
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_amd64dfly_nat (void);
+
+void
+_initialize_amd64dfly_nat (void)
+{
+  struct target_ops *t;
+  int offset;
+
+  amd64_native_gregset32_reg_offset = amd64dfly32_r_reg_offset;
+  amd64_native_gregset64_reg_offset = amd64dfly64_r_reg_offset;
+
+  /* Add some extra features to the common *BSD/i386 target.  */
+  t = amd64bsd_target ();
+  t->to_pid_to_exec_file = fbsd_pid_to_exec_file;
+  t->to_find_memory_regions = fbsd_find_memory_regions;
+  t->to_make_corefile_notes = fbsd_make_corefile_notes;
+  add_target (t);
+
+  /* To support the recognition of signal handlers, i386bsd-tdep.c
+     hardcodes some constants.  Inclusion of this file means that we
+     are compiling a native debugger, which means that we can use the
+     system header files and sysctl(3) to get at the relevant
+     information.  */
+
+#define SC_REG_OFFSET amd64dfly_sc_reg_offset
+
+  /* We only check the program counter, stack pointer and frame
+     pointer since these members of `struct sigcontext' are essential
+     for providing backtraces.  */
+
+#define SC_RIP_OFFSET SC_REG_OFFSET[AMD64_RIP_REGNUM]
+#define SC_RSP_OFFSET SC_REG_OFFSET[AMD64_RSP_REGNUM]
+#define SC_RBP_OFFSET SC_REG_OFFSET[AMD64_RBP_REGNUM]
+
+  /* Override the default value for the offset of the program counter
+     in the sigcontext structure.  */
+  offset = offsetof (struct sigcontext, sc_rip);
+
+  if (SC_RIP_OFFSET != offset)
+    {
+      warning (_("\
+offsetof (struct sigcontext, sc_rip) yields %d instead of %d.\n\
+Please report this to <bug-gdb@gnu.org>."),
+              offset, SC_RIP_OFFSET);
+    }
+
+  SC_RIP_OFFSET = offset;
+
+  /* Likewise for the stack pointer.  */
+  offset = offsetof (struct sigcontext, sc_rsp);
+
+  if (SC_RSP_OFFSET != offset)
+    {
+      warning (_("\
+offsetof (struct sigcontext, sc_rsp) yields %d instead of %d.\n\
+Please report this to <bug-gdb@gnu.org>."),
+              offset, SC_RSP_OFFSET);
+    }
+
+  SC_RSP_OFFSET = offset;
+
+  /* And the frame pointer.  */
+  offset = offsetof (struct sigcontext, sc_rbp);
+
+  if (SC_RBP_OFFSET != offset)
+    {
+      warning (_("\
+offsetof (struct sigcontext, sc_rbp) yields %d instead of %d.\n\
+Please report this to <bug-gdb@gnu.org>."),
+              offset, SC_RBP_OFFSET);
+    }
+
+  SC_RBP_OFFSET = offset;
+
+  /* DragonFly provides a kern.ps_strings sysctl that we can use to
+     locate the sigtramp.  That way we can still recognize a sigtramp
+     if its location is changed in a new kernel.  Of course this is
+     still based on the assumption that the sigtramp is placed
+     directly under the location where the program arguments and
+     environment can be found.  */
+  {
+    int mib[2];
+    long ps_strings;
+    size_t len;
+
+    mib[0] = CTL_KERN;
+    mib[1] = KERN_PS_STRINGS;
+    len = sizeof (ps_strings);
+    if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0)
+      {
+       amd64dfly_sigtramp_start_addr = ps_strings - 32;
+       amd64dfly_sigtramp_end_addr = ps_strings;
+      }
+  }
+}
diff --git a/contrib/gdb-7/gdb/amd64dfly-tdep.c b/contrib/gdb-7/gdb/amd64dfly-tdep.c
new file mode 100644 (file)
index 0000000..a9c91c0
--- /dev/null
@@ -0,0 +1,222 @@
+/* Target-dependent code for DragonFly/amd64.
+
+   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "osabi.h"
+
+#include "gdb_assert.h"
+#include "gdb_string.h"
+
+#include "amd64-tdep.h"
+#include "bsd-uthread.h"
+#include "solib-svr4.h"
+
+/* Support for signal handlers.  */
+
+/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
+   address of the associated sigcontext structure.  */
+
+static CORE_ADDR
+amd64dfly_sigcontext_addr (struct frame_info *this_frame)
+{
+  CORE_ADDR sp;
+
+  /* The `struct sigcontext' (which really is an `ucontext_t' on
+     DragonFly/amd64) lives at a fixed offset in the signal frame.  See
+     <machine/sigframe.h>.  */
+  sp = frame_unwind_register_unsigned (this_frame, AMD64_RSP_REGNUM);
+  return sp + 16;
+}
+\f
+/* DragonFly 5.1-RELEASE or later.  */
+
+/* Mapping between the general-purpose registers in `struct reg'
+   format and GDB's register cache layout.
+
+   Note that some registers are 32-bit, but since we're little-endian
+   we get away with that.  */
+
+/* From <machine/reg.h>.  */
+static int amd64dfly_r_reg_offset[] =
+{
+  6 * 8,                       /* %rax */
+  7 * 8,                       /* %rbx */
+  3 * 8,                       /* %rcx */
+  2 * 8,                       /* %rdx */
+  1 * 8,                       /* %rsi */
+  0 * 8,                       /* %rdi */
+  8 * 8,                       /* %rbp */
+  23 * 8,                      /* %rsp */
+  4 * 8,                       /* %r8 ... */
+  5 * 8,
+  9 * 8,
+  10 * 8,
+  11 * 8,
+  12 * 8,
+  13 * 8,
+  14 * 8,                      /* ... %r15 */
+  20 * 8,                      /* %rip */
+  22 * 8,                      /* %eflags */
+  21 * 8,                      /* %cs */
+  24 * 8,                      /* %ss */
+  -1,                          /* %ds */
+  -1,                          /* %es */
+  -1,                          /* %fs */
+  -1                           /* %gs */
+};
+
+/* Location of the signal trampoline.  */
+CORE_ADDR amd64dfly_sigtramp_start_addr = 0x7fffffffffc0ULL;
+CORE_ADDR amd64dfly_sigtramp_end_addr = 0x7fffffffffe0ULL;
+
+/* From <machine/signal.h>.  */
+int amd64dfly_sc_reg_offset[] =
+{
+  24 + 6 * 8,                  /* %rax */
+  24 + 7 * 8,                  /* %rbx */
+  24 + 3 * 8,                  /* %rcx */
+  24 + 2 * 8,                  /* %rdx */
+  24 + 1 * 8,                  /* %rsi */
+  24 + 0 * 8,                  /* %rdi */
+  24 + 8 * 8,                  /* %rbp */
+  24 + 23 * 8,                 /* %rsp */
+  24 + 4 * 8,                  /* %r8 ... */
+  24 + 5 * 8,
+  24 + 9 * 8,
+  24 + 10 * 8,
+  24 + 11 * 8,
+  24 + 12 * 8,
+  24 + 13 * 8,
+  24 + 14 * 8,                 /* ... %r15 */
+  24 + 20 * 8,                 /* %rip */
+  24 + 22 * 8,                 /* %eflags */
+  24 + 21 * 8,                 /* %cs */
+  24 + 24 * 8,                 /* %ss */
+  -1,                          /* %ds */
+  -1,                          /* %es */
+  -1,                          /* %fs */
+  -1                           /* %gs */
+};
+
+/* From /usr/src/lib/libc/amd64/gen/_setjmp.S.  */
+static int amd64dfly_jmp_buf_reg_offset[] =
+{
+  -1,                          /* %rax */
+  1 * 8,                       /* %rbx */
+  -1,                          /* %rcx */
+  -1,                          /* %rdx */
+  -1,                          /* %rsi */
+  -1,                          /* %rdi */
+  3 * 8,                       /* %rbp */
+  2 * 8,                       /* %rsp */
+  -1,                          /* %r8 ... */
+  -1,
+  -1,
+  -1,                          /* ... %r11 */
+  4 * 8,                       /* %r12 ... */
+  5 * 8,
+  6 * 8,
+  7 * 8,                       /* ... %r15 */
+  0 * 8                                /* %rip */
+};
+
+static void
+amd64dfly_supply_uthread (struct regcache *regcache,
+                         int regnum, CORE_ADDR addr)
+{
+  gdb_byte buf[8];
+  int i;
+
+  gdb_assert (regnum >= -1);
+
+  for (i = 0; i < ARRAY_SIZE (amd64dfly_jmp_buf_reg_offset); i++)
+    {
+      if (amd64dfly_jmp_buf_reg_offset[i] != -1
+         && (regnum == -1 || regnum == i))
+       {
+         read_memory (addr + amd64dfly_jmp_buf_reg_offset[i], buf, 8);
+         regcache_raw_supply (regcache, i, buf);
+       }
+    }
+}
+
+static void
+amd64dfly_collect_uthread (const struct regcache *regcache,
+                          int regnum, CORE_ADDR addr)
+{
+  gdb_byte buf[8];
+  int i;
+
+  gdb_assert (regnum >= -1);
+
+  for (i = 0; i < ARRAY_SIZE (amd64dfly_jmp_buf_reg_offset); i++)
+    {
+      if (amd64dfly_jmp_buf_reg_offset[i] != -1
+         && (regnum == -1 || regnum == i))
+       {
+         regcache_raw_collect (regcache, i, buf);
+         write_memory (addr + amd64dfly_jmp_buf_reg_offset[i], buf, 8);
+       }
+    }
+}
+
+static void
+amd64dfly_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* DragonFly is BSD-based.  */
+  i386bsd_init_abi (info, gdbarch);
+
+  tdep->gregset_reg_offset = amd64dfly_r_reg_offset;
+  tdep->gregset_num_regs = ARRAY_SIZE (amd64dfly_r_reg_offset);
+  tdep->sizeof_gregset = 25 * 8;
+
+  amd64_init_abi (info, gdbarch);
+
+  tdep->sigtramp_start = amd64dfly_sigtramp_start_addr;
+  tdep->sigtramp_end = amd64dfly_sigtramp_end_addr;
+  tdep->sigcontext_addr = amd64dfly_sigcontext_addr;
+  tdep->sc_reg_offset = amd64dfly_sc_reg_offset;
+  tdep->sc_num_regs = ARRAY_SIZE (amd64dfly_sc_reg_offset);
+
+  /* DragonFly provides a user-level threads implementation.  */
+  bsd_uthread_set_supply_uthread (gdbarch, amd64dfly_supply_uthread);
+  bsd_uthread_set_collect_uthread (gdbarch, amd64dfly_collect_uthread);
+
+  /* DragonFly uses SVR4-style shared libraries.  */
+  set_solib_svr4_fetch_link_map_offsets
+    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_amd64dfly_tdep (void);
+
+void
+_initialize_amd64dfly_tdep (void)
+{
+  gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
+                         GDB_OSABI_DRAGONFLY, amd64dfly_init_abi);
+}
index a59d9c6..4889f09 100644 (file)
@@ -412,6 +412,38 @@ cleanup_iconv (void *p)
   iconv_close (*descp);
 }
 
+static size_t
+convert_wchar (gdb_wchar_t **pinp, size_t *pinleft, char **poutp, size_t *poutleft)
+{
+  char tmp[MB_CUR_MAX];
+  int r;
+
+  while (*pinleft >= sizeof(gdb_wchar_t))
+    {
+      r = wctomb(tmp, **pinp);
+
+      if (r == -1)
+       perror_with_name ("Internal error while converting character sets");
+
+      if (*poutleft < r)
+       {
+         errno = E2BIG;
+         return (size_t) -1;
+       }
+
+      memcpy(*poutp, tmp, r);
+      *poutp += r;
+      *poutleft -= r;
+      ++*pinp;
+      *pinleft -= sizeof(gdb_wchar_t);
+    }
+
+  if (*pinleft != 0)
+    return EINVAL;
+
+  return 0;
+}
+
 void
 convert_between_encodings (const char *from, const char *to,
                           const gdb_byte *bytes, unsigned int num_bytes,
@@ -423,6 +455,7 @@ convert_between_encodings (const char *from, const char *to,
   size_t inleft;
   char *inp;
   unsigned int space_request;
+  int use_wctomb = 0;
 
   /* Often, the host and target charsets will be the same.  */
   if (!strcmp (from, to))
@@ -431,10 +464,20 @@ convert_between_encodings (const char *from, const char *to,
       return;
     }
 
-  desc = iconv_open (to, from);
-  if (desc == (iconv_t) -1)
-    perror_with_name ("Converting character sets");
-  cleanups = make_cleanup (cleanup_iconv, &desc);
+  if (!strcmp (from, "wchar_t"))
+    {
+      if (strcmp (to, host_charset ()))
+       perror_with_name ("Converting character sets");
+      cleanups = NULL; /* silence gcc complaints */
+      use_wctomb = 1;
+    }
+  else
+    {
+      desc = iconv_open (to, from);
+      if (desc == (iconv_t) -1)
+       perror_with_name ("Converting character sets");
+      cleanups = make_cleanup (cleanup_iconv, &desc);
+    }
 
   inleft = num_bytes;
   inp = (char *) bytes;
@@ -453,7 +496,10 @@ convert_between_encodings (const char *from, const char *to,
       outp = obstack_base (output) + old_size;
       outleft = space_request;
 
-      r = iconv (desc, (ICONV_CONST char **) &inp, &inleft, &outp, &outleft);
+      if (use_wctomb)
+       r = convert_wchar((gdb_wchar_t **)(void *)&inp, &inleft, &outp, &outleft);
+      else
+       r = iconv (desc, (ICONV_CONST char **) &inp, &inleft, &outp, &outleft);
 
       /* Now make sure that the object on the obstack only includes
         bytes we have converted.  */
@@ -505,7 +551,8 @@ convert_between_encodings (const char *from, const char *to,
        }
     }
 
-  do_cleanups (cleanups);
+  if (!use_wctomb)
+    do_cleanups (cleanups);
 }
 
 \f
@@ -524,9 +571,13 @@ struct wchar_iterator
   /* The width of an input character.  */
   size_t width;
 
-  /* The output buffer and its size.  */
-  gdb_wchar_t *out;
-  size_t out_size;
+  /* The intermediate buffer */
+  char *inter;
+  size_t inter_size;
+  size_t inter_len;
+
+  /* The output byte.  */
+  gdb_wchar_t out;
 };
 
 /* Create a new iterator.  */
@@ -537,7 +588,7 @@ make_wchar_iterator (const gdb_byte *input, size_t bytes, const char *charset,
   struct wchar_iterator *result;
   iconv_t desc;
 
-  desc = iconv_open (INTERMEDIATE_ENCODING, charset);
+  desc = iconv_open (host_charset (), charset);
   if (desc == (iconv_t) -1)
     perror_with_name ("Converting character sets");
 
@@ -547,8 +598,9 @@ make_wchar_iterator (const gdb_byte *input, size_t bytes, const char *charset,
   result->bytes = bytes;
   result->width = width;
 
-  result->out = XNEW (gdb_wchar_t);
-  result->out_size = 1;
+  result->inter = XNEW (char);
+  result->inter_size = 1;
+  result->inter_len = 0;
 
   return result;
 }
@@ -559,7 +611,7 @@ do_cleanup_iterator (void *p)
   struct wchar_iterator *iter = p;
 
   iconv_close (iter->desc);
-  xfree (iter->out);
+  xfree (iter->inter);
   xfree (iter);
 }
 
@@ -577,76 +629,97 @@ wchar_iterate (struct wchar_iterator *iter,
               size_t *len)
 {
   size_t out_request;
+  char *orig_inptr = iter->input;
+  size_t orig_in = iter->bytes;
 
   /* Try to convert some characters.  At first we try to convert just
      a single character.  The reason for this is that iconv does not
      necessarily update its outgoing arguments when it encounters an
      invalid input sequence -- but we want to reliably report this to
      our caller so it can emit an escape sequence.  */
-  out_request = 1;
-  while (iter->bytes > 0)
+  while (iter->inter_len == 0 && iter->bytes > 0)
     {
-      char *outptr = (char *) &iter->out[0];
-      char *orig_inptr = iter->input;
-      size_t orig_in = iter->bytes;
-      size_t out_avail = out_request * sizeof (gdb_wchar_t);
-      size_t num;
-      gdb_wchar_t result;
-
-      size_t r = iconv (iter->desc,
-                       (ICONV_CONST char **) &iter->input, &iter->bytes,
-                       &outptr, &out_avail);
-      if (r == (size_t) -1)
+      out_request = 1;
+      while (iter->bytes > 0)
        {
-         switch (errno)
-           {
-           case EILSEQ:
-             /* Invalid input sequence.  Skip it, and let the caller
-                know about it.  */
-             *out_result = wchar_iterate_invalid;
-             *ptr = iter->input;
-             *len = iter->width;
-             iter->input += iter->width;
-             iter->bytes -= iter->width;
-             return 0;
+         char *outptr = (char *) &iter->inter[iter->inter_len];
+         size_t out_avail = out_request;
 
-           case E2BIG:
-             /* We ran out of space.  We still might have converted a
-                character; if so, return it.  Otherwise, grow the
-                buffer and try again.  */
-             if (out_avail < out_request * sizeof (gdb_wchar_t))
-               break;
-
-             ++out_request;
-             if (out_request > iter->out_size)
+         size_t r = iconv (iter->desc,
+                           (ICONV_CONST char **) &iter->input, &iter->bytes,
+                           &outptr, &out_avail);
+         if (r == (size_t) -1)
+           {
+             switch (errno)
                {
-                 iter->out_size = out_request;
-                 iter->out = xrealloc (iter->out,
-                                       out_request * sizeof (gdb_wchar_t));
+               case EILSEQ:
+                 /* Invalid input sequence.  Skip it, and let the caller
+                    know about it.  */
+                 *out_result = wchar_iterate_invalid;
+                 *ptr = iter->input;
+                 *len = iter->width;
+                 iter->input += iter->width;
+                 iter->bytes -= iter->width;
+                 return 0;
+
+               case E2BIG:
+                 /* We ran out of space.  We still might have converted a
+                    character; if so, return it.  Otherwise, grow the
+                    buffer and try again.  */
+                 if (out_avail < out_request)
+                   break;
+
+                 ++out_request;
+                 if (out_request > iter->inter_size)
+                   {
+                     iter->inter_size = out_request;
+                     iter->inter = xrealloc (iter->inter, out_request);
+                   }
+                 continue;
+
+               case EINVAL:
+                 /* Incomplete input sequence.  Let the caller know, and
+                    arrange for future calls to see EOF.  */
+                 *out_result = wchar_iterate_incomplete;
+                 *ptr = iter->input;
+                 *len = iter->bytes;
+                 iter->bytes = 0;
+                 return 0;
+
+               default:
+                 perror_with_name ("Internal error while converting character sets");
                }
-             continue;
-
-           case EINVAL:
-             /* Incomplete input sequence.  Let the caller know, and
-                arrange for future calls to see EOF.  */
-             *out_result = wchar_iterate_incomplete;
-             *ptr = iter->input;
-             *len = iter->bytes;
-             iter->bytes = 0;
-             return 0;
-
-           default:
-             perror_with_name ("Internal error while converting character sets");
            }
+
+         /* We converted something.  */
+         iter->inter_len += out_request - out_avail;
+         break;
        }
+    }
+
+  if (iter->inter_len > 0)
+    {
+      int r;
+
+      /* Now convert from our charset to wchar_t */
+      r = mbtowc(&iter->out, &iter->inter[0], iter->inter_len);
+
+      /* This must never happen: we just converted to a valid charset! */
+      if (r < 0)
+       perror_with_name ("Internal error while converting character sets");
+
+      /* NUL bytes are alright */
+      if (r == 0)
+         r = 1;
+
+      iter->inter_len -= r;
+      memmove(&iter->inter[0], &iter->inter[r], iter->inter_len);
 
-      /* We converted something.  */
-      num = out_request - out_avail / sizeof (gdb_wchar_t);
       *out_result = wchar_iterate_ok;
-      *out_chars = iter->out;
+      *out_chars = &iter->out;
       *ptr = orig_inptr;
       *len = orig_in - iter->bytes;
-      return num;
+      return 1;
     }
 
   /* Really done.  */
index 1d6218f..ee17aa2 100644 (file)
@@ -89,6 +89,7 @@ i[34567]86-*-freebsd* | i[34567]86-*-kfreebsd*-gnu)
 i[34567]86-*-netbsdelf* | i[34567]86-*-knetbsd*-gnu)
                        gdb_host=nbsdelf ;;
 i[34567]86-*-netbsd*)  gdb_host=nbsdaout ;;
+i[34567]86-*-dragonfly*) gdb_host=dfly ;;
 i[34567]86-*-go32*)    gdb_host=go32 ;;
 i[34567]86-*-mingw32*) gdb_host=mingw
                        gdb_host_obs=mingw-hdep.o
@@ -171,6 +172,7 @@ x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
 x86_64-*-netbsd* | x86_64-*-knetbsd*-gnu)
                        gdb_host=nbsd64 ;;
 x86_64-*-openbsd*)     gdb_host=obsd64 ;;
+x86_64-*-dragonfly*)   gdb_host=dfly64 ;;
 x86_64-*-mingw*)        gdb_host=mingw64
                        gdb_host_obs=mingw-hdep.o
                        ;;
index 24331c3..2d4cf5e 100644 (file)
@@ -181,6 +181,11 @@ i[34567]86-*-openbsd*)
        gdb_target_obs="i386-tdep.o i387-tdep.o i386bsd-tdep.o i386obsd-tdep.o \
                        bsd-uthread.o corelow.o solib.o solib-svr4.o"
        ;;
+i[34567]86-*-dragonfly*)
+       # Target: DragonFly/i386
+       gdb_target_obs="i386-tdep.o i387-tdep.o i386bsd-tdep.o i386fbsd-tdep.o \
+                       i386dfly-tdep.o bsd-uthread.o corelow.o solib.o solib-svr4.o"
+       ;;
 i[34567]86-*-nto*)
        # Target: Intel 386 running qnx6.
        gdb_target_obs="i386-tdep.o i387-tdep.o corelow.o solib.o solib-svr4.o \
@@ -578,6 +583,12 @@ x86_64-*-openbsd*)
                        i387-tdep.o i386bsd-tdep.o i386obsd-tdep.o \
                        bsd-uthread.o corelow.o solib.o solib-svr4.o"
        ;;
+x86_64-*-dragonfly*)
+       # Target: DragonFly/amd64
+       gdb_target_obs="amd64-tdep.o amd64dfly-tdep.o i386-tdep.o \
+                       i387-tdep.o i386bsd-tdep.o i386fbsd-tdep.o i386dfly-tdep.o \
+                       i386dfly-tdep.o bsd-uthread.o corelow.o solib.o solib-svr4.o"
+       ;;
 xtensa*-*-linux*)      gdb_target=linux
        # Target: GNU/Linux Xtensa
        gdb_target_obs="xtensa-tdep.o xtensa-config.o xtensa-linux-tdep.o \
@@ -599,6 +610,7 @@ case "${targ}" in
 *-*-nto*)      gdb_osabi=GDB_OSABI_QNXNTO ;;
 m68*-*-openbsd* | m88*-*-openbsd* | vax-*-openbsd*) ;;
 *-*-openbsd*)  gdb_osabi=GDB_OSABI_OPENBSD_ELF ;;
+*-*-dragonfly*)        gdb_osabi=GDB_OSABI_DRAGONFLY ;;
 *-*-solaris*)  gdb_osabi=GDB_OSABI_SOLARIS ;;
 *-*-*-gnu*)    ;; # prevent non-GNU kernels to match the Hurd rule below
 *-*-gnu*)      gdb_osabi=GDB_OSABI_HURD ;;
index 94674dc..cab0954 100644 (file)
@@ -950,6 +950,7 @@ enum gdb_osabi
   GDB_OSABI_NETBSD_AOUT,
   GDB_OSABI_NETBSD_ELF,
   GDB_OSABI_OPENBSD_ELF,
+  GDB_OSABI_DRAGONFLY,
   GDB_OSABI_WINCE,
   GDB_OSABI_GO32,
   GDB_OSABI_IRIX,
index b236532..e64b3f7 100644 (file)
@@ -271,6 +271,9 @@ extern CORE_ADDR i386fbsd_sigtramp_start_addr;
 extern CORE_ADDR i386fbsd_sigtramp_end_addr;
 extern CORE_ADDR i386obsd_sigtramp_start_addr;
 extern CORE_ADDR i386obsd_sigtramp_end_addr;
+extern CORE_ADDR i386dfly_sigtramp_start_addr;
+extern CORE_ADDR i386dfly_sigtramp_end_addr;
+extern int i386dfly_sc_reg_offset[];
 extern int i386fbsd4_sc_reg_offset[];
 extern int i386fbsd_sc_reg_offset[];
 extern int i386nbsd_sc_reg_offset[];
index 79bf25b..3741ac1 100644 (file)
@@ -350,6 +350,8 @@ _initialize_i386bsd_nat (void)
 #define SC_REG_OFFSET i386nbsd_sc_reg_offset
 #elif defined (OpenBSD)
 #define SC_REG_OFFSET i386obsd_sc_reg_offset
+#elif defined (DragonFly)
+#define SC_REG_OFFSET i386dfly_sc_reg_offset
 #endif
 
 #ifdef SC_REG_OFFSET
diff --git a/contrib/gdb-7/gdb/i386dfly-nat.c b/contrib/gdb-7/gdb/i386dfly-nat.c
new file mode 100644 (file)
index 0000000..2f83956
--- /dev/null
@@ -0,0 +1,86 @@
+/* Native-dependent code for DragonFly/i386.
+
+   Copyright (C) 2001, 2002, 2003, 2004, 2007, 2008, 2009
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/sysctl.h>
+
+#include "fbsd-nat.h"
+#include "i386-tdep.h"
+#include "i386-nat.h"
+#include "i386bsd-nat.h"
+
+/* Prevent warning from -Wmissing-prototypes.  */
+void _initialize_i386dfly_nat (void);
+
+void
+_initialize_i386dfly_nat (void)
+{
+  struct target_ops *t;
+
+  /* Add some extra features to the common *BSD/i386 target.  */
+  t = i386bsd_target ();
+
+#ifdef HAVE_PT_GETDBREGS
+
+  i386_use_watchpoints (t);
+
+  i386_dr_low.set_control = i386bsd_dr_set_control;
+  i386_dr_low.set_addr = i386bsd_dr_set_addr;
+  i386_dr_low.reset_addr = i386bsd_dr_reset_addr;
+  i386_dr_low.get_status = i386bsd_dr_get_status;
+  i386_set_debug_register_length (4);
+
+#endif /* HAVE_PT_GETDBREGS */
+
+
+  t->to_pid_to_exec_file = fbsd_pid_to_exec_file;
+  t->to_find_memory_regions = fbsd_find_memory_regions;
+  t->to_make_corefile_notes = fbsd_make_corefile_notes;
+  add_target (t);
+
+  /* DragonFly provides a kern.ps_strings sysctl that we can use to
+     locate the sigtramp.  That way we can still recognize a sigtramp
+     if its location is changed in a new kernel.  Of course this is
+     still based on the assumption that the sigtramp is placed
+     directly under the location where the program arguments and
+     environment can be found.  */
+#ifdef KERN_PS_STRINGS
+  {
+    int mib[2];
+    u_long ps_strings;
+    size_t len;
+
+    mib[0] = CTL_KERN;
+    mib[1] = KERN_PS_STRINGS;
+    len = sizeof (ps_strings);
+    if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0)
+      {
+       i386dfly_sigtramp_start_addr = ps_strings - 128;
+       i386dfly_sigtramp_end_addr = ps_strings;
+      }
+  }
+#endif
+}
diff --git a/contrib/gdb-7/gdb/i386dfly-tdep.c b/contrib/gdb-7/gdb/i386dfly-tdep.c
new file mode 100644 (file)
index 0000000..92134d1
--- /dev/null
@@ -0,0 +1,102 @@
+/* Target-dependent code for DragonFly/i386.
+
+   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "regcache.h"
+
+#include "gdb_assert.h"
+
+#include "i386-tdep.h"
+#include "i387-tdep.h"
+#include "bsd-uthread.h"
+#include "solib-svr4.h"
+
+static int i386dfly_r_reg_offset[] =
+{
+  44, /* %eax */
+  40, /* %ecx */
+  36, /* %edx */
+  32, /* %ebx */
+  72, /* %esp */
+  24, /* %ebp */
+  20, /* %esi */
+  16, /* %edi */
+  60, /* %eip */
+  68, /* %eflags */
+  64, /* %cs */
+  76, /* %ss */
+  12, /* %ds */
+  8, /* %es */
+  4, /* %fs */
+  0  /* %gs */
+};
+
+/* Sigtramp routine location.  */
+CORE_ADDR i386dfly_sigtramp_start_addr = 0xbfbfdf20;
+CORE_ADDR i386dfly_sigtramp_end_addr = 0xbfbfdff0;
+
+int i386dfly_sc_reg_offset[] =
+{
+  64, /* %eax */
+  60, /* %ecx */
+  56, /* %edx */
+  52, /* %ebx */
+  92, /* %esp */
+  44, /* %ebp */
+  40, /* %esi */
+  36, /* %edi */
+  80, /* %eip */
+  88, /* %eflags */
+  84, /* %cs */
+  96, /* %ss */
+  32, /* %ds */
+  28, /* %es */
+  24, /* %fs */
+  20  /* %gs */
+};
+
+static void
+i386dfly_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  i386fbsd4_init_abi(info, gdbarch);
+
+  tdep->gregset_reg_offset = i386dfly_r_reg_offset;
+  tdep->gregset_num_regs = ARRAY_SIZE (i386dfly_r_reg_offset);
+  tdep->sizeof_gregset = 80;
+
+  tdep->sc_reg_offset = i386dfly_sc_reg_offset;
+  tdep->sc_num_regs = ARRAY_SIZE (i386dfly_sc_reg_offset);
+}
+
+\f
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_i386dfly_tdep (void);
+
+void
+_initialize_i386dfly_tdep (void)
+{
+  gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_DRAGONFLY,
+                         i386dfly_init_abi);
+}
index 17d88a7..57e18bc 100644 (file)
@@ -202,7 +202,7 @@ int i386fbsd4_sc_reg_offset[] =
   20 + 0 * 4                   /* %gs */
 };
 
-static void
+void
 i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
index a8ecc8c..bf9e2ca 100644 (file)
@@ -61,6 +61,7 @@ static const char * const gdb_osabi_names[] =
   "NetBSD a.out",
   "NetBSD ELF",
   "OpenBSD ELF",
+  "DragonFly",
   "Windows CE",
   "DJGPP",
   "Irix",
@@ -474,6 +475,14 @@ generic_elf_osabi_sniff_abi_tag_sections: unknown OS number %d"),
          return;
        }
 
+      /* DragonFly.  */
+      if (check_note (abfd, sect, note, "DragonFly", 4, NT_DRAGONFLY_ABI_TAG))
+       {
+         /* There is no need to check the version yet.  */
+         *osabi = GDB_OSABI_DRAGONFLY;
+         return;
+       }
+
       return;
     }
       
index a597f37..2bcad31 100644 (file)
@@ -408,9 +408,6 @@ static void
 tui_rl_display_match_list (char **matches, int len, int max)
 {
   typedef int QSFUNC (const void *, const void *);
-  extern int _rl_qsort_string_compare (const void *, 
-                                      const void *);
-  extern int _rl_print_completions_horizontally;
   
   int count, limit, printed_len;
   int i, j, k, l;
index 3788395..9bcbc89 100644 (file)
 
 #define NT_FREEBSD_ABI_TAG     1
 
+/* Values for DragonFly .note.ABI-tag notes.  Note name is "DragonFly".  */
+
+#define NT_DRAGONFLY_ABI_TAG   1
+
 /* These three macros disassemble and assemble a symbol table st_info field,
    which contains the symbol binding and symbol type.  The STB_ and STT_
    defines identify the binding and type.  */
index a7716e4..b03ccf3 100644 (file)
@@ -102,7 +102,7 @@ extern int writeargv PARAMS ((char **, FILE *));
    to find the declaration so provide a fully prototyped one.  If it
    is 1, we found it so don't provide any declaration at all.  */
 #if !HAVE_DECL_BASENAME
-#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (__MINGW32__) || defined (HAVE_DECL_BASENAME)
+#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (__MINGW32__) || defined (HAVE_DECL_BASENAME)
 extern char *basename (const char *);
 #else
 /* Do not allow basename to be used if there is no prototype seen.  We