rts: unrust 'libbfd' debug symbols parser
authorSergei Trofimovich <slyfox@gentoo.org>
Sun, 5 Oct 2014 20:20:39 +0000 (21:20 +0100)
committerSergei Trofimovich <slyfox@gentoo.org>
Sun, 5 Oct 2014 21:10:08 +0000 (22:10 +0100)
Summary:
Patch does the following:
- fixes detection of working libbfd on modern linux
  platforms (where bfd_uncompress_section_contents is a macro)
- disables 'bfd' by default and adds '--enable-bfd-debug'
  configure option. As bfd's ABI is unstable
  the feature is primarily useful by ghc hackers.

Not done (subject for another patch):
- one-time bfd object memory leak in DEBUG_LoadSymbols
- in '-dynamic' mode debugging symbols are loaded only for
  current executable, not all libraries it is linked against.

Fixes Issue #8790

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
Test Plan: built unregisterised ghc on amd64 and ran './hello +RTS -Di' there

Reviewers: simonmar, austin

Reviewed By: simonmar, austin

Subscribers: thomie, simonmar, ezyang, carter

Differential Revision: https://phabricator.haskell.org/D193

GHC Trac Issues: #8790

aclocal.m4
configure.ac
rts/Printer.c
rts/RtsStartup.c

index a98691e..0db231d 100644 (file)
@@ -2215,4 +2215,53 @@ $2=$HS_CPP_ARGS
 
 ])
 
+# FP_BFD_SUPPORT()
+# ----------------------
+# whether to use libbfd for debugging RTS
+AC_DEFUN([FP_BFD_SUPPORT], [
+    AC_ARG_ENABLE(bfd-debug,
+        [AC_HELP_STRING([--enable-bfd-debug],
+              [Enable symbol resolution for -debug rts ('+RTS -Di') via binutils' libbfd [default=no]])],
+        [
+            # don't pollute general LIBS environment
+            save_LIBS="$LIBS"
+            AC_CHECK_HEADERS([bfd.h])
+            dnl ** check whether this machine has BFD and libiberty installed (used for debugging)
+            dnl    the order of these tests matters: bfd needs libiberty
+            AC_CHECK_LIB(iberty, xmalloc)
+            dnl 'bfd_init' is a rare non-macro in libbfd
+            AC_CHECK_LIB(bfd,    bfd_init)
+
+            AC_TRY_LINK([#include <bfd.h>],
+                        [
+                                /* mimic our rts/Printer.c */
+                                bfd* abfd;
+                                const char * name;
+                                char **matching;
+
+                                name = "some.executable";
+                                bfd_init();
+                                abfd = bfd_openr(name, "default");
+                                bfd_check_format_matches (abfd, bfd_object, &matching);
+                                {
+                                    long storage_needed;
+                                    storage_needed = bfd_get_symtab_upper_bound (abfd);
+                                }
+                                {
+                                    asymbol **symbol_table;
+                                    long number_of_symbols;
+                                    symbol_info info;
+
+                                    number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
+                                    bfd_get_symbol_info(abfd,symbol_table[0],&info);
+                                }
+                        ],
+                        [],dnl bfd seems to work
+                        [AC_MSG_ERROR([can't use 'bfd' library])])
+            LIBS="$save_LIBS"
+        ],
+        []
+    )
+])
+
 # LocalWords:  fi
index e7a0774..7b59f78 100644 (file)
@@ -753,7 +753,7 @@ dnl    off_t, because it will affect the result of that test.
 AC_SYS_LARGEFILE
 
 dnl ** check for specific header (.h) files that we are interested in
-AC_CHECK_HEADERS([bfd.h ctype.h dirent.h dlfcn.h errno.h fcntl.h grp.h limits.h locale.h nlist.h pthread.h pwd.h signal.h sys/param.h sys/mman.h sys/resource.h sys/select.h sys/time.h sys/timeb.h sys/timers.h sys/times.h sys/utsname.h sys/wait.h termios.h time.h utime.h windows.h winsock.h sched.h])
+AC_CHECK_HEADERS([ctype.h dirent.h dlfcn.h errno.h fcntl.h grp.h limits.h locale.h nlist.h pthread.h pwd.h signal.h sys/param.h sys/mman.h sys/resource.h sys/select.h sys/time.h sys/timeb.h sys/timers.h sys/times.h sys/utsname.h sys/wait.h termios.h time.h utime.h windows.h winsock.h sched.h])
 
 dnl sys/cpuset.h needs sys/param.h to be included first on FreeBSD 9.1; #7708
 AC_CHECK_HEADERS([sys/cpuset.h], [], [],
@@ -846,10 +846,7 @@ then
   AC_DEFINE([HAVE_LIBM], [1], [Define to 1 if you need to link with libm])
 fi
 
-dnl ** check whether this machine has BFD and libiberty installed (used for debugging)
-dnl    the order of these tests matters: bfd needs libiberty
-AC_CHECK_LIB(iberty, xmalloc)
-AC_CHECK_LIB(bfd,    bfd_uncompress_section_contents)
+FP_BFD_SUPPORT
 
 dnl ################################################################
 dnl Check for libraries
index 3d77e83..9bc2984 100644 (file)
@@ -7,6 +7,8 @@
  * ---------------------------------------------------------------------------*/
 
 #include "PosixSource.h"
+#include "ghcconfig.h"
+
 #include "Rts.h"
 #include "rts/Bytecodes.h"  /* for InstrPtr */
 
@@ -664,8 +666,16 @@ const char *lookupGHCName( void *addr )
    disabling this for now.
 */
 #ifdef USING_LIBBFD
-
-#include <bfd.h>
+#    define PACKAGE 1
+#    define PACKAGE_VERSION 1
+/* Those PACKAGE_* defines are workarounds for bfd:
+ *     https://sourceware.org/bugzilla/show_bug.cgi?id=14243
+ * ghc's build system filter PACKAGE_* values out specifically to avoid clashes
+ * with user's autoconf-based Cabal packages.
+ * It's a shame <bfd.h> checks for unrelated fields instead of actually used
+ * macros.
+ */
+#    include <bfd.h>
 
 /* Fairly ad-hoc piece of code that seems to filter out a lot of
  * rubbish like the obj-splitting symbols
@@ -733,7 +743,6 @@ extern void DEBUG_LoadSymbols( char *name )
         for( i = 0; i != number_of_symbols; ++i ) {
             symbol_info info;
             bfd_get_symbol_info(abfd,symbol_table[i],&info);
-            /*debugBelch("\t%c\t0x%x      \t%s\n",info.type,(nat)info.value,info.name); */
             if (isReal(info.type, info.name)) {
                 num_real_syms += 1;
             }
index 98a43c0..5e6f9fa 100644 (file)
@@ -19,6 +19,7 @@
 #include "RtsFlags.h"
 #include "RtsUtils.h"
 #include "Prelude.h"
+#include "Printer.h"    /* DEBUG_LoadSymbols */
 #include "Schedule.h"   /* initScheduler */
 #include "Stats.h"      /* initStats */
 #include "STM.h"        /* initSTM */
@@ -162,6 +163,11 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config)
                       rts_config.rts_opts_enabled, rts_config.rts_opts, rts_config.rts_hs_main);
     }
 
+#ifdef DEBUG
+    /* load debugging symbols for current binary */
+    DEBUG_LoadSymbols((*argv)[0]);
+#endif /* DEBUG */
+
     /* Initialise the stats department, phase 1 */
     initStats1();