[RFC][gdb] Handle static libipt

Tom de Vries tdevries@suse.de
Mon Jul 27 07:49:08 GMT 2020


Hi,

Libipt can be build as shared library, and used by gdb when f.i. specifying
configure flags --with-libipt-prefix=<path/to/install> and
--with-libipt-type=shared.

Since libipt release v2.0.1, there's support to build as static library.

But when trying to use this in gdb by specifying --with-libipt-type=static, we
run into the problem that the constructor is not called ( filed as
https://github.com/intel/libipt/issues/71 ).

Work around this problem in gdb by inlining the constructor contents in main.

Tested on x86_64-linux, with static libipt master, v2.0.2 and v1.4.4 (with
static support backported).

Any comments?

Thanks,
- Tom

[gdb] Handle static libipt

gdb/ChangeLog:

2020-07-26  Tom de Vries  <tdevries@suse.de>

	* config.in: Regenerate.
	* configure: Regenerate.
	* gdb.c (main)[HAVE_LIBIPT_STATIC]: Call libipt constructor.

gdbserver/ChangeLog:

2020-07-26  Tom de Vries  <tdevries@suse.de>

	* config.in: Regenerate.
	* configure: Regenerate.

gdbsupport/ChangeLog:

2020-07-26  Tom de Vries  <tdevries@suse.de>

	* common.m4 (HAVE_LIBIPT_STATIC): New AC_DEFINE.
	(pt_ild_init, pti_ild_init): New AC_CHECK_FUNCS.
	* config.in: Regenerate.
	* configure: Regenerate.

---
 gdb/config.in        |  9 +++++++++
 gdb/configure        | 29 +++++++++++++++++++++++++++++
 gdb/gdb.c            | 28 ++++++++++++++++++++++++++++
 gdbserver/config.in  |  9 +++++++++
 gdbserver/configure  | 29 +++++++++++++++++++++++++++++
 gdbsupport/common.m4 |  7 +++++++
 gdbsupport/config.in |  9 +++++++++
 gdbsupport/configure | 29 +++++++++++++++++++++++++++++
 8 files changed, 149 insertions(+)

diff --git a/gdb/config.in b/gdb/config.in
index 340c421ca0..e036ede34d 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -238,6 +238,9 @@
 /* Define if you have the ipt library. */
 #undef HAVE_LIBIPT
 
+/* Define if libipt is static lib. */
+#undef HAVE_LIBIPT_STATIC
+
 /* Define if you have the lzma library. */
 #undef HAVE_LIBLZMA
 
@@ -346,6 +349,9 @@
 /* Define to 1 if you have the `pthread_sigmask' function. */
 #undef HAVE_PTHREAD_SIGMASK
 
+/* Define to 1 if you have the `pti_ild_init' function. */
+#undef HAVE_PTI_ILD_INIT
+
 /* Define to 1 if you have the `ptrace64' function. */
 #undef HAVE_PTRACE64
 
@@ -364,6 +370,9 @@
 /* Define if sys/ptrace.h defines the PT_GETXMMREGS request. */
 #undef HAVE_PT_GETXMMREGS
 
+/* Define to 1 if you have the `pt_ild_init' function. */
+#undef HAVE_PT_ILD_INIT
+
 /* Define to 1 if you have the `pt_insn_event' function. */
 #undef HAVE_PT_INSN_EVENT
 
diff --git a/gdb/configure b/gdb/configure
index 06b11e2252..16c91ceeca 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -14802,6 +14802,35 @@ $as_echo "$as_me: WARNING: libipt is missing or unusable; some features may be u
     else
       save_LIBS=$LIBS
       LIBS="$LIBS $LIBIPT"
+      case $LIBIPT in
+	   *.a)
+
+$as_echo "#define HAVE_LIBIPT_STATIC 1" >>confdefs.h
+
+		 for ac_func in pt_ild_init
+do :
+  ac_fn_c_check_func "$LINENO" "pt_ild_init" "ac_cv_func_pt_ild_init"
+if test "x$ac_cv_func_pt_ild_init" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_PT_ILD_INIT 1
+_ACEOF
+
+fi
+done
+
+		 for ac_func in pti_ild_init
+do :
+  ac_fn_c_check_func "$LINENO" "pti_ild_init" "ac_cv_func_pti_ild_init"
+if test "x$ac_cv_func_pti_ild_init" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_PTI_ILD_INIT 1
+_ACEOF
+
+fi
+done
+
+	   ;;
+      esac
       for ac_func in pt_insn_event
 do :
   ac_fn_c_check_func "$LINENO" "pt_insn_event" "ac_cv_func_pt_insn_event"
diff --git a/gdb/gdb.c b/gdb/gdb.c
index 1a52a088fc..be51444bfd 100644
--- a/gdb/gdb.c
+++ b/gdb/gdb.c
@@ -20,11 +20,39 @@
 #include "main.h"
 #include "interps.h"
 
+#ifdef HAVE_LIBIPT_STATIC
+/* When using libipt as static library, the constructor init won't be called
+   ( https://github.com/intel/libipt/issues/71 ).  Since it's a static
+   function, we can't call it explictly from gdb either.  We could use
+   -Wl,--whole-archive libipt.a -Wl,--no-whole-archive, but that could pull
+   in more code than necessary.  Instead, we (hack alert) inline the contents
+   of init here.  */
+#ifdef HAVE_PT_ILD_INIT
+/* Libipt's init constructor calls lib internal function pt_ild_init starting
+   v1.5.  */
+extern "C" void pt_ild_init (void);
+#endif
+#ifdef HAVE_PTI_ILD_INIT
+/* Libipt's init constructor calls lib internal function pti_ild_init
+   v1.4-v1.4.4.  */
+extern "C" void pti_ild_init (void);
+#endif
+#endif
+
 int
 main (int argc, char **argv)
 {
   struct captured_main_args args;
 
+#ifdef HAVE_LIBIPT_STATIC
+#ifdef HAVE_PT_ILD_INIT
+  pt_ild_init ();
+#endif
+#ifdef HAVE_PTI_ILD_INIT
+  pti_ild_init ();
+#endif
+#endif
+
   memset (&args, 0, sizeof args);
   args.argc = argc;
   args.argv = argv;
diff --git a/gdbserver/config.in b/gdbserver/config.in
index 07213aa527..f48ba91c02 100644
--- a/gdbserver/config.in
+++ b/gdbserver/config.in
@@ -143,6 +143,9 @@
 /* Define if you have the ipt library. */
 #undef HAVE_LIBIPT
 
+/* Define if libipt is static lib. */
+#undef HAVE_LIBIPT_STATIC
+
 /* Define if the target supports branch tracing. */
 #undef HAVE_LINUX_BTRACE
 
@@ -227,6 +230,9 @@
 /* Define to 1 if you have the `pthread_sigmask' function. */
 #undef HAVE_PTHREAD_SIGMASK
 
+/* Define to 1 if you have the `pti_ild_init' function. */
+#undef HAVE_PTI_ILD_INIT
+
 /* Define to 1 if you have the `ptrace64' function. */
 #undef HAVE_PTRACE64
 
@@ -240,6 +246,9 @@
 /* Define to 1 if you have the <ptrace.h> header file. */
 #undef HAVE_PTRACE_H
 
+/* Define to 1 if you have the `pt_ild_init' function. */
+#undef HAVE_PT_ILD_INIT
+
 /* Define to 1 if you have the `pt_insn_event' function. */
 #undef HAVE_PT_INSN_EVENT
 
diff --git a/gdbserver/configure b/gdbserver/configure
index 0f77ac6cb8..93f7a42991 100755
--- a/gdbserver/configure
+++ b/gdbserver/configure
@@ -8566,6 +8566,35 @@ $as_echo "$as_me: WARNING: libipt is missing or unusable; some features may be u
     else
       save_LIBS=$LIBS
       LIBS="$LIBS $LIBIPT"
+      case $LIBIPT in
+	   *.a)
+
+$as_echo "#define HAVE_LIBIPT_STATIC 1" >>confdefs.h
+
+		 for ac_func in pt_ild_init
+do :
+  ac_fn_c_check_func "$LINENO" "pt_ild_init" "ac_cv_func_pt_ild_init"
+if test "x$ac_cv_func_pt_ild_init" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_PT_ILD_INIT 1
+_ACEOF
+
+fi
+done
+
+		 for ac_func in pti_ild_init
+do :
+  ac_fn_c_check_func "$LINENO" "pti_ild_init" "ac_cv_func_pti_ild_init"
+if test "x$ac_cv_func_pti_ild_init" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_PTI_ILD_INIT 1
+_ACEOF
+
+fi
+done
+
+	   ;;
+      esac
       for ac_func in pt_insn_event
 do :
   ac_fn_c_check_func "$LINENO" "pt_insn_event" "ac_cv_func_pt_insn_event"
diff --git a/gdbsupport/common.m4 b/gdbsupport/common.m4
index b461f5f017..43b2c62270 100644
--- a/gdbsupport/common.m4
+++ b/gdbsupport/common.m4
@@ -166,6 +166,13 @@ AC_DEFUN([GDB_AC_COMMON], [
     else
       save_LIBS=$LIBS
       LIBS="$LIBS $LIBIPT"
+      case $LIBIPT in
+	   *.a)
+	         AC_DEFINE(HAVE_LIBIPT_STATIC, 1, [Define if libipt is static lib. ])
+		 AC_CHECK_FUNCS(pt_ild_init)
+		 AC_CHECK_FUNCS(pti_ild_init)
+	   ;;
+      esac					
       AC_CHECK_FUNCS(pt_insn_event)
       AC_CHECK_MEMBERS([struct pt_insn.enabled, struct pt_insn.resynced], [], [],
 		       [#include <intel-pt.h>])
diff --git a/gdbsupport/config.in b/gdbsupport/config.in
index 5556501395..0523192406 100644
--- a/gdbsupport/config.in
+++ b/gdbsupport/config.in
@@ -121,6 +121,9 @@
 /* Define if you have the ipt library. */
 #undef HAVE_LIBIPT
 
+/* Define if libipt is static lib. */
+#undef HAVE_LIBIPT_STATIC
+
 /* Define to 1 if you have the <linux/elf.h> header file. */
 #undef HAVE_LINUX_ELF_H
 
@@ -181,12 +184,18 @@
 /* Define to 1 if you have the `pthread_sigmask' function. */
 #undef HAVE_PTHREAD_SIGMASK
 
+/* Define to 1 if you have the `pti_ild_init' function. */
+#undef HAVE_PTI_ILD_INIT
+
 /* Define to 1 if you have the `ptrace64' function. */
 #undef HAVE_PTRACE64
 
 /* Define to 1 if you have the <ptrace.h> header file. */
 #undef HAVE_PTRACE_H
 
+/* Define to 1 if you have the `pt_ild_init' function. */
+#undef HAVE_PT_ILD_INIT
+
 /* Define to 1 if you have the `pt_insn_event' function. */
 #undef HAVE_PT_INSN_EVENT
 
diff --git a/gdbsupport/configure b/gdbsupport/configure
index 51caeeb180..8aaa7e4dbf 100755
--- a/gdbsupport/configure
+++ b/gdbsupport/configure
@@ -10264,6 +10264,35 @@ $as_echo "$as_me: WARNING: libipt is missing or unusable; some features may be u
     else
       save_LIBS=$LIBS
       LIBS="$LIBS $LIBIPT"
+      case $LIBIPT in
+	   *.a)
+
+$as_echo "#define HAVE_LIBIPT_STATIC 1" >>confdefs.h
+
+		 for ac_func in pt_ild_init
+do :
+  ac_fn_c_check_func "$LINENO" "pt_ild_init" "ac_cv_func_pt_ild_init"
+if test "x$ac_cv_func_pt_ild_init" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_PT_ILD_INIT 1
+_ACEOF
+
+fi
+done
+
+		 for ac_func in pti_ild_init
+do :
+  ac_fn_c_check_func "$LINENO" "pti_ild_init" "ac_cv_func_pti_ild_init"
+if test "x$ac_cv_func_pti_ild_init" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_PTI_ILD_INIT 1
+_ACEOF
+
+fi
+done
+
+	   ;;
+      esac
       for ac_func in pt_insn_event
 do :
   ac_fn_c_check_func "$LINENO" "pt_insn_event" "ac_cv_func_pt_insn_event"


More information about the Gdb-patches mailing list