ports/100067: New port: devel/gdb65 GNU GDB 6.5
Philip M. Gollucci
pgollucci at p6m7g8.com
Wed Dec 6 14:50:15 UTC 2006
The following reply was made to PR ports/100067; it has been noted by GNATS.
From: "Philip M. Gollucci" <pgollucci at p6m7g8.com>
To: bug-followup at freebsd.org, pgollucci at p6m7g8.com
Cc:
Subject: Re: ports/100067: New port: devel/gdb65 GNU GDB 6.5
Date: Sun, 03 Dec 2006 04:17:39 -0800
This is a multi-part message in MIME format.
--------------020208080303000907060007
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Fix attached. Its a hack. I can't for the life of me find that "space"
issue. So I hacked/patched the prebuilt configure to just not do the
check. This should be okay since its in the testsuite dir anyway which
I guess we could have just skipped.
Also, I should note, I forgot to say you should ask for a repo copy from
devel/gdb6.
--
------------------------------------------------------------------------
Philip M. Gollucci (pgollucci at p6m7g8.com) 323.219.4708
Consultant / http://p6m7g8.net/Resume/resume.shtml
Senior Software Engineer - TicketMaster - http://ticketmaster.com
1024D/EC88A0BF 0DE5 C55C 6BF3 B235 2DAB B89E 1324 9B4F EC88 A0BF
I never had a dream come true
'Til the day that I found you.
Even though I pretend that I've moved on
You'll always be my baby.
I never found the words to say
You're the one I think about each day
And I know no matter where life takes me to
A part of me will always be...
A part of me will always be with you.
--------------020208080303000907060007
Content-Type: text/plain;
name="gdb65.shar"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="gdb65.shar"
# This is a shell archive. Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file". Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
# gdb65
# gdb65/Makefile
# gdb65/distinfo
# gdb65/pkg-descr
# gdb65/files
# gdb65/files/fbsd4.h
# gdb65/files/freebsd-uthread.c
# gdb65/files/patch-gdb-Makefile.in
# gdb65/files/nm-fbsd.h
# gdb65/files/patch-gdb-version.in
# gdb65/files/patch-gdb-testsuite-configure
# gdb65/pkg-plist
#
echo c - gdb65
mkdir -p gdb65 > /dev/null 2>&1
echo x - gdb65/Makefile
sed 's/^X//' >gdb65/Makefile << 'END-of-gdb65/Makefile'
X# ex:ts=8
X# Ports collection makefile for: GDB 6.5
X# Date created: 10 July 2006
X# Whom: Philip M. Gollucci <pgollucci at p6m7g8.com>
X#
X# $FreeBSD$
X#
X
XPORTNAME= gdb
XPORTVERSION= 6.5
XCATEGORIES= devel
XMASTER_SITES= ${MASTER_SITE_GNU}
XMASTER_SITE_SUBDIR= gdb
XDISTNAME= gdb-${PORTVERSION}
X
XMAINTAINER= pgollucci at p6m7g8.com
XCOMMENT= GNU GDB 6.5
X
XUSE_BZIP2= yes
XGNU_CONFIGURE= yes
XCONFIGURE_ARGS= --program-suffix=6.5
XCFLAGS+= -DRL_NO_COMPAT -DKGDB
X
X.include <bsd.port.pre.mk>
X
X.if ${OSVERSION} < 500000
XCFLAGS+= -include ${FILESDIR}/fbsd4.h
X.endif
X
X.if ${ARCH} == "amd64"
XCONFIGURE_TARGET= x86_64-portbld-freebsd${OSREL}
X.endif
X
Xpre-configure:
X cd ${WRKSRC} ; ${RM} -rf dejagnu expect readline sim tcl texinfo
X ${LN} -sf ${FILESDIR}/freebsd-uthread.c ${WRKSRC}/gdb/freebsd-uthread.c
X ${LN} -sf ${FILESDIR}/nm-fbsd.h ${WRKSRC}/gdb/config
X
Xpost-configure:
X ${PERL} -pi -ane 'next unless /CFLAGS/; s,\s+, ,g' ${WRKSRC}/config.status
Xdo-install:
X ${INSTALL_PROGRAM} ${WRKSRC}/gdb/gdb \
X ${PREFIX}/bin/${PORTNAME}${PORTVERSION:S/.//g}
X
Xc:
X @${ECHO} ${CFLAGS}
X.include <bsd.port.post.mk>
END-of-gdb65/Makefile
echo x - gdb65/distinfo
sed 's/^X//' >gdb65/distinfo << 'END-of-gdb65/distinfo'
XMD5 (gdb-6.5.tar.bz2) = af6c8335230d7604aee0803b1df14f54
XSHA256 (gdb-6.5.tar.bz2) = 0011318d9720781d486c835e88b915f90f2c10e7101d648b64dd4739218d3faf
XSIZE (gdb-6.5.tar.bz2) = 14303558
END-of-gdb65/distinfo
echo x - gdb65/pkg-descr
sed 's/^X//' >gdb65/pkg-descr << 'END-of-gdb65/pkg-descr'
XGNU GDB 6.5
X
XWWW: http://www.gnu.org/software/gdb/bugs/
END-of-gdb65/pkg-descr
echo c - gdb65/files
mkdir -p gdb65/files > /dev/null 2>&1
echo x - gdb65/files/fbsd4.h
sed 's/^X//' >gdb65/files/fbsd4.h << 'END-of-gdb65/files/fbsd4.h'
X// $FreeBSD: ports/devel/gdb6/files/fbsd4.h,v 1.2 2005/03/11 04:52:49 obrien Exp $
X
Xextern void _rl_set_screen_size (int, int);
X
X#define rl_set_screen_size _rl_set_screen_size
X#define rl_filename_completion_function filename_completion_function
X
Xextern int screenwidth, screenheight;
X
Xstatic inline void
Xrl_get_screen_size (int *rows, int *cols)
X{
X if (rows) *rows = screenheight;
X if (cols) *cols = screenwidth;
X}
X
X#if 0
X#define savestring
X#include <readline/readline.h>
X#undef savestring
X#endif
END-of-gdb65/files/fbsd4.h
echo x - gdb65/files/freebsd-uthread.c
sed 's/^X//' >gdb65/files/freebsd-uthread.c << 'END-of-gdb65/files/freebsd-uthread.c'
X/* Low level interface for debugging FreeBSD user threads for GDB, the GNU debugger.
X Copyright 1996, 1999 Free Software Foundation, Inc.
X
XThis file is part of GDB.
X
XThis program is free software; you can redistribute it and/or modify
Xit under the terms of the GNU General Public License as published by
Xthe Free Software Foundation; either version 2 of the License, or
X(at your option) any later version.
X
XThis program is distributed in the hope that it will be useful,
Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
XGNU General Public License for more details.
X
XYou should have received a copy of the GNU General Public License
Xalong with this program; if not, write to the Free Software
XFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
X
X/* $FreeBSD: ports/devel/gdb6/files/freebsd-uthread.c,v 1.4 2004/10/20 19:37:48 obrien Exp $ */
X
X/* This module implements a sort of half target that sits between the
X machine-independent parts of GDB and the ptrace interface (infptrace.c) to
X provide access to the FreeBSD user-mode thread implementation.
X
X FreeBSD threads are true user-mode threads, which are invoked via
X the pthread_* interfaces. These are mostly implemented in
X user-space, with all thread context kept in various structures that
X live in the user's heap. For the most part, the kernel has no
X knowlege of these threads.
X
X Based largely on hpux-thread.c
X
X */
X
X
X#include "defs.h"
X#include <sys/queue.h>
X#include <signal.h>
X#include <setjmp.h>
X#include <string.h>
X#include "gdbthread.h"
X#include "target.h"
X#include "inferior.h"
X#include <fcntl.h>
X#include <ucontext.h>
X#include <unistd.h>
X#include <sys/stat.h>
X#include "gdbcore.h"
X#include "regcache.h"
X
Xextern int child_suppress_run;
Xextern struct target_ops child_ops; /* target vector for inftarg.c */
X
Xextern void _initialize_freebsd_uthread PARAMS ((void));
X
X/* Set to true while we are part-way through attaching */
Xstatic int freebsd_uthread_attaching;
X
Xstatic int freebsd_uthread_active = 0;
Xstatic CORE_ADDR P_thread_list;
Xstatic CORE_ADDR P_thread_run;
X
X/* Pointer to the next function on the objfile event chain. */
Xstatic void (*target_new_objfile_chain) (struct objfile *objfile);
X
Xstatic void freebsd_uthread_resume PARAMS ((ptid_t pid, int step,
X enum target_signal signo));
X
Xstatic void init_freebsd_uthread_ops PARAMS ((void));
X
Xstatic struct target_ops freebsd_uthread_ops;
X
Xstatic ptid_t find_active_ptid PARAMS ((void));
X
Xstruct cached_pthread {
X u_int64_t uniqueid;
X int state;
X CORE_ADDR name;
X union {
X ucontext_t uc;
X jmp_buf jb;
X } ctx;
X};
X
Xstatic ptid_t cached_ptid;
Xstatic struct cached_pthread cached_pthread;
Xstatic CORE_ADDR cached_pthread_addr;
X
XLIST_HEAD(idmaplist, idmap);
X
Xstruct idmap {
X LIST_ENTRY(idmap) link;
X u_int64_t uniqueid;
X int tid;
X};
X
X#define MAPHASH_SIZE 257
X#define TID_MIN 1
X#define TID_MAX 16383
X
Xstatic int tid_to_hash[TID_MAX + 1]; /* set to map_hash index */
Xstatic struct idmaplist map_hash[MAPHASH_SIZE];
Xstatic int next_free_tid = TID_MIN; /* first available tid */
Xstatic int last_free_tid = TID_MIN; /* first unavailable */
X
Xstatic CORE_ADDR P_thread_next_offset;
Xstatic CORE_ADDR P_thread_uniqueid_offset;
Xstatic CORE_ADDR P_thread_state_offset;
Xstatic CORE_ADDR P_thread_name_offset;
Xstatic CORE_ADDR P_thread_ctx_offset;
Xstatic CORE_ADDR P_thread_PS_RUNNING_value;
Xstatic CORE_ADDR P_thread_PS_DEAD_value;
X
Xstatic int next_offset;
Xstatic int uniqueid_offset;
Xstatic int state_offset;
Xstatic int name_offset;
Xstatic int ctx_offset;
Xstatic int PS_RUNNING_value;
Xstatic int PS_DEAD_value;
X
X#define UNIQUEID_HASH(id) (id % MAPHASH_SIZE)
X#define TID_ADD1(tid) (((tid) + 1) == TID_MAX + 1 \
X ? TID_MIN : (tid) + 1)
X#define IS_TID_FREE(tid) (tid_to_hash[tid] == -1)
X
Xstatic int
Xget_new_tid(int h)
X{
X int tid = next_free_tid;
X
X tid_to_hash[tid] = h;
X next_free_tid = TID_ADD1(next_free_tid);
X if (next_free_tid == last_free_tid)
X {
X int i;
X
X for (i = last_free_tid; TID_ADD1(i) != last_free_tid; i = TID_ADD1(i))
X if (IS_TID_FREE(i))
X break;
X if (TID_ADD1(i) == last_free_tid)
X {
X error("too many threads");
X return 0;
X }
X next_free_tid = i;
X for (i = TID_ADD1(i); IS_TID_FREE(i); i = TID_ADD1(i))
X ;
X last_free_tid = i;
X }
X
X return tid;
X}
X
Xstatic ptid_t
Xfind_ptid(u_int64_t uniqueid)
X{
X int h = UNIQUEID_HASH(uniqueid);
X struct idmap *im;
X
X LIST_FOREACH(im, &map_hash[h], link)
X if (im->uniqueid == uniqueid)
X return MERGEPID(PIDGET(inferior_ptid), im->tid);
X
X im = xmalloc(sizeof(struct idmap));
X im->uniqueid = uniqueid;
X im->tid = get_new_tid(h);
X LIST_INSERT_HEAD(&map_hash[h], im, link);
X
X return MERGEPID(PIDGET(inferior_ptid), im->tid);
X}
X
Xstatic void
Xfree_ptid(ptid_t ptid)
X{
X int tid = TIDGET(ptid);
X int h = tid_to_hash[tid];
X struct idmap *im;
X
X if (!tid) return;
X
X LIST_FOREACH(im, &map_hash[h], link)
X if (im->tid == tid)
X break;
X
X if (!im) return;
X
X LIST_REMOVE(im, link);
X tid_to_hash[tid] = -1;
X free(im);
X}
X
X#define READ_OFFSET(field) read_memory(P_thread_##field##_offset, \
X (char *) &field##_offset, \
X sizeof(field##_offset))
X
X#define READ_VALUE(name) read_memory(P_thread_##name##_value, \
X (char *) &name##_value, \
X sizeof(name##_value))
X
Xstatic void
Xread_thread_offsets (void)
X{
X READ_OFFSET(next);
X READ_OFFSET(uniqueid);
X READ_OFFSET(state);
X READ_OFFSET(name);
X READ_OFFSET(ctx);
X
X READ_VALUE(PS_RUNNING);
X READ_VALUE(PS_DEAD);
X}
X
X#define READ_FIELD(ptr, T, field, result) \
X read_memory ((ptr) + field##_offset, (char *) &(result), sizeof result)
X
Xstatic u_int64_t
Xread_pthread_uniqueid (CORE_ADDR ptr)
X{
X u_int64_t uniqueid;
X READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid);
X return uniqueid;
X}
X
Xstatic CORE_ADDR
Xread_pthread_next (CORE_ADDR ptr)
X{
X CORE_ADDR next;
X READ_FIELD(ptr, CORE_ADDR, next, next);
X return next;
X}
X
Xstatic void
Xread_cached_pthread (CORE_ADDR ptr, struct cached_pthread *cache)
X{
X READ_FIELD(ptr, u_int64_t, uniqueid, cache->uniqueid);
X READ_FIELD(ptr, int, state, cache->state);
X READ_FIELD(ptr, CORE_ADDR, name, cache->name);
X READ_FIELD(ptr, ucontext_t, ctx, cache->ctx);
X}
X
Xstatic ptid_t
Xfind_active_ptid (void)
X{
X CORE_ADDR ptr;
X
X read_memory ((CORE_ADDR)P_thread_run,
X (char *)&ptr,
X sizeof ptr);
X
X return find_ptid(read_pthread_uniqueid(ptr));
X}
X
Xstatic CORE_ADDR find_pthread_addr PARAMS ((ptid_t ptid));
Xstatic struct cached_pthread * find_pthread PARAMS ((ptid_t ptid));
X
Xstatic CORE_ADDR
Xfind_pthread_addr (ptid_t ptid)
X{
X CORE_ADDR ptr;
X
X if (ptid_equal(ptid, cached_ptid))
X return cached_pthread_addr;
X
X read_memory ((CORE_ADDR)P_thread_list,
X (char *)&ptr,
X sizeof ptr);
X
X while (ptr != 0)
X {
X if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid))
X {
X cached_ptid = ptid;
X cached_pthread_addr = ptr;
X read_cached_pthread(ptr, &cached_pthread);
X return ptr;
X }
X ptr = read_pthread_next(ptr);
X }
X
X return NULL;
X}
X
Xstatic struct cached_pthread *
Xfind_pthread (ptid_t ptid)
X{
X CORE_ADDR ptr;
X
X if (ptid_equal(ptid, cached_ptid))
X return &cached_pthread;
X
X read_memory ((CORE_ADDR)P_thread_list,
X (char *)&ptr,
X sizeof ptr);
X
X while (ptr != 0)
X {
X if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid))
X {
X cached_ptid = ptid;
X cached_pthread_addr = ptr;
X read_cached_pthread(ptr, &cached_pthread);
X return &cached_pthread;
X }
X ptr = read_pthread_next(ptr);
X }
X
X#if 0
X error ("Can't find pthread %d,%d", PIDGET(ptid), TIDGET(ptid));
X#endif
X return NULL;
X}
X
X
X/* Most target vector functions from here on actually just pass through to
X inftarg.c, as they don't need to do anything specific for threads. */
X
X/* ARGSUSED */
Xstatic void
Xfreebsd_uthread_open (char *arg, int from_tty)
X{
X child_ops.to_open (arg, from_tty);
X}
X
X/* Attach to process PID, then initialize for debugging it
X and wait for the trace-trap that results from attaching. */
X
Xstatic void
Xfreebsd_uthread_attach (char *args, int from_tty)
X{
X child_ops.to_attach (args, from_tty);
X push_target (&freebsd_uthread_ops);
X freebsd_uthread_attaching = 1;
X}
X
X/* After an attach, see if the target is threaded */
X
Xstatic void
Xfreebsd_uthread_post_attach (int pid)
X{
X if (freebsd_uthread_active)
X {
X read_thread_offsets ();
X inferior_ptid = find_active_ptid ();
X add_thread (inferior_ptid);
X }
X else
X {
X unpush_target (&freebsd_uthread_ops);
X push_target (&child_ops);
X }
X
X freebsd_uthread_attaching = 0;
X}
X
X/* Take a program previously attached to and detaches it.
X The program resumes execution and will no longer stop
X on signals, etc. We'd better not have left any breakpoints
X in the program or it'll die when it hits one. For this
X to work, it may be necessary for the process to have been
X previously attached. It *might* work if the program was
X started via the normal ptrace (PTRACE_TRACEME). */
X
Xstatic void
Xfreebsd_uthread_detach (char *args, int from_tty)
X{
X child_ops.to_detach (args, from_tty);
X}
X
X/* Resume execution of process PID. If STEP is nozero, then
X just single step it. If SIGNAL is nonzero, restart it with that
X signal activated. We may have to convert pid from a thread-id to an LWP id
X for procfs. */
X
Xstatic void
Xfreebsd_uthread_resume (ptid_t ptid, int step, enum target_signal signo)
X{
X if (freebsd_uthread_attaching)
X {
X child_ops.to_resume (ptid, step, signo);
X return;
X }
X
X child_ops.to_resume (ptid, step, signo);
X cached_ptid = MERGEPID(0, 0);
X}
X
X/* Wait for any threads to stop. We may have to convert PID from a thread id
X to a LWP id, and vice versa on the way out. */
X
Xstatic ptid_t
Xfreebsd_uthread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
X{
X ptid_t rtnval;
X
X if (freebsd_uthread_attaching)
X {
X return child_ops.to_wait (ptid, ourstatus);
X }
X
X rtnval = child_ops.to_wait (ptid, ourstatus);
X
X if (PIDGET(rtnval) >= 0)
X {
X rtnval = find_active_ptid ();
X if (!in_thread_list (rtnval))
X add_thread (rtnval);
X }
X
X return rtnval;
X}
X
X/* XXX: this needs to be selected by target, not [build] host */
X#ifdef __i386__
X
X#include "i386-tdep.h"
X
Xstatic char sigmap[I386_SSE_NUM_REGS] = /* map reg to sigcontext */
X{
X 12, /* eax */
X 11, /* ecx */
X 10, /* edx */
X 9, /* ebx */
X 8, /* esp */
X 7, /* ebp */
X 6, /* esi */
X 5, /* edi */
X 15, /* eip */
X 17, /* eflags */
X 16, /* cs */
X 19, /* ss */
X 4, /* ds */
X 3, /* es */
X 2, /* fs */
X 1, /* gs */
X -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */
X -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */
X -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */
X -1, /* mxcsr */
X};
X
Xstatic char jmpmap[I386_SSE_NUM_REGS] = /* map reg to jmp_buf */
X{
X 6, /* eax */
X -1, /* ecx */
X -1, /* edx */
X 1, /* ebx */
X 2, /* esp */
X 3, /* ebp */
X 4, /* esi */
X 5, /* edi */
X 0, /* eip */
X -1, /* eflags */
X -1, /* cs */
X -1, /* ss */
X -1, /* ds */
X -1, /* es */
X -1, /* fs */
X -1, /* gs */
X -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */
X -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */
X -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */
X -1, /* mxcsr */
X};
X
X#endif
X
X#ifdef __amd64__
X
X#include "amd64-tdep.h"
X
X// XXX:DEO not fully ported from i386 yet!!
X
Xstatic char sigmap[AMD64_NUM_REGS_TOTAL] = /* map reg to sigcontext */
X{
X 12, /* rax */
X 11, /* rcx */
X 10, /* rdx */
X 9, /* rbx */
X 8, /* rsp */
X 7, /* rbp */
X 6, /* rsi */
X 5, /* rdi */
X 15, /* rip */
X 17, /* rflags */
X 16, /* cs */
X 19, /* ss */
X 4, /* ds */
X 3, /* es */
X 2, /* fs */
X 1, /* gs */
X -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */
X -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */
X -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */
X -1, /* mxcsr */
X};
X
Xstatic char jmpmap[AMD64_NUM_REGS_TOTAL] = /* map reg to jmp_buf */
X{
X 6, /* rax */
X -1, /* rcx */
X -1, /* rdx */
X 1, /* rbx */
X 2, /* rsp */
X 3, /* rbp */
X 4, /* rsi */
X 5, /* rdi */
X 0, /* rip */
X -1, /* rflags */
X -1, /* cs */
X -1, /* ss */
X -1, /* ds */
X -1, /* es */
X -1, /* fs */
X -1, /* gs */
X -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */
X -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */
X -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */
X -1, /* mxcsr */
X};
X
X#endif
X
X#ifdef __alpha__
X
X#include "alpha-tdep.h"
X
Xstatic char sigmap[ALPHA_NUM_REGS] = /* map reg to sigcontext */
X{
X 1, 2, 3, 4, 5, 6, 7, 8, /* v0 - t6 */
X 9, 10, 11, 12, 13, 14, 15, 16, /* t7 - fp */
X 17, 18, 19, 20, 21, 22, 23, 24, /* a0 - t9 */
X 25, 26, 27, 28, 29, 30, 31, 32, /* t10 - zero */
X 38, 39, 40, 41, 42, 43, 44, 45, /* f0 - f7 */
X 46, 47, 48, 49, 50, 51, 52, 53, /* f8 - f15 */
X 54, 55, 56, 57, 58, 59, 60, 61, /* f16 - f23 */
X 62, 63, 64, 65, 66, 67, 68, 69, /* f24 - f31 */
X 33, -1 /* pc, vfp */
X};
Xstatic char jmpmap[ALPHA_NUM_REGS] = {
X 4, 5, 6, 7, 8, 9, 10, 11, /* v0 - t6 */
X 12, 13, 14, 15, 16, 17, 18, 19, /* t7 - fp */
X 20, 21, 22, 23, 24, 25, 26, 27, /* a0 - t9 */
X 28, 29, 30, 31, 32, 33, 34, 35, /* t10 - zero */
X 37, 38, 39, 40, 41, 42, 43, 44, /* f0 - f7 */
X 45, 46, 47, 48, 49, 50, 51, 52, /* f8 - f15 */
X 53, 54, 55, 56, 57, 58, 59, 60, /* f16 - f23 */
X 61, 62, 63, 64, 65, 66, 67, 68, /* f24 - f31 */
X 2, -1, /* pc, vfp */
X};
X
X#endif
X
X#ifdef __sparc64__
X
Xstatic char sigmap[125] = /* map reg to sigcontext */
X{
X -1
X};
Xstatic char jmpmap[125] = {
X -1
X};
X
X#endif
X
Xstatic void
Xfreebsd_uthread_fetch_registers (int regno)
X{
X struct cached_pthread *thread;
X int active;
X int first_regno, last_regno;
X register_t *regbase;
X char *regmap;
X
X if (freebsd_uthread_attaching || TIDGET(inferior_ptid) == 0)
X {
X child_ops.to_fetch_registers (regno);
X return;
X }
X
X thread = find_pthread (inferior_ptid);
X active = (ptid_equal(inferior_ptid, find_active_ptid()));
X
X if (active)
X {
X child_ops.to_fetch_registers (regno);
X return;
X }
X
X if (regno == -1)
X {
X first_regno = 0;
X last_regno = NUM_REGS - 1;
X }
X else
X {
X first_regno = regno;
X last_regno = regno;
X }
X
X regbase = (register_t*) &thread->ctx.jb[0];
X regmap = jmpmap;
X
X for (regno = first_regno; regno <= last_regno; regno++)
X {
X if (regmap[regno] == -1)
X child_ops.to_fetch_registers (regno);
X else
X if (thread)
X regcache_raw_supply (current_regcache, regno, (char*) ®base[regmap[regno]]);
X else
X regcache_raw_supply (current_regcache, regno, NULL);
X }
X}
X
Xstatic void
Xfreebsd_uthread_store_registers (int regno)
X{
X struct cached_pthread *thread;
X CORE_ADDR ptr;
X int first_regno, last_regno;
X u_int32_t *regbase;
X char *regmap;
X
X if (freebsd_uthread_attaching)
X {
X child_ops.to_store_registers (regno);
X return;
X }
X
X thread = find_pthread (inferior_ptid);
X
X if (thread->state == PS_RUNNING_value)
X {
X child_ops.to_store_registers (regno);
X return;
X }
X
X if (regno == -1)
X {
X first_regno = 0;
X last_regno = NUM_REGS - 1;
X }
X else
X {
X first_regno = regno;
X last_regno = regno;
X }
X
X regbase = (u_int32_t*) &thread->ctx.jb[0];
X regmap = jmpmap;
X
X ptr = find_pthread_addr (inferior_ptid);
X for (regno = first_regno; regno <= last_regno; regno++)
X {
X if (regmap[regno] == -1)
X child_ops.to_store_registers (regno);
X else
X {
X u_int32_t *reg = ®base[regmap[regno]];
X int off;
X
X /* Hang onto cached value */
X/*DEO:XXX*/
X memcpy(reg, deprecated_registers /*regcache_collect ()*/+ DEPRECATED_REGISTER_BYTE (regno),
X register_size (current_gdbarch, regno));
X
X /* And push out to inferior */
X off = (char *) reg - (char *) thread;
X write_memory (ptr + off,
X/*DEO:XXX*/
X deprecated_registers /*regcache_collect ()*/+ DEPRECATED_REGISTER_BYTE (regno),
X register_size (current_gdbarch, regno));
X }
X }
X}
X
X/* Get ready to modify the registers array. On machines which store
X individual registers, this doesn't need to do anything. On machines
X which store all the registers in one fell swoop, this makes sure
X that registers contains all the registers from the program being
X debugged. */
X
Xstatic void
Xfreebsd_uthread_prepare_to_store (void)
X{
X child_ops.to_prepare_to_store ();
X}
X
Xstatic int
Xfreebsd_uthread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
X int dowrite, struct mem_attrib *attrib,
X struct target_ops *target)
X{
X return child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite,
X attrib, target);
X}
X
X/* Print status information about what we're accessing. */
X
Xstatic void
Xfreebsd_uthread_files_info (struct target_ops *ignore)
X{
X child_ops.to_files_info (ignore);
X}
X
Xstatic void
Xfreebsd_uthread_kill_inferior (void)
X{
X child_ops.to_kill ();
X}
X
Xstatic void
Xfreebsd_uthread_notice_signals (ptid_t ptid)
X{
X child_ops.to_notice_signals (ptid);
X}
X
X/* Fork an inferior process, and start debugging it with /proc. */
X
Xstatic void
Xfreebsd_uthread_create_inferior (char *exec_file, char *allargs, char **env,
X int from_tty)
X{
X child_ops.to_create_inferior (exec_file, allargs, env, from_tty);
X
X if (PIDGET(inferior_ptid) && freebsd_uthread_active)
X {
X read_thread_offsets ();
X push_target (&freebsd_uthread_ops);
X inferior_ptid = find_active_ptid ();
X add_thread (inferior_ptid);
X }
X}
X
X/* This routine is called to find out if the inferior is using threads.
X We check for the _thread_run and _thread_list globals. */
X
Xvoid
Xfreebsd_uthread_new_objfile (struct objfile *objfile)
X{
X struct minimal_symbol *ms;
X
X if (!objfile)
X {
X freebsd_uthread_active = 0;
X return;
X }
X
X ms = lookup_minimal_symbol ("_thread_run", NULL, objfile);
X
X if (!ms)
X return;
X
X P_thread_run = SYMBOL_VALUE_ADDRESS (ms);
X
X ms = lookup_minimal_symbol ("_thread_list", NULL, objfile);
X
X if (!ms)
X return;
X
X P_thread_list = SYMBOL_VALUE_ADDRESS (ms);
X
X#define OFFSET_SYM(field) "_thread_" #field "_offset"
X#define LOOKUP_OFFSET(field) \
X do { \
X ms = lookup_minimal_symbol (OFFSET_SYM(field), NULL, objfile); \
X if (!ms) \
X return; \
X P_thread_##field##_offset = SYMBOL_VALUE_ADDRESS (ms); \
X } while (0);
X
X#define VALUE_SYM(name) "_thread_" #name "_value"
X#define LOOKUP_VALUE(name) \
X do { \
X ms = lookup_minimal_symbol (VALUE_SYM(name), NULL, objfile); \
X if (!ms) \
X return; \
X P_thread_##name##_value = SYMBOL_VALUE_ADDRESS (ms); \
X } while (0);
X
X LOOKUP_OFFSET(next);
X LOOKUP_OFFSET(uniqueid);
X LOOKUP_OFFSET(state);
X LOOKUP_OFFSET(name);
X LOOKUP_OFFSET(ctx);
X
X LOOKUP_VALUE(PS_RUNNING);
X LOOKUP_VALUE(PS_DEAD);
X
X freebsd_uthread_active = 1;
X}
X
X/* Clean up after the inferior dies. */
X
Xstatic void
Xfreebsd_uthread_mourn_inferior ()
X{
X child_ops.to_mourn_inferior ();
X unpush_target (&freebsd_uthread_ops);
X}
X
X/* Mark our target-struct as eligible for stray "run" and "attach" commands. */
X
Xstatic int
Xfreebsd_uthread_can_run ()
X{
X return child_suppress_run;
X}
X
Xstatic int
Xfreebsd_uthread_thread_alive (ptid_t ptid)
X{
X struct cached_pthread *thread;
X int ret = 0;
X
X if (freebsd_uthread_attaching)
X return 1;
X
X /*
X * We can get called from child_ops.to_wait() which passes the underlying
X * pid (without a thread number).
X */
X if (TIDGET(ptid) == 0)
X return 1;
X
X if (find_pthread_addr (ptid) != 0)
X {
X thread = find_pthread (ptid);
X ret = (thread->state != PS_DEAD_value);
X }
X
X if (!ret)
X free_ptid(ptid);
X
X return ret;
X}
X
Xstatic void
Xfreebsd_uthread_stop (void)
X{
X child_ops.to_stop ();
X}
X
Xstatic void
Xfreebsd_uthread_find_new_threads (void)
X{
X CORE_ADDR ptr;
X int state;
X u_int64_t uniqueid;
X
X read_memory ((CORE_ADDR)P_thread_list,
X (char *)&ptr,
X sizeof ptr);
X
X while (ptr != 0)
X {
X READ_FIELD(ptr, int, state, state);
X READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid);
X if (state != PS_DEAD_value &&
X !in_thread_list (find_ptid(uniqueid)))
X add_thread (find_ptid(uniqueid));
X ptr = read_pthread_next(ptr);
X }
X}
X
X/* MUST MATCH enum pthread_state */
Xstatic const char *statenames[] = {
X "RUNNING",
X "SIGTHREAD",
X "MUTEX_WAIT",
X "COND_WAIT",
X "FDLR_WAIT",
X "FDLW_WAIT",
X "FDR_WAIT",
X "FDW_WAIT",
X "POLL_WAIT",
X "FILE_WAIT",
X "SELECT_WAIT",
X "SLEEP_WAIT",
X "WAIT_WAIT",
X "SIGSUSPEND",
X "SIGWAIT",
X "SPINBLOCK",
X "JOIN",
X "SUSPENDED",
X "DEAD",
X "DEADLOCK",
X};
X
X#if 0
X
Xstatic int
Xfreebsd_uthread_get_thread_info (ref, selection, info)
X gdb_threadref *ref;
X int selection;
X struct gdb_ext_thread_info *info;
X{
X int pid = *ref;
X struct cached_pthread *thread = find_pthread (pid);
X struct cleanup *old_chain;
X
X old_chain = save_inferior_pid ();
X inferior_pid = main_pid;
X
X memset(&info->threadid, 0, OPAQUETHREADBYTES);
X
X memcpy(&info->threadid, ref, sizeof *ref);
X info->active = thread->state == PS_RUNNING_value;
X strcpy(info->display, statenames[thread->state]);
X if (thread->name)
X read_memory ((CORE_ADDR) thread->name, info->shortname, 32);
X else
X strcpy(info->shortname, "");
X
X do_cleanups (old_chain);
X return (0);
X}
X
X#endif
X
Xchar *
Xfreebsd_uthread_pid_to_str (ptid_t ptid)
X{
X static char buf[30];
X
X if (DEPRECATED_STREQ (current_target.to_shortname, "freebsd-uthreads"))
X sprintf (buf, "Process %d, Thread %ld",
X PIDGET(ptid), TIDGET(ptid));
X else
X sprintf (buf, "Process %d", PIDGET(ptid));
X
X return buf;
X}
X
X
Xstatic void
Xinit_freebsd_uthread_ops ()
X{
X freebsd_uthread_ops.to_shortname = "freebsd-uthreads";
X freebsd_uthread_ops.to_longname = "FreeBSD uthreads";
X freebsd_uthread_ops.to_doc = "FreeBSD user threads support.";
X freebsd_uthread_ops.to_open = freebsd_uthread_open;
X freebsd_uthread_ops.to_attach = freebsd_uthread_attach;
X freebsd_uthread_ops.to_post_attach = freebsd_uthread_post_attach;
X freebsd_uthread_ops.to_detach = freebsd_uthread_detach;
X freebsd_uthread_ops.to_resume = freebsd_uthread_resume;
X freebsd_uthread_ops.to_wait = freebsd_uthread_wait;
X freebsd_uthread_ops.to_fetch_registers = freebsd_uthread_fetch_registers;
X freebsd_uthread_ops.to_store_registers = freebsd_uthread_store_registers;
X freebsd_uthread_ops.to_prepare_to_store = freebsd_uthread_prepare_to_store;
X freebsd_uthread_ops.to_xfer_memory = freebsd_uthread_xfer_memory;
X freebsd_uthread_ops.to_files_info = freebsd_uthread_files_info;
X freebsd_uthread_ops.to_insert_breakpoint = memory_insert_breakpoint;
X freebsd_uthread_ops.to_remove_breakpoint = memory_remove_breakpoint;
X freebsd_uthread_ops.to_terminal_init = terminal_init_inferior;
X freebsd_uthread_ops.to_terminal_inferior = terminal_inferior;
X freebsd_uthread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
X freebsd_uthread_ops.to_terminal_ours = terminal_ours;
X freebsd_uthread_ops.to_terminal_info = child_terminal_info;
X freebsd_uthread_ops.to_kill = freebsd_uthread_kill_inferior;
X freebsd_uthread_ops.to_create_inferior = freebsd_uthread_create_inferior;
X freebsd_uthread_ops.to_mourn_inferior = freebsd_uthread_mourn_inferior;
X freebsd_uthread_ops.to_can_run = freebsd_uthread_can_run;
X freebsd_uthread_ops.to_notice_signals = freebsd_uthread_notice_signals;
X freebsd_uthread_ops.to_thread_alive = freebsd_uthread_thread_alive;
X freebsd_uthread_ops.to_stop = freebsd_uthread_stop;
X freebsd_uthread_ops.to_stratum = process_stratum;
X freebsd_uthread_ops.to_has_all_memory = 1;
X freebsd_uthread_ops.to_has_memory = 1;
X freebsd_uthread_ops.to_has_stack = 1;
X freebsd_uthread_ops.to_has_registers = 1;
X freebsd_uthread_ops.to_has_execution = 1;
X freebsd_uthread_ops.to_has_thread_control = 0;
X freebsd_uthread_ops.to_magic = OPS_MAGIC;
X freebsd_uthread_ops.to_find_new_threads = freebsd_uthread_find_new_threads;
X freebsd_uthread_ops.to_pid_to_str = freebsd_uthread_pid_to_str;
X#if 0
X freebsd_uthread_vec.get_thread_info = freebsd_uthread_get_thread_info;
X#endif
X}
X
Xvoid
X_initialize_freebsd_uthread ()
X{
X init_freebsd_uthread_ops ();
X add_target (&freebsd_uthread_ops);
X
X target_new_objfile_chain = deprecated_target_new_objfile_hook;
X deprecated_target_new_objfile_hook = freebsd_uthread_new_objfile;
X
X child_suppress_run = 1;
X}
END-of-gdb65/files/freebsd-uthread.c
echo x - gdb65/files/patch-gdb-Makefile.in
sed 's/^X//' >gdb65/files/patch-gdb-Makefile.in << 'END-of-gdb65/files/patch-gdb-Makefile.in'
X--- gdb/Makefile.in.orig Mon Jul 10 23:49:02 2006
X+++ gdb/Makefile.in Mon Jul 10 23:50:38 2006
X@@ -122,10 +122,10 @@
X BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC)
X
X # Where is the READLINE library? Typically in ../readline.
X-READLINE_DIR = ../readline
X-READLINE = $(READLINE_DIR)/libreadline.a
X-READLINE_SRC = $(srcdir)/$(READLINE_DIR)
X-READLINE_CFLAGS = -I$(READLINE_SRC)/..
X+#READLINE_DIR = ../readline
X+#READLINE = $(READLINE_DIR)/libreadline.a
X+#READLINE_SRC = $(srcdir)/$(READLINE_DIR)
X+#READLINE_CFLAGS = -I$(READLINE_SRC)/..
X
X WARN_CFLAGS = @WARN_CFLAGS@
X WERROR_CFLAGS = @WERROR_CFLAGS@
X@@ -590,9 +590,9 @@
X demangle_h = $(INCLUDE_DIR)/demangle.h
X obstack_h = $(INCLUDE_DIR)/obstack.h
X opcode_m68hc11_h = $(INCLUDE_DIR)/opcode/m68hc11.h
X-readline_h = $(READLINE_SRC)/readline.h
X-readline_tilde_h = $(READLINE_SRC)/tilde.h
X-readline_history_h = $(READLINE_SRC)/history.h
X+#readline_h = $(READLINE_SRC)/readline.h
X+#readline_tilde_h = $(READLINE_SRC)/tilde.h
X+#readline_history_h = $(READLINE_SRC)/history.h
X frv_desc_h = $(OPCODES_SRC)/frv-desc.h
X sh_opc_h = $(OPCODES_SRC)/sh-opc.h
X gdb_callback_h = $(INCLUDE_DIR)/gdb/callback.h
X@@ -3171,3 +3171,4 @@
X $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tui-winsource.c
X
X ### end of the gdb Makefile.in.
X+READLINE = -lreadline
END-of-gdb65/files/patch-gdb-Makefile.in
echo x - gdb65/files/nm-fbsd.h
sed 's/^X//' >gdb65/files/nm-fbsd.h << 'END-of-gdb65/files/nm-fbsd.h'
X#ifndef CONFIG_NM_FBSD_H
X#define CONFIG_NM_FBSD_H
X
X/* $FreeBSD: ports/devel/gdb6/files/nm-fbsd.h,v 1.1 2004/05/13 04:28:38 obrien Exp $ */
X
X#ifdef HAVE_SYS_PARAM_H
X#include <sys/param.h>
X#endif
X
Xextern int kernel_debugging;
Xextern int kernel_writablecore;
X
XCORE_ADDR fbsd_kern_frame_saved_pc(struct frame_info *frame);
X
X#if __FreeBSD_version >= 500032
X#define KGDB 1
X#define ADDITIONAL_OPTIONS \
X {"kernel", no_argument, &kernel_debugging, 1}, \
X {"k", no_argument, &kernel_debugging, 1}, \
X {"wcore", no_argument, &kernel_writablecore, 1}, \
X {"w", no_argument, &kernel_writablecore, 1},
X
X#define ADDITIONAL_OPTION_HELP \
X "\
X --kernel Enable kernel debugging.\n\
X --wcore Make core file writable (only works for /dev/mem).\n\
X This option only works while debugging a kernel !!\n\
X"
X
X#define DEFAULT_PROMPT kernel_debugging?"(kgdb) ":"(gdb) "
X
X/* misuse START_PROGRESS to test whether we're running as kgdb */
X/* START_PROGRESS is called at the top of main */
X#undef START_PROGRESS
X#define START_PROGRESS(STR,N) \
X if (!strcmp (STR, "kgdb")) \
X kernel_debugging = 1;
X#endif
X#endif /* CONFIG_NM_FBSD_H */
END-of-gdb65/files/nm-fbsd.h
echo x - gdb65/files/patch-gdb-version.in
sed 's/^X//' >gdb65/files/patch-gdb-version.in << 'END-of-gdb65/files/patch-gdb-version.in'
X--- gdb/version.in.orig Tue Jun 20 22:05:40 2006
X+++ gdb/version.in Mon Jul 10 23:17:58 2006
X@@ -1 +1 @@
X-6.5
X+6.5 [GDB v6.x for FreeBSD]
END-of-gdb65/files/patch-gdb-version.in
echo x - gdb65/files/patch-gdb-testsuite-configure
sed 's/^X//' >gdb65/files/patch-gdb-testsuite-configure << 'END-of-gdb65/files/patch-gdb-testsuite-configure'
X--- gdb/testsuite/configure.orig Sun Dec 3 04:06:15 2006
X+++ gdb/testsuite/configure Sun Dec 3 04:06:51 2006
X@@ -1247,16 +1247,6 @@
X echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
X ac_cache_corrupted=: ;;
X ,);;
X- *)
X- if test "x$ac_old_val" != "x$ac_new_val"; then
X- { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
X-echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
X- { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
X-echo "$as_me: former value: $ac_old_val" >&2;}
X- { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
X-echo "$as_me: current value: $ac_new_val" >&2;}
X- ac_cache_corrupted=:
X- fi;;
X esac
X # Pass precious variables to config.status.
X if test "$ac_new_set" = set; then
END-of-gdb65/files/patch-gdb-testsuite-configure
echo x - gdb65/pkg-plist
sed 's/^X//' >gdb65/pkg-plist << 'END-of-gdb65/pkg-plist'
X at comment $FreeBSD$
Xbin/gdb65
END-of-gdb65/pkg-plist
exit
--------------020208080303000907060007--
More information about the freebsd-ports-bugs
mailing list