Remove old bmake framework for gdb. It has moved to live next to binutils.

This commit is contained in:
Doug Rabson 1999-05-02 19:51:47 +00:00
parent e3af075499
commit 227d42bebc
23 changed files with 0 additions and 5425 deletions

View file

@ -1,3 +0,0 @@
SUBDIR= bfd libiberty gdb doc gdbreplay gdbserver
.include <bsd.subdir.mk>

View file

@ -1,7 +0,0 @@
# $Id: Makefile.inc,v 1.5 1998/10/15 00:15:01 peter Exp $
CFLAGS+=-I${GDBDIR}/include -I${GDBDIR}/gdb -I${GDBDIR}/bfd
CFLAGS+=-I${GDBDIR}/libiberty -I${GDBDIR}/gdb/config
CFLAGS+=-DHAVE_CONFIG_H
.include "../Makefile.inc"

View file

@ -1,31 +0,0 @@
LIB = bfd
GDBDIR= ${.CURDIR}/../../../../contrib/gdb
.PATH: ${GDBDIR}/bfd
SRCS = libbfd.c opncls.c bfd.c archive.c targets.c cache.c \
archures.c coff-i386.c aout32.c \
srec.c \
ecoff.c ecofflink.c \
coffgen.c format.c \
section.c syms.c stab-syms.c reloc.c init.c \
trad-core.c \
i386aout.c \
i386freebsd.c i386bsd.c \
cpu-i386.c \
elf.c \
hash.c linker.c corefile.c binary.c \
tekhex.c ihex.c
CFLAGS+= -I${.CURDIR}/. -I${.CURDIR}/../gdb/.
CFLAGS+= -DDEFAULT_VECTOR=i386freebsd_vec \
-DSELECT_VECS='&i386freebsd_vec,&i386bsd_vec' \
-DSELECT_ARCHITECTURES='&bfd_i386_arch' -DTRAD_CORE
NOPROFILE=no
NOPIC=no
install:
@echo -n
.include <bsd.lib.mk>

File diff suppressed because it is too large Load diff

View file

@ -1,68 +0,0 @@
/* config.h. Generated automatically by configure. */
/* config.in. Generated automatically from configure.in by autoheader. */
/* Whether malloc must be declared even if <stdlib.h> is included. */
/* #undef NEED_DECLARATION_MALLOC */
/* Whether free must be declared even if <stdlib.h> is included. */
/* #undef NEED_DECLARATION_FREE */
/* Define if you have a working `mmap' system call. */
#define HAVE_MMAP 1
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
/* Do we need to use the b modifier when opening binary files? */
/* #undef USE_BINARY_FOPEN */
/* Name of host specific header file to include in trad-core.c. */
#define TRAD_HEADER "i386freebsd.h"
/* Define only if <sys/procfs.h> is available *and* it defines prstatus_t. */
#define HAVE_SYS_PROCFS_H 1
/* Do we really want to use mmap if it's available? */
/* #undef USE_MMAP */
/* Define if you have the fcntl function. */
#define HAVE_FCNTL 1
/* Define if you have the getpagesize function. */
#define HAVE_GETPAGESIZE 1
/* Define if you have the madvise function. */
#define HAVE_MADVISE 1
/* Define if you have the mprotect function. */
#define HAVE_MPROTECT 1
/* Define if you have the valloc function. */
#define HAVE_VALLOC 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define if you have the <stddef.h> header file. */
#define HAVE_STDDEF_H 1
/* Define if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define if you have the <sys/file.h> header file. */
#define HAVE_SYS_FILE_H 1
/* Define if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1

View file

@ -1,24 +0,0 @@
/* Intel 386 running any FreeBSD Unix */
#include <machine/param.h>
#include <machine/vmparam.h>
#define NBPG PAGE_SIZE
#define HOST_PAGE_SIZE NBPG
#define HOST_MACHINE_ARCH bfd_arch_i386
#define HOST_TEXT_START_ADDR USRTEXT
/* Jolitz suggested defining HOST_STACK_END_ADDR to
(u.u_kproc.kp_eproc.e_vm.vm_maxsaddr + MAXSSIZ), which should work on
both BSDI and 386BSD, but that is believed not to work for BSD 4.4. */
/* This seems to be the right thing for FreeBSD and BSDI */
#define HOST_STACK_END_ADDR USRSTACK
/* Leave HOST_DATA_START_ADDR undefined, since the default when it is not
defined sort of works, and FreeBSD-2.0 through FreeBSD-2.2.2 do not
set u.u_kproc.kp_eproc.e_vm.vm_daddr. */
#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \
((core_bfd)->tdata.trad_core_data->u.u_sig)
#define u_comm u_kproc.kp_proc.p_comm

View file

@ -1,24 +0,0 @@
# $Id$
INFO= annotate gdb gdbint stabs
CONTRIBDIR= ${.CURDIR}/../../../../contrib
SRCDIR= ${CONTRIBDIR}/gdb/gdb/doc
MAKEINFOFLAGS+= -I ${CONTRIBDIR}/libreadline/doc
CLEANFILES= gdb-cfg.texi inc-hist.texi inc-hist.texi.orig
INFOSECTION= "Gdb Documentation"
INFOENTRY_annotate= "* GDB annotation: (annotate). Annotations for the GNU Debugger (GDB)."
gdb.info: gdb.texinfo gdb-cfg.texi GDBvn.texi remote.texi \
rluser.texinfo inc-hist.texi
gdb-cfg.texi: all-cfg.texi
ln -sf ${.ALLSRC} ${.TARGET}
.PATH: ${CONTRIBDIR}/libreadline/doc
inc-hist.texi: hsuser.texinfo inc-hist.diff
cp ${.ALLSRC:M*.texinfo} ${.TARGET}
patch -b .orig < ${.ALLSRC:M*.diff}
.include <bsd.info.mk>

View file

@ -1,131 +0,0 @@
# $Id: Makefile,v 1.38 1998/10/15 14:15:09 bde Exp $
PROG = gdb
GDBDIR= ${.CURDIR}/../../../../contrib/gdb
.if ${OBJFORMAT} == elf
BFDDIR= ${.CURDIR}/../../binutils/libbfd/${MACHINE_ARCH}
BINDIR= /usr/libexec/elf
.else
BFDDIR= ${.CURDIR}/../bfd
BINDIR= /usr/libexec/aout
.endif
.PATH: ${GDBDIR}/gdb
.PATH: ${GDBDIR}/opcodes
.if ${OBJFORMAT} == elf
CFLAGS+= -DFREEBSD_ELF
.endif
XSRCS = 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-regset.c corelow.c cp-valprint.c \
dcache.c dbxread.c demangle.c dwarfread.c \
elfread.c environ.c eval.c exec.c expprint.c \
findvar.c fork-child.c freebsd-nat.c gdbtypes.c \
i386-tdep.c infcmd.c inflow.c infptrace.c \
infrun.c inftarg.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 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 ser-tcp.c mdebugread.c \
c-exp.y f-exp.y m2-exp.y i387-tdep.c \
kvm-fbsd.c bcache.c \
corefile.c ch-exp.c f-lang.c scm-exp.c scm-lang.c \
scm-valprint.c f-typeprint.c f-valprint.c nlmread.c \
callback.c
XSRCS+= i386-dis.c dis-buf.c disassemble.c
SRCS= init.c ${XSRCS}
CFLAGS+= -I$(.CURDIR) -I${DESTDIR}/usr/include/readline -I${BFDDIR}
# use phkmalloc
CFLAGS+= -DNO_MMALLOC
# uncomment the next line if you want to debug gdb
#CFLAGS+= -g
YFLAGS=
CLEANFILES= init.c init.c-tmp
.if ${OBJFORMAT} == elf
.if exists(${.OBJDIR}/../../binutils/libbfd)
LIBBFD= ${.OBJDIR}/../../binutils/libbfd/libbfd.a
.else
LIBBFD= ${.CURDIR}/../../binutils/libbfd/libbfd.a
.endif
.if exists(${.OBJDIR}/../../binutils/libiberty)
LIBIBERTY= ${.OBJDIR}/../../binutils/libiberty/libiberty.a
.else
LIBIBERTY= ${.CURDIR}/../../binutils/libiberty/libiberty.a
.endif
.else
.if exists(${.OBJDIR}/../bfd)
LIBBFD= ${.OBJDIR}/../bfd/libbfd.a
.else
LIBBFD= ${.CURDIR}/../bfd/libbfd.a
.endif
.if exists(${.OBJDIR}/../libiberty)
LIBIBERTY= ${.OBJDIR}/../libiberty/libiberty.a
.else
LIBIBERTY= ${.CURDIR}/../libiberty/libiberty.a
.endif
.endif # OBJFORMAT
DPADD= ${LIBBFD} ${LIBREADLINE} ${LIBGNUREGEX} ${LIBIBERTY} ${LIBTERMCAP}
LDADD= ${LIBBFD} -lreadline -lgnuregex ${LIBIBERTY} -ltermcap
DPADD+= ${LIBIBERTY}
LDADD+= ${LIBIBERTY}
# We do this by grepping through sources. If that turns out to be too slow,
# maybe we could just require every .o file to have an initialization routine
# of a given name (remote-udi.o -> _initialize_remote_udi, etc.).
#
# Formatting conventions: The name of the _initialize_* routines must start
# in column zero, and must not be inside #if.
#
# Note that the set of files with init functions might change, or the names
# of the functions might change, so this files needs to depend on all the
# object files that will be linked into gdb.
init.c: ${XSRCS}
@${ECHO} Making ${.TARGET}
@rm -f init.c-tmp
@echo '/* Do not modify this file. */' >init.c-tmp
@echo '/* It is created automatically by the Makefile. */'>>init.c-tmp
@echo 'void initialize_all_files () {' >>init.c-tmp
@for i in ${.ALLSRC} ; do \
filename=`echo $$i | sed \
-e '/^Onindy.c/d' \
-e '/^nindy.c/d' \
-e '/ttyflush.c/d' \
-e '/xdr_ld.c/d' \
-e '/xdr_ptrace.c/d' \
-e '/xdr_rdb.c/d' \
-e '/udr.c/d' \
-e '/udip2soc.c/d' \
-e '/udi2go32.c/d' \
-e '/version.c/d' \
-e '/^[a-z0-9A-Z_]*_[SU].c/d' \
-e '/[a-z0-9A-Z_]*-exp.tab.c/d'` ; \
case $$filename in \
"") ;; \
*) sed <$$filename >>init.c-tmp -n \
-e '/^_initialize_[a-z_0-9A-Z]* *(/s/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (); \1 ();}/p' ; ;; \
esac ; \
done
@echo '}' >>init.c-tmp
@mv init.c-tmp ${.TARGET}
.PRECIOUS: init.c
.include <bsd.prog.mk>

View file

@ -1,91 +0,0 @@
/* config.h. Generated automatically by configure. */
/* config.in. Generated automatically from configure.in by autoheader. */
/* Define if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
#ifndef _ALL_SOURCE
/* #undef _ALL_SOURCE */
#endif
/* Define if the `long double' type works. */
#define HAVE_LONG_DOUBLE 1
/* Define if you have a working `mmap' system call. */
#define HAVE_MMAP 1
/* Define if on MINIX. */
/* #undef _MINIX */
/* Define if the system does not provide POSIX.1 features except
with this defined. */
/* #undef _POSIX_1_SOURCE */
/* Define if you need to in order for stat and other things to work. */
/* #undef _POSIX_SOURCE */
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
/* #undef STAT_MACROS_BROKEN */
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define if fpregset_t type is available. */
#define HAVE_FPREGSET_T 1
/* Define if gregset_t type is available. */
#define HAVE_GREGSET_T 1
/* Define if the "%Lg" format works to print long doubles. */
#define PRINTF_HAS_LONG_DOUBLE 1
/* Define if you have the getpagesize function. */
#define HAVE_GETPAGESIZE 1
/* Define if you have the sbrk function. */
#define HAVE_SBRK 1
/* Define if you have the setpgid function. */
#define HAVE_SETPGID 1
/* Define if you have the valloc function. */
#define HAVE_VALLOC 1
/* Define if you have the <endian.h> header file. */
/* #undef HAVE_ENDIAN_H */
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define if you have the <link.h> header file. */
#define HAVE_LINK_H 1
/* Define if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define if you have the <sgtty.h> header file. */
#define HAVE_SGTTY_H 1
/* Define if you have the <stddef.h> header file. */
#define HAVE_STDDEF_H 1
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define if you have the <sys/procfs.h> header file. */
#define HAVE_SYS_PROCFS_H 1
/* Define if you have the <termio.h> header file. */
/* #undef HAVE_TERMIO_H */
/* Define if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 1
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define if you have the dl library (-ldl). */
/* #undef HAVE_LIBDL */

View file

@ -1,440 +0,0 @@
/* Native-dependent code for BSD Unix running on i386's, for GDB.
Copyright 1988, 1989, 1991, 1992, 1994, 1996 Free Software Foundation, Inc.
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. */
#include "defs.h"
#include <sys/types.h>
#include <sys/ptrace.h>
#include <machine/reg.h>
#include <machine/frame.h>
#include <sys/param.h>
#include <sys/user.h>
#include "gdbcore.h"
#include "value.h"
#include "inferior.h"
#if defined(HAVE_GREGSET_T) || defined(HAVE_FPREGSET_T)
#include <sys/procfs.h>
#endif
/* this table must line up with REGISTER_NAMES in tm-i386v.h */
/* symbols like 'tEAX' come from <machine/reg.h> */
static int tregmap[] =
{
tEAX, tECX, tEDX, tEBX,
tESP, tEBP, tESI, tEDI,
tEIP, tEFLAGS, tCS, tSS,
tDS, tES, tFS, tGS,
};
static struct save87 pcb_savefpu;
void
fetch_inferior_registers (regno)
int regno;
{
struct reg inferior_registers; /* ptrace order, not gcc/gdb order */
int r;
ptrace (PT_GETREGS, inferior_pid,
(PTRACE_ARG3_TYPE) &inferior_registers, 0);
for (r = 0; r < NUM_REGS; r++)
memcpy (&registers[REGISTER_BYTE (r)], ((int *)&inferior_registers) + tregmap[r], 4);
registers_fetched ();
}
void
store_inferior_registers (regno)
int regno;
{
struct reg inferior_registers; /* ptrace order, not gcc/gdb order */
int r;
for (r = 0; r < NUM_REGS; r++)
memcpy (((int *)&inferior_registers) + tregmap[r], &registers[REGISTER_BYTE (r)], 4);
ptrace (PT_SETREGS, inferior_pid,
(PTRACE_ARG3_TYPE) &inferior_registers, 0);
}
/* Extract the register values out of the core file and store
them where `read_register' will find them.
Extract the floating point state out of the core file and store
it where `float_info' will find it.
CORE_REG_SECT points to the register values themselves, read into memory.
CORE_REG_SIZE is the size of that area.
WHICH says which set of registers we are handling (0 = int, 2 = float
on machines where they are discontiguous).
REG_ADDR is the offset from u.u_ar0 to the register values relative to
core_reg_sect. This is used with old-fashioned core files to
locate the registers in a large upage-plus-stack ".reg" section.
Original upage address X is at location core_reg_sect+x+reg_addr.
*/
static void
fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which;
CORE_ADDR reg_addr;
{
register int regno;
register int cregno;
register int addr;
int bad_reg = -1;
int offset;
struct user *tmp_uaddr;
/*
* First get virtual address of user structure. Then calculate offset.
*/
memcpy(&tmp_uaddr,
&((struct user *) core_reg_sect)->u_kproc.kp_proc.p_addr,
sizeof(tmp_uaddr));
offset = -reg_addr - (int) tmp_uaddr;
for (regno = 0; regno < NUM_REGS; regno++)
{
cregno = tregmap[regno];
if (cregno == tGS)
addr = offsetof (struct user, u_pcb) + offsetof (struct pcb, pcb_gs);
else
addr = offset + 4 * cregno;
if (addr < 0 || addr >= core_reg_size)
{
if (bad_reg < 0)
bad_reg = regno;
}
else
{
supply_register (regno, core_reg_sect + addr);
}
}
if (bad_reg >= 0)
{
error ("Register %s not found in core file.", reg_names[bad_reg]);
}
addr = offsetof (struct user, u_pcb) + offsetof (struct pcb, pcb_savefpu);
memcpy (&pcb_savefpu, core_reg_sect + addr, sizeof pcb_savefpu);
}
#ifdef FLOAT_INFO
#include "expression.h"
#include "language.h" /* for local_hex_string */
#include "floatformat.h"
#include <sys/param.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 "gdb_stat.h"
#include <sys/ptrace.h>
extern void print_387_control_word (); /* i387-tdep.h */
extern void print_387_status_word ();
#define fpstate save87
#define U_FPSTATE(u) u.u_pcb.pcb_savefpu
static void
i387_to_double (from, to)
char *from;
char *to;
{
long *lp;
/* push extended mode on 387 stack, then pop in double mode
*
* first, set exception masks so no error is generated -
* number will be rounded to inf or 0, if necessary
*/
asm ("pushl %eax"); /* grab a stack slot */
asm ("fstcw (%esp)"); /* get 387 control word */
asm ("movl (%esp),%eax"); /* save old value */
asm ("orl $0x3f,%eax"); /* mask all exceptions */
asm ("pushl %eax");
asm ("fldcw (%esp)"); /* load new value into 387 */
asm ("movl 8(%ebp),%eax");
asm ("fldt (%eax)"); /* push extended number on 387 stack */
asm ("fwait");
asm ("movl 12(%ebp),%eax");
asm ("fstpl (%eax)"); /* pop double */
asm ("fwait");
asm ("popl %eax"); /* flush modified control word */
asm ("fnclex"); /* clear exceptions */
asm ("fldcw (%esp)"); /* restore original control word */
asm ("popl %eax"); /* flush saved copy */
}
struct env387
{
unsigned short control;
unsigned short r0;
unsigned short status;
unsigned short r1;
unsigned short tag;
unsigned short r2;
unsigned long eip;
unsigned short code_seg;
unsigned short opcode;
unsigned long operand;
unsigned short operand_seg;
unsigned short r3;
unsigned char regs[8][10];
};
static void
print_387_status (status, ep)
unsigned short status;
struct env387 *ep;
{
int i;
int bothstatus;
int top;
int fpreg;
bothstatus = ((status != 0) && (ep->status != 0));
if (status != 0)
{
if (bothstatus)
printf_unfiltered ("u: ");
print_387_status_word ((unsigned int)status);
}
if (ep->status != 0)
{
if (bothstatus)
printf_unfiltered ("e: ");
print_387_status_word ((unsigned int)ep->status);
}
print_387_control_word ((unsigned int)ep->control);
printf_unfiltered ("last instruction: ");
printf_unfiltered ("opcode %s; ", local_hex_string(ep->opcode));
printf_unfiltered ("pc %s:", local_hex_string(ep->code_seg));
printf_unfiltered ("%s; ", local_hex_string(ep->eip));
printf_unfiltered ("operand %s", local_hex_string(ep->operand_seg));
printf_unfiltered (":%s\n", local_hex_string(ep->operand));
top = (ep->status >> 11) & 7;
printf_unfiltered (" regno tag msb lsb value\n");
for (fpreg = 7; fpreg >= 0; fpreg--)
{
int exp;
int mantissa_or;
int normal;
char *sign;
int st_regno;
unsigned short *usregs;
double val;
/* The physical regno `fpreg' is only relevant as an index into the
* tag word. Logical `%st' numbers are required for indexing ep->regs.
*/
st_regno = (fpreg + 8 - top) & 7;
printf_unfiltered ("%%st(%d) %s ", st_regno, fpreg == top ? "=>" : " ");
switch ((ep->tag >> (fpreg * 2)) & 3)
{
case 0: printf_unfiltered ("valid "); break;
case 1: printf_unfiltered ("zero "); break;
case 2: printf_unfiltered ("trap "); break;
case 3: printf_unfiltered ("empty "); break;
}
for (i = 9; i >= 0; i--)
printf_unfiltered ("%02x", ep->regs[st_regno][i]);
printf_unfiltered (" ");
/*
* Handle weird cases better than floatformat_to_double () and
* printf ().
*/
usregs = (unsigned short *) ep->regs[st_regno];
sign = usregs[4] & 0x8000 ? "-" : "";
exp = usregs[4] & 0x7fff;
normal = usregs[3] & 0x8000;
mantissa_or = usregs[0] | usregs[1] | usregs[2] | (usregs[3] & 0x7fff);
if (exp == 0)
{
if (normal)
printf_unfiltered ("Pseudo Denormal (0 as a double)");
else if (mantissa_or == 0)
printf_unfiltered ("%s0", sign);
else
printf_unfiltered ("Denormal (0 as a double)");
}
else if (exp == 0x7fff)
{
if (!normal)
printf_unfiltered ("Pseudo ");
if (mantissa_or == 0)
printf_unfiltered ("%sInf", sign);
else
printf_unfiltered ("%s NaN",
usregs[3] & 0x4000 ? "Quiet" : "Signaling");
if (!normal)
printf_unfiltered (" (NaN)");
}
else if (!normal)
printf_unfiltered ("Unnormal (NaN)");
else
{
#if 0
/* Use this we stop trapping on overflow. */
floatformat_to_double(&floatformat_i387_ext,
(char *) ep->regs[st_regno], &val);
#else
i387_to_double((char *) ep->regs[st_regno], (char *) &val);
#endif
printf_unfiltered ("%g", val);
}
printf_unfiltered ("\n");
}
}
void
i386_float_info ()
{
struct user u; /* just for address computations */
int i;
/* fpstate defined in <sys/user.h> */
struct fpstate *fpstatep;
char buf[sizeof (struct fpstate) + 2 * sizeof (int)];
unsigned int uaddr;
char fpvalid;
unsigned int rounded_addr;
unsigned int rounded_size;
/*extern int corechan;*/
int skip;
extern int inferior_pid;
uaddr = (char *)&U_FPSTATE(u) - (char *)&u;
if (inferior_pid != 0 && core_bfd == NULL)
{
int *ip;
rounded_addr = uaddr & -sizeof (int);
rounded_size = (((uaddr + sizeof (struct fpstate)) - uaddr) +
sizeof (int) - 1) / sizeof (int);
skip = uaddr - rounded_addr;
ip = (int *)buf;
for (i = 0; i < rounded_size; i++)
{
*ip++ = ptrace (PT_READ_U, inferior_pid, (caddr_t)rounded_addr, 0);
rounded_addr += sizeof (int);
}
fpstatep = (struct fpstate *)(buf + skip);
}
else
fpstatep = &pcb_savefpu;
print_387_status (fpstatep->sv_ex_sw, (struct env387 *)fpstatep);
}
#endif /* FLOAT_INFO */
int
kernel_u_size ()
{
return (sizeof (struct user));
}
#ifdef SETUP_ARBITRARY_FRAME
#include "frame.h"
struct frame_info *
setup_arbitrary_frame (argc, argv)
int argc;
CORE_ADDR *argv;
{
if (argc != 2)
error ("i386 frame specifications require two arguments: sp and pc");
return create_new_frame (argv[0], argv[1]);
}
#endif /* SETUP_ARBITRARY_FRAME */
#ifdef HAVE_GREGSET_T
void
supply_gregset (gp)
gregset_t *gp;
{
int regno = 0;
/* These must be ordered the same as REGISTER_NAMES in
config/i386/tm-i386.h. */
supply_register (regno++, (char *)&gp->r_eax);
supply_register (regno++, (char *)&gp->r_ecx);
supply_register (regno++, (char *)&gp->r_edx);
supply_register (regno++, (char *)&gp->r_ebx);
supply_register (regno++, (char *)&gp->r_esp);
supply_register (regno++, (char *)&gp->r_ebp);
supply_register (regno++, (char *)&gp->r_esi);
supply_register (regno++, (char *)&gp->r_edi);
supply_register (regno++, (char *)&gp->r_eip);
supply_register (regno++, (char *)&gp->r_eflags);
supply_register (regno++, (char *)&gp->r_cs);
supply_register (regno++, (char *)&gp->r_ss);
supply_register (regno++, (char *)&gp->r_ds);
supply_register (regno++, (char *)&gp->r_es);
supply_register (regno++, (char *)&gp->r_fs);
supply_register (regno++, (char *)&gp->r_gs);
}
#endif /* HAVE_GREGSET_T */
#ifdef HAVE_FPREGSET_T
void
supply_fpregset (fp)
fpregset_t *fp;
{
memcpy (&pcb_savefpu, fp, sizeof pcb_savefpu);
}
#endif /* HAVE_FPREGSET_T */
/* Register that we are able to handle aout (trad-core) file formats. */
static struct core_fns aout_core_fns =
{
bfd_target_unknown_flavour,
fetch_core_registers,
NULL
};
void
_initialize_core_aout ()
{
add_core_fns (&aout_core_fns);
}

View file

@ -1,385 +0,0 @@
.\" Copyright (c) 1991 Free Software Foundation
.\" See section COPYING for conditions for redistribution
.\" $Id: gdb.1,v 1.3 1991/12/13 22:22:58 pesch Exp $
.TH gdb 1 "4nov1991" "GNU Tools" "GNU Tools"
.SH NAME
gdb \- The GNU Debugger
.SH SYNOPSIS
.na
.TP
.B gdb
.RB "[\|" \-help "\|]"
.RB "[\|" \-nx "\|]"
.RB "[\|" \-q "\|]"
.RB "[\|" \-batch "\|]"
.RB "[\|" \-cd=\c
.I dir\c
\|]
.RB "[\|" \-f "\|]"
.RB "[\|" \-k "\|]"
.RB "[\|" \-wcore "\|]"
.RB "[\|" "\-b\ "\c
.IR bps "\|]"
.RB "[\|" "\-tty="\c
.IR dev "\|]"
.RB "[\|" "\-s "\c
.I symfile\c
\&\|]
.RB "[\|" "\-e "\c
.I prog\c
\&\|]
.RB "[\|" "\-se "\c
.I prog\c
\&\|]
.RB "[\|" "\-c "\c
.I core\c
\&\|]
.RB "[\|" "\-x "\c
.I cmds\c
\&\|]
.RB "[\|" "\-d "\c
.I dir\c
\&\|]
.RB "[\|" \c
.I prog\c
.RB "[\|" \c
.IR core \||\| procID\c
\&\|]\&\|]
.ad b
.SH DESCRIPTION
The purpose of a debugger such as GDB is to allow you to see what is
going on ``inside'' another program while it executes\(em\&or what another
program was doing at the moment it crashed.
GDB can do four main kinds of things (plus other things in support of
these) to help you catch bugs in the act:
.TP
\ \ \ \(bu
Start your program, specifying anything that might affect its behavior.
.TP
\ \ \ \(bu
Make your program stop on specified conditions.
.TP
\ \ \ \(bu
Examine what has happened, when your program has stopped.
.TP
\ \ \ \(bu
Change things in your program, so you can experiment with correcting the
effects of one bug and go on to learn about another.
.PP
You can use GDB to debug programs written in C, C++, and Modula-2.
Fortran support will be added when a GNU Fortran compiler is ready.
GDB is invoked with the shell command \c
.B gdb\c
\&. Once started, it reads
commands from the terminal until you tell it to exit with the GDB
command \c
.B quit\c
\&. You can get online help from \c
.B gdb\c
\& itself
by using the command \c
.B help\c
\&.
You can run \c
.B gdb\c
\& with no arguments or options; but the most
usual way to start GDB is with one argument or two, specifying an
executable program as the argument:
.sp
.br
gdb\ program
.br
.sp
You can also start with both an executable program and a core file specified:
.sp
.br
gdb\ program\ core
.br
.sp
You can, instead, specify a process ID as a second argument, if you want
to debug a running process:
.sp
.br
gdb\ program\ 1234
.br
.sp
would attach GDB to process \c
.B 1234\c
\& (unless you also have a file
named `\|\c
.B 1234\c
\&\|'; GDB does check for a core file first).
Here are some of the most frequently needed GDB commands:
.TP
.B break \fR[\|\fIfile\fB:\fR\|]\fIfunction
\&
Set a breakpoint at \c
.I function\c
\& (in \c
.I file\c
\&).
.TP
.B run \fR[\|\fIarglist\fR\|]
Start your program (with \c
.I arglist\c
\&, if specified).
.TP
.B bt
Backtrace: display the program stack.
.TP
.BI print " expr"\c
\&
Display the value of an expression.
.TP
.B c
Continue running your program (after stopping, e.g. at a breakpoint).
.TP
.B next
Execute next program line (after stopping); step \c
.I over\c
\& any
function calls in the line.
.TP
.B step
Execute next program line (after stopping); step \c
.I into\c
\& any
function calls in the line.
.TP
.B help \fR[\|\fIname\fR\|]
Show information about GDB command \c
.I name\c
\&, or general information
about using GDB.
.TP
.B quit
Exit from GDB.
.PP
For full details on GDB, see \c
.I
Using GDB: A Guide to the GNU Source-Level Debugger\c
\&, by Richard M. Stallman and Roland H. Pesch. The same text is available online
as the \c
.B gdb\c
\& entry in the \c
.B info\c
\& program.
.SH OPTIONS
Any arguments other than options specify an executable
file and core file (or process ID); that is, the first argument
encountered with no
associated option flag is equivalent to a `\|\c
.B \-se\c
\&\|' option, and the
second, if any, is equivalent to a `\|\c
.B \-c\c
\&\|' option if it's the name of a file. Many options have
both long and short forms; both are shown here. The long forms are also
recognized if you truncate them, so long as enough of the option is
present to be unambiguous. (If you prefer, you can flag option
arguments with `\|\c
.B +\c
\&\|' rather than `\|\c
.B \-\c
\&\|', though we illustrate the
more usual convention.)
All the options and command line arguments you give are processed
in sequential order. The order makes a difference when the
`\|\c
.B \-x\c
\&\|' option is used.
.TP
.B \-help
.TP
.B \-h
List all options, with brief explanations.
.TP
.BI "\-symbols=" "file"\c
.TP
.BI "\-s " "file"\c
\&
Read symbol table from file \c
.I file\c
\&.
.TP
.BI "\-exec=" "file"\c
.TP
.BI "\-e " "file"\c
\&
Use file \c
.I file\c
\& as the executable file to execute when
appropriate, and for examining pure data in conjunction with a core
dump.
.TP
.BI "\-se=" "file"\c
\&
Read symbol table from file \c
.I file\c
\& and use it as the executable
file.
.TP
.BI "\-core=" "file"\c
.TP
.BI "\-c " "file"\c
\&
Use file \c
.I file\c
\& as a core dump to examine.
.TP
.BI "\-command=" "file"\c
.TP
.BI "\-x " "file"\c
\&
Execute GDB commands from file \c
.I file\c
\&.
.TP
.BI "\-directory=" "directory"\c
.TP
.BI "\-d " "directory"\c
\&
Add \c
.I directory\c
\& to the path to search for source files.
.PP
.TP
.B \-nx
.TP
.B \-n
Do not execute commands from any `\|\c
.B .gdbinit\c
\&\|' initialization files.
Normally, the commands in these files are executed after all the
command options and arguments have been processed.
.TP
.B \-quiet
.TP
.B \-q
``Quiet''. Do not print the introductory and copyright messages. These
messages are also suppressed in batch mode.
.TP
.B \-batch
Run in batch mode. Exit with status \c
.B 0\c
\& after processing all the command
files specified with `\|\c
.B \-x\c
\&\|' (and `\|\c
.B .gdbinit\c
\&\|', if not inhibited).
Exit with nonzero status if an error occurs in executing the GDB
commands in the command files.
Batch mode may be useful for running GDB as a filter, for example to
download and run a program on another computer; in order to make this
more useful, the message
.sp
.br
Program\ exited\ normally.
.br
.sp
(which is ordinarily issued whenever a program running under GDB control
terminates) is not issued when running in batch mode.
.TP
.BI "\-cd=" "directory"\c
\&
Run GDB using \c
.I directory\c
\& as its working directory,
instead of the current directory.
.TP
.B \-fullname
.TP
.B \-f
Emacs sets this option when it runs GDB as a subprocess. It tells GDB
to output the full file name and line number in a standard,
recognizable fashion each time a stack frame is displayed (which
includes each time the program stops). This recognizable format looks
like two `\|\c
.B \032\c
\&\|' characters, followed by the file name, line number
and character position separated by colons, and a newline. The
Emacs-to-GDB interface program uses the two `\|\c
.B \032\c
\&\|' characters as
a signal to display the source code for the frame.
.TP
.B \-kernel
.TP
.B \-k
Use gdb in kernel debugging mode. The prompt is set to ``(kgdb)''.
.TP
.B \-wcore
This option may only be used in kernel debugging mode while
debugging a ``live'' kernel and makes the corefile (/dev/mem)
writable.
.TP
.BI "\-b " "bps"\c
\&
Set the line speed (baud rate or bits per second) of any serial
interface used by GDB for remote debugging.
.TP
.BI "\-tty=" "device"\c
\&
Run using \c
.I device\c
\& for your program's standard input and output.
.PP
.SH "SEE ALSO"
.RB "`\|" gdb "\|'"
entry in
.B info\c
\&;
.I
Using GDB: A Guide to the GNU Source-Level Debugger\c
, Richard M. Stallman and Roland H. Pesch, July 1991.
.SH COPYING
Copyright (c) 1991 Free Software Foundation, Inc.
.PP
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
.PP
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the
entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
.PP
Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that this permission notice may be included in
translations approved by the Free Software Foundation instead of in
the original English.

View file

@ -1,23 +0,0 @@
/* Intel 386 running any FreeBSD Unix */
#include <machine/param.h>
#include <machine/vmparam.h>
#define NBPG PAGE_SIZE
#define HOST_PAGE_SIZE NBPG
#define HOST_MACHINE_ARCH bfd_arch_i386
#define HOST_TEXT_START_ADDR USRTEXT
/* Jolitz suggested defining HOST_STACK_END_ADDR to
(u.u_kproc.kp_eproc.e_vm.vm_maxsaddr + MAXSSIZ), which should work on
both BSDI and 386BSD, but that is believed not to work for BSD 4.4. */
/* This seems to be the right thing for FreeBSD and BSDI */
#define HOST_STACK_END_ADDR USRSTACK
/* BSDI defines this too (PST) */
#define HOST_DATA_START_ADDR ((bfd_vma)u.u_kproc.kp_eproc.e_vm.vm_daddr)
#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \
((core_bfd)->tdata.trad_core_data->u.u_sig)
#define u_comm u_kproc.kp_proc.p_comm

View file

@ -1,997 +0,0 @@
/* Live and postmortem kernel debugging functions for FreeBSD.
Copyright 1996 Free Software Foundation, Inc.
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. */
#include "defs.h"
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/sysctl.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/proc.h>
#include <sys/user.h>
#include "frame.h" /* required by inferior.h */
#include "inferior.h"
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
#include "command.h"
#include "bfd.h"
#include "target.h"
#include "gdbcore.h"
#include <sys/stat.h>
#include <unistd.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#include <machine/tss.h>
#include <machine/frame.h>
static void kcore_files_info PARAMS ((struct target_ops *));
static void kcore_close PARAMS ((int));
static void get_kcore_registers PARAMS ((int));
static int kcore_xfer_kmem PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *));
static int xfer_umem PARAMS ((CORE_ADDR, char *, int, int));
static CORE_ADDR ksym_lookup PARAMS ((const char *));
static int read_pcb PARAMS ((int, CORE_ADDR));
static struct proc * curProc PARAMS ((void));
static int set_proc_context PARAMS ((CORE_ADDR paddr));
static void kcore_open PARAMS ((char *filename, int from_tty));
static void kcore_detach PARAMS ((char *args, int from_tty));
static void set_proc_cmd PARAMS ((char *arg, int from_tty));
static void set_cpu_cmd PARAMS ((char *arg, int from_tty));
static CORE_ADDR kvtophys PARAMS ((int, CORE_ADDR));
static int physrd PARAMS ((int, u_int, char*, int));
static int kvm_open PARAMS ((const char *efile, char *cfile, char *sfile,
int perm, char *errout));
static int kvm_close PARAMS ((int fd));
static int kvm_write PARAMS ((int core_kd, CORE_ADDR memaddr,
char *myaddr, int len));
static int kvm_read PARAMS ((int core_kd, CORE_ADDR memaddr,
char *myaddr, int len));
static int kvm_uread PARAMS ((int core_kd, struct proc *p,
CORE_ADDR memaddr, char *myaddr,
int len));
static int kernel_core_file_hook PARAMS ((int fd, CORE_ADDR addr,
char *buf, int len));
static struct kinfo_proc * kvm_getprocs PARAMS ((int cfd, int op,
CORE_ADDR proc, int *cnt));
extern struct target_ops kcore_ops; /* Forward decl */
/* Non-zero means we are debugging a kernel core file */
int kernel_debugging = 0;
int kernel_writablecore = 0;
static char *core_file;
static int core_kd = -1;
static struct proc *cur_proc;
static CORE_ADDR kernel_start;
static int ncpus;
static int cpuid;
static CORE_ADDR prv_space; /* per-cpu private space */
static int prv_space_size;
#define prv_start (prv_space + cpuid * prv_space_size)
/*
* Read the "thing" at kernel address 'addr' into the space pointed to
* by point. The length of the "thing" is determined by the type of p.
* Result is non-zero if transfer fails.
*/
#define kvread(addr, p) \
(target_read_memory ((CORE_ADDR)(addr), (char *)(p), sizeof(*(p))))
/*
* The following is FreeBSD-specific hackery to decode special frames
* and elide the assembly-language stub. This could be made faster by
* defining a frame_type field in the machine-dependent frame information,
* but we don't think that's too important right now.
*/
enum frametype { tf_normal, tf_trap, tf_interrupt, tf_syscall };
CORE_ADDR
fbsd_kern_frame_saved_pc (fr)
struct frame_info *fr;
{
struct minimal_symbol *sym;
CORE_ADDR this_saved_pc;
enum frametype frametype;
this_saved_pc = read_memory_integer (fr->frame + 4, 4);
sym = lookup_minimal_symbol_by_pc (this_saved_pc);
frametype = tf_normal;
if (sym != NULL) {
if (strcmp (SYMBOL_NAME(sym), "calltrap") == 0)
frametype = tf_trap;
else if (strncmp (SYMBOL_NAME(sym), "Xresume", 7) == 0)
frametype = tf_interrupt;
else if (strcmp (SYMBOL_NAME(sym), "Xsyscall") == 0)
frametype = tf_syscall;
}
switch (frametype) {
case tf_normal:
return (this_saved_pc);
#define oEIP offsetof(struct trapframe, tf_eip)
case tf_trap:
return (read_memory_integer (fr->frame + 8 + oEIP, 4));
case tf_interrupt:
return (read_memory_integer (fr->frame + 16 + oEIP, 4));
case tf_syscall:
return (read_memory_integer (fr->frame + 8 + oEIP, 4));
#undef oEIP
}
}
static CORE_ADDR
ksym_lookup (name)
const char *name;
{
struct minimal_symbol *sym;
sym = lookup_minimal_symbol (name, NULL, NULL);
if (sym == NULL)
error ("kernel symbol `%s' not found.", name);
return SYMBOL_VALUE_ADDRESS (sym);
}
static struct proc *
curProc ()
{
struct proc *p;
CORE_ADDR addr = ksym_lookup ("gd_curproc") + prv_start;
if (kvread (addr, &p))
error ("cannot read proc pointer at %x\n", addr);
return p;
}
/*
* Set the process context to that of the proc structure at
* system address paddr.
*/
static int
set_proc_context (paddr)
CORE_ADDR paddr;
{
struct proc p;
if (paddr < kernel_start)
return (1);
cur_proc = (struct proc *)paddr;
#ifdef notyet
set_kernel_boundaries (cur_proc);
#endif
/* Fetch all registers from core file */
target_fetch_registers (-1);
/* Now, set up the frame cache, and print the top of stack */
flush_cached_frames ();
set_current_frame (create_new_frame (read_fp (), read_pc ()));
select_frame (get_current_frame (), 0);
return (0);
}
/* Discard all vestiges of any previous core file
and mark data and stack spaces as empty. */
/* ARGSUSED */
static void
kcore_close (quitting)
int quitting;
{
inferior_pid = 0; /* Avoid confusion from thread stuff */
if (core_kd)
{
kvm_close (core_kd);
free (core_file);
core_file = NULL;
core_kd = -1;
}
}
/* This routine opens and sets up the core file bfd */
static void
kcore_open (filename, from_tty)
char *filename;
int from_tty;
{
const char *p;
struct cleanup *old_chain;
char buf[256], *cp;
int ontop;
CORE_ADDR addr;
struct pcb pcb;
target_preopen (from_tty);
unpush_target (&kcore_ops);
if (!filename)
{
/*error (core_kd?*/
error ( (core_kd >= 0)?
"No core file specified. (Use `detach' to stop debugging a core file.)"
: "No core file specified.");
}
filename = tilde_expand (filename);
if (filename[0] != '/')
{
cp = concat (current_directory, "/", filename, NULL);
free (filename);
filename = cp;
}
old_chain = make_cleanup (free, filename);
/*
* gdb doesn't really do anything if the exec-file couldn't
* be opened (in that case exec_bfd is NULL). Usually that's
* no big deal, but kvm_open needs the exec-file's name,
* which results in dereferencing a NULL pointer, a real NO-NO !
* So, check here if the open of the exec-file succeeded.
*/
if (exec_bfd == NULL) /* the open failed */
error ("kgdb could not open the exec-file, please check the name you used !");
core_kd = kvm_open (exec_bfd->filename, filename, NULL,
kernel_writablecore? O_RDWR : O_RDONLY, "kgdb: ");
if (core_kd < 0)
perror_with_name (filename);
/* Looks semi-reasonable. Toss the old core file and work on the new. */
discard_cleanups (old_chain); /* Don't free filename any more */
core_file = filename;
ontop = !push_target (&kcore_ops);
kernel_start = bfd_get_start_address (exec_bfd); /* XXX */
/* print out the panic string if there is one */
if (kvread (ksym_lookup ("panicstr"), &addr) == 0
&& addr != 0
&& target_read_memory (addr, buf, sizeof (buf)) == 0)
{
for (cp = buf; cp < &buf[sizeof (buf)] && *cp; cp++)
if (!isascii (*cp) || (!isprint (*cp) && !isspace (*cp)))
*cp = '?';
*cp = '\0';
if (buf[0] != '\0')
printf ("panicstr: %s\n", buf);
}
/* Print all the panic messages if possible. */
if (symfile_objfile != NULL)
{
printf ("panic messages:\n---\n");
snprintf (buf, sizeof buf,
"/sbin/dmesg -N %s -M %s | \
/usr/bin/awk '/^(panic:|Fatal trap) / { printing = 1 } \
{ if (printing) print $0 }'",
symfile_objfile->name, filename);
fflush(stdout);
system (buf);
printf ("---\n");
}
if (!ontop)
{
warning ("you won't be able to access this core file until you terminate\n\
your %s; do ``info files''", target_longname);
return;
}
/* we may need this later */
cur_proc = (struct proc *)curProc ();
/* Now, set up the frame cache, and print the top of stack */
flush_cached_frames ();
set_current_frame (create_new_frame (read_fp (), read_pc ()));
select_frame (get_current_frame (), 0);
print_stack_frame (selected_frame, selected_frame_level, 1);
}
static void
kcore_detach (args, from_tty)
char *args;
int from_tty;
{
if (args)
error ("Too many arguments");
unpush_target (&kcore_ops);
reinit_frame_cache ();
if (from_tty)
printf_filtered ("No kernel core file now.\n");
}
/* Get the registers out of a core file. This is the machine-
independent part. Fetch_core_registers is the machine-dependent
part, typically implemented in the xm-file for each architecture. */
/* We just get all the registers, so we don't use regno. */
/* ARGSUSED */
static void
get_kcore_registers (regno)
int regno;
{
struct user *uaddr;
/* find the pcb for the current process */
if (cur_proc == NULL || kvread (&cur_proc->p_addr, &uaddr))
error ("cannot read u area ptr for proc at %#x", cur_proc);
if (read_pcb (core_kd, (CORE_ADDR)&uaddr->u_pcb) < 0)
error ("cannot read pcb at %#x", &uaddr->u_pcb);
}
static void
kcore_files_info (t)
struct target_ops *t;
{
printf ("\t`%s'\n", core_file);
}
static int
kcore_xfer_kmem (memaddr, myaddr, len, write, target)
CORE_ADDR memaddr;
char *myaddr;
int len;
int write;
struct target_ops *target;
{
int ns;
int nu;
if (memaddr >= (CORE_ADDR)VM_MAXUSER_ADDRESS)
nu = 0;
else
{
nu = xfer_umem (memaddr, myaddr, len, write);
if (nu <= 0)
return (0);
if (nu == len)
return (nu);
memaddr += nu;
if (memaddr != (CORE_ADDR)VM_MAXUSER_ADDRESS)
return (nu);
myaddr += nu;
len -= nu;
}
ns = (write ? kvm_write : kvm_read) (core_kd, memaddr, myaddr, len);
if (ns < 0)
ns = 0;
return (nu + ns);
}
static int
xfer_umem (memaddr, myaddr, len, write)
CORE_ADDR memaddr;
char *myaddr;
int len;
int write; /* ignored */
{
int n;
struct proc proc;
if (cur_proc == NULL || kvread (cur_proc, &proc))
error ("cannot read proc at %#x", cur_proc);
n = kvm_uread (core_kd, &proc, memaddr, myaddr, len) ;
if (n < 0)
return 0;
return n;
}
#define KERNOFF ((unsigned)KERNBASE)
#define INKERNEL(x) ((x) >= KERNOFF)
static CORE_ADDR sbr;
static CORE_ADDR curpcb;
static int found_pcb;
static int devmem;
static int kfd;
static struct pcb pcb;
static void
set_proc_cmd (arg, from_tty)
char *arg;
int from_tty;
{
CORE_ADDR paddr;
struct kinfo_proc *kp;
int cnt = 0;
if (!arg)
error_no_arg ("proc address for new current process");
if (!kernel_debugging)
error ("not debugging kernel");
paddr = (CORE_ADDR)parse_and_eval_address (arg);
/* assume it's a proc pointer if it's in the kernel */
if (paddr >= kernel_start) {
if (set_proc_context(paddr))
error("invalid proc address");
} else {
kp = kvm_getprocs(core_kd, KERN_PROC_PID, paddr, &cnt);
if (!cnt)
error("invalid pid");
if (set_proc_context((CORE_ADDR)kp->kp_eproc.e_paddr))
error("invalid proc address");
}
}
static void
set_cpu_cmd (arg, from_tty)
char *arg;
int from_tty;
{
CORE_ADDR paddr;
struct kinfo_proc *kp;
int cpu, cfd;
if (!arg)
error_no_arg ("cpu number");
if (!kernel_debugging)
error ("not debugging kernel");
if (!ncpus)
error ("not debugging SMP kernel");
cpu = (int)parse_and_eval_address (arg);
if (cpu < 0 || cpu > ncpus)
error ("cpu number out of range");
cpuid = cpu;
cfd = core_kd;
curpcb = kvtophys(cfd, ksym_lookup ("gd_curpcb") + prv_start);
physrd (cfd, curpcb, (char*)&curpcb, sizeof curpcb);
if (!devmem)
paddr = ksym_lookup ("dumppcb") - KERNOFF;
else
paddr = kvtophys (cfd, curpcb);
read_pcb (cfd, paddr);
printf ("initial pcb at %lx\n", (unsigned long)paddr);
if ((cur_proc = curProc()))
target_fetch_registers (-1);
/* Now, set up the frame cache, and print the top of stack */
flush_cached_frames ();
set_current_frame (create_new_frame (read_fp (), read_pc ()));
select_frame (get_current_frame (), 0);
print_stack_frame (selected_frame, selected_frame_level, 1);
}
/* 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 */
static int
kvm_open (efile, cfile, sfile, perm, errout)
const char *efile;
char *cfile;
char *sfile; /* makes this kvm_open more compatible to the one in libkvm */
int perm;
char *errout; /* makes this kvm_open more compatible to the one in libkvm */
{
struct stat stb;
int cfd;
CORE_ADDR paddr;
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);
}
if (lookup_minimal_symbol("mp_ncpus", NULL, NULL)) {
physrd(cfd, ksym_lookup("mp_ncpus") - KERNOFF,
(char*)&ncpus, sizeof(ncpus));
prv_space = ksym_lookup("SMP_prvspace");
prv_space_size = (int)ksym_lookup("gd_idlestack_top");
printf ("SMP %d cpus\n", ncpus);
} else {
ncpus = 0;
prv_space = 0;
prv_space_size = 0;
}
cpuid = 0;
physrd (cfd, ksym_lookup ("IdlePTD") - KERNOFF, (char*)&sbr, sizeof sbr);
printf ("IdlePTD %lu\n", (unsigned long)sbr);
curpcb = kvtophys(cfd, ksym_lookup ("gd_curpcb") + prv_start);
physrd (cfd, curpcb, (char*)&curpcb, sizeof curpcb);
found_pcb = 1; /* for vtophys */
if (!devmem)
paddr = ksym_lookup ("dumppcb") - KERNOFF;
else
paddr = kvtophys (cfd, curpcb);
read_pcb (cfd, paddr);
printf ("initial pcb at %lx\n", (unsigned long)paddr);
return (cfd);
}
static int
kvm_close (fd)
int fd;
{
return (close (fd));
}
static int
kvm_write (core_kd, memaddr, myaddr, len)
int core_kd;
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 */
}
static int
kvm_read (core_kd, memaddr, myaddr, len)
int core_kd;
CORE_ADDR memaddr;
char *myaddr;
{
return (kernel_core_file_hook (core_kd, memaddr, myaddr, len));
}
static int
kvm_uread (core_kd, p, memaddr, myaddr, len)
int core_kd;
register struct proc *p;
CORE_ADDR memaddr;
char *myaddr;
int len;
{
register char *cp;
char procfile[MAXPATHLEN];
ssize_t amount;
int fd;
if (devmem)
{
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);
}
cp = myaddr;
while (len > 0)
{
errno = 0;
if (lseek (fd, (off_t)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;
}
if (amount == 0)
{
error ("EOF 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 struct kinfo_proc kp;
/*
* try to do what kvm_proclist in libkvm would do
*/
static int
kvm_proclist (cfd, pid, p, cnt)
int cfd, pid, *cnt;
struct proc *p;
{
struct proc lp;
for (; p != NULL; p = lp.p_list.le_next) {
if (!kvm_read(cfd, (CORE_ADDR)p, (char *)&lp, sizeof (lp)))
return (0);
if (lp.p_pid != pid)
continue;
kp.kp_eproc.e_paddr = p;
*cnt = 1;
return (1);
}
*cnt = 0;
return (0);
}
/*
* try to do what kvm_deadprocs in libkvm would do
*/
static struct kinfo_proc *
kvm_deadprocs (cfd, pid, cnt)
int cfd, pid, *cnt;
{
CORE_ADDR allproc, zombproc;
struct proc *p;
allproc = ksym_lookup("allproc");
if (kvm_read(cfd, allproc, (char *)&p, sizeof (p)) == 0)
return (NULL);
kvm_proclist (cfd, pid, p, cnt);
if (!*cnt) {
zombproc = ksym_lookup("zombproc");
if (kvm_read(cfd, zombproc, (char *)&p, sizeof (p)) == 0)
return (NULL);
kvm_proclist (cfd, pid, p, cnt);
}
return (&kp);
}
/*
* try to do what kvm_getprocs in libkvm would do
*/
static struct kinfo_proc *
kvm_getprocs (cfd, op, proc, cnt)
int cfd, op, *cnt;
CORE_ADDR proc;
{
int mib[4], size;
*cnt = 0;
/* assume it's a pid */
if (devmem) { /* "live" kernel, use sysctl */
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PID;
mib[3] = (int)proc;
size = sizeof (kp);
if (sysctl (mib, 4, &kp, &size, NULL, 0) < 0) {
perror("sysctl");
*cnt = 0;
return (NULL);
}
if (!size)
*cnt = 0;
else
*cnt = 1;
return (&kp);
} else
return (kvm_deadprocs (cfd, (int)proc, cnt));
}
static int
physrd (cfd, addr, dat, len)
int cfd;
u_int addr;
char *dat;
int len;
{
if (lseek (cfd, (off_t)addr, L_SET) == -1)
return (-1);
return (read (cfd, dat, len));
}
static CORE_ADDR
kvtophys (fd, addr)
int fd;
CORE_ADDR addr;
{
CORE_ADDR v;
unsigned int pte;
static CORE_ADDR PTD = -1;
CORE_ADDR current_ptd;
/*
* 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_cr3;
/*
* Read the first-level page table (ptd).
*/
v = current_ptd + ( (unsigned)addr >> PDRSHIFT) * sizeof pte;
if (physrd (fd, v, (char *)&pte, sizeof pte) < 0 || (pte&PG_V) == 0)
return (~0);
if (pte & PG_PS)
{
/*
* No second-level page table; ptd describes one 4MB page.
* (We assume that the kernel wouldn't set PG_PS without enabling
* it cr0, and that the kernel doesn't support 36-bit physical
* addresses).
*/
#define PAGE4M_MASK (NBPDR - 1)
#define PG_FRAME4M (~PAGE4M_MASK)
addr = (pte & PG_FRAME4M) + (addr & PAGE4M_MASK);
}
else
{
/*
* Read the second-level page table.
*/
v = (pte&PG_FRAME) + ((addr >> PAGE_SHIFT)&(NPTEPG-1)) * sizeof pte;
if (physrd (fd, v, (char *) &pte, sizeof (pte)) < 0 || (pte&PG_V) == 0)
return (~0);
addr = (pte & PG_FRAME) + (addr & PAGE_MASK);
}
#if 0
printf ("vtophys (%x) -> %x\n", oldaddr, addr);
#endif
return (addr);
}
static int
read_pcb (fd, uaddr)
int fd;
CORE_ADDR uaddr;
{
int i;
int noreg;
CORE_ADDR nuaddr = uaddr;
/* need this for the `proc' command to work */
if (INKERNEL(uaddr))
nuaddr = kvtophys(fd, uaddr);
if (physrd (fd, nuaddr, (char *)&pcb, sizeof pcb) < 0)
{
error ("cannot read pcb at %x\n", uaddr);
return (-1);
}
/*
* get the register values out of the sys pcb and
* store them where `read_register' will find them.
*/
/*
* XXX many registers aren't available.
* XXX for the non-core case, the registers are stale - they are for
* the last context switch to the debugger.
* XXX gcc's register numbers aren't all #defined in tm-i386.h.
*/
noreg = 0;
for (i = 0; i < 3; ++i) /* eax,ecx,edx */
supply_register (i, (char *)&noreg);
supply_register (3, (char *)&pcb.pcb_ebx);
supply_register (SP_REGNUM, (char *)&pcb.pcb_esp);
supply_register (FP_REGNUM, (char *)&pcb.pcb_ebp);
supply_register (6, (char *)&pcb.pcb_esi);
supply_register (7, (char *)&pcb.pcb_edi);
supply_register (PC_REGNUM, (char *)&pcb.pcb_eip);
for (i = 9; i < 14; ++i) /* eflags, cs, ss, ds, es, fs */
supply_register (i, (char *)&noreg);
supply_register (15, (char *)&pcb.pcb_gs);
/* 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.
*/
static int
kernel_core_file_hook (fd, addr, buf, len)
int fd;
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)
{
memset (buf, '\000', len);
break;
}
/* we can't read across a page boundary */
i = min (len, PAGE_SIZE - (addr & PAGE_MASK));
if ( (cc = physrd (fd, paddr, cp, i)) <= 0)
{
memset (cp, '\000', len);
return (cp - buf);
}
cp += cc;
addr += cc;
len -= cc;
}
return (cp - buf);
}
struct target_ops kcore_ops = {
"kcore", /* to_shortname */
"Kernel core dump file", /* to_longname */
"Use a core file as a target. Specify the filename of the core file.", /* to_doc */
kcore_open, /* to_open */
kcore_close, /* to_close */
find_default_attach, /* to_attach */
kcore_detach, /* to_detach */
NULL, /* to_resume */
NULL, /* to_wait */
get_kcore_registers, /* to_fetch_registers */
NULL, /* to_store_registers */
NULL, /* to_prepare_to_store */
kcore_xfer_kmem, /* to_xfer_memory */
kcore_files_info, /* to_files_info */
NULL, /* to_insert_breakpoint */
NULL, /* to_remove_breakpoint */
NULL, /* to_terminal_init */
NULL, /* to_terminal_inferior */
NULL, /* to_terminal_ours_for_output */
NULL, /* to_terminal_ours */
NULL, /* to_terminal_info */
NULL, /* to_kill */
NULL, /* to_load */
NULL, /* to_lookup_symbol */
find_default_create_inferior, /* to_create_inferior */
NULL, /* to_mourn_inferior */
0, /* to_can_run */
0, /* to_notice_signals */
NULL, /* to_thread_alive */
0, /* to_stop */
kcore_stratum, /* to_stratum */
NULL, /* to_next */
0, /* to_has_all_memory */
1, /* to_has_memory */
1, /* to_has_stack */
1, /* to_has_registers */
0, /* to_has_execution */
NULL, /* sections */
NULL, /* sections_end */
OPS_MAGIC /* to_magic */
};
void
_initialize_kcorelow()
{
add_target (&kcore_ops);
add_com ("proc", class_obscure, set_proc_cmd, "Set current process context");
add_com ("cpu", class_obscure, set_cpu_cmd, "Set current cpu");
}

View file

@ -1,135 +0,0 @@
/* Native-dependent definitions for Intel 386 running BSD Unix, for GDB.
Copyright 1986, 1987, 1989, 1992, 1996 Free Software Foundation, Inc.
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 NM_FBSD_H
#define NM_FBSD_H
#define ATTACH_DETACH
/* Be shared lib aware */
#include "solib.h"
#ifdef FREEBSD_ELF
#define SVR4_SHARED_LIBS
#endif
/* This is the amount to subtract from u.u_ar0
to get the offset in the core file of the register values. */
#include <machine/vmparam.h>
#define KERNEL_U_ADDR USRSTACK
#define REGISTER_U_ADDR(addr, blockend, regno) \
(addr) = i386_register_u_addr ((blockend),(regno));
/* We define our own fetch/store methods */
#define FETCH_INFERIOR_REGISTERS
extern int
i386_register_u_addr PARAMS ((int, int));
#define PTRACE_ARG3_TYPE char*
#ifndef FREEBSD_ELF
/* 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
/* Return sizeof user struct to callers in less machine dependent routines */
#define KERNEL_U_SIZE kernel_u_size()
extern int kernel_u_size PARAMS ((void));
#define ADDITIONAL_OPTIONS \
{"kernel", no_argument, &kernel_debugging, 1}, \
{"k", no_argument, &kernel_debugging, 1}, \
{"wcore", no_argument, &kernel_writablecore, 1}, \
{"w", no_argument, &kernel_writablecore, 1},
#define ADDITIONAL_OPTION_HELP \
"\
--kernel Enable kernel debugging.\n\
--wcore Make core file writable (only works for /dev/mem).\n\
This option only works while debugging a kernel !!\n\
"
extern int kernel_debugging;
extern int kernel_writablecore;
#define DEFAULT_PROMPT kernel_debugging?"(kgdb) ":"(gdb) "
/* misuse START_PROGRESS to test whether we're running as kgdb */
/* START_PROGRESS is called at the top of main */
#undef START_PROGRESS
#define START_PROGRESS(STR,N) \
if (!strcmp(STR, "kgdb")) \
kernel_debugging = 1;
#endif /* NM_FBSD_H */

View file

@ -1,58 +0,0 @@
/* Macro definitions for x86 running under FreeBSD Unix.
Copyright 1996 Free Software Foundation, Inc.
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_FBSD_H
#define TM_FBSD_H 1
#include "i386/tm-i386bsd.h"
#undef NUM_REGS
#define NUM_REGS 16
extern struct frame_info *setup_arbitrary_frame PARAMS ((int, CORE_ADDR *));
#define SETUP_ARBITRARY_FRAME(argc, argv) setup_arbitrary_frame (argc, argv)
extern void i386_float_info PARAMS ((void));
#define FLOAT_INFO i386_float_info ()
#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) STREQ (name, "_DYNAMIC")
/* Saved Pc. Get it from sigcontext if within sigtramp. */
extern CORE_ADDR fbsd_kern_frame_saved_pc (struct frame_info *);
#undef FRAME_SAVED_PC
#define FRAME_SAVED_PC(FRAME) \
(kernel_debugging ? fbsd_kern_frame_saved_pc(FRAME) : \
(((FRAME)->signal_handler_caller \
? sigtramp_saved_pc (FRAME) \
: read_memory_integer ((FRAME)->frame + 4, 4)) \
))
/* On FreeBSD, sigtramp has size 0x18 and is immediately below the
ps_strings struct which has size 0x10 and is at the top of the
user stack. */
#undef SIGTRAMP_START
#undef SIGTRAMP_END
#define SIGTRAMP_START 0xefbfdfd8
#define SIGTRAMP_END 0xefbfdff0
#endif /* ifndef TM_FBSD_H */

View file

@ -1,3 +0,0 @@
char *version = "4.16";
char *host_name = "i386-unknown-freebsd";
char *target_name = "i386-unknown-freebsd";

View file

@ -1,23 +0,0 @@
/* Host-dependent definitions for Intel 386 running BSD Unix, for GDB.
Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
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. */
#define HOST_BYTE_ORDER LITTLE_ENDIAN
#include <machine/limits.h> /* for INT_MIN, to avoid "INT_MIN
redefined" warnings from defs.h */

View file

@ -1,16 +0,0 @@
# $Id: Makefile,v 1.2 1997/04/26 17:34:04 pst Exp $
GDBDIR= ${.CURDIR}/../../../../contrib/gdb
.PATH: ${GDBDIR}/gdb/gdbserver
.PATH: ${GDBDIR}/gdb
.PATH: ${GDBDIR}/opcodes
PROG= gdbreplay
NOMAN= yes
SRCS= gdbreplay.c
CFLAGS+=-I${.CURDIR}/../gdb -I${.CURDIR}/../bfd
CFLAGS+=-DNO_MMALLOC
.include <bsd.prog.mk>

View file

@ -1,16 +0,0 @@
# $Id: Makefile,v 1.2 1997/04/26 17:34:05 pst Exp $
GDBDIR= ${.CURDIR}/../../../../contrib/gdb
.PATH: ${GDBDIR}/gdb/gdbserver
.PATH: ${GDBDIR}/gdb
.PATH: ${GDBDIR}/opcodes
PROG= gdbserver
SRCS= remote-utils.c utils.c server.c
SRCS+= low-fbsd.c
CFLAGS+=-I${.CURDIR}/../gdb -I${.CURDIR}/../bfd
CFLAGS+=-DNO_MMALLOC
.include <bsd.prog.mk>

View file

@ -1,433 +0,0 @@
/* Low level interface to ptrace, for the remote server for GDB.
Copyright (C) 1995 Free Software Foundation, Inc.
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. */
#include "defs.h"
#include <sys/wait.h>
#include "frame.h"
#include "inferior.h"
#include <stdio.h>
#include <sys/param.h>
#include <dirent.h>
#include <sys/user.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sgtty.h>
#include <fcntl.h>
/***************Begin MY defs*********************/
int quit_flag = 0;
char registers[REGISTER_BYTES];
/* Index within `registers' of the first byte of the space for
register N. */
char buf2[MAX_REGISTER_RAW_SIZE];
/***************End MY defs*********************/
#include <sys/ptrace.h>
#include <machine/reg.h>
extern char **environ;
extern int inferior_pid;
void quit (), perror_with_name ();
int query ();
/* Start an inferior process and returns its pid.
ALLARGS is a vector of program-name and args.
ENV is the environment vector to pass. */
int
create_inferior (program, allargs)
char *program;
char **allargs;
{
int pid;
pid = fork ();
if (pid < 0)
perror_with_name ("fork");
if (pid == 0)
{
ptrace (PT_TRACE_ME, 0, 0, 0);
execv (program, allargs);
fprintf (stderr, "Cannot exec %s: %s.\n", program, strerror(errno));
fflush (stderr);
_exit (0177);
}
return pid;
}
/* Kill the inferior process. Make us have no inferior. */
void
kill_inferior ()
{
if (inferior_pid == 0)
return;
ptrace (PT_KILL, inferior_pid, 0, 0);
wait (0);
/*************inferior_died ();****VK**************/
}
/* Return nonzero if the given thread is still alive. */
int
mythread_alive (pid)
int pid;
{
return 1;
}
/* Wait for process, returns status */
unsigned char
mywait (status)
char *status;
{
int pid;
int w;
pid = wait (&w);
if (pid != inferior_pid)
perror_with_name ("wait");
if (WIFEXITED (w))
{
fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
*status = 'W';
return ((unsigned char) WEXITSTATUS (w));
}
else if (!WIFSTOPPED (w))
{
fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
*status = 'X';
return ((unsigned char) WTERMSIG (w));
}
fetch_inferior_registers (0);
*status = 'T';
return ((unsigned char) WSTOPSIG (w));
}
/* Resume execution of the inferior process.
If STEP is nonzero, single-step it.
If SIGNAL is nonzero, give it that signal. */
void
myresume (step, signal)
int step;
int signal;
{
errno = 0;
ptrace (step ? PT_STEP : PT_CONTINUE, inferior_pid,
(PTRACE_ARG3_TYPE) 1, signal);
if (errno)
perror_with_name ("ptrace");
}
#if !defined (offsetof)
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
#endif
/* U_REGS_OFFSET is the offset of the registers within the u area. */
#if !defined (U_REGS_OFFSET)
#define U_REGS_OFFSET \
ptrace (PT_READ_U, inferior_pid, \
(PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
- KERNEL_U_ADDR
#endif
unsigned int
register_addr (regno, blockend)
int regno;
int blockend;
{
int addr;
if (regno < 0 || regno >= ARCH_NUM_REGS)
error ("Invalid register number %d.", regno);
REGISTER_U_ADDR (addr, blockend, regno);
return addr;
}
/* Fetch one register. */
static void
fetch_register (regno)
int regno;
{
register unsigned int regaddr;
char buf[MAX_REGISTER_RAW_SIZE];
register int i;
/* Offset of registers within the u area. */
unsigned int offset;
offset = U_REGS_OFFSET;
regaddr = register_addr (regno, offset);
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
{
errno = 0;
*(int *) &registers[ regno * sizeof(int) + i] =
ptrace (PT_READ_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, 0);
regaddr += sizeof (int);
if (errno != 0)
{
/* Warning, not error, in case we are attached; sometimes the
kernel doesn't let us at the registers. */
char *err = strerror (errno);
char *msg = alloca (strlen (err) + 128);
sprintf (msg, "reading register %d: %s", regno, err);
error (msg);
goto error_exit;
}
}
error_exit:;
}
/* Fetch all registers, or just one, from the child process. */
void
fetch_inferior_registers (regno)
int regno;
{
if (regno == -1 || regno == 0)
for (regno = 0; regno < NUM_REGS; regno++)
fetch_register (regno);
else
fetch_register (regno);
}
/* Store our register values back into the inferior.
If REGNO is -1, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
void
store_inferior_registers (regno)
int regno;
{
register unsigned int regaddr;
char buf[80];
extern char registers[];
register int i;
unsigned int offset = U_REGS_OFFSET;
int scratch;
if (regno >= 0)
{
regaddr = register_addr (regno, offset);
errno = 0;
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int))
{
errno = 0;
ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
*(int *) &registers[REGISTER_BYTE (regno) + i]);
if (errno != 0)
{
/* Warning, not error, in case we are attached; sometimes the
kernel doesn't let us at the registers. */
char *err = strerror (errno);
char *msg = alloca (strlen (err) + 128);
sprintf (msg, "writing register %d: %s",
regno, err);
error (msg);
return;
}
regaddr += sizeof(int);
}
}
else
for (regno = 0; regno < NUM_REGS; regno++)
store_inferior_registers (regno);
}
/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
in the NEW_SUN_PTRACE case.
It ought to be straightforward. But it appears that writing did
not write the data that I specified. I cannot understand where
it got the data that it actually did write. */
/* Copy LEN bytes from inferior's memory starting at MEMADDR
to debugger memory starting at MYADDR. */
read_inferior_memory (memaddr, myaddr, len)
CORE_ADDR memaddr;
char *myaddr;
int len;
{
register int i;
/* Round starting address down to longword boundary. */
register CORE_ADDR addr = memaddr & -sizeof (int);
/* Round ending address up; get number of longwords that makes. */
register int count
= (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
/* Allocate buffer of that many longwords. */
register int *buffer = (int *) alloca (count * sizeof (int));
/* Read all the longwords */
for (i = 0; i < count; i++, addr += sizeof (int))
{
buffer[i] = ptrace (PT_READ_I, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0);
}
/* Copy appropriate bytes out of the buffer. */
memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
}
/* Copy LEN bytes of data from debugger memory at MYADDR
to inferior's memory at MEMADDR.
On failure (cannot write the inferior)
returns the value of errno. */
int
write_inferior_memory (memaddr, myaddr, len)
CORE_ADDR memaddr;
char *myaddr;
int len;
{
register int i;
/* Round starting address down to longword boundary. */
register CORE_ADDR addr = memaddr & -sizeof (int);
/* Round ending address up; get number of longwords that makes. */
register int count
= (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
/* Allocate buffer of that many longwords. */
register int *buffer = (int *) alloca (count * sizeof (int));
extern int errno;
/* Fill start and end extra bytes of buffer with existing memory data. */
buffer[0] = ptrace (PT_READ_I, inferior_pid,
(PTRACE_ARG3_TYPE) addr, 0);
if (count > 1)
{
buffer[count - 1]
= ptrace (PT_READ_I, inferior_pid,
(PTRACE_ARG3_TYPE) addr + (count - 1) * sizeof (int), 0);
}
/* Copy data to be written over corresponding part of buffer */
memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
/* Write the entire buffer. */
for (i = 0; i < count; i++, addr += sizeof (int))
{
errno = 0;
ptrace (PT_WRITE_I, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]);
if (errno)
return errno;
}
return 0;
}
void
initialize ()
{
inferior_pid = 0;
}
int
have_inferior_p ()
{
return inferior_pid != 0;
}
/* Some systems don't provide all the registers on a trap. Use SS as a
default if so. */
#ifndef tDS
#define tDS tSS
#endif
#ifndef tES
#define tES tSS
#endif
#ifndef tFS
#define tFS tSS
#endif
#ifndef tGS
#define tGS tSS
#endif
/* These tables map between the registers on a trap frame, and the register
order used by the rest of GDB. */
/* this table must line up with REGISTER_NAMES in tm-i386.h */
/* symbols like 'tEAX' come from <machine/reg.h> */
static int tregmap[] =
{
tEAX, tECX, tEDX, tEBX,
tESP, tEBP, tESI, tEDI,
tEIP, tEFLAGS, tCS, tSS,
tDS, tES, tFS, tGS
};
#ifdef sEAX
static int sregmap[] =
{
sEAX, sECX, sEDX, sEBX,
sESP, sEBP, sESI, sEDI,
sEIP, sEFLAGS, sCS, sSS
};
#else /* No sEAX */
/* FreeBSD has decided to collapse the s* and t* symbols. So if the s*
ones aren't around, use the t* ones for sregmap too. */
static int sregmap[] =
{
tEAX, tECX, tEDX, tEBX,
tESP, tEBP, tESI, tEDI,
tEIP, tEFLAGS, tCS, tSS,
tDS, tES, tFS, tGS
};
#endif /* No sEAX */
/* blockend is the value of u.u_ar0, and points to the
place where ES is stored. */
int
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. */
if (blockend < 0x1fcc)
return (blockend + 4 * tregmap[regnum]);
else
return (blockend + 4 * sregmap[regnum]);
}

View file

@ -1,15 +0,0 @@
LIB= iberty
INTERNALLIB= true
INTERNALSTATICLIB= true
GDBDIR= ${.CURDIR}/../../../../contrib/gdb
.PATH: ${GDBDIR}/libiberty
SRCS= argv.c basename.c concat.c cplus-dem.c fdmatch.c getopt.c \
getopt1.c getruntime.c hex.c floatformat.c obstack.c spaces.c \
strsignal.c xatexit.c xexit.c \
xmalloc.c xstrdup.c xstrerror.c insque.c
CFLAGS+= -I$(.CURDIR) -I$(.CURDIR)/../gdb/.
.include <bsd.lib.mk>

View file

@ -1,16 +0,0 @@
/* "Normal" configuration for alloca. */
#ifdef __GNUC__
#define alloca __builtin_alloca
#else /* not __GNUC__ */
#ifdef sparc
#include <alloca.h>
extern char *__builtin_alloca(); /* Stupid include file doesn't declare it */
#else
#ifdef __STDC__
PTR alloca (size_t);
#else
PTR alloca (); /* must agree with functions.def */
#endif
#endif /* sparc */
#endif /* not __GNUC__ */

View file

@ -1,7 +0,0 @@
/* !Automatically generated from ./functions.def - DO NOT EDIT! */
#ifndef NEED_basename
#define NEED_basename
#endif
#ifndef NEED_on_exit
#define NEED_on_exit
#endif