* [PATCH] New port: ia64-*-freebsd
@ 2005-07-05 19:52 Marcel Moolenaar
2005-07-06 17:24 ` Followup: " Marcel Moolenaar
2005-07-15 0:01 ` Daniel Jacobowitz
0 siblings, 2 replies; 12+ messages in thread
From: Marcel Moolenaar @ 2005-07-05 19:52 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1218 bytes --]
Gang,
It took a while, but the legal preconditions have recently been
met and I'm delighted to present you with the long awaited port
of GDB to FreeBSD/ia64.
Attached the ChangeLog and actual diffs against the Juli 4th
snapshot. One can also grab them for the time being from:
http://www.xcllnt.net/~marcel/gdb/
The URL also houses various testsuite results:
Results with an unmodified source tree (Juli 4th snapshot) are in
files that start with test-. Test results that include the changes
are in files prefixed with new-.
Test results of a configuration that uses libunwind are in files
of which the basename ends in -with. Test results of a configuration
that doesn't use libunwind are in files of which the basename ends
in -without.
There's a small regression on ia64-*-linux that I'm currently
analyzing and which may relate to process problems. Please let
me know if you see it too if you're able to test the patches.
There are some fixes that aren't exactly related to this port,
but which I ran into and kept. It's probably better to commit
those seperately, but I leave that up to the group.
Please review and preferably: commit :-)
Thanks,
--
Marcel Moolenaar USPA: A-39004 marcel@xcllnt.net
[-- Attachment #2: ChangeLog.txt --]
[-- Type: text/plain, Size: 2328 bytes --]
bfd/ChangeLog:
2005-07-05 Marcel Moolenaar <marcel@xcllnt.net>
* elfxx-ia64.c (elfNN_ia64_grok_prstatus): New function.
(elf_backend_grok_prstatus): define for ia64.
gdb/ChangeLog:
2005-07-05 Marcel Moolenaar <marcel@xcllnt.net>
* configure.host: Match ia64-*-freebsd*.
* corelow.c (core_xfer_partial): Fix TARGET_OBJECT_MEMORY case.
(core_xfer_partial): Add TARGET_OBJECT_DIRTY case.
* ia64-fbsd-nat.c: New file.
* ia64-fbsd-tdep.c: New file.
* ia64-fbsd-tdep.h: New file.
* ia64-linux-nat.c (ia64_linux_xfer_dirty): New function.
* ia64-tdep.c (ia64_read_reg): New function.
(ia64_write_reg): New function.
(ia64_pseudo_register_read): Replace use of read_memory with ia64_read_reg.
(examine_prologue): Likewise.
(ia64_frame_prev_register): Likewise.
(ia64_sigtramp_frame_prev_register): Likewise.
(ia64_pseudo_register_write): Replace use of write_memory and
read_memory with ia64_write_reg and ia64_read_reg (resp).
(ia64_frame_prev_register): Properly construct CFM from PFS.
(ia64_sigtramp_frame_init_saved_regs): Cache BSPSTORE and RSC.
(ia64_find_global_pointer): Use .got section first. Relocate
the value from PT_PLTGOT.
(ia64_push_dummy_call): Avoid masking or setting reserved bits.
(ia64_gdbarch_init): Save the osabi and use NULL for pointers.
* ia64-tdep.h (gdbarch_tdep): Add osabi.
* inf-ptrace.c (inf_ptrace_xfer_partial): Add TARGET_OBJECT_DIRTY
case.
* inftarg.c (child_xfer_partial): Likewise.
* remote.c (remote_protocol_qPart_dirty): New config.
(set_remote_protocol_qPart_dirty_packet_cmd): New function.
(show_remote_protocol_qPart_dirty_packet_cmd): Likewise.
(init_all_packet_configs): Update remote_protocol_qPart_dirty.
(remote_xfer_partial): Add TARGET_OBJECT_DIRTY case.
(show_remote_cmd): Call
show_remote_protocol_qPart_dirty_packet_cmd.
(_initialize_remote): Add new add_packet_config_cmd.
* target.h (enum target_object): Add TARGET_OBJECT_DIRTY.
* config/djgpp/fnchange.lst: Add ia64-fbsd-nat.c, ia64-fbsd-tdep.c
and ia64-fbsd-tdep.h.
* config/ia64/fbsd.mh: New file.
* config/ia64/fbsd.mt: New file.
* config/ia64/nm-fbsd.h: New file.
* config/ia64/tm-fbsd.h: New file.
* testsuite/gdb.asm/ia64.inc: Add necessary breaks.
* testsuite/gdb.asm/ia64.inc: Define gdbasm_declare and
gdbasm_end.
[-- Attachment #3: gdb6.diff --]
[-- Type: text/plain, Size: 47183 bytes --]
Index: bfd/elfxx-ia64.c
===================================================================
RCS file: /home/marcel/CVS/gdb6/bfd/elfxx-ia64.c,v
retrieving revision 1.1.1.7
retrieving revision 1.8
diff -u -r1.1.1.7 -r1.8
--- bfd/elfxx-ia64.c 5 Jul 2005 02:41:41 -0000 1.1.1.7
+++ bfd/elfxx-ia64.c 5 Jul 2005 02:46:39 -0000 1.8
@@ -616,6 +616,36 @@
= lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
}
\f
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+elfNN_ia64_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+
+ if (note->namesz == 8 && strcmp (note->namedata, "FreeBSD") == 0)
+ {
+ int pr_version, pr_gregsetsz;
+
+ pr_version = bfd_get_32 (abfd, note->descdata);
+ if (pr_version != 1)
+ return FALSE;
+
+ /* pr_cursig */
+ elf_tdata (abfd)->core_signal = bfd_get_32 (abfd, note->descdata + 36);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 40);
+
+ /* pr_reg */
+ pr_gregsetsz = bfd_get_32 (abfd, note->descdata + 16);
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg", pr_gregsetsz,
+ note->descpos + 48);
+ }
+
+ return FALSE;
+}
+
+\f
#define PLT_HEADER_SIZE (3 * 16)
#define PLT_MIN_ENTRY_SIZE (1 * 16)
#define PLT_FULL_ENTRY_SIZE (2 * 16)
@@ -5312,6 +5342,7 @@
#define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
#define elf_backend_rela_normal 1
#define elf_backend_special_sections elfNN_ia64_special_sections
+#define elf_backend_grok_prstatus elfNN_ia64_grok_prstatus
/* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
SHF_LINK_ORDER. But it doesn't set theh sh_link or sh_info fields.
Index: gdb/configure.host
===================================================================
RCS file: /home/marcel/CVS/gdb6/gdb/configure.host,v
retrieving revision 1.1.1.6
retrieving revision 1.7
diff -u -r1.1.1.6 -r1.7
--- gdb/configure.host 24 Jun 2005 20:31:34 -0000 1.1.1.6
+++ gdb/configure.host 24 Jun 2005 21:07:35 -0000 1.7
@@ -86,6 +86,7 @@
i[34567]86-*-isc*) gdb_host=i386v ;;
i[34567]86-*-cygwin*) gdb_host=cygwin ;;
+ia64-*-freebsd*) gdb_host=fbsd ;;
ia64-*-linux*) gdb_host=linux ;;
m68*-*-linux*) gdb_host=linux ;;
Index: gdb/corelow.c
===================================================================
RCS file: /home/marcel/CVS/gdb6/gdb/corelow.c,v
retrieving revision 1.1.1.6
retrieving revision 1.7
diff -u -r1.1.1.6 -r1.7
--- gdb/corelow.c 24 Jun 2005 20:31:34 -0000 1.1.1.6
+++ gdb/corelow.c 24 Jun 2005 21:11:39 -0000 1.7
@@ -542,9 +542,9 @@
case TARGET_OBJECT_MEMORY:
if (readbuf)
return (*ops->deprecated_xfer_memory) (offset, readbuf, len,
- 0/*write*/, NULL, ops);
+ 0/*read*/, NULL, ops);
if (writebuf)
- return (*ops->deprecated_xfer_memory) (offset, readbuf, len,
+ return (*ops->deprecated_xfer_memory) (offset, writebuf, len,
1/*write*/, NULL, ops);
return -1;
@@ -612,6 +612,19 @@
}
return -1;
+ case TARGET_OBJECT_DIRTY:
+ {
+ ULONGEST addr;
+ addr = *(ULONGEST*)annex + offset;
+ if (readbuf)
+ return (*ops->deprecated_xfer_memory) (addr, readbuf, len,
+ 0/*read*/, NULL, ops);
+ if (writebuf)
+ return (*ops->deprecated_xfer_memory) (addr, writebuf, len,
+ 1/*write*/, NULL, ops);
+ return -1;
+ }
+
default:
if (ops->beneath != NULL)
return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
Index: gdb/ia64-fbsd-nat.c
===================================================================
RCS file: gdb/ia64-fbsd-nat.c
diff -N gdb/ia64-fbsd-nat.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb/ia64-fbsd-nat.c 4 Jul 2005 19:47:55 -0000 1.8
@@ -0,0 +1,135 @@
+/* Functions specific to running gdb native on FreeBSD/ia64.
+
+ Copyright 2005 Free Software Foundation, Inc.
+
+ Contributed by Marcel Moolenaar (marcel@xcllnt.net).
+
+ 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 "inf-ptrace.h"
+#include "regcache.h"
+#include "fbsd-nat.h"
+#include "ia64-tdep.h"
+#include "ia64-fbsd-tdep.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#ifdef HAVE_SYS_PROCFS_H
+#include <sys/procfs.h>
+#endif
+
+#ifndef HAVE_GREGSET_T
+typedef struct reg gregset_t;
+#endif
+
+#ifndef HAVE_FPREGSET_T
+typedef struct fpreg fpregset_t;
+#endif
+
+#include "gregset.h"
+
+fpregset_t ia64_fbsd_fpregset;
+gregset_t ia64_fbsd_gregset;
+
+void ia64_fbsd_fetch_inferior_registers (int regno)
+{
+ int supplied = 0;
+
+ if (regno == -1 || GREG_SUPPLIES(regno))
+ {
+ if (ptrace (PT_GETREGS, PIDGET(inferior_ptid),
+ (PTRACE_TYPE_ARG3)&ia64_fbsd_gregset, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+ ia64_fbsd_supply_gregset (current_regcache, -1, &ia64_fbsd_gregset);
+ supplied = 1;
+ }
+
+ if (regno == -1 || FPREG_SUPPLIES(regno))
+ {
+ if (ptrace (PT_GETFPREGS, PIDGET(inferior_ptid),
+ (PTRACE_TYPE_ARG3)&ia64_fbsd_fpregset, 0) == -1)
+ perror_with_name ("Couldn't get FP registers");
+ ia64_fbsd_supply_fpregset (current_regcache, -1, &ia64_fbsd_fpregset);
+ supplied = 1;
+ }
+
+ if (!supplied)
+ set_register_cached(regno, -1);
+}
+
+void ia64_fbsd_store_inferior_registers (int regno)
+{
+
+ if (regno == -1 || GREG_SUPPLIES(regno))
+ {
+ ia64_fbsd_collect_gregset (current_regcache, -1, &ia64_fbsd_gregset);
+ if (ptrace (PT_SETREGS, PIDGET(inferior_ptid),
+ (PTRACE_TYPE_ARG3)&ia64_fbsd_gregset, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+ if (ia64_fbsd_gregset.r_special.ndirty != 0)
+ set_register_cached(IA64_BSPSTORE_REGNUM, 0);
+ }
+
+ if (regno == -1 || FPREG_SUPPLIES(regno))
+ {
+ ia64_fbsd_collect_fpregset (current_regcache, -1, &ia64_fbsd_fpregset);
+ if (ptrace (PT_SETFPREGS, PIDGET(inferior_ptid),
+ (PTRACE_TYPE_ARG3)&ia64_fbsd_fpregset, 0) == -1)
+ perror_with_name ("Couldn't get FP registers");
+ }
+}
+
+LONGEST ia64_fbsd_xfer_dirty (struct target_ops *ops, enum target_object obj,
+ const char *annex, void *rbuf, const void *wbuf,
+ ULONGEST ofs, LONGEST len)
+{
+ if (len != 8)
+ return (-1);
+ if (rbuf != NULL) {
+ if (ptrace (PT_GETKSTACK, PIDGET(inferior_ptid), (PTRACE_ARG3_TYPE)rbuf,
+ ofs >> 3) == -1) {
+ perror_with_name ("Couldn't read dirty register");
+ return (-1);
+ }
+ } else {
+ if (ptrace (PT_SETKSTACK, PIDGET(inferior_ptid), (PTRACE_ARG3_TYPE)wbuf,
+ ofs >> 3) == -1) {
+ perror_with_name ("Couldn't write dirty register");
+ return (-1);
+ }
+ }
+ return (len);
+}
+
+void
+_initialize_ia64_fbsd_nat (void)
+{
+ struct target_ops *t;
+
+ t = inf_ptrace_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;
+ t->to_fetch_registers = ia64_fbsd_fetch_inferior_registers;
+ t->to_store_registers = ia64_fbsd_store_inferior_registers;
+ add_target (t);
+}
Index: gdb/ia64-fbsd-tdep.c
===================================================================
RCS file: gdb/ia64-fbsd-tdep.c
diff -N gdb/ia64-fbsd-tdep.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb/ia64-fbsd-tdep.c 4 Jul 2005 19:47:55 -0000 1.14
@@ -0,0 +1,378 @@
+/* Target-dependent code for FreeBSD/ia64.
+
+ Copyright 2005 Free Software Foundation, Inc.
+
+ Contributed by Marcel Moolenaar (marcel@xcllnt.net).
+
+ 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_string.h"
+#include "regcache.h"
+#include "regset.h"
+#include "solib-svr4.h"
+#include "value.h"
+
+#include "ia64-tdep.h"
+#include "ia64-fbsd-tdep.h"
+
+static int reg_offset[462] = {
+ -1, 96, 248, 256, 152, 160, 168, 176, /* Regs 0-7. */
+ 264, 272, 280, 288, 0, 64, 296, 304, /* Regs 8-15. */
+ 312, 320, 328, 336, 344, 352, 360, 368, /* Regs 16-23. */
+ 376, 384, 392, 400, 408, 416, 424, 432, /* Regs 24-31. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 32-39. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 40-47. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 48-55. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 56-63. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 64-71. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 72-79. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 80-87. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 88-95. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 96-103. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 104-111. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 112-119. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 120-127. */
+ -1, -1, 0, 16, 32, 48, 320, 336, /* Regs 128-135. */
+ 352, 368, 384, 400, 416, 432, 448, 464, /* Regs 136-143. */
+ 64, 80, 96, 112, 128, 144, 160, 176, /* Regs 144-151. */
+ 192, 208, 224, 240, 256, 272, 288, 304, /* Regs 152-159. */
+ 480, 496, 512, 528, 544, 560, 576, 592, /* Regs 160-167. */
+ 608, 624, 640, 656, 672, 688, 704, 720, /* Regs 168-175. */
+ 736, 752, 768, 784, 800, 816, 832, 848, /* Regs 176-183. */
+ 864, 880, 896, 912, 928, 944, 960, 976, /* Regs 184-191. */
+ 992, 1008, 1024, 1040, 1056, 1072, 1088, 1104, /* Regs 192-199. */
+ 1120, 1136, 1152, 1168, 1184, 1200, 1216, 1232, /* Regs 200-207. */
+ 1248, 1264, 1280, 1296, 1312, 1328, 1344, 1360, /* Regs 208-215. */
+ 1376, 1392, 1408, 1424, 1440, 1456, 1472, 1488, /* Regs 216-223. */
+ 1504, 1520, 1536, 1552, 1568, 1584, 1600, 1616, /* Regs 224-231. */
+ 1632, 1648, 1664, 1680, 1696, 1712, 1728, 1744, /* Regs 232-239. */
+ 1760, 1776, 1792, 1808, 1824, 1840, 1856, 1872, /* Regs 240-247. */
+ 1888, 1904, 1920, 1936, 1952, 1968, 1984, 2000, /* Regs 248-255. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 256-263. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 264-271. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 272-279. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 280-287. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 288-295. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 296-303. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 304-311. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 312-319. */
+ 16, 184, 192, 200, 208, 216, 440, 448, /* Regs 320-327. */
+ -1, -1, 24, 120, 88, 112, -1, -1, /* Regs 328-335. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 336-343. */
+ -1, -1, -1, -1, -1, -1, 72, 104, /* Regs 344-351. */
+ 40, 48, -1, -1, -1, -1, -1, 464, /* Regs 352-359. */
+ 472, -1, -1, -1, -1, -1, 456, -1, /* Regs 360-367. */
+ -1, -1, 8, -1, -1, -1, 80, -1, /* Regs 368-375. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 376-383. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 384-391. */
+ -1, -1, -1, -1, -1, -1, 32, 224, /* Regs 392-399. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 400-407. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 408-415. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 416-423. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 424-431. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 432-439. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 440-447. */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 448-455. */
+ -1, -1, -1, -1, -1, -1
+};
+
+static void
+ia64_fbsd_regcache_collect (const struct regcache *regcache, int regno,
+ void *regs)
+{
+ int ofs;
+
+ if (regno < 0 || regno >= NUM_REGS)
+ return;
+
+ ofs = reg_offset[regno];
+ if (regno == IA64_BSP_REGNUM)
+ {
+ uint64_t bsp, bspstore;
+ regcache_raw_collect (regcache, regno, &bsp);
+ regcache_raw_collect (regcache, IA64_BSPSTORE_REGNUM, &bspstore);
+ *(uint64_t *)((char *)regs + ofs) = bsp - bspstore;
+ }
+ else
+ {
+ if (ofs >= 0)
+ regcache_raw_collect (regcache, regno, (char*)regs + ofs);
+ }
+}
+
+static void
+ia64_fbsd_regcache_supply (struct regcache *regcache, int regno,
+ const void *regs)
+{
+ int ofs;
+
+ if (regno < 0 || regno >= NUM_REGS)
+ return;
+
+ ofs = reg_offset[regno];
+ if (regno == IA64_BSP_REGNUM)
+ {
+ /* BSP is synthesized. It's not actually present in struct reg,
+ but can be derived from bspstore and ndirty. The offset of
+ IA64_BSP_REGNUM in the reg_offset array above is that of the
+ ndirty field in struct reg. */
+ uint64_t bsp;
+ bsp = *((uint64_t*)((char *)regs + ofs)); /* ndirty */
+ bsp += *((uint64_t*)((char *)regs + reg_offset[IA64_BSPSTORE_REGNUM]));
+ regcache_raw_supply (regcache, regno, &bsp);
+ }
+ else
+ {
+ if (ofs >= 0)
+ regcache_raw_supply (regcache, regno, (char *)regs + ofs);
+ }
+}
+
+void
+ia64_fbsd_collect_fpregset (const struct regcache *regcache, int regno,
+ void *regs)
+{
+ if (regno == -1)
+ {
+ int num_regs = NUM_REGS; /* NUM_REGS expands to a function call. */
+ for (regno = 0; regno < num_regs; regno++)
+ {
+ if (FPREG_SUPPLIES(regno))
+ ia64_fbsd_regcache_collect (regcache, regno, regs);
+ }
+ }
+ else
+ {
+ if (FPREG_SUPPLIES(regno))
+ ia64_fbsd_regcache_collect (regcache, regno, regs);
+ }
+}
+
+void
+ia64_fbsd_collect_gregset (const struct regcache *regcache, int regno,
+ void *regs)
+{
+ if (regno == -1)
+ {
+ int num_regs = NUM_REGS; /* NUM_REGS expands to a function call. */
+ for (regno = 0; regno < num_regs; regno++)
+ {
+ if (GREG_SUPPLIES(regno))
+ ia64_fbsd_regcache_collect (regcache, regno, regs);
+ }
+ }
+ else
+ {
+ if (GREG_SUPPLIES(regno))
+ ia64_fbsd_regcache_collect (regcache, regno, regs);
+ }
+}
+
+void
+ia64_fbsd_supply_fpregset (struct regcache *regcache, int regno,
+ const void *regs)
+{
+ if (regno == -1)
+ {
+ int num_regs = NUM_REGS; /* NUM_REGS expands to a function call. */
+ for (regno = 0; regno < num_regs; regno++)
+ {
+ if (FPREG_SUPPLIES(regno))
+ ia64_fbsd_regcache_supply (regcache, regno, regs);
+ }
+ }
+ else
+ {
+ if (FPREG_SUPPLIES(regno))
+ ia64_fbsd_regcache_supply (regcache, regno, regs);
+ }
+}
+
+void
+ia64_fbsd_supply_gregset (struct regcache *regcache, int regno,
+ const void *regs)
+{
+ if (regno == -1)
+ {
+ int num_regs = NUM_REGS; /* NUM_REGS expands to a function call. */
+ for (regno = 0; regno < num_regs; regno++)
+ {
+ if (GREG_SUPPLIES(regno))
+ ia64_fbsd_regcache_supply (regcache, regno, regs);
+ }
+ }
+ else
+ {
+ if (GREG_SUPPLIES(regno))
+ ia64_fbsd_regcache_supply (regcache, regno, regs);
+ }
+}
+
+int
+ia64_fbsd_in_sigtramp (CORE_ADDR pc, char *fnm)
+{
+ uint64_t gwpage = 5ULL << 61;
+ return (pc >= gwpage && pc < (gwpage + 8192)) ? 1 : 0;
+}
+
+static void
+ia64_fbsd_collect_fpregset_from_core (const struct regset *regset,
+ const struct regcache *regcache,
+ int regno, void *regs, size_t len)
+{
+ ia64_fbsd_collect_fpregset (regcache, regno, regs);
+}
+
+static void
+ia64_fbsd_collect_gregset_from_core (const struct regset *regset,
+ const struct regcache *regcache,
+ int regno, void *regs, size_t len)
+{
+ ia64_fbsd_collect_gregset (regcache, regno, regs);
+}
+
+static void
+ia64_fbsd_supply_fpregset_from_core (const struct regset *regset,
+ struct regcache *regcache, int regno,
+ const void *regs, size_t len)
+{
+ ia64_fbsd_supply_fpregset (regcache, regno, regs);
+}
+
+static void
+ia64_fbsd_supply_gregset_from_core (const struct regset *regset,
+ struct regcache *regcache, int regno,
+ const void *regs, size_t len)
+{
+ ia64_fbsd_supply_gregset (regcache, regno, regs);
+}
+
+static struct regset fpregset =
+ {
+ NULL,
+ ia64_fbsd_supply_fpregset_from_core,
+ ia64_fbsd_collect_fpregset_from_core
+ };
+
+static struct regset gregset =
+ {
+ NULL,
+ ia64_fbsd_supply_gregset_from_core,
+ ia64_fbsd_collect_gregset_from_core
+ };
+
+static const struct regset *
+ia64_fbsd_regset_from_core_section (struct gdbarch *gdbarch,
+ const char *sect_name, size_t sect_size)
+{
+ if (strcmp (sect_name, ".reg") == 0)
+ return (&gregset);
+ if (strcmp (sect_name, ".reg2") == 0)
+ return (&fpregset);
+ return (NULL);
+}
+
+static CORE_ADDR
+ia64_fbsd_sigcontext_register_address (CORE_ADDR fp, int regno)
+{
+ char buf[8];
+ uint64_t flags;
+ int ofs;
+
+ if (regno < 0 || regno >= NUM_REGS)
+ return 0;
+
+ /* Normally BSP is synthesized from BSPSTORE+ndirty, but since ndirty
+ is always 0, we can cheat and have BSP fetched from where BSPSTORE
+ is located. */
+ if (regno == IA64_BSP_REGNUM)
+ regno = IA64_BSPSTORE_REGNUM;
+
+ ofs = reg_offset[regno];
+ if (ofs == -1)
+ return 0;
+
+ /* fp holds the address of struct sigframe on the memory stack,
+ which typically is equal to sp+16 so we don't have to adjust
+ for the 16-byte scratch space. The first field in the signal
+ frame is the ucontext. The second field after the sigset is
+ the mcontext with the register values. The sigset is 16 bytes
+ large. */
+ fp += 16; /* struct __mcontext address. */
+
+ /* The first field in the mcontext is the flags field, which tells
+ is something about the saved context. */
+ if (target_read_memory (fp, buf, sizeof(buf)) == sizeof(buf))
+ flags = extract_unsigned_integer (buf, sizeof(buf));
+ else
+ flags = 0;
+
+ /* Translate offsets into struct reg and struct freg to offsets into
+ struct __mcontext. The mcontext almost looks like the concatenation
+ of struct reg and struct freg, except that the scratch registers and
+ the FP preserved registers are swapped. */
+ fp += 16; /* Skip flags field and reserved space. */
+ if (GREG_SUPPLIES (regno))
+ {
+ /* The preserved FP registers lie inbetween the preserved and scratch
+ registers. */
+ if (ofs >= SIZEOF_SPECIAL+SIZEOF_PRESERVED)
+ fp += SIZEOF_PRESERVED_FP;
+ }
+ else
+ {
+ /* make fp point to the first floating-point group, because the
+ register offset is relative to styruct freg. */
+ fp += SIZEOF_SPECIAL+SIZEOF_PRESERVED;
+ /* The scratch registers lie inbetween the preserved FP and scratch
+ FP registers. */
+ if (ofs >= SIZEOF_PRESERVED_FP)
+ fp += SIZEOF_SCRATCH;
+ /* Check if the mcontext contains the high FP register. */
+ if (ofs >= SIZEOF_PRESERVED_FP+SIZEOF_SCRATCH_FP &&
+ (flags & 2) == 0)
+ ofs = -1;
+ }
+
+ return (ofs == -1) ? 0 : fp + ofs;
+}
+
+static void
+ia64_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->sigcontext_register_address = ia64_fbsd_sigcontext_register_address;
+
+ set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ svr4_lp64_fetch_link_map_offsets);
+
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
+
+ set_gdbarch_regset_from_core_section (gdbarch,
+ ia64_fbsd_regset_from_core_section);
+}
+
+void
+_initialize_ia64_fbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_ia64, 0ul, GDB_OSABI_FREEBSD_ELF,
+ ia64_fbsd_init_abi);
+}
Index: gdb/ia64-fbsd-tdep.h
===================================================================
RCS file: gdb/ia64-fbsd-tdep.h
diff -N gdb/ia64-fbsd-tdep.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb/ia64-fbsd-tdep.h 4 Jul 2005 19:47:56 -0000 1.3
@@ -0,0 +1,53 @@
+/* Target-dependent definitions and declarations for FreeBSD/ia64.
+
+ Copyright 2005 Free Software Foundation, Inc.
+
+ Contributed by Marcel Moolenaar (marcel@xcllnt.net).
+
+ 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 IA64_FBSD_TDEP_H
+#define IA64_FBSD_TDEP_H
+
+#define FPREG_SUPPLIES(r) \
+ ((r) >= IA64_FR0_REGNUM && (r) <= IA64_FR127_REGNUM)
+#define GREG_SUPPLIES(r) \
+ (((r) >= IA64_GR1_REGNUM && (r) <= IA64_GR31_REGNUM) || \
+ ((r) >= IA64_BR0_REGNUM && (r) <= IA64_BR7_REGNUM) || \
+ (r) == IA64_PR_REGNUM || (r) == IA64_IP_REGNUM || \
+ (r) == IA64_PSR_REGNUM || (r) == IA64_CFM_REGNUM || \
+ (r) == IA64_RSC_REGNUM || (r) == IA64_BSP_REGNUM || \
+ (r) == IA64_BSPSTORE_REGNUM || (r) == IA64_RNAT_REGNUM || \
+ (r) == IA64_CSD_REGNUM || (r) == IA64_SSD_REGNUM || \
+ (r) == IA64_CCV_REGNUM || (r) == IA64_UNAT_REGNUM || \
+ (r) == IA64_FPSR_REGNUM || (r) == IA64_PFS_REGNUM || \
+ (r) == IA64_LC_REGNUM || (r) == IA64_EC_REGNUM)
+
+#define SIZEOF_SPECIAL (18*8)
+#define SIZEOF_PRESERVED (12*8)
+#define SIZEOF_SCRATCH (30*8)
+#define SIZEOF_PRESERVED_FP ((32-2)*16)
+#define SIZEOF_SCRATCH_FP (10*16)
+#define SIZEOF_HIGH_FP ((128-32)*16)
+
+void ia64_fbsd_collect_fpregset (const struct regcache *, int, void *);
+void ia64_fbsd_collect_gregset (const struct regcache *, int, void *);
+void ia64_fbsd_supply_fpregset (struct regcache *, int, const void *);
+void ia64_fbsd_supply_gregset (struct regcache *, int, const void *);
+
+#endif /* IA64_FBSD_TDEP_H */
Index: gdb/ia64-linux-nat.c
===================================================================
RCS file: /home/marcel/CVS/gdb6/gdb/ia64-linux-nat.c,v
retrieving revision 1.1.1.3
retrieving revision 1.5
diff -u -r1.1.1.3 -r1.5
--- gdb/ia64-linux-nat.c 24 Jun 2005 20:31:36 -0000 1.1.1.3
+++ gdb/ia64-linux-nat.c 24 Jun 2005 21:12:35 -0000 1.5
@@ -675,3 +675,13 @@
{
return syscall (__NR_getunwind, readbuf, len);
}
+
+LONGEST ia64_linux_xfer_dirty (struct target_ops *ops, enum target_object obj,
+ const char *annex, void *rbuf, const void *wbuf,
+ ULONGEST ofs, LONGEST len)
+{
+ ULONGEST addr;
+ addr = *(ULONGEST*)annex + ofs;
+ return ops->to_xfer_partial (ops, TARGET_OBJECT_MEMORY, NULL, rbuf, wbuf,
+ addr, len);
+}
Index: gdb/ia64-tdep.c
===================================================================
RCS file: /home/marcel/CVS/gdb6/gdb/ia64-tdep.c,v
retrieving revision 1.1.1.5
retrieving revision 1.15
diff -u -r1.1.1.5 -r1.15
--- gdb/ia64-tdep.c 24 Jun 2005 20:31:36 -0000 1.1.1.5
+++ gdb/ia64-tdep.c 5 Jul 2005 18:15:16 -0000 1.15
@@ -672,6 +672,44 @@
}
static void
+ia64_read_reg (struct regcache *regcache, CORE_ADDR addr, void *buf, int len)
+{
+ ULONGEST bspstore;
+ regcache_cooked_read_unsigned (regcache, IA64_BSPSTORE_REGNUM, &bspstore);
+ if (addr >= bspstore)
+ {
+ ULONGEST bsp;
+ regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
+ if (addr < bsp)
+ {
+ target_read_partial (¤t_target, TARGET_OBJECT_DIRTY,
+ (void*)&bspstore, buf, addr - bspstore, len);
+ return;
+ }
+ }
+ target_read_memory (addr, buf, len);
+}
+
+static void
+ia64_write_reg (struct regcache *regcache, CORE_ADDR addr, void *buf, int len)
+{
+ ULONGEST bspstore;
+ regcache_cooked_read_unsigned (regcache, IA64_BSPSTORE_REGNUM, &bspstore);
+ if (addr >= bspstore)
+ {
+ ULONGEST bsp;
+ regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
+ if (addr < bsp)
+ {
+ target_write_partial (¤t_target, TARGET_OBJECT_DIRTY,
+ (void*)&bspstore, buf, addr - bspstore, len);
+ return;
+ }
+ }
+ target_write_memory (addr, buf, len);
+}
+
+static void
ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int regnum, gdb_byte *buf)
{
@@ -689,7 +727,6 @@
this is the best we can do. */
ULONGEST cfm;
ULONGEST bsp;
- CORE_ADDR reg;
regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
@@ -700,8 +737,8 @@
if ((cfm & 0x7f) > regnum - V32_REGNUM)
{
ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
- reg = read_memory_integer ((CORE_ADDR)reg_addr, 8);
- store_unsigned_integer (buf, register_size (current_gdbarch, regnum), reg);
+ ia64_read_reg (regcache, reg_addr, buf,
+ register_size (current_gdbarch, regnum));
}
else
store_unsigned_integer (buf, register_size (current_gdbarch, regnum), 0);
@@ -743,7 +780,11 @@
if (nat_addr >= bsp)
regcache_cooked_read_unsigned (regcache, IA64_RNAT_REGNUM, &nat_collection);
else
- nat_collection = read_memory_integer (nat_addr, 8);
+ {
+ char nat_buf[8];
+ ia64_read_reg (regcache, nat_addr, nat_buf, sizeof(nat_buf));
+ nat_collection = extract_unsigned_integer (nat_buf, 8);
+ }
nat_bit = (gr_addr >> 3) & 0x3f;
natN_val = (nat_collection >> nat_bit) & 1;
}
@@ -808,7 +849,7 @@
if ((cfm & 0x7f) > regnum - V32_REGNUM)
{
ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
- write_memory (reg_addr, (void *)buf, 8);
+ ia64_write_reg (regcache, reg_addr, (void *)buf, 8);
}
}
else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
@@ -863,13 +904,14 @@
else
{
char nat_buf[8];
- nat_collection = read_memory_integer (nat_addr, 8);
+ ia64_read_reg (regcache, nat_addr, nat_buf, sizeof(nat_buf));
+ nat_collection = extract_unsigned_integer (nat_buf, 8);
if (natN_val)
nat_collection |= natN_mask;
else
nat_collection &= ~natN_mask;
- store_unsigned_integer (nat_buf, register_size (current_gdbarch, regnum), nat_collection);
- write_memory (nat_addr, nat_buf, 8);
+ store_unsigned_integer (nat_buf, sizeof(nat_buf), nat_collection);
+ ia64_write_reg (regcache, nat_addr, nat_buf, sizeof(nat_buf));
}
}
}
@@ -1443,7 +1485,10 @@
cfm = 0;
if (cache->saved_regs[IA64_CFM_REGNUM] != 0)
{
- cfm = read_memory_integer (cache->saved_regs[IA64_CFM_REGNUM], 8);
+ char cfm_buf[8];
+ ia64_read_reg (current_regcache, cache->saved_regs[IA64_CFM_REGNUM],
+ cfm_buf, sizeof(cfm_buf));
+ cfm = extract_unsigned_integer (cfm_buf, sizeof(cfm_buf));
}
else if (cfm_reg != 0)
{
@@ -1641,14 +1686,18 @@
{
*lvalp = lval_memory;
*addrp = addr;
- read_memory (addr, valuep, register_size (current_gdbarch, regnum));
+ ia64_read_reg (current_regcache, addr, valuep,
+ register_size (current_gdbarch, regnum));
}
else if (cache->prev_cfm)
store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), cache->prev_cfm);
else if (cache->frameless)
{
- CORE_ADDR cfm = 0;
+ uint64_t cfm;
frame_unwind_register (next_frame, IA64_PFS_REGNUM, valuep);
+ cfm = extract_unsigned_integer (valuep, sizeof(cfm));
+ cfm = 0x8000000000000000ULL | (cfm & 0x3fffffffffULL);
+ store_unsigned_integer (valuep, sizeof(cfm), cfm);
}
}
else if (regnum == IA64_VFP_REGNUM)
@@ -1726,7 +1775,13 @@
nat_collection = extract_unsigned_integer (buf, 8);
}
else
- nat_collection = read_memory_integer (nat_addr, 8);
+ {
+ char nat_buf[8];
+ ia64_read_reg (current_regcache, nat_addr, nat_buf,
+ sizeof(nat_buf));
+ nat_collection = extract_unsigned_integer (nat_buf,
+ sizeof(nat_buf));
+ }
nat_bit = (gr_addr >> 3) & 0x3f;
natval = (nat_collection >> nat_bit) & 1;
}
@@ -1742,7 +1797,8 @@
{
*lvalp = lval_memory;
*addrp = addr;
- read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
+ ia64_read_reg (current_regcache, addr, buf,
+ register_size (current_gdbarch, IA64_IP_REGNUM));
pc = extract_unsigned_integer (buf, 8);
}
else if (cache->frameless)
@@ -1771,7 +1827,8 @@
{
*lvalp = lval_memory;
*addrp = addr;
- read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
+ ia64_read_reg (current_regcache, addr, buf,
+ register_size (current_gdbarch, IA64_IP_REGNUM));
pc = extract_unsigned_integer (buf, 8);
}
else if (cache->frameless)
@@ -1793,7 +1850,8 @@
{
*lvalp = lval_memory;
*addrp = addr;
- read_memory (addr, buf, register_size (current_gdbarch, IA64_BR0_REGNUM));
+ ia64_read_reg (current_regcache, addr, buf,
+ register_size (current_gdbarch, IA64_BR0_REGNUM));
br0 = extract_unsigned_integer (buf, 8);
}
store_unsigned_integer (valuep, 8, br0);
@@ -1809,7 +1867,8 @@
{
*lvalp = lval_memory;
*addrp = addr;
- read_memory (addr, valuep, register_size (current_gdbarch, regnum));
+ ia64_read_reg (current_regcache, addr, valuep,
+ register_size (current_gdbarch, regnum));
}
else if (cache->frameless)
{
@@ -1820,6 +1879,7 @@
CORE_ADDR r_addr;
CORE_ADDR prev_cfm, prev_bsp, prev_bof;
CORE_ADDR addr = 0;
+
if (regnum >= V32_REGNUM)
regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
ia64_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM,
@@ -1833,7 +1893,8 @@
addr = rse_address_add (prev_bof, (regnum - IA64_GR32_REGNUM));
*lvalp = lval_memory;
*addrp = addr;
- read_memory (addr, valuep, register_size (current_gdbarch, regnum));
+ ia64_read_reg (current_regcache, addr, valuep,
+ register_size (current_gdbarch, regnum));
}
}
else
@@ -1857,7 +1918,8 @@
{
*lvalp = lval_memory;
*addrp = addr;
- read_memory (addr, valuep, register_size (current_gdbarch, regnum));
+ ia64_read_reg (current_regcache, addr, valuep,
+ register_size (current_gdbarch, regnum));
}
/* Otherwise, punt and get the current value of the register. */
else
@@ -1902,6 +1964,10 @@
SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_PSR_REGNUM);
cache->saved_regs[IA64_BSP_REGNUM] =
SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_BSP_REGNUM);
+ cache->saved_regs[IA64_BSPSTORE_REGNUM] =
+ SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_BSPSTORE_REGNUM);
+ cache->saved_regs[IA64_RSC_REGNUM] =
+ SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_RSC_REGNUM);
cache->saved_regs[IA64_RNAT_REGNUM] =
SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_RNAT_REGNUM);
cache->saved_regs[IA64_CCV_REGNUM] =
@@ -2012,7 +2078,8 @@
{
*lvalp = lval_memory;
*addrp = addr;
- read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
+ ia64_read_reg (current_regcache, addr, buf,
+ register_size (current_gdbarch, IA64_IP_REGNUM));
pc = extract_unsigned_integer (buf, 8);
}
pc &= ~0xf;
@@ -2029,7 +2096,8 @@
{
*lvalp = lval_memory;
*addrp = addr;
- read_memory (addr, valuep, register_size (current_gdbarch, regnum));
+ ia64_read_reg (current_regcache, addr, valuep,
+ register_size (current_gdbarch, regnum));
}
}
else
@@ -2040,7 +2108,8 @@
{
*lvalp = lval_memory;
*addrp = addr;
- read_memory (addr, valuep, register_size (current_gdbarch, regnum));
+ ia64_read_reg (current_regcache, addr, valuep,
+ register_size (current_gdbarch, regnum));
}
}
@@ -3152,20 +3221,26 @@
faddr_sect = find_pc_section (faddr);
if (faddr_sect != NULL)
{
- struct obj_section *osect;
+ struct obj_section *osect, *dot_dynamic;
+ dot_dynamic = NULL;
ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
{
+ /* We fancy .got sections. Just the thing we need. */
+ if (strcmp (osect->the_bfd_section->name, ".got") == 0)
+ return osect->addr;
+
+ /* As an alternative, we could use DT_PLTGOT. */
if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0)
- break;
+ dot_dynamic = osect;
}
- if (osect < faddr_sect->objfile->sections_end)
+ if (dot_dynamic != NULL)
{
CORE_ADDR addr;
- addr = osect->addr;
- while (addr < osect->endaddr)
+ addr = dot_dynamic->addr;
+ while (addr < dot_dynamic->endaddr)
{
int status;
LONGEST tag;
@@ -3185,6 +3260,9 @@
break;
global_pointer = extract_unsigned_integer (buf, sizeof (buf));
+ /* We need to relocate. */
+ global_pointer += dot_dynamic->offset;
+
/* The payoff... */
return global_pointer;
}
@@ -3350,10 +3428,10 @@
pfs = read_register (IA64_PFS_REGNUM);
pfs &= 0xc000000000000000LL;
- pfs |= (cfm & 0xffffffffffffLL);
+ pfs |= (cfm & 0x3fffffffffLL);
write_register (IA64_PFS_REGNUM, pfs);
- cfm &= 0xc000000000000000LL;
+ cfm &= 0x8000000000000000LL;
cfm |= rseslots;
write_register (IA64_CFM_REGNUM, cfm);
@@ -3544,7 +3622,8 @@
tdep = xmalloc (sizeof (struct gdbarch_tdep));
gdbarch = gdbarch_alloc (&info, tdep);
- tdep->sigcontext_register_address = 0;
+ tdep->osabi = info.osabi;
+ tdep->sigcontext_register_address = NULL;
/* Define the ia64 floating-point format to gdb. */
builtin_type_ia64_ext =
Index: gdb/ia64-tdep.h
===================================================================
RCS file: /home/marcel/CVS/gdb6/gdb/ia64-tdep.h,v
retrieving revision 1.1.1.2
retrieving revision 1.3
diff -u -r1.1.1.2 -r1.3
--- gdb/ia64-tdep.h 24 Jun 2005 20:31:36 -0000 1.1.1.2
+++ gdb/ia64-tdep.h 25 Jun 2005 01:59:15 -0000 1.3
@@ -22,6 +22,8 @@
#ifndef IA64_TDEP_H
#define IA64_TDEP_H
+#include "osabi.h"
+
/* Register numbers of various important registers. */
/* General registers; there are 128 of these 64 bit wide registers.
@@ -198,6 +200,8 @@
struct gdbarch_tdep
{
+ enum gdb_osabi osabi; /* OS/ABI of inferior. */
+
CORE_ADDR (*sigcontext_register_address) (CORE_ADDR, int);
};
Index: gdb/inf-ptrace.c
===================================================================
RCS file: /home/marcel/CVS/gdb6/gdb/inf-ptrace.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -r1.1.1.2 -r1.2
--- gdb/inf-ptrace.c 24 Jun 2005 20:31:36 -0000 1.1.1.2
+++ gdb/inf-ptrace.c 30 Jun 2005 04:56:38 -0000 1.2
@@ -511,6 +511,13 @@
case TARGET_OBJECT_WCOOKIE:
return -1;
+ case TARGET_OBJECT_DIRTY:
+#ifndef NATIVE_XFER_DIRTY
+#define NATIVE_XFER_DIRTY(OPS,OBJ,ANNEX,RDBUF,WRBUF,OFS,LEN) (-1)
+#endif
+ return NATIVE_XFER_DIRTY (ops, object, annex, readbuf, writebuf,
+ offset, len);
+
default:
return -1;
}
Index: gdb/inftarg.c
===================================================================
RCS file: /home/marcel/CVS/gdb6/gdb/inftarg.c,v
retrieving revision 1.1.1.4
retrieving revision 1.6
diff -u -r1.1.1.4 -r1.6
--- gdb/inftarg.c 24 Jun 2005 20:31:36 -0000 1.1.1.4
+++ gdb/inftarg.c 24 Jun 2005 22:20:50 -0000 1.6
@@ -559,6 +559,13 @@
return NATIVE_XFER_AUXV (ops, object, annex, readbuf, writebuf,
offset, len);
+ case TARGET_OBJECT_DIRTY:
+#ifndef NATIVE_XFER_DIRTY
+#define NATIVE_XFER_DIRTY(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1)
+#endif
+ return NATIVE_XFER_DIRTY (ops, object, annex, readbuf, writebuf,
+ offset, len);
+
default:
return -1;
}
Index: gdb/remote.c
===================================================================
RCS file: /home/marcel/CVS/gdb6/gdb/remote.c,v
retrieving revision 1.1.1.6
retrieving revision 1.9
diff -u -r1.1.1.6 -r1.9
--- gdb/remote.c 24 Jun 2005 20:31:37 -0000 1.1.1.6
+++ gdb/remote.c 25 Jun 2005 05:20:28 -0000 1.9
@@ -995,6 +995,23 @@
show_packet_config_cmd (&remote_protocol_p);
}
+/* Should we try the 'qPart:dirty' (target dirty register read) request? */
+static struct packet_config remote_protocol_qPart_dirty;
+
+static void
+set_remote_protocol_qPart_dirty_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_qPart_dirty);
+}
+
+static void
+show_remote_protocol_qPart_dirty_packet_cmd (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
+{
+ show_packet_config_cmd (&remote_protocol_qPart_dirty);
+}
/* Tokens for use by the asynchronous signal handlers for SIGINT. */
@@ -2108,6 +2125,7 @@
downloading. */
update_packet_config (&remote_protocol_binary_download);
update_packet_config (&remote_protocol_qPart_auxv);
+ update_packet_config (&remote_protocol_qPart_dirty);
update_packet_config (&remote_protocol_qGetTLSAddr);
}
@@ -5035,6 +5053,23 @@
}
return -1;
+ case TARGET_OBJECT_DIRTY:
+ if (remote_protocol_qPart_dirty.support != PACKET_DISABLE)
+ {
+ snprintf (buf2, rs->remote_packet_size, "qPart:dirty:read::%lx",
+ (long)(offset >> 3));
+ i = putpkt (buf2);
+ if (i < 0)
+ return i;
+ buf2[0] = '\0';
+ getpkt (buf2, rs->remote_packet_size, 0);
+ if (packet_ok (buf2, &remote_protocol_qPart_dirty) != PACKET_OK)
+ return -1;
+ i = hex2bin (buf2, readbuf, len);
+ return i;
+ }
+ return -1;
+
default:
return -1;
}
@@ -5584,6 +5619,7 @@
show_remote_protocol_vcont_packet_cmd (gdb_stdout, from_tty, NULL, NULL);
show_remote_protocol_binary_download_cmd (gdb_stdout, from_tty, NULL, NULL);
show_remote_protocol_qPart_auxv_packet_cmd (gdb_stdout, from_tty, NULL, NULL);
+ show_remote_protocol_qPart_dirty_packet_cmd (gdb_stdout, from_tty, NULL, NULL);
show_remote_protocol_qGetTLSAddr_packet_cmd (gdb_stdout, from_tty, NULL, NULL);
}
@@ -5814,6 +5850,13 @@
&remote_set_cmdlist, &remote_show_cmdlist,
0);
+ add_packet_config_cmd (&remote_protocol_qPart_dirty,
+ "qPart_dirty", "read-dirty-registers",
+ set_remote_protocol_qPart_dirty_packet_cmd,
+ show_remote_protocol_qPart_dirty_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+
add_packet_config_cmd (&remote_protocol_qGetTLSAddr,
"qGetTLSAddr", "get-thread-local-storage-address",
set_remote_protocol_qGetTLSAddr_packet_cmd,
Index: gdb/target.h
===================================================================
RCS file: /home/marcel/CVS/gdb6/gdb/target.h,v
retrieving revision 1.1.1.4
retrieving revision 1.5
diff -u -r1.1.1.4 -r1.5
--- gdb/target.h 24 Jun 2005 20:31:38 -0000 1.1.1.4
+++ gdb/target.h 24 Jun 2005 21:14:20 -0000 1.5
@@ -229,7 +229,9 @@
/* Transfer auxilliary vector. */
TARGET_OBJECT_AUXV,
/* StackGhost cookie. See "sparc-tdep.c". */
- TARGET_OBJECT_WCOOKIE
+ TARGET_OBJECT_WCOOKIE,
+ /* Dirty registers. See "ia64-tdep.c". */
+ TARGET_OBJECT_DIRTY
/* Possible future objects: TARGET_OBJECT_FILE, TARGET_OBJECT_PROC, ... */
};
Index: gdb/config/djgpp/fnchange.lst
===================================================================
RCS file: /home/marcel/CVS/gdb6/gdb/config/djgpp/fnchange.lst,v
retrieving revision 1.1.1.4
retrieving revision 1.6
diff -u -r1.1.1.4 -r1.6
--- gdb/config/djgpp/fnchange.lst 24 Jun 2005 20:31:41 -0000 1.1.1.4
+++ gdb/config/djgpp/fnchange.lst 4 Jul 2005 19:53:50 -0000 1.6
@@ -145,6 +145,9 @@
@V@/gdb/i386-sol2-tdep.c @V@/gdb/i3sol2-tdep.c
@V@/gdb/ia64-aix-nat.c @V@/gdb/ia64ax-nat.c
@V@/gdb/ia64-aix-tdep.c @V@/gdb/ia64ax-tdep.c
+@V@/gdb/ia64-fbsd-nat.c @V@/gdb/ia64fb-nat.c
+@V@/gdb/ia64-fbsd-tdep.c @V@/gdb/ia64fb-tdep.c
+@V@/gdb/ia64-fbsd-tdep.h @V@/gdb/ia64fb-tdep.h
@V@/gdb/ia64-linux-nat.c @V@/gdb/ia64lx-nat.c
@V@/gdb/ia64-linux-nat.c @V@/gdb/ia64lx-tdep.c
@V@/gdb/jv-exp.tab.c @V@/gdb/jv-exp_tab.c
Index: gdb/config/ia64/fbsd.mh
===================================================================
RCS file: gdb/config/ia64/fbsd.mh
diff -N gdb/config/ia64/fbsd.mh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb/config/ia64/fbsd.mh 30 Jun 2005 04:55:28 -0000 1.3
@@ -0,0 +1,2 @@
+NATDEPFILES= fork-child.o inf-ptrace.o fbsd-nat.o ia64-fbsd-nat.o gcore.o
+NAT_FILE= nm-fbsd.h
Index: gdb/config/ia64/fbsd.mt
===================================================================
RCS file: gdb/config/ia64/fbsd.mt
diff -N gdb/config/ia64/fbsd.mt
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb/config/ia64/fbsd.mt 24 May 2005 04:49:21 -0000 1.2
@@ -0,0 +1,2 @@
+TDEPFILES= corelow.o ia64-fbsd-tdep.o ia64-tdep.o solib.o solib-svr4.o
+DEPRECATED_TM_FILE= tm-fbsd.h
Index: gdb/config/ia64/nm-fbsd.h
===================================================================
RCS file: gdb/config/ia64/nm-fbsd.h
diff -N gdb/config/ia64/nm-fbsd.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb/config/ia64/nm-fbsd.h 5 Jul 2005 02:27:00 -0000 1.6
@@ -0,0 +1,33 @@
+/* Definitions to natively run GDB on FreeBSD/ia64.
+
+ Copyright 2005 Free Software Foundation, Inc.
+
+ Contributed by Marcel Moolenaar (marcel@xcllnt.net).
+
+ 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 NM_FBSD_H
+#define NM_FBSD_H
+
+#include "target.h"
+
+#define NATIVE_XFER_DIRTY ia64_fbsd_xfer_dirty
+extern LONGEST ia64_fbsd_xfer_dirty(struct target_ops *, enum target_object,
+ const char *, void *, const void *, ULONGEST, LONGEST);
+
+#endif /* NM_FBSD_H */
Index: gdb/config/ia64/nm-linux.h
===================================================================
RCS file: /home/marcel/CVS/gdb6/gdb/config/ia64/nm-linux.h,v
retrieving revision 1.1.1.2
retrieving revision 1.4
diff -u -r1.1.1.2 -r1.4
--- gdb/config/ia64/nm-linux.h 28 Apr 2005 21:53:05 -0000 1.1.1.2
+++ gdb/config/ia64/nm-linux.h 24 May 2005 04:41:21 -0000 1.4
@@ -86,4 +86,9 @@
ULONGEST offset,
LONGEST len);
+#define NATIVE_XFER_DIRTY ia64_linux_xfer_dirty
+extern LONGEST ia64_linux_xfer_dirty (struct target_ops *, enum target_object,
+ const char *, void *, const void *,
+ ULONGEST, LONGEST);
+
#endif /* #ifndef NM_LINUX_H */
Index: gdb/config/ia64/tm-fbsd.h
===================================================================
RCS file: gdb/config/ia64/tm-fbsd.h
diff -N gdb/config/ia64/tm-fbsd.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb/config/ia64/tm-fbsd.h 4 Jul 2005 19:50:02 -0000 1.5
@@ -0,0 +1,32 @@
+/* Definitions to target GDB to FreeBSD/ia64.
+
+ Copyright 2005 Free Software Foundation, Inc.
+
+ Contributed by Marcel Moolenaar (marcel@xcllnt.net).
+
+ 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 TM_FBSD_H
+#define TM_FBSD_H
+
+#include "solib.h"
+
+extern int ia64_fbsd_in_sigtramp (CORE_ADDR pc, char *fnm);
+#define DEPRECATED_IN_SIGTRAMP(pc,fnm) ia64_fbsd_in_sigtramp (pc, fnm)
+
+#endif /* TM_FBSD_H */
Index: gdb/testsuite/gdb.asm/ia64.inc
===================================================================
RCS file: /home/marcel/CVS/gdb6/gdb/testsuite/gdb.asm/ia64.inc,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -r1.1.1.2 -r1.2
--- gdb/testsuite/gdb.asm/ia64.inc 24 Jun 2005 20:31:44 -0000 1.1.1.2
+++ gdb/testsuite/gdb.asm/ia64.inc 2 Jul 2005 20:26:22 -0000 1.2
@@ -3,6 +3,7 @@
alloc r33=ar.pfs,0,2,0,0
mov r32=b0
nop.i 0
+ ;;
.endm
comment "subroutine epilogue"
@@ -10,6 +11,7 @@
nop.m 0
mov ar.pfs=r33
mov b0=r32
+ ;;
nop.m 0
nop.f 0
br.ret.sptk.many b0
@@ -49,3 +51,16 @@
\name:
.long \value
.endm
+
+ comment "Declare a subroutine"
+ .purgem gdbasm_declare
+ .macro gdbasm_declare name
+ .proc \name
+\name:
+ .endm
+
+ comment "End a subroutine"
+ .purgem gdbasm_end
+ .macro gdbasm_end name
+ .endp \name
+ .endm
^ permalink raw reply [flat|nested] 12+ messages in thread
* Followup: [PATCH] New port: ia64-*-freebsd
2005-07-05 19:52 [PATCH] New port: ia64-*-freebsd Marcel Moolenaar
@ 2005-07-06 17:24 ` Marcel Moolenaar
2005-07-15 0:01 ` Daniel Jacobowitz
1 sibling, 0 replies; 12+ messages in thread
From: Marcel Moolenaar @ 2005-07-06 17:24 UTC (permalink / raw)
To: Marcel Moolenaar; +Cc: gdb-patches
On Jul 5, 2005, at 12:51 PM, Marcel Moolenaar wrote:
> There's a small regression on ia64-*-linux that I'm currently
> analyzing and which may relate to process problems. Please let
> me know if you see it too if you're able to test the patches.
The 2 regressions for the libunwind case were indeed process
problems. I failed to see the compile failure when not compiling
against libunwind and the failures there were all bogus. I
updated the patch at http://www.xcllnt.net/~marcel/gdb and now
have real results: 3 failures less when not using libunwind.
So: all is well -- better in fact.
Just make sure to use the patch at the URL.
FYI,
--
Marcel Moolenaar marcel@cup.hp.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] New port: ia64-*-freebsd
2005-07-05 19:52 [PATCH] New port: ia64-*-freebsd Marcel Moolenaar
2005-07-06 17:24 ` Followup: " Marcel Moolenaar
@ 2005-07-15 0:01 ` Daniel Jacobowitz
2005-07-15 2:08 ` Marcel Moolenaar
1 sibling, 1 reply; 12+ messages in thread
From: Daniel Jacobowitz @ 2005-07-15 0:01 UTC (permalink / raw)
To: Marcel Moolenaar; +Cc: gdb-patches
I don't know anything about ia64, or much about FreeBSD, so I will
refrain from a thorough review. You'll need Kevin or Jeff to look over
it eventually (see MAINTAINERS). I have a bunch of comments about the
patch anyway, mostly dealing with the bits I couldn't make sense of - I
just wanted to do my part against the patch sitting unread for
months...
On Tue, Jul 05, 2005 at 12:51:04PM -0700, Marcel Moolenaar wrote:
> Gang,
>
> It took a while, but the legal preconditions have recently been
> met and I'm delighted to present you with the long awaited port
> of GDB to FreeBSD/ia64.
It's not very useful as a single jumbo patch - especially since you
didn't explain any of what it was doing.
You added bits to the remote protocol; those must be documented in the
manual (and, generally, discussed beforehand). Are there any stubs
which use them?
The comment on TARGET_OBJECT_DIRTY says "see ia64-tdep.c", which has
basically no comments explaining what it does, or why it is necessary
for FreeBSD when it isn't for GNU/Linux.
NATIVE_XFER_DIRTY is not necessary; the BSDs all use target vector
inheritance now as far as I know, so you can override it that way.
Similarly tm-fbsd.h is not necessary any more.
The corelow.c implementation of TARGET_OBJECT_DIRTY looks pretty
sketchy for target-independent code.
You have a lot of non-GNUish formatting issues - mostly the pesky
spacing rules.
The BFD bits need to go separately to the binutils@ list.
> There are some fixes that aren't exactly related to this port,
> but which I ran into and kept. It's probably better to commit
> those seperately, but I leave that up to the group.
Our preference is to do this sort of thing separately to simplify
review.
--
Daniel Jacobowitz
CodeSourcery, LLC
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] New port: ia64-*-freebsd
2005-07-15 0:01 ` Daniel Jacobowitz
@ 2005-07-15 2:08 ` Marcel Moolenaar
2005-07-15 2:16 ` Daniel Jacobowitz
0 siblings, 1 reply; 12+ messages in thread
From: Marcel Moolenaar @ 2005-07-15 2:08 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Jul 14, 2005, at 5:01 PM, Daniel Jacobowitz wrote:
> I don't know anything about ia64, or much about FreeBSD, so I will
> refrain from a thorough review. You'll need Kevin or Jeff to look over
> it eventually (see MAINTAINERS). I have a bunch of comments about the
> patch anyway, mostly dealing with the bits I couldn't make sense of - I
> just wanted to do my part against the patch sitting unread for
> months...
:-)
Don't worry: Mark has contacted me off-list. We'll go through it
as time permits.
> On Tue, Jul 05, 2005 at 12:51:04PM -0700, Marcel Moolenaar wrote:
>> Gang,
>>
>> It took a while, but the legal preconditions have recently been
>> met and I'm delighted to present you with the long awaited port
>> of GDB to FreeBSD/ia64.
>
> It's not very useful as a single jumbo patch - especially since you
> didn't explain any of what it was doing.
I see. It helps to know what people like to see explained. This
avoids that I ramble on about trivialities while skipping the
complicated or non-intuitive bits.
> You added bits to the remote protocol; those must be documented in the
> manual (and, generally, discussed beforehand). Are there any stubs
> which use them?
Good point about the documentation. I'll dig into it. As for whether
there's a stub that uses it: yes, the FreeBSD kernel.
> The comment on TARGET_OBJECT_DIRTY says "see ia64-tdep.c", which has
> basically no comments explaining what it does, or why it is necessary
> for FreeBSD when it isn't for GNU/Linux.
A quick explanation then:
Stacked registers are either dirty or flushed when it comes to
accessing them. Stacked registers that are flushed have been
written to the backing store by the processor -- they are in
the target's memory. Stacked registers that are dirty are still
in the processor. They end up on the kernel's stack of the
corresponding process whenever there's a kernel context switch.
Linux abstracts this and allows them both to be read and written
the same way. FreeBSD doesn't abstract this. The reason
FreeBSD doesn't abstract it is because it is not always possible
to do so, nor is it always beneficial to do so.
So, in order for gdb to handle all possible failure modes, it
needs to be aware of the difference so that it can access the
registers accordingly.
A typical example of a failure mode that cannot be debugged with
abstraction, is a core file created when the backing store overflows.
The kernel will not be able to move the dirty stacked registers
in the core file, because there's no room for it (there's no space
on the backing store where they would normally go). They need to
be written into the core file as a note (like the general registers)
and fetched seperately.
> NATIVE_XFER_DIRTY is not necessary; the BSDs all use target vector
> inheritance now as far as I know, so you can override it that way.
> Similarly tm-fbsd.h is not necessary any more.
Ok, thanks. I'll dig into that as well.
> The corelow.c implementation of TARGET_OBJECT_DIRTY looks pretty
> sketchy for target-independent code.
What exactly do you mean?
> You have a lot of non-GNUish formatting issues - mostly the pesky
> spacing rules.
No doubt. I'm not used to the GNU formatting :-)
Thanks for the feedback,
--
Marcel Moolenaar USPA: A-39004 marcel@xcllnt.net
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] New port: ia64-*-freebsd
2005-07-15 2:08 ` Marcel Moolenaar
@ 2005-07-15 2:16 ` Daniel Jacobowitz
2005-07-15 18:20 ` Marcel Moolenaar
0 siblings, 1 reply; 12+ messages in thread
From: Daniel Jacobowitz @ 2005-07-15 2:16 UTC (permalink / raw)
To: Marcel Moolenaar; +Cc: gdb-patches
On Thu, Jul 14, 2005 at 07:08:09PM -0700, Marcel Moolenaar wrote:
> >The comment on TARGET_OBJECT_DIRTY says "see ia64-tdep.c", which has
> >basically no comments explaining what it does, or why it is necessary
> >for FreeBSD when it isn't for GNU/Linux.
>
> A quick explanation then:
> Stacked registers are either dirty or flushed when it comes to
> accessing them. Stacked registers that are flushed have been
> written to the backing store by the processor -- they are in
> the target's memory. Stacked registers that are dirty are still
> in the processor. They end up on the kernel's stack of the
> corresponding process whenever there's a kernel context switch.
> Linux abstracts this and allows them both to be read and written
> the same way. FreeBSD doesn't abstract this. The reason
> FreeBSD doesn't abstract it is because it is not always possible
> to do so, nor is it always beneficial to do so.
> So, in order for gdb to handle all possible failure modes, it
> needs to be aware of the difference so that it can access the
> registers accordingly.
>
> A typical example of a failure mode that cannot be debugged with
> abstraction, is a core file created when the backing store overflows.
> The kernel will not be able to move the dirty stacked registers
> in the core file, because there's no room for it (there's no space
> on the backing store where they would normally go). They need to
> be written into the core file as a note (like the general registers)
> and fetched seperately.
Thank you! This needs to be described in the source somewhere. I'd
like to see a more descriptive name for TARGET_OBJECT_DIRTY, also,
though I don't have any advice - right now it would be a good place to
stick a dirty hack. Or dirty laundry.
> >The corelow.c implementation of TARGET_OBJECT_DIRTY looks pretty
> >sketchy for target-independent code.
>
> What exactly do you mean?
+ case TARGET_OBJECT_DIRTY:
+ {
+ ULONGEST addr;
+ addr = *(ULONGEST*)annex + offset;
+ if (readbuf)
+ return (*ops->deprecated_xfer_memory) (addr, readbuf, len,
+ 0/*read*/, NULL, ops);
+ if (writebuf)
+ return (*ops->deprecated_xfer_memory) (addr, writebuf, len,
+ 1/*write*/, NULL, ops);
+ return -1;
+ }
+
So, it treats the annex as a memory pointer and returns the contents of
memory there. Why? And why is this a useful generic implementation?
From your description abov it sounds like these ought to be in their
own core file note anyway; why have they ended up in "memory"?
>
> >You have a lot of non-GNUish formatting issues - mostly the pesky
> >spacing rules.
>
> No doubt. I'm not used to the GNU formatting :-)
You did better than most people not used to it can manage :-)
--
Daniel Jacobowitz
CodeSourcery, LLC
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] New port: ia64-*-freebsd
2005-07-15 2:16 ` Daniel Jacobowitz
@ 2005-07-15 18:20 ` Marcel Moolenaar
2005-07-24 21:26 ` Daniel Jacobowitz
0 siblings, 1 reply; 12+ messages in thread
From: Marcel Moolenaar @ 2005-07-15 18:20 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Jul 14, 2005, at 7:16 PM, Daniel Jacobowitz wrote:
> On Thu, Jul 14, 2005 at 07:08:09PM -0700, Marcel Moolenaar wrote:
>>> The comment on TARGET_OBJECT_DIRTY says "see ia64-tdep.c", which has
>>> basically no comments explaining what it does, or why it is necessary
>>> for FreeBSD when it isn't for GNU/Linux.
>>
>> A quick explanation then:
>> Stacked registers are either dirty or flushed when it comes to
>> accessing them. Stacked registers that are flushed have been
>> written to the backing store by the processor -- they are in
>> the target's memory. Stacked registers that are dirty are still
>> in the processor. They end up on the kernel's stack of the
>> corresponding process whenever there's a kernel context switch.
>> Linux abstracts this and allows them both to be read and written
>> the same way. FreeBSD doesn't abstract this. The reason
>> FreeBSD doesn't abstract it is because it is not always possible
>> to do so, nor is it always beneficial to do so.
>> So, in order for gdb to handle all possible failure modes, it
>> needs to be aware of the difference so that it can access the
>> registers accordingly.
>>
>> A typical example of a failure mode that cannot be debugged with
>> abstraction, is a core file created when the backing store overflows.
>> The kernel will not be able to move the dirty stacked registers
>> in the core file, because there's no room for it (there's no space
>> on the backing store where they would normally go). They need to
>> be written into the core file as a note (like the general registers)
>> and fetched seperately.
>
> Thank you! This needs to be described in the source somewhere.
I'll add this (or the gist of it) to ia64-tdep.c.
> I'd
> like to see a more descriptive name for TARGET_OBJECT_DIRTY, also,
> though I don't have any advice - right now it would be a good place to
> stick a dirty hack. Or dirty laundry.
:-)
An alternative would be TARGET_OBJECT_RSE or TARGET_OBJECT_IA64_RSE.
RSE stands for Register Stack Engine, which is where the dirty
registers live in the CPU. This would actually make a lot of sense,
because we're going to access the registers in the RSE "object".
>>> The corelow.c implementation of TARGET_OBJECT_DIRTY looks pretty
>>> sketchy for target-independent code.
>>
>> What exactly do you mean?
>
> + case TARGET_OBJECT_DIRTY:
> + {
> + ULONGEST addr;
> + addr = *(ULONGEST*)annex + offset;
> + if (readbuf)
> + return (*ops->deprecated_xfer_memory) (addr, readbuf, len,
> + 0/*read*/, NULL, ops);
> + if (writebuf)
> + return (*ops->deprecated_xfer_memory) (addr, writebuf, len,
> + 1/*write*/, NULL,
> ops);
> + return -1;
> + }
> +
>
> So, it treats the annex as a memory pointer and returns the contents of
> memory there. Why? And why is this a useful generic implementation?
Yeah, that's a bit tricky. Here's why:
The stacked registers that are flushed, live in memory below the
address pointed to by the BSPSTORE register. The stacked registers
that are dirty would be flushed to memory between the values of
BSPSTORE (bottom) and BSP (top) if and when they are being flushed.
I figured that from an API point of view it's safer to access the
dirty registers by their index or offset relative to BSPSTORE, and
not by their absolute memory address, because their corresponding
memory address is unreal. I can change the backing store pointer
(i.e. BSPSTORE) and then flush the dirty registers. So, tying the
dirty registers to their would-be memory address seemed "wrong".
Hence, the offset is the offset relative to BSPSTORE.
However when the dirty registers need to be accessed as if they
were flushed, as needs to be done on Linux, then we need to know
to value of BSPSTORE so that we can map the relative offset to
an absolute memory location. For this reason I use the annex.
To support cross-debugging when gdb runs on a 32-bit host, I
cannot pass BSPSTORE by value (sizeof(void*) < sizeof(CORE_ADDR)).
So, I pass it by reference. Hence the indirection.
I couldn't think of a better way to do this without changing the
ptrace(2) implementation in FreeBSD. Mind you, I have no problem
changing the ptrace(2) in FreeBSD if that makes for a better
interface, but I cannot really create a generic ptrace(2)
interface that's tailored to the quirks of gdb and as such is
unusable or unnatural to use by any other application that needs
to use ptrace(2). It was a balancing act...
What I would really like to see in the end is to have the dirty
registers in the regcache. That way the interface to the target
becomes simpler. For core files we can fetch the entire note and
store its contents in the regcache. For ptrace(2) we get something
similar. The ptrace(2) interface on FreeBSD allows fetching and
storing dirty registers one by one. And it's easy to add a second
form that allows fetching them all at once.
There's just one slight problem: the number of dirty registers is
variable, but bounded. Unfortunately the upper bound is rather
high: 16383. This yields a worse-case memory footprint of 128KB :-/
(8 bytes per register and NaT collection).
I think that on average the number of dirty registers is something
like 128. I doesn't really look like a good idea to create the 128KB
of memory for the worst-case when 1KB would be sufficient on
avarage.
Oh, BTW: On HP-UX the dirty registers are in the ucontext, so for
HP-UX it's also required to make the distinction and as far as I
can tell, the way TARGET_OBJECT_DIRTY currently works also works
well for HP-UX. This can be beneficial if someone eventually ports
(the one true) gdb to HP-UX.
>> From your description abov it sounds like these ought to be in their
> own core file note anyway; why have they ended up in "memory"?
That's currently how Linux works and it's also currently how FreeBSD
creates the core files. Linux cannot do it any other way, because it's
all abstracted by the kernel on live processes and if gdb doesn't know
the difference between flushed and dirty stacked registers, you cannot
dump the dirty stacked registers to a core file anywhere else then where
they would be when they were flushed.
On FreeBSD the note isn't yet created because that requires a bit of
work and we had the plans to revamp the core file notes anyway (due
to threading). So, I decided to first get the port contributed and
then work on how best to deal with the dirty stacked registers. This
then could be part of a larger (cross-platform) revamp of how FreeBSD
creates core files, which would also result in a rather large set of
changes to binutils.
Anyway: since some targets work with the abstraction, there need to
be a couple places where accessing dirty registers need to be mapped
to memory references. This may change in the future.
>>> You have a lot of non-GNUish formatting issues - mostly the pesky
>>> spacing rules.
>>
>> No doubt. I'm not used to the GNU formatting :-)
>
> You did better than most people not used to it can manage :-)
Thanks!
--
Marcel Moolenaar USPA: A-39004 marcel@xcllnt.net
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] New port: ia64-*-freebsd
2005-07-15 18:20 ` Marcel Moolenaar
@ 2005-07-24 21:26 ` Daniel Jacobowitz
2005-07-25 17:32 ` Marcel Moolenaar
0 siblings, 1 reply; 12+ messages in thread
From: Daniel Jacobowitz @ 2005-07-24 21:26 UTC (permalink / raw)
To: Marcel Moolenaar; +Cc: gdb-patches
On Fri, Jul 15, 2005 at 11:20:46AM -0700, Marcel Moolenaar wrote:
> On Jul 14, 2005, at 7:16 PM, Daniel Jacobowitz wrote:
> >So, it treats the annex as a memory pointer and returns the contents of
> >memory there. Why? And why is this a useful generic implementation?
>
> Yeah, that's a bit tricky. Here's why:
>
> The stacked registers that are flushed, live in memory below the
> address pointed to by the BSPSTORE register. The stacked registers
> that are dirty would be flushed to memory between the values of
> BSPSTORE (bottom) and BSP (top) if and when they are being flushed.
Unless there isn't room, right? That's where I get confused. How is
the data in the core file mapped onto the memory space?
> I figured that from an API point of view it's safer to access the
> dirty registers by their index or offset relative to BSPSTORE, and
> not by their absolute memory address, because their corresponding
> memory address is unreal. I can change the backing store pointer
> (i.e. BSPSTORE) and then flush the dirty registers. So, tying the
> dirty registers to their would-be memory address seemed "wrong".
> Hence, the offset is the offset relative to BSPSTORE.
Sure... though documentation of this would be good.
> However when the dirty registers need to be accessed as if they
> were flushed, as needs to be done on Linux, then we need to know
> to value of BSPSTORE so that we can map the relative offset to
> an absolute memory location. For this reason I use the annex.
> To support cross-debugging when gdb runs on a 32-bit host, I
> cannot pass BSPSTORE by value (sizeof(void*) < sizeof(CORE_ADDR)).
> So, I pass it by reference. Hence the indirection.
This does not seem like anything that needs or wants a generic
implementation. I think we will need to arrange for the target to
override and augment the core file operations, so that this can be in
an ia64-specific file - probably, an ia64-linux or ia64-freebsd (it's
not clear to me which from your description) specific file.
> There's just one slight problem: the number of dirty registers is
> variable, but bounded. Unfortunately the upper bound is rather
> high: 16383. This yields a worse-case memory footprint of 128KB :-/
> (8 bytes per register and NaT collection).
> I think that on average the number of dirty registers is something
> like 128. I doesn't really look like a good idea to create the 128KB
> of memory for the worst-case when 1KB would be sufficient on
> avarage.
This I know how to handle; it hasn't been implemented yet, but the
optional/target-available registers interface will allow you to create
the necessary number of dirty registers in the regcache. I'm not sure
I agree that they belong there, but I don't know enough about it to
judge.
> >>From your description abov it sounds like these ought to be in their
> >own core file note anyway; why have they ended up in "memory"?
>
> That's currently how Linux works and it's also currently how FreeBSD
> creates the core files. Linux cannot do it any other way, because it's
> all abstracted by the kernel on live processes and if gdb doesn't know
> the difference between flushed and dirty stacked registers, you cannot
> dump the dirty stacked registers to a core file anywhere else then where
> they would be when they were flushed.
>
> On FreeBSD the note isn't yet created because that requires a bit of
> work and we had the plans to revamp the core file notes anyway (due
> to threading). So, I decided to first get the port contributed and
> then work on how best to deal with the dirty stacked registers. This
> then could be part of a larger (cross-platform) revamp of how FreeBSD
> creates core files, which would also result in a rather large set of
> changes to binutils.
>
> Anyway: since some targets work with the abstraction, there need to
> be a couple places where accessing dirty registers need to be mapped
> to memory references. This may change in the future.
Except FreeBSD, it sounds like, supports cases where they couldn't be
mapped unambiguously to memory.
I really recommend fixing your notes first and not making GDB support
this scheme.
Anyway, that's enough out of me. I'll leave the rest to Mark and the
ia64 maintainers.
--
Daniel Jacobowitz
CodeSourcery, LLC
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] New port: ia64-*-freebsd
2005-07-24 21:26 ` Daniel Jacobowitz
@ 2005-07-25 17:32 ` Marcel Moolenaar
2005-07-25 17:36 ` Daniel Jacobowitz
0 siblings, 1 reply; 12+ messages in thread
From: Marcel Moolenaar @ 2005-07-25 17:32 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Jul 24, 2005, at 2:26 PM, Daniel Jacobowitz wrote:
> On Fri, Jul 15, 2005 at 11:20:46AM -0700, Marcel Moolenaar wrote:
>> On Jul 14, 2005, at 7:16 PM, Daniel Jacobowitz wrote:
>>> So, it treats the annex as a memory pointer and returns the contents
>>> of
>>> memory there. Why? And why is this a useful generic implementation?
>>
>> Yeah, that's a bit tricky. Here's why:
>>
>> The stacked registers that are flushed, live in memory below the
>> address pointed to by the BSPSTORE register. The stacked registers
>> that are dirty would be flushed to memory between the values of
>> BSPSTORE (bottom) and BSP (top) if and when they are being flushed.
>
> Unless there isn't room, right?
Exactly. It is possible and not just academic for multi-threaded
applications to run out of backing store (e.g. by running into a
guard page or something along those lines). There's no way for
the processor to flush the dirty stacked registers if such is
needed and it would not be possible for the kernel to write them
out onto the backing store when creating a core dump.
> That's where I get confused. How is
> the data in the core file mapped onto the memory space?
I'm not quite sure I get your drift. Let me just answer what I think
you mean:
The backing store is nothing more than a second stack. The first being
the well-known memory stack onto which (stacked) local variables live.
The backing store grows upwards and the memory stack grows downwards.
So, in essence, it's a mmap'd region. Either created by the kernel when
the process is created, or created by the threading implementation.
In the core file the backing store is part of some loadable segment.
Either by itself or part of a larger block of memory.
>
>> I figured that from an API point of view it's safer to access the
>> dirty registers by their index or offset relative to BSPSTORE, and
>> not by their absolute memory address, because their corresponding
>> memory address is unreal. I can change the backing store pointer
>> (i.e. BSPSTORE) and then flush the dirty registers. So, tying the
>> dirty registers to their would-be memory address seemed "wrong".
>> Hence, the offset is the offset relative to BSPSTORE.
>
> Sure... though documentation of this would be good.
Agreed.
>> However when the dirty registers need to be accessed as if they
>> were flushed, as needs to be done on Linux, then we need to know
>> to value of BSPSTORE so that we can map the relative offset to
>> an absolute memory location. For this reason I use the annex.
>> To support cross-debugging when gdb runs on a 32-bit host, I
>> cannot pass BSPSTORE by value (sizeof(void*) < sizeof(CORE_ADDR)).
>> So, I pass it by reference. Hence the indirection.
>
> This does not seem like anything that needs or wants a generic
> implementation. I think we will need to arrange for the target to
> override and augment the core file operations, so that this can be in
> an ia64-specific file - probably, an ia64-linux or ia64-freebsd (it's
> not clear to me which from your description) specific file.
It's not just the core file operation that needs augmenting. In theory
and practice all targets (ptrace, core, remote, etc) will need this.
That's why I figured that a new target object would be acceptable.
>> There's just one slight problem: the number of dirty registers is
>> variable, but bounded. Unfortunately the upper bound is rather
>> high: 16383. This yields a worse-case memory footprint of 128KB :-/
>> (8 bytes per register and NaT collection).
>> I think that on average the number of dirty registers is something
>> like 128. I doesn't really look like a good idea to create the 128KB
>> of memory for the worst-case when 1KB would be sufficient on
>> avarage.
>
> This I know how to handle; it hasn't been implemented yet, but the
> optional/target-available registers interface will allow you to create
> the necessary number of dirty registers in the regcache. I'm not sure
> I agree that they belong there, but I don't know enough about it to
> judge.
Just FYI: I made a mistake. The number of dirty registers is not
expressed in register count, but in the amount of bytes they
occupy. This means that the amount of storage required to hold all
possible dirty stacked registers is 16KB (or 2048 registers and NaT
collections). This isn't nearly as bad a 128KB.
Sorry for the confusion.
>>>> From your description abov it sounds like these ought to be in their
>>> own core file note anyway; why have they ended up in "memory"?
>>
>> That's currently how Linux works and it's also currently how FreeBSD
>> creates the core files. Linux cannot do it any other way, because it's
>> all abstracted by the kernel on live processes and if gdb doesn't know
>> the difference between flushed and dirty stacked registers, you cannot
>> dump the dirty stacked registers to a core file anywhere else then
>> where
>> they would be when they were flushed.
>>
>> On FreeBSD the note isn't yet created because that requires a bit of
>> work and we had the plans to revamp the core file notes anyway (due
>> to threading). So, I decided to first get the port contributed and
>> then work on how best to deal with the dirty stacked registers. This
>> then could be part of a larger (cross-platform) revamp of how FreeBSD
>> creates core files, which would also result in a rather large set of
>> changes to binutils.
>>
>> Anyway: since some targets work with the abstraction, there need to
>> be a couple places where accessing dirty registers need to be mapped
>> to memory references. This may change in the future.
>
> Except FreeBSD, it sounds like, supports cases where they couldn't be
> mapped unambiguously to memory.
Correct.
> I really recommend fixing your notes first and not making GDB support
> this scheme.
I've thought about it. The point is that GDB already needs to support it
for Linux, so splitting up the work in such a way that FreeBSD
temporarily
has the same "limitations" as Linux seemed ideal. Not only is it
possible
to improve the overall core file support in FreeBSD, it also allows
Linux
to move away from the abstraction. In that sense, the abstraction is
gradually moved out of GDB. And as for any interim solution: there is
bound
to be some icky code for a while.
All I can say is that I'll think about it: The FreeBSD release schedule
is
now in my advantage, but getting binutils to grok a whole new kind of
core
notes may by itself turn out to be... euh... challenging... :-)
> Anyway, that's enough out of me. I'll leave the rest to Mark and the
> ia64 maintainers.
Thanks for comments. I appreciated it.
--
Marcel Moolenaar USPA: A-39004 marcel@xcllnt.net
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] New port: ia64-*-freebsd
2005-07-25 17:32 ` Marcel Moolenaar
@ 2005-07-25 17:36 ` Daniel Jacobowitz
2005-07-25 17:58 ` Marcel Moolenaar
0 siblings, 1 reply; 12+ messages in thread
From: Daniel Jacobowitz @ 2005-07-25 17:36 UTC (permalink / raw)
To: Marcel Moolenaar; +Cc: gdb-patches
On Mon, Jul 25, 2005 at 10:32:27AM -0700, Marcel Moolenaar wrote:
> > That's where I get confused. How is
> >the data in the core file mapped onto the memory space?
>
> I'm not quite sure I get your drift. Let me just answer what I think
> you mean:
>
> The backing store is nothing more than a second stack. The first being
> the well-known memory stack onto which (stacked) local variables live.
> The backing store grows upwards and the memory stack grows downwards.
> So, in essence, it's a mmap'd region. Either created by the kernel when
> the process is created, or created by the threading implementation.
> In the core file the backing store is part of some loadable segment.
> Either by itself or part of a larger block of memory.
No, that's not what I mean.
Here and further below you think I'm talking about the concept of the
target object. I'm not. I'm talking specifically about the corefile
implementation you included.
That implementation reads from an address in memory to find the
registers. If there's no room for them in memory, where the heck are
they, and how can you find them by reading from memory?
> >I really recommend fixing your notes first and not making GDB support
> >this scheme.
>
> I've thought about it. The point is that GDB already needs to support it
> for Linux, so splitting up the work in such a way that FreeBSD
> temporarily
> has the same "limitations" as Linux seemed ideal. Not only is it
> possible
> to improve the overall core file support in FreeBSD, it also allows
> Linux
> to move away from the abstraction. In that sense, the abstraction is
> gradually moved out of GDB. And as for any interim solution: there is
> bound
> to be some icky code for a while.
So the answer to my above question is "you can't yet"?
> All I can say is that I'll think about it: The FreeBSD release schedule
> is
> now in my advantage, but getting binutils to grok a whole new kind of
> core
> notes may by itself turn out to be... euh... challenging... :-)
Actually it's quite easy.
--
Daniel Jacobowitz
CodeSourcery, LLC
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] New port: ia64-*-freebsd
2005-07-25 17:36 ` Daniel Jacobowitz
@ 2005-07-25 17:58 ` Marcel Moolenaar
2005-07-25 19:34 ` Mark Kettenis
0 siblings, 1 reply; 12+ messages in thread
From: Marcel Moolenaar @ 2005-07-25 17:58 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Jul 25, 2005, at 10:35 AM, Daniel Jacobowitz wrote:
> On Mon, Jul 25, 2005 at 10:32:27AM -0700, Marcel Moolenaar wrote:
>>> That's where I get confused. How is
>>> the data in the core file mapped onto the memory space?
>>
>> I'm not quite sure I get your drift. Let me just answer what I think
>> you mean:
>>
>> The backing store is nothing more than a second stack. The first being
>> the well-known memory stack onto which (stacked) local variables live.
>> The backing store grows upwards and the memory stack grows downwards.
>> So, in essence, it's a mmap'd region. Either created by the kernel
>> when
>> the process is created, or created by the threading implementation.
>> In the core file the backing store is part of some loadable segment.
>> Either by itself or part of a larger block of memory.
>
> No, that's not what I mean.
>
> Here and further below you think I'm talking about the concept of the
> target object. I'm not. I'm talking specifically about the corefile
> implementation you included.
>
> That implementation reads from an address in memory to find the
> registers. If there's no room for them in memory, where the heck are
> they, and how can you find them by reading from memory?
They're lost. If the core file is created because the process ran out
of backing store, then you're pretty much hosed. There's no way you
can get a stack trace because the stacked registers you'll need first
are the dirty ones and those aren't in the core file. This is the
fundamental problem that Linux has.
>>> I really recommend fixing your notes first and not making GDB support
>>> this scheme.
>>
>> I've thought about it. The point is that GDB already needs to support
>> it
>> for Linux, so splitting up the work in such a way that FreeBSD
>> temporarily
>> has the same "limitations" as Linux seemed ideal. Not only is it
>> possible
>> to improve the overall core file support in FreeBSD, it also allows
>> Linux
>> to move away from the abstraction. In that sense, the abstraction is
>> gradually moved out of GDB. And as for any interim solution: there is
>> bound
>> to be some icky code for a while.
>
> So the answer to my above question is "you can't yet"?
Correct.
>> All I can say is that I'll think about it: The FreeBSD release
>> schedule
>> is
>> now in my advantage, but getting binutils to grok a whole new kind of
>> core
>> notes may by itself turn out to be... euh... challenging... :-)
>
> Actually it's quite easy.
Challenge extended...
... Challenge accepted :-)
"I'll be back"
-- A. Schwarzenegger
--
Marcel Moolenaar USPA: A-39004 marcel@xcllnt.net
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] New port: ia64-*-freebsd
2005-07-25 17:58 ` Marcel Moolenaar
@ 2005-07-25 19:34 ` Mark Kettenis
2005-07-25 20:41 ` Marcel Moolenaar
0 siblings, 1 reply; 12+ messages in thread
From: Mark Kettenis @ 2005-07-25 19:34 UTC (permalink / raw)
To: marcel; +Cc: drow, gdb-patches
From: Marcel Moolenaar <marcel@cup.hp.com>
Date: Mon, 25 Jul 2005 10:58:30 -0700
On Jul 25, 2005, at 10:35 AM, Daniel Jacobowitz wrote:
> On Mon, Jul 25, 2005 at 10:32:27AM -0700, Marcel Moolenaar wrote:
>>> That's where I get confused. How is
>>> the data in the core file mapped onto the memory space?
>>
>> I'm not quite sure I get your drift. Let me just answer what I think
>> you mean:
>>
>> The backing store is nothing more than a second stack. The first being
>> the well-known memory stack onto which (stacked) local variables live.
>> The backing store grows upwards and the memory stack grows downwards.
>> So, in essence, it's a mmap'd region. Either created by the kernel
>> when
>> the process is created, or created by the threading implementation.
>> In the core file the backing store is part of some loadable segment.
>> Either by itself or part of a larger block of memory.
>
> No, that's not what I mean.
>
> Here and further below you think I'm talking about the concept of the
> target object. I'm not. I'm talking specifically about the corefile
> implementation you included.
>
> That implementation reads from an address in memory to find the
> registers. If there's no room for them in memory, where the heck are
> they, and how can you find them by reading from memory?
They're lost. If the core file is created because the process ran out
of backing store, then you're pretty much hosed. There's no way you
can get a stack trace because the stacked registers you'll need first
are the dirty ones and those aren't in the core file. This is the
fundamental problem that Linux has.
Damn, I'm somehow lost. Are we talking about Linux or FreeBSD here?
In any case it seems a rather nasty problem. It seems that the kernel
should somehow be able to realise it ran out of backing store, and
stick the stacked registers somewhere else in the core file. This is
what you had in mind for FreeBSD isn't it? Then, if GDB knew how to
find those dirty registers, it'd be able to do proper backtraces. But
then the user wouldn't be able to tell why the program crashed. It's
probably better to be able to provide a useful backtrace though.
>>> I really recommend fixing your notes first and not making GDB support
>>> this scheme.
>>
>> I've thought about it. The point is that GDB already needs to support
>> it
>> for Linux, so splitting up the work in such a way that FreeBSD
>> temporarily
>> has the same "limitations" as Linux seemed ideal. Not only is it
>> possible
>> to improve the overall core file support in FreeBSD, it also allows
>> Linux
>> to move away from the abstraction. In that sense, the abstraction is
>> gradually moved out of GDB. And as for any interim solution: there is
>> bound
>> to be some icky code for a while.
>
> So the answer to my above question is "you can't yet"?
Correct.
The proper way to push this out of GDB is (in my opinion) what I did
for StackGhost on OpenBSD/sparc. GDB expects to find a .wcookie
(psuedo-)section in the core file. Filling this section is the job of
platform-dependent code in BFD. For ELF core files the most logical
way would be to provide a note which is converted into that section by
BFD. That's how I would do it for .wcookie in ELF core files anyway.
But since OpenBSD still uses old NetBSD-style core files, this isn't
implemented yet. This whole approach is handled very similar to the
way normal register are handled in core files.
>> All I can say is that I'll think about it: The FreeBSD release
>> schedule
>> is
>> now in my advantage, but getting binutils to grok a whole new kind of
>> core
>> notes may by itself turn out to be... euh... challenging... :-)
>
> Actually it's quite easy.
Challenge extended...
... Challenge accepted :-)
I think the code that implements NetBSD core file handling is a good
example of how to do this.
Mark
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] New port: ia64-*-freebsd
2005-07-25 19:34 ` Mark Kettenis
@ 2005-07-25 20:41 ` Marcel Moolenaar
0 siblings, 0 replies; 12+ messages in thread
From: Marcel Moolenaar @ 2005-07-25 20:41 UTC (permalink / raw)
To: Mark Kettenis; +Cc: drow, gdb-patches
On Jul 25, 2005, at 12:31 PM, Mark Kettenis wrote:
> From: Marcel Moolenaar <marcel@cup.hp.com>
> Date: Mon, 25 Jul 2005 10:58:30 -0700
>
> On Jul 25, 2005, at 10:35 AM, Daniel Jacobowitz wrote:
>
>> On Mon, Jul 25, 2005 at 10:32:27AM -0700, Marcel Moolenaar wrote:
>>>> That's where I get confused. How is
>>>> the data in the core file mapped onto the memory space?
>>>
>>> I'm not quite sure I get your drift. Let me just answer what I think
>>> you mean:
>>>
>>> The backing store is nothing more than a second stack. The first
>>> being
>>> the well-known memory stack onto which (stacked) local variables
>>> live.
>>> The backing store grows upwards and the memory stack grows downwards.
>>> So, in essence, it's a mmap'd region. Either created by the kernel
>>> when
>>> the process is created, or created by the threading implementation.
>>> In the core file the backing store is part of some loadable segment.
>>> Either by itself or part of a larger block of memory.
>>
>> No, that's not what I mean.
>>
>> Here and further below you think I'm talking about the concept of the
>> target object. I'm not. I'm talking specifically about the corefile
>> implementation you included.
>>
>> That implementation reads from an address in memory to find the
>> registers. If there's no room for them in memory, where the heck are
>> they, and how can you find them by reading from memory?
>
> They're lost. If the core file is created because the process ran
> out
> of backing store, then you're pretty much hosed. There's no way you
> can get a stack trace because the stacked registers you'll need
> first
> are the dirty ones and those aren't in the core file. This is the
> fundamental problem that Linux has.
>
> Damn, I'm somehow lost. Are we talking about Linux or FreeBSD here?
Both. Currently the FreeBSD kernel "flushes" the dirty stacked registers
onto the backing store (i.e. writes it out to the process' memory before
the memory map is dumped) because there's no immediate support in the
toolchain (both binutils and gdb) for having them "out-of-band" in
notes.
This is a temporary measure until the toolchain has been enhanced. If
and
when the toolchain is enhanced, I'll fix the FreeBSD kernel and the
statements above will only apply to Linux.
> In any case it seems a rather nasty problem. It seems that the kernel
> should somehow be able to realise it ran out of backing store, and
> stick the stacked registers somewhere else in the core file. This is
> what you had in mind for FreeBSD isn't it?
Yes. Since we talked about revamping the core file notes prior to
FreeBSD 5.3, I did some swift finger-based arithmetic and came to
the conclusion that as a first implementation it would be acceptable
(for me :-) that this corner case would not be finished.
BTW, to get into details: I'll have the kernel dump the dirty stacked
registers in a note unconditionally. In other words, even if the core
dump doesn't seem to be caused by backing store overflow. The reason
for this is that even if the backing store could be written to, the
kernel may actually destroy valuable state. Think for example about a
multi-threaded application for which the memory stack grows down
towards the backing store and the register stack grows upwards to the
memory stack. Suppose also that the stacks are not protected from each
other by a guard page. Then, writing the dirty stacked registers may
cause the kernel to overwrite the memory stack even in the situation
that the running process did not overflow either stacks (due to the
lazy nature with which the processor flushes dirty registers).
Better safe than sorry...
> Then, if GDB knew how to
> find those dirty registers, it'd be able to do proper backtraces. But
> then the user wouldn't be able to tell why the program crashed. It's
> probably better to be able to provide a useful backtrace though.
Agreed. One can infer that a process dumped core due to an overflow of
the backing store. The faulting instruction would typically be the alloc
or flushrs instruction and the faulting address would typically be the
value of BSPSTORE and would typically point to the first byte of the
page
after the backing store itself (this last is probably not that easy to
figure out because one typically does not know the extend of the backing
store, nor can one fully trust that BSPSTORE points inside the backing
store). But other than that: there are some telltale signs.
*snip*
> The proper way to push this out of GDB is (in my opinion) what I did
> for StackGhost on OpenBSD/sparc. GDB expects to find a .wcookie
> (psuedo-)section in the core file. Filling this section is the job of
> platform-dependent code in BFD. For ELF core files the most logical
> way would be to provide a note which is converted into that section by
> BFD. That's how I would do it for .wcookie in ELF core files anyway.
> But since OpenBSD still uses old NetBSD-style core files, this isn't
> implemented yet. This whole approach is handled very similar to the
> way normal register are handled in core files.
Interesting. I'll keep that in mind. I don't know the details about
StackGhost, but it might be something to guide me.
>
>>> All I can say is that I'll think about it: The FreeBSD release
>>> schedule
>>> is
>>> now in my advantage, but getting binutils to grok a whole new kind of
>>> core
>>> notes may by itself turn out to be... euh... challenging... :-)
>>
>> Actually it's quite easy.
>
> Challenge extended...
>
> ... Challenge accepted :-)
>
> I think the code that implements NetBSD core file handling is a good
> example of how to do this.
Yes, you mentioned this before. There was just one problem I ran into:
The PID and LWPID are concatenated into a 32-bit integral and passed
on the GDB as the "pid". On FreeBSD this cannot be done, because
both PID and LWPID are already 32-bit by itself. As such, the BFD to
GDB interface for extracting the thread ID needs to be modified if
we want to do it right.
To be exact: elfcore_make_pid() in binutils/bfd/elf.c needs to be
fixed.
Anyway: let's not jump ahead. I haven't studied the code lately
and things may be much easier now or I may understand the code
better than before.
--
Marcel Moolenaar USPA: A-39004 marcel@xcllnt.net
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2005-07-25 20:41 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-07-05 19:52 [PATCH] New port: ia64-*-freebsd Marcel Moolenaar
2005-07-06 17:24 ` Followup: " Marcel Moolenaar
2005-07-15 0:01 ` Daniel Jacobowitz
2005-07-15 2:08 ` Marcel Moolenaar
2005-07-15 2:16 ` Daniel Jacobowitz
2005-07-15 18:20 ` Marcel Moolenaar
2005-07-24 21:26 ` Daniel Jacobowitz
2005-07-25 17:32 ` Marcel Moolenaar
2005-07-25 17:36 ` Daniel Jacobowitz
2005-07-25 17:58 ` Marcel Moolenaar
2005-07-25 19:34 ` Mark Kettenis
2005-07-25 20:41 ` Marcel Moolenaar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox