diff options
-rw-r--r-- | gdb/ChangeLog | 26 | ||||
-rw-r--r-- | gdb/config/i386/i386sco5.mt | 3 | ||||
-rw-r--r-- | gdb/config/i386/tm-i386sco5.h | 62 | ||||
-rw-r--r-- | gdb/i386v-nat.c | 2 | ||||
-rw-r--r-- | gdb/procfs.c | 187 |
5 files changed, 269 insertions, 11 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6849484..f7f3240 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,29 @@ +Mon Apr 20 14:18:45 1998 J. Kean Johnston <jkj@sco.com> + + * procfs.c: Added replacement macros for LWP stuff. Fixed support + for UnixWare / SVR4.2MP targets and any targets which use + multi-file /proc entries. Fixed support for hardware watchpoints. + * solib.c: SCO needs some of the same code as SunOS. Change + preprocessor conditionals. + + * config/i386/i386sco5.mt: New file. + * config/i386/tm-i386sco5.h: New file. + * config/i386/i386sco5.mh (NATDEPFILES): add i386v-nat.o. + * config/i386/nm-i386v42mp.h + (TARGET_HAS_HARDWARE_WATCHPOINTS): define. + Add other macros for hardware assisted watchpoints. + * config/i386/nm-i386sco5.h: Correct attributions. + (TARGET_HAS_HARDWARE_WATCHPOINTS): define. + * config/i386/nm-linux.h (target_remote_watchpoint): Pass + 'type' through to i386_insert_watchpoint. + +Mon Apr 20 14:12:30 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) + + * infrun.c (wait_for_inferior): Don't add signalled processes + as new threads. + * procfs.c (wait_fd): Note if LWP has exited. + (procfs_wait): use GETPID to get process ID. + Sat Apr 18 15:21:04 1998 Stan Cox <scox@cygnus.com> * configure.tgt: Added sparc86x support. diff --git a/gdb/config/i386/i386sco5.mt b/gdb/config/i386/i386sco5.mt new file mode 100644 index 0000000..54dc68d --- /dev/null +++ b/gdb/config/i386/i386sco5.mt @@ -0,0 +1,3 @@ +# Target: Intel 386 running SCO Open Server 5 +TDEPFILES= i386-tdep.o i387-tdep.o +TM_FILE= tm-i386sco5.h diff --git a/gdb/config/i386/tm-i386sco5.h b/gdb/config/i386/tm-i386sco5.h new file mode 100644 index 0000000..ffac5b3 --- /dev/null +++ b/gdb/config/i386/tm-i386sco5.h @@ -0,0 +1,62 @@ +/* Macro definitions for GDB on an Intel i386 running SCO Open Server 5. + Copyright (C) 1998 Free Software Foundation, Inc. + Written by J. Kean Johnston (jkj@sco.com). + +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_I386SCO5_H +#define TM_I386SCO5_H 1 + +/* Pick up most of what we need from the generic i386 target include file. */ + +#include "i386/tm-i386.h" + +/* Pick up more stuff from the generic SYSV and SVR4 host include files. */ +#include "i386/tm-i386v.h" +#include "tm-sysv4.h" + +#define KERNEL_U_SIZE kernel_u_size() + +/* + * SCO is unlike other SVR3 targets in that it has SVR4 style shared + * libs, with a slight twist. We expect 3 traps (2 for the exec and + * one for the dynamic loader). After the third trap we insert the + * SOLIB breakpoints, then wait for the 4th trap. + */ +#undef START_INFERIOR_TRAPS_EXPECTED +#define START_INFERIOR_TRAPS_EXPECTED 3 + +/* We can also do hardware watchpoints */ +#define TARGET_HAS_HARDWARE_WATCHPOINTS +#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1 + +/* After a watchpoint trap, the PC points to the instruction which + caused the trap. But we can continue over it without disabling the + trap. */ +#define HAVE_CONTINUABLE_WATCHPOINT +#define HAVE_STEPPABLE_WATCHPOINT + +#define STOPPED_BY_WATCHPOINT(W) \ + i386_stopped_by_watchpoint (inferior_pid) + +#define target_insert_watchpoint(addr, len, type) \ + i386_insert_watchpoint (inferior_pid, addr, len, type) + +#define target_remove_watchpoint(addr, len, type) \ + i386_remove_watchpoint (inferior_pid, addr, len) + +#endif /* ifndef TM_I386SCO5_H */ diff --git a/gdb/i386v-nat.c b/gdb/i386v-nat.c index 38468a9..a7eea53 100644 --- a/gdb/i386v-nat.c +++ b/gdb/i386v-nat.c @@ -155,7 +155,7 @@ i386_insert_aligned_watchpoint (pid, waddr, addr, len, rw) if (i > DR_LASTADDR) return -1; - read_write_bits = ((rw & 1) ? DR_RW_READ : 0) | ((rw & 2) ? DR_RW_WRITE : 0); + read_write_bits = (rw & 1) ? DR_RW_READ : DR_RW_WRITE; if (len == 1) len_bits = DR_LEN_1; diff --git a/gdb/procfs.c b/gdb/procfs.c index 01fa4fd..2d24d9c 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -54,6 +54,42 @@ regardless of whether or not the actual target has floating point hardware. #include "gdbcore.h" #include "gdbthread.h" +#if !defined(SYS_lwp_create) && defined(SYS_lwpcreate) +# define SYS_lwp_create SYS_lwpcreate +#endif + +#if !defined(SYS_lwp_exit) && defined(SYS_lwpexit) +# define SYS_lwp_exit SYS_lwpexit +#endif + +#if !defined(SYS_lwp_wait) && defined(SYS_lwpwait) +# define SYS_lwp_wait SYS_lwpwait +#endif + +#if !defined(SYS_lwp_self) && defined(SYS_lwpself) +# define SYS_lwp_self SYS_lwpself +#endif + +#if !defined(SYS_lwp_info) && defined(SYS_lwpinfo) +# define SYS_lwp_info SYS_lwpinfo +#endif + +#if !defined(SYS_lwp_private) && defined(SYS_lwpprivate) +# define SYS_lwp_private SYS_lwpprivate +#endif + +#if !defined(SYS_lwp_kill) && defined(SYS_lwpkill) +# define SYS_lwp_kill SYS_lwpkill +#endif + +#if !defined(SYS_lwp_suspend) && defined(SYS_lwpsuspend) +# define SYS_lwp_suspend SYS_lwpsuspend +#endif + +#if !defined(SYS_lwp_continue) && defined(SYS_lwpcontinue) +# define SYS_lwp_continue SYS_lwpcontinue +#endif + /* the name of the proc status struct depends on the implementation */ #ifdef HAVE_PSTATUS_T typedef pstatus_t gdb_prstatus_t; @@ -901,6 +937,12 @@ wait_fd () if ((poll_list[i].revents & POLLHUP) != 0 || !procfs_read_status(pi)) { /* The LWP has apparently terminated. */ + if (num_poll_list <= 1) + { + pi->prstatus.pr_flags = 0; + pi->had_event = 1; + break; + } if (info_verbose) printf_filtered ("LWP %d exited.\n", (pi->pid >> 16) & 0xffff); @@ -1689,6 +1731,60 @@ init_syscall_table () #if defined (SYS_lwp_sema_trywait) syscall_table[SYS_lwp_sema_trywait] = "lwp_sema_trywait"; #endif +#if defined(SYS_fstatvfs64) + syscall_table[SYS_fstatvfs64] = "fstatvfs64"; +#endif +#if defined(SYS_statvfs64) + syscall_table[SYS_statvfs64] = "statvfs64"; +#endif +#if defined(SYS_ftruncate64) + syscall_table[SYS_ftruncate64] = "ftruncate64"; +#endif +#if defined(SYS_truncate64) + syscall_table[SYS_truncate64] = "truncate64"; +#endif +#if defined(SYS_getrlimit64) + syscall_table[SYS_getrlimit64] = "getrlimit64"; +#endif +#if defined(SYS_setrlimit64) + syscall_table[SYS_setrlimit64] = "setrlimit64"; +#endif +#if defined(SYS_lseek64) + syscall_table[SYS_lseek64] = "lseek64"; +#endif +#if defined(SYS_mmap64) + syscall_table[SYS_mmap64] = "mmap64"; +#endif +#if defined(SYS_pread64) + syscall_table[SYS_pread64] = "pread64"; +#endif +#if defined(SYS_creat64) + syscall_table[SYS_creat64] = "creat64"; +#endif +#if defined(SYS_dshmsys) + syscall_table[SYS_dshmsys] = "dshmsys"; +#endif +#if defined(SYS_invlpg) + syscall_table[SYS_invlpg] = "invlpg"; +#endif +#if defined(SYS_cg_ids) + syscall_table[SYS_cg_ids] = "cg_ids"; +#endif +#if defined(SYS_cg_processors) + syscall_table[SYS_cg_processors] = "cg_processors"; +#endif +#if defined(SYS_cg_info) + syscall_table[SYS_cg_info] = "cg_info"; +#endif +#if defined(SYS_cg_bind) + syscall_table[SYS_cg_bind] = "cg_bind"; +#endif +#if defined(SYS_cg_current) + syscall_table[SYS_cg_current] = "cg_current"; +#endif +#if defined(SYS_cg_memloc) + syscall_table[SYS_cg_memloc] = "cg_memloc"; +#endif } /* @@ -1975,6 +2071,8 @@ init_procinfo (pid, kill) { struct procinfo *pi = (struct procinfo *) xmalloc (sizeof (struct procinfo)); + struct sig_ctl sctl; + struct flt_ctl fctl; memset ((char *) pi, 0, sizeof (*pi)); if (!open_proc_file (pid, pi, O_RDWR, 1)) @@ -2123,10 +2221,20 @@ procfs_exit_handler (pi, syscall_num, why, rtnvalp, statvalp) int *statvalp; { struct procinfo *temp_pi, *next_pi; + struct proc_ctl pctl; +#ifdef UNIXWARE + pctl.cmd = PCRUN; + pctl.data = PRCFAULT; +#else pi->prrun.pr_flags = PRCFAULT; +#endif +#ifdef PROCFS_USE_READ_WRITE + if (write (pi->ctl_fd, (char *)&pctl, sizeof (struct proc_ctl)) < 0) +#else if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0) +#endif perror_with_name (pi->pathname); if (attach_flag) @@ -2809,6 +2917,7 @@ proc_base_address (addr) #endif /* 0 */ +#ifndef UNIXWARE /* LOCAL FUNCTION @@ -2847,7 +2956,7 @@ proc_address_to_fd (pi, addr, complain) } return (fd); } - +#endif /* !UNIXWARE */ /* Attach to process PID, then initialize for debugging it and wait for the trace-trap that results from attaching. */ @@ -3065,8 +3174,8 @@ do_attach (pid) } add_thread (pi->pid); procfs_set_inferior_syscall_traps (pi); - } #endif /* PROCFS_USE_READ_WRITE */ + } attach_flag = 1; return (pi->pid); } @@ -3247,7 +3356,6 @@ procfs_wait (pid, ourstatus) struct procinfo *pi; struct proc_ctl pctl; -#ifndef UNIXWARE if (pid != -1) /* Non-specific process? */ pi = NULL; else @@ -3269,7 +3377,6 @@ procfs_wait (pid, ourstatus) for (pi = procinfo_list; pi; pi = pi->next) if (pi->pid == pid && pi->had_event) break; -#endif if (!pi && !checkerr) goto wait_again; @@ -3291,7 +3398,7 @@ procfs_wait (pid, ourstatus) { /* XXX Fixme -- what to do if attached? Can't call wait... */ rtnval = wait (&statval); - if ((rtnval) != (inferior_pid)) + if ((rtnval) != (PIDGET (inferior_pid))) { print_sys_errmsg (pi->pathname, errno); error ("procfs_wait: wait failed, returned %d", rtnval); @@ -3305,7 +3412,11 @@ procfs_wait (pid, ourstatus) /* NOTREACHED */ } } +#ifdef UNIXWARE + else if (pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP)) +#else else if (pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP)) +#endif { #ifdef UNIXWARE rtnval = pi->prstatus.pr_pid; @@ -3414,7 +3525,7 @@ procfs_wait (pid, ourstatus) if (!procinfo->had_event) { #ifdef PROCFS_USE_READ_WRITE - cmd = PCSTOP; + long cmd = PCSTOP; if (write (pi->ctl_fd, (char *) &cmd, sizeof (long)) < 0) { print_sys_errmsg (procinfo->pathname, errno); @@ -3448,8 +3559,12 @@ procfs_wait (pid, ourstatus) } else { - error ("PIOCWSTOP, stopped for unknown/unhandled reason, flags %#x", + error ("PIOCWSTOP, stopped for unknown/unhandled reason, flags %#x", +#ifdef UNIXWARE + pi->prstatus.pr_lwp.pr_flags); +#else pi->prstatus.pr_flags); +#endif } store_waitstatus (ourstatus, statval); @@ -3725,7 +3840,6 @@ procfs_resume (pid, step, signo) print_sys_errmsg (procinfo->pathname, errno); error ("PCRUN failed"); } - procfs_read_status (procinfo); #else procinfo->prrun.pr_flags &= PRSTEP; procinfo->prrun.pr_flags |= PRCFAULT | PRCSIG; @@ -3752,9 +3866,9 @@ procfs_resume (pid, step, signo) print_sys_errmsg (procinfo->pathname, errno); warning ("PIOCRUN failed"); } +#endif } procfs_read_status (procinfo); -#endif } } @@ -4794,7 +4908,11 @@ No process. Start debugging a program or specify an explicit process ID."); if (summary || all) { info_proc_stop (pip, summary); +#ifdef UNIXWARE + supply_gregset (&pip->prstatus.pr_lwp.pr_context.uc_mcontext.gregs); +#else supply_gregset (&pip->prstatus.pr_reg); +#endif printf_filtered ("PC: "); print_address (read_pc (), gdb_stdout); printf_filtered ("\n"); @@ -5002,7 +5120,8 @@ procfs_clear_syscall_trap (pi, syscall_num, errok) { sysset_t sysset; int goterr, i; - + +#ifndef UNIXWARE goterr = ioctl (pi->ctl_fd, PIOCGENTRY, &sysset) < 0; if (goterr && !errok) @@ -5042,6 +5161,7 @@ procfs_clear_syscall_trap (pi, syscall_num, errok) error ("PIOCSEXIT failed"); } } +#endif if (!pi->syscall_handlers) { @@ -5106,6 +5226,7 @@ procfs_set_syscall_trap (pi, syscall_num, flags, func) { sysset_t sysset; +#ifndef UNIXWARE if (flags & PROCFS_SYSCALL_ENTRY) { if (ioctl (pi->ctl_fd, PIOCGENTRY, &sysset) < 0) @@ -5141,6 +5262,7 @@ procfs_set_syscall_trap (pi, syscall_num, flags, func) error ("PIOCSEXIT failed"); } } +#endif if (!pi->syscall_handlers) { @@ -5210,6 +5332,7 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp) { int lwp_id; struct procinfo *childpi; + struct proc_ctl pctl; /* We've just detected the completion of an lwp_create system call. Now we need to setup a procinfo struct for this thread, and notify the thread @@ -5218,6 +5341,19 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp) /* If lwp_create failed, then nothing interesting happened. Continue the process and go back to sleep. */ +#ifdef UNIXWARE + /* Joel ... can you check this logic out please? JKJ */ + if (pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs[R_EFL] & 1) + { /* _lwp_create failed */ + pctl.cmd = PCRUN; + pctl.data = PRCFAULT; + + if (write (pi->ctl_fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0) + perror_with_name (pi->pathname); + + return 0; + } +#else /* UNIXWARE */ if (PROCFS_GET_CARRY (pi->prstatus.pr_reg)) { /* _lwp_create failed */ pi->prrun.pr_flags &= PRSTEP; @@ -5228,17 +5364,25 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp) return 0; } +#endif /* At this point, the new thread is stopped at it's first instruction, and the parent is stopped at the exit from lwp_create. */ if (pi->new_child) /* Child? */ { /* Yes, just continue it */ +#ifdef UNIXWARE + pctl.cmd = PCRUN; + pctl.data = PRCFAULT; + + if (write(pi->ctl_fd, (char *)&pctl, sizeof (struct proc_ctl)) < 0) +#else /* !UNIXWARE */ pi->prrun.pr_flags &= PRSTEP; pi->prrun.pr_flags |= PRCFAULT; if ((pi->prstatus.pr_flags & PR_ISTOP) && ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0) +#endif /* !UNIXWARE */ perror_with_name (pi->pathname); pi->new_child = 0; /* No longer new */ @@ -5250,7 +5394,11 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp) in the child and continue the parent. */ /* Third arg is pointer to new thread id. */ +#ifdef UNIXWARE + lwp_id = read_memory_integer (pi->prstatus.pr_lwp.pr_sysarg[2], sizeof (int)); +#else lwp_id = read_memory_integer (pi->prstatus.pr_sysarg[2], sizeof (int)); +#endif lwp_id = (lwp_id << 16) | PIDGET (pi->pid); @@ -5265,25 +5413,42 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp) printf_filtered ("[New %s]\n", target_pid_to_str (lwp_id)); /* Continue the parent */ +#ifdef UNIXWARE + pctl.cmd = PCRUN; + pctl.data = PRCFAULT; + if (write(pi->ctl_fd, (char *)&pctl, sizeof (struct proc_ctl)) < 0) +#else pi->prrun.pr_flags &= PRSTEP; pi->prrun.pr_flags |= PRCFAULT; if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0) +#endif perror_with_name (pi->pathname); /* The new child may have been created in one of two states: SUSPENDED or RUNNABLE. If runnable, we will simply signal it to run. If suspended, we flag it to be continued later, when it has an event. */ +#ifdef UNIXWARE + if (childpi->prstatus.pr_lwp.pr_why == PR_SUSPENDED) +#else if (childpi->prstatus.pr_why == PR_SUSPENDED) +#endif childpi->new_child = 1; /* Flag this as an unseen child process */ else { /* Continue the child */ +#ifdef UNIXWARE + pctl.cmd = PCRUN; + pctl.data = PRCFAULT; + + if (write(pi->ctl_fd, (char *)&pctl, sizeof (struct proc_ctl)) < 0) +#else childpi->prrun.pr_flags &= PRSTEP; childpi->prrun.pr_flags |= PRCFAULT; if (ioctl (childpi->ctl_fd, PIOCRUN, &childpi->prrun) != 0) +#endif perror_with_name (childpi->pathname); } return 0; @@ -5406,6 +5571,7 @@ procfs_can_run () return !procfs_suppress_run; } #ifdef TARGET_HAS_HARDWARE_WATCHPOINTS +#ifndef UNIXWARE /* Insert a watchpoint */ int @@ -5465,6 +5631,7 @@ procfs_stopped_by_watchpoint(pid) } return 0; } +#endif /* !UNIXWARE */ #endif /* TARGET_HAS_HARDWARE_WATCHPOINTS */ /* Why is this necessary? Shouldn't dead threads just be removed from the |