summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libthread_db/Makefile27
-rw-r--r--lib/libthread_db/arch/alpha/libc_r_md.c73
-rw-r--r--lib/libthread_db/arch/alpha/libpthread_md.c59
-rw-r--r--lib/libthread_db/arch/amd64/libc_r_md.c41
-rw-r--r--lib/libthread_db/arch/amd64/libpthread_md.c59
-rw-r--r--lib/libthread_db/arch/i386/libc_r_md.c48
-rw-r--r--lib/libthread_db/arch/i386/libpthread_md.c (renamed from lib/libthread_db/pthread/pthread_db_i386.c)2
-rw-r--r--lib/libthread_db/arch/ia64/libc_r_md.c41
-rw-r--r--lib/libthread_db/arch/ia64/libpthread_md.c59
-rw-r--r--lib/libthread_db/arch/sparc64/libc_r_md.c41
-rw-r--r--lib/libthread_db/arch/sparc64/libpthread_md.c59
-rw-r--r--lib/libthread_db/include/thread_db.h287
-rw-r--r--lib/libthread_db/libc_r_db.c328
-rw-r--r--lib/libthread_db/libpthread_db.c (renamed from lib/libthread_db/pthread/pthread_db.c)610
-rw-r--r--lib/libthread_db/libpthread_db.h (renamed from lib/libthread_db/pthread/pthread_db.h)42
-rw-r--r--lib/libthread_db/libthr_db.c311
-rw-r--r--lib/libthread_db/pthread/Makefile19
-rw-r--r--lib/libthread_db/src/Makefile15
-rw-r--r--lib/libthread_db/src/thread_db.c359
-rw-r--r--lib/libthread_db/thread_db.c236
-rw-r--r--lib/libthread_db/thread_db.h230
-rw-r--r--lib/libthread_db/thread_db_int.h (renamed from lib/libthread_db/include/thread_db_int.h)83
22 files changed, 1851 insertions, 1178 deletions
diff --git a/lib/libthread_db/Makefile b/lib/libthread_db/Makefile
index e629598..5825cc9 100644
--- a/lib/libthread_db/Makefile
+++ b/lib/libthread_db/Makefile
@@ -1,5 +1,28 @@
# $FreeBSD$
-SUBDIR=pthread src
+.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}
-.include <bsd.subdir.mk>
+LIB= thread_db
+SHLIB_MAJOR= 1
+SRCS= thread_db.c
+SRCS+= libpthread_db.c libpthread_md.c
+SRCS+= libc_r_db.c libc_r_md.c
+SRCS+= libthr_db.c
+INCS= thread_db.h
+WARNS?= 2
+
+CFLAGS+=-I. -I${.CURDIR}
+
+SRCS+= libpthread.h
+CLEANFILES+= libpthread.h
+
+LIBPTHREAD= ${.CURDIR}/../libpthread
+LIBPTHREAD_ARCH= ${LIBPTHREAD}/arch/${MACHINE_ARCH}/include
+
+libpthread.h:
+ @echo '#define LIBTHREAD_DB 1' > ${.TARGET}
+ @echo '#include "${LIBPTHREAD}/sys/lock.h"' >> ${.TARGET}
+ @echo '#include "${LIBPTHREAD_ARCH}/pthread_md.h"' >> ${.TARGET}
+ @echo '#include "${LIBPTHREAD}/thread/thr_private.h"' >> ${.TARGET}
+
+.include <bsd.lib.mk>
diff --git a/lib/libthread_db/arch/alpha/libc_r_md.c b/lib/libthread_db/arch/alpha/libc_r_md.c
new file mode 100644
index 0000000..2f0f7f7
--- /dev/null
+++ b/lib/libthread_db/arch/alpha/libc_r_md.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/procfs.h>
+#include <machine/setjmp.h>
+
+void
+libc_r_md_getgregs(jmp_buf jb, prgregset_t *r)
+{
+ r->r_regs[R_V0] = jb->_jb[4];
+ r->r_regs[R_T0] = jb->_jb[5];
+ r->r_regs[R_T1] = jb->_jb[6];
+ r->r_regs[R_T2] = jb->_jb[7];
+ r->r_regs[R_T3] = jb->_jb[8];
+ r->r_regs[R_T4] = jb->_jb[9];
+ r->r_regs[R_T5] = jb->_jb[10];
+ r->r_regs[R_T6] = jb->_jb[11];
+ r->r_regs[R_T7] = jb->_jb[12];
+ r->r_regs[R_S0] = jb->_jb[13];
+ r->r_regs[R_S1] = jb->_jb[14];
+ r->r_regs[R_S2] = jb->_jb[15];
+ r->r_regs[R_S3] = jb->_jb[16];
+ r->r_regs[R_S4] = jb->_jb[17];
+ r->r_regs[R_S5] = jb->_jb[18];
+ r->r_regs[R_S6] = jb->_jb[19];
+ r->r_regs[R_A0] = jb->_jb[20];
+ r->r_regs[R_A1] = jb->_jb[21];
+ r->r_regs[R_A2] = jb->_jb[22];
+ r->r_regs[R_A3] = jb->_jb[23];
+ r->r_regs[R_A4] = jb->_jb[24];
+ r->r_regs[R_A5] = jb->_jb[25];
+ r->r_regs[R_T8] = jb->_jb[26];
+ r->r_regs[R_T9] = jb->_jb[27];
+ r->r_regs[R_T10] = jb->_jb[28];
+ r->r_regs[R_T11] = jb->_jb[29];
+ r->r_regs[R_RA] = jb->_jb[30];
+ r->r_regs[R_T12] = jb->_jb[31];
+ r->r_regs[R_AT] = jb->_jb[32];
+ r->r_regs[R_GP] = jb->_jb[33];
+ r->r_regs[R_SP] = jb->_jb[34];
+ r->r_regs[R_ZERO] = jb->_jb[35];
+}
+
+void
+libc_r_md_getfpregs(jmp_buf jb, prfpregset_t *r)
+{
+}
diff --git a/lib/libthread_db/arch/alpha/libpthread_md.c b/lib/libthread_db/arch/alpha/libpthread_md.c
new file mode 100644
index 0000000..4959387
--- /dev/null
+++ b/lib/libthread_db/arch/alpha/libpthread_md.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+void
+pt_reg_to_ucontext(const struct reg *r, ucontext_t *uc)
+{
+}
+
+void
+pt_ucontext_to_reg(const ucontext_t *uc, struct reg *r)
+{
+}
+
+void
+pt_fpreg_to_ucontext(const struct fpreg* r, ucontext_t *uc)
+{
+}
+
+void
+pt_ucontext_to_fpreg(const ucontext_t *uc, struct fpreg *r)
+{
+}
+
+void
+pt_md_init(void)
+{
+}
+
+int
+pt_reg_sstep(struct reg *reg, int step)
+{
+ return (0);
+}
diff --git a/lib/libthread_db/arch/amd64/libc_r_md.c b/lib/libthread_db/arch/amd64/libc_r_md.c
new file mode 100644
index 0000000..6c53953
--- /dev/null
+++ b/lib/libthread_db/arch/amd64/libc_r_md.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/procfs.h>
+#include <machine/setjmp.h>
+
+void
+libc_r_md_getgregs(jmp_buf jb, prgregset_t *r)
+{
+}
+
+void
+libc_r_md_getfpregs(jmp_buf jb, prfpregset_t *r)
+{
+}
diff --git a/lib/libthread_db/arch/amd64/libpthread_md.c b/lib/libthread_db/arch/amd64/libpthread_md.c
new file mode 100644
index 0000000..4959387
--- /dev/null
+++ b/lib/libthread_db/arch/amd64/libpthread_md.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+void
+pt_reg_to_ucontext(const struct reg *r, ucontext_t *uc)
+{
+}
+
+void
+pt_ucontext_to_reg(const ucontext_t *uc, struct reg *r)
+{
+}
+
+void
+pt_fpreg_to_ucontext(const struct fpreg* r, ucontext_t *uc)
+{
+}
+
+void
+pt_ucontext_to_fpreg(const ucontext_t *uc, struct fpreg *r)
+{
+}
+
+void
+pt_md_init(void)
+{
+}
+
+int
+pt_reg_sstep(struct reg *reg, int step)
+{
+ return (0);
+}
diff --git a/lib/libthread_db/arch/i386/libc_r_md.c b/lib/libthread_db/arch/i386/libc_r_md.c
new file mode 100644
index 0000000..de27b68
--- /dev/null
+++ b/lib/libthread_db/arch/i386/libc_r_md.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/procfs.h>
+#include <machine/setjmp.h>
+
+void
+libc_r_md_getgregs(jmp_buf jb, prgregset_t r)
+{
+ r->r_eip = jb->_jb[0];
+ r->r_ebx = jb->_jb[1];
+ r->r_esp = jb->_jb[2];
+ r->r_ebp = jb->_jb[3];
+ r->r_esi = jb->_jb[4];
+ r->r_edi = jb->_jb[5];
+ r->r_eax = jb->_jb[6];
+}
+
+void
+libc_r_md_getfpregs(jmp_buf jb, prfpregset_t *r)
+{
+}
diff --git a/lib/libthread_db/pthread/pthread_db_i386.c b/lib/libthread_db/arch/i386/libpthread_md.c
index 4875b74..86bb88d 100644
--- a/lib/libthread_db/pthread/pthread_db_i386.c
+++ b/lib/libthread_db/arch/i386/libpthread_md.c
@@ -33,7 +33,7 @@ __FBSDID("$FreeBSD$");
#include <thread_db.h>
#include <machine/npx.h>
-#include "pthread_db.h"
+#include "libpthread_db.h"
static int has_xmm_regs;
diff --git a/lib/libthread_db/arch/ia64/libc_r_md.c b/lib/libthread_db/arch/ia64/libc_r_md.c
new file mode 100644
index 0000000..6c53953
--- /dev/null
+++ b/lib/libthread_db/arch/ia64/libc_r_md.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/procfs.h>
+#include <machine/setjmp.h>
+
+void
+libc_r_md_getgregs(jmp_buf jb, prgregset_t *r)
+{
+}
+
+void
+libc_r_md_getfpregs(jmp_buf jb, prfpregset_t *r)
+{
+}
diff --git a/lib/libthread_db/arch/ia64/libpthread_md.c b/lib/libthread_db/arch/ia64/libpthread_md.c
new file mode 100644
index 0000000..4959387
--- /dev/null
+++ b/lib/libthread_db/arch/ia64/libpthread_md.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+void
+pt_reg_to_ucontext(const struct reg *r, ucontext_t *uc)
+{
+}
+
+void
+pt_ucontext_to_reg(const ucontext_t *uc, struct reg *r)
+{
+}
+
+void
+pt_fpreg_to_ucontext(const struct fpreg* r, ucontext_t *uc)
+{
+}
+
+void
+pt_ucontext_to_fpreg(const ucontext_t *uc, struct fpreg *r)
+{
+}
+
+void
+pt_md_init(void)
+{
+}
+
+int
+pt_reg_sstep(struct reg *reg, int step)
+{
+ return (0);
+}
diff --git a/lib/libthread_db/arch/sparc64/libc_r_md.c b/lib/libthread_db/arch/sparc64/libc_r_md.c
new file mode 100644
index 0000000..6c53953
--- /dev/null
+++ b/lib/libthread_db/arch/sparc64/libc_r_md.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/procfs.h>
+#include <machine/setjmp.h>
+
+void
+libc_r_md_getgregs(jmp_buf jb, prgregset_t *r)
+{
+}
+
+void
+libc_r_md_getfpregs(jmp_buf jb, prfpregset_t *r)
+{
+}
diff --git a/lib/libthread_db/arch/sparc64/libpthread_md.c b/lib/libthread_db/arch/sparc64/libpthread_md.c
new file mode 100644
index 0000000..4959387
--- /dev/null
+++ b/lib/libthread_db/arch/sparc64/libpthread_md.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+void
+pt_reg_to_ucontext(const struct reg *r, ucontext_t *uc)
+{
+}
+
+void
+pt_ucontext_to_reg(const ucontext_t *uc, struct reg *r)
+{
+}
+
+void
+pt_fpreg_to_ucontext(const struct fpreg* r, ucontext_t *uc)
+{
+}
+
+void
+pt_ucontext_to_fpreg(const ucontext_t *uc, struct fpreg *r)
+{
+}
+
+void
+pt_md_init(void)
+{
+}
+
+int
+pt_reg_sstep(struct reg *reg, int step)
+{
+ return (0);
+}
diff --git a/lib/libthread_db/include/thread_db.h b/lib/libthread_db/include/thread_db.h
deleted file mode 100644
index 82c8dc2..0000000
--- a/lib/libthread_db/include/thread_db.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (c) 2004 David Xu <davidxu@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _THREAD_DB_H_
-#define _THREAD_DB_H_
-
-#include <sys/types.h>
-#include <pthread.h>
-
-typedef enum
-{
- TD_OK,
- TD_ERR,
- TD_NOTHR,
- TD_NOSV,
- TD_NOLWP,
- TD_BADPH,
- TD_BADTH,
- TD_BADSH,
- TD_BADTA,
- TD_BADKEY,
- TD_NOMSG,
- TD_NOFPREGS,
- TD_NOLIBTHREAD,
- TD_NOEVENT,
- TD_NOCAPAB,
- TD_DBERR,
- TD_NOAPLIC,
- TD_NOTSD,
- TD_MALLOC,
- TD_PARTIALREG,
- TD_NOXREGS
-} td_err_e;
-
-typedef enum
-{
- TD_THR_ANY_STATE,
- TD_THR_UNKNOWN,
- TD_THR_STOPPED,
- TD_THR_RUN,
- TD_THR_ACTIVE,
- TD_THR_ZOMBIE,
- TD_THR_SLEEP,
- TD_THR_STOPPED_ASLEEP
-} td_thr_state_e;
-
-typedef enum
-{
- TD_THR_ANY_TYPE,
- TD_THR_USER,
- TD_THR_SYSTEM
-} td_thr_type_e;
-
-typedef long thread_t;
-typedef pthread_key_t thread_key_t;
-typedef struct td_thragent td_thragent_t;
-
-typedef struct td_thrhandle
-{
- td_thragent_t *th_ta_p;
- thread_t th_unique;
- int th_ta_data;
-} td_thrhandle_t;
-
-/* Flags for `td_ta_thr_iter'. */
-#define TD_THR_ANY_USER_FLAGS 0xffffffff
-#define TD_THR_LOWEST_PRIORITY 0
-#define TD_SIGNO_MASK NULL
-
-typedef uint32_t td_thr_events_t;
-
-typedef enum
-{
- TD_ALL_EVENTS,
- TD_EVENT_NONE = TD_ALL_EVENTS,
- TD_CREATE,
- TD_DEATH,
- TD_REAP,
- TD_READY,
- TD_SLEEP,
- TD_SWITCHTO,
- TD_SWITCHFROM,
- TD_LOCK_TRY,
- TD_CATCHSIG,
- TD_IDLE,
- TD_PREEMPT,
- TD_PRI_INHERIT,
- TD_CONCURRENCY,
- TD_TIMEOUT,
- TD_MIN_EVENT_NUM = TD_READY,
- TD_MAX_EVENT_NUM = TD_TIMEOUT,
- TD_EVENTS_ENABLE = 31
-} td_event_e;
-
-typedef enum
-{
- NOTIFY_BPT,
- NOTIFY_AUTOBPT,
- NOTIFY_SYSCALL
-} td_notify_e;
-
-typedef struct td_notify
-{
- td_notify_e type;
- union {
- psaddr_t bptaddr;
- int syscallno;
- } u;
-} td_notify_t;
-
-typedef struct td_event_msg
-{
- td_event_e event;
- const td_thrhandle_t *th_p;
- union {
-#if 0
- td_synchandle_t *sh;
-#endif
- uintptr_t data;
- } msg;
-} td_event_msg_t;
-
-/* Structure containing event data available in each thread structure. */
-typedef struct
-{
- td_thr_events_t eventmask; /* Mask of enabled events. */
- td_event_e eventnum; /* Number of last event. */
- void *eventdata; /* Data associated with event. */
-} td_eventbuf_t;
-
-/* Gathered statistics about the process. */
-typedef struct td_ta_stats
-{
- int nthreads; /* Total number of threads in use. */
- int r_concurrency; /* Concurrency level requested by user. */
- int nrunnable_num; /* Average runnable threads, numerator. */
- int nrunnable_den; /* Average runnable threads, denominator. */
- int a_concurrency_num; /* Achieved concurrency level, numerator. */
- int a_concurrency_den; /* Achieved concurrency level, denominator. */
- int nlwps_num; /* Average number of processes in use,
- numerator. */
- int nlwps_den; /* Average number of processes in use,
- denominator. */
- int nidle_num; /* Average number of idling processes,
- numerator. */
- int nidle_den; /* Average number of idling processes,
- denominator. */
-} td_ta_stats_t;
-
-static inline void
-td_event_emptyset(td_thr_events_t *setp)
-{
- *setp = 0;
-}
-
-static inline void
-td_event_fillset(td_thr_events_t *setp)
-{
- *setp = 0xFFFFFFFF;
-}
-
-static inline void
-td_event_addset(td_thr_events_t *setp, int n)
-{
- *setp |= (1 << (n-1));
-}
-
-static inline void
-td_event_delset(td_thr_events_t *setp, int n)
-{
- *setp &= ~(1 << (n-1));
-}
-
-static inline int
-td_eventismember(td_thr_events_t *setp, int n)
-{
- return (*setp & (1 << (n-1)) ? 1 : 0);
-}
-
-static inline int
-td_eventisempty(td_thr_events_t *setp)
-{
- return (*setp == 0);
-}
-
-typedef int td_thr_iter_f(const td_thrhandle_t *, void *);
-typedef int td_key_iter_f(thread_key_t, void (*) (void *), void *);
-
-struct ps_prochandle;
-
-typedef struct td_thrinfo
-{
- td_thragent_t *ti_ta_p;
- unsigned int ti_user_flags;
- thread_t ti_tid;
- char *ti_tls;
- psaddr_t ti_startfunc;
- psaddr_t ti_stkbase;
- long int ti_stksize;
- psaddr_t ti_ro_area;
- int ti_ro_size;
- td_thr_state_e ti_state;
- unsigned char ti_db_suspended;
- td_thr_type_e ti_type;
- intptr_t ti_pc;
- intptr_t ti_sp;
- short int ti_flags;
- int ti_pri;
- lwpid_t ti_lid;
- sigset_t ti_sigmask;
- unsigned char ti_traceme;
- unsigned char ti_preemptflag;
- unsigned char ti_pirecflag;
- sigset_t ti_pending;
- td_thr_events_t ti_events;
-} td_thrinfo_t;
-
-td_err_e td_init(void);
-td_err_e td_log(void);
-td_err_e td_ta_new(struct ps_prochandle *, td_thragent_t **);
-td_err_e td_ta_delete(td_thragent_t *);
-td_err_e td_ta_get_nthreads(const td_thragent_t *, int *);
-td_err_e td_ta_get_ph(const td_thragent_t *, struct ps_prochandle **);
-td_err_e td_ta_map_id2thr(const td_thragent_t *, thread_t, td_thrhandle_t *);
-td_err_e td_ta_map_lwp2thr(const td_thragent_t *, lwpid_t lwpid,
- td_thrhandle_t *);
-td_err_e td_ta_thr_iter(const td_thragent_t *, td_thr_iter_f *, void *,
- td_thr_state_e, int, sigset_t *, unsigned int);
-td_err_e td_ta_tsd_iter(const td_thragent_t *, td_key_iter_f *, void *);
-td_err_e td_ta_event_addr(const td_thragent_t *, td_event_e , td_notify_t *);
-td_err_e td_ta_set_event(const td_thragent_t *, td_thr_events_t *);
-td_err_e td_ta_clear_event(const td_thragent_t *, td_thr_events_t *);
-td_err_e td_ta_event_getmsg(const td_thragent_t *, td_event_msg_t *);
-td_err_e td_ta_setconcurrency(const td_thragent_t *, int);
-td_err_e td_ta_enable_stats(const td_thragent_t *, int);
-td_err_e td_ta_reset_stats(const td_thragent_t *);
-td_err_e td_ta_get_stats(const td_thragent_t *, td_ta_stats_t *);
-td_err_e td_thr_validate(const td_thrhandle_t *);
-td_err_e td_thr_get_info(const td_thrhandle_t *, td_thrinfo_t *);
-td_err_e td_thr_getfpregs(const td_thrhandle_t *, prfpregset_t *);
-td_err_e td_thr_getgregs(const td_thrhandle_t *, prgregset_t);
-td_err_e td_thr_getxregs(const td_thrhandle_t *, void *);
-td_err_e td_thr_getxregsize(const td_thrhandle_t *, int *);
-td_err_e td_thr_setfpregs(const td_thrhandle_t *, const prfpregset_t *);
-td_err_e td_thr_setgregs(const td_thrhandle_t *, const prgregset_t);
-td_err_e td_thr_setxregs(const td_thrhandle_t *, const void *);
-td_err_e td_thr_event_enable(const td_thrhandle_t *, int);
-td_err_e td_thr_set_event(const td_thrhandle_t *, td_thr_events_t *);
-td_err_e td_thr_clear_event(const td_thrhandle_t *, td_thr_events_t *);
-td_err_e td_thr_event_getmsg(const td_thrhandle_t *, td_event_msg_t *);
-td_err_e td_thr_setprio(const td_thrhandle_t *, int);
-td_err_e td_thr_setsigpending(const td_thrhandle_t *, unsigned char,
- const sigset_t *);
-td_err_e td_thr_sigsetmask(const td_thrhandle_t *, const sigset_t *);
-td_err_e td_thr_tsd(const td_thrhandle_t *, const thread_key_t, void **);
-td_err_e td_thr_dbsuspend(const td_thrhandle_t *);
-td_err_e td_thr_dbresume(const td_thrhandle_t *);
-td_err_e td_get_ta(int pid, td_thragent_t **);
-td_err_e td_ta_activated(td_thragent_t *, int *);
-td_err_e td_thr_sstep(td_thrhandle_t *, int);
-
-#endif
diff --git a/lib/libthread_db/libc_r_db.c b/lib/libthread_db/libc_r_db.c
new file mode 100644
index 0000000..c141f0e
--- /dev/null
+++ b/lib/libthread_db/libc_r_db.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <machine/setjmp.h>
+#include <proc_service.h>
+#include <stdlib.h>
+#include <string.h>
+#include <thread_db.h>
+
+#include "thread_db_int.h"
+
+void libc_r_md_getfpregs(jmp_buf jb, prfpregset_t *);
+void libc_r_md_getgregs(jmp_buf jb, prgregset_t);
+
+struct td_thragent {
+ TD_THRAGENT_FIELDS;
+ struct ps_prochandle *ta_ph;
+ psaddr_t ta_thread_initial;
+ psaddr_t ta_thread_list;
+ psaddr_t ta_thread_run;
+ int ta_ofs_ctx;
+ int ta_ofs_next;
+ int ta_ofs_uniqueid;
+};
+
+static td_err_e
+libc_r_db_init()
+{
+ return (TD_OK);
+}
+
+static td_err_e
+libc_r_db_ta_clear_event(const td_thragent_t *ta, td_thr_events_t *ev)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libc_r_db_ta_delete(td_thragent_t *ta)
+{
+ free(ta);
+ return (TD_OK);
+}
+
+static td_err_e
+libc_r_db_ta_event_addr(const td_thragent_t *ta, td_thr_events_e ev,
+ td_notify_t *n)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libc_r_db_ta_event_getmsg(const td_thragent_t *ta, td_event_msg_t *msg)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libc_r_db_ta_map_id2thr(const td_thragent_t *ta, thread_t tid,
+ td_thrhandle_t *th)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libc_r_db_ta_map_lwp2thr(const td_thragent_t *ta, lwpid_t lwpid,
+ td_thrhandle_t *th)
+{
+ psaddr_t addr;
+ ps_err_e err;
+
+ th->th_ta = ta;
+ err = ps_pread(ta->ta_ph, ta->ta_thread_initial, &addr, sizeof(addr));
+ if (err != PS_OK)
+ return (TD_ERR);
+ if (addr == NULL)
+ return (TD_NOLWP);
+ err = ps_pread(ta->ta_ph, ta->ta_thread_run, &th->th_thread,
+ sizeof(psaddr_t));
+ return ((err == PS_OK) ? TD_OK : TD_ERR);
+}
+
+static td_err_e
+libc_r_db_ta_new(struct ps_prochandle *ph, td_thragent_t **ta_p)
+{
+ td_thragent_t *ta;
+ psaddr_t addr;
+ ps_err_e err;
+
+ ta = malloc(sizeof(td_thragent_t));
+ if (ta == NULL)
+ return (TD_MALLOC);
+
+ ta->ta_ph = ph;
+
+ err = ps_pglobal_lookup(ph, NULL, "_thread_initial",
+ &ta->ta_thread_initial);
+ if (err != PS_OK)
+ goto fail;
+ err = ps_pglobal_lookup(ph, NULL, "_thread_list", &ta->ta_thread_list);
+ if (err != PS_OK)
+ goto fail;
+ err = ps_pglobal_lookup(ph, NULL, "_thread_run", &ta->ta_thread_run);
+ if (err != PS_OK)
+ goto fail;
+ err = ps_pglobal_lookup(ph, NULL, "_thread_ctx_offset", &addr);
+ if (err != PS_OK)
+ goto fail;
+ err = ps_pread(ph, addr, &ta->ta_ofs_ctx, sizeof(int));
+ if (err != PS_OK)
+ goto fail;
+ err = ps_pglobal_lookup(ph, NULL, "_thread_next_offset", &addr);
+ if (err != PS_OK)
+ goto fail;
+ err = ps_pread(ph, addr, &ta->ta_ofs_next, sizeof(int));
+ if (err != PS_OK)
+ goto fail;
+ err = ps_pglobal_lookup(ph, NULL, "_thread_uniqueid_offset", &addr);
+ if (err != PS_OK)
+ goto fail;
+ err = ps_pread(ph, addr, &ta->ta_ofs_uniqueid, sizeof(int));
+ if (err != PS_OK)
+ goto fail;
+
+ *ta_p = ta;
+ return (TD_OK);
+
+ fail:
+ free(ta);
+ *ta_p = NULL;
+ return (TD_ERR);
+}
+
+static td_err_e
+libc_r_db_ta_set_event(const td_thragent_t *ta, td_thr_events_t *ev)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libc_r_db_ta_thr_iter(const td_thragent_t *ta, td_thr_iter_f *cb, void *data,
+ td_thr_state_e state, int pri, sigset_t *mask, unsigned int flags)
+{
+ td_thrhandle_t th;
+ psaddr_t addr;
+ ps_err_e err;
+
+ th.th_ta = ta;
+
+ err = ps_pread(ta->ta_ph, ta->ta_thread_list, &th.th_thread,
+ sizeof(th.th_thread));
+ if (err != PS_OK)
+ return (TD_ERR);
+ while (th.th_thread != NULL) {
+ if (cb(&th, data) != 0)
+ return (TD_OK);
+ addr = (psaddr_t)((uintptr_t)th.th_thread + ta->ta_ofs_next);
+ err = ps_pread(ta->ta_ph, addr, &th.th_thread,
+ sizeof(th.th_thread));
+ if (err != PS_OK)
+ return (TD_ERR);
+ }
+ return (TD_OK);
+}
+
+static td_err_e
+libc_r_db_thr_clear_event(const td_thrhandle_t *th, td_thr_events_t *ev)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libc_r_db_thr_event_enable(const td_thrhandle_t *th, int oo)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libc_r_db_thr_event_getmsg(const td_thrhandle_t *th, td_event_msg_t *msg)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libc_r_db_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *ti)
+{
+ const td_thragent_t *ta;
+ psaddr_t addr, current;
+ ps_err_e err;
+
+ ta = th->th_ta;
+ ti->ti_ta_p = ta;
+ err = ps_pread(ta->ta_ph, ta->ta_thread_run, &current,
+ sizeof(psaddr_t));
+ if (err != PS_OK)
+ return (TD_ERR);
+ ti->ti_lid = (th->th_thread == current) ? -1 : 0;
+ addr = (psaddr_t)((uintptr_t)th->th_thread + ta->ta_ofs_uniqueid);
+ err = ps_pread(ta->ta_ph, addr, &ti->ti_tid, sizeof(thread_t));
+ /* libc_r numbers its threads starting with 0. Not smart. */
+ ti->ti_tid++;
+ return ((err == PS_OK) ? TD_OK : TD_ERR);
+}
+
+static td_err_e
+libc_r_db_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *r)
+{
+ jmp_buf jb;
+ const td_thragent_t *ta;
+ psaddr_t addr;
+ ps_err_e err;
+
+ ta = th->th_ta;
+ err = ps_lgetfpregs(ta->ta_ph, -1, r);
+ if (err != PS_OK)
+ return (TD_ERR);
+ err = ps_pread(ta->ta_ph, ta->ta_thread_run, &addr, sizeof(psaddr_t));
+ if (err != PS_OK)
+ return (TD_ERR);
+ if (th->th_thread == addr)
+ return (TD_OK);
+ addr = (psaddr_t)((uintptr_t)th->th_thread + ta->ta_ofs_ctx);
+ err = ps_pread(ta->ta_ph, addr, jb, sizeof(jb));
+ if (err != PS_OK)
+ return (TD_ERR);
+ libc_r_md_getfpregs(jb, r);
+ return (TD_OK);
+}
+
+static td_err_e
+libc_r_db_thr_getgregs(const td_thrhandle_t *th, prgregset_t r)
+{
+ jmp_buf jb;
+ const td_thragent_t *ta;
+ psaddr_t addr;
+ ps_err_e err;
+
+ ta = th->th_ta;
+ err = ps_lgetregs(ta->ta_ph, -1, r);
+ if (err != PS_OK)
+ return (TD_ERR);
+ err = ps_pread(ta->ta_ph, ta->ta_thread_run, &addr, sizeof(psaddr_t));
+ if (err != PS_OK)
+ return (TD_ERR);
+ if (th->th_thread == addr)
+ return (TD_OK);
+ addr = (psaddr_t)((uintptr_t)th->th_thread + ta->ta_ofs_ctx);
+ err = ps_pread(ta->ta_ph, addr, jb, sizeof(jb));
+ if (err != PS_OK)
+ return (TD_ERR);
+ libc_r_md_getgregs(jb, r);
+ return (TD_OK);
+}
+
+static td_err_e
+libc_r_db_thr_set_event(const td_thrhandle_t *th, td_thr_events_t *ev)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libc_r_db_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *r)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libc_r_db_thr_setgregs(const td_thrhandle_t *th, const prgregset_t r)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libc_r_db_thr_validate(const td_thrhandle_t *th)
+{
+ return (TD_ERR);
+}
+
+struct ta_ops libc_r_db_ops = {
+ .to_init = libc_r_db_init,
+
+ .to_ta_clear_event = libc_r_db_ta_clear_event,
+ .to_ta_delete = libc_r_db_ta_delete,
+ .to_ta_event_addr = libc_r_db_ta_event_addr,
+ .to_ta_event_getmsg = libc_r_db_ta_event_getmsg,
+ .to_ta_map_id2thr = libc_r_db_ta_map_id2thr,
+ .to_ta_map_lwp2thr = libc_r_db_ta_map_lwp2thr,
+ .to_ta_new = libc_r_db_ta_new,
+ .to_ta_set_event = libc_r_db_ta_set_event,
+ .to_ta_thr_iter = libc_r_db_ta_thr_iter,
+
+ .to_thr_clear_event = libc_r_db_thr_clear_event,
+ .to_thr_event_enable = libc_r_db_thr_event_enable,
+ .to_thr_event_getmsg = libc_r_db_thr_event_getmsg,
+ .to_thr_get_info = libc_r_db_thr_get_info,
+ .to_thr_getfpregs = libc_r_db_thr_getfpregs,
+ .to_thr_getgregs = libc_r_db_thr_getgregs,
+ .to_thr_set_event = libc_r_db_thr_set_event,
+ .to_thr_setfpregs = libc_r_db_thr_setfpregs,
+ .to_thr_setgregs = libc_r_db_thr_setgregs,
+ .to_thr_validate = libc_r_db_thr_validate
+};
diff --git a/lib/libthread_db/pthread/pthread_db.c b/lib/libthread_db/libpthread_db.c
index 9a468b3..0afb689 100644
--- a/lib/libthread_db/pthread/pthread_db.c
+++ b/lib/libthread_db/libpthread_db.c
@@ -32,34 +32,18 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
#include <pthread.h>
-#include <thr_private.h>
#include <sys/types.h>
#include <sys/kse.h>
#include <sys/ptrace.h>
#include <proc_service.h>
#include <thread_db.h>
-#include "pthread_db.h"
-
-struct pt_map {
- enum {
- PT_NONE,
- PT_USER,
- PT_LWP
- } type;
-
- union {
- lwpid_t lwp;
- psaddr_t thr;
- };
-};
+#include "libpthread.h"
+#include "libpthread_db.h"
#define P2T(c) ps2td(c)
-static td_err_e pt_ta_activated(pt_thragent_t *ta, int *a);
-static long pt_map_thread(const pt_thragent_t *ta, psaddr_t pt);
-static long pt_map_lwp(const pt_thragent_t *ta, lwpid_t lwp);
-static void pt_unmap_lwp(const pt_thragent_t *ta, lwpid_t lwp);
+static void pt_unmap_lwp(const td_thragent_t *ta, lwpid_t lwp);
static int pt_validate(const td_thrhandle_t *th);
static int
@@ -85,6 +69,48 @@ ps2td(int c)
}
}
+static long
+pt_map_thread(const td_thragent_t *const_ta, psaddr_t pt, int type)
+{
+ td_thragent_t *ta = __DECONST(td_thragent_t *, const_ta);
+ struct pt_map *new;
+ int i, first = -1;
+
+ /* leave zero out */
+ for (i = 1; i < ta->map_len; ++i) {
+ if (ta->map[i].type == PT_NONE) {
+ if (first == -1)
+ first = i;
+ } else if (ta->map[i].type == type && ta->map[i].thr == pt) {
+ return (i);
+ }
+ }
+
+ if (first == -1) {
+ if (ta->map_len == 0) {
+ ta->map = calloc(20, sizeof(struct pt_map));
+ if (ta->map == NULL)
+ return (-1);
+ ta->map_len = 20;
+ first = 1;
+ } else {
+ new = realloc(ta->map,
+ sizeof(struct pt_map) * ta->map_len * 2);
+ if (new == NULL)
+ return (-1);
+ memset(new + ta->map_len, '\0', sizeof(struct pt_map) *
+ ta->map_len);
+ first = ta->map_len;
+ ta->map = new;
+ ta->map_len *= 2;
+ }
+ }
+
+ ta->map[first].type = type;
+ ta->map[first].thr = pt;
+ return (first);
+}
+
static td_err_e
pt_init(void)
{
@@ -93,7 +119,7 @@ pt_init(void)
}
static td_err_e
-pt_ta_new(struct ps_prochandle *ph, pt_thragent_t **pta)
+pt_ta_new(struct ps_prochandle *ph, td_thragent_t **pta)
{
#define LOOKUP_SYM(proc, sym, addr) \
ret = ps_pglobal_lookup(proc, NULL, sym, addr); \
@@ -103,13 +129,13 @@ pt_ta_new(struct ps_prochandle *ph, pt_thragent_t **pta)
goto error; \
}
- pt_thragent_t *ta;
+ td_thragent_t *ta;
int dbg;
int ret;
TDBG_FUNC();
- ta = malloc(sizeof(pt_thragent_t));
+ ta = malloc(sizeof(td_thragent_t));
if (ta == NULL)
return (TD_MALLOC);
@@ -129,7 +155,7 @@ pt_ta_new(struct ps_prochandle *ph, pt_thragent_t **pta)
* If this fails it probably means we're debugging a core file and
* can't write to it.
*/
- ps_pdwrite(ph, ta->libkse_debug_addr, &dbg, sizeof(int));
+ ps_pwrite(ph, ta->libkse_debug_addr, &dbg, sizeof(int));
*pta = ta;
return (0);
@@ -139,7 +165,7 @@ error:
}
static td_err_e
-pt_ta_delete(pt_thragent_t *ta)
+pt_ta_delete(td_thragent_t *ta)
{
int dbg;
@@ -150,7 +176,7 @@ pt_ta_delete(pt_thragent_t *ta)
* Error returns from this write are not really a problem;
* the process doesn't exist any more.
*/
- ps_pdwrite(ta->ph, ta->libkse_debug_addr, &dbg, sizeof(int));
+ ps_pwrite(ta->ph, ta->libkse_debug_addr, &dbg, sizeof(int));
if (ta->map)
free(ta->map);
free(ta);
@@ -158,28 +184,7 @@ pt_ta_delete(pt_thragent_t *ta)
}
static td_err_e
-pt_ta_get_nthreads (const pt_thragent_t *ta, int *np)
-{
- int ret;
-
- TDBG_FUNC();
-
- ret = ps_pdread(ta->ph, ta->thread_active_threads_addr, np,
- sizeof(int));
- return (P2T(ret));
-}
-
-static td_err_e
-pt_ta_get_ph(const pt_thragent_t *ta, struct ps_prochandle **ph)
-{
- TDBG_FUNC();
-
- *ph = ta->ph;
- return (TD_OK);
-}
-
-static td_err_e
-pt_ta_map_id2thr(const pt_thragent_t *ta, thread_t id, td_thrhandle_t *th)
+pt_ta_map_id2thr(const td_thragent_t *ta, thread_t id, td_thrhandle_t *th)
{
prgregset_t gregs;
TAILQ_HEAD(, pthread) thread_list;
@@ -191,7 +196,7 @@ pt_ta_map_id2thr(const pt_thragent_t *ta, thread_t id, td_thrhandle_t *th)
if (id < 0 || id >= ta->map_len || ta->map[id].type == PT_NONE)
return (TD_NOTHR);
- ret = ps_pdread(ta->ph, ta->thread_list_addr, &thread_list,
+ ret = ps_pread(ta->ph, ta->thread_list_addr, &thread_list,
sizeof(thread_list));
if (ret != 0)
return (P2T(ret));
@@ -202,12 +207,12 @@ pt_ta_map_id2thr(const pt_thragent_t *ta, thread_t id, td_thrhandle_t *th)
* mapped to user thread.
*/
while (pt != 0) {
- ret = ps_pdread(ta->ph,
+ ret = ps_pread(ta->ph,
pt + offsetof(struct pthread, tcb),
&tcb_addr, sizeof(tcb_addr));
if (ret != 0)
return (P2T(ret));
- ret = ps_pdread(ta->ph,
+ ret = ps_pread(ta->ph,
tcb_addr + offsetof(struct tcb,
tcb_tmbx.tm_lwp),
&lwp, sizeof(lwp));
@@ -222,7 +227,7 @@ pt_ta_map_id2thr(const pt_thragent_t *ta, thread_t id, td_thrhandle_t *th)
return (TD_NOTHR);
}
/* get next thread */
- ret = ps_pdread(ta->ph,
+ ret = ps_pread(ta->ph,
pt + offsetof(struct pthread, tle.tqe_next),
&pt, sizeof(pt));
if (ret != 0)
@@ -237,13 +242,13 @@ pt_ta_map_id2thr(const pt_thragent_t *ta, thread_t id, td_thrhandle_t *th)
}
} else {
while (pt != 0 && ta->map[id].thr != pt) {
- ret = ps_pdread(ta->ph,
+ ret = ps_pread(ta->ph,
pt + offsetof(struct pthread, tcb),
&tcb_addr, sizeof(tcb_addr));
if (ret != 0)
return (P2T(ret));
/* get next thread */
- ret = ps_pdread(ta->ph,
+ ret = ps_pread(ta->ph,
pt + offsetof(struct pthread, tle.tqe_next),
&pt, sizeof(pt));
if (ret != 0)
@@ -256,13 +261,13 @@ pt_ta_map_id2thr(const pt_thragent_t *ta, thread_t id, td_thrhandle_t *th)
return (TD_NOTHR);
}
}
- th->th_ta_p = (td_thragent_t *)ta;
- th->th_unique = id;
+ th->th_ta = ta;
+ th->th_tid = id;
return (TD_OK);
}
static td_err_e
-pt_ta_map_lwp2thr(const pt_thragent_t *ta, lwpid_t lwp, td_thrhandle_t *th)
+pt_ta_map_lwp2thr(const td_thragent_t *ta, lwpid_t lwp, td_thrhandle_t *th)
{
TAILQ_HEAD(, pthread) thread_list;
psaddr_t pt, ptr;
@@ -271,31 +276,31 @@ pt_ta_map_lwp2thr(const pt_thragent_t *ta, lwpid_t lwp, td_thrhandle_t *th)
TDBG_FUNC();
- ret = ps_pdread(ta->ph, ta->thread_list_addr, &thread_list,
+ ret = ps_pread(ta->ph, ta->thread_list_addr, &thread_list,
sizeof(thread_list));
if (ret != 0)
return (P2T(ret));
pt = (psaddr_t)thread_list.tqh_first;
while (pt != 0) {
- ret = ps_pdread(ta->ph, pt + offsetof(struct pthread, tcb),
+ ret = ps_pread(ta->ph, pt + offsetof(struct pthread, tcb),
&ptr, sizeof(ptr));
if (ret != 0)
return (P2T(ret));
ptr += offsetof(struct tcb, tcb_tmbx.tm_lwp);
- ret = ps_pdread(ta->ph, ptr, &tmp_lwp, sizeof(lwpid_t));
+ ret = ps_pread(ta->ph, ptr, &tmp_lwp, sizeof(lwpid_t));
if (ret != 0)
return (P2T(ret));
if (tmp_lwp == lwp) {
- th->th_ta_p = (td_thragent_t *)ta;
- th->th_unique = pt_map_thread(ta, pt);
- if (th->th_unique == -1)
+ th->th_ta = ta;
+ th->th_tid = pt_map_thread(ta, pt, PT_USER);
+ if (th->th_tid == -1)
return (TD_MALLOC);
pt_unmap_lwp(ta, lwp);
return (TD_OK);
}
/* get next thread */
- ret = ps_pdread(ta->ph,
+ ret = ps_pread(ta->ph,
pt + offsetof(struct pthread, tle.tqe_next),
&pt, sizeof(pt));
if (ret != 0)
@@ -306,7 +311,7 @@ pt_ta_map_lwp2thr(const pt_thragent_t *ta, lwpid_t lwp, td_thrhandle_t *th)
}
static td_err_e
-pt_ta_thr_iter(const pt_thragent_t *ta,
+pt_ta_thr_iter(const td_thragent_t *ta,
td_thr_iter_f *callback, void *cbdata_p,
td_thr_state_e state, int ti_pri,
sigset_t *ti_sigmask_p,
@@ -315,47 +320,50 @@ pt_ta_thr_iter(const pt_thragent_t *ta,
TAILQ_HEAD(, pthread) thread_list;
td_thrhandle_t th;
psaddr_t pt;
- int ret, activated;
-
+ ps_err_e pserr;
+ int activated;
+
TDBG_FUNC();
- ret = pt_ta_activated((pt_thragent_t *)ta, &activated);
- if (ret != 0)
- return (P2T(ret));
+ pserr = ps_pread(ta->ph, ta->thread_activated_addr, &activated,
+ sizeof(int));
+ if (pserr != PS_OK)
+ return (P2T(pserr));
if (!activated)
- return (0);
- ret = ps_pdread(ta->ph, ta->thread_list_addr, &thread_list,
- sizeof(thread_list));
- if (ret != 0)
- return (P2T(ret));
+ return (TD_OK);
+
+ pserr = ps_pread(ta->ph, ta->thread_list_addr, &thread_list,
+ sizeof(thread_list));
+ if (pserr != 0)
+ return (P2T(pserr));
pt = (psaddr_t)thread_list.tqh_first;
while (pt != 0) {
- th.th_ta_p = (td_thragent_t *)ta;
- th.th_unique = pt_map_thread(ta, pt);
+ th.th_ta = ta;
+ th.th_tid = pt_map_thread(ta, pt, PT_USER);
/* should we unmap lwp here ? */
- if (th.th_unique == -1)
+ if (th.th_tid == -1)
return (TD_MALLOC);
if ((*callback)(&th, cbdata_p))
return (TD_DBERR);
/* get next thread */
- ret = ps_pdread(ta->ph,
- pt + offsetof(struct pthread, tle.tqe_next),
- &pt, sizeof(pt));
- if (ret != 0)
- return (P2T(ret));
+ pserr = ps_pread(ta->ph,
+ pt + offsetof(struct pthread, tle.tqe_next), &pt,
+ sizeof(pt));
+ if (pserr != PS_OK)
+ return (P2T(pserr));
}
return (TD_OK);
}
static td_err_e
-pt_ta_tsd_iter(const pt_thragent_t *ta, td_key_iter_f *ki, void *arg)
+pt_ta_tsd_iter(const td_thragent_t *ta, td_key_iter_f *ki, void *arg)
{
struct pthread_key keytable[PTHREAD_KEYS_MAX];
int i, ret;
TDBG_FUNC();
- ret = ps_pdread(ta->ph, (psaddr_t)ta->thread_keytable_addr, keytable,
+ ret = ps_pread(ta->ph, (psaddr_t)ta->thread_keytable_addr, keytable,
sizeof(keytable));
if (ret != 0)
return (P2T(ret));
@@ -371,59 +379,45 @@ pt_ta_tsd_iter(const pt_thragent_t *ta, td_key_iter_f *ki, void *arg)
}
static td_err_e
-pt_ta_event_addr(const pt_thragent_t *ta, td_event_e event, td_notify_t *ptr)
+pt_ta_event_addr(const td_thragent_t *ta, td_event_e event, td_notify_t *ptr)
{
TDBG_FUNC();
return (TD_NOEVENT);
}
static td_err_e
-pt_ta_set_event(const pt_thragent_t *ta, td_thr_events_t *events)
+pt_ta_set_event(const td_thragent_t *ta, td_thr_events_t *events)
{
TDBG_FUNC();
return (TD_ERR);
}
static td_err_e
-pt_ta_clear_event(const pt_thragent_t *ta, td_thr_events_t *events)
+pt_ta_clear_event(const td_thragent_t *ta, td_thr_events_t *events)
{
TDBG_FUNC();
return (TD_ERR);
}
static td_err_e
-pt_ta_event_getmsg(const pt_thragent_t *ta, td_event_msg_t *msg)
+pt_ta_event_getmsg(const td_thragent_t *ta, td_event_msg_t *msg)
{
TDBG_FUNC();
return (TD_NOMSG);
}
static td_err_e
-pt_ta_setconcurrency(const pt_thragent_t *ta, int level)
-{
- TDBG_FUNC();
- return (TD_OK);
-}
-
-static td_err_e
-pt_ta_enable_stats(const pt_thragent_t *ta, int enable)
-{
- TDBG_FUNC();
- return (TD_OK);
-}
-
-static td_err_e
-pt_ta_reset_stats(const pt_thragent_t *ta)
+pt_thr_dbresume(const td_thrhandle_t *th)
{
TDBG_FUNC();
- return (TD_OK);
+ return (TD_ERR);
}
static td_err_e
-pt_ta_get_stats(const pt_thragent_t *ta, td_ta_stats_t *statsp)
+pt_thr_dbsuspend(const td_thrhandle_t *th)
{
TDBG_FUNC();
- return (TD_OK);
+ return (TD_ERR);
}
static td_err_e
@@ -434,7 +428,7 @@ pt_thr_validate(const td_thrhandle_t *th)
TDBG_FUNC();
- ret = pt_ta_map_id2thr((pt_thragent_t *)th->th_ta_p, th->th_unique,
+ ret = pt_ta_map_id2thr(th->th_ta, th->th_tid,
&temp);
return (P2T(ret));
}
@@ -442,10 +436,8 @@ pt_thr_validate(const td_thrhandle_t *th)
static td_err_e
pt_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
{
+ const td_thragent_t *ta = th->th_ta;
struct pthread pt;
- pt_thragent_t *ta = (pt_thragent_t *)th->th_ta_p;
- psaddr_t tcb_addr;
- uint32_t dflags;
int ret;
TDBG_FUNC();
@@ -455,32 +447,29 @@ pt_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
return (ret);
memset(info, 0, sizeof(*info));
- if (ta->map[th->th_unique].type == PT_LWP) {
+ if (ta->map[th->th_tid].type == PT_LWP) {
info->ti_type = TD_THR_SYSTEM;
- info->ti_lid = ta->map[th->th_unique].lwp;
- info->ti_tid = th->th_unique;
+ info->ti_lid = ta->map[th->th_tid].lwp;
+ info->ti_tid = th->th_tid;
info->ti_state = TD_THR_RUN;
info->ti_type = TD_THR_SYSTEM;
return (TD_OK);
}
- ret = ps_pdread(ta->ph, (psaddr_t)(ta->map[th->th_unique].thr),
+ ret = ps_pread(ta->ph, (psaddr_t)(ta->map[th->th_tid].thr),
&pt, sizeof(pt));
if (ret != 0)
return (P2T(ret));
if (pt.magic != THR_MAGIC)
return (TD_BADTH);
- tcb_addr = (psaddr_t) pt.tcb;
- ret = ps_pdread(ta->ph,
- tcb_addr + offsetof(struct tcb, tcb_tmbx.tm_lwp),
+ ret = ps_pread(ta->ph,
+ ((psaddr_t)pt.tcb) + offsetof(struct tcb, tcb_tmbx.tm_lwp),
&info->ti_lid, sizeof(lwpid_t));
if (ret != 0)
return (P2T(ret));
- ret = ps_pdread(ta->ph,
- tcb_addr + offsetof(struct tcb, tcb_tmbx.tm_dflags),
- &dflags, sizeof(dflags));
- info->ti_ta_p = th->th_ta_p;
- info->ti_tid = th->th_unique;
+
+ info->ti_ta_p = th->th_ta;
+ info->ti_tid = th->th_tid;
info->ti_tls = (char *)pt.specific;
info->ti_startfunc = (psaddr_t)pt.start_routine;
info->ti_stkbase = (psaddr_t) pt.attr.stackaddr_attr;
@@ -508,7 +497,7 @@ pt_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
break;
}
- info->ti_db_suspended = ((dflags & TMDF_DONOTRUNUSER) != 0);
+ info->ti_db_suspended = 0;
info->ti_type = TD_THR_USER;
info->ti_pri = pt.active_priority;
info->ti_sigmask = pt.sigmask;
@@ -521,8 +510,8 @@ pt_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
static td_err_e
pt_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregs)
{
+ const td_thragent_t *ta = th->th_ta;
struct kse_thr_mailbox tmbx;
- pt_thragent_t *ta = (pt_thragent_t *)th->th_ta_p;
psaddr_t tcb_addr, tmbx_addr, ptr;
lwpid_t lwp;
int ret;
@@ -533,19 +522,19 @@ pt_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregs)
if (ret)
return (ret);
- if (ta->map[th->th_unique].type == PT_LWP) {
- ret = ps_lgetfpregs(ta->ph, ta->map[th->th_unique].lwp, fpregs);
+ if (ta->map[th->th_tid].type == PT_LWP) {
+ ret = ps_lgetfpregs(ta->ph, ta->map[th->th_tid].lwp, fpregs);
return (P2T(ret));
}
- ret = ps_pdread(ta->ph, ta->map[th->th_unique].thr +
+ ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
offsetof(struct pthread, tcb),
&tcb_addr, sizeof(tcb_addr));
if (ret != 0)
return (P2T(ret));
tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
- ret = ps_pdread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
+ ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
if (ret != 0)
return (P2T(ret));
if (lwp != 0) {
@@ -553,7 +542,7 @@ pt_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregs)
return (P2T(ret));
}
- ret = ps_pdread(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
+ ret = ps_pread(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
if (ret != 0)
return (P2T(ret));
pt_ucontext_to_fpreg(&tmbx.tm_context, fpregs);
@@ -563,8 +552,8 @@ pt_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregs)
static td_err_e
pt_thr_getgregs(const td_thrhandle_t *th, prgregset_t gregs)
{
+ const td_thragent_t *ta = th->th_ta;
struct kse_thr_mailbox tmbx;
- pt_thragent_t *ta = (pt_thragent_t *)th->th_ta_p;
psaddr_t tcb_addr, tmbx_addr, ptr;
lwpid_t lwp;
int ret;
@@ -575,27 +564,27 @@ pt_thr_getgregs(const td_thrhandle_t *th, prgregset_t gregs)
if (ret)
return (ret);
- if (ta->map[th->th_unique].type == PT_LWP) {
+ if (ta->map[th->th_tid].type == PT_LWP) {
ret = ps_lgetregs(ta->ph,
- ta->map[th->th_unique].lwp, gregs);
+ ta->map[th->th_tid].lwp, gregs);
return (P2T(ret));
}
- ret = ps_pdread(ta->ph, ta->map[th->th_unique].thr +
+ ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
offsetof(struct pthread, tcb),
&tcb_addr, sizeof(tcb_addr));
if (ret != 0)
return (P2T(ret));
tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
- ret = ps_pdread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
+ ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
if (ret != 0)
return (P2T(ret));
if (lwp != 0) {
ret = ps_lgetregs(ta->ph, lwp, gregs);
return (P2T(ret));
}
- ret = ps_pdread(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
+ ret = ps_pread(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
if (ret != 0)
return (P2T(ret));
pt_ucontext_to_reg(&tmbx.tm_context, gregs);
@@ -603,22 +592,10 @@ pt_thr_getgregs(const td_thrhandle_t *th, prgregset_t gregs)
}
static td_err_e
-pt_thr_getxregs (const td_thrhandle_t *th, void *xregs)
-{
- return (TD_NOXREGS);
-}
-
-static td_err_e
-pt_thr_getxregsize (const td_thrhandle_t *th, int *sizep)
-{
- return (TD_NOXREGS);
-}
-
-static td_err_e
pt_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *fpregs)
{
+ const td_thragent_t *ta = th->th_ta;
struct kse_thr_mailbox tmbx;
- pt_thragent_t *ta = (pt_thragent_t *)th->th_ta_p;
psaddr_t tcb_addr, tmbx_addr, ptr;
lwpid_t lwp;
int ret;
@@ -629,19 +606,19 @@ pt_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *fpregs)
if (ret)
return (ret);
- if (ta->map[th->th_unique].type == PT_LWP) {
- ret = ps_lsetfpregs(ta->ph, ta->map[th->th_unique].lwp, fpregs);
+ if (ta->map[th->th_tid].type == PT_LWP) {
+ ret = ps_lsetfpregs(ta->ph, ta->map[th->th_tid].lwp, fpregs);
return (P2T(ret));
}
- ret = ps_pdread(ta->ph, ta->map[th->th_unique].thr +
+ ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
offsetof(struct pthread, tcb),
&tcb_addr, sizeof(tcb_addr));
if (ret != 0)
return (P2T(ret));
tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
- ret = ps_pdread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
+ ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
if (ret != 0)
return (P2T(ret));
if (lwp != 0) {
@@ -652,20 +629,20 @@ pt_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *fpregs)
* Read a copy of context, this makes sure that registers
* not covered by structure reg won't be clobbered
*/
- ret = ps_pdread(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
+ ret = ps_pread(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
if (ret != 0)
return (P2T(ret));
pt_fpreg_to_ucontext(fpregs, &tmbx.tm_context);
- ret = ps_pdwrite(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
+ ret = ps_pwrite(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
return (P2T(ret));
}
static td_err_e
pt_thr_setgregs(const td_thrhandle_t *th, const prgregset_t gregs)
{
+ const td_thragent_t *ta = th->th_ta;
struct kse_thr_mailbox tmbx;
- pt_thragent_t *ta = (pt_thragent_t *)th->th_ta_p;
psaddr_t tcb_addr, tmbx_addr, ptr;
lwpid_t lwp;
int ret;
@@ -676,19 +653,19 @@ pt_thr_setgregs(const td_thrhandle_t *th, const prgregset_t gregs)
if (ret)
return (ret);
- if (ta->map[th->th_unique].type == PT_LWP) {
- ret = ps_lsetregs(ta->ph, ta->map[th->th_unique].lwp, gregs);
+ if (ta->map[th->th_tid].type == PT_LWP) {
+ ret = ps_lsetregs(ta->ph, ta->map[th->th_tid].lwp, gregs);
return (P2T(ret));
}
- ret = ps_pdread(ta->ph, ta->map[th->th_unique].thr +
+ ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
offsetof(struct pthread, tcb),
&tcb_addr, sizeof(tcb_addr));
if (ret != 0)
return (P2T(ret));
tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
- ret = ps_pdread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
+ ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
if (ret != 0)
return (P2T(ret));
if (lwp != 0) {
@@ -700,22 +677,15 @@ pt_thr_setgregs(const td_thrhandle_t *th, const prgregset_t gregs)
* Read a copy of context, make sure that registers
* not covered by structure reg won't be clobbered
*/
- ret = ps_pdread(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
+ ret = ps_pread(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
if (ret != 0)
return (P2T(ret));
pt_reg_to_ucontext(gregs, &tmbx.tm_context);
- ret = ps_pdwrite(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
+ ret = ps_pwrite(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
return (P2T(ret));
}
static td_err_e
-pt_thr_setxregs(const td_thrhandle_t *th, const void *addr)
-{
- TDBG_FUNC();
- return (TD_NOXREGS);
-}
-
-static td_err_e
pt_thr_event_enable(const td_thrhandle_t *th, int en)
{
TDBG_FUNC();
@@ -744,173 +714,11 @@ pt_thr_event_getmsg(const td_thrhandle_t *th, td_event_msg_t *msg)
}
static td_err_e
-pt_thr_setprio(const td_thrhandle_t *th, int pri)
-{
- TDBG_FUNC();
- return (TD_OK);
-}
-
-static td_err_e
-pt_thr_setsigpending(const td_thrhandle_t *th, unsigned char n,
- const sigset_t *set)
-{
- TDBG_FUNC();
- return (TD_OK);
-}
-
-static td_err_e
-pt_thr_sigsetmask(const td_thrhandle_t *th, const sigset_t *set)
-{
- TDBG_FUNC();
- return (TD_OK);
-}
-
-static td_err_e
-pt_thr_tsd(const td_thrhandle_t *th, const thread_key_t key, void **data)
-{
- pt_thragent_t *ta = (pt_thragent_t *)th->th_ta_p;
- struct pthread_specific_elem *spec, elem;
- int ret;
-
- TDBG_FUNC();
-
- ret = pt_validate(th);
- if (ret)
- return (ret);
-
- if (key < 0 || key >= PTHREAD_KEYS_MAX)
- return (TD_BADKEY);
-
- if (ta->map[th->th_unique].type == PT_LWP) {
- *data = NULL;
- return (TD_OK);
- }
-
- ret = ps_pdread(ta->ph,
- ta->map[th->th_unique].thr +
- offsetof(struct pthread, specific),
- &spec, sizeof(spec));
- if (ret == 0) {
- if (spec == NULL) {
- *data = NULL;
- return (0);
- }
- ret = ps_pdread(ta->ph, (psaddr_t)&spec[key],
- &elem, sizeof(elem));
- if (ret == 0)
- *data = (void *)elem.data;
- }
- return (P2T(ret));
-}
-
-static td_err_e
-pt_dbsuspend(const td_thrhandle_t *th, int suspend)
-{
- pt_thragent_t *ta = (pt_thragent_t *)th->th_ta_p;
- psaddr_t tcb_addr, tmbx_addr, ptr;
- lwpid_t lwp;
- uint32_t dflags;
- int attrflags;
- int ret;
-
- TDBG_FUNC();
-
- ret = pt_validate(th);
- if (ret)
- return (ret);
-
- if (ta->map[th->th_unique].type == PT_LWP) {
- if (suspend)
- ret = ps_lstop(ta->ph, ta->map[th->th_unique].lwp);
- else
- ret = ps_lcontinue(ta->ph, ta->map[th->th_unique].lwp);
- return (P2T(ret));
- }
-
- ret = ps_pdread(ta->ph, ta->map[th->th_unique].thr +
- offsetof(struct pthread, attr.flags),
- &attrflags, sizeof(attrflags));
- if (ret != 0)
- return (P2T(ret));
- ret = ps_pdread(ta->ph, ta->map[th->th_unique].thr +
- offsetof(struct pthread, tcb),
- &tcb_addr, sizeof(tcb_addr));
- if (ret != 0)
- return (P2T(ret));
- tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
- ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
- ret = ps_pdread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
- if (ret != 0)
- return (P2T(ret));
- /*
- * don't stop lwp assigned to a M:N thread, it belongs
- * to UTS, UTS shouldn't be stopped.
- */
- if (lwp != 0 && (attrflags & PTHREAD_SCOPE_SYSTEM)) {
- /* dont' suspend signal thread */
- if (attrflags & THR_SIGNAL_THREAD)
- return 0;
- if (suspend)
- ret = ps_lstop(ta->ph, lwp);
- else
- ret = ps_lcontinue(ta->ph, lwp);
- return (P2T(ret));
- }
-
- ret = ps_pdread(ta->ph,
- tmbx_addr + offsetof(struct kse_thr_mailbox, tm_dflags),
- &dflags, sizeof(dflags));
- if (ret != 0)
- return (P2T(ret));
-
- if (suspend)
- dflags |= TMDF_DONOTRUNUSER;
- else
- dflags &= ~TMDF_DONOTRUNUSER;
- ret = ps_pdwrite(ta->ph,
- tmbx_addr + offsetof(struct kse_thr_mailbox, tm_dflags),
- &dflags, sizeof(dflags));
- return (P2T(ret));
-}
-
-static td_err_e
-pt_thr_dbsuspend(const td_thrhandle_t *th)
-{
- TDBG_FUNC();
- return pt_dbsuspend(th, 1);
-}
-
-static td_err_e
-pt_thr_dbresume(const td_thrhandle_t *th)
-{
- TDBG_FUNC();
- return pt_dbsuspend(th, 0);
-}
-
-static td_err_e
-pt_ta_activated(pt_thragent_t *ta, int *a)
-{
- int ret;
-
- TDBG_FUNC();
-
- if (ta->thread_activated) {
- *a = ta->thread_activated;
- return (TD_OK);
- }
- ret = ps_pdread(ta->ph, ta->thread_activated_addr,
- &ta->thread_activated, sizeof(int));
- if (ret == 0)
- *a = ta->thread_activated;
- return (P2T(ret));
-}
-
-static td_err_e
-pt_thr_sstep(td_thrhandle_t *th, int step)
+pt_thr_sstep(const td_thrhandle_t *th, int step)
{
+ const td_thragent_t *ta = th->th_ta;
struct kse_thr_mailbox tmbx;
struct reg regs;
- pt_thragent_t *ta = (pt_thragent_t *)th->th_ta_p;
psaddr_t tcb_addr, tmbx_addr;
uint32_t tmp;
lwpid_t lwp;
@@ -922,12 +730,10 @@ pt_thr_sstep(td_thrhandle_t *th, int step)
if (ret)
return (ret);
- if (ta->map[th->th_unique].type == PT_LWP) {
- /* Let debugger deal with single step flag in in kernel */
- return (0);
- }
+ if (ta->map[th->th_tid].type == PT_LWP)
+ return (TD_BADTH);
- ret = ps_pdread(ta->ph, ta->map[th->th_unique].thr +
+ ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
offsetof(struct pthread, tcb),
&tcb_addr, sizeof(tcb_addr));
if (ret != 0)
@@ -935,17 +741,17 @@ pt_thr_sstep(td_thrhandle_t *th, int step)
/* Clear or set single step flag in thread mailbox */
tmp = step ? TMDF_SSTEP : 0;
- ret = ps_pdwrite(ta->ph, tcb_addr + offsetof(struct tcb,
+ ret = ps_pwrite(ta->ph, tcb_addr + offsetof(struct tcb,
tcb_tmbx.tm_dflags), &tmp, sizeof(tmp));
if (ret != 0)
return (P2T(ret));
/* Get lwp */
- ret = ps_pdread(ta->ph, tcb_addr + offsetof(struct tcb,
+ ret = ps_pread(ta->ph, tcb_addr + offsetof(struct tcb,
tcb_tmbx.tm_lwp), &lwp, sizeof(lwpid_t));
if (ret != 0)
return (P2T(ret));
- if (lwp != 0) /* Let debugger deal with single step flag in in kernel */
- return (0);
+ if (lwp != 0)
+ return (TD_BADTH);
tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
/*
@@ -953,76 +759,21 @@ pt_thr_sstep(td_thrhandle_t *th, int step)
* single step status in registers, we should change
* these registers.
*/
- ret = ps_pdread(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
+ ret = ps_pread(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
if (ret == 0) {
pt_ucontext_to_reg(&tmbx.tm_context, &regs);
/* only write out if it is really changed. */
if (pt_reg_sstep(&regs, step) != 0) {
pt_reg_to_ucontext(&regs, &tmbx.tm_context);
- ret = ps_pdwrite(ta->ph, tmbx_addr, &tmbx,
+ ret = ps_pwrite(ta->ph, tmbx_addr, &tmbx,
sizeof(tmbx));
}
}
return (P2T(ret));
}
-static long
-_map_thread(pt_thragent_t *ta, psaddr_t pt, int type)
-{
- struct pt_map *new;
- int i, first = -1;
-
- /* leave zero out */
- for (i = 1; i < ta->map_len; ++i) {
- if (ta->map[i].type == PT_NONE) {
- if (first == -1)
- first = i;
- } else if (ta->map[i].type == type && ta->map[i].thr == pt) {
- return (i);
- }
- }
-
- if (first == -1) {
- if (ta->map_len == 0) {
- ta->map = calloc(20, sizeof(struct pt_map));
- if (ta->map == NULL)
- return (-1);
- ta->map_len = 20;
- first = 1;
- } else {
- new = realloc(ta->map,
- sizeof(struct pt_map) * ta->map_len * 2);
- if (new == NULL)
- return (-1);
- memset(new + ta->map_len, '\0', sizeof(struct pt_map) *
- ta->map_len);
- first = ta->map_len;
- ta->map = new;
- ta->map_len *= 2;
- }
- }
-
- ta->map[first].type = type;
- ta->map[first].thr = pt;
- return (first);
-}
-
-static long
-pt_map_thread(const pt_thragent_t *ta, psaddr_t pt)
-{
- return _map_thread((pt_thragent_t *)ta, pt, PT_USER);
-}
-
-#if 0
-static long
-pt_map_lwp(const pt_thragent_t *ta, lwpid_t lwp)
-{
- return _map_thread((pt_thragent_t *)ta, (psaddr_t)lwp, PT_LWP);
-}
-#endif
-
static void
-pt_unmap_lwp(const pt_thragent_t *ta, lwpid_t lwp)
+pt_unmap_lwp(const td_thragent_t *ta, lwpid_t lwp)
{
int i;
@@ -1037,51 +788,38 @@ pt_unmap_lwp(const pt_thragent_t *ta, lwpid_t lwp)
static int
pt_validate(const td_thrhandle_t *th)
{
- pt_thragent_t *ta = (pt_thragent_t *)th->th_ta_p;
- if (th->th_unique < 0 || th->th_unique >= ta->map_len ||
- ta->map[th->th_unique].type == PT_NONE)
+ if (th->th_tid < 0 || th->th_tid >= th->th_ta->map_len ||
+ th->th_ta->map[th->th_tid].type == PT_NONE)
return (TD_NOTHR);
return (TD_OK);
}
-struct ta_ops pthread_ops = {
+struct ta_ops libpthread_db_ops = {
.to_init = pt_init,
- .to_ta_new = (void *)pt_ta_new,
- .to_ta_delete = (void *)pt_ta_delete,
- .to_ta_get_nthreads = (void *)pt_ta_get_nthreads,
- .to_ta_get_ph = (void *)pt_ta_get_ph,
- .to_ta_map_id2thr = (void *)pt_ta_map_id2thr,
- .to_ta_map_lwp2thr = (void *)pt_ta_map_lwp2thr,
- .to_ta_thr_iter = (void *)pt_ta_thr_iter,
- .to_ta_tsd_iter = (void *)pt_ta_tsd_iter,
- .to_ta_event_addr = (void *)pt_ta_event_addr,
- .to_ta_set_event = (void *)pt_ta_set_event,
- .to_ta_clear_event = (void *)pt_ta_clear_event,
- .to_ta_event_getmsg = (void *)pt_ta_event_getmsg,
- .to_ta_setconcurrency = (void *)pt_ta_setconcurrency,
- .to_ta_enable_stats = (void *)pt_ta_enable_stats,
- .to_ta_reset_stats = (void *)pt_ta_reset_stats,
- .to_ta_get_stats = (void *)pt_ta_get_stats,
- .to_thr_validate = pt_thr_validate,
+ .to_ta_clear_event = pt_ta_clear_event,
+ .to_ta_delete = pt_ta_delete,
+ .to_ta_event_addr = pt_ta_event_addr,
+ .to_ta_event_getmsg = pt_ta_event_getmsg,
+ .to_ta_map_id2thr = pt_ta_map_id2thr,
+ .to_ta_map_lwp2thr = pt_ta_map_lwp2thr,
+ .to_ta_new = pt_ta_new,
+ .to_ta_set_event = pt_ta_set_event,
+ .to_ta_thr_iter = pt_ta_thr_iter,
+ .to_ta_tsd_iter = pt_ta_tsd_iter,
+ .to_thr_clear_event = pt_thr_clear_event,
+ .to_thr_dbresume = pt_thr_dbresume,
+ .to_thr_dbsuspend = pt_thr_dbsuspend,
+ .to_thr_event_enable = pt_thr_event_enable,
+ .to_thr_event_getmsg = pt_thr_event_getmsg,
.to_thr_get_info = pt_thr_get_info,
- .to_thr_getfpregs = (void *)pt_thr_getfpregs,
+ .to_thr_getfpregs = pt_thr_getfpregs,
.to_thr_getgregs = pt_thr_getgregs,
- .to_thr_getxregs = pt_thr_getxregs,
- .to_thr_getxregsize = pt_thr_getxregsize,
+ .to_thr_set_event = pt_thr_set_event,
.to_thr_setfpregs = pt_thr_setfpregs,
.to_thr_setgregs = pt_thr_setgregs,
- .to_thr_setxregs = pt_thr_setxregs,
- .to_thr_event_enable = pt_thr_event_enable,
- .to_thr_set_event = pt_thr_set_event,
- .to_thr_clear_event = pt_thr_clear_event,
- .to_thr_event_getmsg = pt_thr_event_getmsg,
- .to_thr_setprio = pt_thr_setprio,
- .to_thr_setsigpending = pt_thr_setsigpending,
- .to_thr_sigsetmask = pt_thr_sigsetmask,
- .to_thr_tsd = pt_thr_tsd,
- .to_thr_dbsuspend = pt_thr_dbsuspend,
- .to_thr_dbresume = pt_thr_dbresume,
- .to_ta_activated = (void *)pt_ta_activated,
- .to_thr_sstep = pt_thr_sstep
+ .to_thr_validate = pt_thr_validate,
+
+ /* FreeBSD specific extensions. */
+ .to_thr_sstep = pt_thr_sstep,
};
diff --git a/lib/libthread_db/pthread/pthread_db.h b/lib/libthread_db/libpthread_db.h
index 49dcdd7..397ec72 100644
--- a/lib/libthread_db/pthread/pthread_db.h
+++ b/lib/libthread_db/libpthread_db.h
@@ -26,29 +26,39 @@
* $FreeBSD$
*/
-#ifndef _PTHREAD_DB_H
-#define _PTHREAD_DB_H
+#ifndef _LIBPTHREAD_DB_H_
+#define _LIBPTHREAD_DB_H_
#include <sys/ucontext.h>
#include <machine/reg.h>
#include "thread_db_int.h"
-struct pt_thragent {
- struct td_thragent base;
- struct ps_prochandle *ph;
- psaddr_t libkse_debug_addr;
- psaddr_t thread_list_addr;
- psaddr_t thread_listgen_addr;
- psaddr_t thread_activated_addr;
- psaddr_t thread_active_threads_addr;
- psaddr_t thread_keytable_addr;
- int thread_activated;
- struct pt_map *map;
- int map_len;
+struct pt_map {
+ enum {
+ PT_NONE,
+ PT_USER,
+ PT_LWP
+ } type;
+
+ union {
+ lwpid_t lwp;
+ psaddr_t thr;
+ };
};
-typedef struct pt_thragent pt_thragent_t;
+struct td_thragent {
+ TD_THRAGENT_FIELDS;
+ psaddr_t libkse_debug_addr;
+ psaddr_t thread_list_addr;
+ psaddr_t thread_listgen_addr;
+ psaddr_t thread_activated_addr;
+ psaddr_t thread_active_threads_addr;
+ psaddr_t thread_keytable_addr;
+ int thread_activated;
+ struct pt_map *map;
+ int map_len;
+};
void pt_md_init(void);
void pt_reg_to_ucontext(const struct reg *, ucontext_t *);
@@ -57,4 +67,4 @@ void pt_fpreg_to_ucontext(const struct fpreg *, ucontext_t *);
void pt_ucontext_to_fpreg(const ucontext_t *, struct fpreg *);
int pt_reg_sstep(struct reg *reg, int step);
-#endif
+#endif /* _LIBPTHREAD_DB_H_ */
diff --git a/lib/libthread_db/libthr_db.c b/lib/libthread_db/libthr_db.c
new file mode 100644
index 0000000..878fcb0
--- /dev/null
+++ b/lib/libthread_db/libthr_db.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <proc_service.h>
+#include <stdlib.h>
+#include <thread_db.h>
+
+#include "thread_db_int.h"
+
+struct td_thragent {
+ TD_THRAGENT_FIELDS;
+ struct ps_prochandle *ta_ph;
+ psaddr_t ta_thread_list;
+ int ta_ofs_ctx;
+ int ta_ofs_next;
+ int ta_ofs_thr_id;
+};
+
+static td_err_e
+libthr_db_init()
+{
+ return (TD_OK);
+}
+
+static td_err_e
+libthr_db_ta_clear_event(const td_thragent_t *ta, td_thr_events_t *ev)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libthr_db_ta_delete(td_thragent_t *ta)
+{
+ free(ta);
+ return (TD_OK);
+}
+
+static td_err_e
+libthr_db_ta_event_addr(const td_thragent_t *ta, td_thr_events_e event,
+ td_notify_t *n)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libthr_db_ta_event_getmsg(const td_thragent_t *ta, td_event_msg_t *msg)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libthr_db_ta_map_id2thr(const td_thragent_t *ta, thread_t tid,
+ td_thrhandle_t *th)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libthr_db_ta_map_lwp2thr(const td_thragent_t *ta, lwpid_t lwpid,
+ td_thrhandle_t *th)
+{
+ psaddr_t addr;
+ thread_t tid;
+ ps_err_e err;
+
+ th->th_ta = ta;
+
+ err = ps_pread(ta->ta_ph, ta->ta_thread_list, &th->th_thread,
+ sizeof(th->th_thread));
+ if (err != PS_OK)
+ return (TD_ERR);
+ while (th->th_thread != NULL) {
+ addr = (psaddr_t)((uintptr_t)th->th_thread +
+ ta->ta_ofs_thr_id);
+ err = ps_pread(ta->ta_ph, addr, &tid, sizeof(thread_t));
+ if (err != PS_OK)
+ return (TD_ERR);
+ if (tid == lwpid)
+ return (TD_OK);
+ addr = (psaddr_t)((uintptr_t)th->th_thread + ta->ta_ofs_next);
+ err = ps_pread(ta->ta_ph, addr, &th->th_thread,
+ sizeof(th->th_thread));
+ if (err != PS_OK)
+ return (TD_ERR);
+ }
+ return (TD_NOLWP);
+}
+
+static td_err_e
+libthr_db_ta_new(struct ps_prochandle *ph, td_thragent_t **ta_p)
+{
+ td_thragent_t *ta;
+ psaddr_t addr;
+ ps_err_e err;
+
+ err = ps_pglobal_lookup(ph, NULL, "_libthr_debug", &addr);
+ if (err != PS_OK)
+ return (TD_NOLIBTHREAD);
+
+ ta = malloc(sizeof(td_thragent_t));
+ if (ta == NULL)
+ return (TD_MALLOC);
+
+ ta->ta_ph = ph;
+
+ err = ps_pglobal_lookup(ph, NULL, "_thread_list", &ta->ta_thread_list);
+ if (err != PS_OK)
+ goto fail;
+ err = ps_pglobal_lookup(ph, NULL, "_thread_ctx_offset", &addr);
+ if (err != PS_OK)
+ goto fail;
+ err = ps_pread(ph, addr, &ta->ta_ofs_ctx, sizeof(int));
+ if (err != PS_OK)
+ goto fail;
+ err = ps_pglobal_lookup(ph, NULL, "_thread_next_offset", &addr);
+ if (err != PS_OK)
+ goto fail;
+ err = ps_pread(ph, addr, &ta->ta_ofs_next, sizeof(int));
+ if (err != PS_OK)
+ goto fail;
+ err = ps_pglobal_lookup(ph, NULL, "_thread_thr_id_offset", &addr);
+ if (err != PS_OK)
+ goto fail;
+ err = ps_pread(ph, addr, &ta->ta_ofs_thr_id, sizeof(int));
+ if (err != PS_OK)
+ goto fail;
+
+ *ta_p = ta;
+ return (TD_OK);
+
+ fail:
+ free(ta);
+ *ta_p = NULL;
+ return (TD_ERR);
+}
+
+static td_err_e
+libthr_db_ta_set_event(const td_thragent_t *ta, td_thr_events_t *ev)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libthr_db_ta_thr_iter(const td_thragent_t *ta, td_thr_iter_f *cb, void *data,
+ td_thr_state_e state, int pri, sigset_t *mask, unsigned int flags)
+{
+ td_thrhandle_t th;
+ psaddr_t addr;
+ ps_err_e err;
+
+ th.th_ta = ta;
+
+ err = ps_pread(ta->ta_ph, ta->ta_thread_list, &th.th_thread,
+ sizeof(th.th_thread));
+ if (err != PS_OK)
+ return (TD_ERR);
+ while (th.th_thread != NULL) {
+ if (cb(&th, data) != 0)
+ return (TD_OK);
+ addr = (psaddr_t)((uintptr_t)th.th_thread + ta->ta_ofs_next);
+ err = ps_pread(ta->ta_ph, addr, &th.th_thread,
+ sizeof(th.th_thread));
+ if (err != PS_OK)
+ return (TD_ERR);
+ }
+ return (TD_OK);
+}
+
+static td_err_e
+libthr_db_thr_clear_event(const td_thrhandle_t *th, td_thr_events_t *ev)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libthr_db_thr_event_enable(const td_thrhandle_t *th, int oo)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libthr_db_thr_event_getmsg(const td_thrhandle_t *th, td_event_msg_t *msg)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libthr_db_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *ti)
+{
+ const td_thragent_t *ta;
+ psaddr_t addr;
+ thread_t tid;
+ ps_err_e err;
+
+ ta = th->th_ta;
+ ti->ti_ta_p = ta;
+ addr = (psaddr_t)((uintptr_t)th->th_thread + ta->ta_ofs_thr_id);
+ err = ps_pread(ta->ta_ph, addr, &tid, sizeof(thread_t));
+ ti->ti_lid = tid;
+ ti->ti_tid = tid;
+ return ((err == PS_OK) ? TD_OK : TD_ERR);
+}
+
+static td_err_e
+libthr_db_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *r)
+{
+ const td_thragent_t *ta;
+ psaddr_t addr;
+ thread_t tid;
+ ps_err_e err;
+
+ ta = th->th_ta;
+ addr = (psaddr_t)((uintptr_t)th->th_thread + ta->ta_ofs_thr_id);
+ err = ps_pread(ta->ta_ph, addr, &tid, sizeof(thread_t));
+ if (err != PS_OK)
+ return (TD_ERR);
+ err = ps_lgetfpregs(ta->ta_ph, tid, r);
+ return ((err == PS_OK) ? TD_OK : TD_ERR);
+}
+
+static td_err_e
+libthr_db_thr_getgregs(const td_thrhandle_t *th, prgregset_t r)
+{
+ const td_thragent_t *ta;
+ psaddr_t addr;
+ thread_t tid;
+ ps_err_e err;
+
+ ta = th->th_ta;
+ addr = (psaddr_t)((uintptr_t)th->th_thread + ta->ta_ofs_thr_id);
+ err = ps_pread(ta->ta_ph, addr, &tid, sizeof(thread_t));
+ if (err != PS_OK)
+ return (TD_ERR);
+ err = ps_lgetregs(ta->ta_ph, tid, r);
+ return ((err == PS_OK) ? TD_OK : TD_ERR);
+}
+
+static td_err_e
+libthr_db_thr_set_event(const td_thrhandle_t *th, td_thr_events_t *ev)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libthr_db_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *r)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libthr_db_thr_setgregs(const td_thrhandle_t *th, const prgregset_t r)
+{
+ return (TD_ERR);
+}
+
+static td_err_e
+libthr_db_thr_validate(const td_thrhandle_t *th)
+{
+ return (TD_ERR);
+}
+
+struct ta_ops libthr_db_ops = {
+ .to_init = libthr_db_init,
+
+ .to_ta_clear_event = libthr_db_ta_clear_event,
+ .to_ta_delete = libthr_db_ta_delete,
+ .to_ta_event_addr = libthr_db_ta_event_addr,
+ .to_ta_event_getmsg = libthr_db_ta_event_getmsg,
+ .to_ta_map_id2thr = libthr_db_ta_map_id2thr,
+ .to_ta_map_lwp2thr = libthr_db_ta_map_lwp2thr,
+ .to_ta_new = libthr_db_ta_new,
+ .to_ta_set_event = libthr_db_ta_set_event,
+ .to_ta_thr_iter = libthr_db_ta_thr_iter,
+
+ .to_thr_clear_event = libthr_db_thr_clear_event,
+ .to_thr_event_enable = libthr_db_thr_event_enable,
+ .to_thr_event_getmsg = libthr_db_thr_event_getmsg,
+ .to_thr_get_info = libthr_db_thr_get_info,
+ .to_thr_getfpregs = libthr_db_thr_getfpregs,
+ .to_thr_getgregs = libthr_db_thr_getgregs,
+ .to_thr_set_event = libthr_db_thr_set_event,
+ .to_thr_setfpregs = libthr_db_thr_setfpregs,
+ .to_thr_setgregs = libthr_db_thr_setgregs,
+ .to_thr_validate = libthr_db_thr_validate
+};
diff --git a/lib/libthread_db/pthread/Makefile b/lib/libthread_db/pthread/Makefile
deleted file mode 100644
index cbd245d..0000000
--- a/lib/libthread_db/pthread/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# $FreeBSD$
-
-LIB=pthread_db
-INTERNALLIB=yes
-NOPROFILE=yes
-NOPIC=yes
-CFLAGS+=-DPTHREAD_KERNEL -fpic -DPIC
-CFLAGS+=-I${.CURDIR}/../include \
- -I${.CURDIR}/../../libc/include -I${.CURDIR}/../../libpthread/thread \
- -I${.CURDIR}/../../../include
-CFLAGS+=-I${.CURDIR}/../../libpthread/arch/${MACHINE_ARCH}/include
-CFLAGS+=-I${.CURDIR}/../../libpthread/sys
-CFLAGS+=-Wall
-
-.PATH: ${.CURDIR}
-
-SRCS+=pthread_db.c pthread_db_${MACHINE_ARCH}.c
-
-.include <bsd.lib.mk>
diff --git a/lib/libthread_db/src/Makefile b/lib/libthread_db/src/Makefile
deleted file mode 100644
index 236e7bc..0000000
--- a/lib/libthread_db/src/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# $FreeBSD$
-
-SHLIB_NAME=libthread_db.so.1
-NOPROFILE=yes
-CFLAGS+=-Wall -I${.CURDIR}/../../../include -I${.CURDIR}/../include
-LDADD=../pthread/libpthread_db.a
-
-PRECIOUSLIB=yes
-
-.PATH: ${.CURDIR}
-
-SRCS+=thread_db.c
-INCS=../include/thread_db.h
-
-.include <bsd.lib.mk>
diff --git a/lib/libthread_db/src/thread_db.c b/lib/libthread_db/src/thread_db.c
deleted file mode 100644
index 1e841c2..0000000
--- a/lib/libthread_db/src/thread_db.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (c) 2004 David Xu <davidxu@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <stddef.h>
-#include <unistd.h>
-
-#include <proc_service.h>
-#include <thread_db.h>
-#include "thread_db_int.h"
-
-static TAILQ_HEAD(, td_thragent) proclist = TAILQ_HEAD_INITIALIZER(proclist);
-
-extern struct ta_ops pthread_ops;
-#if 0
-extern struct ta_ops thr_ops;
-extern struct ta_ops c_r_ops;
-#endif
-
-static struct ta_ops *ops[] = {
- &pthread_ops,
-#if 0
- &thr_ops,
- &c_r_ops
-#endif
-};
-
-td_err_e
-td_init(void)
-{
- int i, ret = 0;
-
- for (i = 0; i < sizeof(ops)/sizeof(ops[0]); ++i) {
- int tmp;
- if ((tmp = ops[i]->to_init()) != 0)
- ret = tmp;
- }
- return (ret);
-}
-
-td_err_e
-td_ta_new(struct ps_prochandle *ph, td_thragent_t **pta)
-{
- int i;
-
- for (i = 0; i < sizeof(ops)/sizeof(ops[0]); ++i) {
- if (ops[i]->to_ta_new(ph, pta) == 0) {
- (*pta)->ta_ops = ops[i];
- TAILQ_INSERT_HEAD(&proclist, *pta, ta_next);
- return (0);
- }
- }
- return (TD_NOLIBTHREAD);
-
-}
-
-td_err_e
-td_ta_delete(td_thragent_t *ta)
-{
- TAILQ_REMOVE(&proclist, ta, ta_next);
- return ta->ta_ops->to_ta_delete(ta);
-}
-
-td_err_e
-td_ta_get_nthreads(const td_thragent_t *ta, int *np)
-{
- return ta->ta_ops->to_ta_get_nthreads(ta, np);
-}
-
-td_err_e
-td_ta_get_ph(const td_thragent_t *ta, struct ps_prochandle **ph)
-{
- return ta->ta_ops->to_ta_get_ph(ta, ph);
-}
-
-td_err_e
-td_ta_map_id2thr(const td_thragent_t *ta, thread_t id, td_thrhandle_t *th)
-{
- return ta->ta_ops->to_ta_map_id2thr(ta, id, th);
-}
-
-td_err_e
-td_ta_map_lwp2thr(const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
-{
- return ta->ta_ops->to_ta_map_lwp2thr(ta, lwpid, th);
-}
-
-td_err_e
-td_ta_thr_iter(const td_thragent_t *ta,
- td_thr_iter_f *callback, void *cbdata_p,
- td_thr_state_e state, int ti_pri,
- sigset_t *ti_sigmask_p,
- unsigned int ti_user_flags)
-{
- return ta->ta_ops->to_ta_thr_iter(ta, callback, cbdata_p, state,
- ti_pri, ti_sigmask_p, ti_user_flags);
-}
-
-td_err_e
-td_ta_tsd_iter(const td_thragent_t *ta, td_key_iter_f *ki, void *arg)
-{
- return ta->ta_ops->to_ta_tsd_iter(ta, ki, arg);
-}
-
-td_err_e
-td_ta_event_addr(const td_thragent_t *ta, td_event_e event, td_notify_t *ptr)
-{
- return ta->ta_ops->to_ta_event_addr(ta, event, ptr);
-}
-
-td_err_e
-td_ta_set_event(const td_thragent_t *ta, td_thr_events_t *events)
-{
- return ta->ta_ops->to_ta_set_event(ta, events);
-}
-
-td_err_e
-td_ta_clear_event(const td_thragent_t *ta, td_thr_events_t *events)
-{
- return ta->ta_ops->to_ta_clear_event(ta, events);
-}
-
-td_err_e
-td_ta_event_getmsg(const td_thragent_t *ta, td_event_msg_t *msg)
-{
- return ta->ta_ops->to_ta_event_getmsg(ta, msg);
-}
-
-td_err_e
-td_ta_setconcurrency(const td_thragent_t *ta, int level)
-{
- return ta->ta_ops->to_ta_setconcurrency(ta, level);
-}
-
-td_err_e
-td_ta_enable_stats(const td_thragent_t *ta, int enable)
-{
- return ta->ta_ops->to_ta_enable_stats(ta, enable);
-}
-
-td_err_e
-td_ta_reset_stats(const td_thragent_t *ta)
-{
- return ta->ta_ops->to_ta_reset_stats(ta);
-}
-
-td_err_e
-td_ta_get_stats(const td_thragent_t *ta, td_ta_stats_t *statsp)
-{
- return ta->ta_ops->to_ta_get_stats(ta, statsp);
-}
-
-td_err_e
-td_thr_validate(const td_thrhandle_t *th)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_validate(th);
-}
-
-td_err_e
-td_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_get_info(th, info);
-}
-
-td_err_e
-td_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregset)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_getfpregs(th, fpregset);
-}
-
-td_err_e
-td_thr_getgregs(const td_thrhandle_t *th, prgregset_t gregs)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_getgregs(th, gregs);
-}
-
-td_err_e
-td_thr_getxregs(const td_thrhandle_t *th, void *xregs)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_getxregs(th, xregs);
-}
-
-td_err_e
-td_thr_getxregsize(const td_thrhandle_t *th, int *sizep)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_getxregsize(th, sizep);
-}
-
-td_err_e
-td_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *fpregs)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_setfpregs(th, fpregs);
-}
-
-td_err_e
-td_thr_setgregs(const td_thrhandle_t *th, const prgregset_t gregs)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_setgregs(th, gregs);
-}
-
-td_err_e
-td_thr_setxregs(const td_thrhandle_t *th, const void *addr)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_setxregs(th, addr);
-}
-
-td_err_e
-td_thr_event_enable(const td_thrhandle_t *th, int en)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_event_enable(th, en);
-}
-
-td_err_e
-td_thr_set_event(const td_thrhandle_t *th, td_thr_events_t *setp)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_set_event(th, setp);
-}
-
-td_err_e
-td_thr_clear_event(const td_thrhandle_t *th, td_thr_events_t *setp)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_clear_event(th, setp);
-}
-
-td_err_e
-td_thr_event_getmsg(const td_thrhandle_t *th, td_event_msg_t *msg)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_event_getmsg(th, msg);
-}
-
-td_err_e
-td_thr_setprio(const td_thrhandle_t *th, int pri)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_setprio(th, pri);
-}
-
-td_err_e
-td_thr_setsigpending(const td_thrhandle_t *th, unsigned char n,
- const sigset_t *set)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_setsigpending(th, n, set);
-}
-
-td_err_e
-td_thr_sigsetmask(const td_thrhandle_t *th, const sigset_t *set)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_sigsetmask(th, set);
-}
-
-td_err_e
-td_thr_tsd(const td_thrhandle_t *th, const thread_key_t key, void **data)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_tsd(th, key, data);
-}
-
-td_err_e
-td_thr_dbsuspend(const td_thrhandle_t *th)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_dbsuspend(th);
-}
-
-td_err_e
-td_thr_dbresume(const td_thrhandle_t *th)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_dbresume(th);
-}
-
-td_err_e
-td_get_ta(int pid, td_thragent_t **ta_p)
-{
- td_thragent_t *ta;
- struct ps_prochandle *ph;
-
- TAILQ_FOREACH(ta, &proclist, ta_next) {
- td_ta_get_ph(ta, &ph);
- if (ps_getpid(ph) == pid) {
- *ta_p = ta;
- return (TD_OK);
- }
- }
- return (TD_ERR);
-}
-
-td_err_e
-td_ta_activated(td_thragent_t *ta, int *a)
-{
- return ta->ta_ops->to_ta_activated(ta, a);
-}
-
-td_err_e
-td_thr_sstep(td_thrhandle_t *th, int step)
-{
- td_thragent_t *ta = th->th_ta_p;
-
- return ta->ta_ops->to_thr_sstep(th, step);
-}
diff --git a/lib/libthread_db/thread_db.c b/lib/libthread_db/thread_db.c
new file mode 100644
index 0000000..e92d4ff
--- /dev/null
+++ b/lib/libthread_db/thread_db.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2004 David Xu <davidxu@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <proc_service.h>
+#include <stddef.h>
+#include <thread_db.h>
+#include <unistd.h>
+
+#include "thread_db_int.h"
+
+struct td_thragent
+{
+ TD_THRAGENT_FIELDS;
+};
+
+static TAILQ_HEAD(, td_thragent) proclist = TAILQ_HEAD_INITIALIZER(proclist);
+
+extern struct ta_ops libc_r_db_ops;
+extern struct ta_ops libpthread_db_ops;
+extern struct ta_ops libthr_db_ops;
+
+static struct ta_ops *ops[] = {
+ &libpthread_db_ops,
+ &libthr_db_ops,
+ &libc_r_db_ops
+};
+
+td_err_e
+td_init(void)
+{
+ td_err_e ret, tmp;
+ size_t i;
+
+ ret = 0;
+ for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) {
+ if (ops[i]->to_init != NULL) {
+ tmp = ops[i]->to_init();
+ if (tmp != TD_OK)
+ ret = tmp;
+ }
+ }
+ return (ret);
+}
+
+td_err_e
+td_ta_clear_event(const td_thragent_t *ta, td_thr_events_t *events)
+{
+ return (ta->ta_ops->to_ta_clear_event(ta, events));
+}
+
+td_err_e
+td_ta_delete(td_thragent_t *ta)
+{
+ TAILQ_REMOVE(&proclist, ta, ta_next);
+ return (ta->ta_ops->to_ta_delete(ta));
+}
+
+td_err_e
+td_ta_event_addr(const td_thragent_t *ta, td_event_e event, td_notify_t *ptr)
+{
+ return (ta->ta_ops->to_ta_event_addr(ta, event, ptr));
+}
+
+td_err_e
+td_ta_event_getmsg(const td_thragent_t *ta, td_event_msg_t *msg)
+{
+ return (ta->ta_ops->to_ta_event_getmsg(ta, msg));
+}
+
+td_err_e
+td_ta_map_id2thr(const td_thragent_t *ta, thread_t id, td_thrhandle_t *th)
+{
+ return (ta->ta_ops->to_ta_map_id2thr(ta, id, th));
+}
+
+td_err_e
+td_ta_map_lwp2thr(const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
+{
+ return (ta->ta_ops->to_ta_map_lwp2thr(ta, lwpid, th));
+}
+
+td_err_e
+td_ta_new(struct ps_prochandle *ph, td_thragent_t **pta)
+{
+ size_t i;
+
+ for (i = 0; i < sizeof(ops)/sizeof(ops[0]); ++i) {
+ if (ops[i]->to_ta_new(ph, pta) == TD_OK) {
+ TAILQ_INSERT_HEAD(&proclist, *pta, ta_next);
+ (*pta)->ta_ops = ops[i];
+ return (TD_OK);
+ }
+ }
+ return (TD_NOLIBTHREAD);
+}
+
+td_err_e
+td_ta_set_event(const td_thragent_t *ta, td_thr_events_t *events)
+{
+ return (ta->ta_ops->to_ta_set_event(ta, events));
+}
+
+td_err_e
+td_ta_thr_iter(const td_thragent_t *ta, td_thr_iter_f *callback,
+ void *cbdata_p, td_thr_state_e state, int ti_pri, sigset_t *ti_sigmask_p,
+ unsigned int ti_user_flags)
+{
+ return (ta->ta_ops->to_ta_thr_iter(ta, callback, cbdata_p, state,
+ ti_pri, ti_sigmask_p, ti_user_flags));
+}
+
+td_err_e
+td_ta_tsd_iter(const td_thragent_t *ta, td_key_iter_f *callback,
+ void *cbdata_p)
+{
+ return (ta->ta_ops->to_ta_tsd_iter(ta, callback, cbdata_p));
+}
+
+td_err_e
+td_thr_clear_event(const td_thrhandle_t *th, td_thr_events_t *events)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_clear_event(th, events));
+}
+
+td_err_e
+td_thr_dbresume(const td_thrhandle_t *th)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_dbresume(th));
+}
+
+td_err_e
+td_thr_dbsuspend(const td_thrhandle_t *th)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_dbsuspend(th));
+}
+
+td_err_e
+td_thr_event_enable(const td_thrhandle_t *th, int en)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_event_enable(th, en));
+}
+
+td_err_e
+td_thr_event_getmsg(const td_thrhandle_t *th, td_event_msg_t *msg)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_event_getmsg(th, msg));
+}
+
+td_err_e
+td_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_get_info(th, info));
+}
+
+td_err_e
+td_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregset)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_getfpregs(th, fpregset));
+}
+
+td_err_e
+td_thr_getgregs(const td_thrhandle_t *th, prgregset_t gregs)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_getgregs(th, gregs));
+}
+
+td_err_e
+td_thr_set_event(const td_thrhandle_t *th, td_thr_events_t *events)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_set_event(th, events));
+}
+
+td_err_e
+td_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *fpregs)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_setfpregs(th, fpregs));
+}
+
+td_err_e
+td_thr_setgregs(const td_thrhandle_t *th, const prgregset_t gregs)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_setgregs(th, gregs));
+}
+
+td_err_e
+td_thr_validate(const td_thrhandle_t *th)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_validate(th));
+}
+
+/* FreeBSD specific extensions. */
+
+td_err_e
+td_thr_sstep(const td_thrhandle_t *th, int step)
+{
+ const td_thragent_t *ta = th->th_ta;
+ return (ta->ta_ops->to_thr_sstep(th, step));
+}
diff --git a/lib/libthread_db/thread_db.h b/lib/libthread_db/thread_db.h
new file mode 100644
index 0000000..ec0baaf
--- /dev/null
+++ b/lib/libthread_db/thread_db.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _THREAD_DB_H_
+#define _THREAD_DB_H_
+
+#include <sys/procfs.h>
+#include <pthread.h>
+
+typedef enum {
+ TD_ERR = -1, /* Unspecified error. */
+ TD_OK = 0, /* No error. */
+ TD_BADKEY,
+ TD_BADPH,
+ TD_BADSH,
+ TD_BADTA,
+ TD_BADTH,
+ TD_DBERR,
+ TD_MALLOC,
+ TD_NOAPLIC,
+ TD_NOCAPAB,
+ TD_NOEVENT,
+ TD_NOFPREGS,
+ TD_NOLIBTHREAD,
+ TD_NOLWP,
+ TD_NOMSG,
+ TD_NOSV,
+ TD_NOTHR,
+ TD_NOTSD,
+ TD_NOXREGS,
+ TD_PARTIALREG
+} td_err_e;
+
+typedef struct td_thragent td_thragent_t;
+typedef long thread_t; /* Must be an integral type. */
+
+typedef struct {
+ const td_thragent_t *th_ta;
+ psaddr_t th_thread;
+ thread_t th_tid;
+} td_thrhandle_t; /* Used non-opaguely. */
+
+/*
+ * Events.
+ */
+
+typedef enum {
+ TD_EVENT_NONE = 0,
+ TD_CREATE = 0x0001,
+ TD_DEATH = 0x0002,
+ TD_ALL_EVENTS = ~0
+} td_thr_events_e;
+
+/* Compatibility with Linux. */
+#define td_event_e td_thr_events_e
+
+typedef struct {
+ td_thr_events_e event;
+ const td_thrhandle_t *th_p;
+ uintptr_t data;
+} td_event_msg_t;
+
+typedef unsigned int td_thr_events_t;
+
+/* XXX can't be it... */
+typedef struct {
+ union {
+ psaddr_t bptaddr;
+ } u;
+} td_notify_t;
+
+static __inline void
+td_event_addset(td_thr_events_t *es, td_thr_events_e e)
+{
+ *es |= e;
+}
+
+static __inline void
+td_event_delset(td_thr_events_t *es, td_thr_events_e e)
+{
+ *es &= ~e;
+}
+
+static __inline void
+td_event_emptyset(td_thr_events_t *es)
+{
+ *es = TD_EVENT_NONE;
+}
+
+static __inline void
+td_event_fillset(td_thr_events_t *es)
+{
+ *es = TD_ALL_EVENTS;
+}
+
+static __inline int
+td_eventisempty(td_thr_events_t *es)
+{
+ return ((*es == TD_EVENT_NONE) ? 1 : 0);
+}
+
+static __inline int
+td_eventismember(td_thr_events_t *es, td_thr_events_e e)
+{
+ return ((*es & e) ? 1 : 0);
+}
+
+/*
+ * Thread info.
+ */
+
+typedef enum {
+ TD_THR_UNKNOWN = -1,
+ TD_THR_ANY_STATE = 0,
+ TD_THR_ACTIVE,
+ TD_THR_RUN,
+ TD_THR_SLEEP,
+ TD_THR_STOPPED,
+ TD_THR_STOPPED_ASLEEP,
+ TD_THR_ZOMBIE
+} td_thr_state_e;
+
+typedef enum
+{
+ TD_THR_SYSTEM = 1,
+ TD_THR_USER
+} td_thr_type_e;
+
+typedef int thread_key_t;
+
+#if 0
+typedef struct td_thrinfo_t {
+ unsigned int ti_user_flags;
+ psaddr_t ti_pc;
+ psaddr_t ti_sp;
+ short ti_flags;
+ uchar_t ti_preemptflag;
+ uchar_t ti_pirecflag;
+};
+#endif
+
+typedef struct {
+ const td_thragent_t *ti_ta_p;
+ thread_t ti_tid;
+ td_thr_state_e ti_state;
+ td_thr_type_e ti_type;
+ td_thr_events_t ti_events;
+ int ti_pri;
+ lwpid_t ti_lid;
+ char ti_db_suspended;
+ char ti_traceme;
+ sigset_t ti_sigmask;
+ sigset_t ti_pending;
+ psaddr_t ti_tls;
+ psaddr_t ti_startfunc;
+ psaddr_t ti_stkbase;
+ size_t ti_stksize;
+} td_thrinfo_t;
+
+/*
+ * Prototypes.
+ */
+
+typedef int td_key_iter_f(thread_key_t, void (*)(void *), void *);
+typedef int td_thr_iter_f(const td_thrhandle_t *, void *);
+
+/* Flags for `td_ta_thr_iter'. */
+#define TD_THR_ANY_USER_FLAGS 0xffffffff
+#define TD_THR_LOWEST_PRIORITY -20
+#define TD_SIGNO_MASK NULL
+
+__BEGIN_DECLS
+td_err_e td_init(void);
+
+td_err_e td_ta_clear_event(const td_thragent_t *, td_thr_events_t *);
+td_err_e td_ta_delete(td_thragent_t *);
+td_err_e td_ta_event_addr(const td_thragent_t *, td_thr_events_e,
+ td_notify_t *);
+td_err_e td_ta_event_getmsg(const td_thragent_t *, td_event_msg_t *);
+td_err_e td_ta_map_id2thr(const td_thragent_t *, thread_t, td_thrhandle_t *);
+td_err_e td_ta_map_lwp2thr(const td_thragent_t *, lwpid_t, td_thrhandle_t *);
+td_err_e td_ta_new(struct ps_prochandle *, td_thragent_t **);
+td_err_e td_ta_set_event(const td_thragent_t *, td_thr_events_t *);
+td_err_e td_ta_thr_iter(const td_thragent_t *, td_thr_iter_f *, void *,
+ td_thr_state_e, int, sigset_t *, unsigned int);
+td_err_e td_ta_tsd_iter(const td_thragent_t *, td_key_iter_f *, void *);
+
+td_err_e td_thr_clear_event(const td_thrhandle_t *, td_thr_events_t *);
+td_err_e td_thr_dbresume(const td_thrhandle_t *);
+td_err_e td_thr_dbsuspend(const td_thrhandle_t *);
+td_err_e td_thr_event_enable(const td_thrhandle_t *, int);
+td_err_e td_thr_event_getmsg(const td_thrhandle_t *, td_event_msg_t *);
+td_err_e td_thr_get_info(const td_thrhandle_t *, td_thrinfo_t *);
+td_err_e td_thr_getfpregs(const td_thrhandle_t *, prfpregset_t *);
+td_err_e td_thr_getgregs(const td_thrhandle_t *, prgregset_t);
+td_err_e td_thr_set_event(const td_thrhandle_t *, td_thr_events_t *);
+td_err_e td_thr_setfpregs(const td_thrhandle_t *, const prfpregset_t *);
+td_err_e td_thr_setgregs(const td_thrhandle_t *, const prgregset_t);
+td_err_e td_thr_validate(const td_thrhandle_t *);
+
+/* FreeBSD specific extensions. */
+td_err_e td_thr_sstep(const td_thrhandle_t *, int);
+__END_DECLS
+
+#endif /* _THREAD_DB_H_ */
diff --git a/lib/libthread_db/include/thread_db_int.h b/lib/libthread_db/thread_db_int.h
index 5afcb02..1b56251 100644
--- a/lib/libthread_db/include/thread_db_int.h
+++ b/lib/libthread_db/thread_db_int.h
@@ -26,68 +26,65 @@
* $FreeBSD$
*/
-#ifndef _THREAD_DB_INT_H
-#define _THREAD_DB_INT_H
+#ifndef _THREAD_DB_INT_H_
+#define _THREAD_DB_INT_H_
#include <sys/types.h>
#include <sys/queue.h>
-struct td_thragent {
- struct ta_ops *ta_ops;
- TAILQ_ENTRY(td_thragent) ta_next;
-};
+#define TD_THRAGENT_FIELDS \
+ struct ta_ops *ta_ops; \
+ TAILQ_ENTRY(td_thragent) ta_next; \
+ struct ps_prochandle *ph
struct ta_ops {
td_err_e (*to_init)(void);
- td_err_e (*to_ta_new)(struct ps_prochandle *, td_thragent_t **);
+
+ td_err_e (*to_ta_clear_event)(const td_thragent_t *,
+ td_thr_events_t *);
td_err_e (*to_ta_delete)(td_thragent_t *);
- td_err_e (*to_ta_get_nthreads)(const td_thragent_t *, int *);
- td_err_e (*to_ta_get_ph)(const td_thragent_t *, struct ps_prochandle **);
- td_err_e (*to_ta_map_id2thr)(const td_thragent_t *, thread_t, td_thrhandle_t *);
- td_err_e (*to_ta_map_lwp2thr)(const td_thragent_t *, lwpid_t lwpid,
- td_thrhandle_t *);
- td_err_e (*to_ta_thr_iter)(const td_thragent_t *, td_thr_iter_f *, void *,
- td_thr_state_e, int, sigset_t *, unsigned int);
- td_err_e (*to_ta_tsd_iter)(const td_thragent_t *, td_key_iter_f *, void *);
- td_err_e (*to_ta_event_addr)(const td_thragent_t *, td_event_e , td_notify_t *);
+ td_err_e (*to_ta_event_addr)(const td_thragent_t *, td_thr_events_e,
+ td_notify_t *);
+ td_err_e (*to_ta_event_getmsg)(const td_thragent_t *,
+ td_event_msg_t *);
+ td_err_e (*to_ta_map_id2thr)(const td_thragent_t *, thread_t,
+ td_thrhandle_t *);
+ td_err_e (*to_ta_map_lwp2thr)(const td_thragent_t *, lwpid_t,
+ td_thrhandle_t *);
+ td_err_e (*to_ta_new)(struct ps_prochandle *, td_thragent_t **);
td_err_e (*to_ta_set_event)(const td_thragent_t *, td_thr_events_t *);
- td_err_e (*to_ta_clear_event)(const td_thragent_t *, td_thr_events_t *);
- td_err_e (*to_ta_event_getmsg)(const td_thragent_t *, td_event_msg_t *);
- td_err_e (*to_ta_setconcurrency)(const td_thragent_t *, int);
- td_err_e (*to_ta_enable_stats)(const td_thragent_t *, int);
- td_err_e (*to_ta_reset_stats)(const td_thragent_t *);
- td_err_e (*to_ta_get_stats)(const td_thragent_t *, td_ta_stats_t *);
- td_err_e (*to_thr_validate)(const td_thrhandle_t *);
+ td_err_e (*to_ta_thr_iter)(const td_thragent_t *, td_thr_iter_f *,
+ void *, td_thr_state_e, int, sigset_t *, unsigned int);
+ td_err_e (*to_ta_tsd_iter)(const td_thragent_t *, td_key_iter_f *,
+ void *);
+
+ td_err_e (*to_thr_clear_event)(const td_thrhandle_t *,
+ td_thr_events_t *);
+ td_err_e (*to_thr_dbresume)(const td_thrhandle_t *);
+ td_err_e (*to_thr_dbsuspend)(const td_thrhandle_t *);
+ td_err_e (*to_thr_event_enable)(const td_thrhandle_t *, int);
+ td_err_e (*to_thr_event_getmsg)(const td_thrhandle_t *,
+ td_event_msg_t *);
td_err_e (*to_thr_get_info)(const td_thrhandle_t *, td_thrinfo_t *);
td_err_e (*to_thr_getfpregs)(const td_thrhandle_t *, prfpregset_t *);
td_err_e (*to_thr_getgregs)(const td_thrhandle_t *, prgregset_t);
- td_err_e (*to_thr_getxregs)(const td_thrhandle_t *, void *);
- td_err_e (*to_thr_getxregsize)(const td_thrhandle_t *, int *);
- td_err_e (*to_thr_setfpregs)(const td_thrhandle_t *, const prfpregset_t *);
+ td_err_e (*to_thr_set_event)(const td_thrhandle_t *,
+ td_thr_events_t *);
+ td_err_e (*to_thr_setfpregs)(const td_thrhandle_t *,
+ const prfpregset_t *);
td_err_e (*to_thr_setgregs)(const td_thrhandle_t *, const prgregset_t);
- td_err_e (*to_thr_setxregs)(const td_thrhandle_t *, const void *);
- td_err_e (*to_thr_event_enable)(const td_thrhandle_t *, int);
- td_err_e (*to_thr_set_event)(const td_thrhandle_t *, td_thr_events_t *);
- td_err_e (*to_thr_clear_event)(const td_thrhandle_t *, td_thr_events_t *);
- td_err_e (*to_thr_event_getmsg)(const td_thrhandle_t *, td_event_msg_t *);
- td_err_e (*to_thr_setprio)(const td_thrhandle_t *, int);
- td_err_e (*to_thr_setsigpending)(const td_thrhandle_t *, unsigned char,
- const sigset_t *);
- td_err_e (*to_thr_sigsetmask)(const td_thrhandle_t *, const sigset_t *);
- td_err_e (*to_thr_tsd)(const td_thrhandle_t *, const thread_key_t, void **);
- td_err_e (*to_thr_dbsuspend)(const td_thrhandle_t *);
- td_err_e (*to_thr_dbresume)(const td_thrhandle_t *);
- td_err_e (*to_get_ta)(int pid, td_thragent_t **);
- td_err_e (*to_ta_activated)(td_thragent_t *, int *);
- td_err_e (*to_thr_sstep)(td_thrhandle_t *, int step);
+ td_err_e (*to_thr_validate)(const td_thrhandle_t *);
+
+ /* FreeBSD specific extensions. */
+ td_err_e (*to_thr_sstep)(const td_thrhandle_t *, int);
};
#ifdef TD_DEBUG
#define TDBG(...) ps_plog(__VA_ARGS__)
-#define TDBG_FUNC() ps_plog(__func__); ps_plog("\n")
+#define TDBG_FUNC() ps_plog("%s\n", __func__)
#else
#define TDBG(...)
#define TDBG_FUNC()
#endif
-#endif
+#endif /* _THREAD_DB_INT_H_ */
OpenPOWER on IntegriCloud