diff options
author | obrien <obrien@FreeBSD.org> | 2004-05-13 04:28:38 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2004-05-13 04:28:38 +0000 |
commit | 010ed4b30ecfc4f61afb7216f26db86d9bf50d80 (patch) | |
tree | cb2fd4f2d7e1c9495fd632954a05e4eefe743c33 /devel | |
parent | 0c0a70e5d3555b6d92fe4447a17b04a2703da485 (diff) | |
download | FreeBSD-ports-010ed4b30ecfc4f61afb7216f26db86d9bf50d80.zip FreeBSD-ports-010ed4b30ecfc4f61afb7216f26db86d9bf50d80.tar.gz |
Update to the 2004-05-11 snapshot.
Also enable kgdb and thread support!
This is missing IA64 support, and the AMD64 kgdb support is hokey and needs
a few more bits filled in.
Diffstat (limited to 'devel')
58 files changed, 4236 insertions, 4018 deletions
diff --git a/devel/gdb6/Makefile b/devel/gdb6/Makefile index 660de03..35c4d09 100644 --- a/devel/gdb6/Makefile +++ b/devel/gdb6/Makefile @@ -6,7 +6,7 @@ # $FreeBSD$ # -SNAPDATE= 2004-05-04 +SNAPDATE= 2004-05-11 SNAPVER= ${SNAPDATE:S/-//g} PORTNAME= gdb @@ -17,17 +17,20 @@ MASTER_SITES= ${MASTER_SITE_SOURCEWARE} MASTER_SITE_SUBDIR= gdb/snapshots/current DISTNAME= gdb+dejagnu-weekly-${SNAPVER} +PATCH_SITES= ${MASTER_SITE_LOCAL} +PATCH_SITE_SUBDIR= obrien +#PATCHFILES= gdb60_xfree-loadmod.diff + MAINTAINER= obrien@FreeBSD.org COMMENT= GNU GDB 6 -LATEST_LINK= gdb6 WRKSRC= ${WRKDIR}/${DISTNAME:S/-weekly//} USE_BZIP2= yes USE_GMAKE= yes USE_REINPLACE= yes GNU_CONFIGURE= yes CONFIGURE_ARGS= --program-suffix=6 -CFLAGS+= -DRL_NO_COMPAT +CFLAGS+= -DRL_NO_COMPAT -DKGDB .include <bsd.port.pre.mk> @@ -47,22 +50,23 @@ PLIST_SUB+= NO_NATIVE_GDB="@comment " .endif post-patch: - @${REINPLACE_CMD} -e 's/$$/ [FreeBSD]/' ${WRKSRC}/gdb/version.in + @${REINPLACE_CMD} -e 's/$$/ [GDB v6.x for FreeBSD]/' \ + ${WRKSRC}/gdb/version.in @${REINPLACE_CMD} -e 's/^READLINE/#READLINE/' \ -e 's/^readline/#readline/' \ ${WRKSRC}/gdb/Makefile.in ${ECHO} 'READLINE = -lreadline' >> ${WRKSRC}/gdb/Makefile.in -do-patch: post-patch - @${ECHO} 'FreeBSD-specific patches disabled for now, until upgraded.' - pre-configure: cd ${WRKSRC} ; ${RM} -rf dejagnu expect readline sim tcl texinfo +.for f in freebsd-uthread.c kvm-fbsd.c + ${LN} -sf ${FILESDIR}/${f} ${WRKSRC}/gdb +.endfor + ${LN} -sf ${FILESDIR}/nm-fbsd.h ${WRKSRC}/gdb/config do-install: ${INSTALL_PROGRAM} ${WRKSRC}/gdb/gdb \ ${PREFIX}/bin/${PORTNAME}${PORTVERSION:S/.//g} - cklatest: ncftpls \ ftp://sources.redhat.com/pub/${MASTER_SITE_SUBDIR}/ \ diff --git a/devel/gdb6/distinfo b/devel/gdb6/distinfo index ba05099..23a57b9 100644 --- a/devel/gdb6/distinfo +++ b/devel/gdb6/distinfo @@ -1,2 +1,2 @@ -MD5 (gdb+dejagnu-weekly-20040504.tar.bz2) = 020cb9bc6e414050fb813f23c84b6bc2 -SIZE (gdb+dejagnu-weekly-20040504.tar.bz2) = 16736958 +MD5 (gdb+dejagnu-weekly-20040511.tar.bz2) = 885cc6fc6265a4c43c10d8d1b14e76f8 +SIZE (gdb+dejagnu-weekly-20040511.tar.bz2) = 16759923 diff --git a/devel/gdb6/files/freebsd-uthread.c b/devel/gdb6/files/freebsd-uthread.c new file mode 100644 index 0000000..933dc51 --- /dev/null +++ b/devel/gdb6/files/freebsd-uthread.c @@ -0,0 +1,993 @@ +/* Low level interface for debugging FreeBSD user threads for GDB, the GNU debugger. + Copyright 1996, 1999 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. */ + +/* $FreeBSD$ */ + +/* This module implements a sort of half target that sits between the + machine-independent parts of GDB and the ptrace interface (infptrace.c) to + provide access to the FreeBSD user-mode thread implementation. + + FreeBSD threads are true user-mode threads, which are invoked via + the pthread_* interfaces. These are mostly implemented in + user-space, with all thread context kept in various structures that + live in the user's heap. For the most part, the kernel has no + knowlege of these threads. + + Based largely on hpux-thread.c + + */ + + +#include "defs.h" +#include <sys/queue.h> +#include <signal.h> +#include <setjmp.h> +#include <string.h> +#include "gdbthread.h" +#include "target.h" +#include "inferior.h" +#include <fcntl.h> +#include <ucontext.h> +#include <unistd.h> +#include <sys/stat.h> +#include "gdbcore.h" +#include "regcache.h" + +extern int child_suppress_run; +extern struct target_ops child_ops; /* target vector for inftarg.c */ + +extern void _initialize_freebsd_uthread PARAMS ((void)); + +/* Set to true while we are part-way through attaching */ +static int freebsd_uthread_attaching; + +static int freebsd_uthread_active = 0; +static CORE_ADDR P_thread_list; +static CORE_ADDR P_thread_run; + +/* Pointer to the next function on the objfile event chain. */ +static void (*target_new_objfile_chain) (struct objfile *objfile); + +static void freebsd_uthread_resume PARAMS ((ptid_t pid, int step, + enum target_signal signo)); + +static void init_freebsd_uthread_ops PARAMS ((void)); + +static struct target_ops freebsd_uthread_ops; + +static ptid_t find_active_ptid PARAMS ((void)); + +struct cached_pthread { + u_int64_t uniqueid; + int state; + CORE_ADDR name; + union { + ucontext_t uc; + jmp_buf jb; + } ctx; +}; + +static ptid_t cached_ptid; +static struct cached_pthread cached_pthread; +static CORE_ADDR cached_pthread_addr; + +LIST_HEAD(idmaplist, idmap); + +struct idmap { + LIST_ENTRY(idmap) link; + u_int64_t uniqueid; + int tid; +}; + +#define MAPHASH_SIZE 257 +#define TID_MIN 1 +#define TID_MAX 16383 + +static int tid_to_hash[TID_MAX + 1]; /* set to map_hash index */ +static struct idmaplist map_hash[MAPHASH_SIZE]; +static int next_free_tid = TID_MIN; /* first available tid */ +static int last_free_tid = TID_MIN; /* first unavailable */ + +static CORE_ADDR P_thread_next_offset; +static CORE_ADDR P_thread_uniqueid_offset; +static CORE_ADDR P_thread_state_offset; +static CORE_ADDR P_thread_name_offset; +static CORE_ADDR P_thread_ctx_offset; +static CORE_ADDR P_thread_PS_RUNNING_value; +static CORE_ADDR P_thread_PS_DEAD_value; + +static int next_offset; +static int uniqueid_offset; +static int state_offset; +static int name_offset; +static int ctx_offset; +static int PS_RUNNING_value; +static int PS_DEAD_value; + +#define UNIQUEID_HASH(id) (id % MAPHASH_SIZE) +#define TID_ADD1(tid) (((tid) + 1) == TID_MAX + 1 \ + ? TID_MIN : (tid) + 1) +#define IS_TID_FREE(tid) (tid_to_hash[tid] == -1) + +static int +get_new_tid(int h) +{ + int tid = next_free_tid; + + tid_to_hash[tid] = h; + next_free_tid = TID_ADD1(next_free_tid); + if (next_free_tid == last_free_tid) + { + int i; + + for (i = last_free_tid; TID_ADD1(i) != last_free_tid; i = TID_ADD1(i)) + if (IS_TID_FREE(i)) + break; + if (TID_ADD1(i) == last_free_tid) + { + error("too many threads"); + return 0; + } + next_free_tid = i; + for (i = TID_ADD1(i); IS_TID_FREE(i); i = TID_ADD1(i)) + ; + last_free_tid = i; + } + + return tid; +} + +static ptid_t +find_ptid(u_int64_t uniqueid) +{ + int h = UNIQUEID_HASH(uniqueid); + struct idmap *im; + + LIST_FOREACH(im, &map_hash[h], link) + if (im->uniqueid == uniqueid) + return MERGEPID(PIDGET(inferior_ptid), im->tid); + + im = xmalloc(sizeof(struct idmap)); + im->uniqueid = uniqueid; + im->tid = get_new_tid(h); + LIST_INSERT_HEAD(&map_hash[h], im, link); + + return MERGEPID(PIDGET(inferior_ptid), im->tid); +} + +static void +free_ptid(ptid_t ptid) +{ + int tid = TIDGET(ptid); + int h = tid_to_hash[tid]; + struct idmap *im; + + if (!tid) return; + + LIST_FOREACH(im, &map_hash[h], link) + if (im->tid == tid) + break; + + if (!im) return; + + LIST_REMOVE(im, link); + tid_to_hash[tid] = -1; + free(im); +} + +#define READ_OFFSET(field) read_memory(P_thread_##field##_offset, \ + (char *) &field##_offset, \ + sizeof(field##_offset)) + +#define READ_VALUE(name) read_memory(P_thread_##name##_value, \ + (char *) &name##_value, \ + sizeof(name##_value)) + +static void +read_thread_offsets (void) +{ + READ_OFFSET(next); + READ_OFFSET(uniqueid); + READ_OFFSET(state); + READ_OFFSET(name); + READ_OFFSET(ctx); + + READ_VALUE(PS_RUNNING); + READ_VALUE(PS_DEAD); +} + +#define READ_FIELD(ptr, T, field, result) \ + read_memory ((ptr) + field##_offset, (char *) &(result), sizeof result) + +static u_int64_t +read_pthread_uniqueid (CORE_ADDR ptr) +{ + u_int64_t uniqueid; + READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid); + return uniqueid; +} + +static CORE_ADDR +read_pthread_next (CORE_ADDR ptr) +{ + CORE_ADDR next; + READ_FIELD(ptr, CORE_ADDR, next, next); + return next; +} + +static void +read_cached_pthread (CORE_ADDR ptr, struct cached_pthread *cache) +{ + READ_FIELD(ptr, u_int64_t, uniqueid, cache->uniqueid); + READ_FIELD(ptr, int, state, cache->state); + READ_FIELD(ptr, CORE_ADDR, name, cache->name); + READ_FIELD(ptr, ucontext_t, ctx, cache->ctx); +} + +static ptid_t +find_active_ptid (void) +{ + CORE_ADDR ptr; + + read_memory ((CORE_ADDR)P_thread_run, + (char *)&ptr, + sizeof ptr); + + return find_ptid(read_pthread_uniqueid(ptr)); +} + +static CORE_ADDR find_pthread_addr PARAMS ((ptid_t ptid)); +static struct cached_pthread * find_pthread PARAMS ((ptid_t ptid)); + +static CORE_ADDR +find_pthread_addr (ptid_t ptid) +{ + CORE_ADDR ptr; + + if (ptid_equal(ptid, cached_ptid)) + return cached_pthread_addr; + + read_memory ((CORE_ADDR)P_thread_list, + (char *)&ptr, + sizeof ptr); + + while (ptr != 0) + { + if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid)) + { + cached_ptid = ptid; + cached_pthread_addr = ptr; + read_cached_pthread(ptr, &cached_pthread); + return ptr; + } + ptr = read_pthread_next(ptr); + } + + return NULL; +} + +static struct cached_pthread * +find_pthread (ptid_t ptid) +{ + CORE_ADDR ptr; + + if (ptid_equal(ptid, cached_ptid)) + return &cached_pthread; + + read_memory ((CORE_ADDR)P_thread_list, + (char *)&ptr, + sizeof ptr); + + while (ptr != 0) + { + if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid)) + { + cached_ptid = ptid; + cached_pthread_addr = ptr; + read_cached_pthread(ptr, &cached_pthread); + return &cached_pthread; + } + ptr = read_pthread_next(ptr); + } + +#if 0 + error ("Can't find pthread %d,%d", PIDGET(ptid), TIDGET(ptid)); +#endif + return NULL; +} + + +/* Most target vector functions from here on actually just pass through to + inftarg.c, as they don't need to do anything specific for threads. */ + +/* ARGSUSED */ +static void +freebsd_uthread_open (char *arg, int from_tty) +{ + child_ops.to_open (arg, from_tty); +} + +/* Attach to process PID, then initialize for debugging it + and wait for the trace-trap that results from attaching. */ + +static void +freebsd_uthread_attach (char *args, int from_tty) +{ + child_ops.to_attach (args, from_tty); + push_target (&freebsd_uthread_ops); + freebsd_uthread_attaching = 1; +} + +/* After an attach, see if the target is threaded */ + +static void +freebsd_uthread_post_attach (int pid) +{ + if (freebsd_uthread_active) + { + read_thread_offsets (); + inferior_ptid = find_active_ptid (); + add_thread (inferior_ptid); + } + else + { + unpush_target (&freebsd_uthread_ops); + push_target (&child_ops); + } + + freebsd_uthread_attaching = 0; +} + +/* Take a program previously attached to and detaches it. + The program resumes execution and will no longer stop + on signals, etc. We'd better not have left any breakpoints + in the program or it'll die when it hits one. For this + to work, it may be necessary for the process to have been + previously attached. It *might* work if the program was + started via the normal ptrace (PTRACE_TRACEME). */ + +static void +freebsd_uthread_detach (char *args, int from_tty) +{ + child_ops.to_detach (args, from_tty); +} + +/* Resume execution of process PID. If STEP is nozero, then + just single step it. If SIGNAL is nonzero, restart it with that + signal activated. We may have to convert pid from a thread-id to an LWP id + for procfs. */ + +static void +freebsd_uthread_resume (ptid_t ptid, int step, enum target_signal signo) +{ + if (freebsd_uthread_attaching) + { + child_ops.to_resume (ptid, step, signo); + return; + } + + child_ops.to_resume (ptid, step, signo); + cached_ptid = MERGEPID(0, 0); +} + +/* Wait for any threads to stop. We may have to convert PID from a thread id + to a LWP id, and vice versa on the way out. */ + +static ptid_t +freebsd_uthread_wait (ptid_t ptid, struct target_waitstatus *ourstatus) +{ + ptid_t rtnval; + + if (freebsd_uthread_attaching) + { + return child_ops.to_wait (ptid, ourstatus); + } + + rtnval = child_ops.to_wait (ptid, ourstatus); + + if (PIDGET(rtnval) >= 0) + { + rtnval = find_active_ptid (); + if (!in_thread_list (rtnval)) + add_thread (rtnval); + } + + return rtnval; +} + +/* XXX: this needs to be selected by target, not [build] host */ +#ifdef __i386__ + +#include "i386-tdep.h" + +static char sigmap[I386_SSE_NUM_REGS] = /* map reg to sigcontext */ +{ + 12, /* eax */ + 11, /* ecx */ + 10, /* edx */ + 9, /* ebx */ + 8, /* esp */ + 7, /* ebp */ + 6, /* esi */ + 5, /* edi */ + 15, /* eip */ + 17, /* eflags */ + 16, /* cs */ + 19, /* ss */ + 4, /* ds */ + 3, /* es */ + 2, /* fs */ + 1, /* gs */ + -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ + -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ + -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ + -1, /* mxcsr */ +}; + +static char jmpmap[I386_SSE_NUM_REGS] = /* map reg to jmp_buf */ +{ + 6, /* eax */ + -1, /* ecx */ + -1, /* edx */ + 1, /* ebx */ + 2, /* esp */ + 3, /* ebp */ + 4, /* esi */ + 5, /* edi */ + 0, /* eip */ + -1, /* eflags */ + -1, /* cs */ + -1, /* ss */ + -1, /* ds */ + -1, /* es */ + -1, /* fs */ + -1, /* gs */ + -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ + -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ + -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ + -1, /* mxcsr */ +}; + +#endif + +#ifdef __amd64__ + +#include "amd64-tdep.h" + +// XXX:DEO not fully ported from i386 yet!! + +static char sigmap[AMD64_NUM_REGS_TOTAL] = /* map reg to sigcontext */ +{ + 12, /* rax */ + 11, /* rcx */ + 10, /* rdx */ + 9, /* rbx */ + 8, /* rsp */ + 7, /* rbp */ + 6, /* rsi */ + 5, /* rdi */ + 15, /* rip */ + 17, /* rflags */ + 16, /* cs */ + 19, /* ss */ + 4, /* ds */ + 3, /* es */ + 2, /* fs */ + 1, /* gs */ + -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ + -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ + -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ + -1, /* mxcsr */ +}; + +static char jmpmap[AMD64_NUM_REGS_TOTAL] = /* map reg to jmp_buf */ +{ + 6, /* rax */ + -1, /* rcx */ + -1, /* rdx */ + 1, /* rbx */ + 2, /* rsp */ + 3, /* rbp */ + 4, /* rsi */ + 5, /* rdi */ + 0, /* rip */ + -1, /* rflags */ + -1, /* cs */ + -1, /* ss */ + -1, /* ds */ + -1, /* es */ + -1, /* fs */ + -1, /* gs */ + -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ + -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ + -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ + -1, /* mxcsr */ +}; + +#endif + +#ifdef __alpha__ + +#include "alpha-tdep.h" + +static char sigmap[ALPHA_NUM_REGS] = /* map reg to sigcontext */ +{ + 1, 2, 3, 4, 5, 6, 7, 8, /* v0 - t6 */ + 9, 10, 11, 12, 13, 14, 15, 16, /* t7 - fp */ + 17, 18, 19, 20, 21, 22, 23, 24, /* a0 - t9 */ + 25, 26, 27, 28, 29, 30, 31, 32, /* t10 - zero */ + 38, 39, 40, 41, 42, 43, 44, 45, /* f0 - f7 */ + 46, 47, 48, 49, 50, 51, 52, 53, /* f8 - f15 */ + 54, 55, 56, 57, 58, 59, 60, 61, /* f16 - f23 */ + 62, 63, 64, 65, 66, 67, 68, 69, /* f24 - f31 */ + 33, -1 /* pc, vfp */ +}; +static char jmpmap[ALPHA_NUM_REGS] = { + 4, 5, 6, 7, 8, 9, 10, 11, /* v0 - t6 */ + 12, 13, 14, 15, 16, 17, 18, 19, /* t7 - fp */ + 20, 21, 22, 23, 24, 25, 26, 27, /* a0 - t9 */ + 28, 29, 30, 31, 32, 33, 34, 35, /* t10 - zero */ + 37, 38, 39, 40, 41, 42, 43, 44, /* f0 - f7 */ + 45, 46, 47, 48, 49, 50, 51, 52, /* f8 - f15 */ + 53, 54, 55, 56, 57, 58, 59, 60, /* f16 - f23 */ + 61, 62, 63, 64, 65, 66, 67, 68, /* f24 - f31 */ + 2, -1, /* pc, vfp */ +}; + +#endif + +#ifdef __sparc64__ + +static char sigmap[125] = /* map reg to sigcontext */ +{ + -1 +}; +static char jmpmap[125] = { + -1 +}; + +#endif + +static void +freebsd_uthread_fetch_registers (int regno) +{ + struct cached_pthread *thread; + int active; + int first_regno, last_regno; + register_t *regbase; + char *regmap; + + if (freebsd_uthread_attaching || TIDGET(inferior_ptid) == 0) + { + child_ops.to_fetch_registers (regno); + return; + } + + thread = find_pthread (inferior_ptid); + active = (ptid_equal(inferior_ptid, find_active_ptid())); + + if (active) + { + child_ops.to_fetch_registers (regno); + return; + } + + if (regno == -1) + { + first_regno = 0; + last_regno = NUM_REGS - 1; + } + else + { + first_regno = regno; + last_regno = regno; + } + + regbase = (register_t*) &thread->ctx.jb[0]; + regmap = jmpmap; + + for (regno = first_regno; regno <= last_regno; regno++) + { + if (regmap[regno] == -1) + child_ops.to_fetch_registers (regno); + else + if (thread) + supply_register (regno, (char*) ®base[regmap[regno]]); + else + supply_register (regno, NULL); + } +} + +static void +freebsd_uthread_store_registers (int regno) +{ + struct cached_pthread *thread; + CORE_ADDR ptr; + int first_regno, last_regno; + u_int32_t *regbase; + char *regmap; + + if (freebsd_uthread_attaching) + { + child_ops.to_store_registers (regno); + return; + } + + thread = find_pthread (inferior_ptid); + + if (thread->state == PS_RUNNING_value) + { + child_ops.to_store_registers (regno); + return; + } + + if (regno == -1) + { + first_regno = 0; + last_regno = NUM_REGS - 1; + } + else + { + first_regno = regno; + last_regno = regno; + } + + regbase = (u_int32_t*) &thread->ctx.jb[0]; + regmap = jmpmap; + + ptr = find_pthread_addr (inferior_ptid); + for (regno = first_regno; regno <= last_regno; regno++) + { + if (regmap[regno] == -1) + child_ops.to_store_registers (regno); + else + { + u_int32_t *reg = ®base[regmap[regno]]; + int off; + + /* Hang onto cached value */ +/*DEO:XXX*/ + memcpy(reg, deprecated_registers /*regcache_collect ()*/+ DEPRECATED_REGISTER_BYTE (regno), + DEPRECATED_REGISTER_RAW_SIZE (regno)); + + /* And push out to inferior */ + off = (char *) reg - (char *) thread; + write_memory (ptr + off, +/*DEO:XXX*/ + deprecated_registers /*regcache_collect ()*/+ DEPRECATED_REGISTER_BYTE (regno), + DEPRECATED_REGISTER_RAW_SIZE (regno)); + } + } +} + +/* Get ready to modify the registers array. On machines which store + individual registers, this doesn't need to do anything. On machines + which store all the registers in one fell swoop, this makes sure + that registers contains all the registers from the program being + debugged. */ + +static void +freebsd_uthread_prepare_to_store (void) +{ + child_ops.to_prepare_to_store (); +} + +static int +freebsd_uthread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, + int dowrite, struct mem_attrib *attrib, + struct target_ops *target) +{ + return child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, + attrib, target); +} + +/* Print status information about what we're accessing. */ + +static void +freebsd_uthread_files_info (struct target_ops *ignore) +{ + child_ops.to_files_info (ignore); +} + +static void +freebsd_uthread_kill_inferior (void) +{ + child_ops.to_kill (); +} + +static void +freebsd_uthread_notice_signals (ptid_t ptid) +{ + child_ops.to_notice_signals (ptid); +} + +/* Fork an inferior process, and start debugging it with /proc. */ + +static void +freebsd_uthread_create_inferior (char *exec_file, char *allargs, char **env) +{ + child_ops.to_create_inferior (exec_file, allargs, env); + + if (PIDGET(inferior_ptid) && freebsd_uthread_active) + { + read_thread_offsets (); + push_target (&freebsd_uthread_ops); + inferior_ptid = find_active_ptid (); + add_thread (inferior_ptid); + } +} + +/* This routine is called to find out if the inferior is using threads. + We check for the _thread_run and _thread_list globals. */ + +void +freebsd_uthread_new_objfile (struct objfile *objfile) +{ + struct minimal_symbol *ms; + + if (!objfile) + { + freebsd_uthread_active = 0; + return; + } + + ms = lookup_minimal_symbol ("_thread_run", NULL, objfile); + + if (!ms) + return; + + P_thread_run = SYMBOL_VALUE_ADDRESS (ms); + + ms = lookup_minimal_symbol ("_thread_list", NULL, objfile); + + if (!ms) + return; + + P_thread_list = SYMBOL_VALUE_ADDRESS (ms); + +#define OFFSET_SYM(field) "_thread_" #field "_offset" +#define LOOKUP_OFFSET(field) \ + do { \ + ms = lookup_minimal_symbol (OFFSET_SYM(field), NULL, objfile); \ + if (!ms) \ + return; \ + P_thread_##field##_offset = SYMBOL_VALUE_ADDRESS (ms); \ + } while (0); + +#define VALUE_SYM(name) "_thread_" #name "_value" +#define LOOKUP_VALUE(name) \ + do { \ + ms = lookup_minimal_symbol (VALUE_SYM(name), NULL, objfile); \ + if (!ms) \ + return; \ + P_thread_##name##_value = SYMBOL_VALUE_ADDRESS (ms); \ + } while (0); + + LOOKUP_OFFSET(next); + LOOKUP_OFFSET(uniqueid); + LOOKUP_OFFSET(state); + LOOKUP_OFFSET(name); + LOOKUP_OFFSET(ctx); + + LOOKUP_VALUE(PS_RUNNING); + LOOKUP_VALUE(PS_DEAD); + + freebsd_uthread_active = 1; +} + +/* Clean up after the inferior dies. */ + +static void +freebsd_uthread_mourn_inferior () +{ + child_ops.to_mourn_inferior (); + unpush_target (&freebsd_uthread_ops); +} + +/* Mark our target-struct as eligible for stray "run" and "attach" commands. */ + +static int +freebsd_uthread_can_run () +{ + return child_suppress_run; +} + +static int +freebsd_uthread_thread_alive (ptid_t ptid) +{ + struct cached_pthread *thread; + int ret = 0; + + if (freebsd_uthread_attaching) + return 1; + + /* + * We can get called from child_ops.to_wait() which passes the underlying + * pid (without a thread number). + */ + if (TIDGET(ptid) == 0) + return 1; + + if (find_pthread_addr (ptid) != 0) + { + thread = find_pthread (ptid); + ret = (thread->state != PS_DEAD_value); + } + + if (!ret) + free_ptid(ptid); + + return ret; +} + +static void +freebsd_uthread_stop (void) +{ + child_ops.to_stop (); +} + +static void +freebsd_uthread_find_new_threads (void) +{ + CORE_ADDR ptr; + int state; + u_int64_t uniqueid; + + read_memory ((CORE_ADDR)P_thread_list, + (char *)&ptr, + sizeof ptr); + + while (ptr != 0) + { + READ_FIELD(ptr, int, state, state); + READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid); + if (state != PS_DEAD_value && + !in_thread_list (find_ptid(uniqueid))) + add_thread (find_ptid(uniqueid)); + ptr = read_pthread_next(ptr); + } +} + +/* MUST MATCH enum pthread_state */ +static const char *statenames[] = { + "RUNNING", + "SIGTHREAD", + "MUTEX_WAIT", + "COND_WAIT", + "FDLR_WAIT", + "FDLW_WAIT", + "FDR_WAIT", + "FDW_WAIT", + "POLL_WAIT", + "FILE_WAIT", + "SELECT_WAIT", + "SLEEP_WAIT", + "WAIT_WAIT", + "SIGSUSPEND", + "SIGWAIT", + "SPINBLOCK", + "JOIN", + "SUSPENDED", + "DEAD", + "DEADLOCK", +}; + +#if 0 + +static int +freebsd_uthread_get_thread_info (ref, selection, info) + gdb_threadref *ref; + int selection; + struct gdb_ext_thread_info *info; +{ + int pid = *ref; + struct cached_pthread *thread = find_pthread (pid); + struct cleanup *old_chain; + + old_chain = save_inferior_pid (); + inferior_pid = main_pid; + + memset(&info->threadid, 0, OPAQUETHREADBYTES); + + memcpy(&info->threadid, ref, sizeof *ref); + info->active = thread->state == PS_RUNNING_value; + strcpy(info->display, statenames[thread->state]); + if (thread->name) + read_memory ((CORE_ADDR) thread->name, info->shortname, 32); + else + strcpy(info->shortname, ""); + + do_cleanups (old_chain); + return (0); +} + +#endif + +char * +freebsd_uthread_pid_to_str (ptid_t ptid) +{ + static char buf[30]; + + if (DEPRECATED_STREQ (current_target.to_shortname, "freebsd-uthreads")) + sprintf (buf, "Process %d, Thread %ld", + PIDGET(ptid), TIDGET(ptid)); + else + sprintf (buf, "Process %d", PIDGET(ptid)); + + return buf; +} + + +static void +init_freebsd_uthread_ops () +{ + freebsd_uthread_ops.to_shortname = "freebsd-uthreads"; + freebsd_uthread_ops.to_longname = "FreeBSD uthreads"; + freebsd_uthread_ops.to_doc = "FreeBSD user threads support."; + freebsd_uthread_ops.to_open = freebsd_uthread_open; + freebsd_uthread_ops.to_attach = freebsd_uthread_attach; + freebsd_uthread_ops.to_post_attach = freebsd_uthread_post_attach; + freebsd_uthread_ops.to_detach = freebsd_uthread_detach; + freebsd_uthread_ops.to_resume = freebsd_uthread_resume; + freebsd_uthread_ops.to_wait = freebsd_uthread_wait; + freebsd_uthread_ops.to_fetch_registers = freebsd_uthread_fetch_registers; + freebsd_uthread_ops.to_store_registers = freebsd_uthread_store_registers; + freebsd_uthread_ops.to_prepare_to_store = freebsd_uthread_prepare_to_store; + freebsd_uthread_ops.to_xfer_memory = freebsd_uthread_xfer_memory; + freebsd_uthread_ops.to_files_info = freebsd_uthread_files_info; + freebsd_uthread_ops.to_insert_breakpoint = memory_insert_breakpoint; + freebsd_uthread_ops.to_remove_breakpoint = memory_remove_breakpoint; + freebsd_uthread_ops.to_terminal_init = terminal_init_inferior; + freebsd_uthread_ops.to_terminal_inferior = terminal_inferior; + freebsd_uthread_ops.to_terminal_ours_for_output = terminal_ours_for_output; + freebsd_uthread_ops.to_terminal_ours = terminal_ours; + freebsd_uthread_ops.to_terminal_info = child_terminal_info; + freebsd_uthread_ops.to_kill = freebsd_uthread_kill_inferior; + freebsd_uthread_ops.to_create_inferior = freebsd_uthread_create_inferior; + freebsd_uthread_ops.to_mourn_inferior = freebsd_uthread_mourn_inferior; + freebsd_uthread_ops.to_can_run = freebsd_uthread_can_run; + freebsd_uthread_ops.to_notice_signals = freebsd_uthread_notice_signals; + freebsd_uthread_ops.to_thread_alive = freebsd_uthread_thread_alive; + freebsd_uthread_ops.to_stop = freebsd_uthread_stop; + freebsd_uthread_ops.to_stratum = process_stratum; + freebsd_uthread_ops.to_has_all_memory = 1; + freebsd_uthread_ops.to_has_memory = 1; + freebsd_uthread_ops.to_has_stack = 1; + freebsd_uthread_ops.to_has_registers = 1; + freebsd_uthread_ops.to_has_execution = 1; + freebsd_uthread_ops.to_has_thread_control = 0; + freebsd_uthread_ops.to_magic = OPS_MAGIC; + freebsd_uthread_ops.to_find_new_threads = freebsd_uthread_find_new_threads; + freebsd_uthread_ops.to_pid_to_str = freebsd_uthread_pid_to_str; +#if 0 + freebsd_uthread_vec.get_thread_info = freebsd_uthread_get_thread_info; +#endif +} + +void +_initialize_freebsd_uthread () +{ + init_freebsd_uthread_ops (); + add_target (&freebsd_uthread_ops); + + target_new_objfile_chain = deprecated_target_new_objfile_hook; + deprecated_target_new_objfile_hook = freebsd_uthread_new_objfile; + + child_suppress_run = 1; +} diff --git a/devel/gdb6/files/kvm-fbsd.c b/devel/gdb6/files/kvm-fbsd.c new file mode 100644 index 0000000..ad64dd9 --- /dev/null +++ b/devel/gdb6/files/kvm-fbsd.c @@ -0,0 +1,886 @@ +/* Kernel core dump functions below target vector, for GDB. + Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 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. +*/ + +/* $FreeBSD$ */ + +/* + * This works like "remote" but, you use it like this: + * target kcore /dev/mem + * or + * target kcore /var/crash/host/core.0 + * + * This way makes it easy to short-circut the whole bfd monster, + * and direct the inferior stuff to our libkvm implementation. + * + */ + +#include <sys/param.h> +#include <machine/frame.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/time.h> +#include <sys/user.h> + +#include <ctype.h> +#include <errno.h> +#include <signal.h> +#include <fcntl.h> +#include <kvm.h> +#include <paths.h> + +#include "defs.h" +#include "gdb_string.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 "regcache.h" +#include <readline/tilde.h> + +#if __FreeBSD_version >= 500032 +static void +kcore_files_info (struct target_ops *); + +static void +kcore_close (int); + +static void +get_kcore_registers (int); + + + /* +static int +xfer_mem (CORE_ADDR, char *, int, int, struct mem_attrib *, + struct target_ops *); + */ + +static int +xfer_umem (CORE_ADDR, char *, int, int); + +static char *core_file; +static kvm_t *core_kd; +static struct pcb cur_pcb; +static struct kinfo_proc *cur_proc; + +static struct target_ops kcore_ops; + +int kernel_debugging; +int kernel_writablecore; + +/* 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)))) + +static CORE_ADDR +ksym_kernbase (void) +{ + static CORE_ADDR kernbase; + struct minimal_symbol *sym; + + if (kernbase == 0) + { + sym = lookup_minimal_symbol ("kernbase", NULL, NULL); + if (sym == NULL) { + kernbase = KERNBASE; + } else { + kernbase = SYMBOL_VALUE_ADDRESS (sym); + } + } + return kernbase; +} + +#define KERNOFF (ksym_kernbase ()) +#define INKERNEL(x) ((x) >= KERNOFF) + +CORE_ADDR +ksym_lookup(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); +} + +/* Provide the address of an initial PCB to use. + If this is a crash dump, try for "dumppcb". + If no "dumppcb" or it's /dev/mem, use proc0. + Return the core address of the PCB we found. */ + +static CORE_ADDR +initial_pcb (void) +{ + struct minimal_symbol *sym; + CORE_ADDR addr; + void *val; + + /* Make sure things are open... */ + if (!core_kd || !core_file) + return (0); + + /* If this is NOT /dev/mem try for dumppcb. */ + if (strncmp (core_file, _PATH_DEV, sizeof _PATH_DEV - 1)) + { + sym = lookup_minimal_symbol ("dumppcb", NULL, NULL); + if (sym != NULL) + { + addr = SYMBOL_VALUE_ADDRESS (sym); + return (addr); + } + } + + /* OK, just use thread0's pcb. Note that curproc might + not exist, and if it does, it will point to gdb. + Therefore, just use proc0 and let the user set + some other context if they care about it. */ + + addr = ksym_lookup ("thread0"); + if (kvread (addr, &val)) + { + error ("cannot read thread0 pointer at %lx\n", addr); + val = 0; + } + else + { + /* Read the PCB address in thread structure. */ + addr += offsetof (struct thread, td_pcb); + if (kvread (addr, &val)) + { + error ("cannot read thread0->td_pcb pointer at %lx\n", addr); + val = 0; + } + } + + /* thread0 is wholly in the kernel and cur_proc is only used for + reading user mem, so no point in setting this up. */ + cur_proc = 0; + + return ((CORE_ADDR)val); +} + +/* Set the current context to that of the PCB struct at the system address + passed. */ + +static int +set_context (CORE_ADDR addr) +{ + CORE_ADDR procaddr = 0; + + if (kvread (addr, &cur_pcb)) + error ("cannot read pcb at %#lx", addr); + + /* 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 (); +/*DEO XXX + set_current_frame (create_new_frame (read_fp (), read_pc ())); + set_current_frame (create_new_frame (deprecated_read_fp (), read_pc ())); + select_frame (get_current_frame ()); +*/ + print_stack_frame (get_selected_frame (), -1, 1); + return (0); +} + +/* Discard all vestiges of any previous core file and mark data and stack + spaces as empty. */ + +/* ARGSUSED */ +static void +kcore_close (int quitting) +{ + + inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */ + + if (core_kd) + { + kvm_close (core_kd); + free (core_file); + core_file = NULL; + core_kd = NULL; + } +} + +/* This routine opens and sets up the core file bfd. */ + +static void +kcore_open (char *filename /* the core file */, int from_tty) +{ + kvm_t *kd; + const char *p; + struct cleanup *old_chain; + char buf[256], *cp; + int ontop; + CORE_ADDR addr; + + target_preopen (from_tty); + + /* The exec file is required for symbols. */ + if (exec_bfd == NULL) + error ("No kernel exec file specified"); + + if (core_kd) + { + error ("No core file specified." + " (Use `detach' to stop debugging a core file.)"); + return; + } + + if (!filename) + { + error ("No core file specified."); + return; + } + + filename = tilde_expand (filename); + if (filename[0] != '/') + { + cp = concat (current_directory, "/", filename, NULL); + free (filename); + filename = cp; + } + + old_chain = make_cleanup (free, filename); + + kd = kvm_open (bfd_get_filename(exec_bfd), filename, NULL, + kernel_writablecore ? O_RDWR: O_RDONLY, 0); + if (kd == NULL) + { + perror_with_name (filename); + return; + } + + /* 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; + unpush_target (&kcore_ops); + ontop = !push_target (&kcore_ops); + + /* Note unpush_target (above) calls kcore_close. */ + core_kd = kd; + + /* 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_filtered ("panic: %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; + } + + /* Now, set up process context, and print the top of stack. */ + (void)set_context (initial_pcb()); + print_stack_frame (get_selected_frame (), + frame_relative_level (get_selected_frame ()), 1); +} + +static void +kcore_detach (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"); +} + +#ifdef __alpha__ + +#include "alpha/tm-alpha.h" +#include "alpha-tdep.h" + +#ifndef S0_REGNUM +#define S0_REGNUM (ALPHA_T7_REGNUM+1) +#endif + +static void +fetch_kcore_registers (struct pcb *pcbp) +{ + + /* First clear out any garbage. */ + memset (deprecated_registers, '\0', DEPRECATED_REGISTER_BYTES); + + /* SP */ + *(long *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (SP_REGNUM)] = + pcbp->pcb_hw.apcb_ksp; + + /* S0 through S6 */ + memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (S0_REGNUM)], + &pcbp->pcb_context[0], 7 * sizeof (long)); + + /* PC */ + *(long *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)] = + pcbp->pcb_context[7]; + + deprecated_registers_fetched (); +} + + +CORE_ADDR +fbsd_kern_frame_saved_pc (struct frame_info *fi) +{ + struct minimal_symbol *sym; + CORE_ADDR this_saved_pc; + + this_saved_pc = DEPRECATED_FRAME_SAVED_PC(fi); + + sym = lookup_minimal_symbol_by_pc (this_saved_pc); + + if (sym != NULL && + (strcmp (DEPRECATED_SYMBOL_NAME (sym), "XentArith") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "XentIF") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "XentInt") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "XentMM") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "XentSys") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "XentUna") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "XentRestart") == 0)) + { + return (read_memory_integer (get_frame_base (fi) + 32 * 8, 8)); + } + else + { + return (this_saved_pc); + } +} + +#endif /* __alpha__ */ + +#ifdef __i386__ + +#include "i386-tdep.h" + +static CORE_ADDR +ksym_maxuseraddr (void) +{ + static CORE_ADDR maxuseraddr; + struct minimal_symbol *sym; + + if (maxuseraddr == 0) + { + sym = lookup_minimal_symbol ("PTmap", NULL, NULL); + if (sym == NULL) { + maxuseraddr = VM_MAXUSER_ADDRESS; + } else { + maxuseraddr = SYMBOL_VALUE_ADDRESS (sym); + } + } + return maxuseraddr; +} + + +/* Symbol names of kernel entry points. Use special frames. */ +#define KSYM_TRAP "calltrap" +#define KSYM_INTR "Xintr" +#define KSYM_FASTINTR "Xfastintr" +#define KSYM_OLDSYSCALL "Xlcall_syscall" +#define KSYM_SYSCALL "Xint0x80_syscall" + +/* 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 (struct frame_info *fi) +{ + struct minimal_symbol *sym; + CORE_ADDR this_saved_pc; + enum frametype frametype; + + this_saved_pc = read_memory_integer (get_frame_base (fi) + 4, 4); + sym = lookup_minimal_symbol_by_pc (this_saved_pc); + frametype = tf_normal; + if (sym != NULL) + { + if (strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_TRAP) == 0) + frametype = tf_trap; + else + if (strncmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_INTR, + strlen (KSYM_INTR)) == 0 || strncmp (DEPRECATED_SYMBOL_NAME(sym), + KSYM_FASTINTR, strlen (KSYM_FASTINTR)) == 0) + frametype = tf_interrupt; + else + if (strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_SYSCALL) == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_OLDSYSCALL) == 0) + frametype = tf_syscall; + } + + switch (frametype) + { + default: + case tf_normal: + return (this_saved_pc); +#define oEIP offsetof (struct trapframe, tf_eip) + + case tf_trap: + return (read_memory_integer (get_frame_base (fi) + 8 + oEIP, 4)); + + case tf_interrupt: + return (read_memory_integer (get_frame_base (fi) + 12 + oEIP, 4)); + + case tf_syscall: + return (read_memory_integer (get_frame_base (fi) + 8 + oEIP, 4)); +#undef oEIP + } +} + +static void +fetch_kcore_registers (struct pcb *pcb) +{ + int i; + int noreg; + + /* 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); + + /* DEO:XXX use SP_REGNUM and PC_REGNUM -- this is GDB_MULTI_ARCH */ + supply_register (3, (char *) &pcb->pcb_ebx); + supply_register (SP_REGNUM, (char *) &pcb->pcb_esp); + supply_register (I386_EBP_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? */ +} + +#endif /* __i386__ */ + +#ifdef __amd64__ + +#include "amd64-tdep.h" + +static CORE_ADDR +ksym_maxuseraddr (void) +{ + static CORE_ADDR maxuseraddr; + struct minimal_symbol *sym; + + if (maxuseraddr == 0) + { + sym = lookup_minimal_symbol ("PTmap", NULL, NULL); + if (sym == NULL) { + maxuseraddr = VM_MAXUSER_ADDRESS; + } else { + maxuseraddr = SYMBOL_VALUE_ADDRESS (sym); + } + } + return maxuseraddr; +} + + +/* Symbol names of kernel entry points. Use special frames. */ +#define KSYM_TRAP "calltrap" +#define KSYM_INTR "Xintr" +#define KSYM_FASTINTR "Xfastintr" +#define KSYM_OLDSYSCALL "Xlcall_syscall" +#define KSYM_SYSCALL "Xint0x80_syscall" + +/* 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 (struct frame_info *fi) +{ + struct minimal_symbol *sym; + CORE_ADDR this_saved_pc; + enum frametype frametype; + + this_saved_pc = read_memory_integer (get_frame_base (fi) + 4, 4); + sym = lookup_minimal_symbol_by_pc (this_saved_pc); + frametype = tf_normal; + if (sym != NULL) + { + if (strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_TRAP) == 0) + frametype = tf_trap; + else + if (strncmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_INTR, + strlen (KSYM_INTR)) == 0 || strncmp (DEPRECATED_SYMBOL_NAME(sym), + KSYM_FASTINTR, strlen (KSYM_FASTINTR)) == 0) + frametype = tf_interrupt; + else + if (strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_SYSCALL) == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_OLDSYSCALL) == 0) + frametype = tf_syscall; + } + + switch (frametype) + { + default: + case tf_normal: + return (this_saved_pc); +#define oEIP offsetof (struct trapframe, tf_rip) + + case tf_trap: + return (read_memory_integer (get_frame_base (fi) + 8 + oEIP, 4)); + + case tf_interrupt: + return (read_memory_integer (get_frame_base (fi) + 12 + oEIP, 4)); + + case tf_syscall: + return (read_memory_integer (get_frame_base (fi) + 8 + oEIP, 4)); +#undef oEIP + } +} + +static void +fetch_kcore_registers (struct pcb *pcb) +{ + int i; + int noreg; + + /* 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-amd64.h. + */ + noreg = 0; + for (i = 0; i < 3; ++i) /* eax,ecx,edx */ + supply_register (i, (char *)&noreg); + + /* DEO:XXX use SP_REGNUM and PC_REGNUM -- this is GDB_MULTI_ARCH */ + supply_register (3, (char *) &pcb->pcb_rbx); + supply_register (SP_REGNUM, (char *) &pcb->pcb_rsp); + supply_register (AMD64_RBP_REGNUM, (char *) &pcb->pcb_rbp); + supply_register (PC_REGNUM, (char *) &pcb->pcb_rip); + + for (i = 9; i < 14; ++i) /* rflags, cs, ss, ds, es, fs */ + supply_register (i, (char *) &noreg); + supply_register (15, (char *) &pcb->pcb_gs); + + /* XXX 80387 registers? */ +} + +#endif /* __amd64__ */ + +#ifdef __sparc64__ + +#include "sparc-tdep.h" + +#define SPARC_INTREG_SIZE 8 + +static void +fetch_kcore_registers (struct pcb *pcbp) +{ + static struct frame top; + CORE_ADDR f_addr; + int i; + + /* 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 do something with the floating-point registers? + */ + supply_register (SP_REGNUM, &pcbp->pcb_sp); + supply_register (PC_REGNUM, &pcbp->pcb_pc); + f_addr = extract_unsigned_integer (&pcbp->pcb_sp, SPARC_INTREG_SIZE); + /* Load the previous frame by hand (XXX) and supply it. */ + read_memory (f_addr + SPOFF, (char *)&top, sizeof (top)); + for (i = 0; i < 8; i++) + supply_register (i + SPARC_L0_REGNUM, &top.fr_local[i]); + for (i = 0; i < 8; i++) + supply_register (i + SPARC_I0_REGNUM, &top.fr_in[i]); +} + +CORE_ADDR +fbsd_kern_frame_saved_pc (struct frame_info *fi) +{ + struct minimal_symbol *sym; + CORE_ADDR frame, pc_addr, pc; + char *buf; + + buf = alloca (MAX_REGISTER_SIZE); //or use DEPRECATED_MAX_REGISTER_RAW_SIZE + /* XXX: duplicates fi->extra_info->bottom. */ + frame = (get_next_frame (fi) != NULL) ? get_frame_base (get_next_frame (fi)) : read_sp (); + pc_addr = frame + offsetof (struct frame, fr_in[7]); + +#define READ_PC(pc, a, b) do { \ + read_memory (a, b, SPARC_INTREG_SIZE); \ + pc = extract_unsigned_integer (b, SPARC_INTREG_SIZE); \ +} while (0) + + READ_PC (pc, pc_addr, buf); + + sym = lookup_minimal_symbol_by_pc (pc); + if (sym != NULL) + { + if (strncmp (DEPRECATED_SYMBOL_NAME (sym), "tl0_", 4) == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "btext") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "mp_startup") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "fork_trampoline") == 0) + { + /* + * Ugly kluge: user space addresses aren't separated from kernel + * ones by range; if encountering a trap from user space, just + * return a 0 to stop the trace. + * Do the same for entry points of kernel processes to avoid + * printing garbage. + */ + pc = 0; + } + if (strncmp (DEPRECATED_SYMBOL_NAME (sym), "tl1_", 4) == 0) + { + pc_addr = get_frame_base (fi) + sizeof (struct frame) + + offsetof (struct trapframe, tf_tpc); + READ_PC (pc, pc_addr, buf); + } + } + return (pc); +} + +#endif /* __sparc64__ */ + +/* 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 (int regno) +{ + + /* XXX - Only read the pcb when set_context() is called. + When looking at a live kernel this may be a problem, + but the user can do another "proc" or "pcb" command to + grab a new copy of the pcb... */ + + /* Zero out register set then fill in the ones we know about. */ + fetch_kcore_registers (&cur_pcb); +} + +static void +kcore_files_info (t) + struct target_ops *t; +{ + printf_filtered ("\t`%s'\n", core_file); +} + +/* If mourn is being called in all the right places, this could be say + `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */ + + /* +static int +ignore (CORE_ADDR addr, char *contents) +{ + return 0; +} + */ + +static int +xfer_kmem (CORE_ADDR memaddr, char *myaddr, int len, int write, + struct mem_attrib *attrib, struct target_ops *target) +{ + int n; + + + if (!INKERNEL (memaddr)) + return xfer_umem (memaddr, myaddr, len, write); + + if (core_kd == NULL) + return 0; + + if (write) + n = kvm_write (core_kd, memaddr, myaddr, len); + else + n = kvm_read (core_kd, memaddr, myaddr, len) ; + if (n < 0) { + fprintf_unfiltered (gdb_stderr, "can not access 0x%lx, %s\n", + memaddr, kvm_geterr (core_kd)); + n = 0; + } + + return n; +} + + +static int +xfer_umem (CORE_ADDR memaddr, char *myaddr, int len, int write /* ignored */) +{ + int n = 0; + + if (cur_proc == 0) + { + error ("---Can't read userspace from dump, or kernel process---\n"); + return 0; + } + + if (write) + error ("kvm_uwrite unimplemented\n"); + else + n = kvm_uread (core_kd, cur_proc, memaddr, myaddr, len) ; + + if (n < 0) + return 0; + + return n; +} + +static void +set_proc_cmd (char *arg, int from_tty) +{ + CORE_ADDR addr, pid_addr, first_td; + void *val; + struct kinfo_proc *kp; + int cnt; + pid_t pid; + + if (!arg) + error_no_arg ("proc address for the new context"); + + if (core_kd == NULL) + error ("no kernel core file"); + + addr = (CORE_ADDR) parse_and_eval_address (arg); + + if (!INKERNEL (addr)) + { + kp = kvm_getprocs (core_kd, KERN_PROC_PID, addr, &cnt); + if (!cnt) + error ("invalid pid"); + addr = (CORE_ADDR)kp->ki_paddr; + cur_proc = kp; + } + else + { + /* Update cur_proc. */ + pid_addr = addr + offsetof (struct proc, p_pid); + if (kvread (pid_addr, &pid)) + error ("cannot read pid ptr"); + cur_proc = kvm_getprocs (core_kd, KERN_PROC_PID, pid, &cnt); + if (!cnt) + error("invalid pid"); + } + + /* Find the first thread in the process. XXXKSE */ + addr += offsetof (struct proc, p_threads.tqh_first); + if (kvread (addr, &first_td)) + error ("cannot read thread ptr"); + + /* Read the PCB address in thread structure. */ + addr = first_td + offsetof (struct thread, td_pcb); + if (kvread (addr, &val)) + error("cannot read pcb ptr"); + + /* Read the PCB address in proc structure. */ + if (set_context ((CORE_ADDR) val)) + error ("invalid proc address"); +} +#else +int kernel_debugging = 0; +int kernel_writablecore = 0; + +CORE_ADDR +fbsd_kern_frame_saved_pc (struct frame_info *fi) +{ + return 0; +} +#endif + +void +_initialize_kcorelow (void) +{ +#if __FreeBSD_version >= 500032 + kcore_ops.to_shortname = "kcore"; + kcore_ops.to_longname = "Kernel core dump file"; + kcore_ops.to_doc = + "Use a core file as a target. Specify the filename of the core file."; + kcore_ops.to_open = kcore_open; + kcore_ops.to_close = kcore_close; + kcore_ops.to_attach = find_default_attach; + kcore_ops.to_detach = kcore_detach; + kcore_ops.to_fetch_registers = get_kcore_registers; + kcore_ops.to_xfer_memory = xfer_kmem; + kcore_ops.to_files_info = kcore_files_info; + kcore_ops.to_create_inferior = find_default_create_inferior; + kcore_ops.to_stratum = kcore_stratum; + kcore_ops.to_has_memory = 1; + kcore_ops.to_has_stack = 1; + kcore_ops.to_has_registers = 1; + kcore_ops.to_magic = OPS_MAGIC; + + add_target (&kcore_ops); + add_com ("proc", class_obscure, set_proc_cmd, "Set current process context"); +#endif +} diff --git a/devel/gdb6/files/nm-fbsd.h b/devel/gdb6/files/nm-fbsd.h new file mode 100644 index 0000000..b0d784f --- /dev/null +++ b/devel/gdb6/files/nm-fbsd.h @@ -0,0 +1,39 @@ +#ifndef CONFIG_NM_FBSD_H +#define CONFIG_NM_FBSD_H + +/* $FreeBSD$ */ + +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif + +extern int kernel_debugging; +extern int kernel_writablecore; + +CORE_ADDR fbsd_kern_frame_saved_pc(struct frame_info *frame); + +#if __FreeBSD_version >= 500032 +#define KGDB 1 +#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\ +" + +#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 +#endif /* CONFIG_NM_FBSD_H */ diff --git a/devel/gdb6/files/patch-Makefile.in b/devel/gdb6/files/patch-Makefile.in new file mode 100644 index 0000000..33ed469 --- /dev/null +++ b/devel/gdb6/files/patch-Makefile.in @@ -0,0 +1,11 @@ +--- gdb/Makefile.in.orig Fri Oct 17 14:44:26 2003 ++++ gdb/Makefile.in Thu Jan 15 11:41:06 2004 +@@ -119,4 +119,4 @@ +-READLINE_DIR = ../readline +-READLINE = $(READLINE_DIR)/libreadline.a +-READLINE_SRC = $(srcdir)/$(READLINE_DIR) +-READLINE_CFLAGS = -I$(READLINE_SRC)/.. ++#READLINE_DIR = ../readline ++READLINE = -lreadline ++#READLINE_SRC = $(srcdir)/$(READLINE_DIR) ++#READLINE_CFLAGS = -I$(READLINE_SRC)/.. diff --git a/devel/gdb6/files/patch-amd64-tdep.c b/devel/gdb6/files/patch-amd64-tdep.c new file mode 100644 index 0000000..88305cc --- /dev/null +++ b/devel/gdb6/files/patch-amd64-tdep.c @@ -0,0 +1,15 @@ +--- gdb/amd64-tdep.c.orig Fri Apr 9 16:24:05 2004 ++++ gdb/amd64-tdep.c Wed May 5 10:56:22 2004 +@@ -126,6 +126,12 @@ + #define AMD64_NUM_REGS \ + (sizeof (amd64_register_info) / sizeof (amd64_register_info[0])) + ++int ++amd64_num_regs(void) ++{ ++ return AMD64_NUM_REGS; ++} ++ + /* Return the name of register REGNUM. */ + + static const char * diff --git a/devel/gdb6/files/patch-amd64-tdep.h b/devel/gdb6/files/patch-amd64-tdep.h new file mode 100644 index 0000000..2ad0170 --- /dev/null +++ b/devel/gdb6/files/patch-amd64-tdep.h @@ -0,0 +1,16 @@ +--- gdb/amd64-tdep.h.orig Wed May 5 10:48:28 2004 ++++ gdb/amd64-tdep.h Wed May 5 11:02:33 2004 +@@ -59,6 +59,13 @@ + /* Number of general purpose registers. */ + #define AMD64_NUM_GREGS 24 + ++#define AMD64_NUM_FREGS 16 ++#define AMD64_NUM_XREGS 17 ++#define AMD64_NUM_REGS_TOTAL (AMD64_NUM_GREGS + AMD64_NUM_FREGS \ ++ + AMD64_NUM_XREGS) ++ ++extern int amd64_num_regs (void); ++ + extern void amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch); + + /* Fill register REGNUM in REGCACHE with the appropriate diff --git a/devel/gdb6/files/patch-config_alpha_nm-fbsd.h b/devel/gdb6/files/patch-config_alpha_nm-fbsd.h index d364e03c..2f7e710 100644 --- a/devel/gdb6/files/patch-config_alpha_nm-fbsd.h +++ b/devel/gdb6/files/patch-config_alpha_nm-fbsd.h @@ -1,11 +1,10 @@ ---- gdb/config/alpha/nm-fbsd.h Tue Mar 6 00:21:21 2001 -+++ gdb/config/alpha/nm-fbsd.h Sun Oct 13 12:23:51 2002 -@@ -22,6 +22,8 @@ - #ifndef NM_FBSD_H - #define NM_FBSD_H +--- gdb/config/alpha/nm-fbsd.h.orig Sat Mar 13 05:07:19 2004 ++++ gdb/config/alpha/nm-fbsd.h Sat Apr 10 00:49:21 2004 +@@ -25,6 +25,7 @@ + /* Get generic BSD native definitions. */ + #include "config/nm-bsd.h" +#include "config/nm-fbsd.h" -+ - /* Type of the third argument to the `ptrace' system call. */ - #define PTRACE_ARG3_TYPE caddr_t + /* The Alpha does not step over a breakpoint. */ + #define CANNOT_STEP_BREAKPOINT 1 diff --git a/devel/gdb6/files/patch-config_i386_fbsd.mh b/devel/gdb6/files/patch-config_i386_fbsd.mh index b9645a9..2215bd7 100644 --- a/devel/gdb6/files/patch-config_i386_fbsd.mh +++ b/devel/gdb6/files/patch-config_i386_fbsd.mh @@ -1,10 +1,10 @@ ---- gdb/config/i386/fbsd.mh Sat May 11 10:22:27 2002 -+++ gdb/config/i386/fbsd.mh Sun Oct 13 11:50:47 2002 -@@ -4,4 +4,6 @@ - +--- gdb/config/i386/fbsd.mh.orig Sun Feb 22 08:20:22 2004 ++++ gdb/config/i386/fbsd.mh Sat Apr 10 01:00:26 2004 +@@ -3,3 +3,7 @@ + i386-nat.o i386bsd-nat.o i386fbsd-nat.o gcore.o fbsd-proc.o NAT_FILE= nm-fbsd.h - # NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make. --NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o core-aout.o core-regset.o i386-nat.o i386bsd-nat.o i386fbsd-nat.o gcore.o fbsd-proc.o -+NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o core-aout.o core-regset.o i386-nat.o i386bsd-nat.o i386fbsd-nat.o gcore.o fbsd-proc.o kvm-fbsd.o freebsd-uthread.o + XM_FILE= xm-i386.h + ++# kgdb support ++NATDEPFILES+= kvm-fbsd.o freebsd-uthread.o +NAT_CLIBS= -lkvm diff --git a/devel/gdb6/files/patch-config_i386_fbsd64.mh b/devel/gdb6/files/patch-config_i386_fbsd64.mh new file mode 100644 index 0000000..ee00c31 --- /dev/null +++ b/devel/gdb6/files/patch-config_i386_fbsd64.mh @@ -0,0 +1,10 @@ +--- gdb/config/i386/fbsd64.mh.orig Sun Feb 22 08:20:22 2004 ++++ gdb/config/i386/fbsd64.mh Fri Apr 23 12:28:40 2004 +@@ -3,3 +3,7 @@ + amd64-nat.o amd64bsd-nat.o amd64fbsd-nat.o gcore.o fbsd-proc.o + NAT_FILE= nm-fbsd64.h + XM_FILE= xm-i386.h ++ ++# kgdb support ++NATDEPFILES+= kvm-fbsd.o freebsd-uthread.o ++NAT_CLIBS= -lkvm diff --git a/devel/gdb6/files/patch-config_i386_nm-fbsd.h b/devel/gdb6/files/patch-config_i386_nm-fbsd.h index efd2ce2..781f069 100644 --- a/devel/gdb6/files/patch-config_i386_nm-fbsd.h +++ b/devel/gdb6/files/patch-config_i386_nm-fbsd.h @@ -1,10 +1,12 @@ ---- gdb/config/i386/nm-fbsd.h Fri Jun 28 11:44:49 2002 -+++ gdb/config/i386/nm-fbsd.h Sun Oct 13 10:53:27 2002 -@@ -26,6 +26,7 @@ +--- gdb/config/i386/nm-fbsd.h.orig Fri Jun 28 11:44:49 2002 ++++ gdb/config/i386/nm-fbsd.h Sun Jan 18 20:50:33 2004 +@@ -26,6 +26,9 @@ #define I386_USE_GENERIC_WATCHPOINTS #endif ++/* Get generic FreeBSD native definitions. */ +#include "config/nm-fbsd.h" ++ #include "i386/nm-i386.h" #ifdef HAVE_SYS_PARAM_H diff --git a/devel/gdb6/files/patch-config_nm-fbsd.h b/devel/gdb6/files/patch-config_nm-fbsd.h deleted file mode 100644 index 9b6c033..0000000 --- a/devel/gdb6/files/patch-config_nm-fbsd.h +++ /dev/null @@ -1,39 +0,0 @@ ---- gdb/config/nm-fbsd.h Fri Jan 3 09:33:00 2003 -+++ gdb/config/nm-fbsd.h Fri Jan 3 09:36:00 2003 -@@ -0,0 +1,36 @@ -+#ifndef CONFIG_NM_FBSD_H -+#define CONFIG_NM_FBSD_H -+ -+#ifdef HAVE_SYS_PARAM_H -+#include <sys/param.h> -+#endif -+ -+extern int kernel_debugging; -+extern int kernel_writablecore; -+ -+CORE_ADDR fbsd_kern_frame_saved_pc(struct frame_info *frame); -+ -+#if __FreeBSD_version >= 500032 -+#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\ -+" -+ -+#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 -+#endif /* CONFIG_NM_FBSD_H */ diff --git a/devel/gdb6/files/patch-config_sparc_fbsd.mh b/devel/gdb6/files/patch-config_sparc_fbsd.mh index 1a23ca9..c9c6de6 100644 --- a/devel/gdb6/files/patch-config_sparc_fbsd.mh +++ b/devel/gdb6/files/patch-config_sparc_fbsd.mh @@ -1,13 +1,12 @@ ---- gdb/config/sparc/fbsd.mh.orig Wed Mar 13 03:20:24 2002 -+++ gdb/config/sparc/fbsd.mh Thu Oct 17 05:59:25 2002 -@@ -19,7 +19,7 @@ - # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - # Host: FreeBSD/sparc64 --NATDEPFILES= sparc-nat.o \ -- corelow.o fork-child.o infptrace.o inftarg.o \ -- solib.o solib-svr4.o solib-legacy.o -+NATDEPFILES= fork-child.o infptrace.o inftarg.o sparc64nbsd-nat.o \ -+ solib.o solib-svr4.o solib-legacy.o kvm-fbsd.o +--- gdb/config/sparc/fbsd.mh.orig Tue Mar 12 19:20:24 2002 ++++ gdb/config/sparc/fbsd.mh Tue Jan 20 08:28:50 2004 +@@ -23,3 +23,9 @@ + corelow.o fork-child.o infptrace.o inftarg.o \ + solib.o solib-svr4.o solib-legacy.o NAT_FILE= nm-fbsd.h ++ ++# kgdb support ++NATDEPFILES+= kvm-fbsd.o freebsd-uthread.o +NAT_CLIBS= -lkvm ++# /proc support ++NATDEPFILES+= fbsd-proc.o # sparc-linux-nat.o diff --git a/devel/gdb6/files/patch-config_sparc_fbsd.mt b/devel/gdb6/files/patch-config_sparc_fbsd.mt index 3147c4e..a76e2c5 100644 --- a/devel/gdb6/files/patch-config_sparc_fbsd.mt +++ b/devel/gdb6/files/patch-config_sparc_fbsd.mt @@ -1,10 +1,7 @@ ---- gdb/config/sparc/fbsd.mt.orig Wed Mar 13 03:20:24 2002 -+++ gdb/config/sparc/fbsd.mt Thu Oct 17 05:59:59 2002 -@@ -19,5 +19,6 @@ - # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - +--- gdb/config/sparc/fbsd.mt.orig Sat Jan 3 02:08:45 2004 ++++ gdb/config/sparc/fbsd.mt Sat Jan 24 20:10:22 2004 +@@ -1,3 +1,4 @@ # Target: FreeBSD/sparc64 --TDEPFILES= sparc-tdep.o solib.o solib-svr4.o solib-legacy.o -+TDEPFILES= sparc-tdep.o sparcnbsd-tdep.o nbsd-tdep.o corelow.o solib.o \ -+ solib-svr4.o solib-legacy.o + TDEPFILES= sparc-tdep.o sparc64-tdep.o sparc64fbsd-tdep.o corelow.o ++###TDEPFILES+= sparcnbsd-tdep.o nbsd-tdep.o solib.o solib-svr4.o solib-legacy.o TM_FILE= tm-fbsd.h diff --git a/devel/gdb6/files/patch-config_sparc_nm-fbsd.h b/devel/gdb6/files/patch-config_sparc_nm-fbsd.h index 4ab0b5a..f5e005f 100644 --- a/devel/gdb6/files/patch-config_sparc_nm-fbsd.h +++ b/devel/gdb6/files/patch-config_sparc_nm-fbsd.h @@ -1,72 +1,33 @@ ---- gdb/config/sparc/nm-fbsd.h.orig Fri Mar 1 18:35:24 2002 -+++ gdb/config/sparc/nm-fbsd.h Tue Oct 22 16:33:14 2002 -@@ -32,36 +32,45 @@ - #define ATTACH_DETACH - +--- gdb/config/sparc/nm-fbsd.h.orig Sat Mar 13 05:07:20 2004 ++++ gdb/config/sparc/nm-fbsd.h Sat Apr 10 01:06:19 2004 +@@ -24,9 +24,30 @@ --/* Shared library support. */ -+#include "regcache.h" -+ -+/* Get generic FreeBSD native definitions. */ -+ + /* Get generic BSD native definitions. */ + #include "config/nm-bsd.h" ++/* Get generic FreeBSD native definitions. */ +#include "config/nm-fbsd.h" -+ -+/* Shared library support. */ - #define SVR4_SHARED_LIBS + /* Shared library support. */ - #include "solib.h" /* Support for shared libraries. */ - #include "elf/common.h" /* Additional ELF shared library info. */ - --/* Make things match up with what is expected in sparc-nat.c. */ -+/* Before storing, we need to read all the registers. */ + #include "solib.h" + -+#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES) ++/* Override child_pid_to_exec_file in 'inftarg.c'. */ ++#define CHILD_PID_TO_EXEC_FILE + -+#define REG32_OFFSET_GLOBAL (0) -+#define REG32_OFFSET_OUT (32) -+#define REG32_OFFSET_NPC (96) -+#define REG32_OFFSET_PC (100) -+#define REG32_OFFSET_PSR (104) -+#define REG32_OFFSET_Y (112) -+#define REG32_SIZE (128) -+#define FPREG32_SIZE (136) ++/* FreeBSD has a /proc. */ ++#define USE_PROC_FS + -+#define REG64_OFFSET_GLOBAL (0) -+#define REG64_OFFSET_OUT (64) -+#define REG64_OFFSET_NPC (192) -+#define REG64_OFFSET_PC (200) -+#define REG64_OFFSET_TSTATE (208) -+#define REG64_OFFSET_Y (224) -+#define REG64_SIZE (256) -+#define FPREG64_SIZE (272) ++/* DEO:XXX where did the rest of this file go vs 6.0.0.90 ?? */ + -+#define JB32_OFFSET_PC REG32_OFFSET_PC -+#define JB64_OFFSET_PC REG64_OFFSET_PC - --#define PTRACE_GETREGS PT_GETREGS --#define PTRACE_SETREGS PT_SETREGS --#define PTRACE_GETFPREGS PT_GETFPREGS --#define PTRACE_SETFPREGS PT_SETFPREGS -- --#define GDB_GREGSET_T struct reg --#define GDB_FPREGSET_T struct fpreg -- --#define regs trapframe --#define r_g1 tf_global[1] --#define r_ps tf_tstate --#define r_pc tf_tpc --#define r_npc tf_tnpc --#define r_y tf_y -- --#define FPU_FSR_TYPE unsigned long --#define fp_status fpreg /* our reg.h */ --#define fpu fpreg /* our reg.h */ --#define fpu_regs fr_regs /* one field of fpu_fr on Solaris */ --#define fpu_fr fr_regs /* a union w/in struct fpu on Solaris */ --#define fpu_fsr fr_fsr --#define Fpu_fsr fr_fsr -+#define reg64 reg -+#define fpreg64 fpreg ++/* Solaris compatability. */ ++#define R_PC r_pc ++#define R_nPC r_npc ++#define R_Y r_y ++#define R_I7 /* ?? */ ++#define pr_fr fpu_fr ++#define pr_fsr fpu_fsr ++#define regp /* ?? */ ++#if 0 ++#endif - #endif /* NM_FBSD_H */ + #endif /* nm-fbsd.h */ diff --git a/devel/gdb6/files/patch-config_sparc_tm-fbsd.h b/devel/gdb6/files/patch-config_sparc_tm-fbsd.h index 4e15435..ccca904 100644 --- a/devel/gdb6/files/patch-config_sparc_tm-fbsd.h +++ b/devel/gdb6/files/patch-config_sparc_tm-fbsd.h @@ -1,17 +1,12 @@ ---- gdb/config/sparc/tm-fbsd.h.orig Fri Mar 1 18:35:24 2002 -+++ gdb/config/sparc/tm-fbsd.h Thu Oct 17 06:01:10 2002 -@@ -22,13 +22,7 @@ - #define TM_FBSD_H +--- gdb/config/sparc/tm-fbsd.h.orig Sat Jan 24 20:06:31 2004 ++++ gdb/config/sparc/tm-fbsd.h Sat Jan 24 20:07:02 2004 +@@ -24,4 +24,9 @@ - #define SVR4_SHARED_LIBS -+#include "sparc/tm-sp64.h" /* sets GDB_MULTI_ARCH */ - #include "solib.h" /* Support for shared libraries. */ --#include "sparc/tm-sp64.h" -- --/* Number of traps that happen between exec'ing the shell to run an -- inferior, and when we finally get to the inferior code. The -- default is right for FreeBSD. */ -- --#undef START_INFERIOR_TRAPS_EXPECTED + #define GDB_MULTI_ARCH GDB_MULTI_ARCH_TM - #endif /* TM_FBSD_H */ ++#if 0 ++#define SVR4_SHARED_LIBS ++#include "sparc/tm-sp64.h" /* sets GDB_MULTI_ARCH */ ++#endif ++ + #endif /* tm-fbsd.h */ diff --git a/devel/gdb6/files/patch-defs.h b/devel/gdb6/files/patch-defs.h deleted file mode 100644 index be60dcf..0000000 --- a/devel/gdb6/files/patch-defs.h +++ /dev/null @@ -1,20 +0,0 @@ ---- gdb/defs.h Thu Aug 1 10:18:32 2002 -+++ gdb/defs.h Sun Oct 13 10:44:10 2002 -@@ -39,8 +39,6 @@ - #include <unistd.h> - #endif - --#include "gdb_locale.h" -- - /* For ``enum target_signal''. */ - #include "gdb/signals.h" - -@@ -57,6 +55,8 @@ - here and in all subsequent file inclusions. */ - - #include "ansidecl.h" -+ -+#include "gdb_locale.h" - - #include <stdarg.h> /* for va_list */ - diff --git a/devel/gdb6/files/patch-freebsd-uthread.c b/devel/gdb6/files/patch-freebsd-uthread.c deleted file mode 100644 index 9d3fd54..0000000 --- a/devel/gdb6/files/patch-freebsd-uthread.c +++ /dev/null @@ -1,937 +0,0 @@ ---- gdb/freebsd-uthread.c Wed Dec 31 16:00:00 1969 -+++ gdb/freebsd-uthread.c Sun Oct 13 13:10:51 2002 -@@ -0,0 +1,934 @@ -+/* $FreeBSD$ */ -+/* Low level interface for debugging FreeBSD user threads for GDB, the GNU debugger. -+ Copyright 1996, 1999 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. */ -+ -+/* This module implements a sort of half target that sits between the -+ machine-independent parts of GDB and the ptrace interface (infptrace.c) to -+ provide access to the FreeBSD user-mode thread implementation. -+ -+ FreeBSD threads are true user-mode threads, which are invoked via -+ the pthread_* interfaces. These are mostly implemented in -+ user-space, with all thread context kept in various structures that -+ live in the user's heap. For the most part, the kernel has no -+ knowlege of these threads. -+ -+ Based largely on hpux-thread.c -+ -+ */ -+ -+ -+#include "defs.h" -+#include <sys/queue.h> -+#include <signal.h> -+#include <setjmp.h> -+#include <string.h> -+#include "gdbthread.h" -+#include "target.h" -+#include "inferior.h" -+#include <fcntl.h> -+#include <ucontext.h> -+#include <unistd.h> -+#include <sys/stat.h> -+#include "gdbcore.h" -+#include "regcache.h" -+ -+extern int child_suppress_run; -+extern struct target_ops child_ops; /* target vector for inftarg.c */ -+ -+extern void _initialize_freebsd_uthread PARAMS ((void)); -+ -+/* Set to true while we are part-way through attaching */ -+static int freebsd_uthread_attaching; -+ -+static int freebsd_uthread_active = 0; -+static CORE_ADDR P_thread_list; -+static CORE_ADDR P_thread_run; -+ -+/* Pointer to the next function on the objfile event chain. */ -+static void (*target_new_objfile_chain) (struct objfile *objfile); -+ -+static void freebsd_uthread_resume PARAMS ((ptid_t pid, int step, -+ enum target_signal signo)); -+ -+static void init_freebsd_uthread_ops PARAMS ((void)); -+ -+static struct target_ops freebsd_uthread_ops; -+ -+static ptid_t find_active_ptid PARAMS ((void)); -+ -+struct cached_pthread { -+ u_int64_t uniqueid; -+ int state; -+ CORE_ADDR name; -+ union { -+ ucontext_t uc; -+ jmp_buf jb; -+ } ctx; -+}; -+ -+static ptid_t cached_ptid; -+static struct cached_pthread cached_pthread; -+static CORE_ADDR cached_pthread_addr; -+ -+LIST_HEAD(idmaplist, idmap); -+ -+struct idmap { -+ LIST_ENTRY(idmap) link; -+ u_int64_t uniqueid; -+ int tid; -+}; -+ -+#define MAPHASH_SIZE 257 -+#define TID_MIN 1 -+#define TID_MAX 16383 -+ -+static int tid_to_hash[TID_MAX + 1]; /* set to map_hash index */ -+static struct idmaplist map_hash[MAPHASH_SIZE]; -+static int next_free_tid = TID_MIN; /* first available tid */ -+static int last_free_tid = TID_MIN; /* first unavailable */ -+ -+static CORE_ADDR P_thread_next_offset; -+static CORE_ADDR P_thread_uniqueid_offset; -+static CORE_ADDR P_thread_state_offset; -+static CORE_ADDR P_thread_name_offset; -+static CORE_ADDR P_thread_ctx_offset; -+static CORE_ADDR P_thread_PS_RUNNING_value; -+static CORE_ADDR P_thread_PS_DEAD_value; -+ -+static int next_offset; -+static int uniqueid_offset; -+static int state_offset; -+static int name_offset; -+static int ctx_offset; -+static int PS_RUNNING_value; -+static int PS_DEAD_value; -+ -+#define UNIQUEID_HASH(id) (id % MAPHASH_SIZE) -+#define TID_ADD1(tid) (((tid) + 1) == TID_MAX + 1 \ -+ ? TID_MIN : (tid) + 1) -+#define IS_TID_FREE(tid) (tid_to_hash[tid] == -1) -+ -+static int -+get_new_tid(int h) -+{ -+ int tid = next_free_tid; -+ -+ tid_to_hash[tid] = h; -+ next_free_tid = TID_ADD1(next_free_tid); -+ if (next_free_tid == last_free_tid) -+ { -+ int i; -+ -+ for (i = last_free_tid; TID_ADD1(i) != last_free_tid; i = TID_ADD1(i)) -+ if (IS_TID_FREE(i)) -+ break; -+ if (TID_ADD1(i) == last_free_tid) -+ { -+ error("too many threads"); -+ return 0; -+ } -+ next_free_tid = i; -+ for (i = TID_ADD1(i); IS_TID_FREE(i); i = TID_ADD1(i)) -+ ; -+ last_free_tid = i; -+ } -+ -+ return tid; -+} -+ -+static ptid_t -+find_ptid(u_int64_t uniqueid) -+{ -+ int h = UNIQUEID_HASH(uniqueid); -+ struct idmap *im; -+ -+ LIST_FOREACH(im, &map_hash[h], link) -+ if (im->uniqueid == uniqueid) -+ return MERGEPID(PIDGET(inferior_ptid), im->tid); -+ -+ im = xmalloc(sizeof(struct idmap)); -+ im->uniqueid = uniqueid; -+ im->tid = get_new_tid(h); -+ LIST_INSERT_HEAD(&map_hash[h], im, link); -+ -+ return MERGEPID(PIDGET(inferior_ptid), im->tid); -+} -+ -+static void -+free_ptid(ptid_t ptid) -+{ -+ int tid = TIDGET(ptid); -+ int h = tid_to_hash[tid]; -+ struct idmap *im; -+ -+ if (!tid) return; -+ -+ LIST_FOREACH(im, &map_hash[h], link) -+ if (im->tid == tid) -+ break; -+ -+ if (!im) return; -+ -+ LIST_REMOVE(im, link); -+ tid_to_hash[tid] = -1; -+ free(im); -+} -+ -+#define READ_OFFSET(field) read_memory(P_thread_##field##_offset, \ -+ (char *) &field##_offset, \ -+ sizeof(field##_offset)) -+ -+#define READ_VALUE(name) read_memory(P_thread_##name##_value, \ -+ (char *) &name##_value, \ -+ sizeof(name##_value)) -+ -+static void -+read_thread_offsets (void) -+{ -+ READ_OFFSET(next); -+ READ_OFFSET(uniqueid); -+ READ_OFFSET(state); -+ READ_OFFSET(name); -+ READ_OFFSET(ctx); -+ -+ READ_VALUE(PS_RUNNING); -+ READ_VALUE(PS_DEAD); -+} -+ -+#define READ_FIELD(ptr, T, field, result) \ -+ read_memory ((ptr) + field##_offset, (char *) &(result), sizeof result) -+ -+static u_int64_t -+read_pthread_uniqueid (CORE_ADDR ptr) -+{ -+ u_int64_t uniqueid; -+ READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid); -+ return uniqueid; -+} -+ -+static CORE_ADDR -+read_pthread_next (CORE_ADDR ptr) -+{ -+ CORE_ADDR next; -+ READ_FIELD(ptr, CORE_ADDR, next, next); -+ return next; -+} -+ -+static void -+read_cached_pthread (CORE_ADDR ptr, struct cached_pthread *cache) -+{ -+ READ_FIELD(ptr, u_int64_t, uniqueid, cache->uniqueid); -+ READ_FIELD(ptr, int, state, cache->state); -+ READ_FIELD(ptr, CORE_ADDR, name, cache->name); -+ READ_FIELD(ptr, ucontext_t, ctx, cache->ctx); -+} -+ -+static ptid_t -+find_active_ptid (void) -+{ -+ CORE_ADDR ptr; -+ -+ read_memory ((CORE_ADDR)P_thread_run, -+ (char *)&ptr, -+ sizeof ptr); -+ -+ return find_ptid(read_pthread_uniqueid(ptr)); -+} -+ -+static CORE_ADDR find_pthread_addr PARAMS ((ptid_t ptid)); -+static struct cached_pthread * find_pthread PARAMS ((ptid_t ptid)); -+ -+static CORE_ADDR -+find_pthread_addr (ptid_t ptid) -+{ -+ CORE_ADDR ptr; -+ -+ if (ptid_equal(ptid, cached_ptid)) -+ return cached_pthread_addr; -+ -+ read_memory ((CORE_ADDR)P_thread_list, -+ (char *)&ptr, -+ sizeof ptr); -+ -+ while (ptr != 0) -+ { -+ if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid)) -+ { -+ cached_ptid = ptid; -+ cached_pthread_addr = ptr; -+ read_cached_pthread(ptr, &cached_pthread); -+ return ptr; -+ } -+ ptr = read_pthread_next(ptr); -+ } -+ -+ return NULL; -+} -+ -+static struct cached_pthread * -+find_pthread (ptid_t ptid) -+{ -+ CORE_ADDR ptr; -+ -+ if (ptid_equal(ptid, cached_ptid)) -+ return &cached_pthread; -+ -+ read_memory ((CORE_ADDR)P_thread_list, -+ (char *)&ptr, -+ sizeof ptr); -+ -+ while (ptr != 0) -+ { -+ if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid)) -+ { -+ cached_ptid = ptid; -+ cached_pthread_addr = ptr; -+ read_cached_pthread(ptr, &cached_pthread); -+ return &cached_pthread; -+ } -+ ptr = read_pthread_next(ptr); -+ } -+ -+#if 0 -+ error ("Can't find pthread %d,%d", PIDGET(ptid), TIDGET(ptid)); -+#endif -+ return NULL; -+} -+ -+ -+/* Most target vector functions from here on actually just pass through to -+ inftarg.c, as they don't need to do anything specific for threads. */ -+ -+/* ARGSUSED */ -+static void -+freebsd_uthread_open (char *arg, int from_tty) -+{ -+ child_ops.to_open (arg, from_tty); -+} -+ -+/* Attach to process PID, then initialize for debugging it -+ and wait for the trace-trap that results from attaching. */ -+ -+static void -+freebsd_uthread_attach (char *args, int from_tty) -+{ -+ child_ops.to_attach (args, from_tty); -+ push_target (&freebsd_uthread_ops); -+ freebsd_uthread_attaching = 1; -+} -+ -+/* After an attach, see if the target is threaded */ -+ -+static void -+freebsd_uthread_post_attach (int pid) -+{ -+ if (freebsd_uthread_active) -+ { -+ read_thread_offsets (); -+ inferior_ptid = find_active_ptid (); -+ add_thread (inferior_ptid); -+ } -+ else -+ { -+ unpush_target (&freebsd_uthread_ops); -+ push_target (&child_ops); -+ } -+ -+ freebsd_uthread_attaching = 0; -+} -+ -+/* Take a program previously attached to and detaches it. -+ The program resumes execution and will no longer stop -+ on signals, etc. We'd better not have left any breakpoints -+ in the program or it'll die when it hits one. For this -+ to work, it may be necessary for the process to have been -+ previously attached. It *might* work if the program was -+ started via the normal ptrace (PTRACE_TRACEME). */ -+ -+static void -+freebsd_uthread_detach (char *args, int from_tty) -+{ -+ child_ops.to_detach (args, from_tty); -+} -+ -+/* Resume execution of process PID. If STEP is nozero, then -+ just single step it. If SIGNAL is nonzero, restart it with that -+ signal activated. We may have to convert pid from a thread-id to an LWP id -+ for procfs. */ -+ -+static void -+freebsd_uthread_resume (ptid_t ptid, int step, enum target_signal signo) -+{ -+ if (freebsd_uthread_attaching) -+ { -+ child_ops.to_resume (ptid, step, signo); -+ return; -+ } -+ -+ child_ops.to_resume (ptid, step, signo); -+ cached_ptid = MERGEPID(0, 0); -+} -+ -+/* Wait for any threads to stop. We may have to convert PID from a thread id -+ to a LWP id, and vice versa on the way out. */ -+ -+static ptid_t -+freebsd_uthread_wait (ptid_t ptid, struct target_waitstatus *ourstatus) -+{ -+ ptid_t rtnval; -+ -+ if (freebsd_uthread_attaching) -+ { -+ return child_ops.to_wait (ptid, ourstatus); -+ } -+ -+ rtnval = child_ops.to_wait (ptid, ourstatus); -+ -+ if (PIDGET(rtnval) >= 0) -+ { -+ rtnval = find_active_ptid (); -+ if (!in_thread_list (rtnval)) -+ add_thread (rtnval); -+ } -+ -+ return rtnval; -+} -+ -+/* XXX: this needs to be selected by target, not [build] host */ -+#ifdef __i386__ -+ -+#include "i386-tdep.h" -+ -+static char sigmap[I386_SSE_NUM_REGS] = /* map reg to sigcontext */ -+{ -+ 12, /* eax */ -+ 11, /* ecx */ -+ 10, /* edx */ -+ 9, /* ebx */ -+ 8, /* esp */ -+ 7, /* ebp */ -+ 6, /* esi */ -+ 5, /* edi */ -+ 15, /* eip */ -+ 17, /* eflags */ -+ 16, /* cs */ -+ 19, /* ss */ -+ 4, /* ds */ -+ 3, /* es */ -+ 2, /* fs */ -+ 1, /* gs */ -+ -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ -+ -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ -+ -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ -+ -1, /* mxcsr */ -+}; -+ -+static char jmpmap[I386_SSE_NUM_REGS] = /* map reg to jmp_buf */ -+{ -+ 6, /* eax */ -+ -1, /* ecx */ -+ -1, /* edx */ -+ 1, /* ebx */ -+ 2, /* esp */ -+ 3, /* ebp */ -+ 4, /* esi */ -+ 5, /* edi */ -+ 0, /* eip */ -+ -1, /* eflags */ -+ -1, /* cs */ -+ -1, /* ss */ -+ -1, /* ds */ -+ -1, /* es */ -+ -1, /* fs */ -+ -1, /* gs */ -+ -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ -+ -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ -+ -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ -+ -1, /* mxcsr */ -+}; -+ -+#endif -+ -+#ifdef __alpha__ -+ -+#include "alpha-tdep.h" -+ -+static char sigmap[ALPHA_NUM_REGS] = /* map reg to sigcontext */ -+{ -+ 1, 2, 3, 4, 5, 6, 7, 8, /* v0 - t6 */ -+ 9, 10, 11, 12, 13, 14, 15, 16, /* t7 - fp */ -+ 17, 18, 19, 20, 21, 22, 23, 24, /* a0 - t9 */ -+ 25, 26, 27, 28, 29, 30, 31, 32, /* t10 - zero */ -+ 38, 39, 40, 41, 42, 43, 44, 45, /* f0 - f7 */ -+ 46, 47, 48, 49, 50, 51, 52, 53, /* f8 - f15 */ -+ 54, 55, 56, 57, 58, 59, 60, 61, /* f16 - f23 */ -+ 62, 63, 64, 65, 66, 67, 68, 69, /* f24 - f31 */ -+ 33, -1 /* pc, vfp */ -+}; -+static char jmpmap[ALPHA_NUM_REGS] = { -+ 4, 5, 6, 7, 8, 9, 10, 11, /* v0 - t6 */ -+ 12, 13, 14, 15, 16, 17, 18, 19, /* t7 - fp */ -+ 20, 21, 22, 23, 24, 25, 26, 27, /* a0 - t9 */ -+ 28, 29, 30, 31, 32, 33, 34, 35, /* t10 - zero */ -+ 37, 38, 39, 40, 41, 42, 43, 44, /* f0 - f7 */ -+ 45, 46, 47, 48, 49, 50, 51, 52, /* f8 - f15 */ -+ 53, 54, 55, 56, 57, 58, 59, 60, /* f16 - f23 */ -+ 61, 62, 63, 64, 65, 66, 67, 68, /* f24 - f31 */ -+ 2, -1, /* pc, vfp */ -+}; -+ -+#endif -+ -+#ifdef __sparc64__ -+ -+static char sigmap[125] = /* map reg to sigcontext */ -+{ -+ -1 -+}; -+static char jmpmap[125] = { -+ -1 -+}; -+ -+#endif -+ -+static void -+freebsd_uthread_fetch_registers (int regno) -+{ -+ struct cached_pthread *thread; -+ int active; -+ int first_regno, last_regno; -+ register_t *regbase; -+ char *regmap; -+ -+ if (freebsd_uthread_attaching || TIDGET(inferior_ptid) == 0) -+ { -+ child_ops.to_fetch_registers (regno); -+ return; -+ } -+ -+ thread = find_pthread (inferior_ptid); -+ active = (ptid_equal(inferior_ptid, find_active_ptid())); -+ -+ if (active) -+ { -+ child_ops.to_fetch_registers (regno); -+ return; -+ } -+ -+ if (regno == -1) -+ { -+ first_regno = 0; -+ last_regno = NUM_REGS - 1; -+ } -+ else -+ { -+ first_regno = regno; -+ last_regno = regno; -+ } -+ -+ regbase = (register_t*) &thread->ctx.jb[0]; -+ regmap = jmpmap; -+ -+ for (regno = first_regno; regno <= last_regno; regno++) -+ { -+ if (regmap[regno] == -1) -+ child_ops.to_fetch_registers (regno); -+ else -+ if (thread) -+ supply_register (regno, (char*) ®base[regmap[regno]]); -+ else -+ supply_register (regno, NULL); -+ } -+} -+ -+static void -+freebsd_uthread_store_registers (int regno) -+{ -+ struct cached_pthread *thread; -+ CORE_ADDR ptr; -+ int first_regno, last_regno; -+ u_int32_t *regbase; -+ char *regmap; -+ -+ if (freebsd_uthread_attaching) -+ { -+ child_ops.to_store_registers (regno); -+ return; -+ } -+ -+ thread = find_pthread (inferior_ptid); -+ -+ if (thread->state == PS_RUNNING_value) -+ { -+ child_ops.to_store_registers (regno); -+ return; -+ } -+ -+ if (regno == -1) -+ { -+ first_regno = 0; -+ last_regno = NUM_REGS - 1; -+ } -+ else -+ { -+ first_regno = regno; -+ last_regno = regno; -+ } -+ -+ regbase = (u_int32_t*) &thread->ctx.jb[0]; -+ regmap = jmpmap; -+ -+ ptr = find_pthread_addr (inferior_ptid); -+ for (regno = first_regno; regno <= last_regno; regno++) -+ { -+ if (regmap[regno] == -1) -+ child_ops.to_store_registers (regno); -+ else -+ { -+ u_int32_t *reg = ®base[regmap[regno]]; -+ int off; -+ -+ /* Hang onto cached value */ -+ memcpy(reg, registers + REGISTER_BYTE (regno), -+ REGISTER_RAW_SIZE (regno)); -+ -+ /* And push out to inferior */ -+ off = (char *) reg - (char *) thread; -+ write_memory (ptr + off, -+ registers + REGISTER_BYTE (regno), -+ REGISTER_RAW_SIZE (regno)); -+ } -+ } -+} -+ -+/* Get ready to modify the registers array. On machines which store -+ individual registers, this doesn't need to do anything. On machines -+ which store all the registers in one fell swoop, this makes sure -+ that registers contains all the registers from the program being -+ debugged. */ -+ -+static void -+freebsd_uthread_prepare_to_store (void) -+{ -+ child_ops.to_prepare_to_store (); -+} -+ -+static int -+freebsd_uthread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, -+ int dowrite, struct mem_attrib *attrib, -+ struct target_ops *target) -+{ -+ return child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, -+ attrib, target); -+} -+ -+/* Print status information about what we're accessing. */ -+ -+static void -+freebsd_uthread_files_info (struct target_ops *ignore) -+{ -+ child_ops.to_files_info (ignore); -+} -+ -+static void -+freebsd_uthread_kill_inferior (void) -+{ -+ child_ops.to_kill (); -+} -+ -+static void -+freebsd_uthread_notice_signals (ptid_t ptid) -+{ -+ child_ops.to_notice_signals (ptid); -+} -+ -+/* Fork an inferior process, and start debugging it with /proc. */ -+ -+static void -+freebsd_uthread_create_inferior (char *exec_file, char *allargs, char **env) -+{ -+ child_ops.to_create_inferior (exec_file, allargs, env); -+ -+ if (PIDGET(inferior_ptid) && freebsd_uthread_active) -+ { -+ read_thread_offsets (); -+ push_target (&freebsd_uthread_ops); -+ inferior_ptid = find_active_ptid (); -+ add_thread (inferior_ptid); -+ } -+} -+ -+/* This routine is called to find out if the inferior is using threads. -+ We check for the _thread_run and _thread_list globals. */ -+ -+void -+freebsd_uthread_new_objfile (struct objfile *objfile) -+{ -+ struct minimal_symbol *ms; -+ -+ if (!objfile) -+ { -+ freebsd_uthread_active = 0; -+ return; -+ } -+ -+ ms = lookup_minimal_symbol ("_thread_run", NULL, objfile); -+ -+ if (!ms) -+ return; -+ -+ P_thread_run = SYMBOL_VALUE_ADDRESS (ms); -+ -+ ms = lookup_minimal_symbol ("_thread_list", NULL, objfile); -+ -+ if (!ms) -+ return; -+ -+ P_thread_list = SYMBOL_VALUE_ADDRESS (ms); -+ -+#define OFFSET_SYM(field) "_thread_" #field "_offset" -+#define LOOKUP_OFFSET(field) \ -+ do { \ -+ ms = lookup_minimal_symbol (OFFSET_SYM(field), NULL, objfile); \ -+ if (!ms) \ -+ return; \ -+ P_thread_##field##_offset = SYMBOL_VALUE_ADDRESS (ms); \ -+ } while (0); -+ -+#define VALUE_SYM(name) "_thread_" #name "_value" -+#define LOOKUP_VALUE(name) \ -+ do { \ -+ ms = lookup_minimal_symbol (VALUE_SYM(name), NULL, objfile); \ -+ if (!ms) \ -+ return; \ -+ P_thread_##name##_value = SYMBOL_VALUE_ADDRESS (ms); \ -+ } while (0); -+ -+ LOOKUP_OFFSET(next); -+ LOOKUP_OFFSET(uniqueid); -+ LOOKUP_OFFSET(state); -+ LOOKUP_OFFSET(name); -+ LOOKUP_OFFSET(ctx); -+ -+ LOOKUP_VALUE(PS_RUNNING); -+ LOOKUP_VALUE(PS_DEAD); -+ -+ freebsd_uthread_active = 1; -+} -+ -+/* Clean up after the inferior dies. */ -+ -+static void -+freebsd_uthread_mourn_inferior () -+{ -+ child_ops.to_mourn_inferior (); -+ unpush_target (&freebsd_uthread_ops); -+} -+ -+/* Mark our target-struct as eligible for stray "run" and "attach" commands. */ -+ -+static int -+freebsd_uthread_can_run () -+{ -+ return child_suppress_run; -+} -+ -+static int -+freebsd_uthread_thread_alive (ptid_t ptid) -+{ -+ struct cached_pthread *thread; -+ int ret = 0; -+ -+ if (freebsd_uthread_attaching) -+ return 1; -+ -+ /* -+ * We can get called from child_ops.to_wait() which passes the underlying -+ * pid (without a thread number). -+ */ -+ if (TIDGET(ptid) == 0) -+ return 1; -+ -+ if (find_pthread_addr (ptid) != 0) -+ { -+ thread = find_pthread (ptid); -+ ret = (thread->state != PS_DEAD_value); -+ } -+ -+ if (!ret) -+ free_ptid(ptid); -+ -+ return ret; -+} -+ -+static void -+freebsd_uthread_stop (void) -+{ -+ child_ops.to_stop (); -+} -+ -+static void -+freebsd_uthread_find_new_threads (void) -+{ -+ CORE_ADDR ptr; -+ int state; -+ u_int64_t uniqueid; -+ -+ read_memory ((CORE_ADDR)P_thread_list, -+ (char *)&ptr, -+ sizeof ptr); -+ -+ while (ptr != 0) -+ { -+ READ_FIELD(ptr, int, state, state); -+ READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid); -+ if (state != PS_DEAD_value && -+ !in_thread_list (find_ptid(uniqueid))) -+ add_thread (find_ptid(uniqueid)); -+ ptr = read_pthread_next(ptr); -+ } -+} -+ -+/* MUST MATCH enum pthread_state */ -+static const char *statenames[] = { -+ "RUNNING", -+ "SIGTHREAD", -+ "MUTEX_WAIT", -+ "COND_WAIT", -+ "FDLR_WAIT", -+ "FDLW_WAIT", -+ "FDR_WAIT", -+ "FDW_WAIT", -+ "POLL_WAIT", -+ "FILE_WAIT", -+ "SELECT_WAIT", -+ "SLEEP_WAIT", -+ "WAIT_WAIT", -+ "SIGSUSPEND", -+ "SIGWAIT", -+ "SPINBLOCK", -+ "JOIN", -+ "SUSPENDED", -+ "DEAD", -+ "DEADLOCK", -+}; -+ -+#if 0 -+ -+static int -+freebsd_uthread_get_thread_info (ref, selection, info) -+ gdb_threadref *ref; -+ int selection; -+ struct gdb_ext_thread_info *info; -+{ -+ int pid = *ref; -+ struct cached_pthread *thread = find_pthread (pid); -+ struct cleanup *old_chain; -+ -+ old_chain = save_inferior_pid (); -+ inferior_pid = main_pid; -+ -+ memset(&info->threadid, 0, OPAQUETHREADBYTES); -+ -+ memcpy(&info->threadid, ref, sizeof *ref); -+ info->active = thread->state == PS_RUNNING_value; -+ strcpy(info->display, statenames[thread->state]); -+ if (thread->name) -+ read_memory ((CORE_ADDR) thread->name, info->shortname, 32); -+ else -+ strcpy(info->shortname, ""); -+ -+ do_cleanups (old_chain); -+ return (0); -+} -+ -+#endif -+ -+char * -+freebsd_uthread_pid_to_str (ptid_t ptid) -+{ -+ static char buf[30]; -+ -+ if (STREQ (current_target.to_shortname, "freebsd-uthreads")) -+ sprintf (buf, "Process %d, Thread %ld", -+ PIDGET(ptid), TIDGET(ptid)); -+ else -+ sprintf (buf, "Process %d", PIDGET(ptid)); -+ -+ return buf; -+} -+ -+ -+static void -+init_freebsd_uthread_ops () -+{ -+ freebsd_uthread_ops.to_shortname = "freebsd-uthreads"; -+ freebsd_uthread_ops.to_longname = "FreeBSD uthreads"; -+ freebsd_uthread_ops.to_doc = "FreeBSD user threads support."; -+ freebsd_uthread_ops.to_open = freebsd_uthread_open; -+ freebsd_uthread_ops.to_attach = freebsd_uthread_attach; -+ freebsd_uthread_ops.to_post_attach = freebsd_uthread_post_attach; -+ freebsd_uthread_ops.to_detach = freebsd_uthread_detach; -+ freebsd_uthread_ops.to_resume = freebsd_uthread_resume; -+ freebsd_uthread_ops.to_wait = freebsd_uthread_wait; -+ freebsd_uthread_ops.to_fetch_registers = freebsd_uthread_fetch_registers; -+ freebsd_uthread_ops.to_store_registers = freebsd_uthread_store_registers; -+ freebsd_uthread_ops.to_prepare_to_store = freebsd_uthread_prepare_to_store; -+ freebsd_uthread_ops.to_xfer_memory = freebsd_uthread_xfer_memory; -+ freebsd_uthread_ops.to_files_info = freebsd_uthread_files_info; -+ freebsd_uthread_ops.to_insert_breakpoint = memory_insert_breakpoint; -+ freebsd_uthread_ops.to_remove_breakpoint = memory_remove_breakpoint; -+ freebsd_uthread_ops.to_terminal_init = terminal_init_inferior; -+ freebsd_uthread_ops.to_terminal_inferior = terminal_inferior; -+ freebsd_uthread_ops.to_terminal_ours_for_output = terminal_ours_for_output; -+ freebsd_uthread_ops.to_terminal_ours = terminal_ours; -+ freebsd_uthread_ops.to_terminal_info = child_terminal_info; -+ freebsd_uthread_ops.to_kill = freebsd_uthread_kill_inferior; -+ freebsd_uthread_ops.to_create_inferior = freebsd_uthread_create_inferior; -+ freebsd_uthread_ops.to_mourn_inferior = freebsd_uthread_mourn_inferior; -+ freebsd_uthread_ops.to_can_run = freebsd_uthread_can_run; -+ freebsd_uthread_ops.to_notice_signals = freebsd_uthread_notice_signals; -+ freebsd_uthread_ops.to_thread_alive = freebsd_uthread_thread_alive; -+ freebsd_uthread_ops.to_stop = freebsd_uthread_stop; -+ freebsd_uthread_ops.to_stratum = process_stratum; -+ freebsd_uthread_ops.to_has_all_memory = 1; -+ freebsd_uthread_ops.to_has_memory = 1; -+ freebsd_uthread_ops.to_has_stack = 1; -+ freebsd_uthread_ops.to_has_registers = 1; -+ freebsd_uthread_ops.to_has_execution = 1; -+ freebsd_uthread_ops.to_has_thread_control = 0; -+ freebsd_uthread_ops.to_magic = OPS_MAGIC; -+ freebsd_uthread_ops.to_find_new_threads = freebsd_uthread_find_new_threads; -+ freebsd_uthread_ops.to_pid_to_str = freebsd_uthread_pid_to_str; -+#if 0 -+ freebsd_uthread_vec.get_thread_info = freebsd_uthread_get_thread_info; -+#endif -+} -+ -+void -+_initialize_freebsd_uthread () -+{ -+ init_freebsd_uthread_ops (); -+ add_target (&freebsd_uthread_ops); -+ -+ target_new_objfile_chain = target_new_objfile_hook; -+ target_new_objfile_hook = freebsd_uthread_new_objfile; -+ -+ child_suppress_run = 1; -+} diff --git a/devel/gdb6/files/patch-i386%nm-fbsd64.h b/devel/gdb6/files/patch-i386%nm-fbsd64.h new file mode 100644 index 0000000..03ec32a --- /dev/null +++ b/devel/gdb6/files/patch-i386%nm-fbsd64.h @@ -0,0 +1,12 @@ +--- gdb/config/i386/nm-fbsd64.h.orig Sat Mar 13 05:07:20 2004 ++++ gdb/config/i386/nm-fbsd64.h Wed May 5 11:20:14 2004 +@@ -25,6 +25,9 @@ + /* Get generic BSD native definitions. */ + #include "config/nm-bsd.h" + ++/* Get generic FreeBSD native definitions. */ ++#include "config/nm-fbsd.h" ++ + /* Override child_pid_to_exec_file in 'inftarg.c'. */ + #define CHILD_PID_TO_EXEC_FILE + diff --git a/devel/gdb6/files/patch-i386-tdep.c b/devel/gdb6/files/patch-i386-tdep.c deleted file mode 100644 index f91663c..0000000 --- a/devel/gdb6/files/patch-i386-tdep.c +++ /dev/null @@ -1,12 +0,0 @@ ---- gdb/i386-tdep.c Mon Aug 26 11:35:25 2002 -+++ gdb/i386-tdep.c Sun Oct 13 14:15:58 2002 -@@ -534,6 +534,9 @@ - static CORE_ADDR - i386_frame_saved_pc (struct frame_info *frame) - { -+ if (kernel_debugging) -+ return fbsd_kern_frame_saved_pc(frame); -+ - if (PC_IN_CALL_DUMMY (frame->pc, 0, 0)) - return generic_read_register_dummy (frame->pc, frame->frame, - PC_REGNUM); diff --git a/devel/gdb6/files/patch-i386bsd-nat.c b/devel/gdb6/files/patch-i386bsd-nat.c deleted file mode 100644 index a28ce60..0000000 --- a/devel/gdb6/files/patch-i386bsd-nat.c +++ /dev/null @@ -1,20 +0,0 @@ ---- gdb/i386bsd-nat.c 2003/01/02 20:22:00 1.1 -+++ gdb/i386bsd-nat.c 2003/01/02 20:22:35 -@@ -306,7 +306,7 @@ - /* For some mysterious reason, some of the reserved bits in the - debug control register get set. Mask these off, otherwise the - ptrace call below will fail. */ -- dbregs.dr7 &= ~(0x0000fc00); -+ DBREG_DRX ((&dbregs), 7) = ~(0x0000fc00); - - DBREG_DRX ((&dbregs), regnum) = value; - -@@ -355,7 +355,7 @@ - return 0; - #endif - -- return dbregs.dr6; -+ return DBREG_DRX ((&dbregs), 6); - } - - #endif /* PT_GETDBREGS */ diff --git a/devel/gdb6/files/patch-kvm-fbsd.c b/devel/gdb6/files/patch-kvm-fbsd.c deleted file mode 100644 index 8838f0d..0000000 --- a/devel/gdb6/files/patch-kvm-fbsd.c +++ /dev/null @@ -1,759 +0,0 @@ ---- gdb/kvm-fbsd.c Fri Jan 3 08:57:23 2003 -+++ gdb/kvm-fbsd.c Fri Jan 3 08:57:20 2003 -@@ -0,0 +1,756 @@ -+/* Kernel core dump functions below target vector, for GDB. -+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 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. -+*/ -+ -+/* $FreeBSD: /tmp/pcvs/ports/devel/gdb6/files/Attic/patch-kvm-fbsd.c,v 1.5 2003-04-08 08:37:55 jake Exp $ */ -+ -+/* -+ * This works like "remote" but, you use it like this: -+ * target kcore /dev/mem -+ * or -+ * target kcore /var/crash/host/core.0 -+ * -+ * This way makes it easy to short-circut the whole bfd monster, -+ * and direct the inferior stuff to our libkvm implementation. -+ * -+ */ -+ -+#include <sys/param.h> -+#include <sys/time.h> -+#include <sys/proc.h> -+#include <sys/user.h> -+#include <ctype.h> -+#include <errno.h> -+#include <signal.h> -+#include <fcntl.h> -+#include <kvm.h> -+#include <sys/sysctl.h> -+#include <paths.h> -+#include <readline/tilde.h> -+#include <machine/frame.h> -+ -+#include "defs.h" -+#include "gdb_string.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 "regcache.h" -+ -+#if __FreeBSD_version >= 500032 -+static void -+kcore_files_info (struct target_ops *); -+ -+static void -+kcore_close (int); -+ -+static void -+get_kcore_registers (int); -+ -+static int -+xfer_mem (CORE_ADDR, char *, int, int, struct mem_attrib *, -+ struct target_ops *); -+ -+static int -+xfer_umem (CORE_ADDR, char *, int, int); -+ -+static char *core_file; -+static kvm_t *core_kd; -+static struct pcb cur_pcb; -+static struct kinfo_proc *cur_proc; -+ -+static struct target_ops kcore_ops; -+ -+int kernel_debugging; -+int kernel_writablecore; -+ -+/* 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)))) -+ -+static CORE_ADDR -+ksym_kernbase (void) -+{ -+ static CORE_ADDR kernbase; -+ struct minimal_symbol *sym; -+ -+ if (kernbase == 0) -+ { -+ sym = lookup_minimal_symbol ("kernbase", NULL, NULL); -+ if (sym == NULL) { -+ kernbase = KERNBASE; -+ } else { -+ kernbase = SYMBOL_VALUE_ADDRESS (sym); -+ } -+ } -+ return kernbase; -+} -+ -+#define KERNOFF (ksym_kernbase ()) -+#define INKERNEL(x) ((x) >= KERNOFF) -+ -+CORE_ADDR -+ksym_lookup(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); -+} -+ -+/* Provide the address of an initial PCB to use. -+ If this is a crash dump, try for "dumppcb". -+ If no "dumppcb" or it's /dev/mem, use proc0. -+ Return the core address of the PCB we found. */ -+ -+static CORE_ADDR -+initial_pcb (void) -+{ -+ struct minimal_symbol *sym; -+ CORE_ADDR addr; -+ void *val; -+ -+ /* Make sure things are open... */ -+ if (!core_kd || !core_file) -+ return (0); -+ -+ /* If this is NOT /dev/mem try for dumppcb. */ -+ if (strncmp (core_file, _PATH_DEV, sizeof _PATH_DEV - 1)) -+ { -+ sym = lookup_minimal_symbol ("dumppcb", NULL, NULL); -+ if (sym != NULL) -+ { -+ addr = SYMBOL_VALUE_ADDRESS (sym); -+ return (addr); -+ } -+ } -+ -+ /* OK, just use thread0's pcb. Note that curproc might -+ not exist, and if it does, it will point to gdb. -+ Therefore, just use proc0 and let the user set -+ some other context if they care about it. */ -+ -+ addr = ksym_lookup ("thread0"); -+ if (kvread (addr, &val)) -+ { -+ error ("cannot read thread0 pointer at %x\n", addr); -+ val = 0; -+ } -+ else -+ { -+ /* Read the PCB address in thread structure. */ -+ addr += offsetof (struct thread, td_pcb); -+ if (kvread (addr, &val)) -+ { -+ error ("cannot read thread0->td_pcb pointer at %x\n", addr); -+ val = 0; -+ } -+ } -+ -+ /* thread0 is wholly in the kernel and cur_proc is only used for -+ reading user mem, so no point in setting this up. */ -+ cur_proc = 0; -+ -+ return ((CORE_ADDR)val); -+} -+ -+/* Set the current context to that of the PCB struct at the system address -+ passed. */ -+ -+static int -+set_context (CORE_ADDR addr) -+{ -+ CORE_ADDR procaddr = 0; -+ -+ if (kvread (addr, &cur_pcb)) -+ error ("cannot read pcb at %#x", addr); -+ -+ /* 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 ()); -+ return (0); -+} -+ -+/* Discard all vestiges of any previous core file and mark data and stack -+ spaces as empty. */ -+ -+/* ARGSUSED */ -+static void -+kcore_close (int quitting) -+{ -+ -+ inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */ -+ -+ if (core_kd) -+ { -+ kvm_close (core_kd); -+ free (core_file); -+ core_file = NULL; -+ core_kd = NULL; -+ } -+} -+ -+/* This routine opens and sets up the core file bfd. */ -+ -+static void -+kcore_open (char *filename /* the core file */, int from_tty) -+{ -+ kvm_t *kd; -+ const char *p; -+ struct cleanup *old_chain; -+ char buf[256], *cp; -+ int ontop; -+ CORE_ADDR addr; -+ -+ target_preopen (from_tty); -+ -+ /* The exec file is required for symbols. */ -+ if (exec_bfd == NULL) -+ error ("No kernel exec file specified"); -+ -+ if (core_kd) -+ { -+ error ("No core file specified." -+ " (Use `detach' to stop debugging a core file.)"); -+ return; -+ } -+ -+ if (!filename) -+ { -+ error ("No core file specified."); -+ return; -+ } -+ -+ filename = tilde_expand (filename); -+ if (filename[0] != '/') -+ { -+ cp = concat (current_directory, "/", filename, NULL); -+ free (filename); -+ filename = cp; -+ } -+ -+ old_chain = make_cleanup (free, filename); -+ -+ kd = kvm_open (bfd_get_filename(exec_bfd), filename, NULL, -+ kernel_writablecore ? O_RDWR: O_RDONLY, 0); -+ if (kd == NULL) -+ { -+ perror_with_name (filename); -+ return; -+ } -+ -+ /* 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; -+ unpush_target (&kcore_ops); -+ ontop = !push_target (&kcore_ops); -+ -+ /* Note unpush_target (above) calls kcore_close. */ -+ core_kd = kd; -+ -+ /* 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_filtered ("panic: %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; -+ } -+ -+ /* Now, set up process context, and print the top of stack. */ -+ (void)set_context (initial_pcb()); -+ print_stack_frame (selected_frame, frame_relative_level(selected_frame), 1); -+} -+ -+static void -+kcore_detach (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"); -+} -+ -+#ifdef __alpha__ -+ -+#include "alpha/tm-alpha.h" -+#include "alpha-tdep.h" -+ -+#ifndef S0_REGNUM -+#define S0_REGNUM (ALPHA_T7_REGNUM+1) -+#endif -+ -+fetch_kcore_registers (struct pcb *pcbp) -+{ -+ -+ /* First clear out any garbage. */ -+ memset (registers, '\0', REGISTER_BYTES); -+ -+ /* SP */ -+ *(long *) ®isters[REGISTER_BYTE (SP_REGNUM)] = -+ pcbp->pcb_hw.apcb_ksp; -+ -+ /* S0 through S6 */ -+ memcpy (®isters[REGISTER_BYTE (S0_REGNUM)], -+ &pcbp->pcb_context[0], 7 * sizeof (long)); -+ -+ /* PC */ -+ *(long *) ®isters[REGISTER_BYTE (PC_REGNUM)] = -+ pcbp->pcb_context[7]; -+ -+ registers_fetched (); -+} -+ -+ -+CORE_ADDR -+fbsd_kern_frame_saved_pc (struct frame_info *fi) -+{ -+ struct minimal_symbol *sym; -+ CORE_ADDR this_saved_pc; -+ -+ this_saved_pc = FRAME_SAVED_PC(fi); -+ -+ sym = lookup_minimal_symbol_by_pc (this_saved_pc); -+ -+ if (sym != NULL && -+ (strcmp (SYMBOL_NAME (sym), "XentArith") == 0 || -+ strcmp (SYMBOL_NAME (sym), "XentIF") == 0 || -+ strcmp (SYMBOL_NAME (sym), "XentInt") == 0 || -+ strcmp (SYMBOL_NAME (sym), "XentMM") == 0 || -+ strcmp (SYMBOL_NAME (sym), "XentSys") == 0 || -+ strcmp (SYMBOL_NAME (sym), "XentUna") == 0 || -+ strcmp (SYMBOL_NAME (sym), "XentRestart") == 0)) -+ { -+ return (read_memory_integer (fi->frame + 32 * 8, 8)); -+ } -+ else -+ { -+ return (this_saved_pc); -+ } -+} -+ -+#endif /* __alpha__ */ -+ -+#ifdef __i386__ -+ -+static CORE_ADDR -+ksym_maxuseraddr (void) -+{ -+ static CORE_ADDR maxuseraddr; -+ struct minimal_symbol *sym; -+ -+ if (maxuseraddr == 0) -+ { -+ sym = lookup_minimal_symbol ("PTmap", NULL, NULL); -+ if (sym == NULL) { -+ maxuseraddr = VM_MAXUSER_ADDRESS; -+ } else { -+ maxuseraddr = SYMBOL_VALUE_ADDRESS (sym); -+ } -+ } -+ return maxuseraddr; -+} -+ -+ -+/* Symbol names of kernel entry points. Use special frames. */ -+#define KSYM_TRAP "calltrap" -+#define KSYM_INTR "Xintr" -+#define KSYM_FASTINTR "Xfastintr" -+#define KSYM_OLDSYSCALL "Xlcall_syscall" -+#define KSYM_SYSCALL "Xint0x80_syscall" -+ -+/* 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 (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), KSYM_TRAP) == 0) -+ frametype = tf_trap; -+ else -+ if (strncmp (SYMBOL_NAME (sym), KSYM_INTR, -+ strlen (KSYM_INTR)) == 0 || strncmp (SYMBOL_NAME(sym), -+ KSYM_FASTINTR, strlen (KSYM_FASTINTR)) == 0) -+ frametype = tf_interrupt; -+ else -+ if (strcmp (SYMBOL_NAME (sym), KSYM_SYSCALL) == 0 || -+ strcmp (SYMBOL_NAME (sym), KSYM_OLDSYSCALL) == 0) -+ frametype = tf_syscall; -+ } -+ -+ switch (frametype) -+ { -+ default: -+ 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 + 12 + oEIP, 4)); -+ -+ case tf_syscall: -+ return (read_memory_integer (fr->frame + 8 + oEIP, 4)); -+#undef oEIP -+ } -+} -+ -+static void -+fetch_kcore_registers (struct pcb *pcb) -+{ -+ int i; -+ int noreg; -+ -+ /* 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? */ -+} -+ -+#endif /* __i386__ */ -+ -+#ifdef __sparc64__ -+ -+#define SPARC_INTREG_SIZE 8 -+ -+static void -+fetch_kcore_registers (struct pcb *pcbp) -+{ -+ static struct frame top; -+ CORE_ADDR f_addr; -+ int i; -+ -+ /* 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 do something with the floating-point registers? -+ */ -+ supply_register (SP_REGNUM, &pcbp->pcb_sp); -+ supply_register (PC_REGNUM, &pcbp->pcb_pc); -+ f_addr = extract_address (&pcbp->pcb_sp, SPARC_INTREG_SIZE); -+ /* Load the previous frame by hand (XXX) and supply it. */ -+ read_memory (f_addr + SPOFF, (char *)&top, sizeof (top)); -+ for (i = 0; i < 8; i++) -+ supply_register (i + L0_REGNUM, &top.fr_local[i]); -+ for (i = 0; i < 8; i++) -+ supply_register (i + I0_REGNUM, &top.fr_in[i]); -+} -+ -+CORE_ADDR -+fbsd_kern_frame_saved_pc (struct frame_info *fi) -+{ -+ struct minimal_symbol *sym; -+ CORE_ADDR frame, pc_addr, pc; -+ char *buf; -+ -+ buf = alloca (MAX_REGISTER_RAW_SIZE); -+ /* XXX: duplicates fi->extra_info->bottom. */ -+ frame = (fi->next != NULL) ? fi->next->frame : read_sp (); -+ pc_addr = frame + offsetof (struct frame, fr_in[7]); -+ -+#define READ_PC(pc, a, b) do { \ -+ read_memory (a, b, SPARC_INTREG_SIZE); \ -+ pc = extract_address (b, SPARC_INTREG_SIZE); \ -+} while (0) -+ -+ READ_PC (pc, pc_addr, buf); -+ -+ sym = lookup_minimal_symbol_by_pc (pc); -+ if (sym != NULL) -+ { -+ if (strncmp (SYMBOL_NAME (sym), "tl0_", 4) == 0 || -+ strcmp (SYMBOL_NAME (sym), "btext") == 0 || -+ strcmp (SYMBOL_NAME (sym), "mp_startup") == 0 || -+ strcmp (SYMBOL_NAME (sym), "fork_trampoline") == 0) -+ { -+ /* -+ * Ugly kluge: user space addresses aren't separated from kernel -+ * ones by range; if encountering a trap from user space, just -+ * return a 0 to stop the trace. -+ * Do the same for entry points of kernel processes to avoid -+ * printing garbage. -+ */ -+ pc = 0; -+ } -+ if (strncmp (SYMBOL_NAME (sym), "tl1_", 4) == 0) -+ { -+ pc_addr = fi->frame + sizeof (struct frame) + -+ offsetof (struct trapframe, tf_tpc); -+ READ_PC (pc, pc_addr, buf); -+ } -+ } -+ return (pc); -+} -+ -+#endif /* __sparc64__ */ -+ -+/* 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 (int regno) -+{ -+ -+ /* XXX - Only read the pcb when set_context() is called. -+ When looking at a live kernel this may be a problem, -+ but the user can do another "proc" or "pcb" command to -+ grab a new copy of the pcb... */ -+ -+ /* Zero out register set then fill in the ones we know about. */ -+ fetch_kcore_registers (&cur_pcb); -+} -+ -+static void -+kcore_files_info (t) -+ struct target_ops *t; -+{ -+ printf_filtered ("\t`%s'\n", core_file); -+} -+ -+/* If mourn is being called in all the right places, this could be say -+ `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */ -+ -+static int -+ignore (CORE_ADDR addr, char *contents) -+{ -+ return 0; -+} -+ -+static int -+xfer_kmem (CORE_ADDR memaddr, char *myaddr, int len, int write, -+ struct mem_attrib *attrib, struct target_ops *target) -+{ -+ int n; -+ -+ -+ if (!INKERNEL (memaddr)) -+ return xfer_umem (memaddr, myaddr, len, write); -+ -+ if (core_kd == NULL) -+ return 0; -+ -+ if (write) -+ n = kvm_write (core_kd, memaddr, myaddr, len); -+ else -+ n = kvm_read (core_kd, memaddr, myaddr, len) ; -+ if (n < 0) { -+ fprintf_unfiltered (gdb_stderr, "can not access 0x%x, %s\n", -+ memaddr, kvm_geterr (core_kd)); -+ n = 0; -+ } -+ -+ return n; -+} -+ -+ -+static int -+xfer_umem (CORE_ADDR memaddr, char *myaddr, int len, int write /* ignored */) -+{ -+ int n = 0; -+ -+ if (cur_proc == 0) -+ { -+ error ("---Can't read userspace from dump, or kernel process---\n"); -+ return 0; -+ } -+ -+ if (write) -+ error ("kvm_uwrite unimplemented\n"); -+ else -+ n = kvm_uread (core_kd, cur_proc, memaddr, myaddr, len) ; -+ -+ if (n < 0) -+ return 0; -+ -+ return n; -+} -+ -+static void -+set_proc_cmd (char *arg, int from_tty) -+{ -+ CORE_ADDR addr, pid_addr, first_td; -+ void *val; -+ struct kinfo_proc *kp; -+ int cnt; -+ pid_t pid; -+ -+ if (!arg) -+ error_no_arg ("proc address for the new context"); -+ -+ if (core_kd == NULL) -+ error ("no kernel core file"); -+ -+ addr = (CORE_ADDR) parse_and_eval_address (arg); -+ -+ if (!INKERNEL (addr)) -+ { -+ kp = kvm_getprocs (core_kd, KERN_PROC_PID, addr, &cnt); -+ if (!cnt) -+ error ("invalid pid"); -+ addr = (CORE_ADDR)kp->ki_paddr; -+ cur_proc = kp; -+ } -+ else -+ { -+ /* Update cur_proc. */ -+ pid_addr = addr + offsetof (struct proc, p_pid); -+ if (kvread (pid_addr, &pid)) -+ error ("cannot read pid ptr"); -+ cur_proc = kvm_getprocs (core_kd, KERN_PROC_PID, pid, &cnt); -+ if (!cnt) -+ error("invalid pid"); -+ } -+ -+ /* Find the first thread in the process. XXXKSE */ -+ addr += offsetof (struct proc, p_threads.tqh_first); -+ if (kvread (addr, &first_td)) -+ error ("cannot read thread ptr"); -+ -+ /* Read the PCB address in thread structure. */ -+ addr = first_td + offsetof (struct thread, td_pcb); -+ if (kvread (addr, &val)) -+ error("cannot read pcb ptr"); -+ -+ /* Read the PCB address in proc structure. */ -+ if (set_context ((CORE_ADDR) val)) -+ error ("invalid proc address"); -+} -+#else -+int kernel_debugging = 0; -+int kernel_writablecore = 0; -+ -+CORE_ADDR -+fbsd_kern_frame_saved_pc (struct frame_info *fi) -+{ -+ return 0; -+} -+#endif -+ -+void -+_initialize_kcorelow (void) -+{ -+#if __FreeBSD_version >= 500032 -+ kcore_ops.to_shortname = "kcore"; -+ kcore_ops.to_longname = "Kernel core dump file"; -+ kcore_ops.to_doc = -+ "Use a core file as a target. Specify the filename of the core file."; -+ kcore_ops.to_open = kcore_open; -+ kcore_ops.to_close = kcore_close; -+ kcore_ops.to_attach = find_default_attach; -+ kcore_ops.to_detach = kcore_detach; -+ kcore_ops.to_fetch_registers = get_kcore_registers; -+ kcore_ops.to_xfer_memory = xfer_kmem; -+ kcore_ops.to_files_info = kcore_files_info; -+ kcore_ops.to_create_inferior = find_default_create_inferior; -+ kcore_ops.to_stratum = kcore_stratum; -+ kcore_ops.to_has_memory = 1; -+ kcore_ops.to_has_stack = 1; -+ kcore_ops.to_has_registers = 1; -+ kcore_ops.to_magic = OPS_MAGIC; -+ -+ add_target (&kcore_ops); -+ add_com ("proc", class_obscure, set_proc_cmd, "Set current process context"); -+#endif -+} diff --git a/devel/gdb6/files/patch-main.c b/devel/gdb6/files/patch-main.c new file mode 100644 index 0000000..bd5cd46 --- /dev/null +++ b/devel/gdb6/files/patch-main.c @@ -0,0 +1,53 @@ +--- gdb/main.c.orig Thu Apr 15 22:40:39 2004 ++++ gdb/main.c Thu Apr 15 22:47:51 2004 +@@ -66,6 +66,12 @@ + /* Whether dbx commands will be handled */ + int dbx_commands = 0; + ++#ifdef KGDB ++/* Kernel debugging support. */ ++int kernel_debugging; ++int kernel_writablecore; ++#endif ++ + /* System root path, used to find libraries etc. */ + char *gdb_sysroot = 0; + +@@ -311,6 +317,12 @@ + {"statistics", no_argument, 0, OPT_STATISTICS}, + {"write", no_argument, &write_files, 1}, + {"args", no_argument, &set_args, 1}, ++#ifdef KGDB ++ {"kernel", no_argument, &kernel_debugging, 1}, ++ {"k", no_argument, &kernel_debugging, 1}, ++ {"wcore", no_argument, &kernel_writablecore, 1}, ++ {"w", no_argument, &kernel_writablecore, 1}, ++#endif + {0, no_argument, 0, 0} + }; + +@@ -857,6 +869,11 @@ + --interpreter=INTERP\n\ + Select a specific interpreter / user interface\n\ + "), stream); ++#ifdef KGDB ++ fputs_unfiltered (_("\ ++ --kernel Enable kernel debugging.\n\ ++"), stream); ++#endif + fputs_unfiltered (_("\ + --mapped Use mapped symbol files if supported on this system.\n\ + --nw Do not use a window interface.\n\ +@@ -874,6 +891,12 @@ + #if defined(TUI) + fputs_unfiltered (_("\ + --tui Use a terminal user interface.\n\ ++"), stream); ++#endif ++#ifdef KGDB ++ fputs_unfiltered (_("\ ++ --wcore Make core file writable (only works for /dev/mem).\n\ ++ This option only works while debugging a kernel !!\n\ + "), stream); + #endif + fputs_unfiltered (_("\ diff --git a/devel/gdb6/files/patch-sparc-tdep.c b/devel/gdb6/files/patch-sparc-tdep.c deleted file mode 100644 index 950276e..0000000 --- a/devel/gdb6/files/patch-sparc-tdep.c +++ /dev/null @@ -1,13 +0,0 @@ ---- gdb/sparc-tdep.c.orig Sun Oct 20 18:21:09 2002 -+++ gdb/sparc-tdep.c Sun Oct 20 18:16:53 2002 -@@ -450,6 +450,9 @@ - char *buf; - CORE_ADDR addr; - -+ if (kernel_debugging) -+ return fbsd_kern_frame_saved_pc(frame); -+ - buf = alloca (MAX_REGISTER_RAW_SIZE); - if (frame->signal_handler_caller) - { - diff --git a/devel/gdb6/files/patch-sparcnbsd-tdep.c b/devel/gdb6/files/patch-sparcnbsd-tdep.c deleted file mode 100644 index 13ba396..0000000 --- a/devel/gdb6/files/patch-sparcnbsd-tdep.c +++ /dev/null @@ -1,63 +0,0 @@ -diff -urN gdb/sparcnbsd-tdep.c.orig gdb/sparcnbsd-tdep.c ---- gdb/sparcnbsd-tdep.c.orig Sat Oct 19 17:19:17 2002 -+++ gdb/sparcnbsd-tdep.c Sat Oct 19 17:44:47 2002 -@@ -31,20 +31,6 @@ - - #include "solib-svr4.h" - --#define REG32_OFFSET_PSR (0 * 4) --#define REG32_OFFSET_PC (1 * 4) --#define REG32_OFFSET_NPC (2 * 4) --#define REG32_OFFSET_Y (3 * 4) --#define REG32_OFFSET_GLOBAL (4 * 4) --#define REG32_OFFSET_OUT (12 * 4) -- --#define REG64_OFFSET_TSTATE (0 * 8) --#define REG64_OFFSET_PC (1 * 8) --#define REG64_OFFSET_NPC (2 * 8) --#define REG64_OFFSET_Y (3 * 8) --#define REG64_OFFSET_GLOBAL (4 * 8) --#define REG64_OFFSET_OUT (12 * 8) -- - void - sparcnbsd_supply_reg32 (char *regs, int regno) - { -@@ -375,16 +361,13 @@ - - if (gdbarch_ptr_bit (current_gdbarch) == 32) - { -- reg_size = (20 * 4); -- fpreg_size = (33 * 4); -+ reg_size = REG32_SIZE; -+ fpreg_size = FPREG32_SIZE; - } - else - { -- reg_size = (20 * 8); -- fpreg_size = (64 * 4) -- + 8 /* fsr */ -- + 4 /* gsr */ -- + 4; /* pad */ -+ reg_size = REG64_SIZE; -+ fpreg_size = FPREG64_SIZE; - } - - switch (which) -@@ -442,7 +425,7 @@ - - jb_addr = read_register (O0_REGNUM); - -- if (target_read_memory (jb_addr + 12, buf, sizeof (buf))) -+ if (target_read_memory (jb_addr + JB32_OFFSET_PC, buf, sizeof (buf))) - return 0; - - *pc = extract_address (buf, sizeof (buf)); -@@ -458,7 +441,7 @@ - - jb_addr = read_register (O0_REGNUM); - -- if (target_read_memory (jb_addr + 16, buf, sizeof (buf))) -+ if (target_read_memory (jb_addr + JB64_OFFSET_PC, buf, sizeof (buf))) - return 0; - - *pc = extract_address (buf, sizeof (buf)); diff --git a/devel/gdb6/files/patch-symfile.c b/devel/gdb6/files/patch-symfile.c deleted file mode 100644 index 99c75ff..0000000 --- a/devel/gdb6/files/patch-symfile.c +++ /dev/null @@ -1,15 +0,0 @@ ---- gdb/symfile.c Tue Feb 26 17:40:36 2002 -+++ gdb/symfile.c Wed May 29 11:10:17 2002 -@@ -1546,11 +1546,7 @@ - char *val = sect_opts[i].value; - char *sec = sect_opts[i].name; - -- val = sect_opts[i].value; -- if (val[0] == '0' && val[1] == 'x') -- addr = strtoul (val+2, NULL, 16); -- else -- addr = strtoul (val, NULL, 10); -+ addr = parse_and_eval_address(val); - - /* Here we store the section offsets in the order they were - entered on the command line. */ diff --git a/devel/gdb6/files/patch-version.in b/devel/gdb6/files/patch-version.in deleted file mode 100644 index 4496ebf..0000000 --- a/devel/gdb6/files/patch-version.in +++ /dev/null @@ -1,5 +0,0 @@ ---- gdb/version.in Fri Apr 26 18:04:22 2002 -+++ gdb/version.in Mon Jun 3 08:14:54 2002 -@@ -1 +1 @@ --5.2.90 -+5.3 (FreeBSD) diff --git a/devel/gdb6/pkg-descr b/devel/gdb6/pkg-descr index be3a113..a6e471a 100644 --- a/devel/gdb6/pkg-descr +++ b/devel/gdb6/pkg-descr @@ -1 +1 @@ -GNU GDB 5.3 developmental snapshot. +GNU GDB 6.x developmental snapshot. diff --git a/devel/gdb66/Makefile b/devel/gdb66/Makefile index 660de03..35c4d09 100644 --- a/devel/gdb66/Makefile +++ b/devel/gdb66/Makefile @@ -6,7 +6,7 @@ # $FreeBSD$ # -SNAPDATE= 2004-05-04 +SNAPDATE= 2004-05-11 SNAPVER= ${SNAPDATE:S/-//g} PORTNAME= gdb @@ -17,17 +17,20 @@ MASTER_SITES= ${MASTER_SITE_SOURCEWARE} MASTER_SITE_SUBDIR= gdb/snapshots/current DISTNAME= gdb+dejagnu-weekly-${SNAPVER} +PATCH_SITES= ${MASTER_SITE_LOCAL} +PATCH_SITE_SUBDIR= obrien +#PATCHFILES= gdb60_xfree-loadmod.diff + MAINTAINER= obrien@FreeBSD.org COMMENT= GNU GDB 6 -LATEST_LINK= gdb6 WRKSRC= ${WRKDIR}/${DISTNAME:S/-weekly//} USE_BZIP2= yes USE_GMAKE= yes USE_REINPLACE= yes GNU_CONFIGURE= yes CONFIGURE_ARGS= --program-suffix=6 -CFLAGS+= -DRL_NO_COMPAT +CFLAGS+= -DRL_NO_COMPAT -DKGDB .include <bsd.port.pre.mk> @@ -47,22 +50,23 @@ PLIST_SUB+= NO_NATIVE_GDB="@comment " .endif post-patch: - @${REINPLACE_CMD} -e 's/$$/ [FreeBSD]/' ${WRKSRC}/gdb/version.in + @${REINPLACE_CMD} -e 's/$$/ [GDB v6.x for FreeBSD]/' \ + ${WRKSRC}/gdb/version.in @${REINPLACE_CMD} -e 's/^READLINE/#READLINE/' \ -e 's/^readline/#readline/' \ ${WRKSRC}/gdb/Makefile.in ${ECHO} 'READLINE = -lreadline' >> ${WRKSRC}/gdb/Makefile.in -do-patch: post-patch - @${ECHO} 'FreeBSD-specific patches disabled for now, until upgraded.' - pre-configure: cd ${WRKSRC} ; ${RM} -rf dejagnu expect readline sim tcl texinfo +.for f in freebsd-uthread.c kvm-fbsd.c + ${LN} -sf ${FILESDIR}/${f} ${WRKSRC}/gdb +.endfor + ${LN} -sf ${FILESDIR}/nm-fbsd.h ${WRKSRC}/gdb/config do-install: ${INSTALL_PROGRAM} ${WRKSRC}/gdb/gdb \ ${PREFIX}/bin/${PORTNAME}${PORTVERSION:S/.//g} - cklatest: ncftpls \ ftp://sources.redhat.com/pub/${MASTER_SITE_SUBDIR}/ \ diff --git a/devel/gdb66/distinfo b/devel/gdb66/distinfo index ba05099..23a57b9 100644 --- a/devel/gdb66/distinfo +++ b/devel/gdb66/distinfo @@ -1,2 +1,2 @@ -MD5 (gdb+dejagnu-weekly-20040504.tar.bz2) = 020cb9bc6e414050fb813f23c84b6bc2 -SIZE (gdb+dejagnu-weekly-20040504.tar.bz2) = 16736958 +MD5 (gdb+dejagnu-weekly-20040511.tar.bz2) = 885cc6fc6265a4c43c10d8d1b14e76f8 +SIZE (gdb+dejagnu-weekly-20040511.tar.bz2) = 16759923 diff --git a/devel/gdb66/files/freebsd-uthread.c b/devel/gdb66/files/freebsd-uthread.c new file mode 100644 index 0000000..933dc51 --- /dev/null +++ b/devel/gdb66/files/freebsd-uthread.c @@ -0,0 +1,993 @@ +/* Low level interface for debugging FreeBSD user threads for GDB, the GNU debugger. + Copyright 1996, 1999 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. */ + +/* $FreeBSD$ */ + +/* This module implements a sort of half target that sits between the + machine-independent parts of GDB and the ptrace interface (infptrace.c) to + provide access to the FreeBSD user-mode thread implementation. + + FreeBSD threads are true user-mode threads, which are invoked via + the pthread_* interfaces. These are mostly implemented in + user-space, with all thread context kept in various structures that + live in the user's heap. For the most part, the kernel has no + knowlege of these threads. + + Based largely on hpux-thread.c + + */ + + +#include "defs.h" +#include <sys/queue.h> +#include <signal.h> +#include <setjmp.h> +#include <string.h> +#include "gdbthread.h" +#include "target.h" +#include "inferior.h" +#include <fcntl.h> +#include <ucontext.h> +#include <unistd.h> +#include <sys/stat.h> +#include "gdbcore.h" +#include "regcache.h" + +extern int child_suppress_run; +extern struct target_ops child_ops; /* target vector for inftarg.c */ + +extern void _initialize_freebsd_uthread PARAMS ((void)); + +/* Set to true while we are part-way through attaching */ +static int freebsd_uthread_attaching; + +static int freebsd_uthread_active = 0; +static CORE_ADDR P_thread_list; +static CORE_ADDR P_thread_run; + +/* Pointer to the next function on the objfile event chain. */ +static void (*target_new_objfile_chain) (struct objfile *objfile); + +static void freebsd_uthread_resume PARAMS ((ptid_t pid, int step, + enum target_signal signo)); + +static void init_freebsd_uthread_ops PARAMS ((void)); + +static struct target_ops freebsd_uthread_ops; + +static ptid_t find_active_ptid PARAMS ((void)); + +struct cached_pthread { + u_int64_t uniqueid; + int state; + CORE_ADDR name; + union { + ucontext_t uc; + jmp_buf jb; + } ctx; +}; + +static ptid_t cached_ptid; +static struct cached_pthread cached_pthread; +static CORE_ADDR cached_pthread_addr; + +LIST_HEAD(idmaplist, idmap); + +struct idmap { + LIST_ENTRY(idmap) link; + u_int64_t uniqueid; + int tid; +}; + +#define MAPHASH_SIZE 257 +#define TID_MIN 1 +#define TID_MAX 16383 + +static int tid_to_hash[TID_MAX + 1]; /* set to map_hash index */ +static struct idmaplist map_hash[MAPHASH_SIZE]; +static int next_free_tid = TID_MIN; /* first available tid */ +static int last_free_tid = TID_MIN; /* first unavailable */ + +static CORE_ADDR P_thread_next_offset; +static CORE_ADDR P_thread_uniqueid_offset; +static CORE_ADDR P_thread_state_offset; +static CORE_ADDR P_thread_name_offset; +static CORE_ADDR P_thread_ctx_offset; +static CORE_ADDR P_thread_PS_RUNNING_value; +static CORE_ADDR P_thread_PS_DEAD_value; + +static int next_offset; +static int uniqueid_offset; +static int state_offset; +static int name_offset; +static int ctx_offset; +static int PS_RUNNING_value; +static int PS_DEAD_value; + +#define UNIQUEID_HASH(id) (id % MAPHASH_SIZE) +#define TID_ADD1(tid) (((tid) + 1) == TID_MAX + 1 \ + ? TID_MIN : (tid) + 1) +#define IS_TID_FREE(tid) (tid_to_hash[tid] == -1) + +static int +get_new_tid(int h) +{ + int tid = next_free_tid; + + tid_to_hash[tid] = h; + next_free_tid = TID_ADD1(next_free_tid); + if (next_free_tid == last_free_tid) + { + int i; + + for (i = last_free_tid; TID_ADD1(i) != last_free_tid; i = TID_ADD1(i)) + if (IS_TID_FREE(i)) + break; + if (TID_ADD1(i) == last_free_tid) + { + error("too many threads"); + return 0; + } + next_free_tid = i; + for (i = TID_ADD1(i); IS_TID_FREE(i); i = TID_ADD1(i)) + ; + last_free_tid = i; + } + + return tid; +} + +static ptid_t +find_ptid(u_int64_t uniqueid) +{ + int h = UNIQUEID_HASH(uniqueid); + struct idmap *im; + + LIST_FOREACH(im, &map_hash[h], link) + if (im->uniqueid == uniqueid) + return MERGEPID(PIDGET(inferior_ptid), im->tid); + + im = xmalloc(sizeof(struct idmap)); + im->uniqueid = uniqueid; + im->tid = get_new_tid(h); + LIST_INSERT_HEAD(&map_hash[h], im, link); + + return MERGEPID(PIDGET(inferior_ptid), im->tid); +} + +static void +free_ptid(ptid_t ptid) +{ + int tid = TIDGET(ptid); + int h = tid_to_hash[tid]; + struct idmap *im; + + if (!tid) return; + + LIST_FOREACH(im, &map_hash[h], link) + if (im->tid == tid) + break; + + if (!im) return; + + LIST_REMOVE(im, link); + tid_to_hash[tid] = -1; + free(im); +} + +#define READ_OFFSET(field) read_memory(P_thread_##field##_offset, \ + (char *) &field##_offset, \ + sizeof(field##_offset)) + +#define READ_VALUE(name) read_memory(P_thread_##name##_value, \ + (char *) &name##_value, \ + sizeof(name##_value)) + +static void +read_thread_offsets (void) +{ + READ_OFFSET(next); + READ_OFFSET(uniqueid); + READ_OFFSET(state); + READ_OFFSET(name); + READ_OFFSET(ctx); + + READ_VALUE(PS_RUNNING); + READ_VALUE(PS_DEAD); +} + +#define READ_FIELD(ptr, T, field, result) \ + read_memory ((ptr) + field##_offset, (char *) &(result), sizeof result) + +static u_int64_t +read_pthread_uniqueid (CORE_ADDR ptr) +{ + u_int64_t uniqueid; + READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid); + return uniqueid; +} + +static CORE_ADDR +read_pthread_next (CORE_ADDR ptr) +{ + CORE_ADDR next; + READ_FIELD(ptr, CORE_ADDR, next, next); + return next; +} + +static void +read_cached_pthread (CORE_ADDR ptr, struct cached_pthread *cache) +{ + READ_FIELD(ptr, u_int64_t, uniqueid, cache->uniqueid); + READ_FIELD(ptr, int, state, cache->state); + READ_FIELD(ptr, CORE_ADDR, name, cache->name); + READ_FIELD(ptr, ucontext_t, ctx, cache->ctx); +} + +static ptid_t +find_active_ptid (void) +{ + CORE_ADDR ptr; + + read_memory ((CORE_ADDR)P_thread_run, + (char *)&ptr, + sizeof ptr); + + return find_ptid(read_pthread_uniqueid(ptr)); +} + +static CORE_ADDR find_pthread_addr PARAMS ((ptid_t ptid)); +static struct cached_pthread * find_pthread PARAMS ((ptid_t ptid)); + +static CORE_ADDR +find_pthread_addr (ptid_t ptid) +{ + CORE_ADDR ptr; + + if (ptid_equal(ptid, cached_ptid)) + return cached_pthread_addr; + + read_memory ((CORE_ADDR)P_thread_list, + (char *)&ptr, + sizeof ptr); + + while (ptr != 0) + { + if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid)) + { + cached_ptid = ptid; + cached_pthread_addr = ptr; + read_cached_pthread(ptr, &cached_pthread); + return ptr; + } + ptr = read_pthread_next(ptr); + } + + return NULL; +} + +static struct cached_pthread * +find_pthread (ptid_t ptid) +{ + CORE_ADDR ptr; + + if (ptid_equal(ptid, cached_ptid)) + return &cached_pthread; + + read_memory ((CORE_ADDR)P_thread_list, + (char *)&ptr, + sizeof ptr); + + while (ptr != 0) + { + if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid)) + { + cached_ptid = ptid; + cached_pthread_addr = ptr; + read_cached_pthread(ptr, &cached_pthread); + return &cached_pthread; + } + ptr = read_pthread_next(ptr); + } + +#if 0 + error ("Can't find pthread %d,%d", PIDGET(ptid), TIDGET(ptid)); +#endif + return NULL; +} + + +/* Most target vector functions from here on actually just pass through to + inftarg.c, as they don't need to do anything specific for threads. */ + +/* ARGSUSED */ +static void +freebsd_uthread_open (char *arg, int from_tty) +{ + child_ops.to_open (arg, from_tty); +} + +/* Attach to process PID, then initialize for debugging it + and wait for the trace-trap that results from attaching. */ + +static void +freebsd_uthread_attach (char *args, int from_tty) +{ + child_ops.to_attach (args, from_tty); + push_target (&freebsd_uthread_ops); + freebsd_uthread_attaching = 1; +} + +/* After an attach, see if the target is threaded */ + +static void +freebsd_uthread_post_attach (int pid) +{ + if (freebsd_uthread_active) + { + read_thread_offsets (); + inferior_ptid = find_active_ptid (); + add_thread (inferior_ptid); + } + else + { + unpush_target (&freebsd_uthread_ops); + push_target (&child_ops); + } + + freebsd_uthread_attaching = 0; +} + +/* Take a program previously attached to and detaches it. + The program resumes execution and will no longer stop + on signals, etc. We'd better not have left any breakpoints + in the program or it'll die when it hits one. For this + to work, it may be necessary for the process to have been + previously attached. It *might* work if the program was + started via the normal ptrace (PTRACE_TRACEME). */ + +static void +freebsd_uthread_detach (char *args, int from_tty) +{ + child_ops.to_detach (args, from_tty); +} + +/* Resume execution of process PID. If STEP is nozero, then + just single step it. If SIGNAL is nonzero, restart it with that + signal activated. We may have to convert pid from a thread-id to an LWP id + for procfs. */ + +static void +freebsd_uthread_resume (ptid_t ptid, int step, enum target_signal signo) +{ + if (freebsd_uthread_attaching) + { + child_ops.to_resume (ptid, step, signo); + return; + } + + child_ops.to_resume (ptid, step, signo); + cached_ptid = MERGEPID(0, 0); +} + +/* Wait for any threads to stop. We may have to convert PID from a thread id + to a LWP id, and vice versa on the way out. */ + +static ptid_t +freebsd_uthread_wait (ptid_t ptid, struct target_waitstatus *ourstatus) +{ + ptid_t rtnval; + + if (freebsd_uthread_attaching) + { + return child_ops.to_wait (ptid, ourstatus); + } + + rtnval = child_ops.to_wait (ptid, ourstatus); + + if (PIDGET(rtnval) >= 0) + { + rtnval = find_active_ptid (); + if (!in_thread_list (rtnval)) + add_thread (rtnval); + } + + return rtnval; +} + +/* XXX: this needs to be selected by target, not [build] host */ +#ifdef __i386__ + +#include "i386-tdep.h" + +static char sigmap[I386_SSE_NUM_REGS] = /* map reg to sigcontext */ +{ + 12, /* eax */ + 11, /* ecx */ + 10, /* edx */ + 9, /* ebx */ + 8, /* esp */ + 7, /* ebp */ + 6, /* esi */ + 5, /* edi */ + 15, /* eip */ + 17, /* eflags */ + 16, /* cs */ + 19, /* ss */ + 4, /* ds */ + 3, /* es */ + 2, /* fs */ + 1, /* gs */ + -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ + -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ + -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ + -1, /* mxcsr */ +}; + +static char jmpmap[I386_SSE_NUM_REGS] = /* map reg to jmp_buf */ +{ + 6, /* eax */ + -1, /* ecx */ + -1, /* edx */ + 1, /* ebx */ + 2, /* esp */ + 3, /* ebp */ + 4, /* esi */ + 5, /* edi */ + 0, /* eip */ + -1, /* eflags */ + -1, /* cs */ + -1, /* ss */ + -1, /* ds */ + -1, /* es */ + -1, /* fs */ + -1, /* gs */ + -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ + -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ + -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ + -1, /* mxcsr */ +}; + +#endif + +#ifdef __amd64__ + +#include "amd64-tdep.h" + +// XXX:DEO not fully ported from i386 yet!! + +static char sigmap[AMD64_NUM_REGS_TOTAL] = /* map reg to sigcontext */ +{ + 12, /* rax */ + 11, /* rcx */ + 10, /* rdx */ + 9, /* rbx */ + 8, /* rsp */ + 7, /* rbp */ + 6, /* rsi */ + 5, /* rdi */ + 15, /* rip */ + 17, /* rflags */ + 16, /* cs */ + 19, /* ss */ + 4, /* ds */ + 3, /* es */ + 2, /* fs */ + 1, /* gs */ + -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ + -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ + -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ + -1, /* mxcsr */ +}; + +static char jmpmap[AMD64_NUM_REGS_TOTAL] = /* map reg to jmp_buf */ +{ + 6, /* rax */ + -1, /* rcx */ + -1, /* rdx */ + 1, /* rbx */ + 2, /* rsp */ + 3, /* rbp */ + 4, /* rsi */ + 5, /* rdi */ + 0, /* rip */ + -1, /* rflags */ + -1, /* cs */ + -1, /* ss */ + -1, /* ds */ + -1, /* es */ + -1, /* fs */ + -1, /* gs */ + -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ + -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ + -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ + -1, /* mxcsr */ +}; + +#endif + +#ifdef __alpha__ + +#include "alpha-tdep.h" + +static char sigmap[ALPHA_NUM_REGS] = /* map reg to sigcontext */ +{ + 1, 2, 3, 4, 5, 6, 7, 8, /* v0 - t6 */ + 9, 10, 11, 12, 13, 14, 15, 16, /* t7 - fp */ + 17, 18, 19, 20, 21, 22, 23, 24, /* a0 - t9 */ + 25, 26, 27, 28, 29, 30, 31, 32, /* t10 - zero */ + 38, 39, 40, 41, 42, 43, 44, 45, /* f0 - f7 */ + 46, 47, 48, 49, 50, 51, 52, 53, /* f8 - f15 */ + 54, 55, 56, 57, 58, 59, 60, 61, /* f16 - f23 */ + 62, 63, 64, 65, 66, 67, 68, 69, /* f24 - f31 */ + 33, -1 /* pc, vfp */ +}; +static char jmpmap[ALPHA_NUM_REGS] = { + 4, 5, 6, 7, 8, 9, 10, 11, /* v0 - t6 */ + 12, 13, 14, 15, 16, 17, 18, 19, /* t7 - fp */ + 20, 21, 22, 23, 24, 25, 26, 27, /* a0 - t9 */ + 28, 29, 30, 31, 32, 33, 34, 35, /* t10 - zero */ + 37, 38, 39, 40, 41, 42, 43, 44, /* f0 - f7 */ + 45, 46, 47, 48, 49, 50, 51, 52, /* f8 - f15 */ + 53, 54, 55, 56, 57, 58, 59, 60, /* f16 - f23 */ + 61, 62, 63, 64, 65, 66, 67, 68, /* f24 - f31 */ + 2, -1, /* pc, vfp */ +}; + +#endif + +#ifdef __sparc64__ + +static char sigmap[125] = /* map reg to sigcontext */ +{ + -1 +}; +static char jmpmap[125] = { + -1 +}; + +#endif + +static void +freebsd_uthread_fetch_registers (int regno) +{ + struct cached_pthread *thread; + int active; + int first_regno, last_regno; + register_t *regbase; + char *regmap; + + if (freebsd_uthread_attaching || TIDGET(inferior_ptid) == 0) + { + child_ops.to_fetch_registers (regno); + return; + } + + thread = find_pthread (inferior_ptid); + active = (ptid_equal(inferior_ptid, find_active_ptid())); + + if (active) + { + child_ops.to_fetch_registers (regno); + return; + } + + if (regno == -1) + { + first_regno = 0; + last_regno = NUM_REGS - 1; + } + else + { + first_regno = regno; + last_regno = regno; + } + + regbase = (register_t*) &thread->ctx.jb[0]; + regmap = jmpmap; + + for (regno = first_regno; regno <= last_regno; regno++) + { + if (regmap[regno] == -1) + child_ops.to_fetch_registers (regno); + else + if (thread) + supply_register (regno, (char*) ®base[regmap[regno]]); + else + supply_register (regno, NULL); + } +} + +static void +freebsd_uthread_store_registers (int regno) +{ + struct cached_pthread *thread; + CORE_ADDR ptr; + int first_regno, last_regno; + u_int32_t *regbase; + char *regmap; + + if (freebsd_uthread_attaching) + { + child_ops.to_store_registers (regno); + return; + } + + thread = find_pthread (inferior_ptid); + + if (thread->state == PS_RUNNING_value) + { + child_ops.to_store_registers (regno); + return; + } + + if (regno == -1) + { + first_regno = 0; + last_regno = NUM_REGS - 1; + } + else + { + first_regno = regno; + last_regno = regno; + } + + regbase = (u_int32_t*) &thread->ctx.jb[0]; + regmap = jmpmap; + + ptr = find_pthread_addr (inferior_ptid); + for (regno = first_regno; regno <= last_regno; regno++) + { + if (regmap[regno] == -1) + child_ops.to_store_registers (regno); + else + { + u_int32_t *reg = ®base[regmap[regno]]; + int off; + + /* Hang onto cached value */ +/*DEO:XXX*/ + memcpy(reg, deprecated_registers /*regcache_collect ()*/+ DEPRECATED_REGISTER_BYTE (regno), + DEPRECATED_REGISTER_RAW_SIZE (regno)); + + /* And push out to inferior */ + off = (char *) reg - (char *) thread; + write_memory (ptr + off, +/*DEO:XXX*/ + deprecated_registers /*regcache_collect ()*/+ DEPRECATED_REGISTER_BYTE (regno), + DEPRECATED_REGISTER_RAW_SIZE (regno)); + } + } +} + +/* Get ready to modify the registers array. On machines which store + individual registers, this doesn't need to do anything. On machines + which store all the registers in one fell swoop, this makes sure + that registers contains all the registers from the program being + debugged. */ + +static void +freebsd_uthread_prepare_to_store (void) +{ + child_ops.to_prepare_to_store (); +} + +static int +freebsd_uthread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, + int dowrite, struct mem_attrib *attrib, + struct target_ops *target) +{ + return child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, + attrib, target); +} + +/* Print status information about what we're accessing. */ + +static void +freebsd_uthread_files_info (struct target_ops *ignore) +{ + child_ops.to_files_info (ignore); +} + +static void +freebsd_uthread_kill_inferior (void) +{ + child_ops.to_kill (); +} + +static void +freebsd_uthread_notice_signals (ptid_t ptid) +{ + child_ops.to_notice_signals (ptid); +} + +/* Fork an inferior process, and start debugging it with /proc. */ + +static void +freebsd_uthread_create_inferior (char *exec_file, char *allargs, char **env) +{ + child_ops.to_create_inferior (exec_file, allargs, env); + + if (PIDGET(inferior_ptid) && freebsd_uthread_active) + { + read_thread_offsets (); + push_target (&freebsd_uthread_ops); + inferior_ptid = find_active_ptid (); + add_thread (inferior_ptid); + } +} + +/* This routine is called to find out if the inferior is using threads. + We check for the _thread_run and _thread_list globals. */ + +void +freebsd_uthread_new_objfile (struct objfile *objfile) +{ + struct minimal_symbol *ms; + + if (!objfile) + { + freebsd_uthread_active = 0; + return; + } + + ms = lookup_minimal_symbol ("_thread_run", NULL, objfile); + + if (!ms) + return; + + P_thread_run = SYMBOL_VALUE_ADDRESS (ms); + + ms = lookup_minimal_symbol ("_thread_list", NULL, objfile); + + if (!ms) + return; + + P_thread_list = SYMBOL_VALUE_ADDRESS (ms); + +#define OFFSET_SYM(field) "_thread_" #field "_offset" +#define LOOKUP_OFFSET(field) \ + do { \ + ms = lookup_minimal_symbol (OFFSET_SYM(field), NULL, objfile); \ + if (!ms) \ + return; \ + P_thread_##field##_offset = SYMBOL_VALUE_ADDRESS (ms); \ + } while (0); + +#define VALUE_SYM(name) "_thread_" #name "_value" +#define LOOKUP_VALUE(name) \ + do { \ + ms = lookup_minimal_symbol (VALUE_SYM(name), NULL, objfile); \ + if (!ms) \ + return; \ + P_thread_##name##_value = SYMBOL_VALUE_ADDRESS (ms); \ + } while (0); + + LOOKUP_OFFSET(next); + LOOKUP_OFFSET(uniqueid); + LOOKUP_OFFSET(state); + LOOKUP_OFFSET(name); + LOOKUP_OFFSET(ctx); + + LOOKUP_VALUE(PS_RUNNING); + LOOKUP_VALUE(PS_DEAD); + + freebsd_uthread_active = 1; +} + +/* Clean up after the inferior dies. */ + +static void +freebsd_uthread_mourn_inferior () +{ + child_ops.to_mourn_inferior (); + unpush_target (&freebsd_uthread_ops); +} + +/* Mark our target-struct as eligible for stray "run" and "attach" commands. */ + +static int +freebsd_uthread_can_run () +{ + return child_suppress_run; +} + +static int +freebsd_uthread_thread_alive (ptid_t ptid) +{ + struct cached_pthread *thread; + int ret = 0; + + if (freebsd_uthread_attaching) + return 1; + + /* + * We can get called from child_ops.to_wait() which passes the underlying + * pid (without a thread number). + */ + if (TIDGET(ptid) == 0) + return 1; + + if (find_pthread_addr (ptid) != 0) + { + thread = find_pthread (ptid); + ret = (thread->state != PS_DEAD_value); + } + + if (!ret) + free_ptid(ptid); + + return ret; +} + +static void +freebsd_uthread_stop (void) +{ + child_ops.to_stop (); +} + +static void +freebsd_uthread_find_new_threads (void) +{ + CORE_ADDR ptr; + int state; + u_int64_t uniqueid; + + read_memory ((CORE_ADDR)P_thread_list, + (char *)&ptr, + sizeof ptr); + + while (ptr != 0) + { + READ_FIELD(ptr, int, state, state); + READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid); + if (state != PS_DEAD_value && + !in_thread_list (find_ptid(uniqueid))) + add_thread (find_ptid(uniqueid)); + ptr = read_pthread_next(ptr); + } +} + +/* MUST MATCH enum pthread_state */ +static const char *statenames[] = { + "RUNNING", + "SIGTHREAD", + "MUTEX_WAIT", + "COND_WAIT", + "FDLR_WAIT", + "FDLW_WAIT", + "FDR_WAIT", + "FDW_WAIT", + "POLL_WAIT", + "FILE_WAIT", + "SELECT_WAIT", + "SLEEP_WAIT", + "WAIT_WAIT", + "SIGSUSPEND", + "SIGWAIT", + "SPINBLOCK", + "JOIN", + "SUSPENDED", + "DEAD", + "DEADLOCK", +}; + +#if 0 + +static int +freebsd_uthread_get_thread_info (ref, selection, info) + gdb_threadref *ref; + int selection; + struct gdb_ext_thread_info *info; +{ + int pid = *ref; + struct cached_pthread *thread = find_pthread (pid); + struct cleanup *old_chain; + + old_chain = save_inferior_pid (); + inferior_pid = main_pid; + + memset(&info->threadid, 0, OPAQUETHREADBYTES); + + memcpy(&info->threadid, ref, sizeof *ref); + info->active = thread->state == PS_RUNNING_value; + strcpy(info->display, statenames[thread->state]); + if (thread->name) + read_memory ((CORE_ADDR) thread->name, info->shortname, 32); + else + strcpy(info->shortname, ""); + + do_cleanups (old_chain); + return (0); +} + +#endif + +char * +freebsd_uthread_pid_to_str (ptid_t ptid) +{ + static char buf[30]; + + if (DEPRECATED_STREQ (current_target.to_shortname, "freebsd-uthreads")) + sprintf (buf, "Process %d, Thread %ld", + PIDGET(ptid), TIDGET(ptid)); + else + sprintf (buf, "Process %d", PIDGET(ptid)); + + return buf; +} + + +static void +init_freebsd_uthread_ops () +{ + freebsd_uthread_ops.to_shortname = "freebsd-uthreads"; + freebsd_uthread_ops.to_longname = "FreeBSD uthreads"; + freebsd_uthread_ops.to_doc = "FreeBSD user threads support."; + freebsd_uthread_ops.to_open = freebsd_uthread_open; + freebsd_uthread_ops.to_attach = freebsd_uthread_attach; + freebsd_uthread_ops.to_post_attach = freebsd_uthread_post_attach; + freebsd_uthread_ops.to_detach = freebsd_uthread_detach; + freebsd_uthread_ops.to_resume = freebsd_uthread_resume; + freebsd_uthread_ops.to_wait = freebsd_uthread_wait; + freebsd_uthread_ops.to_fetch_registers = freebsd_uthread_fetch_registers; + freebsd_uthread_ops.to_store_registers = freebsd_uthread_store_registers; + freebsd_uthread_ops.to_prepare_to_store = freebsd_uthread_prepare_to_store; + freebsd_uthread_ops.to_xfer_memory = freebsd_uthread_xfer_memory; + freebsd_uthread_ops.to_files_info = freebsd_uthread_files_info; + freebsd_uthread_ops.to_insert_breakpoint = memory_insert_breakpoint; + freebsd_uthread_ops.to_remove_breakpoint = memory_remove_breakpoint; + freebsd_uthread_ops.to_terminal_init = terminal_init_inferior; + freebsd_uthread_ops.to_terminal_inferior = terminal_inferior; + freebsd_uthread_ops.to_terminal_ours_for_output = terminal_ours_for_output; + freebsd_uthread_ops.to_terminal_ours = terminal_ours; + freebsd_uthread_ops.to_terminal_info = child_terminal_info; + freebsd_uthread_ops.to_kill = freebsd_uthread_kill_inferior; + freebsd_uthread_ops.to_create_inferior = freebsd_uthread_create_inferior; + freebsd_uthread_ops.to_mourn_inferior = freebsd_uthread_mourn_inferior; + freebsd_uthread_ops.to_can_run = freebsd_uthread_can_run; + freebsd_uthread_ops.to_notice_signals = freebsd_uthread_notice_signals; + freebsd_uthread_ops.to_thread_alive = freebsd_uthread_thread_alive; + freebsd_uthread_ops.to_stop = freebsd_uthread_stop; + freebsd_uthread_ops.to_stratum = process_stratum; + freebsd_uthread_ops.to_has_all_memory = 1; + freebsd_uthread_ops.to_has_memory = 1; + freebsd_uthread_ops.to_has_stack = 1; + freebsd_uthread_ops.to_has_registers = 1; + freebsd_uthread_ops.to_has_execution = 1; + freebsd_uthread_ops.to_has_thread_control = 0; + freebsd_uthread_ops.to_magic = OPS_MAGIC; + freebsd_uthread_ops.to_find_new_threads = freebsd_uthread_find_new_threads; + freebsd_uthread_ops.to_pid_to_str = freebsd_uthread_pid_to_str; +#if 0 + freebsd_uthread_vec.get_thread_info = freebsd_uthread_get_thread_info; +#endif +} + +void +_initialize_freebsd_uthread () +{ + init_freebsd_uthread_ops (); + add_target (&freebsd_uthread_ops); + + target_new_objfile_chain = deprecated_target_new_objfile_hook; + deprecated_target_new_objfile_hook = freebsd_uthread_new_objfile; + + child_suppress_run = 1; +} diff --git a/devel/gdb66/files/kvm-fbsd.c b/devel/gdb66/files/kvm-fbsd.c new file mode 100644 index 0000000..ad64dd9 --- /dev/null +++ b/devel/gdb66/files/kvm-fbsd.c @@ -0,0 +1,886 @@ +/* Kernel core dump functions below target vector, for GDB. + Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 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. +*/ + +/* $FreeBSD$ */ + +/* + * This works like "remote" but, you use it like this: + * target kcore /dev/mem + * or + * target kcore /var/crash/host/core.0 + * + * This way makes it easy to short-circut the whole bfd monster, + * and direct the inferior stuff to our libkvm implementation. + * + */ + +#include <sys/param.h> +#include <machine/frame.h> +#include <sys/proc.h> +#include <sys/sysctl.h> +#include <sys/time.h> +#include <sys/user.h> + +#include <ctype.h> +#include <errno.h> +#include <signal.h> +#include <fcntl.h> +#include <kvm.h> +#include <paths.h> + +#include "defs.h" +#include "gdb_string.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 "regcache.h" +#include <readline/tilde.h> + +#if __FreeBSD_version >= 500032 +static void +kcore_files_info (struct target_ops *); + +static void +kcore_close (int); + +static void +get_kcore_registers (int); + + + /* +static int +xfer_mem (CORE_ADDR, char *, int, int, struct mem_attrib *, + struct target_ops *); + */ + +static int +xfer_umem (CORE_ADDR, char *, int, int); + +static char *core_file; +static kvm_t *core_kd; +static struct pcb cur_pcb; +static struct kinfo_proc *cur_proc; + +static struct target_ops kcore_ops; + +int kernel_debugging; +int kernel_writablecore; + +/* 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)))) + +static CORE_ADDR +ksym_kernbase (void) +{ + static CORE_ADDR kernbase; + struct minimal_symbol *sym; + + if (kernbase == 0) + { + sym = lookup_minimal_symbol ("kernbase", NULL, NULL); + if (sym == NULL) { + kernbase = KERNBASE; + } else { + kernbase = SYMBOL_VALUE_ADDRESS (sym); + } + } + return kernbase; +} + +#define KERNOFF (ksym_kernbase ()) +#define INKERNEL(x) ((x) >= KERNOFF) + +CORE_ADDR +ksym_lookup(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); +} + +/* Provide the address of an initial PCB to use. + If this is a crash dump, try for "dumppcb". + If no "dumppcb" or it's /dev/mem, use proc0. + Return the core address of the PCB we found. */ + +static CORE_ADDR +initial_pcb (void) +{ + struct minimal_symbol *sym; + CORE_ADDR addr; + void *val; + + /* Make sure things are open... */ + if (!core_kd || !core_file) + return (0); + + /* If this is NOT /dev/mem try for dumppcb. */ + if (strncmp (core_file, _PATH_DEV, sizeof _PATH_DEV - 1)) + { + sym = lookup_minimal_symbol ("dumppcb", NULL, NULL); + if (sym != NULL) + { + addr = SYMBOL_VALUE_ADDRESS (sym); + return (addr); + } + } + + /* OK, just use thread0's pcb. Note that curproc might + not exist, and if it does, it will point to gdb. + Therefore, just use proc0 and let the user set + some other context if they care about it. */ + + addr = ksym_lookup ("thread0"); + if (kvread (addr, &val)) + { + error ("cannot read thread0 pointer at %lx\n", addr); + val = 0; + } + else + { + /* Read the PCB address in thread structure. */ + addr += offsetof (struct thread, td_pcb); + if (kvread (addr, &val)) + { + error ("cannot read thread0->td_pcb pointer at %lx\n", addr); + val = 0; + } + } + + /* thread0 is wholly in the kernel and cur_proc is only used for + reading user mem, so no point in setting this up. */ + cur_proc = 0; + + return ((CORE_ADDR)val); +} + +/* Set the current context to that of the PCB struct at the system address + passed. */ + +static int +set_context (CORE_ADDR addr) +{ + CORE_ADDR procaddr = 0; + + if (kvread (addr, &cur_pcb)) + error ("cannot read pcb at %#lx", addr); + + /* 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 (); +/*DEO XXX + set_current_frame (create_new_frame (read_fp (), read_pc ())); + set_current_frame (create_new_frame (deprecated_read_fp (), read_pc ())); + select_frame (get_current_frame ()); +*/ + print_stack_frame (get_selected_frame (), -1, 1); + return (0); +} + +/* Discard all vestiges of any previous core file and mark data and stack + spaces as empty. */ + +/* ARGSUSED */ +static void +kcore_close (int quitting) +{ + + inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */ + + if (core_kd) + { + kvm_close (core_kd); + free (core_file); + core_file = NULL; + core_kd = NULL; + } +} + +/* This routine opens and sets up the core file bfd. */ + +static void +kcore_open (char *filename /* the core file */, int from_tty) +{ + kvm_t *kd; + const char *p; + struct cleanup *old_chain; + char buf[256], *cp; + int ontop; + CORE_ADDR addr; + + target_preopen (from_tty); + + /* The exec file is required for symbols. */ + if (exec_bfd == NULL) + error ("No kernel exec file specified"); + + if (core_kd) + { + error ("No core file specified." + " (Use `detach' to stop debugging a core file.)"); + return; + } + + if (!filename) + { + error ("No core file specified."); + return; + } + + filename = tilde_expand (filename); + if (filename[0] != '/') + { + cp = concat (current_directory, "/", filename, NULL); + free (filename); + filename = cp; + } + + old_chain = make_cleanup (free, filename); + + kd = kvm_open (bfd_get_filename(exec_bfd), filename, NULL, + kernel_writablecore ? O_RDWR: O_RDONLY, 0); + if (kd == NULL) + { + perror_with_name (filename); + return; + } + + /* 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; + unpush_target (&kcore_ops); + ontop = !push_target (&kcore_ops); + + /* Note unpush_target (above) calls kcore_close. */ + core_kd = kd; + + /* 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_filtered ("panic: %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; + } + + /* Now, set up process context, and print the top of stack. */ + (void)set_context (initial_pcb()); + print_stack_frame (get_selected_frame (), + frame_relative_level (get_selected_frame ()), 1); +} + +static void +kcore_detach (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"); +} + +#ifdef __alpha__ + +#include "alpha/tm-alpha.h" +#include "alpha-tdep.h" + +#ifndef S0_REGNUM +#define S0_REGNUM (ALPHA_T7_REGNUM+1) +#endif + +static void +fetch_kcore_registers (struct pcb *pcbp) +{ + + /* First clear out any garbage. */ + memset (deprecated_registers, '\0', DEPRECATED_REGISTER_BYTES); + + /* SP */ + *(long *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (SP_REGNUM)] = + pcbp->pcb_hw.apcb_ksp; + + /* S0 through S6 */ + memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (S0_REGNUM)], + &pcbp->pcb_context[0], 7 * sizeof (long)); + + /* PC */ + *(long *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)] = + pcbp->pcb_context[7]; + + deprecated_registers_fetched (); +} + + +CORE_ADDR +fbsd_kern_frame_saved_pc (struct frame_info *fi) +{ + struct minimal_symbol *sym; + CORE_ADDR this_saved_pc; + + this_saved_pc = DEPRECATED_FRAME_SAVED_PC(fi); + + sym = lookup_minimal_symbol_by_pc (this_saved_pc); + + if (sym != NULL && + (strcmp (DEPRECATED_SYMBOL_NAME (sym), "XentArith") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "XentIF") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "XentInt") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "XentMM") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "XentSys") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "XentUna") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "XentRestart") == 0)) + { + return (read_memory_integer (get_frame_base (fi) + 32 * 8, 8)); + } + else + { + return (this_saved_pc); + } +} + +#endif /* __alpha__ */ + +#ifdef __i386__ + +#include "i386-tdep.h" + +static CORE_ADDR +ksym_maxuseraddr (void) +{ + static CORE_ADDR maxuseraddr; + struct minimal_symbol *sym; + + if (maxuseraddr == 0) + { + sym = lookup_minimal_symbol ("PTmap", NULL, NULL); + if (sym == NULL) { + maxuseraddr = VM_MAXUSER_ADDRESS; + } else { + maxuseraddr = SYMBOL_VALUE_ADDRESS (sym); + } + } + return maxuseraddr; +} + + +/* Symbol names of kernel entry points. Use special frames. */ +#define KSYM_TRAP "calltrap" +#define KSYM_INTR "Xintr" +#define KSYM_FASTINTR "Xfastintr" +#define KSYM_OLDSYSCALL "Xlcall_syscall" +#define KSYM_SYSCALL "Xint0x80_syscall" + +/* 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 (struct frame_info *fi) +{ + struct minimal_symbol *sym; + CORE_ADDR this_saved_pc; + enum frametype frametype; + + this_saved_pc = read_memory_integer (get_frame_base (fi) + 4, 4); + sym = lookup_minimal_symbol_by_pc (this_saved_pc); + frametype = tf_normal; + if (sym != NULL) + { + if (strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_TRAP) == 0) + frametype = tf_trap; + else + if (strncmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_INTR, + strlen (KSYM_INTR)) == 0 || strncmp (DEPRECATED_SYMBOL_NAME(sym), + KSYM_FASTINTR, strlen (KSYM_FASTINTR)) == 0) + frametype = tf_interrupt; + else + if (strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_SYSCALL) == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_OLDSYSCALL) == 0) + frametype = tf_syscall; + } + + switch (frametype) + { + default: + case tf_normal: + return (this_saved_pc); +#define oEIP offsetof (struct trapframe, tf_eip) + + case tf_trap: + return (read_memory_integer (get_frame_base (fi) + 8 + oEIP, 4)); + + case tf_interrupt: + return (read_memory_integer (get_frame_base (fi) + 12 + oEIP, 4)); + + case tf_syscall: + return (read_memory_integer (get_frame_base (fi) + 8 + oEIP, 4)); +#undef oEIP + } +} + +static void +fetch_kcore_registers (struct pcb *pcb) +{ + int i; + int noreg; + + /* 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); + + /* DEO:XXX use SP_REGNUM and PC_REGNUM -- this is GDB_MULTI_ARCH */ + supply_register (3, (char *) &pcb->pcb_ebx); + supply_register (SP_REGNUM, (char *) &pcb->pcb_esp); + supply_register (I386_EBP_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? */ +} + +#endif /* __i386__ */ + +#ifdef __amd64__ + +#include "amd64-tdep.h" + +static CORE_ADDR +ksym_maxuseraddr (void) +{ + static CORE_ADDR maxuseraddr; + struct minimal_symbol *sym; + + if (maxuseraddr == 0) + { + sym = lookup_minimal_symbol ("PTmap", NULL, NULL); + if (sym == NULL) { + maxuseraddr = VM_MAXUSER_ADDRESS; + } else { + maxuseraddr = SYMBOL_VALUE_ADDRESS (sym); + } + } + return maxuseraddr; +} + + +/* Symbol names of kernel entry points. Use special frames. */ +#define KSYM_TRAP "calltrap" +#define KSYM_INTR "Xintr" +#define KSYM_FASTINTR "Xfastintr" +#define KSYM_OLDSYSCALL "Xlcall_syscall" +#define KSYM_SYSCALL "Xint0x80_syscall" + +/* 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 (struct frame_info *fi) +{ + struct minimal_symbol *sym; + CORE_ADDR this_saved_pc; + enum frametype frametype; + + this_saved_pc = read_memory_integer (get_frame_base (fi) + 4, 4); + sym = lookup_minimal_symbol_by_pc (this_saved_pc); + frametype = tf_normal; + if (sym != NULL) + { + if (strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_TRAP) == 0) + frametype = tf_trap; + else + if (strncmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_INTR, + strlen (KSYM_INTR)) == 0 || strncmp (DEPRECATED_SYMBOL_NAME(sym), + KSYM_FASTINTR, strlen (KSYM_FASTINTR)) == 0) + frametype = tf_interrupt; + else + if (strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_SYSCALL) == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_OLDSYSCALL) == 0) + frametype = tf_syscall; + } + + switch (frametype) + { + default: + case tf_normal: + return (this_saved_pc); +#define oEIP offsetof (struct trapframe, tf_rip) + + case tf_trap: + return (read_memory_integer (get_frame_base (fi) + 8 + oEIP, 4)); + + case tf_interrupt: + return (read_memory_integer (get_frame_base (fi) + 12 + oEIP, 4)); + + case tf_syscall: + return (read_memory_integer (get_frame_base (fi) + 8 + oEIP, 4)); +#undef oEIP + } +} + +static void +fetch_kcore_registers (struct pcb *pcb) +{ + int i; + int noreg; + + /* 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-amd64.h. + */ + noreg = 0; + for (i = 0; i < 3; ++i) /* eax,ecx,edx */ + supply_register (i, (char *)&noreg); + + /* DEO:XXX use SP_REGNUM and PC_REGNUM -- this is GDB_MULTI_ARCH */ + supply_register (3, (char *) &pcb->pcb_rbx); + supply_register (SP_REGNUM, (char *) &pcb->pcb_rsp); + supply_register (AMD64_RBP_REGNUM, (char *) &pcb->pcb_rbp); + supply_register (PC_REGNUM, (char *) &pcb->pcb_rip); + + for (i = 9; i < 14; ++i) /* rflags, cs, ss, ds, es, fs */ + supply_register (i, (char *) &noreg); + supply_register (15, (char *) &pcb->pcb_gs); + + /* XXX 80387 registers? */ +} + +#endif /* __amd64__ */ + +#ifdef __sparc64__ + +#include "sparc-tdep.h" + +#define SPARC_INTREG_SIZE 8 + +static void +fetch_kcore_registers (struct pcb *pcbp) +{ + static struct frame top; + CORE_ADDR f_addr; + int i; + + /* 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 do something with the floating-point registers? + */ + supply_register (SP_REGNUM, &pcbp->pcb_sp); + supply_register (PC_REGNUM, &pcbp->pcb_pc); + f_addr = extract_unsigned_integer (&pcbp->pcb_sp, SPARC_INTREG_SIZE); + /* Load the previous frame by hand (XXX) and supply it. */ + read_memory (f_addr + SPOFF, (char *)&top, sizeof (top)); + for (i = 0; i < 8; i++) + supply_register (i + SPARC_L0_REGNUM, &top.fr_local[i]); + for (i = 0; i < 8; i++) + supply_register (i + SPARC_I0_REGNUM, &top.fr_in[i]); +} + +CORE_ADDR +fbsd_kern_frame_saved_pc (struct frame_info *fi) +{ + struct minimal_symbol *sym; + CORE_ADDR frame, pc_addr, pc; + char *buf; + + buf = alloca (MAX_REGISTER_SIZE); //or use DEPRECATED_MAX_REGISTER_RAW_SIZE + /* XXX: duplicates fi->extra_info->bottom. */ + frame = (get_next_frame (fi) != NULL) ? get_frame_base (get_next_frame (fi)) : read_sp (); + pc_addr = frame + offsetof (struct frame, fr_in[7]); + +#define READ_PC(pc, a, b) do { \ + read_memory (a, b, SPARC_INTREG_SIZE); \ + pc = extract_unsigned_integer (b, SPARC_INTREG_SIZE); \ +} while (0) + + READ_PC (pc, pc_addr, buf); + + sym = lookup_minimal_symbol_by_pc (pc); + if (sym != NULL) + { + if (strncmp (DEPRECATED_SYMBOL_NAME (sym), "tl0_", 4) == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "btext") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "mp_startup") == 0 || + strcmp (DEPRECATED_SYMBOL_NAME (sym), "fork_trampoline") == 0) + { + /* + * Ugly kluge: user space addresses aren't separated from kernel + * ones by range; if encountering a trap from user space, just + * return a 0 to stop the trace. + * Do the same for entry points of kernel processes to avoid + * printing garbage. + */ + pc = 0; + } + if (strncmp (DEPRECATED_SYMBOL_NAME (sym), "tl1_", 4) == 0) + { + pc_addr = get_frame_base (fi) + sizeof (struct frame) + + offsetof (struct trapframe, tf_tpc); + READ_PC (pc, pc_addr, buf); + } + } + return (pc); +} + +#endif /* __sparc64__ */ + +/* 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 (int regno) +{ + + /* XXX - Only read the pcb when set_context() is called. + When looking at a live kernel this may be a problem, + but the user can do another "proc" or "pcb" command to + grab a new copy of the pcb... */ + + /* Zero out register set then fill in the ones we know about. */ + fetch_kcore_registers (&cur_pcb); +} + +static void +kcore_files_info (t) + struct target_ops *t; +{ + printf_filtered ("\t`%s'\n", core_file); +} + +/* If mourn is being called in all the right places, this could be say + `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */ + + /* +static int +ignore (CORE_ADDR addr, char *contents) +{ + return 0; +} + */ + +static int +xfer_kmem (CORE_ADDR memaddr, char *myaddr, int len, int write, + struct mem_attrib *attrib, struct target_ops *target) +{ + int n; + + + if (!INKERNEL (memaddr)) + return xfer_umem (memaddr, myaddr, len, write); + + if (core_kd == NULL) + return 0; + + if (write) + n = kvm_write (core_kd, memaddr, myaddr, len); + else + n = kvm_read (core_kd, memaddr, myaddr, len) ; + if (n < 0) { + fprintf_unfiltered (gdb_stderr, "can not access 0x%lx, %s\n", + memaddr, kvm_geterr (core_kd)); + n = 0; + } + + return n; +} + + +static int +xfer_umem (CORE_ADDR memaddr, char *myaddr, int len, int write /* ignored */) +{ + int n = 0; + + if (cur_proc == 0) + { + error ("---Can't read userspace from dump, or kernel process---\n"); + return 0; + } + + if (write) + error ("kvm_uwrite unimplemented\n"); + else + n = kvm_uread (core_kd, cur_proc, memaddr, myaddr, len) ; + + if (n < 0) + return 0; + + return n; +} + +static void +set_proc_cmd (char *arg, int from_tty) +{ + CORE_ADDR addr, pid_addr, first_td; + void *val; + struct kinfo_proc *kp; + int cnt; + pid_t pid; + + if (!arg) + error_no_arg ("proc address for the new context"); + + if (core_kd == NULL) + error ("no kernel core file"); + + addr = (CORE_ADDR) parse_and_eval_address (arg); + + if (!INKERNEL (addr)) + { + kp = kvm_getprocs (core_kd, KERN_PROC_PID, addr, &cnt); + if (!cnt) + error ("invalid pid"); + addr = (CORE_ADDR)kp->ki_paddr; + cur_proc = kp; + } + else + { + /* Update cur_proc. */ + pid_addr = addr + offsetof (struct proc, p_pid); + if (kvread (pid_addr, &pid)) + error ("cannot read pid ptr"); + cur_proc = kvm_getprocs (core_kd, KERN_PROC_PID, pid, &cnt); + if (!cnt) + error("invalid pid"); + } + + /* Find the first thread in the process. XXXKSE */ + addr += offsetof (struct proc, p_threads.tqh_first); + if (kvread (addr, &first_td)) + error ("cannot read thread ptr"); + + /* Read the PCB address in thread structure. */ + addr = first_td + offsetof (struct thread, td_pcb); + if (kvread (addr, &val)) + error("cannot read pcb ptr"); + + /* Read the PCB address in proc structure. */ + if (set_context ((CORE_ADDR) val)) + error ("invalid proc address"); +} +#else +int kernel_debugging = 0; +int kernel_writablecore = 0; + +CORE_ADDR +fbsd_kern_frame_saved_pc (struct frame_info *fi) +{ + return 0; +} +#endif + +void +_initialize_kcorelow (void) +{ +#if __FreeBSD_version >= 500032 + kcore_ops.to_shortname = "kcore"; + kcore_ops.to_longname = "Kernel core dump file"; + kcore_ops.to_doc = + "Use a core file as a target. Specify the filename of the core file."; + kcore_ops.to_open = kcore_open; + kcore_ops.to_close = kcore_close; + kcore_ops.to_attach = find_default_attach; + kcore_ops.to_detach = kcore_detach; + kcore_ops.to_fetch_registers = get_kcore_registers; + kcore_ops.to_xfer_memory = xfer_kmem; + kcore_ops.to_files_info = kcore_files_info; + kcore_ops.to_create_inferior = find_default_create_inferior; + kcore_ops.to_stratum = kcore_stratum; + kcore_ops.to_has_memory = 1; + kcore_ops.to_has_stack = 1; + kcore_ops.to_has_registers = 1; + kcore_ops.to_magic = OPS_MAGIC; + + add_target (&kcore_ops); + add_com ("proc", class_obscure, set_proc_cmd, "Set current process context"); +#endif +} diff --git a/devel/gdb66/files/nm-fbsd.h b/devel/gdb66/files/nm-fbsd.h new file mode 100644 index 0000000..b0d784f --- /dev/null +++ b/devel/gdb66/files/nm-fbsd.h @@ -0,0 +1,39 @@ +#ifndef CONFIG_NM_FBSD_H +#define CONFIG_NM_FBSD_H + +/* $FreeBSD$ */ + +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif + +extern int kernel_debugging; +extern int kernel_writablecore; + +CORE_ADDR fbsd_kern_frame_saved_pc(struct frame_info *frame); + +#if __FreeBSD_version >= 500032 +#define KGDB 1 +#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\ +" + +#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 +#endif /* CONFIG_NM_FBSD_H */ diff --git a/devel/gdb66/files/patch-Makefile.in b/devel/gdb66/files/patch-Makefile.in new file mode 100644 index 0000000..33ed469 --- /dev/null +++ b/devel/gdb66/files/patch-Makefile.in @@ -0,0 +1,11 @@ +--- gdb/Makefile.in.orig Fri Oct 17 14:44:26 2003 ++++ gdb/Makefile.in Thu Jan 15 11:41:06 2004 +@@ -119,4 +119,4 @@ +-READLINE_DIR = ../readline +-READLINE = $(READLINE_DIR)/libreadline.a +-READLINE_SRC = $(srcdir)/$(READLINE_DIR) +-READLINE_CFLAGS = -I$(READLINE_SRC)/.. ++#READLINE_DIR = ../readline ++READLINE = -lreadline ++#READLINE_SRC = $(srcdir)/$(READLINE_DIR) ++#READLINE_CFLAGS = -I$(READLINE_SRC)/.. diff --git a/devel/gdb66/files/patch-amd64-tdep.c b/devel/gdb66/files/patch-amd64-tdep.c new file mode 100644 index 0000000..88305cc --- /dev/null +++ b/devel/gdb66/files/patch-amd64-tdep.c @@ -0,0 +1,15 @@ +--- gdb/amd64-tdep.c.orig Fri Apr 9 16:24:05 2004 ++++ gdb/amd64-tdep.c Wed May 5 10:56:22 2004 +@@ -126,6 +126,12 @@ + #define AMD64_NUM_REGS \ + (sizeof (amd64_register_info) / sizeof (amd64_register_info[0])) + ++int ++amd64_num_regs(void) ++{ ++ return AMD64_NUM_REGS; ++} ++ + /* Return the name of register REGNUM. */ + + static const char * diff --git a/devel/gdb66/files/patch-amd64-tdep.h b/devel/gdb66/files/patch-amd64-tdep.h new file mode 100644 index 0000000..2ad0170 --- /dev/null +++ b/devel/gdb66/files/patch-amd64-tdep.h @@ -0,0 +1,16 @@ +--- gdb/amd64-tdep.h.orig Wed May 5 10:48:28 2004 ++++ gdb/amd64-tdep.h Wed May 5 11:02:33 2004 +@@ -59,6 +59,13 @@ + /* Number of general purpose registers. */ + #define AMD64_NUM_GREGS 24 + ++#define AMD64_NUM_FREGS 16 ++#define AMD64_NUM_XREGS 17 ++#define AMD64_NUM_REGS_TOTAL (AMD64_NUM_GREGS + AMD64_NUM_FREGS \ ++ + AMD64_NUM_XREGS) ++ ++extern int amd64_num_regs (void); ++ + extern void amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch); + + /* Fill register REGNUM in REGCACHE with the appropriate diff --git a/devel/gdb66/files/patch-config_alpha_nm-fbsd.h b/devel/gdb66/files/patch-config_alpha_nm-fbsd.h index d364e03c..2f7e710 100644 --- a/devel/gdb66/files/patch-config_alpha_nm-fbsd.h +++ b/devel/gdb66/files/patch-config_alpha_nm-fbsd.h @@ -1,11 +1,10 @@ ---- gdb/config/alpha/nm-fbsd.h Tue Mar 6 00:21:21 2001 -+++ gdb/config/alpha/nm-fbsd.h Sun Oct 13 12:23:51 2002 -@@ -22,6 +22,8 @@ - #ifndef NM_FBSD_H - #define NM_FBSD_H +--- gdb/config/alpha/nm-fbsd.h.orig Sat Mar 13 05:07:19 2004 ++++ gdb/config/alpha/nm-fbsd.h Sat Apr 10 00:49:21 2004 +@@ -25,6 +25,7 @@ + /* Get generic BSD native definitions. */ + #include "config/nm-bsd.h" +#include "config/nm-fbsd.h" -+ - /* Type of the third argument to the `ptrace' system call. */ - #define PTRACE_ARG3_TYPE caddr_t + /* The Alpha does not step over a breakpoint. */ + #define CANNOT_STEP_BREAKPOINT 1 diff --git a/devel/gdb66/files/patch-config_i386_fbsd.mh b/devel/gdb66/files/patch-config_i386_fbsd.mh index b9645a9..2215bd7 100644 --- a/devel/gdb66/files/patch-config_i386_fbsd.mh +++ b/devel/gdb66/files/patch-config_i386_fbsd.mh @@ -1,10 +1,10 @@ ---- gdb/config/i386/fbsd.mh Sat May 11 10:22:27 2002 -+++ gdb/config/i386/fbsd.mh Sun Oct 13 11:50:47 2002 -@@ -4,4 +4,6 @@ - +--- gdb/config/i386/fbsd.mh.orig Sun Feb 22 08:20:22 2004 ++++ gdb/config/i386/fbsd.mh Sat Apr 10 01:00:26 2004 +@@ -3,3 +3,7 @@ + i386-nat.o i386bsd-nat.o i386fbsd-nat.o gcore.o fbsd-proc.o NAT_FILE= nm-fbsd.h - # NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make. --NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o core-aout.o core-regset.o i386-nat.o i386bsd-nat.o i386fbsd-nat.o gcore.o fbsd-proc.o -+NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o core-aout.o core-regset.o i386-nat.o i386bsd-nat.o i386fbsd-nat.o gcore.o fbsd-proc.o kvm-fbsd.o freebsd-uthread.o + XM_FILE= xm-i386.h + ++# kgdb support ++NATDEPFILES+= kvm-fbsd.o freebsd-uthread.o +NAT_CLIBS= -lkvm diff --git a/devel/gdb66/files/patch-config_i386_fbsd64.mh b/devel/gdb66/files/patch-config_i386_fbsd64.mh new file mode 100644 index 0000000..ee00c31 --- /dev/null +++ b/devel/gdb66/files/patch-config_i386_fbsd64.mh @@ -0,0 +1,10 @@ +--- gdb/config/i386/fbsd64.mh.orig Sun Feb 22 08:20:22 2004 ++++ gdb/config/i386/fbsd64.mh Fri Apr 23 12:28:40 2004 +@@ -3,3 +3,7 @@ + amd64-nat.o amd64bsd-nat.o amd64fbsd-nat.o gcore.o fbsd-proc.o + NAT_FILE= nm-fbsd64.h + XM_FILE= xm-i386.h ++ ++# kgdb support ++NATDEPFILES+= kvm-fbsd.o freebsd-uthread.o ++NAT_CLIBS= -lkvm diff --git a/devel/gdb66/files/patch-config_i386_nm-fbsd.h b/devel/gdb66/files/patch-config_i386_nm-fbsd.h index efd2ce2..781f069 100644 --- a/devel/gdb66/files/patch-config_i386_nm-fbsd.h +++ b/devel/gdb66/files/patch-config_i386_nm-fbsd.h @@ -1,10 +1,12 @@ ---- gdb/config/i386/nm-fbsd.h Fri Jun 28 11:44:49 2002 -+++ gdb/config/i386/nm-fbsd.h Sun Oct 13 10:53:27 2002 -@@ -26,6 +26,7 @@ +--- gdb/config/i386/nm-fbsd.h.orig Fri Jun 28 11:44:49 2002 ++++ gdb/config/i386/nm-fbsd.h Sun Jan 18 20:50:33 2004 +@@ -26,6 +26,9 @@ #define I386_USE_GENERIC_WATCHPOINTS #endif ++/* Get generic FreeBSD native definitions. */ +#include "config/nm-fbsd.h" ++ #include "i386/nm-i386.h" #ifdef HAVE_SYS_PARAM_H diff --git a/devel/gdb66/files/patch-config_nm-fbsd.h b/devel/gdb66/files/patch-config_nm-fbsd.h deleted file mode 100644 index 9b6c033..0000000 --- a/devel/gdb66/files/patch-config_nm-fbsd.h +++ /dev/null @@ -1,39 +0,0 @@ ---- gdb/config/nm-fbsd.h Fri Jan 3 09:33:00 2003 -+++ gdb/config/nm-fbsd.h Fri Jan 3 09:36:00 2003 -@@ -0,0 +1,36 @@ -+#ifndef CONFIG_NM_FBSD_H -+#define CONFIG_NM_FBSD_H -+ -+#ifdef HAVE_SYS_PARAM_H -+#include <sys/param.h> -+#endif -+ -+extern int kernel_debugging; -+extern int kernel_writablecore; -+ -+CORE_ADDR fbsd_kern_frame_saved_pc(struct frame_info *frame); -+ -+#if __FreeBSD_version >= 500032 -+#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\ -+" -+ -+#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 -+#endif /* CONFIG_NM_FBSD_H */ diff --git a/devel/gdb66/files/patch-config_sparc_fbsd.mh b/devel/gdb66/files/patch-config_sparc_fbsd.mh index 1a23ca9..c9c6de6 100644 --- a/devel/gdb66/files/patch-config_sparc_fbsd.mh +++ b/devel/gdb66/files/patch-config_sparc_fbsd.mh @@ -1,13 +1,12 @@ ---- gdb/config/sparc/fbsd.mh.orig Wed Mar 13 03:20:24 2002 -+++ gdb/config/sparc/fbsd.mh Thu Oct 17 05:59:25 2002 -@@ -19,7 +19,7 @@ - # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - # Host: FreeBSD/sparc64 --NATDEPFILES= sparc-nat.o \ -- corelow.o fork-child.o infptrace.o inftarg.o \ -- solib.o solib-svr4.o solib-legacy.o -+NATDEPFILES= fork-child.o infptrace.o inftarg.o sparc64nbsd-nat.o \ -+ solib.o solib-svr4.o solib-legacy.o kvm-fbsd.o +--- gdb/config/sparc/fbsd.mh.orig Tue Mar 12 19:20:24 2002 ++++ gdb/config/sparc/fbsd.mh Tue Jan 20 08:28:50 2004 +@@ -23,3 +23,9 @@ + corelow.o fork-child.o infptrace.o inftarg.o \ + solib.o solib-svr4.o solib-legacy.o NAT_FILE= nm-fbsd.h ++ ++# kgdb support ++NATDEPFILES+= kvm-fbsd.o freebsd-uthread.o +NAT_CLIBS= -lkvm ++# /proc support ++NATDEPFILES+= fbsd-proc.o # sparc-linux-nat.o diff --git a/devel/gdb66/files/patch-config_sparc_fbsd.mt b/devel/gdb66/files/patch-config_sparc_fbsd.mt index 3147c4e..a76e2c5 100644 --- a/devel/gdb66/files/patch-config_sparc_fbsd.mt +++ b/devel/gdb66/files/patch-config_sparc_fbsd.mt @@ -1,10 +1,7 @@ ---- gdb/config/sparc/fbsd.mt.orig Wed Mar 13 03:20:24 2002 -+++ gdb/config/sparc/fbsd.mt Thu Oct 17 05:59:59 2002 -@@ -19,5 +19,6 @@ - # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - +--- gdb/config/sparc/fbsd.mt.orig Sat Jan 3 02:08:45 2004 ++++ gdb/config/sparc/fbsd.mt Sat Jan 24 20:10:22 2004 +@@ -1,3 +1,4 @@ # Target: FreeBSD/sparc64 --TDEPFILES= sparc-tdep.o solib.o solib-svr4.o solib-legacy.o -+TDEPFILES= sparc-tdep.o sparcnbsd-tdep.o nbsd-tdep.o corelow.o solib.o \ -+ solib-svr4.o solib-legacy.o + TDEPFILES= sparc-tdep.o sparc64-tdep.o sparc64fbsd-tdep.o corelow.o ++###TDEPFILES+= sparcnbsd-tdep.o nbsd-tdep.o solib.o solib-svr4.o solib-legacy.o TM_FILE= tm-fbsd.h diff --git a/devel/gdb66/files/patch-config_sparc_nm-fbsd.h b/devel/gdb66/files/patch-config_sparc_nm-fbsd.h index 4ab0b5a..f5e005f 100644 --- a/devel/gdb66/files/patch-config_sparc_nm-fbsd.h +++ b/devel/gdb66/files/patch-config_sparc_nm-fbsd.h @@ -1,72 +1,33 @@ ---- gdb/config/sparc/nm-fbsd.h.orig Fri Mar 1 18:35:24 2002 -+++ gdb/config/sparc/nm-fbsd.h Tue Oct 22 16:33:14 2002 -@@ -32,36 +32,45 @@ - #define ATTACH_DETACH - +--- gdb/config/sparc/nm-fbsd.h.orig Sat Mar 13 05:07:20 2004 ++++ gdb/config/sparc/nm-fbsd.h Sat Apr 10 01:06:19 2004 +@@ -24,9 +24,30 @@ --/* Shared library support. */ -+#include "regcache.h" -+ -+/* Get generic FreeBSD native definitions. */ -+ + /* Get generic BSD native definitions. */ + #include "config/nm-bsd.h" ++/* Get generic FreeBSD native definitions. */ +#include "config/nm-fbsd.h" -+ -+/* Shared library support. */ - #define SVR4_SHARED_LIBS + /* Shared library support. */ - #include "solib.h" /* Support for shared libraries. */ - #include "elf/common.h" /* Additional ELF shared library info. */ - --/* Make things match up with what is expected in sparc-nat.c. */ -+/* Before storing, we need to read all the registers. */ + #include "solib.h" + -+#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES) ++/* Override child_pid_to_exec_file in 'inftarg.c'. */ ++#define CHILD_PID_TO_EXEC_FILE + -+#define REG32_OFFSET_GLOBAL (0) -+#define REG32_OFFSET_OUT (32) -+#define REG32_OFFSET_NPC (96) -+#define REG32_OFFSET_PC (100) -+#define REG32_OFFSET_PSR (104) -+#define REG32_OFFSET_Y (112) -+#define REG32_SIZE (128) -+#define FPREG32_SIZE (136) ++/* FreeBSD has a /proc. */ ++#define USE_PROC_FS + -+#define REG64_OFFSET_GLOBAL (0) -+#define REG64_OFFSET_OUT (64) -+#define REG64_OFFSET_NPC (192) -+#define REG64_OFFSET_PC (200) -+#define REG64_OFFSET_TSTATE (208) -+#define REG64_OFFSET_Y (224) -+#define REG64_SIZE (256) -+#define FPREG64_SIZE (272) ++/* DEO:XXX where did the rest of this file go vs 6.0.0.90 ?? */ + -+#define JB32_OFFSET_PC REG32_OFFSET_PC -+#define JB64_OFFSET_PC REG64_OFFSET_PC - --#define PTRACE_GETREGS PT_GETREGS --#define PTRACE_SETREGS PT_SETREGS --#define PTRACE_GETFPREGS PT_GETFPREGS --#define PTRACE_SETFPREGS PT_SETFPREGS -- --#define GDB_GREGSET_T struct reg --#define GDB_FPREGSET_T struct fpreg -- --#define regs trapframe --#define r_g1 tf_global[1] --#define r_ps tf_tstate --#define r_pc tf_tpc --#define r_npc tf_tnpc --#define r_y tf_y -- --#define FPU_FSR_TYPE unsigned long --#define fp_status fpreg /* our reg.h */ --#define fpu fpreg /* our reg.h */ --#define fpu_regs fr_regs /* one field of fpu_fr on Solaris */ --#define fpu_fr fr_regs /* a union w/in struct fpu on Solaris */ --#define fpu_fsr fr_fsr --#define Fpu_fsr fr_fsr -+#define reg64 reg -+#define fpreg64 fpreg ++/* Solaris compatability. */ ++#define R_PC r_pc ++#define R_nPC r_npc ++#define R_Y r_y ++#define R_I7 /* ?? */ ++#define pr_fr fpu_fr ++#define pr_fsr fpu_fsr ++#define regp /* ?? */ ++#if 0 ++#endif - #endif /* NM_FBSD_H */ + #endif /* nm-fbsd.h */ diff --git a/devel/gdb66/files/patch-config_sparc_tm-fbsd.h b/devel/gdb66/files/patch-config_sparc_tm-fbsd.h index 4e15435..ccca904 100644 --- a/devel/gdb66/files/patch-config_sparc_tm-fbsd.h +++ b/devel/gdb66/files/patch-config_sparc_tm-fbsd.h @@ -1,17 +1,12 @@ ---- gdb/config/sparc/tm-fbsd.h.orig Fri Mar 1 18:35:24 2002 -+++ gdb/config/sparc/tm-fbsd.h Thu Oct 17 06:01:10 2002 -@@ -22,13 +22,7 @@ - #define TM_FBSD_H +--- gdb/config/sparc/tm-fbsd.h.orig Sat Jan 24 20:06:31 2004 ++++ gdb/config/sparc/tm-fbsd.h Sat Jan 24 20:07:02 2004 +@@ -24,4 +24,9 @@ - #define SVR4_SHARED_LIBS -+#include "sparc/tm-sp64.h" /* sets GDB_MULTI_ARCH */ - #include "solib.h" /* Support for shared libraries. */ --#include "sparc/tm-sp64.h" -- --/* Number of traps that happen between exec'ing the shell to run an -- inferior, and when we finally get to the inferior code. The -- default is right for FreeBSD. */ -- --#undef START_INFERIOR_TRAPS_EXPECTED + #define GDB_MULTI_ARCH GDB_MULTI_ARCH_TM - #endif /* TM_FBSD_H */ ++#if 0 ++#define SVR4_SHARED_LIBS ++#include "sparc/tm-sp64.h" /* sets GDB_MULTI_ARCH */ ++#endif ++ + #endif /* tm-fbsd.h */ diff --git a/devel/gdb66/files/patch-defs.h b/devel/gdb66/files/patch-defs.h deleted file mode 100644 index be60dcf..0000000 --- a/devel/gdb66/files/patch-defs.h +++ /dev/null @@ -1,20 +0,0 @@ ---- gdb/defs.h Thu Aug 1 10:18:32 2002 -+++ gdb/defs.h Sun Oct 13 10:44:10 2002 -@@ -39,8 +39,6 @@ - #include <unistd.h> - #endif - --#include "gdb_locale.h" -- - /* For ``enum target_signal''. */ - #include "gdb/signals.h" - -@@ -57,6 +55,8 @@ - here and in all subsequent file inclusions. */ - - #include "ansidecl.h" -+ -+#include "gdb_locale.h" - - #include <stdarg.h> /* for va_list */ - diff --git a/devel/gdb66/files/patch-freebsd-uthread.c b/devel/gdb66/files/patch-freebsd-uthread.c deleted file mode 100644 index 9d3fd54..0000000 --- a/devel/gdb66/files/patch-freebsd-uthread.c +++ /dev/null @@ -1,937 +0,0 @@ ---- gdb/freebsd-uthread.c Wed Dec 31 16:00:00 1969 -+++ gdb/freebsd-uthread.c Sun Oct 13 13:10:51 2002 -@@ -0,0 +1,934 @@ -+/* $FreeBSD$ */ -+/* Low level interface for debugging FreeBSD user threads for GDB, the GNU debugger. -+ Copyright 1996, 1999 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. */ -+ -+/* This module implements a sort of half target that sits between the -+ machine-independent parts of GDB and the ptrace interface (infptrace.c) to -+ provide access to the FreeBSD user-mode thread implementation. -+ -+ FreeBSD threads are true user-mode threads, which are invoked via -+ the pthread_* interfaces. These are mostly implemented in -+ user-space, with all thread context kept in various structures that -+ live in the user's heap. For the most part, the kernel has no -+ knowlege of these threads. -+ -+ Based largely on hpux-thread.c -+ -+ */ -+ -+ -+#include "defs.h" -+#include <sys/queue.h> -+#include <signal.h> -+#include <setjmp.h> -+#include <string.h> -+#include "gdbthread.h" -+#include "target.h" -+#include "inferior.h" -+#include <fcntl.h> -+#include <ucontext.h> -+#include <unistd.h> -+#include <sys/stat.h> -+#include "gdbcore.h" -+#include "regcache.h" -+ -+extern int child_suppress_run; -+extern struct target_ops child_ops; /* target vector for inftarg.c */ -+ -+extern void _initialize_freebsd_uthread PARAMS ((void)); -+ -+/* Set to true while we are part-way through attaching */ -+static int freebsd_uthread_attaching; -+ -+static int freebsd_uthread_active = 0; -+static CORE_ADDR P_thread_list; -+static CORE_ADDR P_thread_run; -+ -+/* Pointer to the next function on the objfile event chain. */ -+static void (*target_new_objfile_chain) (struct objfile *objfile); -+ -+static void freebsd_uthread_resume PARAMS ((ptid_t pid, int step, -+ enum target_signal signo)); -+ -+static void init_freebsd_uthread_ops PARAMS ((void)); -+ -+static struct target_ops freebsd_uthread_ops; -+ -+static ptid_t find_active_ptid PARAMS ((void)); -+ -+struct cached_pthread { -+ u_int64_t uniqueid; -+ int state; -+ CORE_ADDR name; -+ union { -+ ucontext_t uc; -+ jmp_buf jb; -+ } ctx; -+}; -+ -+static ptid_t cached_ptid; -+static struct cached_pthread cached_pthread; -+static CORE_ADDR cached_pthread_addr; -+ -+LIST_HEAD(idmaplist, idmap); -+ -+struct idmap { -+ LIST_ENTRY(idmap) link; -+ u_int64_t uniqueid; -+ int tid; -+}; -+ -+#define MAPHASH_SIZE 257 -+#define TID_MIN 1 -+#define TID_MAX 16383 -+ -+static int tid_to_hash[TID_MAX + 1]; /* set to map_hash index */ -+static struct idmaplist map_hash[MAPHASH_SIZE]; -+static int next_free_tid = TID_MIN; /* first available tid */ -+static int last_free_tid = TID_MIN; /* first unavailable */ -+ -+static CORE_ADDR P_thread_next_offset; -+static CORE_ADDR P_thread_uniqueid_offset; -+static CORE_ADDR P_thread_state_offset; -+static CORE_ADDR P_thread_name_offset; -+static CORE_ADDR P_thread_ctx_offset; -+static CORE_ADDR P_thread_PS_RUNNING_value; -+static CORE_ADDR P_thread_PS_DEAD_value; -+ -+static int next_offset; -+static int uniqueid_offset; -+static int state_offset; -+static int name_offset; -+static int ctx_offset; -+static int PS_RUNNING_value; -+static int PS_DEAD_value; -+ -+#define UNIQUEID_HASH(id) (id % MAPHASH_SIZE) -+#define TID_ADD1(tid) (((tid) + 1) == TID_MAX + 1 \ -+ ? TID_MIN : (tid) + 1) -+#define IS_TID_FREE(tid) (tid_to_hash[tid] == -1) -+ -+static int -+get_new_tid(int h) -+{ -+ int tid = next_free_tid; -+ -+ tid_to_hash[tid] = h; -+ next_free_tid = TID_ADD1(next_free_tid); -+ if (next_free_tid == last_free_tid) -+ { -+ int i; -+ -+ for (i = last_free_tid; TID_ADD1(i) != last_free_tid; i = TID_ADD1(i)) -+ if (IS_TID_FREE(i)) -+ break; -+ if (TID_ADD1(i) == last_free_tid) -+ { -+ error("too many threads"); -+ return 0; -+ } -+ next_free_tid = i; -+ for (i = TID_ADD1(i); IS_TID_FREE(i); i = TID_ADD1(i)) -+ ; -+ last_free_tid = i; -+ } -+ -+ return tid; -+} -+ -+static ptid_t -+find_ptid(u_int64_t uniqueid) -+{ -+ int h = UNIQUEID_HASH(uniqueid); -+ struct idmap *im; -+ -+ LIST_FOREACH(im, &map_hash[h], link) -+ if (im->uniqueid == uniqueid) -+ return MERGEPID(PIDGET(inferior_ptid), im->tid); -+ -+ im = xmalloc(sizeof(struct idmap)); -+ im->uniqueid = uniqueid; -+ im->tid = get_new_tid(h); -+ LIST_INSERT_HEAD(&map_hash[h], im, link); -+ -+ return MERGEPID(PIDGET(inferior_ptid), im->tid); -+} -+ -+static void -+free_ptid(ptid_t ptid) -+{ -+ int tid = TIDGET(ptid); -+ int h = tid_to_hash[tid]; -+ struct idmap *im; -+ -+ if (!tid) return; -+ -+ LIST_FOREACH(im, &map_hash[h], link) -+ if (im->tid == tid) -+ break; -+ -+ if (!im) return; -+ -+ LIST_REMOVE(im, link); -+ tid_to_hash[tid] = -1; -+ free(im); -+} -+ -+#define READ_OFFSET(field) read_memory(P_thread_##field##_offset, \ -+ (char *) &field##_offset, \ -+ sizeof(field##_offset)) -+ -+#define READ_VALUE(name) read_memory(P_thread_##name##_value, \ -+ (char *) &name##_value, \ -+ sizeof(name##_value)) -+ -+static void -+read_thread_offsets (void) -+{ -+ READ_OFFSET(next); -+ READ_OFFSET(uniqueid); -+ READ_OFFSET(state); -+ READ_OFFSET(name); -+ READ_OFFSET(ctx); -+ -+ READ_VALUE(PS_RUNNING); -+ READ_VALUE(PS_DEAD); -+} -+ -+#define READ_FIELD(ptr, T, field, result) \ -+ read_memory ((ptr) + field##_offset, (char *) &(result), sizeof result) -+ -+static u_int64_t -+read_pthread_uniqueid (CORE_ADDR ptr) -+{ -+ u_int64_t uniqueid; -+ READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid); -+ return uniqueid; -+} -+ -+static CORE_ADDR -+read_pthread_next (CORE_ADDR ptr) -+{ -+ CORE_ADDR next; -+ READ_FIELD(ptr, CORE_ADDR, next, next); -+ return next; -+} -+ -+static void -+read_cached_pthread (CORE_ADDR ptr, struct cached_pthread *cache) -+{ -+ READ_FIELD(ptr, u_int64_t, uniqueid, cache->uniqueid); -+ READ_FIELD(ptr, int, state, cache->state); -+ READ_FIELD(ptr, CORE_ADDR, name, cache->name); -+ READ_FIELD(ptr, ucontext_t, ctx, cache->ctx); -+} -+ -+static ptid_t -+find_active_ptid (void) -+{ -+ CORE_ADDR ptr; -+ -+ read_memory ((CORE_ADDR)P_thread_run, -+ (char *)&ptr, -+ sizeof ptr); -+ -+ return find_ptid(read_pthread_uniqueid(ptr)); -+} -+ -+static CORE_ADDR find_pthread_addr PARAMS ((ptid_t ptid)); -+static struct cached_pthread * find_pthread PARAMS ((ptid_t ptid)); -+ -+static CORE_ADDR -+find_pthread_addr (ptid_t ptid) -+{ -+ CORE_ADDR ptr; -+ -+ if (ptid_equal(ptid, cached_ptid)) -+ return cached_pthread_addr; -+ -+ read_memory ((CORE_ADDR)P_thread_list, -+ (char *)&ptr, -+ sizeof ptr); -+ -+ while (ptr != 0) -+ { -+ if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid)) -+ { -+ cached_ptid = ptid; -+ cached_pthread_addr = ptr; -+ read_cached_pthread(ptr, &cached_pthread); -+ return ptr; -+ } -+ ptr = read_pthread_next(ptr); -+ } -+ -+ return NULL; -+} -+ -+static struct cached_pthread * -+find_pthread (ptid_t ptid) -+{ -+ CORE_ADDR ptr; -+ -+ if (ptid_equal(ptid, cached_ptid)) -+ return &cached_pthread; -+ -+ read_memory ((CORE_ADDR)P_thread_list, -+ (char *)&ptr, -+ sizeof ptr); -+ -+ while (ptr != 0) -+ { -+ if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid)) -+ { -+ cached_ptid = ptid; -+ cached_pthread_addr = ptr; -+ read_cached_pthread(ptr, &cached_pthread); -+ return &cached_pthread; -+ } -+ ptr = read_pthread_next(ptr); -+ } -+ -+#if 0 -+ error ("Can't find pthread %d,%d", PIDGET(ptid), TIDGET(ptid)); -+#endif -+ return NULL; -+} -+ -+ -+/* Most target vector functions from here on actually just pass through to -+ inftarg.c, as they don't need to do anything specific for threads. */ -+ -+/* ARGSUSED */ -+static void -+freebsd_uthread_open (char *arg, int from_tty) -+{ -+ child_ops.to_open (arg, from_tty); -+} -+ -+/* Attach to process PID, then initialize for debugging it -+ and wait for the trace-trap that results from attaching. */ -+ -+static void -+freebsd_uthread_attach (char *args, int from_tty) -+{ -+ child_ops.to_attach (args, from_tty); -+ push_target (&freebsd_uthread_ops); -+ freebsd_uthread_attaching = 1; -+} -+ -+/* After an attach, see if the target is threaded */ -+ -+static void -+freebsd_uthread_post_attach (int pid) -+{ -+ if (freebsd_uthread_active) -+ { -+ read_thread_offsets (); -+ inferior_ptid = find_active_ptid (); -+ add_thread (inferior_ptid); -+ } -+ else -+ { -+ unpush_target (&freebsd_uthread_ops); -+ push_target (&child_ops); -+ } -+ -+ freebsd_uthread_attaching = 0; -+} -+ -+/* Take a program previously attached to and detaches it. -+ The program resumes execution and will no longer stop -+ on signals, etc. We'd better not have left any breakpoints -+ in the program or it'll die when it hits one. For this -+ to work, it may be necessary for the process to have been -+ previously attached. It *might* work if the program was -+ started via the normal ptrace (PTRACE_TRACEME). */ -+ -+static void -+freebsd_uthread_detach (char *args, int from_tty) -+{ -+ child_ops.to_detach (args, from_tty); -+} -+ -+/* Resume execution of process PID. If STEP is nozero, then -+ just single step it. If SIGNAL is nonzero, restart it with that -+ signal activated. We may have to convert pid from a thread-id to an LWP id -+ for procfs. */ -+ -+static void -+freebsd_uthread_resume (ptid_t ptid, int step, enum target_signal signo) -+{ -+ if (freebsd_uthread_attaching) -+ { -+ child_ops.to_resume (ptid, step, signo); -+ return; -+ } -+ -+ child_ops.to_resume (ptid, step, signo); -+ cached_ptid = MERGEPID(0, 0); -+} -+ -+/* Wait for any threads to stop. We may have to convert PID from a thread id -+ to a LWP id, and vice versa on the way out. */ -+ -+static ptid_t -+freebsd_uthread_wait (ptid_t ptid, struct target_waitstatus *ourstatus) -+{ -+ ptid_t rtnval; -+ -+ if (freebsd_uthread_attaching) -+ { -+ return child_ops.to_wait (ptid, ourstatus); -+ } -+ -+ rtnval = child_ops.to_wait (ptid, ourstatus); -+ -+ if (PIDGET(rtnval) >= 0) -+ { -+ rtnval = find_active_ptid (); -+ if (!in_thread_list (rtnval)) -+ add_thread (rtnval); -+ } -+ -+ return rtnval; -+} -+ -+/* XXX: this needs to be selected by target, not [build] host */ -+#ifdef __i386__ -+ -+#include "i386-tdep.h" -+ -+static char sigmap[I386_SSE_NUM_REGS] = /* map reg to sigcontext */ -+{ -+ 12, /* eax */ -+ 11, /* ecx */ -+ 10, /* edx */ -+ 9, /* ebx */ -+ 8, /* esp */ -+ 7, /* ebp */ -+ 6, /* esi */ -+ 5, /* edi */ -+ 15, /* eip */ -+ 17, /* eflags */ -+ 16, /* cs */ -+ 19, /* ss */ -+ 4, /* ds */ -+ 3, /* es */ -+ 2, /* fs */ -+ 1, /* gs */ -+ -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ -+ -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ -+ -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ -+ -1, /* mxcsr */ -+}; -+ -+static char jmpmap[I386_SSE_NUM_REGS] = /* map reg to jmp_buf */ -+{ -+ 6, /* eax */ -+ -1, /* ecx */ -+ -1, /* edx */ -+ 1, /* ebx */ -+ 2, /* esp */ -+ 3, /* ebp */ -+ 4, /* esi */ -+ 5, /* edi */ -+ 0, /* eip */ -+ -1, /* eflags */ -+ -1, /* cs */ -+ -1, /* ss */ -+ -1, /* ds */ -+ -1, /* es */ -+ -1, /* fs */ -+ -1, /* gs */ -+ -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ -+ -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ -+ -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ -+ -1, /* mxcsr */ -+}; -+ -+#endif -+ -+#ifdef __alpha__ -+ -+#include "alpha-tdep.h" -+ -+static char sigmap[ALPHA_NUM_REGS] = /* map reg to sigcontext */ -+{ -+ 1, 2, 3, 4, 5, 6, 7, 8, /* v0 - t6 */ -+ 9, 10, 11, 12, 13, 14, 15, 16, /* t7 - fp */ -+ 17, 18, 19, 20, 21, 22, 23, 24, /* a0 - t9 */ -+ 25, 26, 27, 28, 29, 30, 31, 32, /* t10 - zero */ -+ 38, 39, 40, 41, 42, 43, 44, 45, /* f0 - f7 */ -+ 46, 47, 48, 49, 50, 51, 52, 53, /* f8 - f15 */ -+ 54, 55, 56, 57, 58, 59, 60, 61, /* f16 - f23 */ -+ 62, 63, 64, 65, 66, 67, 68, 69, /* f24 - f31 */ -+ 33, -1 /* pc, vfp */ -+}; -+static char jmpmap[ALPHA_NUM_REGS] = { -+ 4, 5, 6, 7, 8, 9, 10, 11, /* v0 - t6 */ -+ 12, 13, 14, 15, 16, 17, 18, 19, /* t7 - fp */ -+ 20, 21, 22, 23, 24, 25, 26, 27, /* a0 - t9 */ -+ 28, 29, 30, 31, 32, 33, 34, 35, /* t10 - zero */ -+ 37, 38, 39, 40, 41, 42, 43, 44, /* f0 - f7 */ -+ 45, 46, 47, 48, 49, 50, 51, 52, /* f8 - f15 */ -+ 53, 54, 55, 56, 57, 58, 59, 60, /* f16 - f23 */ -+ 61, 62, 63, 64, 65, 66, 67, 68, /* f24 - f31 */ -+ 2, -1, /* pc, vfp */ -+}; -+ -+#endif -+ -+#ifdef __sparc64__ -+ -+static char sigmap[125] = /* map reg to sigcontext */ -+{ -+ -1 -+}; -+static char jmpmap[125] = { -+ -1 -+}; -+ -+#endif -+ -+static void -+freebsd_uthread_fetch_registers (int regno) -+{ -+ struct cached_pthread *thread; -+ int active; -+ int first_regno, last_regno; -+ register_t *regbase; -+ char *regmap; -+ -+ if (freebsd_uthread_attaching || TIDGET(inferior_ptid) == 0) -+ { -+ child_ops.to_fetch_registers (regno); -+ return; -+ } -+ -+ thread = find_pthread (inferior_ptid); -+ active = (ptid_equal(inferior_ptid, find_active_ptid())); -+ -+ if (active) -+ { -+ child_ops.to_fetch_registers (regno); -+ return; -+ } -+ -+ if (regno == -1) -+ { -+ first_regno = 0; -+ last_regno = NUM_REGS - 1; -+ } -+ else -+ { -+ first_regno = regno; -+ last_regno = regno; -+ } -+ -+ regbase = (register_t*) &thread->ctx.jb[0]; -+ regmap = jmpmap; -+ -+ for (regno = first_regno; regno <= last_regno; regno++) -+ { -+ if (regmap[regno] == -1) -+ child_ops.to_fetch_registers (regno); -+ else -+ if (thread) -+ supply_register (regno, (char*) ®base[regmap[regno]]); -+ else -+ supply_register (regno, NULL); -+ } -+} -+ -+static void -+freebsd_uthread_store_registers (int regno) -+{ -+ struct cached_pthread *thread; -+ CORE_ADDR ptr; -+ int first_regno, last_regno; -+ u_int32_t *regbase; -+ char *regmap; -+ -+ if (freebsd_uthread_attaching) -+ { -+ child_ops.to_store_registers (regno); -+ return; -+ } -+ -+ thread = find_pthread (inferior_ptid); -+ -+ if (thread->state == PS_RUNNING_value) -+ { -+ child_ops.to_store_registers (regno); -+ return; -+ } -+ -+ if (regno == -1) -+ { -+ first_regno = 0; -+ last_regno = NUM_REGS - 1; -+ } -+ else -+ { -+ first_regno = regno; -+ last_regno = regno; -+ } -+ -+ regbase = (u_int32_t*) &thread->ctx.jb[0]; -+ regmap = jmpmap; -+ -+ ptr = find_pthread_addr (inferior_ptid); -+ for (regno = first_regno; regno <= last_regno; regno++) -+ { -+ if (regmap[regno] == -1) -+ child_ops.to_store_registers (regno); -+ else -+ { -+ u_int32_t *reg = ®base[regmap[regno]]; -+ int off; -+ -+ /* Hang onto cached value */ -+ memcpy(reg, registers + REGISTER_BYTE (regno), -+ REGISTER_RAW_SIZE (regno)); -+ -+ /* And push out to inferior */ -+ off = (char *) reg - (char *) thread; -+ write_memory (ptr + off, -+ registers + REGISTER_BYTE (regno), -+ REGISTER_RAW_SIZE (regno)); -+ } -+ } -+} -+ -+/* Get ready to modify the registers array. On machines which store -+ individual registers, this doesn't need to do anything. On machines -+ which store all the registers in one fell swoop, this makes sure -+ that registers contains all the registers from the program being -+ debugged. */ -+ -+static void -+freebsd_uthread_prepare_to_store (void) -+{ -+ child_ops.to_prepare_to_store (); -+} -+ -+static int -+freebsd_uthread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, -+ int dowrite, struct mem_attrib *attrib, -+ struct target_ops *target) -+{ -+ return child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, -+ attrib, target); -+} -+ -+/* Print status information about what we're accessing. */ -+ -+static void -+freebsd_uthread_files_info (struct target_ops *ignore) -+{ -+ child_ops.to_files_info (ignore); -+} -+ -+static void -+freebsd_uthread_kill_inferior (void) -+{ -+ child_ops.to_kill (); -+} -+ -+static void -+freebsd_uthread_notice_signals (ptid_t ptid) -+{ -+ child_ops.to_notice_signals (ptid); -+} -+ -+/* Fork an inferior process, and start debugging it with /proc. */ -+ -+static void -+freebsd_uthread_create_inferior (char *exec_file, char *allargs, char **env) -+{ -+ child_ops.to_create_inferior (exec_file, allargs, env); -+ -+ if (PIDGET(inferior_ptid) && freebsd_uthread_active) -+ { -+ read_thread_offsets (); -+ push_target (&freebsd_uthread_ops); -+ inferior_ptid = find_active_ptid (); -+ add_thread (inferior_ptid); -+ } -+} -+ -+/* This routine is called to find out if the inferior is using threads. -+ We check for the _thread_run and _thread_list globals. */ -+ -+void -+freebsd_uthread_new_objfile (struct objfile *objfile) -+{ -+ struct minimal_symbol *ms; -+ -+ if (!objfile) -+ { -+ freebsd_uthread_active = 0; -+ return; -+ } -+ -+ ms = lookup_minimal_symbol ("_thread_run", NULL, objfile); -+ -+ if (!ms) -+ return; -+ -+ P_thread_run = SYMBOL_VALUE_ADDRESS (ms); -+ -+ ms = lookup_minimal_symbol ("_thread_list", NULL, objfile); -+ -+ if (!ms) -+ return; -+ -+ P_thread_list = SYMBOL_VALUE_ADDRESS (ms); -+ -+#define OFFSET_SYM(field) "_thread_" #field "_offset" -+#define LOOKUP_OFFSET(field) \ -+ do { \ -+ ms = lookup_minimal_symbol (OFFSET_SYM(field), NULL, objfile); \ -+ if (!ms) \ -+ return; \ -+ P_thread_##field##_offset = SYMBOL_VALUE_ADDRESS (ms); \ -+ } while (0); -+ -+#define VALUE_SYM(name) "_thread_" #name "_value" -+#define LOOKUP_VALUE(name) \ -+ do { \ -+ ms = lookup_minimal_symbol (VALUE_SYM(name), NULL, objfile); \ -+ if (!ms) \ -+ return; \ -+ P_thread_##name##_value = SYMBOL_VALUE_ADDRESS (ms); \ -+ } while (0); -+ -+ LOOKUP_OFFSET(next); -+ LOOKUP_OFFSET(uniqueid); -+ LOOKUP_OFFSET(state); -+ LOOKUP_OFFSET(name); -+ LOOKUP_OFFSET(ctx); -+ -+ LOOKUP_VALUE(PS_RUNNING); -+ LOOKUP_VALUE(PS_DEAD); -+ -+ freebsd_uthread_active = 1; -+} -+ -+/* Clean up after the inferior dies. */ -+ -+static void -+freebsd_uthread_mourn_inferior () -+{ -+ child_ops.to_mourn_inferior (); -+ unpush_target (&freebsd_uthread_ops); -+} -+ -+/* Mark our target-struct as eligible for stray "run" and "attach" commands. */ -+ -+static int -+freebsd_uthread_can_run () -+{ -+ return child_suppress_run; -+} -+ -+static int -+freebsd_uthread_thread_alive (ptid_t ptid) -+{ -+ struct cached_pthread *thread; -+ int ret = 0; -+ -+ if (freebsd_uthread_attaching) -+ return 1; -+ -+ /* -+ * We can get called from child_ops.to_wait() which passes the underlying -+ * pid (without a thread number). -+ */ -+ if (TIDGET(ptid) == 0) -+ return 1; -+ -+ if (find_pthread_addr (ptid) != 0) -+ { -+ thread = find_pthread (ptid); -+ ret = (thread->state != PS_DEAD_value); -+ } -+ -+ if (!ret) -+ free_ptid(ptid); -+ -+ return ret; -+} -+ -+static void -+freebsd_uthread_stop (void) -+{ -+ child_ops.to_stop (); -+} -+ -+static void -+freebsd_uthread_find_new_threads (void) -+{ -+ CORE_ADDR ptr; -+ int state; -+ u_int64_t uniqueid; -+ -+ read_memory ((CORE_ADDR)P_thread_list, -+ (char *)&ptr, -+ sizeof ptr); -+ -+ while (ptr != 0) -+ { -+ READ_FIELD(ptr, int, state, state); -+ READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid); -+ if (state != PS_DEAD_value && -+ !in_thread_list (find_ptid(uniqueid))) -+ add_thread (find_ptid(uniqueid)); -+ ptr = read_pthread_next(ptr); -+ } -+} -+ -+/* MUST MATCH enum pthread_state */ -+static const char *statenames[] = { -+ "RUNNING", -+ "SIGTHREAD", -+ "MUTEX_WAIT", -+ "COND_WAIT", -+ "FDLR_WAIT", -+ "FDLW_WAIT", -+ "FDR_WAIT", -+ "FDW_WAIT", -+ "POLL_WAIT", -+ "FILE_WAIT", -+ "SELECT_WAIT", -+ "SLEEP_WAIT", -+ "WAIT_WAIT", -+ "SIGSUSPEND", -+ "SIGWAIT", -+ "SPINBLOCK", -+ "JOIN", -+ "SUSPENDED", -+ "DEAD", -+ "DEADLOCK", -+}; -+ -+#if 0 -+ -+static int -+freebsd_uthread_get_thread_info (ref, selection, info) -+ gdb_threadref *ref; -+ int selection; -+ struct gdb_ext_thread_info *info; -+{ -+ int pid = *ref; -+ struct cached_pthread *thread = find_pthread (pid); -+ struct cleanup *old_chain; -+ -+ old_chain = save_inferior_pid (); -+ inferior_pid = main_pid; -+ -+ memset(&info->threadid, 0, OPAQUETHREADBYTES); -+ -+ memcpy(&info->threadid, ref, sizeof *ref); -+ info->active = thread->state == PS_RUNNING_value; -+ strcpy(info->display, statenames[thread->state]); -+ if (thread->name) -+ read_memory ((CORE_ADDR) thread->name, info->shortname, 32); -+ else -+ strcpy(info->shortname, ""); -+ -+ do_cleanups (old_chain); -+ return (0); -+} -+ -+#endif -+ -+char * -+freebsd_uthread_pid_to_str (ptid_t ptid) -+{ -+ static char buf[30]; -+ -+ if (STREQ (current_target.to_shortname, "freebsd-uthreads")) -+ sprintf (buf, "Process %d, Thread %ld", -+ PIDGET(ptid), TIDGET(ptid)); -+ else -+ sprintf (buf, "Process %d", PIDGET(ptid)); -+ -+ return buf; -+} -+ -+ -+static void -+init_freebsd_uthread_ops () -+{ -+ freebsd_uthread_ops.to_shortname = "freebsd-uthreads"; -+ freebsd_uthread_ops.to_longname = "FreeBSD uthreads"; -+ freebsd_uthread_ops.to_doc = "FreeBSD user threads support."; -+ freebsd_uthread_ops.to_open = freebsd_uthread_open; -+ freebsd_uthread_ops.to_attach = freebsd_uthread_attach; -+ freebsd_uthread_ops.to_post_attach = freebsd_uthread_post_attach; -+ freebsd_uthread_ops.to_detach = freebsd_uthread_detach; -+ freebsd_uthread_ops.to_resume = freebsd_uthread_resume; -+ freebsd_uthread_ops.to_wait = freebsd_uthread_wait; -+ freebsd_uthread_ops.to_fetch_registers = freebsd_uthread_fetch_registers; -+ freebsd_uthread_ops.to_store_registers = freebsd_uthread_store_registers; -+ freebsd_uthread_ops.to_prepare_to_store = freebsd_uthread_prepare_to_store; -+ freebsd_uthread_ops.to_xfer_memory = freebsd_uthread_xfer_memory; -+ freebsd_uthread_ops.to_files_info = freebsd_uthread_files_info; -+ freebsd_uthread_ops.to_insert_breakpoint = memory_insert_breakpoint; -+ freebsd_uthread_ops.to_remove_breakpoint = memory_remove_breakpoint; -+ freebsd_uthread_ops.to_terminal_init = terminal_init_inferior; -+ freebsd_uthread_ops.to_terminal_inferior = terminal_inferior; -+ freebsd_uthread_ops.to_terminal_ours_for_output = terminal_ours_for_output; -+ freebsd_uthread_ops.to_terminal_ours = terminal_ours; -+ freebsd_uthread_ops.to_terminal_info = child_terminal_info; -+ freebsd_uthread_ops.to_kill = freebsd_uthread_kill_inferior; -+ freebsd_uthread_ops.to_create_inferior = freebsd_uthread_create_inferior; -+ freebsd_uthread_ops.to_mourn_inferior = freebsd_uthread_mourn_inferior; -+ freebsd_uthread_ops.to_can_run = freebsd_uthread_can_run; -+ freebsd_uthread_ops.to_notice_signals = freebsd_uthread_notice_signals; -+ freebsd_uthread_ops.to_thread_alive = freebsd_uthread_thread_alive; -+ freebsd_uthread_ops.to_stop = freebsd_uthread_stop; -+ freebsd_uthread_ops.to_stratum = process_stratum; -+ freebsd_uthread_ops.to_has_all_memory = 1; -+ freebsd_uthread_ops.to_has_memory = 1; -+ freebsd_uthread_ops.to_has_stack = 1; -+ freebsd_uthread_ops.to_has_registers = 1; -+ freebsd_uthread_ops.to_has_execution = 1; -+ freebsd_uthread_ops.to_has_thread_control = 0; -+ freebsd_uthread_ops.to_magic = OPS_MAGIC; -+ freebsd_uthread_ops.to_find_new_threads = freebsd_uthread_find_new_threads; -+ freebsd_uthread_ops.to_pid_to_str = freebsd_uthread_pid_to_str; -+#if 0 -+ freebsd_uthread_vec.get_thread_info = freebsd_uthread_get_thread_info; -+#endif -+} -+ -+void -+_initialize_freebsd_uthread () -+{ -+ init_freebsd_uthread_ops (); -+ add_target (&freebsd_uthread_ops); -+ -+ target_new_objfile_chain = target_new_objfile_hook; -+ target_new_objfile_hook = freebsd_uthread_new_objfile; -+ -+ child_suppress_run = 1; -+} diff --git a/devel/gdb66/files/patch-i386%nm-fbsd64.h b/devel/gdb66/files/patch-i386%nm-fbsd64.h new file mode 100644 index 0000000..03ec32a --- /dev/null +++ b/devel/gdb66/files/patch-i386%nm-fbsd64.h @@ -0,0 +1,12 @@ +--- gdb/config/i386/nm-fbsd64.h.orig Sat Mar 13 05:07:20 2004 ++++ gdb/config/i386/nm-fbsd64.h Wed May 5 11:20:14 2004 +@@ -25,6 +25,9 @@ + /* Get generic BSD native definitions. */ + #include "config/nm-bsd.h" + ++/* Get generic FreeBSD native definitions. */ ++#include "config/nm-fbsd.h" ++ + /* Override child_pid_to_exec_file in 'inftarg.c'. */ + #define CHILD_PID_TO_EXEC_FILE + diff --git a/devel/gdb66/files/patch-i386-tdep.c b/devel/gdb66/files/patch-i386-tdep.c deleted file mode 100644 index f91663c..0000000 --- a/devel/gdb66/files/patch-i386-tdep.c +++ /dev/null @@ -1,12 +0,0 @@ ---- gdb/i386-tdep.c Mon Aug 26 11:35:25 2002 -+++ gdb/i386-tdep.c Sun Oct 13 14:15:58 2002 -@@ -534,6 +534,9 @@ - static CORE_ADDR - i386_frame_saved_pc (struct frame_info *frame) - { -+ if (kernel_debugging) -+ return fbsd_kern_frame_saved_pc(frame); -+ - if (PC_IN_CALL_DUMMY (frame->pc, 0, 0)) - return generic_read_register_dummy (frame->pc, frame->frame, - PC_REGNUM); diff --git a/devel/gdb66/files/patch-i386bsd-nat.c b/devel/gdb66/files/patch-i386bsd-nat.c deleted file mode 100644 index a28ce60..0000000 --- a/devel/gdb66/files/patch-i386bsd-nat.c +++ /dev/null @@ -1,20 +0,0 @@ ---- gdb/i386bsd-nat.c 2003/01/02 20:22:00 1.1 -+++ gdb/i386bsd-nat.c 2003/01/02 20:22:35 -@@ -306,7 +306,7 @@ - /* For some mysterious reason, some of the reserved bits in the - debug control register get set. Mask these off, otherwise the - ptrace call below will fail. */ -- dbregs.dr7 &= ~(0x0000fc00); -+ DBREG_DRX ((&dbregs), 7) = ~(0x0000fc00); - - DBREG_DRX ((&dbregs), regnum) = value; - -@@ -355,7 +355,7 @@ - return 0; - #endif - -- return dbregs.dr6; -+ return DBREG_DRX ((&dbregs), 6); - } - - #endif /* PT_GETDBREGS */ diff --git a/devel/gdb66/files/patch-kvm-fbsd.c b/devel/gdb66/files/patch-kvm-fbsd.c deleted file mode 100644 index 7259fd1..0000000 --- a/devel/gdb66/files/patch-kvm-fbsd.c +++ /dev/null @@ -1,759 +0,0 @@ ---- gdb/kvm-fbsd.c Fri Jan 3 08:57:23 2003 -+++ gdb/kvm-fbsd.c Fri Jan 3 08:57:20 2003 -@@ -0,0 +1,756 @@ -+/* Kernel core dump functions below target vector, for GDB. -+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 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. -+*/ -+ -+/* $FreeBSD: /tmp/pcvs/ports/devel/gdb66/files/Attic/patch-kvm-fbsd.c,v 1.5 2003-04-08 08:37:55 jake Exp $ */ -+ -+/* -+ * This works like "remote" but, you use it like this: -+ * target kcore /dev/mem -+ * or -+ * target kcore /var/crash/host/core.0 -+ * -+ * This way makes it easy to short-circut the whole bfd monster, -+ * and direct the inferior stuff to our libkvm implementation. -+ * -+ */ -+ -+#include <sys/param.h> -+#include <sys/time.h> -+#include <sys/proc.h> -+#include <sys/user.h> -+#include <ctype.h> -+#include <errno.h> -+#include <signal.h> -+#include <fcntl.h> -+#include <kvm.h> -+#include <sys/sysctl.h> -+#include <paths.h> -+#include <readline/tilde.h> -+#include <machine/frame.h> -+ -+#include "defs.h" -+#include "gdb_string.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 "regcache.h" -+ -+#if __FreeBSD_version >= 500032 -+static void -+kcore_files_info (struct target_ops *); -+ -+static void -+kcore_close (int); -+ -+static void -+get_kcore_registers (int); -+ -+static int -+xfer_mem (CORE_ADDR, char *, int, int, struct mem_attrib *, -+ struct target_ops *); -+ -+static int -+xfer_umem (CORE_ADDR, char *, int, int); -+ -+static char *core_file; -+static kvm_t *core_kd; -+static struct pcb cur_pcb; -+static struct kinfo_proc *cur_proc; -+ -+static struct target_ops kcore_ops; -+ -+int kernel_debugging; -+int kernel_writablecore; -+ -+/* 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)))) -+ -+static CORE_ADDR -+ksym_kernbase (void) -+{ -+ static CORE_ADDR kernbase; -+ struct minimal_symbol *sym; -+ -+ if (kernbase == 0) -+ { -+ sym = lookup_minimal_symbol ("kernbase", NULL, NULL); -+ if (sym == NULL) { -+ kernbase = KERNBASE; -+ } else { -+ kernbase = SYMBOL_VALUE_ADDRESS (sym); -+ } -+ } -+ return kernbase; -+} -+ -+#define KERNOFF (ksym_kernbase ()) -+#define INKERNEL(x) ((x) >= KERNOFF) -+ -+CORE_ADDR -+ksym_lookup(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); -+} -+ -+/* Provide the address of an initial PCB to use. -+ If this is a crash dump, try for "dumppcb". -+ If no "dumppcb" or it's /dev/mem, use proc0. -+ Return the core address of the PCB we found. */ -+ -+static CORE_ADDR -+initial_pcb (void) -+{ -+ struct minimal_symbol *sym; -+ CORE_ADDR addr; -+ void *val; -+ -+ /* Make sure things are open... */ -+ if (!core_kd || !core_file) -+ return (0); -+ -+ /* If this is NOT /dev/mem try for dumppcb. */ -+ if (strncmp (core_file, _PATH_DEV, sizeof _PATH_DEV - 1)) -+ { -+ sym = lookup_minimal_symbol ("dumppcb", NULL, NULL); -+ if (sym != NULL) -+ { -+ addr = SYMBOL_VALUE_ADDRESS (sym); -+ return (addr); -+ } -+ } -+ -+ /* OK, just use thread0's pcb. Note that curproc might -+ not exist, and if it does, it will point to gdb. -+ Therefore, just use proc0 and let the user set -+ some other context if they care about it. */ -+ -+ addr = ksym_lookup ("thread0"); -+ if (kvread (addr, &val)) -+ { -+ error ("cannot read thread0 pointer at %x\n", addr); -+ val = 0; -+ } -+ else -+ { -+ /* Read the PCB address in thread structure. */ -+ addr += offsetof (struct thread, td_pcb); -+ if (kvread (addr, &val)) -+ { -+ error ("cannot read thread0->td_pcb pointer at %x\n", addr); -+ val = 0; -+ } -+ } -+ -+ /* thread0 is wholly in the kernel and cur_proc is only used for -+ reading user mem, so no point in setting this up. */ -+ cur_proc = 0; -+ -+ return ((CORE_ADDR)val); -+} -+ -+/* Set the current context to that of the PCB struct at the system address -+ passed. */ -+ -+static int -+set_context (CORE_ADDR addr) -+{ -+ CORE_ADDR procaddr = 0; -+ -+ if (kvread (addr, &cur_pcb)) -+ error ("cannot read pcb at %#x", addr); -+ -+ /* 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 ()); -+ return (0); -+} -+ -+/* Discard all vestiges of any previous core file and mark data and stack -+ spaces as empty. */ -+ -+/* ARGSUSED */ -+static void -+kcore_close (int quitting) -+{ -+ -+ inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */ -+ -+ if (core_kd) -+ { -+ kvm_close (core_kd); -+ free (core_file); -+ core_file = NULL; -+ core_kd = NULL; -+ } -+} -+ -+/* This routine opens and sets up the core file bfd. */ -+ -+static void -+kcore_open (char *filename /* the core file */, int from_tty) -+{ -+ kvm_t *kd; -+ const char *p; -+ struct cleanup *old_chain; -+ char buf[256], *cp; -+ int ontop; -+ CORE_ADDR addr; -+ -+ target_preopen (from_tty); -+ -+ /* The exec file is required for symbols. */ -+ if (exec_bfd == NULL) -+ error ("No kernel exec file specified"); -+ -+ if (core_kd) -+ { -+ error ("No core file specified." -+ " (Use `detach' to stop debugging a core file.)"); -+ return; -+ } -+ -+ if (!filename) -+ { -+ error ("No core file specified."); -+ return; -+ } -+ -+ filename = tilde_expand (filename); -+ if (filename[0] != '/') -+ { -+ cp = concat (current_directory, "/", filename, NULL); -+ free (filename); -+ filename = cp; -+ } -+ -+ old_chain = make_cleanup (free, filename); -+ -+ kd = kvm_open (bfd_get_filename(exec_bfd), filename, NULL, -+ kernel_writablecore ? O_RDWR: O_RDONLY, 0); -+ if (kd == NULL) -+ { -+ perror_with_name (filename); -+ return; -+ } -+ -+ /* 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; -+ unpush_target (&kcore_ops); -+ ontop = !push_target (&kcore_ops); -+ -+ /* Note unpush_target (above) calls kcore_close. */ -+ core_kd = kd; -+ -+ /* 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_filtered ("panic: %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; -+ } -+ -+ /* Now, set up process context, and print the top of stack. */ -+ (void)set_context (initial_pcb()); -+ print_stack_frame (selected_frame, frame_relative_level(selected_frame), 1); -+} -+ -+static void -+kcore_detach (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"); -+} -+ -+#ifdef __alpha__ -+ -+#include "alpha/tm-alpha.h" -+#include "alpha-tdep.h" -+ -+#ifndef S0_REGNUM -+#define S0_REGNUM (ALPHA_T7_REGNUM+1) -+#endif -+ -+fetch_kcore_registers (struct pcb *pcbp) -+{ -+ -+ /* First clear out any garbage. */ -+ memset (registers, '\0', REGISTER_BYTES); -+ -+ /* SP */ -+ *(long *) ®isters[REGISTER_BYTE (SP_REGNUM)] = -+ pcbp->pcb_hw.apcb_ksp; -+ -+ /* S0 through S6 */ -+ memcpy (®isters[REGISTER_BYTE (S0_REGNUM)], -+ &pcbp->pcb_context[0], 7 * sizeof (long)); -+ -+ /* PC */ -+ *(long *) ®isters[REGISTER_BYTE (PC_REGNUM)] = -+ pcbp->pcb_context[7]; -+ -+ registers_fetched (); -+} -+ -+ -+CORE_ADDR -+fbsd_kern_frame_saved_pc (struct frame_info *fi) -+{ -+ struct minimal_symbol *sym; -+ CORE_ADDR this_saved_pc; -+ -+ this_saved_pc = FRAME_SAVED_PC(fi); -+ -+ sym = lookup_minimal_symbol_by_pc (this_saved_pc); -+ -+ if (sym != NULL && -+ (strcmp (SYMBOL_NAME (sym), "XentArith") == 0 || -+ strcmp (SYMBOL_NAME (sym), "XentIF") == 0 || -+ strcmp (SYMBOL_NAME (sym), "XentInt") == 0 || -+ strcmp (SYMBOL_NAME (sym), "XentMM") == 0 || -+ strcmp (SYMBOL_NAME (sym), "XentSys") == 0 || -+ strcmp (SYMBOL_NAME (sym), "XentUna") == 0 || -+ strcmp (SYMBOL_NAME (sym), "XentRestart") == 0)) -+ { -+ return (read_memory_integer (fi->frame + 32 * 8, 8)); -+ } -+ else -+ { -+ return (this_saved_pc); -+ } -+} -+ -+#endif /* __alpha__ */ -+ -+#ifdef __i386__ -+ -+static CORE_ADDR -+ksym_maxuseraddr (void) -+{ -+ static CORE_ADDR maxuseraddr; -+ struct minimal_symbol *sym; -+ -+ if (maxuseraddr == 0) -+ { -+ sym = lookup_minimal_symbol ("PTmap", NULL, NULL); -+ if (sym == NULL) { -+ maxuseraddr = VM_MAXUSER_ADDRESS; -+ } else { -+ maxuseraddr = SYMBOL_VALUE_ADDRESS (sym); -+ } -+ } -+ return maxuseraddr; -+} -+ -+ -+/* Symbol names of kernel entry points. Use special frames. */ -+#define KSYM_TRAP "calltrap" -+#define KSYM_INTR "Xintr" -+#define KSYM_FASTINTR "Xfastintr" -+#define KSYM_OLDSYSCALL "Xlcall_syscall" -+#define KSYM_SYSCALL "Xint0x80_syscall" -+ -+/* 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 (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), KSYM_TRAP) == 0) -+ frametype = tf_trap; -+ else -+ if (strncmp (SYMBOL_NAME (sym), KSYM_INTR, -+ strlen (KSYM_INTR)) == 0 || strncmp (SYMBOL_NAME(sym), -+ KSYM_FASTINTR, strlen (KSYM_FASTINTR)) == 0) -+ frametype = tf_interrupt; -+ else -+ if (strcmp (SYMBOL_NAME (sym), KSYM_SYSCALL) == 0 || -+ strcmp (SYMBOL_NAME (sym), KSYM_OLDSYSCALL) == 0) -+ frametype = tf_syscall; -+ } -+ -+ switch (frametype) -+ { -+ default: -+ 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 + 12 + oEIP, 4)); -+ -+ case tf_syscall: -+ return (read_memory_integer (fr->frame + 8 + oEIP, 4)); -+#undef oEIP -+ } -+} -+ -+static void -+fetch_kcore_registers (struct pcb *pcb) -+{ -+ int i; -+ int noreg; -+ -+ /* 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? */ -+} -+ -+#endif /* __i386__ */ -+ -+#ifdef __sparc64__ -+ -+#define SPARC_INTREG_SIZE 8 -+ -+static void -+fetch_kcore_registers (struct pcb *pcbp) -+{ -+ static struct frame top; -+ CORE_ADDR f_addr; -+ int i; -+ -+ /* 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 do something with the floating-point registers? -+ */ -+ supply_register (SP_REGNUM, &pcbp->pcb_sp); -+ supply_register (PC_REGNUM, &pcbp->pcb_pc); -+ f_addr = extract_address (&pcbp->pcb_sp, SPARC_INTREG_SIZE); -+ /* Load the previous frame by hand (XXX) and supply it. */ -+ read_memory (f_addr + SPOFF, (char *)&top, sizeof (top)); -+ for (i = 0; i < 8; i++) -+ supply_register (i + L0_REGNUM, &top.fr_local[i]); -+ for (i = 0; i < 8; i++) -+ supply_register (i + I0_REGNUM, &top.fr_in[i]); -+} -+ -+CORE_ADDR -+fbsd_kern_frame_saved_pc (struct frame_info *fi) -+{ -+ struct minimal_symbol *sym; -+ CORE_ADDR frame, pc_addr, pc; -+ char *buf; -+ -+ buf = alloca (MAX_REGISTER_RAW_SIZE); -+ /* XXX: duplicates fi->extra_info->bottom. */ -+ frame = (fi->next != NULL) ? fi->next->frame : read_sp (); -+ pc_addr = frame + offsetof (struct frame, fr_in[7]); -+ -+#define READ_PC(pc, a, b) do { \ -+ read_memory (a, b, SPARC_INTREG_SIZE); \ -+ pc = extract_address (b, SPARC_INTREG_SIZE); \ -+} while (0) -+ -+ READ_PC (pc, pc_addr, buf); -+ -+ sym = lookup_minimal_symbol_by_pc (pc); -+ if (sym != NULL) -+ { -+ if (strncmp (SYMBOL_NAME (sym), "tl0_", 4) == 0 || -+ strcmp (SYMBOL_NAME (sym), "btext") == 0 || -+ strcmp (SYMBOL_NAME (sym), "mp_startup") == 0 || -+ strcmp (SYMBOL_NAME (sym), "fork_trampoline") == 0) -+ { -+ /* -+ * Ugly kluge: user space addresses aren't separated from kernel -+ * ones by range; if encountering a trap from user space, just -+ * return a 0 to stop the trace. -+ * Do the same for entry points of kernel processes to avoid -+ * printing garbage. -+ */ -+ pc = 0; -+ } -+ if (strncmp (SYMBOL_NAME (sym), "tl1_", 4) == 0) -+ { -+ pc_addr = fi->frame + sizeof (struct frame) + -+ offsetof (struct trapframe, tf_tpc); -+ READ_PC (pc, pc_addr, buf); -+ } -+ } -+ return (pc); -+} -+ -+#endif /* __sparc64__ */ -+ -+/* 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 (int regno) -+{ -+ -+ /* XXX - Only read the pcb when set_context() is called. -+ When looking at a live kernel this may be a problem, -+ but the user can do another "proc" or "pcb" command to -+ grab a new copy of the pcb... */ -+ -+ /* Zero out register set then fill in the ones we know about. */ -+ fetch_kcore_registers (&cur_pcb); -+} -+ -+static void -+kcore_files_info (t) -+ struct target_ops *t; -+{ -+ printf_filtered ("\t`%s'\n", core_file); -+} -+ -+/* If mourn is being called in all the right places, this could be say -+ `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */ -+ -+static int -+ignore (CORE_ADDR addr, char *contents) -+{ -+ return 0; -+} -+ -+static int -+xfer_kmem (CORE_ADDR memaddr, char *myaddr, int len, int write, -+ struct mem_attrib *attrib, struct target_ops *target) -+{ -+ int n; -+ -+ -+ if (!INKERNEL (memaddr)) -+ return xfer_umem (memaddr, myaddr, len, write); -+ -+ if (core_kd == NULL) -+ return 0; -+ -+ if (write) -+ n = kvm_write (core_kd, memaddr, myaddr, len); -+ else -+ n = kvm_read (core_kd, memaddr, myaddr, len) ; -+ if (n < 0) { -+ fprintf_unfiltered (gdb_stderr, "can not access 0x%x, %s\n", -+ memaddr, kvm_geterr (core_kd)); -+ n = 0; -+ } -+ -+ return n; -+} -+ -+ -+static int -+xfer_umem (CORE_ADDR memaddr, char *myaddr, int len, int write /* ignored */) -+{ -+ int n = 0; -+ -+ if (cur_proc == 0) -+ { -+ error ("---Can't read userspace from dump, or kernel process---\n"); -+ return 0; -+ } -+ -+ if (write) -+ error ("kvm_uwrite unimplemented\n"); -+ else -+ n = kvm_uread (core_kd, cur_proc, memaddr, myaddr, len) ; -+ -+ if (n < 0) -+ return 0; -+ -+ return n; -+} -+ -+static void -+set_proc_cmd (char *arg, int from_tty) -+{ -+ CORE_ADDR addr, pid_addr, first_td; -+ void *val; -+ struct kinfo_proc *kp; -+ int cnt; -+ pid_t pid; -+ -+ if (!arg) -+ error_no_arg ("proc address for the new context"); -+ -+ if (core_kd == NULL) -+ error ("no kernel core file"); -+ -+ addr = (CORE_ADDR) parse_and_eval_address (arg); -+ -+ if (!INKERNEL (addr)) -+ { -+ kp = kvm_getprocs (core_kd, KERN_PROC_PID, addr, &cnt); -+ if (!cnt) -+ error ("invalid pid"); -+ addr = (CORE_ADDR)kp->ki_paddr; -+ cur_proc = kp; -+ } -+ else -+ { -+ /* Update cur_proc. */ -+ pid_addr = addr + offsetof (struct proc, p_pid); -+ if (kvread (pid_addr, &pid)) -+ error ("cannot read pid ptr"); -+ cur_proc = kvm_getprocs (core_kd, KERN_PROC_PID, pid, &cnt); -+ if (!cnt) -+ error("invalid pid"); -+ } -+ -+ /* Find the first thread in the process. XXXKSE */ -+ addr += offsetof (struct proc, p_threads.tqh_first); -+ if (kvread (addr, &first_td)) -+ error ("cannot read thread ptr"); -+ -+ /* Read the PCB address in thread structure. */ -+ addr = first_td + offsetof (struct thread, td_pcb); -+ if (kvread (addr, &val)) -+ error("cannot read pcb ptr"); -+ -+ /* Read the PCB address in proc structure. */ -+ if (set_context ((CORE_ADDR) val)) -+ error ("invalid proc address"); -+} -+#else -+int kernel_debugging = 0; -+int kernel_writablecore = 0; -+ -+CORE_ADDR -+fbsd_kern_frame_saved_pc (struct frame_info *fi) -+{ -+ return 0; -+} -+#endif -+ -+void -+_initialize_kcorelow (void) -+{ -+#if __FreeBSD_version >= 500032 -+ kcore_ops.to_shortname = "kcore"; -+ kcore_ops.to_longname = "Kernel core dump file"; -+ kcore_ops.to_doc = -+ "Use a core file as a target. Specify the filename of the core file."; -+ kcore_ops.to_open = kcore_open; -+ kcore_ops.to_close = kcore_close; -+ kcore_ops.to_attach = find_default_attach; -+ kcore_ops.to_detach = kcore_detach; -+ kcore_ops.to_fetch_registers = get_kcore_registers; -+ kcore_ops.to_xfer_memory = xfer_kmem; -+ kcore_ops.to_files_info = kcore_files_info; -+ kcore_ops.to_create_inferior = find_default_create_inferior; -+ kcore_ops.to_stratum = kcore_stratum; -+ kcore_ops.to_has_memory = 1; -+ kcore_ops.to_has_stack = 1; -+ kcore_ops.to_has_registers = 1; -+ kcore_ops.to_magic = OPS_MAGIC; -+ -+ add_target (&kcore_ops); -+ add_com ("proc", class_obscure, set_proc_cmd, "Set current process context"); -+#endif -+} diff --git a/devel/gdb66/files/patch-main.c b/devel/gdb66/files/patch-main.c new file mode 100644 index 0000000..bd5cd46 --- /dev/null +++ b/devel/gdb66/files/patch-main.c @@ -0,0 +1,53 @@ +--- gdb/main.c.orig Thu Apr 15 22:40:39 2004 ++++ gdb/main.c Thu Apr 15 22:47:51 2004 +@@ -66,6 +66,12 @@ + /* Whether dbx commands will be handled */ + int dbx_commands = 0; + ++#ifdef KGDB ++/* Kernel debugging support. */ ++int kernel_debugging; ++int kernel_writablecore; ++#endif ++ + /* System root path, used to find libraries etc. */ + char *gdb_sysroot = 0; + +@@ -311,6 +317,12 @@ + {"statistics", no_argument, 0, OPT_STATISTICS}, + {"write", no_argument, &write_files, 1}, + {"args", no_argument, &set_args, 1}, ++#ifdef KGDB ++ {"kernel", no_argument, &kernel_debugging, 1}, ++ {"k", no_argument, &kernel_debugging, 1}, ++ {"wcore", no_argument, &kernel_writablecore, 1}, ++ {"w", no_argument, &kernel_writablecore, 1}, ++#endif + {0, no_argument, 0, 0} + }; + +@@ -857,6 +869,11 @@ + --interpreter=INTERP\n\ + Select a specific interpreter / user interface\n\ + "), stream); ++#ifdef KGDB ++ fputs_unfiltered (_("\ ++ --kernel Enable kernel debugging.\n\ ++"), stream); ++#endif + fputs_unfiltered (_("\ + --mapped Use mapped symbol files if supported on this system.\n\ + --nw Do not use a window interface.\n\ +@@ -874,6 +891,12 @@ + #if defined(TUI) + fputs_unfiltered (_("\ + --tui Use a terminal user interface.\n\ ++"), stream); ++#endif ++#ifdef KGDB ++ fputs_unfiltered (_("\ ++ --wcore Make core file writable (only works for /dev/mem).\n\ ++ This option only works while debugging a kernel !!\n\ + "), stream); + #endif + fputs_unfiltered (_("\ diff --git a/devel/gdb66/files/patch-sparc-tdep.c b/devel/gdb66/files/patch-sparc-tdep.c deleted file mode 100644 index 950276e..0000000 --- a/devel/gdb66/files/patch-sparc-tdep.c +++ /dev/null @@ -1,13 +0,0 @@ ---- gdb/sparc-tdep.c.orig Sun Oct 20 18:21:09 2002 -+++ gdb/sparc-tdep.c Sun Oct 20 18:16:53 2002 -@@ -450,6 +450,9 @@ - char *buf; - CORE_ADDR addr; - -+ if (kernel_debugging) -+ return fbsd_kern_frame_saved_pc(frame); -+ - buf = alloca (MAX_REGISTER_RAW_SIZE); - if (frame->signal_handler_caller) - { - diff --git a/devel/gdb66/files/patch-sparcnbsd-tdep.c b/devel/gdb66/files/patch-sparcnbsd-tdep.c deleted file mode 100644 index 13ba396..0000000 --- a/devel/gdb66/files/patch-sparcnbsd-tdep.c +++ /dev/null @@ -1,63 +0,0 @@ -diff -urN gdb/sparcnbsd-tdep.c.orig gdb/sparcnbsd-tdep.c ---- gdb/sparcnbsd-tdep.c.orig Sat Oct 19 17:19:17 2002 -+++ gdb/sparcnbsd-tdep.c Sat Oct 19 17:44:47 2002 -@@ -31,20 +31,6 @@ - - #include "solib-svr4.h" - --#define REG32_OFFSET_PSR (0 * 4) --#define REG32_OFFSET_PC (1 * 4) --#define REG32_OFFSET_NPC (2 * 4) --#define REG32_OFFSET_Y (3 * 4) --#define REG32_OFFSET_GLOBAL (4 * 4) --#define REG32_OFFSET_OUT (12 * 4) -- --#define REG64_OFFSET_TSTATE (0 * 8) --#define REG64_OFFSET_PC (1 * 8) --#define REG64_OFFSET_NPC (2 * 8) --#define REG64_OFFSET_Y (3 * 8) --#define REG64_OFFSET_GLOBAL (4 * 8) --#define REG64_OFFSET_OUT (12 * 8) -- - void - sparcnbsd_supply_reg32 (char *regs, int regno) - { -@@ -375,16 +361,13 @@ - - if (gdbarch_ptr_bit (current_gdbarch) == 32) - { -- reg_size = (20 * 4); -- fpreg_size = (33 * 4); -+ reg_size = REG32_SIZE; -+ fpreg_size = FPREG32_SIZE; - } - else - { -- reg_size = (20 * 8); -- fpreg_size = (64 * 4) -- + 8 /* fsr */ -- + 4 /* gsr */ -- + 4; /* pad */ -+ reg_size = REG64_SIZE; -+ fpreg_size = FPREG64_SIZE; - } - - switch (which) -@@ -442,7 +425,7 @@ - - jb_addr = read_register (O0_REGNUM); - -- if (target_read_memory (jb_addr + 12, buf, sizeof (buf))) -+ if (target_read_memory (jb_addr + JB32_OFFSET_PC, buf, sizeof (buf))) - return 0; - - *pc = extract_address (buf, sizeof (buf)); -@@ -458,7 +441,7 @@ - - jb_addr = read_register (O0_REGNUM); - -- if (target_read_memory (jb_addr + 16, buf, sizeof (buf))) -+ if (target_read_memory (jb_addr + JB64_OFFSET_PC, buf, sizeof (buf))) - return 0; - - *pc = extract_address (buf, sizeof (buf)); diff --git a/devel/gdb66/files/patch-symfile.c b/devel/gdb66/files/patch-symfile.c deleted file mode 100644 index 99c75ff..0000000 --- a/devel/gdb66/files/patch-symfile.c +++ /dev/null @@ -1,15 +0,0 @@ ---- gdb/symfile.c Tue Feb 26 17:40:36 2002 -+++ gdb/symfile.c Wed May 29 11:10:17 2002 -@@ -1546,11 +1546,7 @@ - char *val = sect_opts[i].value; - char *sec = sect_opts[i].name; - -- val = sect_opts[i].value; -- if (val[0] == '0' && val[1] == 'x') -- addr = strtoul (val+2, NULL, 16); -- else -- addr = strtoul (val, NULL, 10); -+ addr = parse_and_eval_address(val); - - /* Here we store the section offsets in the order they were - entered on the command line. */ diff --git a/devel/gdb66/files/patch-version.in b/devel/gdb66/files/patch-version.in deleted file mode 100644 index 4496ebf..0000000 --- a/devel/gdb66/files/patch-version.in +++ /dev/null @@ -1,5 +0,0 @@ ---- gdb/version.in Fri Apr 26 18:04:22 2002 -+++ gdb/version.in Mon Jun 3 08:14:54 2002 -@@ -1 +1 @@ --5.2.90 -+5.3 (FreeBSD) diff --git a/devel/gdb66/pkg-descr b/devel/gdb66/pkg-descr index be3a113..a6e471a 100644 --- a/devel/gdb66/pkg-descr +++ b/devel/gdb66/pkg-descr @@ -1 +1 @@ -GNU GDB 5.3 developmental snapshot. +GNU GDB 6.x developmental snapshot. |