HChar* from_fnpatt; /* from fnname pattern */
Addr to_addr; /* where redirecting to */
Bool isWrap; /* wrap or replacement? */
- const HChar* mandatory; /* non-NULL ==> abort V and print the
- string if from_sopatt is loaded but
+ HChar** mandatory; /* non-NULL ==> abort V and print the
+ strings if from_sopatt is loaded but
from_fnpatt cannot be found */
/* VARIABLE PARTS -- used transiently whilst processing redirections */
Bool mark; /* set if spec requires further processing */
break;
}
if (sp) {
+ HChar** strp;
HChar* v = "valgrind: ";
vg_assert(sp->mark);
vg_assert(!sp->done);
v, VG_(DebugInfo_get_soname)(di));
VG_(printf)(
"%s\n", v);
- VG_(printf)(
- "%s%s\n", v, sp->mandatory);
+
+ for (strp = sp->mandatory; *strp; strp++)
+ VG_(printf)(
+ "%s%s\n", v, *strp);
+
VG_(printf)(
"%s\n", v);
VG_(printf)(
__attribute__((unused)) /* not used on all platforms */
static void add_hardwired_spec ( HChar* sopatt, HChar* fnpatt,
Addr to_addr,
- const HChar* const mandatory )
+ HChar** mandatory )
{
Spec* spec = dinfo_zalloc("redir.ahs.1", sizeof(Spec));
vg_assert(spec);
}
+__attribute__((unused)) /* not used on all platforms */
+static const HChar* complain_about_stripped_glibc_ldso[]
+= { "Possible fixes: (1, short term): install glibc's debuginfo",
+ "package on this machine. (2, longer term): ask the packagers",
+ "for your Linux distribution to please in future ship a non-",
+ "stripped ld.so (or whatever the dynamic linker .so is called)",
+ "that exports the above-named function using the standard",
+ "calling conventions for this platform.",
+ NULL
+ };
+
+
/* Initialise the redir system, and create the initial Spec list and
for amd64-linux a couple of permanent active mappings. The initial
Specs are not converted into Actives yet, on the (checked)
(Addr)&VG_(amd64_linux_REDIR_FOR_vtime)
);
-# elif defined(VGP_ppc32_linux)
- {
- static const HChar croakage[]
- = "Possible fix: install glibc's debuginfo package on this machine.";
+ /* If we're using memcheck, use these intercepts right from
+ the start, otherwise ld.so makes a lot of noise. */
+ if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
+ add_hardwired_spec(
+ "ld-linux-x86-64.so.2", "strlen",
+ (Addr)&VG_(amd64_linux_REDIR_FOR_strlen),
+# if defined(GLIBC_2_2) || defined(GLIBC_2_3) || defined(GLIBC_2_4) \
+ || defined(GLIBC_2_5) || defined(GLIBC_2_6) || defined(GLIBC_2_7) \
+ || defined(GLIBC_2_8) || defined(GLIBC_2_9)
+ NULL
+# else
+ /* for glibc-2.10 and later, this is mandatory - can't sanely
+ continue without it */
+ complain_about_stripped_glibc_ldso
+# endif
+ );
+ }
+
+# elif defined(VGP_ppc32_linux)
/* If we're using memcheck, use these intercepts right from
the start, otherwise ld.so makes a lot of noise. */
if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
add_hardwired_spec(
"ld.so.1", "strlen",
(Addr)&VG_(ppc32_linux_REDIR_FOR_strlen),
- croakage
+ complain_about_stripped_glibc_ldso
);
add_hardwired_spec(
"ld.so.1", "strcmp",
/* glibc-2.6.1 (openSUSE 10.3, ppc32) seems fine without it */
);
}
- }
# elif defined(VGP_ppc64_linux)
- {
- static const HChar croakage[]
- = "Possible fix: install glibc's debuginfo package on this machine.";
-
/* If we're using memcheck, use these intercepts right from
the start, otherwise ld.so makes a lot of noise. */
if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
add_hardwired_spec(
"ld64.so.1", "strlen",
(Addr)VG_(fnptr_to_fnentry)( &VG_(ppc64_linux_REDIR_FOR_strlen) ),
- croakage
+ complain_about_stripped_glibc_ldso
);
add_hardwired_spec(
/* glibc-2.5 (FC6, ppc64) seems fine without it */
);
}
- }
# elif defined(VGP_ppc32_aix5)
/* nothing so far */
(Addr)&VG_(darwin_REDIR_FOR_strcpy), NULL);
add_hardwired_spec("dyld", "strlcat",
(Addr)&VG_(darwin_REDIR_FOR_strlcat), NULL);
-#if defined(VGP_amd64_darwin)
+# if defined(VGP_amd64_darwin)
// DDD: #warning fixme rdar://6166275
add_hardwired_spec("dyld", "arc4random",
(Addr)&VG_(darwin_REDIR_FOR_arc4random), NULL);
-#endif
+# endif
}
# else
.LfnE3:
.size VG_(amd64_linux_REDIR_FOR_vtime), .-.LfnB3
-/* A CIE for the above two functions, followed by their FDEs */
+/* There's no particular reason that this needs to be handwritten
+ assembly, but since that's what this file contains, here's a
+ simple strlen implementation (written in C and compiled by gcc.)
+*/
+.global VG_(amd64_linux_REDIR_FOR_strlen)
+.type VG_(amd64_linux_REDIR_FOR_strlen), @function
+VG_(amd64_linux_REDIR_FOR_strlen):
+.LfnB4:
+ xorl %eax, %eax
+ cmpb $0, (%rdi)
+ movq %rdi, %rdx
+ je .L41
+.L40: addq $1, %rdx
+ cmpb $0, (%rdx)
+ jne .L40
+ movq %rdx, %rax
+ subq %rdi, %rax
+.L41: ret
+.LfnE4:
+.size VG_(amd64_linux_REDIR_FOR_strlen), .-VG_(amd64_linux_REDIR_FOR_strlen)
+
+
+/* A CIE for the above three functions, followed by their FDEs */
.section .eh_frame,"a",@progbits
.Lframe1:
.long .LEcie1-.LScie1
.uleb128 0x0
.align 8
.LEfde3:
+.LSfde4:
+ .long .LEfde4-.LASfde4
+.LASfde4:
+ .long .LASfde4-.Lframe1
+ .long .LfnB4
+ .long .LfnE4-.LfnB4
+ .uleb128 0x0
+ .align 8
+.LEfde4:
.previous
.global VG_(trampoline_stuff_end)