2 /*--------------------------------------------------------------------*/
3 /*--- Client-space code for the core. vg_preloaded.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2013 Julian Seward
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 The GNU General Public License is contained in the file COPYING.
32 /* ---------------------------------------------------------------------
33 ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
35 These functions are not called directly - they're the targets of code
36 redirection or load notifications (see pub_core_redir.h for info).
37 They're named weirdly so that the intercept code can find them when the
38 shared object is initially loaded.
40 Note that this filename has the "vg_" prefix because it can appear
41 in stack traces, and the "vg_" makes it a little clearer that it
42 originates from Valgrind.
43 ------------------------------------------------------------------ */
45 #include "pub_core_basics.h"
46 #include "pub_core_clreq.h"
47 #include "pub_core_debuginfo.h" // Needed for pub_core_redir.h
48 #include "pub_core_redir.h" // For VG_NOTIFY_ON_LOAD
50 #if defined(VGO_linux)
52 /* ---------------------------------------------------------------------
53 Hook for running __libc_freeres once the program exits.
54 ------------------------------------------------------------------ */
56 void VG_NOTIFY_ON_LOAD(freeres
)( void );
57 void VG_NOTIFY_ON_LOAD(freeres
)( void )
59 # if !defined(__UCLIBC__) \
60 && !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \
61 && !defined(VGPV_mips32_linux_android)
62 extern void __libc_freeres(void);
65 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LIBC_FREERES_DONE
,
68 *(volatile int *)0 = 'x';
71 /* ---------------------------------------------------------------------
72 Wrapper for indirect functions which need to be redirected.
73 ------------------------------------------------------------------ */
75 void * VG_NOTIFY_ON_LOAD(ifunc_wrapper
) (void);
76 void * VG_NOTIFY_ON_LOAD(ifunc_wrapper
) (void)
82 /* Call the original indirect function and get it's result */
83 VALGRIND_GET_ORIG_FN(fn
);
84 CALL_FN_W_v(result
, fn
);
86 #if defined(VGP_ppc64be_linux)
87 /* ppc64be uses function descriptors, so get the actual function entry
88 address for the client request, but return the function descriptor
90 result points to the function descriptor, which starts with the
92 fnentry
= *(Addr
*)result
;
97 /* Ask the valgrind core running on the real CPU (as opposed to this
98 code which runs on the emulated CPU) to update the redirection that
99 led to this function. This client request eventually gives control to
100 the function VG_(redir_add_ifunc_target) in m_redir.c */
101 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__ADD_IFUNC_TARGET
,
102 fn
.nraddr
, fnentry
, 0, 0, 0);
103 return (void*)result
;
106 #elif defined(VGO_darwin)
108 #include "config.h" /* VERSION */
110 /* ---------------------------------------------------------------------
111 Darwin crash log hints
112 ------------------------------------------------------------------ */
114 /* This string will be inserted into crash logs, so crashes while
115 running under Valgrind can be distinguished from other crashes. */
116 __private_extern__
const char *__crashreporter_info__
= "Instrumented by Valgrind " VERSION
;
118 /* ---------------------------------------------------------------------
119 Darwin environment cleanup
120 ------------------------------------------------------------------ */
122 /* Scrubbing DYLD_INSERT_LIBRARIES from envp during exec is insufficient,
123 as there are other ways to launch a process with environment that
124 valgrind can't catch easily (i.e. launchd).
125 Instead, scrub DYLD_INSERT_LIBRARIES from the parent process once
126 dyld is done loading vg_preload.so.
129 #include <crt_externs.h>
131 // GrP fixme copied from m_libcproc
132 static void env_unsetenv ( HChar
**env
, const HChar
*varname
)
136 Int len
= strlen(varname
);
138 for (from
= to
= env
; from
&& *from
; from
++) {
139 if (!(strncmp(varname
, *from
, len
) == 0 && (*from
)[len
] == '=')) {
145 /* fix the 4th "char* apple" pointer (aka. executable path pointer) */
150 static void vg_cleanup_env(void) __attribute__((constructor
));
151 static void vg_cleanup_env(void)
153 HChar
**envp
= (HChar
**)*_NSGetEnviron();
154 env_unsetenv(envp
, "VALGRIND_LAUNCHER");
155 env_unsetenv(envp
, "DYLD_SHARED_REGION");
156 // GrP fixme should be more like mash_colon_env()
157 env_unsetenv(envp
, "DYLD_INSERT_LIBRARIES");
160 /* ---------------------------------------------------------------------
161 Darwin arc4random (rdar://6166275)
162 ------------------------------------------------------------------ */
167 int VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib
, arc4random
)(void);
168 int VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib
, arc4random
)(void)
173 if (rnd
< 0) rnd
= open("/dev/random", O_RDONLY
);
175 read(rnd
, &result
, sizeof(result
));
179 void VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib
, arc4random_stir
)(void);
180 void VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib
, arc4random_stir
)(void)
185 void VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib
, arc4random_addrandom
)(unsigned char *dat
, int datlen
);
186 void VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib
, arc4random_addrandom
)(unsigned char *dat
, int datlen
)
189 // GrP fixme ought to check [dat..dat+datlen) is defined
190 // but don't care if it's initialized
198 /*--------------------------------------------------------------------*/
200 /*--------------------------------------------------------------------*/