Blame SOURCES/ltrace-0.7.91-unwind-elfutils.patch

0678d0
diff -u ltrace-0.7.91/configure.ac ltrace-0.7.91-pm/configure.ac
0678d0
--- ltrace-0.7.91/configure.ac	2015-01-09 00:38:17.977190726 +0100
0678d0
+++ ltrace-0.7.91-pm/configure.ac	2015-01-09 00:37:40.261910548 +0100
0678d0
@@ -128,6 +128,51 @@
0678d0
 AC_CHECK_HEADERS(selinux/selinux.h)
0678d0
 AC_CHECK_LIB(selinux, security_get_boolean_active)
0678d0
 
0678d0
+dnl Whether (and which) elfutils libdw.so to use for unwinding.
0678d0
+AC_ARG_WITH(elfutils,
0678d0
+  AS_HELP_STRING([--with-elfutils], [Use elfutils libdwfl unwinding support]),
0678d0
+  [case "${withval}" in
0678d0
+  (yes|no) enable_elfutils=$withval;;
0678d0
+  (*) enable_elfutils=yes
0678d0
+    AM_CPPFLAGS="${AM_CPPFLAGS} -I${withval}/include"
0678d0
+    AM_LDFLAGS="${AM_LDFLAGS} -L${withval}/lib"
0678d0
+    elfutils_LD_LIBRARY_PATH="${withval}/lib:${withval}/lib/elfutils"
0678d0
+    ;;
0678d0
+esac],[enable_elfutils=maybe])
0678d0
+
0678d0
+dnl Check whether we have the elfutils libdwfl.h header installed.
0678d0
+saved_CPPFLAGS="${CPPFLAGS}"
0678d0
+CPPFLAGS="${CPPFLAGS} ${AM_CPPFLAGS}"
0678d0
+AC_CHECK_HEADERS([elfutils/libdwfl.h],[have_libdwfl_h=yes])
0678d0
+CPPFLAGS="${saved_CPPFLAGS}"
0678d0
+
0678d0
+dnl And whether libdw.so provides the unwinding functions.
0678d0
+saved_LDFLAGS="${LDFLAGS}"
0678d0
+LDFLAGS="${LDFLAGS} ${AM_LDFLAGS}"
0678d0
+AC_CHECK_LIB([dw], [dwfl_getthread_frames], [have_libdw_dwfl_frames=yes])
0678d0
+LDFLAGS="${saved_LDFLAGS}"
0678d0
+
0678d0
+AC_MSG_CHECKING([whether to use elfutils libdwfl unwinding support])
0678d0
+case "${enable_elfutils}" in
0678d0
+(yes|maybe)
0678d0
+  if test x$have_libdwfl_h = xyes -a x$have_libdw_dwfl_frames = xyes; then
0678d0
+    enable_elfutils=yes
0678d0
+  elif test $enable_elfutils = maybe; then
0678d0
+    enable_elfutils=no
0678d0
+  else
0678d0
+    AC_MSG_RESULT([$enable_elfutils])
0678d0
+    AC_MSG_ERROR([Missing elfutils/libdwfl.h or dwfl_getthread_frames not in libdw.so])
0678d0
+  fi
0678d0
+  ;;
0678d0
+(*) ;;
0678d0
+esac
0678d0
+AC_MSG_RESULT([$enable_elfutils])
0678d0
+
0678d0
+if test x"$enable_elfutils" = xyes; then
0678d0
+  libdw_LIBS=-ldw
0678d0
+  AC_SUBST(libdw_LIBS)
0678d0
+  AC_DEFINE([HAVE_LIBDW], [1], [we have elfutils libdw])
0678d0
+fi
0678d0
 
0678d0
 # HAVE_LIBUNWIND
0678d0
 AC_ARG_WITH(libunwind,
0678d0
@@ -193,6 +238,13 @@
0678d0
   LDFLAGS="${saved_LDFLAGS}"
0678d0
 fi
0678d0
 
0678d0
+if test x"$enable_elfutils" = xyes -a x"$enable_libunwind" = xyes; then
0678d0
+  AC_MSG_ERROR([Cannot enable both --with-libunwind and --with-elfutils])
0678d0
+fi
0678d0
+
0678d0
+if test x"$enable_elfutils" = xyes -o x"$enable_libunwind" = xyes; then
0678d0
+  AC_DEFINE([HAVE_UNWINDER], [1], [we have an unwinder available])
0678d0
+fi
0678d0
 
0678d0
 saved_CPPFLAGS="${CPPFLAGS}"
0678d0
 saved_LDFLAGS="${LDFLAGS}"
0678d0
@@ -340,6 +392,7 @@
0678d0
 AC_SUBST(AM_CFLAGS)
0678d0
 AC_SUBST(AM_LDFLAGS)
0678d0
 AC_SUBST(libelf_LD_LIBRARY_PATH)
0678d0
+AC_SUBST(elfutils_LD_LIBRARY_PATH)
0678d0
 AC_SUBST(libunwind_LD_LIBRARY_PATH)
0678d0
 
0678d0
 AC_CONFIG_FILES([
0678d0
diff -u ltrace-0.7.91/ltrace.1 ltrace-0.7.91-pm/ltrace.1
0678d0
--- ltrace-0.7.91/ltrace.1	2015-01-09 00:38:17.975190764 +0100
0678d0
+++ ltrace-0.7.91-pm/ltrace.1	2015-01-09 00:37:40.261910548 +0100
0678d0
@@ -196,7 +196,8 @@
0678d0
 correct execution of setuid and/or setgid binaries.
0678d0
 .IP "\-w, --where \fInr"
0678d0
 Show backtrace of \fInr\fR stack frames for each traced function. This
0678d0
-option enabled only if libunwind support was enabled at compile time.
0678d0
+option enabled only if elfutils or libunwind support was enabled at compile
0678d0
+time.
0678d0
 .IP "\-x \fIfilter"
0678d0
 A qualifying expression which modifies which symbol table entry points
0678d0
 to trace.  The format of the filter expression is described in the
0678d0
diff -u ltrace-0.7.91/Makefile.am ltrace-0.7.91-pm/Makefile.am
0678d0
--- ltrace-0.7.91/Makefile.am	2015-01-09 00:38:17.965190955 +0100
0678d0
+++ ltrace-0.7.91-pm/Makefile.am	2015-01-09 00:37:40.260910568 +0100
0678d0
@@ -40,6 +40,7 @@
0678d0
 	$(liberty_LIBS) \
0678d0
 	$(libsupcxx_LIBS) \
0678d0
 	$(libstdcxx_LIBS) \
0678d0
+	$(libdw_LIBS) \
0678d0
 	$(libunwind_LIBS) \
0678d0
 	sysdeps/libos.la
0678d0
 
0678d0
diff -u ltrace-0.7.91/options.c ltrace-0.7.91-pm/options.c
0678d0
--- ltrace-0.7.91/options.c	2015-01-09 00:38:17.974190783 +0100
0678d0
+++ ltrace-0.7.91-pm/options.c	2015-01-09 00:37:40.261910548 +0100
0678d0
@@ -107,9 +107,9 @@
0678d0
 		"  -T                  show the time spent inside each call.\n"
0678d0
 		"  -u USERNAME         run command with the userid, groupid of username.\n"
0678d0
 		"  -V, --version       output version information and exit.\n"
0678d0
-#if defined(HAVE_LIBUNWIND)
0678d0
+#if defined(HAVE_UNWINDER)
0678d0
 		"  -w, --where=NR      print backtrace showing NR stack frames at most.\n"
0678d0
-#endif /* defined(HAVE_LIBUNWIND) */
0678d0
+#endif /* defined(HAVE_UNWINDER) */
0678d0
 		"  -x FILTER           modify which static functions to trace.\n"
0678d0
 		"\nReport bugs to ltrace-devel@lists.alioth.debian.org\n",
0678d0
 		progname);
0678d0
@@ -519,9 +519,9 @@
0678d0
 	progname = argv[0];
0678d0
 	options.output = stderr;
0678d0
 	options.no_signals = 0;
0678d0
-#if defined(HAVE_LIBUNWIND)
0678d0
+#if defined(HAVE_UNWINDER)
0678d0
 	options.bt_depth = -1;
0678d0
-#endif /* defined(HAVE_LIBUNWIND) */
0678d0
+#endif /* defined(HAVE_UNWINDER) */
0678d0
 
0678d0
 	guess_cols();
0678d0
 
0678d0
@@ -545,9 +545,9 @@
0678d0
 			{"output", 1, 0, 'o'},
0678d0
 			{"version", 0, 0, 'V'},
0678d0
 			{"no-signals", 0, 0, 'b'},
0678d0
-# if defined(HAVE_LIBUNWIND)
0678d0
+# if defined(HAVE_UNWINDER)
0678d0
 			{"where", 1, 0, 'w'},
0678d0
-# endif /* defined(HAVE_LIBUNWIND) */
0678d0
+# endif /* defined(HAVE_UNWINDER) */
0678d0
 			{0, 0, 0, 0}
0678d0
 		};
0678d0
 #endif
0678d0
@@ -556,7 +556,7 @@
0678d0
 #ifdef USE_DEMANGLE
0678d0
 			"C"
0678d0
 #endif
0678d0
-#if defined(HAVE_LIBUNWIND)
0678d0
+#if defined(HAVE_UNWINDER)
0678d0
 			"w:"
0678d0
 #endif
0678d0
 			"cfhiLrStTVba:A:D:e:F:l:n:o:p:s:u:x:X:";
0678d0
@@ -681,11 +681,11 @@
0678d0
 			       "There is NO WARRANTY, to the extent permitted by law.\n");
0678d0
 			exit(0);
0678d0
 			break;
0678d0
-#if defined(HAVE_LIBUNWIND)
0678d0
+#if defined(HAVE_UNWINDER)
0678d0
 		case 'w':
0678d0
 			options.bt_depth = parse_int(optarg, 'w', 1, 0);
0678d0
 			break;
0678d0
-#endif /* defined(HAVE_LIBUNWIND) */
0678d0
+#endif /* defined(HAVE_UNWINDER) */
0678d0
 
0678d0
 		case 'x':
0678d0
 			parse_filter_chain(optarg, &options.static_filter);
0678d0
diff -u ltrace-0.7.91/options.h ltrace-0.7.91-pm/options.h
0678d0
--- ltrace-0.7.91/options.h	2015-01-09 00:38:17.966190936 +0100
0678d0
+++ ltrace-0.7.91-pm/options.h	2015-01-09 00:37:40.261910548 +0100
0678d0
@@ -44,9 +44,9 @@
0678d0
 	size_t strlen;     /* default maximum # of bytes printed in strings */
0678d0
 	int follow;     /* trace child processes */
0678d0
 	int no_signals; /* don't print signals */
0678d0
-#if defined(HAVE_LIBUNWIND)
0678d0
+#if defined(HAVE_UNWINDER)
0678d0
 	int bt_depth;	 /* how may levels of stack frames to show */
0678d0
-#endif /* defined(HAVE_LIBUNWIND) */
0678d0
+#endif /* defined(HAVE_UNWINDER) */
0678d0
 	struct filter *plt_filter;
0678d0
 	struct filter *static_filter;
0678d0
 
0678d0
diff -u ltrace-0.7.91/output.c ltrace-0.7.91-pm/output.c
0678d0
--- ltrace-0.7.91/output.c	2015-01-09 00:38:17.966190936 +0100
0678d0
+++ ltrace-0.7.91-pm/output.c	2015-01-09 00:37:40.261910548 +0100
0678d0
@@ -33,6 +33,7 @@
0678d0
 #include <unistd.h>
0678d0
 #include <errno.h>
0678d0
 #include <assert.h>
0678d0
+#include <inttypes.h>
0678d0
 
0678d0
 #include "output.h"
0678d0
 #include "demangle.h"
0678d0
@@ -567,6 +568,73 @@
0678d0
 	stel->out.need_delim = need_delim;
0678d0
 }
0678d0
 
0678d0
+#if defined(HAVE_LIBDW)
0678d0
+/* Prints information about one frame of a thread.  Called by
0678d0
+   dwfl_getthread_frames in output_right.  Returns 1 when done (max
0678d0
+   number of frames reached).  Returns -1 on error.  Returns 0 on
0678d0
+   success (if there are more frames in the thread, call us again).  */
0678d0
+static int
0678d0
+frame_callback (Dwfl_Frame *state, void *arg)
0678d0
+{
0678d0
+	Dwarf_Addr pc;
0678d0
+	bool isactivation;
0678d0
+
0678d0
+	int *frames = (int *) arg;
0678d0
+
0678d0
+	if (!dwfl_frame_pc(state, &pc, &isactivation))
0678d0
+		return -1;
0678d0
+
0678d0
+	if (!isactivation)
0678d0
+		pc--;
0678d0
+
0678d0
+	Dwfl *dwfl = dwfl_thread_dwfl(dwfl_frame_thread(state));
0678d0
+	Dwfl_Module *mod = dwfl_addrmodule(dwfl, pc);
0678d0
+	const char *modname = NULL;
0678d0
+	const char *symname = NULL;
0678d0
+	GElf_Off off = 0;
0678d0
+	if (mod != NULL) {
0678d0
+		GElf_Sym sym;
0678d0
+		modname = dwfl_module_info(mod, NULL, NULL, NULL, NULL,
0678d0
+					   NULL, NULL, NULL);
0678d0
+		symname = dwfl_module_addrinfo(mod, pc, &off, &sym,
0678d0
+					       NULL, NULL, NULL);
0678d0
+	}
0678d0
+
0678d0
+	/* This mimics the output produced by libunwind below.  */
0678d0
+	fprintf(options.output, " > %s(%s+0x%" PRIx64 ") [%" PRIx64 "]\n",
0678d0
+		modname, symname, off, pc);
0678d0
+
0678d0
+	/* See if we can extract the source line too and print it on
0678d0
+	   the next line if we can find it.  */
0678d0
+	if (mod != NULL) {
0678d0
+		Dwfl_Line *l = dwfl_module_getsrc(mod, pc);
0678d0
+		if (l != NULL) {
0678d0
+			int line, col;
0678d0
+			line = col = -1;
0678d0
+			const char *src = dwfl_lineinfo(l, NULL, &line, &col,
0678d0
+							NULL, NULL);
0678d0
+			if (src != NULL) {
0678d0
+				fprintf(options.output, "\t%s", src);
0678d0
+				if (line > 0) {
0678d0
+					fprintf(options.output, ":%d", line);
0678d0
+					if (col > 0)
0678d0
+			                        fprintf(options.output,
0678d0
+							":%d", col);
0678d0
+				}
0678d0
+				fprintf(options.output, "\n");
0678d0
+			}
0678d0
+
0678d0
+		}
0678d0
+	}
0678d0
+
0678d0
+	/* Max number of frames to print reached? */
0678d0
+	if ((*frames)-- == 0)
0678d0
+		return 1;
0678d0
+
0678d0
+	return 0;
0678d0
+}
0678d0
+#endif /* defined(HAVE_LIBDW) */
0678d0
+
0678d0
 void
0678d0
 output_right(enum tof type, struct process *proc, struct library_symbol *libsym,
0678d0
 	     struct timedelta *spent)
0678d0
@@ -694,6 +762,24 @@
0678d0
 	}
0678d0
 #endif /* defined(HAVE_LIBUNWIND) */
0678d0
 
0678d0
+#if defined(HAVE_LIBDW)
0678d0
+	if (options.bt_depth > 0 && proc->leader->dwfl != NULL) {
0678d0
+		int frames = options.bt_depth;
0678d0
+		if (dwfl_getthread_frames(proc->leader->dwfl, proc->pid,
0678d0
+					  frame_callback, &frames) < 0) {
0678d0
+			// Only print an error if we couldn't show anything.
0678d0
+			// Otherwise just show there might be more...
0678d0
+			if (frames == options.bt_depth)
0678d0
+				fprintf(stderr,
0678d0
+					"dwfl_getthread_frames tid %d: %s\n",
0678d0
+					proc->pid, dwfl_errmsg(-1));
0678d0
+			else
0678d0
+				fprintf(options.output, " > [...]\n");
0678d0
+		}
0678d0
+		fprintf(options.output, "\n");
0678d0
+	  }
0678d0
+#endif /* defined(HAVE_LIBDW) */
0678d0
+
0678d0
 	current_proc = NULL;
0678d0
 	current_column = 0;
0678d0
 }
0678d0
diff -u ltrace-0.7.91/proc.c ltrace-0.7.91-pm/proc.c
0678d0
--- ltrace-0.7.91/proc.c	2015-01-09 00:38:17.981190650 +0100
0678d0
+++ ltrace-0.7.91-pm/proc.c	2015-01-09 00:37:40.261910548 +0100
0678d0
@@ -111,6 +111,11 @@
0678d0
 	if (proc->unwind_as != NULL)
0678d0
 		unw_destroy_addr_space(proc->unwind_as);
0678d0
 #endif /* defined(HAVE_LIBUNWIND) */
0678d0
+
0678d0
+#if defined(HAVE_LIBDW)
0678d0
+	if (proc->dwfl != NULL)
0678d0
+		dwfl_end(proc->dwfl);
0678d0
+#endif /* defined(HAVE_LIBDW) */
0678d0
 }
0678d0
 
0678d0
 static int
0678d0
@@ -172,6 +177,10 @@
0678d0
 	}
0678d0
 #endif /* defined(HAVE_LIBUNWIND) */
0678d0
 
0678d0
+#if defined(HAVE_LIBDW)
0678d0
+	proc->dwfl = NULL; /* Initialize for leader only on first library.  */
0678d0
+#endif /* defined(HAVE_LIBDW) */
0678d0
+
0678d0
 	return 0;
0678d0
 }
0678d0
 
0678d0
@@ -887,6 +896,59 @@
0678d0
 	debug(DEBUG_PROCESS, "added library %s@%p (%s) to %d",
0678d0
 	      lib->soname, lib->base, lib->pathname, proc->pid);
0678d0
 
0678d0
+#if defined(HAVE_LIBDW)
0678d0
+	if (options.bt_depth > 0) {
0678d0
+		/* Setup module tracking for libdwfl unwinding.  */
0678d0
+		struct process *leader = proc->leader;
0678d0
+		Dwfl *dwfl = leader->dwfl;
0678d0
+		if (dwfl == NULL) {
0678d0
+			static const Dwfl_Callbacks proc_callbacks = {
0678d0
+				.find_elf = dwfl_linux_proc_find_elf,
0678d0
+				.find_debuginfo = dwfl_standard_find_debuginfo
0678d0
+			};
0678d0
+			dwfl = dwfl_begin(&proc_callbacks);
0678d0
+			if (dwfl == NULL)
0678d0
+				fprintf(stderr,
0678d0
+					"Couldn't initialize libdwfl unwinding "
0678d0
+					"for process %d: %s\n", leader->pid,
0678d0
+					dwfl_errmsg (-1));
0678d0
+		}
0678d0
+
0678d0
+		if (dwfl != NULL) {
0678d0
+			dwfl_report_begin_add(dwfl);
0678d0
+			if (dwfl_report_elf(dwfl, lib->soname,
0678d0
+					    lib->pathname, -1,
0678d0
+					    (GElf_Addr) lib->base,
0678d0
+					    false) == NULL)
0678d0
+				fprintf(stderr,
0678d0
+					"dwfl_report_elf %s@%p (%s) %d: %s\n",
0678d0
+					lib->soname, lib->base, lib->pathname,
0678d0
+					proc->pid, dwfl_errmsg (-1));
0678d0
+			dwfl_report_end(dwfl, NULL, NULL);
0678d0
+
0678d0
+			if (leader->dwfl == NULL) {
0678d0
+				int r = dwfl_linux_proc_attach(dwfl,
0678d0
+							       leader->pid,
0678d0
+							       true);
0678d0
+				if (r == 0)
0678d0
+					leader->dwfl = dwfl;
0678d0
+				else {
0678d0
+					const char *msg;
0678d0
+					dwfl_end(dwfl);
0678d0
+					if (r < 0)
0678d0
+						msg = dwfl_errmsg(-1);
0678d0
+					else
0678d0
+						msg = strerror(r);
0678d0
+					fprintf(stderr, "Couldn't initialize "
0678d0
+						"libdwfl unwinding for "
0678d0
+						"process %d: %s\n",
0678d0
+						leader->pid, msg);
0678d0
+				}
0678d0
+			}
0678d0
+		}
0678d0
+	}
0678d0
+#endif /* defined(HAVE_LIBDW) */
0678d0
+
0678d0
 	/* Insert breakpoints for all active (non-latent) symbols.  */
0678d0
 	struct library_symbol *libsym = NULL;
0678d0
 	while ((libsym = library_each_symbol(lib, libsym,
0678d0
diff -u ltrace-0.7.91/proc.c.orig ltrace-0.7.91-pm/proc.c.orig
0678d0
--- ltrace-0.7.91/proc.h	2015-01-09 00:38:17.966190936 +0100
0678d0
+++ ltrace-0.7.91-pm/proc.h	2015-01-09 00:37:40.261910548 +0100
0678d0
@@ -28,6 +28,10 @@
0678d0
 #include <sys/time.h>
0678d0
 #include <stdint.h>
0678d0
 
0678d0
+#if defined(HAVE_LIBDW)
0678d0
+# include <elfutils/libdwfl.h>
0678d0
+#endif
0678d0
+
0678d0
 #if defined(HAVE_LIBUNWIND)
0678d0
 # include <libunwind.h>
0678d0
 #endif /* defined(HAVE_LIBUNWIND) */
0678d0
@@ -113,6 +117,11 @@
0678d0
 	short e_machine;
0678d0
 	char e_class;
0678d0
 
0678d0
+#if defined(HAVE_LIBDW)
0678d0
+	/* Unwind info for leader, NULL for non-leader procs. */
0678d0
+	Dwfl *dwfl;
0678d0
+#endif /* defined(HAVE_LIBDW) */
0678d0
+
0678d0
 #if defined(HAVE_LIBUNWIND)
0678d0
 	/* libunwind address space */
0678d0
 	unw_addr_space_t unwind_as;
0678d0
diff -up ltrace-0.7.91/proc.c\~ ltrace-0.7.91/proc.c
0678d0
--- ltrace-0.7.91/proc.c~	2015-01-09 01:55:38.289864078 +0100
0678d0
+++ ltrace-0.7.91/proc.c	2015-01-09 01:56:29.818881935 +0100
0678d0
@@ -918,7 +918,8 @@ proc_add_library(struct process *proc, s
0678d0
 			dwfl_report_begin_add(dwfl);
0678d0
 			if (dwfl_report_elf(dwfl, lib->soname,
0678d0
 					    lib->pathname, -1,
0678d0
-					    (GElf_Addr) lib->base,
0678d0
+					    /* XXX double cast */
0678d0
+					    (GElf_Addr) (uintptr_t) lib->base,
0678d0
 					    false) == NULL)
0678d0
 				fprintf(stderr,
0678d0
 					"dwfl_report_elf %s@%p (%s) %d: %s\n",
0678d0
diff -up a/configure b/configure
0678d0
--- a/configure	2018-04-06 19:48:06.543593689 -0400
0678d0
+++ b/configure	2018-04-06 19:47:52.039859482 -0400
0678d0
@@ -637,6 +637,7 @@ am__EXEEXT_TRUE
0678d0
 LTLIBOBJS
0678d0
 LIBOBJS
0678d0
 libunwind_LD_LIBRARY_PATH
0678d0
+elfutils_LD_LIBRARY_PATH
0678d0
 libelf_LD_LIBRARY_PATH
0678d0
 AM_LDFLAGS
0678d0
 AM_CFLAGS
0678d0
@@ -645,6 +646,7 @@ USE_VALGRIND_FALSE
0678d0
 USE_VALGRIND_TRUE
0678d0
 HAVE_VALGRIND
0678d0
 libunwind_LIBS
0678d0
+libdw_LIBS
0678d0
 libstdcxx_LIBS
0678d0
 libsupcxx_LIBS
0678d0
 liberty_LIBS
0678d0
@@ -780,6 +782,7 @@ enable_silent_rules
0678d0
 enable_maintainer_mode
0678d0
 enable_largefile
0678d0
 with_libelf
0678d0
+with_elfutils
0678d0
 with_libunwind
0678d0
 enable_debug
0678d0
 enable_werror
0678d0
@@ -1440,6 +1443,7 @@ Optional Packages:
0678d0
   --with-sysroot=DIR Search for dependent libraries within DIR
0678d0
                         (or the compiler's sysroot if not specified).
0678d0
   --with-libelf           Prefix of libelf headers/library
0678d0
+  --with-elfutils         Use elfutils libdwfl unwinding support
0678d0
   --with-libunwind        Use libunwind frame unwinding support
0678d0
 
0678d0
 Some influential environment variables:
0678d0
@@ -12115,6 +12119,108 @@ fi
0678d0
 
0678d0
 
0678d0
 
0678d0
+# Check whether --with-elfutils was given.
0678d0
+if test "${with_elfutils+set}" = set; then :
0678d0
+  withval=$with_elfutils; case "${withval}" in
0678d0
+  (yes|no) enable_elfutils=$withval;;
0678d0
+  (*) enable_elfutils=yes
0678d0
+    AM_CPPFLAGS="${AM_CPPFLAGS} -I${withval}/include"
0678d0
+    AM_LDFLAGS="${AM_LDFLAGS} -L${withval}/lib"
0678d0
+    elfutils_LD_LIBRARY_PATH="${withval}/lib:${withval}/lib/elfutils"
0678d0
+    ;;
0678d0
+esac
0678d0
+else
0678d0
+  enable_elfutils=maybe
0678d0
+fi
0678d0
+
0678d0
+
0678d0
+saved_CPPFLAGS="${CPPFLAGS}"
0678d0
+CPPFLAGS="${CPPFLAGS} ${AM_CPPFLAGS}"
0678d0
+for ac_header in elfutils/libdwfl.h
0678d0
+do :
0678d0
+  ac_fn_c_check_header_mongrel "$LINENO" "elfutils/libdwfl.h" "ac_cv_header_elfutils_libdwfl_h" "$ac_includes_default"
0678d0
+if test "x$ac_cv_header_elfutils_libdwfl_h" = xyes; then :
0678d0
+  cat >>confdefs.h <<_ACEOF
0678d0
+#define HAVE_ELFUTILS_LIBDWFL_H 1
0678d0
+_ACEOF
0678d0
+ have_libdwfl_h=yes
0678d0
+fi
0678d0
+
0678d0
+done
0678d0
+
0678d0
+CPPFLAGS="${saved_CPPFLAGS}"
0678d0
+
0678d0
+saved_LDFLAGS="${LDFLAGS}"
0678d0
+LDFLAGS="${LDFLAGS} ${AM_LDFLAGS}"
0678d0
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dwfl_getthread_frames in -ldw" >&5
0678d0
+$as_echo_n "checking for dwfl_getthread_frames in -ldw... " >&6; }
0678d0
+if ${ac_cv_lib_dw_dwfl_getthread_frames+:} false; then :
0678d0
+  $as_echo_n "(cached) " >&6
0678d0
+else
0678d0
+  ac_check_lib_save_LIBS=$LIBS
0678d0
+LIBS="-ldw  $LIBS"
0678d0
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
0678d0
+/* end confdefs.h.  */
0678d0
+
0678d0
+/* Override any GCC internal prototype to avoid an error.
0678d0
+   Use char because int might match the return type of a GCC
0678d0
+   builtin and then its argument prototype would still apply.  */
0678d0
+#ifdef __cplusplus
0678d0
+extern "C"
0678d0
+#endif
0678d0
+char dwfl_getthread_frames ();
0678d0
+int
0678d0
+main ()
0678d0
+{
0678d0
+return dwfl_getthread_frames ();
0678d0
+  ;
0678d0
+  return 0;
0678d0
+}
0678d0
+_ACEOF
0678d0
+if ac_fn_c_try_link "$LINENO"; then :
0678d0
+  ac_cv_lib_dw_dwfl_getthread_frames=yes
0678d0
+else
0678d0
+  ac_cv_lib_dw_dwfl_getthread_frames=no
0678d0
+fi
0678d0
+rm -f core conftest.err conftest.$ac_objext \
0678d0
+    conftest$ac_exeext conftest.$ac_ext
0678d0
+LIBS=$ac_check_lib_save_LIBS
0678d0
+fi
0678d0
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dw_dwfl_getthread_frames" >&5
0678d0
+$as_echo "$ac_cv_lib_dw_dwfl_getthread_frames" >&6; }
0678d0
+if test "x$ac_cv_lib_dw_dwfl_getthread_frames" = xyes; then :
0678d0
+  have_libdw_dwfl_frames=yes
0678d0
+fi
0678d0
+
0678d0
+LDFLAGS="${saved_LDFLAGS}"
0678d0
+
0678d0
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use elfutils libdwfl unwinding support" >&5
0678d0
+$as_echo_n "checking whether to use elfutils libdwfl unwinding support... " >&6; }
0678d0
+case "${enable_elfutils}" in
0678d0
+(yes|maybe)
0678d0
+  if test x$have_libdwfl_h = xyes -a x$have_libdw_dwfl_frames = xyes; then
0678d0
+    enable_elfutils=yes
0678d0
+  elif test $enable_elfutils = maybe; then
0678d0
+    enable_elfutils=no
0678d0
+  else
0678d0
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_elfutils" >&5
0678d0
+$as_echo "$enable_elfutils" >&6; }
0678d0
+    as_fn_error $? "Missing elfutils/libdwfl.h or dwfl_getthread_frames not in libdw.so" "$LINENO" 5
0678d0
+  fi
0678d0
+  ;;
0678d0
+(*) ;;
0678d0
+esac
0678d0
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_elfutils" >&5
0678d0
+$as_echo "$enable_elfutils" >&6; }
0678d0
+
0678d0
+if test x"$enable_elfutils" = xyes; then
0678d0
+  libdw_LIBS=-ldw
0678d0
+
0678d0
+
0678d0
+$as_echo "#define HAVE_LIBDW 1" >>confdefs.h
0678d0
+
0678d0
+fi
0678d0
+
0678d0
 # HAVE_LIBUNWIND
0678d0
 
0678d0
 # Check whether --with-libunwind was given.
0678d0
@@ -12329,6 +12435,15 @@ $as_echo "#define HAVE_LIBUNWIND 1" >>co
0678d0
   LDFLAGS="${saved_LDFLAGS}"
0678d0
 fi
0678d0
 
0678d0
+if test x"$enable_elfutils" = xyes -a x"$enable_libunwind" = xyes; then
0678d0
+  as_fn_error $? "Cannot enable both --with-libunwind and --with-elfutils" "$LINENO" 5
0678d0
+fi
0678d0
+
0678d0
+if test x"$enable_elfutils" = xyes -o x"$enable_libunwind" = xyes; then
0678d0
+
0678d0
+$as_echo "#define HAVE_UNWINDER 1" >>confdefs.h
0678d0
+
0678d0
+fi
0678d0
 
0678d0
 saved_CPPFLAGS="${CPPFLAGS}"
0678d0
 saved_LDFLAGS="${LDFLAGS}"
0678d0
diff a/config.h.in b/config.h.in
0678d0
--- a/config.h.in	2013-03-22 19:12:35.000000000 -0400
0678d0
+++ b/config.h.in	2018-04-06 21:49:42.000000000 -0400
0678d0
@@ -15,6 +15,9 @@
0678d0
 /* Define to 1 if you have the <dlfcn.h> header file. */
0678d0
 #undef HAVE_DLFCN_H
0678d0
 
0678d0
+/* Define to 1 if you have the <elfutils/libdwfl.h> header file. */
0678d0
+#undef HAVE_ELFUTILS_LIBDWFL_H
0678d0
+
0678d0
 /* we have read mmap support */
0678d0
 #undef HAVE_ELF_C_READ_MMAP
0678d0
 
0678d0
@@ -39,6 +42,9 @@
0678d0
 /* Define to 1 if you have the <inttypes.h> header file. */
0678d0
 #undef HAVE_INTTYPES_H
0678d0
 
0678d0
+/* we have elfutils libdw */
0678d0
+#undef HAVE_LIBDW
0678d0
+
0678d0
 /* Define to 1 if you have the `elf' library (-lelf). */
0678d0
 #undef HAVE_LIBELF
0678d0
 
0678d0
@@ -129,6 +135,9 @@
0678d0
 /* Define to 1 if you have the <unistd.h> header file. */
0678d0
 #undef HAVE_UNISTD_H
0678d0
 
0678d0
+/* we have an unwinder available */
0678d0
+#undef HAVE_UNWINDER
0678d0
+
0678d0
 /* Define to 1 if you have the `vfork' function. */
0678d0
 #undef HAVE_VFORK
0678d0
 
0678d0
@@ -175,6 +184,11 @@
0678d0
 /* Version number of package */
0678d0
 #undef VERSION
0678d0
 
0678d0
+/* Enable large inode numbers on Mac OS X 10.5.  */
0678d0
+#ifndef _DARWIN_USE_64_BIT_INODE
0678d0
+# define _DARWIN_USE_64_BIT_INODE 1
0678d0
+#endif
0678d0
+
0678d0
 /* Number of bits in a file offset, on hosts where this is settable. */
0678d0
 #undef _FILE_OFFSET_BITS
0678d0
 
0678d0
diff a/Makefile.in b/Makefile.in
0678d0
--- a/Makefile.in	2013-11-04 20:22:47.000000000 -0500
0678d0
+++ b/Makefile.in	2018-04-06 23:29:16.919673155 -0400
0678d0
@@ -297,6 +297,7 @@ includedir = @includedir@
0678d0
 infodir = @infodir@
0678d0
 install_sh = @install_sh@
0678d0
 libdir = @libdir@
0678d0
+libdw_LIBS = @libdw_LIBS@
0678d0
 libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@
0678d0
 liberty_LIBS = @liberty_LIBS@
0678d0
 libexecdir = @libexecdir@
0678d0
@@ -342,6 +343,7 @@ libltrace_la_LIBADD = \
0678d0
 	$(liberty_LIBS) \
0678d0
 	$(libsupcxx_LIBS) \
0678d0
 	$(libstdcxx_LIBS) \
0678d0
+	$(libdw_LIBS) \
0678d0
 	$(libunwind_LIBS) \
0678d0
 	sysdeps/libos.la
0678d0