|
From: <sv...@va...> - 2005-04-02 17:39:05
|
Author: sewardj
Date: 2005-04-02 18:38:59 +0100 (Sat, 02 Apr 2005)
New Revision: 3510
Added:
trunk/coregrind/vg_replace_malloc.c
Removed:
trunk/coregrind/gen_intercepts.pl
trunk/coregrind/vg_replace_malloc.c.base
Modified:
trunk/coregrind/Makefile.am
trunk/coregrind/core.h
trunk/coregrind/vg_symtab2.c
Log:
A major overhaul of how malloc/free intercepts are done. The general
idea is the same -- write functions with special names encoding
sonames and fn names, and have the redir mechanism notice them.
However the way the functions are generated is significantly changed:
* The name mangling scheme has been replaced with one which is just about
simple enough not to need a preprocessing phase. Hence
vg_replace_malloc.c.base is replaced by vg_replace_malloc.c, and
the preprocessor disappears. The demangler in vg_symtab2.c changes
accordingly.
* Kill off the horrendous LIBALIAS macro. In return we have to
enumerate all the redirections longhand, but this is not a big deal.
* Remove use of the GNUisms "attribute alias" and "attribute
protected".
* Remove the hardwired assumption that any C++ new/new[]/etc symbols
we might want to intercept are mangled in GNU style.
* Add more comments.
Modified: trunk/coregrind/Makefile.am
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/Makefile.am 2005-04-02 17:30:19 UTC (rev 3509)
+++ trunk/coregrind/Makefile.am 2005-04-02 17:38:59 UTC (rev 3510)
@@ -37,10 +37,10 @@
EXTRA_DIST =3D \
valgrind.vs \
gen_toolint.pl toolfuncs.def \
- gen_intercepts.pl vg_replace_malloc.c.base
+ gen_intercepts.pl
=20
BUILT_SOURCES =3D vg_toolint.c vg_toolint.h
-CLEANFILES =3D vg_toolint.c vg_toolint.h vg_replace_malloc.c
+CLEANFILES =3D vg_toolint.c vg_toolint.h
=20
valgrind_SOURCES =3D \
ume.c \
@@ -61,6 +61,7 @@
vg_demangle.c \
vg_errcontext.c \
vg_hashtable.c \
+ vg_replace_malloc.c \
vg_main.c \
vg_malloc2.c \
vg_memory.c \
@@ -114,10 +115,6 @@
stage2_LDADD=3D $(stage2_extra) -ldl
=20
=20
-vg_replace_malloc.c: $(srcdir)/gen_intercepts.pl $(srcdir)/vg_replace_ma=
lloc.c.base
- rm -f $@
- $(PERL) $(srcdir)/gen_intercepts.pl < $(srcdir)/vg_replace_malloc.c.bas=
e > $@
-
vg_toolint.c: $(srcdir)/gen_toolint.pl $(srcdir)/toolfuncs.def ./Makefil=
e
rm -f $@
$(PERL) $(srcdir)/gen_toolint.pl callwrap < $(srcdir)/toolfuncs.def=
> $@ || rm -f $@
Modified: trunk/coregrind/core.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/core.h 2005-04-02 17:30:19 UTC (rev 3509)
+++ trunk/coregrind/core.h 2005-04-02 17:38:59 UTC (rev 3510)
@@ -468,15 +468,18 @@
A synonym for exit. */
#define VG_USERREQ__LIBC_FREERES_DONE 0x3029
=20
-#define VG_INTERCEPT_PREFIX "_vgi__"
-#define VG_INTERCEPT_PREFIX_LEN 6
-#define VG_INTERCEPT(name) _vgi__##name
-#define VG_INTERCEPT_ALIAS(name) "_vgi__" #name
+/* Intercept prefix stuff. See coregrind/vg_replace_malloc.c for
+ details. Unfortunately the "_vgi_" literal is also hardcoded in
+ that file, so if you change this one you must also change the other
+ one. */
+#define VG_INTERCEPT_PREFIX "_vgi_"
+#define VG_INTERCEPT_PREFIX_LEN 5
=20
-#define VG_WRAPPER_PREFIX "_vgw__"
-#define VG_WRAPPER_PREFIX_LEN 6
-#define VG_WRAPPER(name) _vgw__##name
-#define VG_WRAPPER_ALIAS(name) "_vgw__" #name
+/* Not sure what these are for. Todo: clarify */
+#define VG_WRAPPER_PREFIX "_vgw_"
+#define VG_WRAPPER_PREFIX_LEN 5
+#define VG_WRAPPER(name) _vgw_##name
+#define VG_WRAPPER_ALIAS(name) "_vgw_" #name
=20
=20
struct vg_mallocfunc_info {
Deleted: trunk/coregrind/gen_intercepts.pl
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/gen_intercepts.pl 2005-04-02 17:30:19 UTC (rev 3509)
+++ trunk/coregrind/gen_intercepts.pl 2005-04-02 17:38:59 UTC (rev 3510)
@@ -1,49 +0,0 @@
-#!/usr/bin/perl -w
-
-# This file is part of Valgrind, a dynamic binary instrumentation
-# framework.
-#
-# Copyright (C) 2000-2005 Julian Seward=20
-# js...@ac...
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-# 02111-1307, USA.
-#
-# The GNU General Public License is contained in the file COPYING.
-
-use strict;
-
-while(<>) {
- if(/VG_INTERCEPT\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/) {
- my $ver =3D $1 . ":" . $2;
- ($ver =3D~ /J/) and die "Argh, 'J' in intercept muck...";
- $ver =3D~ s/\*/J2A/g;
- $ver =3D~ s/\+/J2B/g;
- $ver =3D~ s/\-/J2D/g;
- $ver =3D~ s/\./J2E/g;
- $ver =3D~ s/\:/J3A/g;
- s/VG_INTERCEPT\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/VG_INTERCEPT($ver)/g;
- } elsif(/VG_INTERCEPT_ALIAS\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/) {
- my $ver =3D $1 . ":" . $2;
- ($ver =3D~ /J/) and die "Argh, 'J' in intercept muck...";
- $ver =3D~ s/\*/J2A/g;
- $ver =3D~ s/\+/J2B/g;
- $ver =3D~ s/\-/J2D/g;
- $ver =3D~ s/\./J2E/g;
- $ver =3D~ s/\:/J3A/g;
- s/VG_INTERCEPT_ALIAS\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/VG_INTERCEPT_ALIA=
S($ver)/g;
- }
- print $_;
-}
Added: trunk/coregrind/vg_replace_malloc.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/vg_replace_malloc.c 2005-04-02 17:30:19 UTC (rev 3509=
)
+++ trunk/coregrind/vg_replace_malloc.c 2005-04-02 17:38:59 UTC (rev 3510=
)
@@ -0,0 +1,525 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Replacements for malloc() et al, which run on the simulated ---*/
+/*--- CPU. vg_replace_malloc.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2005 Julian Seward=20
+ js...@ac...
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+/* ---------------------------------------------------------------------
+ All the code in this file runs on the SIMULATED CPU. It is intended
+ for various reasons as drop-in replacements for malloc() and friends.
+ These functions have global scope, but are not intended to be called
+ directly. See the comments in coregrind/vg_intercept.c for the
+ gory details.
+
+ This file can be linked into the injected so file for any tool that
+ wishes to know about calls to malloc(). It should define functions
+ TL_(malloc) et al that will be called.
+ ------------------------------------------------------------------ */
+
+#include "valgrind.h" /* for VALGRIND_NON_SIMD_CALL[12] */
+#include "core.h"
+
+/* The general idea is: you can write a function like this:
+
+ retty ENCODE(foo, bar) ( ... args ... )
+ {
+ ... body ...
+ }
+
+ If foo is a Z-encoded soname and bar is an unencoded fn name, then
+ the core's symbol-table reading machinery and redirection machinery
+ will conspire to cause calls to the function 'bar' in object with
+ soname 'foo' to actually be routed to the function written here.
+ We use this below to define dozens of replacements of malloc, free,
+ etc.
+
+ The soname must be a Z-encoded bit of text because sonames can
+ contain dots etc which are not valid symbol names. However, it is
+ better not to Z-encode the function name, because C++ function names
+ are already mangled, and we don't want our own Z encoding to interact
+ badly with them; furthermore there's no point, because mangled C++
+ function names are by definition already valid symbol names.
+ =20
+ It is important that the Z-encoded soname contains no unencoded=20
+ underscores, since the intercept-handlers in vg_symtab2.c detect
+ the end of the soname by looking for the first trailing underscore.
+*/
+
+/* We use a Z-encoding scheme here, a la GHC. This is just about
+ readable enough to make a preprocessor unnecessary.
+
+ The intercept-me function names are encoded as
+
+ _vgi_zEncodedSoname_fnname
+
+ where soname is Z-encoded but fnname isn't.
+
+ The Z-encoding scheme is as follows:
+
+ * --> Za (asterisk)
+ + --> Zp
+ : --> Zc
+ . --> Zd
+ _ --> Zu
+ (space) --> Zs
+ Z --> ZZ
+*/
+
+
+/* It would be nice to be able to write VG_INTERCEPT_PREFIX instead of
+ "_vgi_" here, but I can't figure out how to get cpp to cooperate.
+ If you change this "_vgi_" you should also change the definitiion
+ of VG_INTERCEPT_PREFIX in core.h accordingly.
+*/
+#define ENCODE(libname,fnname) _vgi_##libname##_##fnname
+
+
+/* Some handy mangled names */
+#define m_libstc_plus_plus_star libstdcZpZpZa // libstdc++*
+#define m_libc_dot_so_dot_6 libcZdsoZd6 // libc.so.6
+//#define m_libpgc_dot_so libpgcZdso // libpgc.so
+
+/* 2 Apr 05: the Portland Group compiler, which uses cfront/ARM style
+ mangling, could be supported properly by the redirects in this
+ module. Except we can't because it doesn't put its allocation
+ functions in libpgc.so but instead hardwires them into the
+ compilation unit holding main(), which makes them impossible to
+ intercept directly. Fortunately those fns seem to route everything
+ through to malloc/free.
+*/
+
+extern void _exit(int);
+
+/*------------------------------------------------------------*/
+/*--- Replacing malloc() et al ---*/
+/*------------------------------------------------------------*/
+
+/* This struct is initially empty. Before the first use of any of
+ these functions, we make a client request which fills in the
+ fields.=20
+*/
+static struct vg_mallocfunc_info info;
+static int init_done;
+
+/* Startup hook - called as init section */
+static void init(void) __attribute__((constructor));
+
+// Functions for printing from code within Valgrind, but which runs on t=
he
+// sim'd CPU. They must be functions rather than macros so that va_list=
can
+// be used.
+// Nb: at one point, these were used by multiple files that run on the s=
im'd
+// CPU, and so were *defined* in core.h with the 'weak' attribute. That=
was
+// pretty ugly. It's much better if this is the only file that needs th=
em.
+
+__attribute__((format(__printf__, 1, 2)))
+static int
+internal_printf(char *format, ...)
+{
+ UWord _qzz_res =3D 0;
+ va_list vargs;
+ va_start(vargs, format);
+ VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__INTERNAL_PRINTF,
+ (UWord)format, (UWord)vargs, 0, 0);
+ va_end(vargs);
+ return _qzz_res;
+}
+
+#define MALLOC_TRACE(format, args...) \
+ if (info.clo_trace_malloc) \
+ internal_printf(format, ## args )
+
+#define MAYBE_SLOPPIFY(n) \
+ if (info.clo_sloppy_malloc) { \
+ n =3D (n+(VG_SLOPPY_MALLOC_SZB-1)) & ~(VG_SLOPPY_MALLOC_SZB-1); \
+ }
+
+
+/* Below are new versions of malloc, __builtin_new, free,=20
+ __builtin_delete, calloc, realloc, memalign, and friends.
+
+ None of these functions are called directly - they are not meant to
+ be found by the dynamic linker. But ALL client calls to malloc() and
+ friends wind up here eventually. They get called because vg_replace_=
malloc
+ installs a bunch of code redirects which causes Valgrind to use these
+ functions rather than the ones they're replacing.
+*/
+
+/* Generate a replacement for 'fnname' in object 'soname', which calls
+ 'vg_replacement' to allocate memory. If that fails, return NULL.
+*/
+#define ALLOC_or_NULL(soname, fnname, vg_replacement) \
+ \
+ void* ENCODE(soname,fnname) (SizeT n); \
+ void* ENCODE(soname,fnname) (SizeT n) \
+ { \
+ void* v; \
+ \
+ MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
+ MAYBE_SLOPPIFY(n); \
+ if (!init_done) init(); \
+ \
+ v =3D (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n =
); \
+ MALLOC_TRACE(" =3D %p", v ); \
+ return v; \
+ }
+
+
+/* Generate a replacement for 'fnname' in object 'soname', which calls
+ 'vg_replacement' to allocate memory. If that fails, it bombs the
+ system.
+*/
+#define ALLOC_or_BOMB(soname, fnname, vg_replacement) \
+ \
+ void* ENCODE(soname,fnname) (SizeT n); \
+ void* ENCODE(soname,fnname) (SizeT n) \
+ { \
+ void* v; \
+ \
+ MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
+ MAYBE_SLOPPIFY(n); \
+ if (!init_done) init(); \
+ \
+ v =3D (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n =
); \
+ MALLOC_TRACE(" =3D %p", v ); \
+ if (NULL =3D=3D v) { \
+ VALGRIND_PRINTF_BACKTRACE( \
+ "new/new[] failed and should throw an exception, but Valgrin=
d\n" \
+ " cannot throw exceptions and so is aborting instead. Sor=
ry."); \
+ _exit(1); \
+ } \
+ return v; \
+ }
+
+// Each of these lines generates a replacement function:
+// (from_so, from_fn, v's replacement)
+
+// malloc
+ALLOC_or_NULL(m_libstc_plus_plus_star, malloc, malloc);
+ALLOC_or_NULL(m_libc_dot_so_dot_6, malloc, malloc);
+//ALLOC_or_NULL(m_libpgc_dot_so, malloc, malloc);
+
+// operator new(unsigned int), GNU mangling
+ALLOC_or_BOMB(m_libstc_plus_plus_star, builtin_new, __builtin_new);
+ALLOC_or_BOMB(m_libc_dot_so_dot_6, builtin_new, __builtin_new);
+
+ALLOC_or_BOMB(m_libstc_plus_plus_star, __builtin_new, __builtin_new);
+ALLOC_or_BOMB(m_libc_dot_so_dot_6, __builtin_new, __builtin_new);
+
+ALLOC_or_BOMB(m_libstc_plus_plus_star, _Znwj, __builtin_new);
+ALLOC_or_BOMB(m_libc_dot_so_dot_6, _Znwj, __builtin_new);
+
+// operator new(unsigned int), ARM/cfront mangling
+//ALLOC_or_BOMB(m_libpgc_dot_so, __nw__FUi, __builtin_new);
+
+// operator new(unsigned, std::nothrow_t const&), GNU mangling
+ALLOC_or_NULL(m_libstc_plus_plus_star, _ZnwjRKSt9nothrow_t, __builtin_n=
ew);
+ALLOC_or_NULL(m_libc_dot_so_dot_6, _ZnwjRKSt9nothrow_t, __builtin_n=
ew);
+
+// operator new[](unsigned int), GNU mangling
+ALLOC_or_BOMB(m_libstc_plus_plus_star, __builtin_vec_new, __builtin_vec_=
new );
+ALLOC_or_BOMB(m_libc_dot_so_dot_6, __builtin_vec_new, __builtin_vec_=
new );
+ALLOC_or_BOMB(m_libstc_plus_plus_star, _Znaj, __builtin_vec_=
new );
+ALLOC_or_BOMB(m_libc_dot_so_dot_6, _Znaj, __builtin_vec_=
new );
+
+// operator new[](unsigned, std::nothrow_t const&), GNU mangling
+ALLOC_or_NULL(m_libstc_plus_plus_star, _ZnajRKSt9nothrow_t, __builtin_ve=
c_new );
+ALLOC_or_NULL(m_libc_dot_so_dot_6, _ZnajRKSt9nothrow_t, __builtin_ve=
c_new );
+
+
+/* Generate a replacement for 'fnname' in object 'soname', which calls
+ 'vg_replacement' to free previously allocated memory.
+*/
+#define FREE(soname, fnname, vg_replacement) \
+ \
+ void ENCODE(soname,fnname) (void *p); \
+ void ENCODE(soname,fnname) (void *p) \
+ { \
+ MALLOC_TRACE(#vg_replacement "(%p)", p ); \
+ if (p =3D=3D NULL) \
+ return; \
+ if (!init_done) init(); \
+ (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
+ }
+
+// free
+FREE(m_libstc_plus_plus_star, free, free );
+FREE(m_libc_dot_so_dot_6, free, free );
+
+// cfree
+FREE(m_libstc_plus_plus_star, cfree, free );
+FREE(m_libc_dot_so_dot_6, cfree, free );
+
+// do we really need these?
+FREE(m_libstc_plus_plus_star, __builtin_delete, __builtin_delete );
+FREE(m_libc_dot_so_dot_6, __builtin_delete, __builtin_delete );
+
+// operator delete(void*), GNU mangling
+FREE(m_libstc_plus_plus_star, _ZdlPv, __builtin_delete );
+FREE(m_libc_dot_so_dot_6, _ZdlPv, __builtin_delete );
+
+// operator delete(void*, std::nothrow_t const&), GNU mangling
+FREE(m_libstc_plus_plus_star, _ZdlPvRKSt9nothrow_t, __builtin_delete );
+FREE(m_libc_dot_so_dot_6, _ZdlPvRKSt9nothrow_t, __builtin_delete );
+
+// operator delete[](void*), GNU mangling
+FREE(m_libstc_plus_plus_star, __builtin_vec_delete, __builtin_vec_delet=
e );
+FREE(m_libc_dot_so_dot_6, __builtin_vec_delete, __builtin_vec_delet=
e );
+FREE(m_libstc_plus_plus_star, _ZdaPv, __builtin_vec_delet=
e );
+FREE(m_libc_dot_so_dot_6, _ZdaPv, __builtin_vec_delet=
e );
+
+// operator delete[](void*, std::nothrow_t const&), GNU mangling
+FREE(m_libstc_plus_plus_star, _ZdaPvRKSt9nothrow_t, __builtin_vec_delet=
e );
+FREE(m_libc_dot_so_dot_6, _ZdaPvRKSt9nothrow_t, __builtin_vec_delet=
e );
+
+
+#define CALLOC(soname, fnname) \
+ \
+ void* ENCODE(soname,fnname) ( SizeT nmemb, SizeT size ); \
+ void* ENCODE(soname,fnname) ( SizeT nmemb, SizeT size ) \
+ { \
+ void* v; \
+ \
+ MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
+ MAYBE_SLOPPIFY(size); \
+ \
+ if (!init_done) init(); \
+ v =3D (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size =
); \
+ MALLOC_TRACE(" =3D %p", v ); \
+ return v; \
+ }
+
+CALLOC(m_libc_dot_so_dot_6, calloc);
+
+
+#define REALLOC(soname, fnname) \
+ \
+ void* ENCODE(soname,fnname) ( void* ptrV, SizeT new_size ); \
+ void* ENCODE(soname,fnname) ( void* ptrV, SizeT new_size ) \
+ { \
+ void* v; \
+ \
+ MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
+ MAYBE_SLOPPIFY(new_size); \
+ \
+ if (ptrV =3D=3D NULL) \
+ /* We need to call a malloc-like function; so let's use \
+ one which we know exists. */ \
+ return ENCODE(libcZdsoZd6,malloc) (new_size); \
+ if (new_size <=3D 0) { \
+ ENCODE(libcZdsoZd6,free)(ptrV); \
+ if (info.clo_trace_malloc) \
+ internal_printf(" =3D 0" ); \
+ return NULL; \
+ } \
+ if (!init_done) init(); \
+ v =3D (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_s=
ize ); \
+ MALLOC_TRACE(" =3D %p", v ); \
+ return v; \
+ }
+
+REALLOC(m_libc_dot_so_dot_6, realloc);
+
+
+#define MEMALIGN(soname, fnname) \
+ \
+ void* ENCODE(soname,fnname) ( SizeT alignment, SizeT n ); \
+ void* ENCODE(soname,fnname) ( SizeT alignment, SizeT n ) \
+ { \
+ void* v; \
+ \
+ MALLOC_TRACE("memalign(al %llu, size %llu)", \
+ (ULong)alignment, (ULong)n ); \
+ MAYBE_SLOPPIFY(n); \
+ \
+ /* Round up to minimum alignment if necessary. */ \
+ if (alignment < VG_MIN_MALLOC_SZB) \
+ alignment =3D VG_MIN_MALLOC_SZB; \
+ \
+ /* Round up to nearest power-of-two if necessary (like glibc). */ =
\
+ while (0 !=3D (alignment & (alignment - 1))) alignment++; \
+ \
+ if (!init_done) init(); \
+ v =3D (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment,=
n ); \
+ MALLOC_TRACE(" =3D %p", v ); \
+ return v; \
+ }
+
+MEMALIGN(m_libc_dot_so_dot_6, memalign);
+
+
+#define VALLOC(soname, fnname) \
+ \
+ void* ENCODE(soname,fnname) ( SizeT size ); \
+ void* ENCODE(soname,fnname) ( SizeT size ) \
+ { \
+ return ENCODE(libcZdsoZd6,memalign)(VKI_PAGE_SIZE, size); \
+ }
+
+VALLOC(m_libc_dot_so_dot_6, valloc);
+
+
+/* Various compatibility wrapper functions, for glibc and libstdc++. */
+
+#define MALLOPT(soname, fnname) \
+ \
+ int ENCODE(soname, fnname) ( int cmd, int value ); \
+ int ENCODE(soname, fnname) ( int cmd, int value ) \
+ { \
+ /* In glibc-2.2.4, 1 denotes a successful return value for \
+ mallopt */ \
+ return 1; \
+ }
+
+MALLOPT(m_libc_dot_so_dot_6, mallopt);
+
+
+#define POSIX_MEMALIGN(soname, fnname) \
+ \
+ int ENCODE(soname, fnname) ( void **memptr, SizeT alignment, SizeT si=
ze ); \
+ int ENCODE(soname, fnname) ( void **memptr, SizeT alignment, SizeT si=
ze ) \
+ { \
+ void *mem; \
+ \
+ /* Test whether the alignment argument is valid. It must be \
+ a power of two multiple of sizeof (void *). */ \
+ if (alignment % sizeof (void *) !=3D 0 \
+ || (alignment & (alignment - 1)) !=3D 0) \
+ return VKI_EINVAL; \
+ \
+ mem =3D ENCODE(libcZdsoZd6,memalign)(alignment, size); \
+ \
+ if (mem !=3D NULL) { \
+ *memptr =3D mem; \
+ return 0; \
+ } \
+ \
+ return VKI_ENOMEM; \
+ }
+
+POSIX_MEMALIGN(m_libc_dot_so_dot_6, posix_memalign);
+
+
+#define MALLOC_USABLE_SIZE(soname, fnname) \
+ \
+ int ENCODE(soname, fnname) ( void* p ); \
+ int ENCODE(soname, fnname) ( void* p ) \
+ { \
+ SizeT pszB; \
+ \
+ MALLOC_TRACE("malloc_usable_size(%p)", p ); \
+ if (NULL =3D=3D p) \
+ return 0; \
+ \
+ if (!init_done) init(); \
+ pszB =3D (SizeT)VALGRIND_NON_SIMD_CALL2( info.arena_payload_szB, \
+ VG_AR_CLIENT, p ); \
+ MALLOC_TRACE(" =3D %llu", (ULong)pszB ); \
+ \
+ return pszB; \
+ }
+
+MALLOC_USABLE_SIZE(m_libc_dot_so_dot_6, malloc_usable_size);
+
+
+/* Bomb out if we get any of these. */
+
+static void panic(const char *str)
+{
+ VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s", s=
tr);
+ _exit(99);
+ *(int *)0 =3D 'x';
+}
+
+#define PANIC(soname, fnname) \
+ \
+ void ENCODE(soname, fnname) ( void ); \
+ void ENCODE(soname, fnname) ( void ) \
+ { \
+ panic(#fnname); \
+ }
+
+PANIC(m_libc_dot_so_dot_6, pvalloc);
+PANIC(m_libc_dot_so_dot_6, malloc_stats);
+PANIC(m_libc_dot_so_dot_6, malloc_trim);
+PANIC(m_libc_dot_so_dot_6, malloc_get_state);
+PANIC(m_libc_dot_so_dot_6, malloc_set_state);
+
+
+/* Yet another ugly hack. Cannot include <malloc.h> because we
+ implement functions implemented there with different signatures.
+ This struct definition MUST match the system one. */
+
+/* SVID2/XPG mallinfo structure */
+struct mallinfo {
+ int arena; /* total space allocated from system */
+ int ordblks; /* number of non-inuse chunks */
+ int smblks; /* unused -- always zero */
+ int hblks; /* number of mmapped regions */
+ int hblkhd; /* total space in mmapped regions */
+ int usmblks; /* unused -- always zero */
+ int fsmblks; /* unused -- always zero */
+ int uordblks; /* total allocated space */
+ int fordblks; /* total non-inuse space */
+ int keepcost; /* top-most, releasable (via malloc_trim) space */
+};
+
+#define MALLINFO(soname, fnname) \
+ \
+ struct mallinfo ENCODE(soname, fnname) ( void ); \
+ struct mallinfo ENCODE(soname, fnname) ( void ) \
+ { \
+ /* Should really try to return something a bit more meaningful */ =
\
+ UInt i; \
+ struct mallinfo mi; \
+ UChar* pmi =3D (UChar*)(&mi); \
+ for (i =3D 0; i < sizeof(mi); i++) \
+ pmi[i] =3D 0; \
+ return mi; \
+ }
+
+MALLINFO(m_libc_dot_so_dot_6, mallinfo);
+
+
+/* All the code in here is unused until this function is called */
+
+static void init(void)
+{
+ int res;
+
+ if (init_done)
+ return;
+
+ init_done =3D 1;
+
+ VALGRIND_MAGIC_SEQUENCE(res, -1, VG_USERREQ__GET_MALLOCFUNCS, &info,
+ 0, 0, 0);
+}
+
+/*--------------------------------------------------------------------*/
+/*--- end vg_replace_malloc.c ---*/
+/*--------------------------------------------------------------------*/
Deleted: trunk/coregrind/vg_replace_malloc.c.base
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/vg_replace_malloc.c.base 2005-04-02 17:30:19 UTC (rev=
3509)
+++ trunk/coregrind/vg_replace_malloc.c.base 2005-04-02 17:38:59 UTC (rev=
3510)
@@ -1,365 +0,0 @@
-
-/*--------------------------------------------------------------------*/
-/*--- Replacements for malloc() et al, which run on the simulated ---*/
-/*--- CPU. vg_replace_malloc.c ---*/
-/*--------------------------------------------------------------------*/
-
-/*
- This file is part of Valgrind, a dynamic binary instrumentation
- framework.
-
- Copyright (C) 2000-2005 Julian Seward=20
- js...@ac...
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307, USA.
-
- The GNU General Public License is contained in the file COPYING.
-*/
-
-/* ---------------------------------------------------------------------
- All the code in this file runs on the SIMULATED CPU. It is intended
- for various reasons as drop-in replacements for malloc() and friends.
- These functions have global scope, but are not intended to be called
- directly. See the comments in coregrind/vg_intercept.c for the
- gory details.
-
- This file can be linked into the injected so file for any tool that
- wishes to know about calls to malloc(). It should define functions
- TL_(malloc) et al that will be called.
- ------------------------------------------------------------------ */
-
-#include "valgrind.h" /* for VALGRIND_NON_SIMD_CALL[12] */
-#include "core.h"
-
-// Nb: the last line is repeated -- once for the declaration, once for t=
he
-// definition. If we don't have the declaration there GCC complains.
-#define LIBALIAS(ret, name, args) \
- ret VG_INTERCEPT(soname:libstdc++*, __libc_##name) args \
- __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, ##name))=
, \
- visibility("protected"))); \
- ret VG_INTERCEPT(soname:libc.so.6, __libc_##name) args \
- __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, ##name))=
, \
- visibility("protected"))); \
- ret VG_INTERCEPT(soname:libstdc++*, __##name) args \
- __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, ##name))=
, \
- visibility("protected"))); \
- ret VG_INTERCEPT(soname:libc.so.6, __##name) args \
- __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, ##name))=
, \
- visibility("protected"))); \
- ret VG_INTERCEPT(soname:libstdc++*, ##name) args \
- __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, ##name))=
, \
- visibility("protected"))); \
- ret VG_INTERCEPT(soname:libc.so.6, ##name) args; \
- ret VG_INTERCEPT(soname:libc.so.6, ##name) args
-
-extern void _exit(int);
-
-/*------------------------------------------------------------*/
-/*--- Replacing malloc() et al ---*/
-/*------------------------------------------------------------*/
-
-static struct vg_mallocfunc_info info;
-static int init_done;
-
-/* Startup hook - called as init section */
-static void init(void) __attribute__((constructor));
-
-// Functions for printing from code within Valgrind, but which runs on t=
he
-// sim'd CPU. They must be functions rather than macros so that va_list=
can
-// be used.
-// Nb: at one point, these were used by multiple files that run on the s=
im'd
-// CPU, and so were *defined* in core.h with the 'weak' attribute. That=
was
-// pretty ugly. It's much better if this is the only file that needs th=
em.
-
-__attribute__((format(__printf__, 1, 2)))
-static int
-internal_printf(char *format, ...)
-{
- UWord _qzz_res =3D 0;
- va_list vargs;
- va_start(vargs, format);
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__INTERNAL_PRINTF,
- (UWord)format, (UWord)vargs, 0, 0);
- va_end(vargs);
- return _qzz_res;
-}
-
-#define MALLOC_TRACE(format, args...) \
- if (info.clo_trace_malloc) \
- internal_printf(format, ## args )
-
-#define MAYBE_SLOPPIFY(n) \
- if (info.clo_sloppy_malloc) { \
- n =3D (n+(VG_SLOPPY_MALLOC_SZB-1)) & ~(VG_SLOPPY_MALLOC_SZB-1); \
- }
-
-/* Below are new versions of malloc, __builtin_new, free,=20
- __builtin_delete, calloc, realloc, memalign, and friends.
-
- None of these functions are called directly - they are not meant to
- be found by the dynamic linker. But ALL client calls to malloc() and
- friends wind up here eventually. They get called because vg_replace_=
malloc
- installs a bunch of code redirects which causes Valgrind to use these
- functions rather than the ones they're replacing. */
-
-#define ALLOC(fff, vgfff) \
-LIBALIAS(void *, fff, (SizeT n)) \
-{ \
- void* v; \
- \
- MALLOC_TRACE(#fff "(%llu)", (ULong)n ); \
- MAYBE_SLOPPIFY(n); \
- if (!init_done) init(); \
- \
- v =3D (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vgfff, n ); \
- MALLOC_TRACE(" =3D %p", v ); \
- return v; \
-}
-
-#define ALLOC2(fff, vgfff) \
-LIBALIAS(void *, fff, (SizeT n)) \
-{ \
- void* v; \
- \
- MALLOC_TRACE(#fff "(%llu)", (ULong)n ); \
- MAYBE_SLOPPIFY(n); \
- if (!init_done) init(); \
- \
- v =3D (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vgfff, n ); \
- MALLOC_TRACE(" =3D %p", v ); \
- if (NULL =3D=3D v) { \
- VALGRIND_PRINTF_BACKTRACE( \
- "new/new[] failed and should throw an exception, but Valgrind\n=
" \
- " cannot throw exceptions and so is aborting instead. Sorry.=
"); \
- _exit(1); \
- } \
- return v; \
-}
-ALLOC( malloc, malloc );
-ALLOC2(__builtin_new, __builtin_new );
-ALLOC2(_Znwj, __builtin_new );
-
-// operator new(unsigned, std::nothrow_t const&)
-ALLOC( _ZnwjRKSt9nothrow_t, __builtin_new );
-
-ALLOC2(__builtin_vec_new, __builtin_vec_new );
-ALLOC2(_Znaj, __builtin_vec_new );
-
-// operator new[](unsigned, std::nothrow_t const&)
-ALLOC( _ZnajRKSt9nothrow_t, __builtin_vec_new );
-
-#define FREE(fff, vgfff) \
-LIBALIAS(void, fff, (void *p)) \
-{ \
- MALLOC_TRACE(#fff "(%p)", p ); \
- if (p =3D=3D NULL) \
- return; \
- if (!init_done) init(); \
- (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vgfff, p ); \
-}
-FREE( free, free );
-FREE( cfree, free );
-FREE( __builtin_delete, __builtin_delete );
-FREE( _ZdlPv, __builtin_delete );
-
-// operator delete(void*, std::nothrow_t const&)
-FREE( _ZdlPvRKSt9nothrow_t, __builtin_delete );
-
-FREE( __builtin_vec_delete, __builtin_vec_delete );
-FREE( _ZdaPv, __builtin_vec_delete );
-
-// operator delete[](void*, std::nothrow_t const&)
-FREE( _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
-
-
-LIBALIAS(void*, calloc, ( SizeT nmemb, SizeT size ))
-{
- void* v;
-
- MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size );
- MAYBE_SLOPPIFY(size);
-
- if (!init_done) init();
- v =3D (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size );
- MALLOC_TRACE(" =3D %p", v );
- return v;
-}
-
-LIBALIAS(void*, realloc, ( void* ptrV, SizeT new_size ))
-{
- void* v;
-
- MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size );
- MAYBE_SLOPPIFY(new_size);
-
- if (ptrV =3D=3D NULL)
- return VG_INTERCEPT(soname:libc.so.6, malloc)(new_size);
- if (new_size <=3D 0) {
- VG_INTERCEPT(soname:libc.so.6, free)(ptrV);
- if (info.clo_trace_malloc)=20
- internal_printf(" =3D 0" );
- return NULL;
- } =20
- if (!init_done) init();
- v =3D (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size=
);
- MALLOC_TRACE(" =3D %p", v );
- return v;
-}
-
-
-LIBALIAS(void*, memalign, ( SizeT alignment, SizeT n ))
-{
- void* v;
-
- MALLOC_TRACE("memalign(al %llu, size %llu)", (ULong)alignment, (ULong=
)n );
- MAYBE_SLOPPIFY(n);
-
- // Round up to minimum alignment if necessary.
- if (alignment < VG_MIN_MALLOC_SZB) alignment =3D VG_MIN_MALLOC_SZB;
-
- // Round up to nearest power-of-two if necessary (like glibc).
- while (0 !=3D (alignment & (alignment - 1))) alignment++;
-
- if (!init_done) init();
- v =3D (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n =
);
- MALLOC_TRACE(" =3D %p", v );
- return v;
-}
-
-
-LIBALIAS(void*, valloc, ( SizeT size ))
-{
- return VG_INTERCEPT(soname:libc.so.6, memalign)(VKI_PAGE_SIZE, size);
-}
-
-
-/* Various compatibility wrapper functions, for glibc and libstdc++. */
-
-LIBALIAS(int, mallopt, ( int cmd, int value ))
-{
- /* In glibc-2.2.4, 1 denotes a successful return value for mallopt */
- return 1;
-}
-
-
-LIBALIAS(int, posix_memalign, ( void **memptr, SizeT alignment, SizeT si=
ze ))
-{
- void *mem;
-
- /* Test whether the alignment argument is valid. It must be a power=
of
- two multiple of sizeof (void *). */
- if (alignment % sizeof (void *) !=3D 0 || (alignment & (alignment - =
1)) !=3D 0)
- return VKI_EINVAL /*22*/ /*EINVAL*/;
-
- mem =3D VG_INTERCEPT(soname:libc.so.6, memalign)(alignment, size);
-
- if (mem !=3D NULL) {
- *memptr =3D mem;
- return 0;
- }
-
- return VKI_ENOMEM /*12*/ /*ENOMEM*/;
-}
-
-LIBALIAS(int, malloc_usable_size, ( void* p ))
-{=20
- SizeT pszB;
- =20
- MALLOC_TRACE("malloc_usable_size(%p)", p );
- if (NULL =3D=3D p)
- return 0;
-
- if (!init_done) init();
- pszB =3D (SizeT)VALGRIND_NON_SIMD_CALL2( info.arena_payload_szB,=20
- VG_AR_CLIENT, p );
- MALLOC_TRACE(" =3D %llu", (ULong)pszB );
-
- return pszB;
-}
-
-
-/* Bomb out if we get any of these. */
-
-static void panic(const char *str)
-{
- VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s", s=
tr);
- =20
- _exit(99);
- *(int *)0 =3D 'x';
-}
-
-// As for LIBALIAS, we have the declaration to shut GCC up.
-#define PANIC(x) \
- void VG_INTERCEPT(soname:libc.so.6, ## x)(void); \
- void VG_INTERCEPT(soname:libc.so.6, ## x)(void) \
- { \
- panic(#x); \
- }
-
-PANIC(pvalloc);
-PANIC(malloc_stats);
-PANIC(malloc_trim);
-PANIC(malloc_get_state);
-PANIC(malloc_set_state);
-
-
-/* Yet another ugly hack. Cannot include <malloc.h> because we
- implement functions implemented there with different signatures.
- This struct definition MUST match the system one. */
-
-/* SVID2/XPG mallinfo structure */
-struct mallinfo {
- int arena; /* total space allocated from system */
- int ordblks; /* number of non-inuse chunks */
- int smblks; /* unused -- always zero */
- int hblks; /* number of mmapped regions */
- int hblkhd; /* total space in mmapped regions */
- int usmblks; /* unused -- always zero */
- int fsmblks; /* unused -- always zero */
- int uordblks; /* total allocated space */
- int fordblks; /* total non-inuse space */
- int keepcost; /* top-most, releasable (via malloc_trim) space */
-};
-
-LIBALIAS(struct mallinfo, mallinfo, ( void ))
-{
- /* Should really try to return something a bit more meaningful */
- UInt i;
- struct mallinfo mi;
- UChar* pmi =3D (UChar*)(&mi);
- for (i =3D 0; i < sizeof(mi); i++)
- pmi[i] =3D 0;
- return mi;
-}
-
-/* All the code in here is unused until this function is called */
-
-static void init(void)
-{
- int res;
-
- if (init_done)
- return;
-
- init_done =3D 1;
-
- VALGRIND_MAGIC_SEQUENCE(res, -1, VG_USERREQ__GET_MALLOCFUNCS, &info,
- 0, 0, 0);
-}
-
-/*--------------------------------------------------------------------*/
-/*--- end vg_replace_malloc.c ---*/
-/*--------------------------------------------------------------------*/
Modified: trunk/coregrind/vg_symtab2.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/vg_symtab2.c 2005-04-02 17:30:19 UTC (rev 3509)
+++ trunk/coregrind/vg_symtab2.c 2005-04-02 17:38:59 UTC (rev 3510)
@@ -799,73 +799,121 @@
return False;
}
=20
-/*
- * Demangle an intercept symbol into library:func form
+/* Demangle an intercept symbol into library:func form
+ eg "_vgi_libcZdsoZd6__ZdlPv" --> "libc.so.6:_ZdlPv"
+ Uses the Z-encoding scheme described in vg_replace_malloc.c.
+ Returns True if demangle OK, False otherwise.
*/
=20
static Bool
intercept_demangle(const Char* symbol, Char* result, Int nbytes)
{
- int i, j =3D 0;
- int len =3D VG_(strlen)(symbol);
+# define EMIT(ch) \
+ do { \
+ if (j >=3D nbytes) \
+ result[j-1] =3D 0; \
+ else \
+ result[j++] =3D ch; \
+ } while (0)
=20
- for(i =3D VG_INTERCEPT_PREFIX_LEN; i < len; i++) {
- if(symbol[i] =3D=3D 'J') {
+ Bool error =3D False;
+ Int i, j =3D 0;
+ Int len =3D VG_(strlen)(symbol);
+ if (0) VG_(printf)("idm: %s\n", symbol);
+
+ i =3D VG_INTERCEPT_PREFIX_LEN;
+
+ /* Chew though the Z-encoded soname part. */
+ while (True) {
+
+ if (i >=3D len)=20
+ break;
+
+ if (symbol[i] =3D=3D '_')
+ /* We found the underscore following the Z-encoded soname.
+ Just copy the rest literally. */
+ break;
+
+ if (symbol[i] !=3D 'Z') {
+ EMIT(symbol[i]);
i++;
- vg_assert('J' !=3D symbol[i]);
- if((symbol[i] >=3D '0' && symbol[i] <=3D '9') ||
- (symbol[i] >=3D 'a' && symbol[i] <=3D 'f') ||
- (symbol[i] >=3D 'A' && symbol[i] <=3D 'F'))=20
- {
- int x =3D symbol[i++];
- int y =3D symbol[i];
- if(x >=3D '0' && x <=3D '9') {
- x -=3D '0';
- } else if(x >=3D 'a' && x <=3D 'f') {
- x -=3D 'a';
- } else if(x >=3D 'A' && x <=3D 'F') {
- x -=3D 'A';
- }
- if(y >=3D '0' && y <=3D '9') {
- y -=3D '0';
- } else if(y >=3D 'a' && y <=3D 'f') {
- y =3D y - 'a' + 10;
- } else if(y >=3D 'A' && y <=3D 'F') {
- y =3D y - 'A' + 10;
- } else {
- return False;
- }
- result[j] =3D (x << 4) | y;
- } else {
- return False;
- }
- } else {
- result[j] =3D symbol[i];
+ continue;
}
- if(j >=3D nbytes) {
- result[j] =3D '\0';
- return True;
+
+ /* We've got a Z-escape. Act accordingly. */
+ i++;
+ if (i >=3D len) {
+ /* Hmm, Z right at the end. Something's wrong. */
+ error =3D True;
+ EMIT('Z');
+ break;
}
- j++;
+ switch (symbol[i]) {
+ case 'a': EMIT('*'); break;
+ case 'p': EMIT('+'); break;
+ case 'c': EMIT(':'); break;
+ case 'd': EMIT('.'); break;
+ case 'u': EMIT('_'); break;
+ case 's': EMIT(' '); break;
+ case 'Z': EMIT('Z'); break;
+ default: error =3D True; EMIT('Z'); EMIT(symbol[i]); break;
+ }
+ i++;
}
- result[j] =3D '\0';
+
+ if (error || i >=3D len || symbol[i] !=3D '_') {
+ /* Something's wrong. Give up. */
+ VG_(message)(Vg_UserMsg, "intercept: error demangling: %s", symbol=
);
+ EMIT(0);
+ return False;
+ }
+
+ /* Copy the rest of the string verbatim. */
+ i++;
+ EMIT(':');
+ while (True) {
+ if (i >=3D len)
+ break;
+ EMIT(symbol[i]);
+ i++;
+ }
+
+ EMIT(0);
+ if (0) VG_(printf)("%s\n", result);
return True;
+
+# undef EMIT
}
=20
static
void handle_intercept( SegInfo* si, Char* symbol, ElfXX_Sym* sym)
{
- Int len =3D VG_(strlen)(symbol) + 1 - VG_INTERCEPT_PREFIX_LEN;
- Char *lib =3D VG_(arena_malloc)(VG_AR_SYMTAB, len);
+ Bool ok;
+ Int len =3D VG_(strlen)(symbol) + 1 - VG_INTERCEPT_PREFIX_LEN;
+ Char *lib =3D VG_(arena_malloc)(VG_AR_SYMTAB, len+8);
Char *func;
=20
- intercept_demangle(symbol, lib, len);
- func =3D lib + VG_(strlen)(lib)-1;
+ /* Put "soname:" at the start of lib. */
+ lib[0] =3D 's';
+ lib[1] =3D 'o';
+ lib[2] =3D 'n';
+ lib[3] =3D 'a';
+ lib[4] =3D 'm';
+ lib[5] =3D 'e';
+ lib[6] =3D ':';
+ lib[7] =3D 0;
=20
- while(*func !=3D ':') func--;
- *func =3D '\0';
+ ok =3D intercept_demangle(symbol, lib+7, len);
+ if (ok) {
+ func =3D lib + VG_(strlen)(lib)-1;
=20
- VG_(add_redirect_sym_to_addr)(lib, func+1, si->offset + sym->st_value=
);
+ while(*func !=3D ':') func--;
+ *func =3D '\0';
+
+ if (0) VG_(printf)("lib A%sZ, func A%sZ\n", lib, func+1);
+ VG_(add_redirect_sym_to_addr)(lib, func+1, si->offset + sym->st_va=
lue);
+ }
+
VG_(arena_free)(VG_AR_SYMTAB, lib);
}
=20
|