summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/binutils
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1994-12-30 23:27:33 +0000
committerjkh <jkh@FreeBSD.org>1994-12-30 23:27:33 +0000
commitcbfab23866a6fbbeedaea00fb9cc3c21f292ba86 (patch)
tree9e4e1ee771b678aacbaa34624639c5b3ea159d34 /gnu/usr.bin/binutils
parent571bcca723c6e0e2d2261e69b1f5a46eef8f9d14 (diff)
downloadFreeBSD-src-cbfab23866a6fbbeedaea00fb9cc3c21f292ba86.zip
FreeBSD-src-cbfab23866a6fbbeedaea00fb9cc3c21f292ba86.tar.gz
Hurrah! Let the champagne flow, the olive oil barrel be opened and
the wild, slippery orgy commence! Gary Jennejohn, too studly for his own good, has finally come through with the new, improved gdb 4.13. This gdb features: o kgdb support - if this works (and I urge folks to test it), we can finally purge the old and hateful version of kgdb from our source tree. o attach/detach support. See comments in README.FreeBSD for more details. o Well, it's newer. Our previous version was 4.11. Comments and flames to gj, of course! :-) Thanks, Gary. Much appreciated. The previous state of gdb/kgdb has been a thorn in all of our sides for some time.. Submitted by: gj
Diffstat (limited to 'gnu/usr.bin/binutils')
-rw-r--r--gnu/usr.bin/binutils/gdb/Makefile31
-rw-r--r--gnu/usr.bin/binutils/gdb/gdb.12
-rw-r--r--gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c375
-rw-r--r--gnu/usr.bin/binutils/gdb/i386/nm.h56
-rw-r--r--gnu/usr.bin/binutils/gdb/i386/tm.h2
-rw-r--r--gnu/usr.bin/binutils/gdb/i386/version.c6
-rw-r--r--gnu/usr.bin/binutils/gdb/i386/xm.h4
7 files changed, 410 insertions, 66 deletions
diff --git a/gnu/usr.bin/binutils/gdb/Makefile b/gnu/usr.bin/binutils/gdb/Makefile
index 70f0e0c..3e481ce 100644
--- a/gnu/usr.bin/binutils/gdb/Makefile
+++ b/gnu/usr.bin/binutils/gdb/Makefile
@@ -1,19 +1,23 @@
PROG = gdb
BINDIR= /usr/bin
CLEANFILES+= y.tab.h c-exp.tab.c ch-exp.tab.c m2-exp.tab.c
-SRCS = main.c blockframe.c breakpoint.c findvar.c stack.c thread.c \
- source.c values.c eval.c valops.c valarith.c valprint.c printcmd.c \
- symtab.c symfile.c symmisc.c infcmd.c infrun.c command.c utils.c \
- expprint.c environ.c gdbtypes.c copying.c i386-tdep.c i386-pinsn.c \
- freebsd-solib.c ser-unix.c exec.c fork-child.c infptrace.c inftarg.c \
- corelow.c coredep.c freebsd-nat.c remote.c dcache.c remote-utils.c \
- mem-break.c target.c putenv.c parse.c language.c buildsym.c \
- objfiles.c minsyms.c maint.c demangle.c dbxread.c coffread.c \
- elfread.c dwarfread.c mipsread.c stabsread.c core.c c-lang.c \
- ch-lang.c m2-lang.c complaints.c typeprint.c c-typeprint.c \
- ch-typeprint.c m2-typeprint.c c-valprint.c cp-valprint.c ch-valprint.c \
- m2-valprint.c nlmread.c serial.c inflow.c regex.c init.c \
- c-exp.tab.c ch-exp.tab.c m2-exp.tab.c version.c i386-dis.c dis-buf.c
+SRCS = annotate.c blockframe.c breakpoint.c buildsym.c c-lang.c \
+ c-typeprint.c c-valprint.c ch-lang.c ch-typeprint.c \
+ ch-valprint.c coffread.c command.c complaints.c copying.c core.c \
+ coredep.c corelow.c cp-valprint.c \
+ dcache.c dbxread.c demangle.c disassemble.c dis-buf.c dwarfread.c \
+ elfread.c environ.c eval.c exec.c expprint.c \
+ findvar.c fork-child.c freebsd-nat.c gdbtypes.c i386-dis.c \
+ i386-pinsn.c i386-tdep.c infcmd.c inflow.c infptrace.c \
+ infrun.c inftarg.c init.c kcorelow.c language.c \
+ m2-lang.c m2-typeprint.c m2-valprint.c main.c maint.c \
+ mem-break.c minsyms.c objfiles.c parse.c \
+ printcmd.c regex.c remote.c remote-utils.c solib.c source.c \
+ stabsread.c stack.c symfile.c symmisc.c \
+ symtab.c target.c thread.c top.c \
+ typeprint.c utils.c valarith.c valops.c \
+ valprint.c values.c version.c serial.c ser-unix.c mdebugread.c\
+ c-exp.tab.c ch-exp.tab.c m2-exp.tab.c
c-exp.tab.c: $(.CURDIR)/c-exp.y
yacc -d -p c_ $(.CURDIR)/c-exp.y
@@ -40,7 +44,6 @@ m2-exp.tab.c: $(.CURDIR)/m2-exp.y
mv m2-exp.new ./m2-exp.tab.c
-
CFLAGS+= -I$(.CURDIR)/. -I${DESTDIR}/usr/include/readline -I$(.CURDIR)/../bfd
DPADD+= ${LIBREADLINE} ${LIBTERMCAP}
LDADD+= -lreadline -ltermcap
diff --git a/gnu/usr.bin/binutils/gdb/gdb.1 b/gnu/usr.bin/binutils/gdb/gdb.1
index ccb216e..ee14f70 100644
--- a/gnu/usr.bin/binutils/gdb/gdb.1
+++ b/gnu/usr.bin/binutils/gdb/gdb.1
@@ -1,6 +1,6 @@
.\" Copyright (c) 1991 Free Software Foundation
.\" See section COPYING for conditions for redistribution
-.\" $Id: gdb.1,v 1.1.1.1 1993/10/30 21:59:13 jkh Exp $
+.\" $Id: gdb.1,v 1.1 1994/01/28 12:39:43 pk Exp $
.TH gdb 1 "4nov1991" "GNU Tools" "GNU Tools"
.SH NAME
gdb \- The GNU Debugger
diff --git a/gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c b/gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c
index deb68eb..ba742a3 100644
--- a/gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c
+++ b/gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c
@@ -15,10 +15,20 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#include "defs.h"
+ $Id: freebsd-nat.c,v 1.3 1994/05/18 12:43:13 pk Exp $
+*/
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <signal.h>
+#include <sys/user.h>
#include <machine/reg.h>
+#include <machine/frame.h>
+#include <sys/ptrace.h>
+
+#include "defs.h"
/* this table must line up with REGISTER_NAMES in tm-i386.h */
/* symbols like 'tEAX' come from <machine/reg.h> */
@@ -28,14 +38,7 @@ static int tregmap[] =
tESP, tEBP, tESI, tEDI,
tEIP, tEFLAGS, tCS, tSS
};
-#ifdef sEAX
-static int sregmap[] =
-{
- sEAX, sECX, sEDX, sEBX,
- sESP, sEBP, sESI, sEDI,
- sEIP, sEFLAGS, sCS, sSS
-};
-#endif
+
/* blockend is the value of u.u_ar0, and points to the
place where ES is stored. */
@@ -44,45 +47,14 @@ i386_register_u_addr (blockend, regnum)
int blockend;
int regnum;
{
- /* The following condition is a kludge to get at the proper register map
- depending upon the state of pcb_flag.
- The proper condition would be
- if (u.u_pcb.pcb_flag & FM_TRAP)
- but that would require a ptrace call here and wouldn't work
- for corefiles. */
-
-#ifdef sEAX
- if (blockend < 0x1fcc)
return (blockend + 4 * tregmap[regnum]);
- else
- return (blockend + 4 * sregmap[regnum]);
-#else
- return (blockend + 4 * tregmap[regnum]);
-#endif
}
-#ifdef FLOAT_INFO
-#include <sys/param.h>
-#include <sys/dir.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-
-#include <a.out.h>
-
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/uio.h>
-#define curpcb Xcurpcb /* XXX avoid leaking declaration from pcb.h */
-#include <sys/user.h>
-#undef curpcb
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/ptrace.h>
#define fpstate save87
#define U_FPSTATE(u) u.u_pcb.pcb_savefpu
+static void
i387_to_double (from, to)
char *from;
char *to;
@@ -113,6 +85,7 @@ i387_to_double (from, to)
asm ("popl %eax"); /* flush saved copy */
}
+static void
double_to_i387 (from, to)
char *from;
char *to;
@@ -209,7 +182,7 @@ print_387_status_word (status)
printf ("top %d\n", (status >> 11) & 7);
}
-static
+static void
print_387_status (status, ep)
unsigned short status;
struct env387 *ep;
@@ -271,6 +244,7 @@ print_387_status (status, ep)
}
}
+void
i386_float_info ()
{
struct user u; /* just for address computations */
@@ -320,4 +294,319 @@ i386_float_info ()
print_387_status (0, (struct env387 *)buf);
}
+void
+clear_regs()
+{
+ return;
+}
+
+#ifdef KERNEL_DEBUG
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <unistd.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <machine/vmparam.h>
+#include <machine/pcb.h>
+
+#define KERNOFF ((unsigned)KERNBASE)
+#define INKERNEL(x) ((x) >= KERNOFF)
+
+static CORE_ADDR sbr;
+static CORE_ADDR curpcb;
+static CORE_ADDR kstack;
+static int found_pcb;
+static int devmem;
+static int kfd;
+static struct pcb pcb;
+int read_pcb (int, CORE_ADDR);
+static CORE_ADDR kvtophys (int, CORE_ADDR);
+static physrd(int, u_int, char*, int);
+
+extern CORE_ADDR ksym_lookup(const char *);
+
+/* substitutes for the stuff in libkvm which doesn't work */
+/* most of this was taken from the old kgdb */
+
+/* we don't need all this stuff, but the call should look the same */
+kvm_open (efile, cfile, sfile, perm, errout)
+char *efile;
+char *cfile;
+void *sfile;
+int perm;
+int errout;
+{
+ struct stat stb;
+ CORE_ADDR addr;
+ int cfd;
+
+ if ((cfd = open(cfile, perm, 0)) < 0)
+ return (cfd);
+
+ fstat(cfd, &stb);
+ if ((stb.st_mode & S_IFMT) == S_IFCHR && stb.st_rdev == makedev(2, 0)) {
+ devmem = 1;
+ kfd = open ("/dev/kmem", perm, 0);
+ }
+
+ physrd(cfd, ksym_lookup("IdlePTD") - KERNOFF, (char*)&sbr, sizeof sbr);
+ printf("IdlePTD %x\n", sbr);
+ curpcb = ksym_lookup("curpcb") - KERNOFF;
+ physrd(cfd, curpcb, (char*)&curpcb, sizeof curpcb);
+ kstack = ksym_lookup("kstack");
+
+ found_pcb = 1; /* for vtophys */
+ if (!devmem)
+ read_pcb(cfd, ksym_lookup("dumppcb") - KERNOFF);
+ else
+ read_pcb(cfd, kvtophys(cfd, kstack));
+
+ return (cfd);
+}
+
+kvm_close (fd)
+{
+ return (close (fd));
+}
+
+kvm_write(core_kd, memaddr, myaddr, len)
+CORE_ADDR memaddr;
+char *myaddr;
+{
+ int cc;
+
+ if (devmem) {
+ if (kfd > 0) {
+ /*
+ * Just like kvm_read, only we write.
+ */
+ errno = 0;
+ if (lseek(kfd, (off_t)memaddr, 0) < 0 && errno != 0) {
+ error("kvm_write:invalid address (%x)", memaddr);
+ return (0);
+ }
+ cc = write(kfd, myaddr, len);
+ if (cc < 0) {
+ error("kvm_write:write failed");
+ return (0);
+ } else if (cc < len)
+ error("kvm_write:short write");
+ return (cc);
+ } else
+ return (0);
+ } else {
+ printf("kvm_write not implemented for dead kernels\n");
+ return (0);
+ }
+ /* NOTREACHED */
+}
+
+kvm_read(core_kd, memaddr, myaddr, len)
+CORE_ADDR memaddr;
+char *myaddr;
+{
+ return (kernel_core_file_hook (core_kd, memaddr, myaddr, len));
+}
+
+kvm_uread(core_kd, p, memaddr, myaddr, len)
+register struct proc *p;
+CORE_ADDR memaddr;
+char *myaddr;
+{
+ register char *cp;
+ char procfile[MAXPATHLEN];
+ ssize_t amount;
+ int fd;
+
+ if (devmem) {
+ cp = myaddr;
+
+ sprintf(procfile, "/proc/%d/mem", p->p_pid);
+ fd = open(procfile, O_RDONLY, 0);
+
+ if (fd < 0) {
+ error("cannot open %s", procfile);
+ close(fd);
+ return (0);
+ }
+
+ while (len > 0) {
+ if (lseek(fd, memaddr, 0) == -1 && errno != 0) {
+ error("invalid address (%x) in %s",
+ memaddr, procfile);
+ break;
+ }
+ amount = read(fd, cp, len);
+ if (amount < 0) {
+ error("error reading %s", procfile);
+ break;
+ }
+ cp += amount;
+ memaddr += amount;
+ len -= amount;
+ }
+
+ close(fd);
+ return (ssize_t)(cp - myaddr);
+ } else {
+ return (kernel_core_file_hook (core_kd, memaddr, myaddr, len));
+ }
+}
+
+static
+physrd(cfd, addr, dat, len)
+u_int addr;
+char *dat;
+{
+ if (lseek(cfd, (off_t)addr, L_SET) == -1)
+ return (-1);
+ return (read(cfd, dat, len));
+}
+
+static CORE_ADDR
+kvtophys (fd, addr)
+CORE_ADDR addr;
+{
+ CORE_ADDR v;
+ struct pte pte;
+ static CORE_ADDR PTD = -1;
+ CORE_ADDR current_ptd;
+
+ /*if (devmem && kfd > 0)
+ return (addr);
+ /*
+ * If we're looking at the kernel stack,
+ * munge the address to refer to the user space mapping instead;
+ * that way we get the requested process's kstack, not the running one.
+ */
+ if (addr >= kstack && addr < kstack + ctob(UPAGES))
+ addr = (addr - kstack) + curpcb;
+
+ /*
+ * We may no longer have a linear system page table...
+ *
+ * Here's the scoop. IdlePTD contains the physical address
+ * of a page table directory that always maps the kernel.
+ * IdlePTD is in memory that is mapped 1-to-1, so we can
+ * find it easily given its 'virtual' address from ksym_lookup().
+ * For hysterical reasons, the value of IdlePTD is stored in sbr.
+ *
+ * To look up a kernel address, we first convert it to a 1st-level
+ * address and look it up in IdlePTD. This gives us the physical
+ * address of a page table page; we extract the 2nd-level part of
+ * VA and read the 2nd-level pte. Finally, we add the offset part
+ * of the VA into the physical address from the pte and return it.
+ *
+ * User addresses are a little more complicated. If we don't have
+ * a current PCB from read_pcb(), we use PTD, which is the (fixed)
+ * virtual address of the current ptd. Since it's NOT in 1-to-1
+ * kernel space, we must look it up using IdlePTD. If we do have
+ * a pcb, we get the ptd from pcb_ptd.
+ */
+
+ if (INKERNEL(addr))
+ current_ptd = sbr;
+ else if (found_pcb == 0) {
+ if (PTD == -1)
+ PTD = kvtophys(fd, ksym_lookup("PTD"));
+ current_ptd = PTD;
+ } else
+ current_ptd = pcb.pcb_ptd;
+
+ /*
+ * Read the first-level page table (ptd).
+ */
+ v = current_ptd + ((unsigned)addr >> PD_SHIFT) * sizeof pte;
+ if (physrd(fd, v, (char *)&pte, sizeof pte) < 0 || pte.pg_v == 0)
+ return (~0);
+
+ /*
+ * Read the second-level page table.
+ */
+ v = i386_ptob(pte.pg_pfnum) + ((addr&PT_MASK) >> PG_SHIFT) * sizeof pte;
+ if (physrd(fd, v, (char *) &pte, sizeof(pte)) < 0 || pte.pg_v == 0)
+ return (~0);
+
+ addr = i386_ptob(pte.pg_pfnum) + (addr & PGOFSET);
+#if 0
+ printf("vtophys(%x) -> %x\n", oldaddr, addr);
+#endif
+ return (addr);
+}
+
+read_pcb (fd, uaddr)
+CORE_ADDR uaddr;
+{
+ int i;
+ int *pcb_regs = (int *)&pcb;
+ int eip;
+
+ if (physrd(fd, uaddr, (char *)&pcb, sizeof pcb) < 0) {
+ error("cannot read pcb at %x\n", uaddr);
+ return (-1);
+ }
+ printf("current pcb at %x\n", uaddr);
+
+ /*
+ * get the register values out of the sys pcb and
+ * store them where `read_register' will find them.
+ */
+ for (i = 0; i < 8; ++i)
+ supply_register(i, &pcb_regs[i+10]);
+ supply_register(8, &pcb_regs[8]); /* eip */
+ supply_register(9, &pcb_regs[9]); /* eflags */
+ for (i = 10; i < 13; ++i) /* cs, ss, ds */
+ supply_register(i, &pcb_regs[i+9]);
+ supply_register(13, &pcb_regs[18]); /* es */
+ for (i = 14; i < 16; ++i) /* fs, gs */
+ supply_register(i, &pcb_regs[i+8]);
+
+#if 0 /* doesn't work ??? */
+ /* Hmm... */
+ if (target_read_memory(pcb_regs[5+10]+4, &eip, sizeof eip, 0))
+ error("Cannot read PC.");
+ supply_register(8, &eip); /* eip */
#endif
+
+ /* XXX 80387 registers? */
+}
+
+/*
+ * read len bytes from kernel virtual address 'addr' into local
+ * buffer 'buf'. Return numbert of bytes if read ok, 0 otherwise. On read
+ * errors, portion of buffer not read is zeroed.
+ */
+kernel_core_file_hook(fd, addr, buf, len)
+ CORE_ADDR addr;
+ char *buf;
+ int len;
+{
+ int i;
+ CORE_ADDR paddr;
+ register char *cp;
+ int cc;
+
+ cp = buf;
+
+ while (len > 0) {
+ paddr = kvtophys(fd, addr);
+ if (paddr == ~0) {
+ bzero(buf, len);
+ break;
+ }
+ /* we can't read across a page boundary */
+ i = min(len, NBPG - (addr & PGOFSET));
+ if ((cc = physrd(fd, paddr, cp, i)) <= 0) {
+ bzero(cp, len);
+ return (cp - buf);
+ }
+ cp += cc;
+ addr += cc;
+ len -= cc;
+ }
+ return (cp - buf);
+}
+#endif /* KERNEL_DEBUG */
diff --git a/gnu/usr.bin/binutils/gdb/i386/nm.h b/gnu/usr.bin/binutils/gdb/i386/nm.h
index a7af00f..65c7337 100644
--- a/gnu/usr.bin/binutils/gdb/i386/nm.h
+++ b/gnu/usr.bin/binutils/gdb/i386/nm.h
@@ -40,5 +40,61 @@ extern int
i386_register_u_addr PARAMS ((int, int));
#define PTRACE_ARG3_TYPE char*
+#define ATTACH_DETACH
+#define KERNEL_DEBUG
+
+/* make structure definitions match up with those expected in solib.c */
+
+#define link_object sod
+#define lo_name sod_name
+#define lo_library sod_library
+#define lo_unused sod_reserved
+#define lo_major sod_major
+#define lo_minor sod_minor
+#define lo_next sod_next
+
+#define link_map so_map
+#define lm_addr som_addr
+#define lm_name som_path
+#define lm_next som_next
+#define lm_lop som_sod
+#define lm_lob som_sodbase
+#define lm_rwt som_write
+#define lm_ld som_dynamic
+#define lm_lpd som_spd
+
+#define link_dynamic_2 section_dispatch_table
+#define ld_loaded sdt_loaded
+#define ld_need sdt_sods
+#define ld_rules sdt_filler1
+#define ld_got sdt_got
+#define ld_plt sdt_plt
+#define ld_rel sdt_rel
+#define ld_hash sdt_hash
+#define ld_stab sdt_nzlist
+#define ld_stab_hash sdt_filler2
+#define ld_buckets sdt_buckets
+#define ld_symbols sdt_strings
+#define ld_symb_size sdt_str_sz
+#define ld_text sdt_text_sz
+#define ld_plt_sz sdt_plt_sz
+
+#define rtc_symb rt_symbol
+#define rtc_sp rt_sp
+#define rtc_next rt_next
+
+#define ld_debug so_debug
+#define ldd_version dd_version
+#define ldd_in_debugger dd_in_debugger
+#define ldd_sym_loaded dd_sym_loaded
+#define ldd_bp_addr dd_bpt_addr
+#define ldd_bp_inst dd_bpt_shadow
+#define ldd_cp dd_cc
+
+#define link_dynamic _dynamic
+#define ld_version d_version
+#define ldd d_debug
+#define ld_un d_un
+#define ld_2 d_sdt
#endif /* NM_FREEBSD_H */
diff --git a/gnu/usr.bin/binutils/gdb/i386/tm.h b/gnu/usr.bin/binutils/gdb/i386/tm.h
index 25b66c7..a33a668 100644
--- a/gnu/usr.bin/binutils/gdb/i386/tm.h
+++ b/gnu/usr.bin/binutils/gdb/i386/tm.h
@@ -68,7 +68,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Offset to saved PC in sigcontext, from <sys/signal.h>. */
#define SIGCONTEXT_PC_OFFSET 20
-#undef FRAME_SAVED_PC(FRAME)
+#undef FRAME_SAVED_PC
#define FRAME_SAVED_PC(FRAME) \
(((FRAME)->signal_handler_caller \
? sigtramp_saved_pc (FRAME) \
diff --git a/gnu/usr.bin/binutils/gdb/i386/version.c b/gnu/usr.bin/binutils/gdb/i386/version.c
index d32e958..43f63d2 100644
--- a/gnu/usr.bin/binutils/gdb/i386/version.c
+++ b/gnu/usr.bin/binutils/gdb/i386/version.c
@@ -1,3 +1,3 @@
-char *version = "4.11";
-char *host_canonical = "i386-unknown-freebsd";
-char *target_canonical = "i386-unknown-freebsd";
+char *version = "4.13";
+char *host_name = "i386-unknown-freebsd";
+char *target_name = "i386-unknown-freebsd";
diff --git a/gnu/usr.bin/binutils/gdb/i386/xm.h b/gnu/usr.bin/binutils/gdb/i386/xm.h
index fe5fe76..6a71227 100644
--- a/gnu/usr.bin/binutils/gdb/i386/xm.h
+++ b/gnu/usr.bin/binutils/gdb/i386/xm.h
@@ -26,8 +26,4 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define PSIGNAL_IN_SIGNAL_H
-/* Get rid of any system-imposed stack limit if possible. */
-
-#define SET_STACK_LIMIT_HUGE
-
#define HAVE_TERMIOS
OpenPOWER on IntegriCloud