1
2/*--------------------------------------------------------------------*/
3/*--- Client-space code for the core.               vg_preloaded.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2000-2011 Julian Seward
11      jseward@acm.org
12
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.
17
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.
22
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.
27
28   The GNU General Public License is contained in the file COPYING.
29*/
30
31
32/* ---------------------------------------------------------------------
33   ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
34
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.
39
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   ------------------------------------------------------------------ */
44
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
49
50#if defined(VGO_linux)
51
52/* ---------------------------------------------------------------------
53   Hook for running __libc_freeres once the program exits.
54   ------------------------------------------------------------------ */
55
56void VG_NOTIFY_ON_LOAD(freeres)( void );
57void VG_NOTIFY_ON_LOAD(freeres)( void )
58{
59#  if !defined(__UCLIBC__) && !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
60
61   extern void __libc_freeres(void);
62   __libc_freeres();
63#  endif
64   VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LIBC_FREERES_DONE,
65                                   0, 0, 0, 0, 0);
66   /*NOTREACHED*/
67   *(volatile int *)0 = 'x';
68}
69
70/* ---------------------------------------------------------------------
71   Wrapper for indirect functions which need to be redirected.
72   ------------------------------------------------------------------ */
73
74void * VG_NOTIFY_ON_LOAD(ifunc_wrapper) (void);
75void * VG_NOTIFY_ON_LOAD(ifunc_wrapper) (void)
76{
77    OrigFn fn;
78    Addr result = 0;
79
80    /* Call the original indirect function and get it's result */
81    VALGRIND_GET_ORIG_FN(fn);
82    CALL_FN_W_v(result, fn);
83
84    /* Ask the valgrind core running on the real CPU (as opposed to this
85       code which runs on the emulated CPU) to update the redirection that
86       led to this function. This client request eventually gives control to
87       the function VG_(redir_add_ifunc_target) in m_redir.c  */
88    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__ADD_IFUNC_TARGET,
89                                    fn.nraddr, result, 0, 0, 0);
90    return (void*)result;
91}
92
93#elif defined(VGO_darwin)
94
95#include "config.h" /* VERSION */
96
97/* ---------------------------------------------------------------------
98   Darwin crash log hints
99   ------------------------------------------------------------------ */
100
101/* This string will be inserted into crash logs, so crashes while
102   running under Valgrind can be distinguished from other crashes. */
103__private_extern__ char *__crashreporter_info__ = "Instrumented by Valgrind " VERSION;
104
105/* ---------------------------------------------------------------------
106   Darwin environment cleanup
107   ------------------------------------------------------------------ */
108
109/* Scrubbing DYLD_INSERT_LIBRARIES from envp during exec is insufficient,
110   as there are other ways to launch a process with environment that
111   valgrind can't catch easily (i.e. launchd).
112   Instead, scrub DYLD_INSERT_LIBRARIES from the parent process once
113   dyld is done loading vg_preload.so.
114*/
115#include <string.h>
116#include <crt_externs.h>
117
118// GrP fixme copied from m_libcproc
119static void env_unsetenv ( Char **env, const Char *varname )
120{
121   Char **from;
122   Char **to = NULL;
123   Int len = strlen(varname);
124
125   for (from = to = env; from && *from; from++) {
126      if (!(strncmp(varname, *from, len) == 0 && (*from)[len] == '=')) {
127	 *to = *from;
128	 to++;
129      }
130   }
131   *(to++) = *(from++);
132   /* fix the 4th "char* apple" pointer (aka. executable path pointer) */
133   *(to++) = *(from++);
134   *to = NULL;
135}
136
137static void vg_cleanup_env(void)  __attribute__((constructor));
138static void vg_cleanup_env(void)
139{
140    Char **envp = (Char**)*_NSGetEnviron();
141    env_unsetenv(envp, "VALGRIND_LAUNCHER");
142    env_unsetenv(envp, "DYLD_SHARED_REGION");
143    // GrP fixme should be more like mash_colon_env()
144    env_unsetenv(envp, "DYLD_INSERT_LIBRARIES");
145}
146
147/* ---------------------------------------------------------------------
148   Darwin arc4random (rdar://6166275)
149   ------------------------------------------------------------------ */
150
151#include <fcntl.h>
152#include <unistd.h>
153
154int VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib, arc4random)(void);
155int VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib, arc4random)(void)
156{
157    static int rnd = -1;
158    int result;
159
160    if (rnd < 0) rnd = open("/dev/random", O_RDONLY);
161
162    read(rnd, &result, sizeof(result));
163    return result;
164}
165
166void VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib, arc4random_stir)(void);
167void VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib, arc4random_stir)(void)
168{
169    // do nothing
170}
171
172void VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib, arc4random_addrandom)(unsigned char *dat, int datlen);
173void VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib, arc4random_addrandom)(unsigned char *dat, int datlen)
174{
175    // do nothing
176    // GrP fixme ought to check [dat..dat+datlen) is defined
177    // but don't care if it's initialized
178}
179
180#else
181
182#  error Unknown OS
183#endif
184
185/*--------------------------------------------------------------------*/
186/*--- end                                                          ---*/
187/*--------------------------------------------------------------------*/
188