summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2004-07-18 04:17:15 +0000
committermarcel <marcel@FreeBSD.org>2004-07-18 04:17:15 +0000
commit03a64a6205cacf6f86c1fd453ba860c7c396b285 (patch)
tree7bd51edf97e872db5b632c4e4f5b742ac0fb5e09
parent606ea367aee6e42c3e2ef3e78e6a2c9450ca0733 (diff)
downloadFreeBSD-src-03a64a6205cacf6f86c1fd453ba860c7c396b285.zip
FreeBSD-src-03a64a6205cacf6f86c1fd453ba860c7c396b285.tar.gz
Add rudimentary support and stubs for libthr and libc_r on alpha, amd64,
i386, ia64 and sparc64. Add stubs for alpha, amd64, ia64 and sparc64 for libpthread. Restructure the source files to avoid unnecessary use of subdirectories that also force us to use non-portable compilation flags to deal with the uncommon compilation requirements (building archive libraries for linkage into a shared library). The libpthread support has been copied from the original local and cleaned-up to make them WARNS=2 clean. that also force us to use non-portable compilation flags to deal with the uncommon compilation requirements (building archive libraries for linkage into a shared library). The libpthread support has been copied from the original local and cleaned-up to make them WARNS=2 clean. Tested on: amd64, i386, ia64
-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