Bug 338445 amd64 vbit-test fails with unknown opcodes used by arm64 VEX.
[valgrind.git] / coregrind / vg_preloaded.c
blob775f8b2c151626f2a2dad60a278ac281acb98a31
2 /*--------------------------------------------------------------------*/
3 /*--- Client-space code for the core. vg_preloaded.c ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2000-2013 Julian Seward
11 jseward@acm.org
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
26 02111-1307, USA.
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);
63 __libc_freeres();
64 # endif
65 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LIBC_FREERES_DONE,
66 0, 0, 0, 0, 0);
67 /*NOTREACHED*/
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)
78 OrigFn fn;
79 Addr result = 0;
80 Addr fnentry;
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
89 from this function.
90 result points to the function descriptor, which starts with the
91 function entry. */
92 fnentry = *(Addr*)result;
93 #else
94 fnentry = result;
95 #endif
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.
128 #include <string.h>
129 #include <crt_externs.h>
131 // GrP fixme copied from m_libcproc
132 static void env_unsetenv ( HChar **env, const HChar *varname )
134 HChar **from;
135 HChar **to = NULL;
136 Int len = strlen(varname);
138 for (from = to = env; from && *from; from++) {
139 if (!(strncmp(varname, *from, len) == 0 && (*from)[len] == '=')) {
140 *to = *from;
141 to++;
144 *(to++) = *(from++);
145 /* fix the 4th "char* apple" pointer (aka. executable path pointer) */
146 *(to++) = *(from++);
147 *to = NULL;
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 ------------------------------------------------------------------ */
164 #include <fcntl.h>
165 #include <unistd.h>
167 int VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib, arc4random)(void);
168 int VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib, arc4random)(void)
170 static int rnd = -1;
171 int result;
173 if (rnd < 0) rnd = open("/dev/random", O_RDONLY);
175 read(rnd, &result, sizeof(result));
176 return result;
179 void VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib, arc4random_stir)(void);
180 void VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib, arc4random_stir)(void)
182 // do nothing
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)
188 // do nothing
189 // GrP fixme ought to check [dat..dat+datlen) is defined
190 // but don't care if it's initialized
193 #else
195 # error Unknown OS
196 #endif
198 /*--------------------------------------------------------------------*/
199 /*--- end ---*/
200 /*--------------------------------------------------------------------*/