From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12052 invoked by alias); 12 Aug 2004 23:39:19 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 12017 invoked from network); 12 Aug 2004 23:39:15 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org with SMTP; 12 Aug 2004 23:39:15 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i7CNdEe1029198 for ; Thu, 12 Aug 2004 19:39:14 -0400 Received: from zenia.home.redhat.com (porkchop.devel.redhat.com [172.16.58.2]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i7CNd7a06724; Thu, 12 Aug 2004 19:39:08 -0400 To: gdb-patches@sources.redhat.com Subject: RFA: Support libthread_db xregs interface From: Jim Blandy Date: Thu, 12 Aug 2004 23:39:00 -0000 Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2004-08/txt/msg00477.txt.bz2 This patch adds support to GDB for the libthread_db 'xregs' functions, which allow registers not present in 'gregset_t' or 'fpregset_t' to be passed through libthread_db. The contents of the 'xregs' register set is not specified by GDB; the libthread_db client can specify whatever size it likes, and libthread_db will pass it through unchanged. I'll post a second patch which defines an 'xregs' register set for the PowerPC E500 SPE registers. At present, the GNU C library's libthread_db's xregs functions are stubbed out; I also have a patch to glibc to implement them, which I'll be submitting. If GDB loads a libthread_db that does not implement the xregs functions, this patch handles that case. These have all been tested on E500 powerpc-unknown-linux-gnu and on i686-pc-linux-gnu (where they should have no effect). This patch should allow us to remove the call to dummy_sse_values in supply_fpregset. Not that that call is especially necessary or helpful at the moment anyway, as far as I can tell. This patch was originally posted here: http://sources.redhat.com/ml/gdb-patches/2004-03/msg00571.html I believe it's been revised to implement the suggestions made there. This is kind of a weird case. This patch and the E500 xregs patch have no effect on GDB's visible behavior (other than producing a warning message (once) when the architecture needs xregs but libthread_db doesn't implement the xregs functions). Using a patched libthread_db, it is impossible to write a test that detects its presence. So what's the point? Well, if the gdb_assert in regcache.c:regcache_raw_read were enabled, then you'd definitely be able to detect its presence: without the patch, that assertion would fail, because the call to target_fetch_registers does not mark the SPE vector registers as supplied. The data is there, given the way proc-service.c works, but the register contents are marked 'invalid'. But we've found that there's a lot of other work that needs to be done before that assertion can be enabled. The sloppiness that this patch is meant to work around is pretty endemic amongst GDB targets at the moment. So the argument against this patch is that it introduces complexity with no visible effect. The argument for this patch is that it is a step towards being able to enable that assert. But it's been suggested that we not use libthread_db's register access functions to carry register values at all. If that's pursued, then again, this patch is unnecessary. What do folks think? 2004-06-07 Jim Blandy Allow targets to specify an extended register set, to be passed through libthread_db via its 'xregs' functions. * gdbarch.sh (XREGS_REGSET, XREGS_SIZE, XREGS_NAME): New gdbarch members. * gdbarch.c, gdbarch.h: Regenerated. * proc-service.c: #include "regset.h" and "regcache.h". (ps_lgetxregsize, ps_lgetxregs, ps_lsetxregs): Fill in real implementations of these functions. * thread-db.c: #include "regset.h". (td_thr_getxregsize_p, td_thr_getxregs_p, td_thr_setxregs_p): New variables. (thread_db_load): Initialize them. (warned_xregs_not_implemented): New variable. (thread_db_new_objfile): Clear it here. (thread_db_fetch_registers, thread_db_store_registers): Supply and collect the xregset, too, if the architecture says it has one, and libthread_db seems to be able to support it. * Makefile.in (proc-service.o, thread-db.o): Update dependencies. Index: gdb/gdbarch.sh =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.sh,v retrieving revision 1.345 diff -c -p -r1.345 gdbarch.sh *** gdb/gdbarch.sh 8 Aug 2004 20:50:57 -0000 1.345 --- gdb/gdbarch.sh 12 Aug 2004 22:07:57 -0000 *************** F:=:CORE_ADDR:fetch_pointer_argument:str *** 664,669 **** --- 664,699 ---- # Return the appropriate register set for a core file section with # name SECT_NAME and size SECT_SIZE. M::const struct regset *:regset_from_core_section:const char *sect_name, size_t sect_size:sect_name, sect_size + + # The libthread_db interface passes registers in and out using the same + # structures that appear in core files: gregset_t and fpregset_t. + # Whether reading or writing: + # - GDB first moves data out of the regcache into a struct (using + # fill_gregset or fill_fpregset), + # - crosses the thread_db boundary (for writing, calls + # td_thr_setregs; for reading, returns from td_thr_getregs), and + # - moves the data from the struct back into the regcache (using + # supply_gregset or supply_fpregset). + # + # Some platforms define even more register sets; for example, + # members of the PowerPC family supporting the Signal Processing + # Extension ("SPE") have 'struct speregset'. These need to be passed + # back and forth across the thread_db boundary. + # + # An architecture that has such a register set should: + # - choose a structure to hold the extra registers, + # - set gdbarch_xregs_regset to a 'struct regset' that can move register + # values into and out of that structure, + # - set gdbarch_xregs_size to the structure's size, in bytes, and + # - set gdbarch_xregs_name to a string that can be used to refer to the + # structure in error messages and the like. + # + # Architectures without such a register set should leave + # gdbarch_xregs_regset set to zero. + v:=:const struct regset *:xregs_regset:::0 + v:=:int:xregs_size:::0 + v:=:const char *:xregs_name:::0 + EOF } Index: gdb/gdbarch.c =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.c,v retrieving revision 1.310 diff -c -p -r1.310 gdbarch.c *** gdb/gdbarch.c 8 Aug 2004 19:49:40 -0000 1.310 --- gdb/gdbarch.c 12 Aug 2004 22:07:55 -0000 *************** struct gdbarch *** 229,234 **** --- 229,237 ---- gdbarch_register_reggroup_p_ftype *register_reggroup_p; gdbarch_fetch_pointer_argument_ftype *fetch_pointer_argument; gdbarch_regset_from_core_section_ftype *regset_from_core_section; + const struct regset * xregs_regset; + int xregs_size; + const char * xregs_name; }; *************** struct gdbarch startup_gdbarch = *** 355,360 **** --- 358,366 ---- default_register_reggroup_p, /* register_reggroup_p */ 0, /* fetch_pointer_argument */ 0, /* regset_from_core_section */ + 0, /* xregs_regset */ + 0, /* xregs_size */ + 0, /* xregs_name */ /* startup_gdbarch() */ }; *************** gdbarch_dump (struct gdbarch *current_gd *** 1625,1630 **** --- 1631,1660 ---- fprintf_unfiltered (file, "gdbarch_dump: write_pc = <0x%lx>\n", (long) current_gdbarch->write_pc); + #ifdef XREGS_NAME + fprintf_unfiltered (file, + "gdbarch_dump: XREGS_NAME # %s\n", + XSTRING (XREGS_NAME)); + #endif + fprintf_unfiltered (file, + "gdbarch_dump: xregs_name = %s\n", + paddr_d (current_gdbarch->xregs_name)); + #ifdef XREGS_REGSET + fprintf_unfiltered (file, + "gdbarch_dump: XREGS_REGSET # %s\n", + XSTRING (XREGS_REGSET)); + #endif + fprintf_unfiltered (file, + "gdbarch_dump: xregs_regset = %s\n", + paddr_d (current_gdbarch->xregs_regset)); + #ifdef XREGS_SIZE + fprintf_unfiltered (file, + "gdbarch_dump: XREGS_SIZE # %s\n", + XSTRING (XREGS_SIZE)); + #endif + fprintf_unfiltered (file, + "gdbarch_dump: xregs_size = %s\n", + paddr_d (current_gdbarch->xregs_size)); if (current_gdbarch->dump_tdep != NULL) current_gdbarch->dump_tdep (current_gdbarch, file); } *************** set_gdbarch_regset_from_core_section (st *** 3673,3678 **** --- 3703,3756 ---- gdbarch->regset_from_core_section = regset_from_core_section; } + const struct regset * + gdbarch_xregs_regset (struct gdbarch *gdbarch) + { + gdb_assert (gdbarch != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_xregs_regset called\n"); + return gdbarch->xregs_regset; + } + + void + set_gdbarch_xregs_regset (struct gdbarch *gdbarch, + const struct regset * xregs_regset) + { + gdbarch->xregs_regset = xregs_regset; + } + + int + gdbarch_xregs_size (struct gdbarch *gdbarch) + { + gdb_assert (gdbarch != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_xregs_size called\n"); + return gdbarch->xregs_size; + } + + void + set_gdbarch_xregs_size (struct gdbarch *gdbarch, + int xregs_size) + { + gdbarch->xregs_size = xregs_size; + } + + const char * + gdbarch_xregs_name (struct gdbarch *gdbarch) + { + gdb_assert (gdbarch != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_xregs_name called\n"); + return gdbarch->xregs_name; + } + + void + set_gdbarch_xregs_name (struct gdbarch *gdbarch, + const char * xregs_name) + { + gdbarch->xregs_name = xregs_name; + } + /* Keep a registry of per-architecture data-pointers required by GDB modules. */ Index: gdb/gdbarch.h =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.h,v retrieving revision 1.272 diff -c -p -r1.272 gdbarch.h *** gdb/gdbarch.h 8 Aug 2004 20:50:57 -0000 1.272 --- gdb/gdbarch.h 12 Aug 2004 22:07:56 -0000 *************** typedef const struct regset * (gdbarch_r *** 1435,1440 **** --- 1435,1493 ---- extern const struct regset * gdbarch_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name, size_t sect_size); extern void set_gdbarch_regset_from_core_section (struct gdbarch *gdbarch, gdbarch_regset_from_core_section_ftype *regset_from_core_section); + /* The libthread_db interface passes registers in and out using the same + structures that appear in core files: gregset_t and fpregset_t. + Whether reading or writing: + - GDB first moves data out of the regcache into a struct (using + fill_gregset or fill_fpregset), + - crosses the thread_db boundary (for writing, calls + td_thr_setregs; for reading, returns from td_thr_getregs), and + - moves the data from the struct back into the regcache (using + supply_gregset or supply_fpregset). + + Some platforms define even more register sets; for example, + members of the PowerPC family supporting the Signal Processing + Extension ("SPE") have 'struct speregset'. These need to be passed + back and forth across the thread_db boundary. + + An architecture that has such a register set should: + - choose a structure to hold the extra registers, + - set gdbarch_xregs_regset to a 'struct regset' that can move register + values into and out of that structure, + - set gdbarch_xregs_size to the structure's size, in bytes, and + - set gdbarch_xregs_name to a string that can be used to refer to the + structure in error messages and the like. + + Architectures without such a register set should leave + gdbarch_xregs_regset set to zero. */ + + extern const struct regset * gdbarch_xregs_regset (struct gdbarch *gdbarch); + extern void set_gdbarch_xregs_regset (struct gdbarch *gdbarch, const struct regset * xregs_regset); + #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (XREGS_REGSET) + #error "Non multi-arch definition of XREGS_REGSET" + #endif + #if !defined (XREGS_REGSET) + #define XREGS_REGSET (gdbarch_xregs_regset (current_gdbarch)) + #endif + + extern int gdbarch_xregs_size (struct gdbarch *gdbarch); + extern void set_gdbarch_xregs_size (struct gdbarch *gdbarch, int xregs_size); + #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (XREGS_SIZE) + #error "Non multi-arch definition of XREGS_SIZE" + #endif + #if !defined (XREGS_SIZE) + #define XREGS_SIZE (gdbarch_xregs_size (current_gdbarch)) + #endif + + extern const char * gdbarch_xregs_name (struct gdbarch *gdbarch); + extern void set_gdbarch_xregs_name (struct gdbarch *gdbarch, const char * xregs_name); + #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (XREGS_NAME) + #error "Non multi-arch definition of XREGS_NAME" + #endif + #if !defined (XREGS_NAME) + #define XREGS_NAME (gdbarch_xregs_name (current_gdbarch)) + #endif + extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch); Index: gdb/proc-service.c =================================================================== RCS file: /cvs/src/src/gdb/proc-service.c,v retrieving revision 1.7 diff -c -p -r1.7 proc-service.c *** gdb/proc-service.c 24 Feb 2002 22:31:19 -0000 1.7 --- gdb/proc-service.c 12 Aug 2004 22:07:58 -0000 *************** *** 27,32 **** --- 27,34 ---- #include "inferior.h" #include "symtab.h" #include "target.h" + #include "regset.h" + #include "regcache.h" /* Prototypes for supply_gregset etc. */ #include "gregset.h" *************** ps_lcontinue (gdb_ps_prochandle_t ph, lw *** 131,137 **** ps_err_e ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize) { ! /* FIXME: Not supported yet. */ return PS_OK; } --- 133,143 ---- ps_err_e ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize) { ! if (! gdbarch_xregs_regset (current_gdbarch)) ! /* This architecture has no extra registers. */ ! return PS_ERR; ! ! *xregsize = gdbarch_xregs_size (current_gdbarch); return PS_OK; } *************** ps_lgetxregsize (gdb_ps_prochandle_t ph, *** 141,147 **** ps_err_e ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset) { ! /* FIXME: Not supported yet. */ return PS_OK; } --- 147,167 ---- ps_err_e ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset) { ! struct cleanup *old_chain = save_inferior_ptid (); ! struct regset *xregs_regset = gdbarch_xregs_regset (current_gdbarch); ! ! if (! xregs_regset) ! /* This target has no extra registers. */ ! return PS_OK; ! ! inferior_ptid = BUILD_LWP (lwpid, ph->pid); ! ! target_fetch_registers (-1); ! xregs_regset->collect_regset (xregs_regset, current_regcache, -1, ! (void *) xregset, ! gdbarch_xregs_size (current_gdbarch)); ! ! do_cleanups (old_chain); return PS_OK; } *************** ps_lgetxregs (gdb_ps_prochandle_t ph, lw *** 151,157 **** ps_err_e ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset) { ! /* FIXME: Not supported yet. */ return PS_OK; } --- 171,193 ---- ps_err_e ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset) { ! struct cleanup *old_chain = save_inferior_ptid (); ! struct regset *xregs_regset = gdbarch_xregs_regset (current_gdbarch); ! ! if (! xregs_regset) ! /* This architecture has no extended register set. */ ! return PS_OK; ! ! inferior_ptid = BUILD_LWP (lwpid, ph->pid); ! ! xregs_regset->supply_regset (xregs_regset, current_regcache, -1, ! (void *) xregset, ! gdbarch_xregs_size (current_gdbarch)); ! ! target_store_registers (-1); ! ! do_cleanups (old_chain); ! return PS_OK; } Index: gdb/thread-db.c =================================================================== RCS file: /cvs/src/src/gdb/thread-db.c,v retrieving revision 1.43 diff -c -p -r1.43 thread-db.c *** gdb/thread-db.c 22 Jul 2004 01:31:49 -0000 1.43 --- gdb/thread-db.c 12 Aug 2004 22:07:59 -0000 *************** *** 32,37 **** --- 32,38 ---- #include "symfile.h" #include "objfiles.h" #include "target.h" + #include "regset.h" #include "regcache.h" #include "solib-svr4.h" *************** static td_err_e (*td_ta_event_getmsg_p) *** 105,118 **** --- 106,125 ---- static td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th); static td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th, td_thrinfo_t *infop); + static td_err_e (*td_thr_getxregsize_p) (const td_thrhandle_t *__th, + int *__sizep); static td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th, gdb_prfpregset_t *regset); static td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th, prgregset_t gregs); + static td_err_e (*td_thr_getxregs_p) (const td_thrhandle_t *__th, + void *__xregs); static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th, const gdb_prfpregset_t *fpregs); static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th, prgregset_t gregs); + static td_err_e (*td_thr_setxregs_p) (const td_thrhandle_t *__th, + const void *__addr); static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, int event); *************** static CORE_ADDR td_create_bp_addr; *** 130,135 **** --- 137,150 ---- /* Location of the thread death event breakpoint. */ static CORE_ADDR td_death_bp_addr; + /* On some architectures, there are additional regs beyond the gregset + and fpregset. The libthread_db interface has functions to access + these, but on some versions of libthread_db they are not + implemented. We want to warn the user about this, but not treat it + as a fatal error, since you can still access the other + registers. */ + static int warned_xregs_not_implemented; + /* Prototypes for local functions. */ static void thread_db_find_new_threads (void); static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p, *************** thread_db_load (void) *** 470,475 **** --- 485,494 ---- if (td_thr_get_info_p == NULL) return 0; + td_thr_getxregsize_p = verbose_dlsym (handle, "td_thr_getxregsize"); + if (td_thr_getxregsize_p == NULL) + return 0; + td_thr_getfpregs_p = verbose_dlsym (handle, "td_thr_getfpregs"); if (td_thr_getfpregs_p == NULL) return 0; *************** thread_db_load (void) *** 478,483 **** --- 497,506 ---- if (td_thr_getgregs_p == NULL) return 0; + td_thr_getxregs_p = verbose_dlsym (handle, "td_thr_getxregs"); + if (td_thr_getxregs_p == NULL) + return 0; + td_thr_setfpregs_p = verbose_dlsym (handle, "td_thr_setfpregs"); if (td_thr_setfpregs_p == NULL) return 0; *************** thread_db_load (void) *** 486,491 **** --- 509,518 ---- if (td_thr_setgregs_p == NULL) return 0; + td_thr_setxregs_p = verbose_dlsym (handle, "td_thr_setxregs"); + if (td_thr_setxregs_p == NULL) + return 0; + /* Initialize the library. */ err = td_init_p (); if (err != TD_OK) *************** thread_db_new_objfile (struct objfile *o *** 703,708 **** --- 730,740 ---- push_target (&thread_db_ops); using_thread_db = 1; + /* If the gdbarch says we have an extended register set, but we are + unable to access them via libthread_db, we want to issue one + warning each time we active libthread_db. */ + warned_xregs_not_implemented = 0; + /* If the thread library was detected in the main symbol file itself, we assume that the program was statically linked against the thread library and well have to keep this *************** thread_db_fetch_registers (int regno) *** 1024,1029 **** --- 1056,1064 ---- struct thread_info *thread_info; prgregset_t gregset; gdb_prfpregset_t fpregset; + void *xregs = 0; + int fetched_xregs = 0; + struct regset *xregs_regset = gdbarch_xregs_regset (current_gdbarch); td_err_e err; if (!is_thread (inferior_ptid)) *************** thread_db_fetch_registers (int regno) *** 1036,1041 **** --- 1071,1079 ---- thread_info = find_thread_pid (inferior_ptid); thread_db_map_id2thr (thread_info, 1); + if (xregs_regset) + xregs = alloca (gdbarch_xregs_size (current_gdbarch)); + err = td_thr_getgregs_p (&thread_info->private->th, gregset); if (err != TD_OK) error ("Cannot fetch general-purpose registers for thread %ld: %s", *************** thread_db_fetch_registers (int regno) *** 1046,1056 **** --- 1084,1124 ---- error ("Cannot get floating-point registers for thread %ld: %s", (long) GET_THREAD (inferior_ptid), thread_db_err_str (err)); + if (xregs_regset) + { + err = td_thr_getxregs_p (&thread_info->private->th, xregs); + switch (err) + { + case TD_OK: + fetched_xregs = 1; + break; + + case TD_NOXREGS: + if (! warned_xregs_not_implemented) + { + warning ("thread debugging library is too old to access " + "%s registers.", + gdbarch_xregs_name (current_gdbarch)); + warned_xregs_not_implemented = 1; + } + break; + + default: + error ("Cannot get %s registers for thread %ld: %s", + gdbarch_xregs_name (current_gdbarch), + (long) GET_THREAD (inferior_ptid), thread_db_err_str (err)); + } + } + /* Note that we must call supply_gregset after calling the thread_db routines because the thread_db routines call ps_lgetgregs and friends which clobber GDB's register cache. */ supply_gregset ((gdb_gregset_t *) gregset); supply_fpregset (&fpregset); + + if (fetched_xregs) + xregs_regset->supply_regset (xregs_regset, current_regcache, -1, xregs, + gdbarch_xregs_size (current_gdbarch)); } static void *************** thread_db_store_registers (int regno) *** 1058,1063 **** --- 1126,1133 ---- { prgregset_t gregset; gdb_prfpregset_t fpregset; + void *xregs = 0; + struct regset *xregs_regset = gdbarch_xregs_regset (current_gdbarch); td_err_e err; struct thread_info *thread_info; *************** thread_db_store_registers (int regno) *** 1071,1076 **** --- 1141,1149 ---- thread_info = find_thread_pid (inferior_ptid); thread_db_map_id2thr (thread_info, 1); + if (xregs_regset) + xregs = alloca (gdbarch_xregs_size (current_gdbarch)); + if (regno != -1) { char raw[MAX_REGISTER_SIZE]; *************** thread_db_store_registers (int regno) *** 1082,1087 **** --- 1155,1164 ---- fill_gregset ((gdb_gregset_t *) gregset, -1); fill_fpregset (&fpregset, -1); + if (xregs_regset) + xregs_regset->collect_regset (xregs_regset, current_regcache, -1, + (void *) xregs, + gdbarch_xregs_size (current_gdbarch)); err = td_thr_setgregs_p (&thread_info->private->th, gregset); if (err != TD_OK) *************** thread_db_store_registers (int regno) *** 1091,1096 **** --- 1168,1191 ---- if (err != TD_OK) error ("Cannot store floating-point registers for thread %ld: %s", (long) GET_THREAD (inferior_ptid), thread_db_err_str (err)); + if (xregs_regset) + { + err = td_thr_setxregs_p (&thread_info->private->th, xregs); + if (err == TD_NOXREGS) + { + if (! warned_xregs_not_implemented) + { + warning ("thread debugging library is too old to access" + " %s registers.", + gdbarch_xregs_name (current_gdbarch)); + warned_xregs_not_implemented = 1; + } + } + else if (err != TD_OK) + error ("Cannot store %s registers for thread %ld: %s", + gdbarch_xregs_name (current_gdbarch), + (long) GET_THREAD (inferior_ptid), thread_db_err_str (err)); + } } static void Index: gdb/Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/Makefile.in,v retrieving revision 1.607 diff -c -p -r1.607 Makefile.in *** gdb/Makefile.in 8 Aug 2004 19:27:09 -0000 1.607 --- gdb/Makefile.in 12 Aug 2004 22:07:53 -0000 *************** procfs.o: procfs.c $(defs_h) $(inferior_ *** 2309,2315 **** $(gdb_string_h) $(gdb_assert_h) $(inflow_h) $(auxv_h) \ $(gdb_dirent_h) $(X_OK) $(gdb_stat_h) $(proc_utils_h) $(gregset_h) proc-service.o: proc-service.c $(defs_h) $(gdb_proc_service_h) $(inferior_h) \ ! $(symtab_h) $(target_h) $(gregset_h) proc-why.o: proc-why.c $(defs_h) $(proc_utils_h) p-typeprint.o: p-typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \ $(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(target_h) \ --- 2309,2315 ---- $(gdb_string_h) $(gdb_assert_h) $(inflow_h) $(auxv_h) \ $(gdb_dirent_h) $(X_OK) $(gdb_stat_h) $(proc_utils_h) $(gregset_h) proc-service.o: proc-service.c $(defs_h) $(gdb_proc_service_h) $(inferior_h) \ ! $(symtab_h) $(target_h) $(regset_h) $(regcache_h) $(gregset_h) proc-why.o: proc-why.c $(defs_h) $(proc_utils_h) p-typeprint.o: p-typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \ $(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(target_h) \ *************** thread.o: thread.c $(defs_h) $(symtab_h) *** 2580,2586 **** $(gdbcmd_h) $(regcache_h) $(gdb_h) $(gdb_string_h) $(ui_out_h) thread-db.o: thread-db.c $(defs_h) $(gdb_assert_h) $(gdb_proc_service_h) \ $(gdb_thread_db_h) $(bfd_h) $(gdbthread_h) $(inferior_h) \ ! $(symfile_h) $(objfiles_h) $(target_h) $(regcache_h) $(solib_svr4_h) top.o: top.c $(defs_h) $(gdbcmd_h) $(call_cmds_h) $(cli_cmds_h) \ $(cli_script_h) $(cli_setshow_h) $(cli_decode_h) $(symtab_h) \ $(inferior_h) $(target_h) $(breakpoint_h) $(gdbtypes_h) \ --- 2580,2587 ---- $(gdbcmd_h) $(regcache_h) $(gdb_h) $(gdb_string_h) $(ui_out_h) thread-db.o: thread-db.c $(defs_h) $(gdb_assert_h) $(gdb_proc_service_h) \ $(gdb_thread_db_h) $(bfd_h) $(gdbthread_h) $(inferior_h) \ ! $(symfile_h) $(objfiles_h) $(target_h) $(regset_h) $(regcache_h) \ ! $(solib_svr4_h) top.o: top.c $(defs_h) $(gdbcmd_h) $(call_cmds_h) $(cli_cmds_h) \ $(cli_script_h) $(cli_setshow_h) $(cli_decode_h) $(symtab_h) \ $(inferior_h) $(target_h) $(breakpoint_h) $(gdbtypes_h) \