|
From: <sv...@va...> - 2006-10-01 18:20:37
|
Author: sewardj
Date: 2006-10-01 19:20:35 +0100 (Sun, 01 Oct 2006)
New Revision: 6132
Log:
Minor changes for redirection on AIX. The only significant change is
that it now checks for, warns about and disallows, attempts to
redirect to, or wrap with, a function for which no TOC pointer can be
found, since that would be really asking for trouble (a segfault).
Modified:
branches/AIX5/coregrind/m_redir.c
branches/AIX5/include/pub_tool_redir.h
Modified: branches/AIX5/coregrind/m_redir.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
--- branches/AIX5/coregrind/m_redir.c 2006-10-01 18:16:56 UTC (rev 6131)
+++ branches/AIX5/coregrind/m_redir.c 2006-10-01 18:20:35 UTC (rev 6132)
@@ -43,7 +43,7 @@
#include "pub_core_trampoline.h"
#include "pub_core_transtab.h"
#include "pub_core_tooliface.h" // VG_(needs).malloc_replacement
-#include "pub_tool_machine.h" // VG_(fnptr_to_fnentry)
+#include "pub_core_machine.h" // VG_(fnptr_to_fnentry)
#include "pub_core_aspacemgr.h" // VG_(am_find_nsegment)
#include "pub_core_clientstate.h" // VG_(client___libc_freeres_wrapper)
#include "pub_core_demangle.h" // VG_(maybe_Z_demangle)
@@ -269,6 +269,7 @@
static void symtab_free(void*);
static HChar* symtab_strdup(HChar*);
static Bool is_plausible_guest_addr(Addr);
+static Bool is_aix5_glink_idiom(Addr);
=20
static void show_redir_state ( HChar* who );
static void show_active ( HChar* left, Active* act );
@@ -307,11 +308,16 @@
TopSpec* ts;
TopSpec* newts;
HChar* sym_name;
- Addr sym_addr;
+ Addr sym_addr, sym_toc;
HChar demangled_sopatt[N_DEMANGLED];
HChar demangled_fnpatt[N_DEMANGLED];
+ Bool check_ppcTOCs =3D False;
=20
+
const UChar* newsi_soname;
+# if defined(VG_PLAT_USES_PPCTOC)
+ check_ppcTOCs =3D True;
+# endif
=20
vg_assert(newsi);
newsi_soname =3D VG_(seginfo_soname)(newsi);
@@ -328,15 +334,22 @@
=20
nsyms =3D VG_(seginfo_syms_howmany)( newsi );
for (i =3D 0; i < nsyms; i++) {
- VG_(seginfo_syms_getidx)( newsi, i, &sym_addr, NULL, &sym_name );
+ VG_(seginfo_syms_getidx)( newsi, i, &sym_addr, &sym_toc, NULL, &sy=
m_name );
ok =3D VG_(maybe_Z_demangle)( sym_name, demangled_sopatt, N_DEMANG=
LED,
- demangled_fnpatt, N_DEMANGLED, &isWrap );
+ demangled_fnpatt, N_DEMANGLED, &isWrap=
);
if (!ok) {
/* It's not a full-scale redirect, but perhaps it is a load-not=
ify
fn? Let the load-notify department see it. */
handle_maybe_load_notifier( newsi_soname, sym_name, sym_addr );
continue;=20
}
+ if (check_ppcTOCs && sym_toc =3D=3D 0) {
+ /* This platform uses toc pointers, but none could be found
+ for this symbol, so we can't safely redirect/wrap to it.
+ Just skip it; we'll make a second pass over the symbols in
+ the following loop, and complain at that point. */
+ continue;
+ }
spec =3D symtab_alloc(sizeof(Spec));
vg_assert(spec);
spec->from_sopatt =3D symtab_strdup(demangled_sopatt);
@@ -352,6 +365,34 @@
specList =3D spec;
}
=20
+ if (check_ppcTOCs) {
+ for (i =3D 0; i < nsyms; i++) {
+ VG_(seginfo_syms_getidx)( newsi, i, &sym_addr, &sym_toc, NULL, =
&sym_name );
+ ok =3D VG_(maybe_Z_demangle)( sym_name, demangled_sopatt, N_DEM=
ANGLED,
+ demangled_fnpatt, N_DEMANGLED, &isW=
rap );
+ if (!ok)
+ /* not a redirect. Ignore. */
+ continue;
+ if (sym_toc !=3D 0)
+ /* has a valid toc pointer. Ignore. */
+ continue;
+
+ for (spec =3D specList; spec; spec =3D spec->next)=20
+ if (0 =3D=3D VG_(strcmp)(spec->from_sopatt, demangled_sopatt=
)
+ && 0 =3D=3D VG_(strcmp)(spec->from_fnpatt, demangled_fnp=
att))
+ break;
+ if (spec)
+ /* a redirect to some other copy of that symbol, which does have
+ a TOC value, already exists */
+ continue;
+
+ /* Complain */
+ VG_(message)(Vg_DebugMsg,
+ "WARNING: no TOC ptr for redir/wrap to %s %s",
+ demangled_sopatt, demangled_fnpatt);
+ }
+ }
+
/* Ok. Now specList holds the list of specs from the SegInfo.=20
Build a new TopSpec, but don't add it to topSpecs yet. */
newts =3D symtab_alloc(sizeof(TopSpec));
@@ -384,7 +425,7 @@
generate_and_add_actives( specList, newts,
ts->seginfo, ts );
}
-=09
+
/* Case (2) */
for (ts =3D topSpecs; ts; ts =3D ts->next) {
generate_and_add_actives( ts->specs, ts,=20
@@ -445,7 +486,18 @@
of trashing the caches less. */
nsyms =3D VG_(seginfo_syms_howmany)( si );
for (i =3D 0; i < nsyms; i++) {
- VG_(seginfo_syms_getidx)( si, i, &sym_addr, NULL, &sym_name );
+ VG_(seginfo_syms_getidx)( si, i, &sym_addr, NULL, NULL, &sym_name =
);
+
+ /* On AIX, we cannot redirect calls to a so-called glink
+ function for reasons which are not obvious - something to do
+ with saving r2 across the call. Not a problem, as we don't
+ want to anyway; presumably it is the target of the glink we
+ need to redirect. Hence just spot them and ignore them.
+ They are always of a very specific (more or less
+ ABI-mandated) form. */
+ if (is_aix5_glink_idiom(sym_addr))
+ continue;
+
for (sp =3D specs; sp; sp =3D sp->next) {
if (!sp->mark)
continue; /* soname doesn't match */
@@ -785,6 +837,12 @@
=20
}
=20
+# elif defined(VGP_ppc32_aix5)
+ /* nothing so far */
+
+# elif defined(VGP_ppc64_aix5)
+ /* nothing so far */
+
# else
# error Unknown platform
# endif
@@ -817,12 +875,48 @@
in m_translate. */
static Bool is_plausible_guest_addr(Addr a)
{
- NSegment* seg =3D VG_(am_find_nsegment)(a);
+ NSegment const*const seg =3D VG_(am_find_nsegment)(a);
return seg !=3D NULL
&& (seg->kind =3D=3D SkAnonC || seg->kind =3D=3D SkFileC)
&& (seg->hasX || seg->hasR); /* crude x86-specific hack */
}
=20
+/* A function which spots AIX 'glink' functions. A 'glink' function
+ is a stub function which has something to do with AIX-style dynamic
+ linking, and jumps to the real target (with which it typically
+ shares the same name). See also comment where this function is
+ used (above). */
+static Bool is_aix5_glink_idiom ( Addr sym_addr )
+{
+# if defined(VGP_ppc32_aix5)
+ UInt* w =3D (UInt*)sym_addr;
+ if (VG_IS_4_ALIGNED(w)
+ && is_plausible_guest_addr((Addr)(w+0))
+ && is_plausible_guest_addr((Addr)(w+6))
+ && (w[0] & 0xFFFF0000) =3D=3D 0x81820000 /* lwz r12,func@toc(r2) =
*/
+ && w[1] =3D=3D 0x90410014 /* stw r2,20(r1) */
+ && w[2] =3D=3D 0x800c0000 /* lwz r0,0(r12) */
+ && w[3] =3D=3D 0x804c0004 /* lwz r2,4(r12) */
+ && w[4] =3D=3D 0x7c0903a6 /* mtctr r0 */
+ && w[5] =3D=3D 0x4e800420 /* bctr */
+ && w[6] =3D=3D 0x00000000 /* illegal */)
+ return True;
+# elif defined(VGP_ppc64_aix5)
+ UInt* w =3D (UInt*)sym_addr;
+ if (VG_IS_4_ALIGNED(w)
+ && is_plausible_guest_addr((Addr)(w+0))
+ && is_plausible_guest_addr((Addr)(w+6))
+ && (w[0] & 0xFFFF0000) =3D=3D 0xE9820000 /* ld r12,func@toc(r2) =
*/
+ && w[1] =3D=3D 0xF8410028 /* std r2,40(r1) */
+ && w[2] =3D=3D 0xE80C0000 /* ld r0,0(r12) */
+ && w[3] =3D=3D 0xE84C0008 /* ld r2,8(r12) */
+ && w[4] =3D=3D 0x7c0903a6 /* mtctr r0 */
+ && w[5] =3D=3D 0x4e800420 /* bctr */
+ && w[6] =3D=3D 0x00000000 /* illegal */)
+ return True;
+# endif
+ return False;
+}
=20
/*------------------------------------------------------------*/
/*--- NOTIFY-ON-LOAD FUNCTIONS ---*/
@@ -866,7 +960,7 @@
static void show_spec ( HChar* left, Spec* spec )
{
VG_(message)(Vg_DebugMsg,=20
- "%s%18s %30s %s-> 0x%08llx",
+ "%s%25s %30s %s-> 0x%08llx",
left,
spec->from_sopatt, spec->from_fnpatt,
spec->isWrap ? "W" : "R",
@@ -884,7 +978,7 @@
ok =3D VG_(get_fnname_w_offset)(act->to_addr, name2, 64);
if (!ok) VG_(strcpy)(name2, "???");
=20
- VG_(message)(Vg_DebugMsg, "%s0x%08llx (%10s) %s-> 0x%08llx %s",=20
+ VG_(message)(Vg_DebugMsg, "%s0x%08llx (%20s) %s-> 0x%08llx %s",=20
left,=20
(ULong)act->from_addr, name1,
act->isWrap ? "W" : "R",
Modified: branches/AIX5/include/pub_tool_redir.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
--- branches/AIX5/include/pub_tool_redir.h 2006-10-01 18:16:56 UTC (rev 6=
131)
+++ branches/AIX5/include/pub_tool_redir.h 2006-10-01 18:20:35 UTC (rev 6=
132)
@@ -136,8 +136,10 @@
_ --> Zu (underscore)
- --> Zh (hyphen)
(space) --> Zs (space)
- @ -> ZA (at)
+ @ --> ZA (at)
Z --> ZZ (Z)
+ ( --> ZL (left)
+ ) --> ZR (right)
=20
Everything else is left unchanged.
*/
@@ -146,12 +148,17 @@
changed accordingly. NOTE: duplicates
I_{WRAP,REPLACE}_SONAME_FNNAME_Z{U,Z} in valgrind.h. */
=20
-#define VG_REPLACE_FUNCTION_ZU(soname,fnname) _vgrZU_##soname##_##fnname
-#define VG_REPLACE_FUNCTION_ZZ(soname,fnname) _vgrZZ_##soname##_##fnname
+/* Use an extra level of macroisation so as to ensure the soname/fnname
+ args are fully macro-expanded before pasting them together. */
+#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
=20
-#define VG_WRAP_FUNCTION_ZU(soname,fnname) _vgwZU_##soname##_##fnname
-#define VG_WRAP_FUNCTION_ZZ(soname,fnname) _vgwZZ_##soname##_##fnname
+#define VG_REPLACE_FUNCTION_ZU(soname,fnname) VG_CONCAT4(_vgrZU_,soname,=
_,fnname)
+#define VG_REPLACE_FUNCTION_ZZ(soname,fnname) VG_CONCAT4(_vgrZZ_,soname,=
_,fnname)
=20
+#define VG_WRAP_FUNCTION_ZU(soname,fnname) VG_CONCAT4(_vgwZU_,soname,_,f=
nname)
+#define VG_WRAP_FUNCTION_ZZ(soname,fnname) VG_CONCAT4(_vgwZZ_,soname,_,f=
nname)
+
+
#endif // __PUB_TOOL_REDIR_H
=20
/*--------------------------------------------------------------------*/
|