From 69e0f06d288aa35e8b47136e796a09a4ab94f20b Mon Sep 17 00:00:00 2001 From: Simon Schubert Date: Mon, 19 Oct 2009 13:21:34 +0200 Subject: [PATCH] gdb: add our changes --- contrib/gdb-7/bfd/config.bfd | 12 +- contrib/gdb-7/gdb/amd64-tdep.h | 5 + contrib/gdb-7/gdb/amd64dfly-nat.c | 189 ++++++++++++++++++++++++ contrib/gdb-7/gdb/amd64dfly-tdep.c | 222 +++++++++++++++++++++++++++++ contrib/gdb-7/gdb/charset.c | 205 +++++++++++++++++--------- contrib/gdb-7/gdb/configure.host | 2 + contrib/gdb-7/gdb/configure.tgt | 12 ++ contrib/gdb-7/gdb/defs.h | 1 + contrib/gdb-7/gdb/i386-tdep.h | 3 + contrib/gdb-7/gdb/i386bsd-nat.c | 2 + contrib/gdb-7/gdb/i386dfly-nat.c | 86 +++++++++++ contrib/gdb-7/gdb/i386dfly-tdep.c | 102 +++++++++++++ contrib/gdb-7/gdb/i386fbsd-tdep.c | 2 +- contrib/gdb-7/gdb/osabi.c | 9 ++ contrib/gdb-7/gdb/tui/tui-io.c | 3 - contrib/gdb-7/include/elf/common.h | 4 + contrib/gdb-7/include/libiberty.h | 2 +- 17 files changed, 789 insertions(+), 72 deletions(-) create mode 100644 contrib/gdb-7/gdb/amd64dfly-nat.c create mode 100644 contrib/gdb-7/gdb/amd64dfly-tdep.c create mode 100644 contrib/gdb-7/gdb/i386dfly-nat.c create mode 100644 contrib/gdb-7/gdb/i386dfly-tdep.c diff --git a/contrib/gdb-7/bfd/config.bfd b/contrib/gdb-7/bfd/config.bfd index e340251137..c46b628629 100644 --- a/contrib/gdb-7/bfd/config.bfd +++ b/contrib/gdb-7/bfd/config.bfd @@ -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" diff --git a/contrib/gdb-7/gdb/amd64-tdep.h b/contrib/gdb-7/gdb/amd64-tdep.h index 121d22569a..0a48c63298 100644 --- a/contrib/gdb-7/gdb/amd64-tdep.h +++ b/contrib/gdb-7/gdb/amd64-tdep.h @@ -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 index 0000000000..5d5d3d4f7d --- /dev/null +++ b/contrib/gdb-7/gdb/amd64dfly-nat.c @@ -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 . */ + +#include "defs.h" +#include "inferior.h" +#include "regcache.h" +#include "target.h" + +#include "gdb_assert.h" +#include +#include +#include +#include +#include +#include + +#include "fbsd-nat.h" +#include "amd64-tdep.h" +#include "amd64-nat.h" + + +/* 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 +}; + + +/* 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 . */ +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 */ +}; + + +/* 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 ."), + 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 ."), + 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 ."), + 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 index 0000000000..a9c91c0a3f --- /dev/null +++ b/contrib/gdb-7/gdb/amd64dfly-tdep.c @@ -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 . */ + +#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 + . */ + sp = frame_unwind_register_unsigned (this_frame, AMD64_RSP_REGNUM); + return sp + 16; +} + +/* 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 . */ +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 . */ +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); +} + + +/* 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); +} diff --git a/contrib/gdb-7/gdb/charset.c b/contrib/gdb-7/gdb/charset.c index a59d9c65d3..4889f091fe 100644 --- a/contrib/gdb-7/gdb/charset.c +++ b/contrib/gdb-7/gdb/charset.c @@ -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); } @@ -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. */ diff --git a/contrib/gdb-7/gdb/configure.host b/contrib/gdb-7/gdb/configure.host index 1d6218f442..ee17aa2b67 100644 --- a/contrib/gdb-7/gdb/configure.host +++ b/contrib/gdb-7/gdb/configure.host @@ -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 ;; diff --git a/contrib/gdb-7/gdb/configure.tgt b/contrib/gdb-7/gdb/configure.tgt index 24331c30f7..2d4cf5e6e3 100644 --- a/contrib/gdb-7/gdb/configure.tgt +++ b/contrib/gdb-7/gdb/configure.tgt @@ -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 ;; diff --git a/contrib/gdb-7/gdb/defs.h b/contrib/gdb-7/gdb/defs.h index 94674dc341..cab095491b 100644 --- a/contrib/gdb-7/gdb/defs.h +++ b/contrib/gdb-7/gdb/defs.h @@ -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, diff --git a/contrib/gdb-7/gdb/i386-tdep.h b/contrib/gdb-7/gdb/i386-tdep.h index b236532986..e64b3f7606 100644 --- a/contrib/gdb-7/gdb/i386-tdep.h +++ b/contrib/gdb-7/gdb/i386-tdep.h @@ -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[]; diff --git a/contrib/gdb-7/gdb/i386bsd-nat.c b/contrib/gdb-7/gdb/i386bsd-nat.c index 79bf25bd85..3741ac1253 100644 --- a/contrib/gdb-7/gdb/i386bsd-nat.c +++ b/contrib/gdb-7/gdb/i386bsd-nat.c @@ -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 index 0000000000..2f839563a4 --- /dev/null +++ b/contrib/gdb-7/gdb/i386dfly-nat.c @@ -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 . */ + +#include "defs.h" +#include "inferior.h" +#include "regcache.h" +#include "target.h" + +#include +#include +#include + +#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 index 0000000000..92134d1b98 --- /dev/null +++ b/contrib/gdb-7/gdb/i386dfly-tdep.c @@ -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 . */ + +#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); +} + + +/* 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); +} diff --git a/contrib/gdb-7/gdb/i386fbsd-tdep.c b/contrib/gdb-7/gdb/i386fbsd-tdep.c index 17d88a724d..57e18bc6be 100644 --- a/contrib/gdb-7/gdb/i386fbsd-tdep.c +++ b/contrib/gdb-7/gdb/i386fbsd-tdep.c @@ -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); diff --git a/contrib/gdb-7/gdb/osabi.c b/contrib/gdb-7/gdb/osabi.c index a8ecc8c482..bf9e2ca943 100644 --- a/contrib/gdb-7/gdb/osabi.c +++ b/contrib/gdb-7/gdb/osabi.c @@ -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; } diff --git a/contrib/gdb-7/gdb/tui/tui-io.c b/contrib/gdb-7/gdb/tui/tui-io.c index a597f372e0..2bcad318ba 100644 --- a/contrib/gdb-7/gdb/tui/tui-io.c +++ b/contrib/gdb-7/gdb/tui/tui-io.c @@ -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; diff --git a/contrib/gdb-7/include/elf/common.h b/contrib/gdb-7/include/elf/common.h index 37883958cb..9bcbc89813 100644 --- a/contrib/gdb-7/include/elf/common.h +++ b/contrib/gdb-7/include/elf/common.h @@ -573,6 +573,10 @@ #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. */ diff --git a/contrib/gdb-7/include/libiberty.h b/contrib/gdb-7/include/libiberty.h index a7716e4a41..b03ccf3d97 100644 --- a/contrib/gdb-7/include/libiberty.h +++ b/contrib/gdb-7/include/libiberty.h @@ -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 -- 2.41.0