aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog26
-rw-r--r--gdb/config/i386/i386sco5.mt3
-rw-r--r--gdb/config/i386/tm-i386sco5.h62
-rw-r--r--gdb/i386v-nat.c2
-rw-r--r--gdb/procfs.c187
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