[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