X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fhpux-thread.c;h=26d57ba258641b3edc187e6cee34cc7307dea411;hb=3bcbaac54041e1226ae28cf918d4f5daf1a899af;hp=36421f390ab1289a3343e61fb8ea0088e5b2d3e9;hpb=1996fae84682e8ddd146215dd2959ad1ec924c09;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/hpux-thread.c b/gdb/hpux-thread.c index 36421f390a..26d57ba258 100644 --- a/gdb/hpux-thread.c +++ b/gdb/hpux-thread.c @@ -1,21 +1,22 @@ /* Low level interface for debugging HPUX/DCE threads for GDB, the GNU debugger. - Copyright 1996, 1999 Free Software Foundation, Inc. + Copyright 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. -This file is part of GDB. + 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 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. + 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. */ + 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. */ /* This module implements a sort of half target that sits between the machine-independent parts of GDB and the ptrace interface (infptrace.c) to @@ -27,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ structures that live in the user's heap. For the most part, the kernel has no knowlege of these threads. - */ + */ #include "defs.h" @@ -38,140 +39,92 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "gdbthread.h" #include "target.h" #include "inferior.h" +#include "regcache.h" #include -#include #include #include "gdbcore.h" extern int child_suppress_run; -extern struct target_ops child_ops; /* target vector for inftarg.c */ +extern struct target_ops child_ops; /* target vector for inftarg.c */ -extern void _initialize_hpux_thread PARAMS ((void)); +extern void _initialize_hpux_thread (void); struct string_map -{ - int num; - char *str; -}; + { + int num; + char *str; + }; static int hpux_thread_active = 0; -static int main_pid; /* Real process ID */ +static ptid_t main_ptid; /* Real process ID */ static CORE_ADDR P_cma__g_known_threads; static CORE_ADDR P_cma__g_current_thread; -static struct cleanup * save_inferior_pid PARAMS ((void)); - -static void restore_inferior_pid PARAMS ((int pid)); - -static void hpux_thread_resume PARAMS ((int pid, int step, - enum target_signal signo)); +static void hpux_thread_resume (ptid_t ptid, int step, + enum target_signal signo); -static void init_hpux_thread_ops PARAMS ((void)); +static void init_hpux_thread_ops (void); static struct target_ops hpux_thread_ops; -/* - -LOCAL FUNCTION - - save_inferior_pid - Save inferior_pid on the cleanup list - restore_inferior_pid - Restore inferior_pid from the cleanup list - -SYNOPSIS - - struct cleanup *save_inferior_pid () - void restore_inferior_pid (int pid) - -DESCRIPTION - - These two functions act in unison to restore inferior_pid in - case of an error. - -NOTES - - inferior_pid is a global variable that needs to be changed by many of - these routines before calling functions in procfs.c. In order to - guarantee that inferior_pid gets restored (in case of errors), you - need to call save_inferior_pid before changing it. At the end of the - function, you should invoke do_cleanups to restore it. - - */ - - -static struct cleanup * -save_inferior_pid () -{ - return make_cleanup (restore_inferior_pid, inferior_pid); -} - -static void -restore_inferior_pid (pid) - int pid; -{ - inferior_pid = pid; -} - -static int find_active_thread PARAMS ((void)); +static ptid_t find_active_thread (void); static int cached_thread; -static int cached_active_thread; static cma__t_int_tcb cached_tcb; -static int -find_active_thread () +static ptid_t +find_active_thread (void) { static cma__t_int_tcb tcb; CORE_ADDR tcb_ptr; - if (cached_active_thread != 0) - return cached_active_thread; - - read_memory ((CORE_ADDR)P_cma__g_current_thread, - (char *)&tcb_ptr, + read_memory ((CORE_ADDR) P_cma__g_current_thread, + (char *) &tcb_ptr, sizeof tcb_ptr); - read_memory (tcb_ptr, (char *)&tcb, sizeof tcb); + read_memory (tcb_ptr, (char *) &tcb, sizeof tcb); - return (cma_thread_get_unique (&tcb.prolog.client_thread) << 16) | main_pid; + return (ptid_build (PIDGET (main_ptid), 0, + cma_thread_get_unique (&tcb.prolog.client_thread))); } -static cma__t_int_tcb * find_tcb PARAMS ((int thread)); +static cma__t_int_tcb *find_tcb (ptid_t ptid); static cma__t_int_tcb * -find_tcb (thread) - int thread; +find_tcb (ptid_t ptid) { cma__t_known_object queue_header; cma__t_queue *queue_ptr; + int thread = ptid_get_tid (ptid); if (thread == cached_thread) return &cached_tcb; - read_memory ((CORE_ADDR)P_cma__g_known_threads, - (char *)&queue_header, + read_memory ((CORE_ADDR) P_cma__g_known_threads, + (char *) &queue_header, sizeof queue_header); for (queue_ptr = queue_header.queue.flink; - queue_ptr != (cma__t_queue *)P_cma__g_known_threads; + queue_ptr != (cma__t_queue *) P_cma__g_known_threads; queue_ptr = cached_tcb.threads.flink) { cma__t_int_tcb *tcb_ptr; tcb_ptr = cma__base (queue_ptr, threads, cma__t_int_tcb); - read_memory ((CORE_ADDR)tcb_ptr, (char *)&cached_tcb, sizeof cached_tcb); + read_memory ((CORE_ADDR) tcb_ptr, (char *) &cached_tcb, sizeof cached_tcb); if (cached_tcb.header.type == cma__c_obj_tcb) - if (cma_thread_get_unique (&cached_tcb.prolog.client_thread) == thread >> 16) + if (cma_thread_get_unique (&cached_tcb.prolog.client_thread) == thread) { cached_thread = thread; return &cached_tcb; } } - error ("Can't find TCB %d,%d", thread >> 16, thread & 0xffff); + error ("Can't find TCB %d", thread); return NULL; } @@ -180,9 +133,7 @@ find_tcb (thread) /* ARGSUSED */ static void -hpux_thread_open (arg, from_tty) - char *arg; - int from_tty; +hpux_thread_open (char *arg, int from_tty) { child_ops.to_open (arg, from_tty); } @@ -191,9 +142,7 @@ hpux_thread_open (arg, from_tty) and wait for the trace-trap that results from attaching. */ static void -hpux_thread_attach (args, from_tty) - char *args; - int from_tty; +hpux_thread_attach (char *args, int from_tty) { child_ops.to_attach (args, from_tty); @@ -209,9 +158,7 @@ hpux_thread_attach (args, from_tty) started via the normal ptrace (PTRACE_TRACEME). */ static void -hpux_thread_detach (args, from_tty) - char *args; - int from_tty; +hpux_thread_detach (char *args, int from_tty) { child_ops.to_detach (args, from_tty); } @@ -222,16 +169,14 @@ hpux_thread_detach (args, from_tty) for procfs. */ static void -hpux_thread_resume (pid, step, signo) - int pid; - int step; - enum target_signal signo; +hpux_thread_resume (ptid_t ptid, int step, enum target_signal signo) { struct cleanup *old_chain; - old_chain = save_inferior_pid (); + old_chain = save_inferior_ptid (); - pid = inferior_pid = main_pid; + ptid = main_ptid; + inferior_ptid = main_ptid; #if 0 if (pid != -1) @@ -242,10 +187,9 @@ hpux_thread_resume (pid, step, signo) } #endif - child_ops.to_resume (pid, step, signo); + child_ops.to_resume (ptid, step, signo); cached_thread = 0; - cached_active_thread = 0; do_cleanups (old_chain); } @@ -253,22 +197,20 @@ hpux_thread_resume (pid, step, signo) /* Wait for any threads to stop. We may have to convert PID from a thread id to a LWP id, and vice versa on the way out. */ -static int -hpux_thread_wait (pid, ourstatus) - int pid; - struct target_waitstatus *ourstatus; +static ptid_t +hpux_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { - int rtnval; + ptid_t rtnval; struct cleanup *old_chain; - old_chain = save_inferior_pid (); + old_chain = save_inferior_ptid (); - inferior_pid = main_pid; + inferior_ptid = main_ptid; - if (pid != -1) - pid = main_pid; + if (!ptid_equal (ptid, minus_one_ptid)) + ptid = main_ptid; - rtnval = child_ops.to_wait (pid, ourstatus); + rtnval = child_ops.to_wait (ptid, ourstatus); rtnval = find_active_thread (); @@ -279,9 +221,9 @@ hpux_thread_wait (pid, ourstatus) static char regmap[NUM_REGS] = { - -2, -1, -1, 0, 4, 8, 12, 16, 20, 24, /* flags, r1 -> r9 */ - 28, 32, 36, 40, 44, 48, 52, 56, 60, -1, /* r10 -> r19 */ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* r20 -> r29 */ + -2, -1, -1, 0, 4, 8, 12, 16, 20, 24, /* flags, r1 -> r9 */ + 28, 32, 36, 40, 44, 48, 52, 56, 60, -1, /* r10 -> r19 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* r20 -> r29 */ /* r30, r31, sar, pcoqh, pcsqh, pcoqt, pcsqt, eiem, iir, isr */ -2, -1, -1, -2, -1, -1, -1, -1, -1, -1, @@ -293,30 +235,29 @@ static char regmap[NUM_REGS] = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* mpsfu_high, mpsfu_low, mpsfu_ovflo, pad */ - 144, -1, -1, -1, -1, -1, -1, -1, /* fpsr, fpe1 -> fpe7 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* fr4 -> fr7 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* fr8 -> fr11 */ - 136, -1, 128, -1, 120, -1, 112, -1, /* fr12 -> fr15 */ - 104, -1, 96, -1, 88, -1, 80, -1, /* fr16 -> fr19 */ - 72, -1, 64, -1, -1, -1, -1, -1, /* fr20 -> fr23 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* fr24 -> fr27 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* fr28 -> fr31 */ + 144, -1, -1, -1, -1, -1, -1, -1, /* fpsr, fpe1 -> fpe7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* fr4 -> fr7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* fr8 -> fr11 */ + 136, -1, 128, -1, 120, -1, 112, -1, /* fr12 -> fr15 */ + 104, -1, 96, -1, 88, -1, 80, -1, /* fr16 -> fr19 */ + 72, -1, 64, -1, -1, -1, -1, -1, /* fr20 -> fr23 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* fr24 -> fr27 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* fr28 -> fr31 */ }; static void -hpux_thread_fetch_registers (regno) - int regno; +hpux_thread_fetch_registers (int regno) { cma__t_int_tcb tcb, *tcb_ptr; struct cleanup *old_chain; int i; int first_regno, last_regno; - tcb_ptr = find_tcb (inferior_pid); + tcb_ptr = find_tcb (inferior_ptid); - old_chain = save_inferior_pid (); + old_chain = save_inferior_ptid (); - inferior_pid = main_pid; + inferior_ptid = main_ptid; if (tcb_ptr->state == cma__c_state_running) { @@ -347,7 +288,7 @@ hpux_thread_fetch_registers (regno) unsigned char buf[MAX_REGISTER_RAW_SIZE]; CORE_ADDR sp; - sp = (CORE_ADDR)tcb_ptr->static_ctx.sp - 160; + sp = (CORE_ADDR) tcb_ptr->static_ctx.sp - 160; if (regno == FLAGS_REGNUM) /* Flags must be 0 to avoid bogus value for SS_INSYSCALL */ @@ -367,19 +308,18 @@ hpux_thread_fetch_registers (regno) } static void -hpux_thread_store_registers (regno) - int regno; +hpux_thread_store_registers (int regno) { cma__t_int_tcb tcb, *tcb_ptr; struct cleanup *old_chain; int i; int first_regno, last_regno; - tcb_ptr = find_tcb (inferior_pid); + tcb_ptr = find_tcb (inferior_ptid); - old_chain = save_inferior_pid (); + old_chain = save_inferior_ptid (); - inferior_pid = main_pid; + inferior_ptid = main_ptid; if (tcb_ptr->state == cma__c_state_running) { @@ -410,25 +350,26 @@ hpux_thread_store_registers (regno) unsigned char buf[MAX_REGISTER_RAW_SIZE]; CORE_ADDR sp; - sp = (CORE_ADDR)tcb_ptr->static_ctx.sp - 160; + sp = (CORE_ADDR) tcb_ptr->static_ctx.sp - 160; if (regno == FLAGS_REGNUM) - child_ops.to_store_registers (regno); /* Let lower layer handle this... */ + child_ops.to_store_registers (regno); /* Let lower layer handle this... */ else if (regno == SP_REGNUM) { - write_memory ((CORE_ADDR)&tcb_ptr->static_ctx.sp, - registers + REGISTER_BYTE (regno), + write_memory ((CORE_ADDR) & tcb_ptr->static_ctx.sp, + &deprecated_registers[REGISTER_BYTE (regno)], REGISTER_RAW_SIZE (regno)); tcb_ptr->static_ctx.sp = (cma__t_hppa_regs *) - (extract_address (registers + REGISTER_BYTE (regno), REGISTER_RAW_SIZE (regno)) + 160); + (extract_address (&deprecated_registers[REGISTER_BYTE (regno)], + REGISTER_RAW_SIZE (regno)) + 160); } else if (regno == PC_REGNUM) write_memory (sp - 20, - registers + REGISTER_BYTE (regno), + &deprecated_registers[REGISTER_BYTE (regno)], REGISTER_RAW_SIZE (regno)); else write_memory (sp + regmap[regno], - registers + REGISTER_BYTE (regno), + &deprecated_registers[REGISTER_BYTE (regno)], REGISTER_RAW_SIZE (regno)); } } @@ -443,27 +384,25 @@ hpux_thread_store_registers (regno) debugged. */ static void -hpux_thread_prepare_to_store () +hpux_thread_prepare_to_store (void) { child_ops.to_prepare_to_store (); } static int -hpux_thread_xfer_memory (memaddr, myaddr, len, dowrite, target) - CORE_ADDR memaddr; - char *myaddr; - int len; - int dowrite; - struct target_ops *target; /* ignored */ +hpux_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, + int dowrite, struct mem_attrib *attribs, + struct target_ops *target) { int retval; struct cleanup *old_chain; - old_chain = save_inferior_pid (); + old_chain = save_inferior_ptid (); - inferior_pid = main_pid; + inferior_ptid = main_ptid; - retval = child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, target); + retval = + child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, attribs, target); do_cleanups (old_chain); @@ -473,44 +412,39 @@ hpux_thread_xfer_memory (memaddr, myaddr, len, dowrite, target) /* Print status information about what we're accessing. */ static void -hpux_thread_files_info (ignore) - struct target_ops *ignore; +hpux_thread_files_info (struct target_ops *ignore) { child_ops.to_files_info (ignore); } static void -hpux_thread_kill_inferior () +hpux_thread_kill_inferior (void) { child_ops.to_kill (); } static void -hpux_thread_notice_signals (pid) - int pid; +hpux_thread_notice_signals (ptid_t ptid) { - child_ops.to_notice_signals (pid); + child_ops.to_notice_signals (ptid); } /* Fork an inferior process, and start debugging it with /proc. */ static void -hpux_thread_create_inferior (exec_file, allargs, env) - char *exec_file; - char *allargs; - char **env; +hpux_thread_create_inferior (char *exec_file, char *allargs, char **env) { child_ops.to_create_inferior (exec_file, allargs, env); if (hpux_thread_active) { - main_pid = inferior_pid; + main_ptid = inferior_ptid; push_target (&hpux_thread_ops); - inferior_pid = find_active_thread (); + inferior_ptid = find_active_thread (); - add_thread (inferior_pid); + add_thread (inferior_ptid); } } @@ -520,40 +454,49 @@ hpux_thread_create_inferior (exec_file, allargs, env) those variables don't show up until the library gets mapped and the symbol table is read in. */ +/* This new_objfile event is now managed by a chained function pointer. + * It is the callee's responsability to call the next client on the chain. + */ + +/* Saved pointer to previous owner of the new_objfile event. */ +static void (*target_new_objfile_chain) (struct objfile *); + void -hpux_thread_new_objfile (objfile) - struct objfile *objfile; +hpux_thread_new_objfile (struct objfile *objfile) { struct minimal_symbol *ms; if (!objfile) { hpux_thread_active = 0; - - return; + goto quit; } ms = lookup_minimal_symbol ("cma__g_known_threads", NULL, objfile); if (!ms) - return; + goto quit; P_cma__g_known_threads = SYMBOL_VALUE_ADDRESS (ms); ms = lookup_minimal_symbol ("cma__g_current_thread", NULL, objfile); if (!ms) - return; + goto quit; P_cma__g_current_thread = SYMBOL_VALUE_ADDRESS (ms); hpux_thread_active = 1; +quit: + /* Call predecessor on chain, if any. */ + if (target_new_objfile_chain) + target_new_objfile_chain (objfile); } /* Clean up after the inferior dies. */ static void -hpux_thread_mourn_inferior () +hpux_thread_mourn_inferior (void) { child_ops.to_mourn_inferior (); } @@ -561,20 +504,19 @@ hpux_thread_mourn_inferior () /* Mark our target-struct as eligible for stray "run" and "attach" commands. */ static int -hpux_thread_can_run () +hpux_thread_can_run (void) { return child_suppress_run; } static int -hpux_thread_alive (pid) - int pid; +hpux_thread_alive (ptid_t ptid) { return 1; } static void -hpux_thread_stop () +hpux_thread_stop (void) { child_ops.to_stop (); } @@ -582,18 +524,18 @@ hpux_thread_stop () /* Convert a pid to printable form. */ char * -hpux_pid_to_str (pid) - int pid; +hpux_pid_to_str (ptid_t ptid) { static char buf[100]; + int pid = PIDGET (ptid); - sprintf (buf, "Thread %d", pid >> 16); + sprintf (buf, "Thread %ld", ptid_get_tid (ptid)); return buf; } static void -init_hpux_thread_ops () +init_hpux_thread_ops (void) { hpux_thread_ops.to_shortname = "hpux-threads"; hpux_thread_ops.to_longname = "HPUX threads and pthread."; @@ -613,6 +555,7 @@ init_hpux_thread_ops () hpux_thread_ops.to_terminal_init = terminal_init_inferior; hpux_thread_ops.to_terminal_inferior = terminal_inferior; hpux_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output; + hpux_thread_ops.to_terminal_save_ours = terminal_save_ours; hpux_thread_ops.to_terminal_ours = terminal_ours; hpux_thread_ops.to_terminal_info = child_terminal_info; hpux_thread_ops.to_kill = hpux_thread_kill_inferior; @@ -620,7 +563,7 @@ init_hpux_thread_ops () hpux_thread_ops.to_mourn_inferior = hpux_thread_mourn_inferior; hpux_thread_ops.to_can_run = hpux_thread_can_run; hpux_thread_ops.to_notice_signals = hpux_thread_notice_signals; - hpux_thread_ops.to_thread_alive = hpux_thread_thread_alive; + hpux_thread_ops.to_thread_alive = hpux_thread_alive; hpux_thread_ops.to_stop = hpux_thread_stop; hpux_thread_ops.to_stratum = process_stratum; hpux_thread_ops.to_has_all_memory = 1; @@ -632,10 +575,13 @@ init_hpux_thread_ops () } void -_initialize_hpux_thread () +_initialize_hpux_thread (void) { init_hpux_thread_ops (); add_target (&hpux_thread_ops); child_suppress_run = 1; + /* Hook into new_objfile notification. */ + target_new_objfile_chain = target_new_objfile_hook; + target_new_objfile_hook = hpux_thread_new_objfile; }