[arch-commits] Commit in valgrind/trunk (3 files)

Allan McRae allan at archlinux.org
Sat May 29 10:23:19 UTC 2010


    Date: Saturday, May 29, 2010 @ 06:23:19
  Author: allan
Revision: 81358

upgpkg: valgrind 3.5.0-5
fix excess output with glibc-2.12 (FS#19634), move the sed to use our CFLAGS to a place that actually works...

Added:
  valgrind/trunk/valgrind-3.5.0-elf-indirect-functions.patch
Modified:
  valgrind/trunk/PKGBUILD
  valgrind/trunk/glibc-2.12.patch

---------------------------------------------+
 PKGBUILD                                    |   20 
 glibc-2.12.patch                            |   87 ----
 valgrind-3.5.0-elf-indirect-functions.patch |  528 ++++++++++++++++++++++++++
 3 files changed, 556 insertions(+), 79 deletions(-)

Modified: PKGBUILD
===================================================================
--- PKGBUILD	2010-05-29 09:05:55 UTC (rev 81357)
+++ PKGBUILD	2010-05-29 10:23:19 UTC (rev 81358)
@@ -4,7 +4,7 @@
 
 pkgname=valgrind
 pkgver=3.5.0
-pkgrel=4
+pkgrel=5
 pkgdesc="A tool to help find memory-management problems in programs"
 arch=('i686' 'x86_64')
 license=('GPL')
@@ -15,22 +15,26 @@
 source=(http://valgrind.org/downloads/${pkgname}-${pkgver}.tar.bz2
         glibc-patch-version.patch
         glibc-2.12.patch
-        valgrind-3.5.0-stat_h.patch)
+        valgrind-3.5.0-stat_h.patch
+        valgrind-3.5.0-elf-indirect-functions.patch)
 md5sums=('f03522a4687cf76c676c9494fcc0a517'
          'b657f0ebdde3d9aefc9fd16f9e653702'
-         'feb92ea98059b4e57239220e4b695f9d'
-         'e435a0debedf207b279256eff50c68f6')
+         '0ac843aecfc539a53ae88c48b1a17047'
+         'e435a0debedf207b279256eff50c68f6'
+         '10af3a098fa1f62441b7e52dbce38969')
 
 build() {
   cd ${srcdir}/${pkgname}-${pkgver}
+
+  # make sure our CFLAGS are respected
+  sed -i -e 's:^CFLAGS="-Wno-long-long":CFLAGS="$CFLAGS -Wno-long-long":' configure.in
+
   patch -Np1 -i ${srcdir}/glibc-patch-version.patch || return 1
-  patch -Np1 -i ${srcdir}/glibc-2.12.patch || return 1
+  patch -Np0 -i ${srcdir}/glibc-2.12.patch || return 1
   patch -Np1 -i ${srcdir}/valgrind-3.5.0-stat_h.patch || return 1
+  patch -Np0 -i ${srcdir}/valgrind-3.5.0-elf-indirect-functions.patch || return 1
   autoreconf
 
-  # make sure our CFLAGS are respected
-  sed -i -e 's:^CFLAGS="-Wno-long-long":CFLAGS="$CFLAGS -Wno-long-long":' configure.in
-
   if [ "${CARCH}" = "x86_64" ]; then
     ./configure --prefix=/usr --mandir=/usr/share/man --enable-only64bit || return 1
   else

Modified: glibc-2.12.patch
===================================================================
--- glibc-2.12.patch	2010-05-29 09:05:55 UTC (rev 81357)
+++ glibc-2.12.patch	2010-05-29 10:23:19 UTC (rev 81358)
@@ -1,72 +1,8 @@
-diff -Naur valgrind-3.5.0-old//config.h.in valgrind-3.5.0/config.h.in
---- valgrind-3.5.0-old//config.h.in	2009-08-19 23:39:05.000000000 +1000
-+++ valgrind-3.5.0/config.h.in	2010-05-22 19:55:31.065364428 +1000
-@@ -15,6 +15,9 @@
- /* Define to 1 if you're using glibc 2.10.x */
- #undef GLIBC_2_10
- 
-+/* Define to 1 if you're using glibc 2.12.x */
-+#undef GLIBC_2_12
-+
- /* Define to 1 if you're using glibc 2.2.x */
- #undef GLIBC_2_2
- 
-diff -Naur valgrind-3.5.0-old//configure valgrind-3.5.0/configure
---- valgrind-3.5.0-old//configure	2009-08-19 23:44:07.000000000 +1000
-+++ valgrind-3.5.0/configure	2010-05-22 20:01:04.822065382 +1000
-@@ -5025,6 +5025,29 @@
- cat >>conftest.$ac_ext <<_ACEOF
- /* end confdefs.h.  */
- 
-+#include <features.h>
-+#ifdef __GNU_LIBRARY__
-+ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ == 12)
-+  GLIBC_212
-+ #endif
-+#endif
-+
-+_ACEOF
-+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-+  $EGREP "GLIBC_212" >/dev/null 2>&1; then
-+  GLIBC_VERSION="2.12"
-+fi
-+rm -f conftest*
-+
-+
-+cat >conftest.$ac_ext <<_ACEOF
-+/* confdefs.h.  */
-+_ACEOF
-+cat confdefs.h >>conftest.$ac_ext
-+cat >>conftest.$ac_ext <<_ACEOF
-+/* end confdefs.h.  */
-+
-+
- #include <standards.h>
- #if defined(_AIXVERSION_510) || defined(_AIXVERSION_520) || defined(_AIXVERSION_530)
-   AIX5_LIBC
-@@ -5171,6 +5194,18 @@
- _ACEOF
- 
- 	DEFAULT_SUPP="glibc-2.X.supp ${DEFAULT_SUPP}"
-+	DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
-+	DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
-+	;;
-+     2.12)
-+     	echo "$as_me:$LINENO: result: 2.12 family" >&5
-+echo "${ECHO_T}2.12 family" >&6
-+
-+cat >>confdefs.h <<\_ACEOF
-+#define GLIBC_2_12 1
-+_ACEOF
-+
-+	DEFAULT_SUPP="glibc-2.X.supp ${DEFAULT_SUPP}"
- 	DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
- 	DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
- 	;;
-diff -Naur valgrind-3.5.0-old//configure.in valgrind-3.5.0/configure.in
---- valgrind-3.5.0-old//configure.in	2009-08-19 23:37:48.000000000 +1000
-+++ valgrind-3.5.0/configure.in	2010-05-22 19:54:43.788423252 +1000
-@@ -656,6 +656,16 @@
+Index: configure.in
+===================================================================
+--- configure.in	(revision 11128)
++++ configure.in	(revision 11129)
+@@ -684,6 +684,16 @@
  ],
  GLIBC_VERSION="2.10")
  
@@ -83,11 +19,11 @@
  AC_EGREP_CPP([AIX5_LIBC], [
  #include <standards.h>
  #if defined(_AIXVERSION_510) || defined(_AIXVERSION_520) || defined(_AIXVERSION_530)
-@@ -741,6 +751,13 @@
+@@ -776,6 +786,13 @@
  	DEFAULT_SUPP="glibc-2.X.supp ${DEFAULT_SUPP}"
  	DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
  	DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
-+	;;
++        ;;
 +     2.12)
 +	AC_MSG_RESULT(2.12 family)
 +	AC_DEFINE([GLIBC_2_12], 1, [Define to 1 if you're using glibc 2.12.x])
@@ -97,3 +33,12 @@
  	;;
       aix5)
  	AC_MSG_RESULT(AIX 5.1 or 5.2 or 5.3)
+@@ -790,7 +807,7 @@
+ 
+      *)
+ 	AC_MSG_RESULT(unsupported version)
+-	AC_MSG_ERROR([Valgrind requires glibc version 2.2 - 2.10])
++	AC_MSG_ERROR([Valgrind requires glibc version 2.2 - 2.12])
+ 	AC_MSG_ERROR([or AIX 5.1 or 5.2 or 5.3 GLIBC_VERSION])
+ 	AC_MSG_ERROR([or Darwin libc])
+ 	;;

Added: valgrind-3.5.0-elf-indirect-functions.patch
===================================================================
--- valgrind-3.5.0-elf-indirect-functions.patch	                        (rev 0)
+++ valgrind-3.5.0-elf-indirect-functions.patch	2010-05-29 10:23:19 UTC (rev 81358)
@@ -0,0 +1,528 @@
+Index: memcheck/mc_replace_strmem.c
+===================================================================
+--- memcheck/mc_replace_strmem.c	(revision 10919)
++++ memcheck/mc_replace_strmem.c	(revision 10920)
+@@ -116,6 +116,7 @@
+ STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
+ STRRCHR(VG_Z_LIBC_SONAME,   rindex)
+ #if defined(VGO_linux)
++STRRCHR(VG_Z_LIBC_SONAME,   __GI_strrchr)
+ STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
+ #elif defined(VGO_darwin)
+ STRRCHR(VG_Z_DYLD,          strrchr)
+@@ -140,6 +141,7 @@
+ STRCHR(VG_Z_LIBC_SONAME,          strchr)
+ STRCHR(VG_Z_LIBC_SONAME,          index)
+ #if defined(VGO_linux)
++STRCHR(VG_Z_LIBC_SONAME,          __GI_strchr)
+ STRCHR(VG_Z_LD_LINUX_SO_2,        strchr)
+ STRCHR(VG_Z_LD_LINUX_SO_2,        index)
+ STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
+@@ -172,8 +174,10 @@
+    }
+ 
+ STRCAT(VG_Z_LIBC_SONAME, strcat)
++#if defined(VGO_linux)
++STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
++#endif
+ 
+-
+ #define STRNCAT(soname, fnname) \
+    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+             ( char* dst, const char* src, SizeT n ); \
+@@ -257,6 +261,9 @@
+    }
+ 
+ STRNLEN(VG_Z_LIBC_SONAME, strnlen)
++#if defined(VGO_linux)
++STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
++#endif
+    
+ 
+ // Note that this replacement often doesn't get used because gcc inlines
+@@ -274,6 +281,7 @@
+ 
+ STRLEN(VG_Z_LIBC_SONAME,          strlen)
+ #if defined(VGO_linux)
++STRLEN(VG_Z_LIBC_SONAME,          __GI_strlen)
+ STRLEN(VG_Z_LD_LINUX_SO_2,        strlen)
+ STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
+ #endif
+@@ -301,7 +309,9 @@
+    }
+ 
+ STRCPY(VG_Z_LIBC_SONAME, strcpy)
+-#if defined(VGO_darwin)
++#if defined(VGO_linux)
++STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
++#elif defined(VGO_darwin)
+ STRCPY(VG_Z_DYLD,        strcpy)
+ #endif
+ 
+@@ -327,7 +337,9 @@
+    }
+ 
+ STRNCPY(VG_Z_LIBC_SONAME, strncpy)
+-#if defined(VGO_darwin)
++#if defined(VGO_linux)
++STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
++#elif defined(VGO_darwin)
+ STRNCPY(VG_Z_DYLD,        strncpy)
+ #endif
+ 
+@@ -384,7 +396,9 @@
+    }
+ 
+ STRNCMP(VG_Z_LIBC_SONAME, strncmp)
+-#if defined(VGO_darwin)
++#if defined(VGO_linux)
++STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
++#elif defined(VGO_darwin)
+ STRNCMP(VG_Z_DYLD,        strncmp)
+ #endif
+ 
+@@ -411,6 +425,7 @@
+ 
+ STRCMP(VG_Z_LIBC_SONAME,          strcmp)
+ #if defined(VGO_linux)
++STRCMP(VG_Z_LIBC_SONAME,          __GI_strcmp)
+ STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
+ STRCMP(VG_Z_LD64_SO_1,            strcmp)
+ #endif
+@@ -557,6 +572,7 @@
+ 
+ STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
+ #if defined(VGO_linux)
++STPCPY(VG_Z_LIBC_SONAME,          __GI_stpcpy)
+ STPCPY(VG_Z_LD_LINUX_SO_2,        stpcpy)
+ STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
+ #elif defined(VGO_darwin)
+@@ -709,8 +725,10 @@
+    }
+ 
+ GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
++#if defined (VGO_linux)
++GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
++#endif
+ 
+-
+ /* glibc variant of strcpy that checks the dest is big enough.
+    Copied from glibc-2.5/debug/test-strcpy_chk.c. */
+ #define GLIBC25___STRCPY_CHK(soname,fnname) \
+Index: include/pub_tool_debuginfo.h
+===================================================================
+--- include/pub_tool_debuginfo.h	(revision 10919)
++++ include/pub_tool_debuginfo.h	(revision 10920)
+@@ -212,7 +212,8 @@
+                                    /*OUT*/Addr*   tocptr,
+                                    /*OUT*/UInt*   size,
+                                    /*OUT*/HChar** name,
+-                                   /*OUT*/Bool*   isText );
++                                   /*OUT*/Bool*   isText,
++                                   /*OUT*/Bool*   isIFunc );
+ 
+ /* A simple enumeration to describe the 'kind' of various kinds of
+    segments that arise from the mapping of object files. */
+Index: coregrind/vg_preloaded.c
+===================================================================
+--- coregrind/vg_preloaded.c	(revision 10919)
++++ coregrind/vg_preloaded.c	(revision 10920)
+@@ -47,12 +47,12 @@
+ #include "pub_core_debuginfo.h"  // Needed for pub_core_redir.h
+ #include "pub_core_redir.h"      // For VG_NOTIFY_ON_LOAD
+ 
++#if defined(VGO_linux) || defined(VGO_aix5)
++
+ /* ---------------------------------------------------------------------
+    Hook for running __libc_freeres once the program exits.
+    ------------------------------------------------------------------ */
+ 
+-#if defined(VGO_linux) || defined(VGO_aix5)
+-
+ void VG_NOTIFY_ON_LOAD(freeres)( void );
+ void VG_NOTIFY_ON_LOAD(freeres)( void )
+ {
+@@ -68,6 +68,31 @@
+    *(int *)0 = 'x';
+ }
+ 
++/* ---------------------------------------------------------------------
++   Wrapper for indirect functions which need to be redirected.
++   ------------------------------------------------------------------ */
++
++void * VG_NOTIFY_ON_LOAD(ifunc_wrapper) (void);
++void * VG_NOTIFY_ON_LOAD(ifunc_wrapper) (void)
++{
++    OrigFn fn;
++    Addr result = 0;
++    int res;
++
++    /* Call the original indirect function and get it's result */
++    VALGRIND_GET_ORIG_FN(fn);
++    CALL_FN_W_v(result, fn);
++
++    /* Ask the valgrind core running on the real CPU (as opposed to this
++       code which runs on the emulated CPU) to update the redirection that
++       led to this function. This client request eventually gives control to
++       the function VG_(redir_add_ifunc_target) in m_redir.c  */
++    VALGRIND_DO_CLIENT_REQUEST(res, 0,
++                               VG_USERREQ__ADD_IFUNC_TARGET,
++                               fn.nraddr, result, 0, 0, 0);
++    return result;
++}
++
+ #elif defined(VGO_darwin)
+ 
+ /* ---------------------------------------------------------------------
+Index: coregrind/pub_core_clreq.h
+===================================================================
+--- coregrind/pub_core_clreq.h	(revision 10919)
++++ coregrind/pub_core_clreq.h	(revision 10920)
+@@ -50,6 +50,9 @@
+       /* Internal equivalent of VALGRIND_PRINTF . */
+       VG_USERREQ__INTERNAL_PRINTF   = 0x3103,
+ 
++      /* Add a target for an indirect function redirection. */
++      VG_USERREQ__ADD_IFUNC_TARGET  = 0x3104,
++
+    } Vg_InternalClientRequest;
+ 
+ // Function for printing from code within Valgrind, but which runs on the
+Index: coregrind/m_debuginfo/debuginfo.c
+===================================================================
+--- coregrind/m_debuginfo/debuginfo.c	(revision 10919)
++++ coregrind/m_debuginfo/debuginfo.c	(revision 10920)
+@@ -3435,14 +3435,16 @@
+                                   /*OUT*/Addr*   tocptr,
+                                   /*OUT*/UInt*   size,
+                                   /*OUT*/HChar** name,
+-                                  /*OUT*/Bool*   isText )
++                                  /*OUT*/Bool*   isText,
++                                  /*OUT*/Bool*   isIFunc )
+ {
+    vg_assert(idx >= 0 && idx < si->symtab_used);
+-   if (avma)   *avma   = si->symtab[idx].addr;
+-   if (tocptr) *tocptr = si->symtab[idx].tocptr;
+-   if (size)   *size   = si->symtab[idx].size;
+-   if (name)   *name   = (HChar*)si->symtab[idx].name;
+-   if (isText) *isText = si->symtab[idx].isText;
++   if (avma)    *avma    = si->symtab[idx].addr;
++   if (tocptr)  *tocptr  = si->symtab[idx].tocptr;
++   if (size)    *size    = si->symtab[idx].size;
++   if (name)    *name    = (HChar*)si->symtab[idx].name;
++   if (isText)  *isText  = si->symtab[idx].isText;
++   if (isIFunc) *isIFunc = si->symtab[idx].isIFunc;
+ }
+ 
+ 
+Index: coregrind/m_debuginfo/readelf.c
+===================================================================
+--- coregrind/m_debuginfo/readelf.c	(revision 10919)
++++ coregrind/m_debuginfo/readelf.c	(revision 10920)
+@@ -214,7 +214,8 @@
+                                   used on entry */
+         Bool*  from_opd_out,   /* ppc64-linux only: did we deref an
+                                   .opd entry? */
+-        Bool*  is_text_out     /* is this a text symbol? */
++        Bool*  is_text_out,    /* is this a text symbol? */
++        Bool*  is_ifunc        /* is this a  STT_GNU_IFUNC function ?*/
+      )
+ {
+    Bool plausible;
+@@ -232,6 +233,7 @@
+    *sym_size_out   = (Int)sym->st_size;
+    *sym_tocptr_out = 0; /* unknown/inapplicable */
+    *from_opd_out   = False;
++   *is_ifunc       = False;
+ 
+    /* Figure out if we're interested in the symbol.  Firstly, is it of
+       the right flavour?  */
+@@ -243,6 +245,9 @@
+         &&
+         (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC 
+          || ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT
++#ifdef STT_GNU_IFUNC
++         || ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC
++#endif
+         );
+ 
+    /* Work out the svma and bias for each section as it will appear in
+@@ -325,6 +330,14 @@
+       *sym_avma_out += text_bias;
+    }
+ 
++#  ifdef STT_GNU_IFUNC
++   /* Check for indirect functions. */
++   if (*is_text_out
++       && ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC) {
++       *is_ifunc = True;
++   }
++#  endif
++
+ #  if defined(VGP_ppc64_linux)
+    /* Allow STT_NOTYPE in the very special case where we're running on
+       ppc64-linux and the symbol is one which the .opd-chasing hack
+@@ -570,7 +583,7 @@
+    Char      *sym_name, *sym_name_really;
+    Int        sym_size;
+    Addr       sym_tocptr;
+-   Bool       from_opd, is_text;
++   Bool       from_opd, is_text, is_ifunc;
+    DiSym      risym;
+    ElfXX_Sym *sym;
+ 
+@@ -602,13 +615,14 @@
+                               &sym_avma_really,
+                               &sym_size,
+                               &sym_tocptr,
+-                              &from_opd, &is_text)) {
++                              &from_opd, &is_text, &is_ifunc)) {
+ 
+-         risym.addr   = sym_avma_really;
+-         risym.size   = sym_size;
+-         risym.name   = ML_(addStr) ( di, sym_name_really, -1 );
+-         risym.tocptr = sym_tocptr;
+-         risym.isText = is_text;
++         risym.addr    = sym_avma_really;
++         risym.size    = sym_size;
++         risym.name    = ML_(addStr) ( di, sym_name_really, -1 );
++         risym.tocptr  = sym_tocptr;
++         risym.isText  = is_text;
++         risym.isIFunc = is_ifunc;
+          vg_assert(risym.name != NULL);
+          vg_assert(risym.tocptr == 0); /* has no role except on ppc64-linux */
+          ML_(addSym) ( di, &risym );
+@@ -646,6 +660,7 @@
+       Int        size;
+       Bool       from_opd;
+       Bool       is_text;
++      Bool       is_ifunc;
+    }
+    TempSym;
+ 
+@@ -671,7 +686,7 @@
+    Char       *sym_name, *sym_name_really;
+    Int         sym_size;
+    Addr        sym_tocptr;
+-   Bool        from_opd, modify_size, modify_tocptr, is_text;
++   Bool        from_opd, modify_size, modify_tocptr, is_text, is_ifunc;
+    DiSym       risym;
+    ElfXX_Sym  *sym;
+    OSet       *oset;
+@@ -713,7 +728,7 @@
+                               &sym_avma_really,
+                               &sym_size,
+                               &sym_tocptr,
+-                              &from_opd, &is_text)) {
++                              &from_opd, &is_text, &is_ifunc)) {
+ 
+          /* Check if we've seen this (name,addr) key before. */
+          key.addr = sym_avma_really;
+@@ -785,6 +800,7 @@
+             elem->size     = sym_size;
+             elem->from_opd = from_opd;
+             elem->is_text  = is_text;
++            elem->is_ifunc = is_ifunc;
+             VG_(OSetGen_Insert)(oset, elem);
+             if (di->trace_symtab) {
+                VG_(printf)("   to-oset [%4ld]:          "
+@@ -808,11 +824,12 @@
+    VG_(OSetGen_ResetIter)( oset );
+ 
+    while ( (elem = VG_(OSetGen_Next)(oset)) ) {
+-      risym.addr   = elem->key.addr;
+-      risym.size   = elem->size;
+-      risym.name   = ML_(addStr) ( di, elem->key.name, -1 );
+-      risym.tocptr = elem->tocptr;
+-      risym.isText = elem->is_text;
++      risym.addr    = elem->key.addr;
++      risym.size    = elem->size;
++      risym.name    = ML_(addStr) ( di, elem->key.name, -1 );
++      risym.tocptr  = elem->tocptr;
++      risym.isText  = elem->is_text;
++      risym.isIFunc = elem->is_ifunc;
+       vg_assert(risym.name != NULL);
+ 
+       ML_(addSym) ( di, &risym );
+Index: coregrind/m_debuginfo/priv_storage.h
+===================================================================
+--- coregrind/m_debuginfo/priv_storage.h	(revision 10919)
++++ coregrind/m_debuginfo/priv_storage.h	(revision 10920)
+@@ -48,15 +48,16 @@
+ /* A structure to hold an ELF/XCOFF symbol (very crudely). */
+ typedef 
+    struct { 
+-      Addr  addr;   /* lowest address of entity */
+-      Addr  tocptr; /* ppc64-linux only: value that R2 should have */
+-      UChar *name;  /* name */
++      Addr  addr;    /* lowest address of entity */
++      Addr  tocptr;  /* ppc64-linux only: value that R2 should have */
++      UChar *name;   /* name */
+       // XXX: this could be shrunk (on 32-bit platforms) by using 31 bits for
+       // the size and 1 bit for the isText.  If you do this, make sure that
+       // all assignments to isText use 0 or 1 (or True or False), and that a
+       // positive number larger than 1 is never used to represent True.
+-      UInt  size;   /* size in bytes */
++      UInt  size;    /* size in bytes */
+       Bool  isText;
++      Bool  isIFunc; /* symbol is an indirect function? */
+    }
+    DiSym;
+ 
+Index: coregrind/m_redir.c
+===================================================================
+--- coregrind/m_redir.c	(revision 10919)
++++ coregrind/m_redir.c	(revision 10920)
+@@ -268,12 +268,15 @@
+       TopSpec* parent_spec; /* the TopSpec which supplied the Spec */
+       TopSpec* parent_sym;  /* the TopSpec which supplied the symbol */
+       Bool     isWrap;      /* wrap or replacement? */
++      Bool     isIFunc;     /* indirect function? */
+    }
+    Active;
+ 
+ /* The active set is a fast lookup table */
+ static OSet* activeSet = NULL;
+ 
++/* Wrapper routine for indirect functions */
++static Addr iFuncWrapper;
+ 
+ /*------------------------------------------------------------*/
+ /*--- FWDses                                               ---*/
+@@ -350,8 +353,8 @@
+ 
+    nsyms = VG_(DebugInfo_syms_howmany)( newsi );
+    for (i = 0; i < nsyms; i++) {
+-      VG_(DebugInfo_syms_getidx)( newsi, i, &sym_addr, &sym_toc, 
+-                                            NULL, &sym_name, &isText );
++      VG_(DebugInfo_syms_getidx)( newsi, i, &sym_addr, &sym_toc,
++                                  NULL, &sym_name, &isText, NULL );
+       ok = VG_(maybe_Z_demangle)( sym_name, demangled_sopatt, N_DEMANGLED,
+                                   demangled_fnpatt, N_DEMANGLED, &isWrap );
+       /* ignore data symbols */
+@@ -388,8 +391,8 @@
+ 
+    if (check_ppcTOCs) {
+       for (i = 0; i < nsyms; i++) {
+-         VG_(DebugInfo_syms_getidx)( newsi, i, &sym_addr, &sym_toc, 
+-                                               NULL, &sym_name, &isText );
++         VG_(DebugInfo_syms_getidx)( newsi, i, &sym_addr, &sym_toc,
++                                     NULL, &sym_name, &isText, NULL );
+          ok = isText
+               && VG_(maybe_Z_demangle)( 
+                     sym_name, demangled_sopatt, N_DEMANGLED,
+@@ -470,7 +473,31 @@
+ 
+ #undef N_DEMANGLED
+ 
++/* Add a new target for an indirect function. Adds a new redirection
++   for the indirection function with address old_from that redirects
++   the ordinary function with address new_from to the target address
++   of the original redirection. */
+ 
++void VG_(redir_add_ifunc_target)( Addr old_from, Addr new_from )
++{
++    Active *old, new;
++
++    old = VG_(OSetGen_Lookup)(activeSet, &old_from);
++    vg_assert(old);
++    vg_assert(old->isIFunc);
++
++    new = *old;
++    new.from_addr = new_from;
++    new.isIFunc = False;
++    maybe_add_active (new);
++
++    if (VG_(clo_trace_redir)) {
++       VG_(message)( Vg_DebugMsg,
++                     "Adding redirect for indirect function 0x%llx from 0x%llx -> 0x%llx\n",
++                     (ULong)old_from, (ULong)new_from, (ULong)new.to_addr );
++    }
++}
++
+ /* Do one element of the basic cross product: add to the active set,
+    all matches resulting from comparing all the given specs against
+    all the symbols in the given seginfo.  If a conflicting binding
+@@ -487,7 +514,7 @@
+      )
+ {
+    Spec*  sp;
+-   Bool   anyMark, isText;
++   Bool   anyMark, isText, isIFunc;
+    Active act;
+    Int    nsyms, i;
+    Addr   sym_addr;
+@@ -513,7 +540,7 @@
+    nsyms = VG_(DebugInfo_syms_howmany)( di );
+    for (i = 0; i < nsyms; i++) {
+       VG_(DebugInfo_syms_getidx)( di, i, &sym_addr, NULL, NULL,
+-                                         &sym_name, &isText );
++                                  &sym_name, &isText, &isIFunc );
+ 
+       /* ignore data symbols */
+       if (!isText)
+@@ -539,6 +566,7 @@
+             act.parent_spec = parent_spec;
+             act.parent_sym  = parent_sym;
+             act.isWrap      = sp->isWrap;
++            act.isIFunc     = isIFunc;
+             sp->done = True;
+             maybe_add_active( act );
+          }
+@@ -780,7 +808,9 @@
+ 
+    vg_assert(r->to_addr != 0);
+    if (isWrap)
+-      *isWrap = r->isWrap;
++      *isWrap = r->isWrap || r->isIFunc;
++   if (r->isIFunc)
++      return iFuncWrapper;
+    return r->to_addr;
+ }
+ 
+@@ -1096,6 +1126,8 @@
+ 
+    if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(freeres))) == 0)
+       VG_(client___libc_freeres_wrapper) = addr;
++   else if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(ifunc_wrapper))) == 0)
++      iFuncWrapper = addr;
+    else
+       vg_assert2(0, "unrecognised load notification function: %s", symbol);
+ }
+Index: coregrind/pub_core_redir.h
+===================================================================
+--- coregrind/pub_core_redir.h	(revision 10919)
++++ coregrind/pub_core_redir.h	(revision 10920)
+@@ -58,6 +58,8 @@
+ /* Initialise the module, and load initial "hardwired" redirects. */
+ extern void VG_(redir_initialise)( void );
+ 
++/* Notify the module of a new target for an indirect function. */
++extern void VG_(redir_add_ifunc_target)( Addr old_from, Addr new_from );
+ 
+ //--------------------------------------------------------------------
+ // Queries
+Index: coregrind/m_scheduler/scheduler.c
+===================================================================
+--- coregrind/m_scheduler/scheduler.c	(revision 10919)
++++ coregrind/m_scheduler/scheduler.c	(revision 10920)
+@@ -89,6 +89,7 @@
+ #include "pub_core_debuginfo.h"     // VG_(di_notify_pdb_debuginfo)
+ #include "priv_sema.h"
+ #include "pub_core_scheduler.h"     // self
++#include "pub_core_redir.h"
+ 
+ 
+ /* ---------------------------------------------------------------------
+@@ -1399,6 +1400,11 @@
+             SET_CLREQ_RETVAL( tid, count );
+          break; }
+ 
++      case VG_USERREQ__ADD_IFUNC_TARGET: {
++         VG_(redir_add_ifunc_target)( arg[1], arg[2] );
++         SET_CLREQ_RETVAL( tid, 0);
++         break; }
++
+       case VG_USERREQ__PRINTF_BACKTRACE: {
+          Int count =
+             VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], (void*)arg[2] );




More information about the arch-commits mailing list