blob: 7c7f61219e3b082a7470ce831f7db534117fa01f [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
3/*--- C startup stuff, reached from vg_startup.S. ---*/
4/*--- vg_main.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, an x86 protected-mode emulator
9 designed for debugging and profiling binaries on x86-Unixes.
10
11 Copyright (C) 2000-2002 Julian Seward
12 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000013
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file LICENSE.
30*/
31
32#include "vg_include.h"
33#include "vg_constants.h"
sewardjde4a1d02002-03-22 01:27:54 +000034
35
36/* ---------------------------------------------------------------------
37 Compute offsets into baseBlock. See comments in vg_include.h.
38 ------------------------------------------------------------------ */
39
40/* The variables storing offsets. */
41
42#define INVALID_OFFSET (-1)
43
44Int VGOFF_(m_eax) = INVALID_OFFSET;
45Int VGOFF_(m_ecx) = INVALID_OFFSET;
46Int VGOFF_(m_edx) = INVALID_OFFSET;
47Int VGOFF_(m_ebx) = INVALID_OFFSET;
48Int VGOFF_(m_esp) = INVALID_OFFSET;
49Int VGOFF_(m_ebp) = INVALID_OFFSET;
50Int VGOFF_(m_esi) = INVALID_OFFSET;
51Int VGOFF_(m_edi) = INVALID_OFFSET;
52Int VGOFF_(m_eflags) = INVALID_OFFSET;
53Int VGOFF_(m_fpustate) = INVALID_OFFSET;
54Int VGOFF_(m_eip) = INVALID_OFFSET;
55Int VGOFF_(spillslots) = INVALID_OFFSET;
56Int VGOFF_(sh_eax) = INVALID_OFFSET;
57Int VGOFF_(sh_ecx) = INVALID_OFFSET;
58Int VGOFF_(sh_edx) = INVALID_OFFSET;
59Int VGOFF_(sh_ebx) = INVALID_OFFSET;
60Int VGOFF_(sh_esp) = INVALID_OFFSET;
61Int VGOFF_(sh_ebp) = INVALID_OFFSET;
62Int VGOFF_(sh_esi) = INVALID_OFFSET;
63Int VGOFF_(sh_edi) = INVALID_OFFSET;
64Int VGOFF_(sh_eflags) = INVALID_OFFSET;
65Int VGOFF_(helper_idiv_64_32) = INVALID_OFFSET;
66Int VGOFF_(helper_div_64_32) = INVALID_OFFSET;
67Int VGOFF_(helper_idiv_32_16) = INVALID_OFFSET;
68Int VGOFF_(helper_div_32_16) = INVALID_OFFSET;
69Int VGOFF_(helper_idiv_16_8) = INVALID_OFFSET;
70Int VGOFF_(helper_div_16_8) = INVALID_OFFSET;
71Int VGOFF_(helper_imul_32_64) = INVALID_OFFSET;
72Int VGOFF_(helper_mul_32_64) = INVALID_OFFSET;
73Int VGOFF_(helper_imul_16_32) = INVALID_OFFSET;
74Int VGOFF_(helper_mul_16_32) = INVALID_OFFSET;
75Int VGOFF_(helper_imul_8_16) = INVALID_OFFSET;
76Int VGOFF_(helper_mul_8_16) = INVALID_OFFSET;
77Int VGOFF_(helper_CLD) = INVALID_OFFSET;
78Int VGOFF_(helper_STD) = INVALID_OFFSET;
79Int VGOFF_(helper_get_dirflag) = INVALID_OFFSET;
80Int VGOFF_(helper_shldl) = INVALID_OFFSET;
81Int VGOFF_(helper_shldw) = INVALID_OFFSET;
82Int VGOFF_(helper_shrdl) = INVALID_OFFSET;
83Int VGOFF_(helper_shrdw) = INVALID_OFFSET;
84Int VGOFF_(helper_RDTSC) = INVALID_OFFSET;
85Int VGOFF_(helper_CPUID) = INVALID_OFFSET;
86Int VGOFF_(helper_BSWAP) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000087Int VGOFF_(helper_bsf) = INVALID_OFFSET;
88Int VGOFF_(helper_bsr) = INVALID_OFFSET;
89Int VGOFF_(helper_fstsw_AX) = INVALID_OFFSET;
90Int VGOFF_(helper_SAHF) = INVALID_OFFSET;
sewardj4d0ab1f2002-03-24 10:00:09 +000091Int VGOFF_(helper_DAS) = INVALID_OFFSET;
sewardjfe8a1662002-03-24 11:54:07 +000092Int VGOFF_(helper_DAA) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000093Int VGOFF_(helper_value_check4_fail) = INVALID_OFFSET;
94Int VGOFF_(helper_value_check2_fail) = INVALID_OFFSET;
95Int VGOFF_(helper_value_check1_fail) = INVALID_OFFSET;
96Int VGOFF_(helper_value_check0_fail) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000097Int VGOFF_(helperc_LOADV4) = INVALID_OFFSET;
98Int VGOFF_(helperc_LOADV2) = INVALID_OFFSET;
99Int VGOFF_(helperc_LOADV1) = INVALID_OFFSET;
100Int VGOFF_(helperc_STOREV4) = INVALID_OFFSET;
101Int VGOFF_(helperc_STOREV2) = INVALID_OFFSET;
102Int VGOFF_(helperc_STOREV1) = INVALID_OFFSET;
103Int VGOFF_(handle_esp_assignment) = INVALID_OFFSET;
104Int VGOFF_(fpu_write_check) = INVALID_OFFSET;
105Int VGOFF_(fpu_read_check) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +0000106
107
108/* This is the actual defn of baseblock. */
109UInt VG_(baseBlock)[VG_BASEBLOCK_WORDS];
110
111/* Words. */
112static Int baB_off = 0;
113
114/* Returns the offset, in words. */
115static Int alloc_BaB ( Int words )
116{
117 Int off = baB_off;
118 baB_off += words;
119 if (baB_off >= VG_BASEBLOCK_WORDS)
120 VG_(panic)( "alloc_BaB: baseBlock is too small");
121
122 return off;
123}
124
125/* Allocate 1 word in baseBlock and set it to the given value. */
126static Int alloc_BaB_1_set ( Addr a )
127{
128 Int off = alloc_BaB(1);
129 VG_(baseBlock)[off] = (UInt)a;
130 return off;
131}
132
133
134/* Here we assign actual offsets. It's important to get the most
135 popular referents within 128 bytes of the start, so we can take
136 advantage of short addressing modes relative to %ebp. Popularity
137 of offsets was measured on 22 Feb 02 running a KDE application, and
138 the slots rearranged accordingly, with a 1.5% reduction in total
139 size of translations. */
140
141static void vg_init_baseBlock ( void )
142{
143 baB_off = 0;
144
145 /* Those with offsets under 128 are carefully chosen. */
146
147 /* WORD offsets in this column */
148 /* 0 */ VGOFF_(m_eax) = alloc_BaB(1);
149 /* 1 */ VGOFF_(m_ecx) = alloc_BaB(1);
150 /* 2 */ VGOFF_(m_edx) = alloc_BaB(1);
151 /* 3 */ VGOFF_(m_ebx) = alloc_BaB(1);
152 /* 4 */ VGOFF_(m_esp) = alloc_BaB(1);
153 /* 5 */ VGOFF_(m_ebp) = alloc_BaB(1);
154 /* 6 */ VGOFF_(m_esi) = alloc_BaB(1);
155 /* 7 */ VGOFF_(m_edi) = alloc_BaB(1);
156 /* 8 */ VGOFF_(m_eflags) = alloc_BaB(1);
157
158 /* 9 */ VGOFF_(sh_eax) = alloc_BaB(1);
159 /* 10 */ VGOFF_(sh_ecx) = alloc_BaB(1);
160 /* 11 */ VGOFF_(sh_edx) = alloc_BaB(1);
161 /* 12 */ VGOFF_(sh_ebx) = alloc_BaB(1);
162 /* 13 */ VGOFF_(sh_esp) = alloc_BaB(1);
163 /* 14 */ VGOFF_(sh_ebp) = alloc_BaB(1);
164 /* 15 */ VGOFF_(sh_esi) = alloc_BaB(1);
165 /* 16 */ VGOFF_(sh_edi) = alloc_BaB(1);
166 /* 17 */ VGOFF_(sh_eflags) = alloc_BaB(1);
167
168 /* 18 */
169 VGOFF_(helper_value_check4_fail)
170 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check4_fail) );
171 /* 19 */
172 VGOFF_(helper_value_check0_fail)
173 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check0_fail) );
174
175 /* 20 */
176 VGOFF_(helperc_STOREV4)
177 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV4) );
178 /* 21 */
179 VGOFF_(helperc_STOREV1)
180 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV1) );
181
182 /* 22 */
183 VGOFF_(helperc_LOADV4)
184 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV4) );
185 /* 23 */
186 VGOFF_(helperc_LOADV1)
187 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV1) );
188
189 /* 24 */
190 VGOFF_(handle_esp_assignment)
191 = alloc_BaB_1_set( (Addr) & VGM_(handle_esp_assignment) );
192
193 /* 25 */
194 VGOFF_(m_eip) = alloc_BaB(1);
195
196 /* There are currently 24 spill slots */
197 /* 26 .. 49 This overlaps the magic boundary at >= 32 words, but
198 most spills are to low numbered spill slots, so the ones above
199 the boundary don't see much action. */
200 VGOFF_(spillslots) = alloc_BaB(VG_MAX_SPILLSLOTS);
201
202 /* These two pushed beyond the boundary because 2-byte transactions
203 are rare. */
204 /* 50 */
205 VGOFF_(helperc_STOREV2)
206 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV2) );
207 /* 51 */
208 VGOFF_(helperc_LOADV2)
209 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV2) );
210
211 /* 52 */
212 VGOFF_(fpu_write_check)
213 = alloc_BaB_1_set( (Addr) & VGM_(fpu_write_check) );
214 /* 53 */
215 VGOFF_(fpu_read_check)
216 = alloc_BaB_1_set( (Addr) & VGM_(fpu_read_check) );
217
218 /* Actually I don't think these two are ever used. */
219 /* 54 */
220 VGOFF_(helper_value_check2_fail)
221 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check2_fail) );
222 /* 55 */
223 VGOFF_(helper_value_check1_fail)
224 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check1_fail) );
225
226 /* I gave up counting at this point. Since they're way above the
227 short-amode-boundary, there's no point. */
228
229 VGOFF_(m_fpustate) = alloc_BaB(VG_SIZE_OF_FPUSTATE_W);
230
231 VGOFF_(helper_idiv_64_32)
232 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_64_32) );
233 VGOFF_(helper_div_64_32)
234 = alloc_BaB_1_set( (Addr) & VG_(helper_div_64_32) );
235 VGOFF_(helper_idiv_32_16)
236 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_32_16) );
237 VGOFF_(helper_div_32_16)
238 = alloc_BaB_1_set( (Addr) & VG_(helper_div_32_16) );
239 VGOFF_(helper_idiv_16_8)
240 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_16_8) );
241 VGOFF_(helper_div_16_8)
242 = alloc_BaB_1_set( (Addr) & VG_(helper_div_16_8) );
243
244 VGOFF_(helper_imul_32_64)
245 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_32_64) );
246 VGOFF_(helper_mul_32_64)
247 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_32_64) );
248 VGOFF_(helper_imul_16_32)
249 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_16_32) );
250 VGOFF_(helper_mul_16_32)
251 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_16_32) );
252 VGOFF_(helper_imul_8_16)
253 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_8_16) );
254 VGOFF_(helper_mul_8_16)
255 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_8_16) );
256
257 VGOFF_(helper_CLD)
258 = alloc_BaB_1_set( (Addr) & VG_(helper_CLD) );
259 VGOFF_(helper_STD)
260 = alloc_BaB_1_set( (Addr) & VG_(helper_STD) );
261 VGOFF_(helper_get_dirflag)
262 = alloc_BaB_1_set( (Addr) & VG_(helper_get_dirflag) );
263
264 VGOFF_(helper_shldl)
265 = alloc_BaB_1_set( (Addr) & VG_(helper_shldl) );
266 VGOFF_(helper_shldw)
267 = alloc_BaB_1_set( (Addr) & VG_(helper_shldw) );
268 VGOFF_(helper_shrdl)
269 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdl) );
270 VGOFF_(helper_shrdw)
271 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdw) );
272
273 VGOFF_(helper_RDTSC)
274 = alloc_BaB_1_set( (Addr) & VG_(helper_RDTSC) );
275 VGOFF_(helper_CPUID)
276 = alloc_BaB_1_set( (Addr) & VG_(helper_CPUID) );
277
sewardjde4a1d02002-03-22 01:27:54 +0000278 VGOFF_(helper_bsf)
279 = alloc_BaB_1_set( (Addr) & VG_(helper_bsf) );
280 VGOFF_(helper_bsr)
281 = alloc_BaB_1_set( (Addr) & VG_(helper_bsr) );
282
283 VGOFF_(helper_fstsw_AX)
284 = alloc_BaB_1_set( (Addr) & VG_(helper_fstsw_AX) );
285 VGOFF_(helper_SAHF)
286 = alloc_BaB_1_set( (Addr) & VG_(helper_SAHF) );
sewardj4d0ab1f2002-03-24 10:00:09 +0000287 VGOFF_(helper_DAS)
288 = alloc_BaB_1_set( (Addr) & VG_(helper_DAS) );
sewardjfe8a1662002-03-24 11:54:07 +0000289 VGOFF_(helper_DAA)
290 = alloc_BaB_1_set( (Addr) & VG_(helper_DAA) );
sewardjde4a1d02002-03-22 01:27:54 +0000291}
292
293
294/* ---------------------------------------------------------------------
295 Global entities which are not referenced from generated code.
296 ------------------------------------------------------------------ */
297
298/* The stack on which Valgrind runs. We can't use the same stack as
299 the simulatee -- that's an important design decision. */
300UInt VG_(stack)[10000];
301
302/* Ditto our signal delivery stack. */
303UInt VG_(sigstack)[10000];
304
305/* Saving stuff across system calls. */
306UInt VG_(real_fpu_state_saved_over_syscall_d1)[VG_SIZE_OF_FPUSTATE_W];
307UInt VG_(real_fpu_state_saved_over_syscall_d2)[VG_SIZE_OF_FPUSTATE_W];
308Addr VG_(esp_saved_over_syscall_d1);
309Addr VG_(esp_saved_over_syscall_d2);
310
311/* Counts downwards in vg_run_innerloop. */
312UInt VG_(dispatch_ctr);
313
sewardjde4a1d02002-03-22 01:27:54 +0000314
315/* 64-bit counter for the number of basic blocks done. */
316ULong VG_(bbs_done);
317/* 64-bit counter for the number of bbs to go before a debug exit. */
318ULong VG_(bbs_to_go);
319
320/* Produce debugging output? */
321Bool VG_(disassemble) = False;
322
323/* The current LRU epoch. */
324UInt VG_(current_epoch) = 0;
325
326
327/* ---------------------------------------------------------------------
328 Counters, for informational purposes only.
329 ------------------------------------------------------------------ */
330
331/* Number of lookups which miss the fast tt helper. */
332UInt VG_(tt_fast_misses) = 0;
333
334
335/* Counts for LRU informational messages. */
336
337/* Number and total o/t size of new translations this epoch. */
338UInt VG_(this_epoch_in_count) = 0;
339UInt VG_(this_epoch_in_osize) = 0;
340UInt VG_(this_epoch_in_tsize) = 0;
341/* Number and total o/t size of discarded translations this epoch. */
342UInt VG_(this_epoch_out_count) = 0;
343UInt VG_(this_epoch_out_osize) = 0;
344UInt VG_(this_epoch_out_tsize) = 0;
345/* Number and total o/t size of translations overall. */
346UInt VG_(overall_in_count) = 0;
347UInt VG_(overall_in_osize) = 0;
348UInt VG_(overall_in_tsize) = 0;
349/* Number and total o/t size of discards overall. */
350UInt VG_(overall_out_count) = 0;
351UInt VG_(overall_out_osize) = 0;
352UInt VG_(overall_out_tsize) = 0;
353
354/* The number of LRU-clearings of TT/TC. */
355UInt VG_(number_of_lrus) = 0;
356
357
358/* Counts pertaining to the register allocator. */
359
360/* total number of uinstrs input to reg-alloc */
361UInt VG_(uinstrs_prealloc) = 0;
362
363/* total number of uinstrs added due to spill code */
364UInt VG_(uinstrs_spill) = 0;
365
366/* number of bbs requiring spill code */
367UInt VG_(translations_needing_spill) = 0;
368
369/* total of register ranks over all translations */
370UInt VG_(total_reg_rank) = 0;
371
372
373/* Counts pertaining to the self-modifying-code detection machinery. */
374
375/* Total number of writes checked. */
376UInt VG_(smc_total_check4s) = 0;
377
378/* Number of writes which the fast smc check couldn't show were
379 harmless. */
380UInt VG_(smc_cache_passed) = 0;
381
382/* Numnber of writes which really did write on original code. */
383UInt VG_(smc_fancy_passed) = 0;
384
385/* Number of translations discarded as a result. */
386UInt VG_(smc_discard_count) = 0;
387
388
389/* Counts pertaining to internal sanity checking. */
sewardjde4a1d02002-03-22 01:27:54 +0000390UInt VG_(sanity_fast_count) = 0;
391UInt VG_(sanity_slow_count) = 0;
392
sewardj2e93c502002-04-12 11:12:52 +0000393/* Counts pertaining to the scheduler. */
394UInt VG_(num_scheduling_events_MINOR) = 0;
395UInt VG_(num_scheduling_events_MAJOR) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000396
397
398/* ---------------------------------------------------------------------
399 Values derived from command-line options.
400 ------------------------------------------------------------------ */
401
sewardj97ced732002-03-25 00:07:36 +0000402Bool VG_(clo_check_addrVs);
sewardjde4a1d02002-03-22 01:27:54 +0000403Bool VG_(clo_GDB_attach);
404Int VG_(sanity_level);
405Int VG_(clo_verbosity);
406Bool VG_(clo_demangle);
407Bool VG_(clo_leak_check);
408Bool VG_(clo_show_reachable);
409Int VG_(clo_leak_resolution);
410Bool VG_(clo_sloppy_malloc);
411Bool VG_(clo_partial_loads_ok);
412Bool VG_(clo_trace_children);
413Int VG_(clo_logfile_fd);
414Int VG_(clo_freelist_vol);
415Bool VG_(clo_workaround_gcc296_bugs);
416Int VG_(clo_n_suppressions);
417Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
418Bool VG_(clo_single_step);
419Bool VG_(clo_optimise);
420Bool VG_(clo_instrument);
421Bool VG_(clo_cleanup);
sewardjde4a1d02002-03-22 01:27:54 +0000422Int VG_(clo_smc_check);
423Bool VG_(clo_trace_syscalls);
424Bool VG_(clo_trace_signals);
425Bool VG_(clo_trace_symtab);
426Bool VG_(clo_trace_malloc);
sewardj8937c812002-04-12 20:12:20 +0000427Bool VG_(clo_trace_sched);
sewardj45b4b372002-04-16 22:50:32 +0000428Int VG_(clo_trace_pthread_level);
sewardjde4a1d02002-03-22 01:27:54 +0000429ULong VG_(clo_stop_after);
430Int VG_(clo_dump_error);
431Int VG_(clo_backtrace_size);
432
433/* This Bool is needed by wrappers in vg_clientmalloc.c to decide how
434 to behave. Initially we say False. */
435Bool VG_(running_on_simd_CPU) = False;
436
437/* Holds client's %esp at the point we gained control. */
438Addr VG_(esp_at_startup);
439
440/* As deduced from VG_(esp_at_startup), the client's argc, argv[] and
441 envp[] as extracted from the client's stack at startup-time. */
442Int VG_(client_argc);
443Char** VG_(client_argv);
444Char** VG_(client_envp);
445
446/* A place into which to copy the value of env var VG_ARGS, so we
447 don't have to modify the original. */
448static Char vg_cmdline_copy[M_VG_CMDLINE_STRLEN];
449
450
451/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000452 Processing of command-line options.
453 ------------------------------------------------------------------ */
454
455static void bad_option ( Char* opt )
456{
457 VG_(shutdown_logging)();
458 VG_(clo_logfile_fd) = 2; /* stderr */
459 VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
460 VG_(exit)(1);
461}
462
463static void config_error ( Char* msg )
464{
465 VG_(shutdown_logging)();
466 VG_(clo_logfile_fd) = 2; /* stderr */
467 VG_(printf)("valgrind.so: Startup or configuration error:\n\t%s\n", msg);
468 VG_(printf)("valgrind.so: Unable to start up properly. Giving up.\n");
469 VG_(exit)(1);
470}
471
472
473static void process_cmd_line_options ( void )
474{
475 UChar* argv[M_VG_CMDLINE_OPTS];
476 UInt argc;
477 UChar* p;
478 UChar* str;
479 Int i, eventually_logfile_fd;
480
481# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
482# define STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2)))
483# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
484
485 /* Set defaults. */
sewardj97ced732002-03-25 00:07:36 +0000486 VG_(clo_check_addrVs) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000487 VG_(clo_GDB_attach) = False;
488 VG_(sanity_level) = 1;
489 VG_(clo_verbosity) = 1;
490 VG_(clo_demangle) = True;
491 VG_(clo_leak_check) = False;
492 VG_(clo_show_reachable) = False;
493 VG_(clo_leak_resolution) = 2;
494 VG_(clo_sloppy_malloc) = False;
495 VG_(clo_partial_loads_ok) = True;
496 VG_(clo_trace_children) = False;
497 VG_(clo_logfile_fd) = 2; /* stderr */
498 VG_(clo_freelist_vol) = 1000000;
499 VG_(clo_workaround_gcc296_bugs) = False;
500 VG_(clo_n_suppressions) = 0;
501 VG_(clo_single_step) = False;
502 VG_(clo_optimise) = True;
503 VG_(clo_instrument) = True;
504 VG_(clo_cleanup) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000505 VG_(clo_smc_check) = /* VG_CLO_SMC_SOME */ VG_CLO_SMC_NONE;
506 VG_(clo_trace_syscalls) = False;
507 VG_(clo_trace_signals) = False;
508 VG_(clo_trace_symtab) = False;
509 VG_(clo_trace_malloc) = False;
sewardj8937c812002-04-12 20:12:20 +0000510 VG_(clo_trace_sched) = False;
sewardj45b4b372002-04-16 22:50:32 +0000511 VG_(clo_trace_pthread_level) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000512 VG_(clo_stop_after) = 1000000000000LL;
513 VG_(clo_dump_error) = 0;
514 VG_(clo_backtrace_size) = 4;
515
516 eventually_logfile_fd = VG_(clo_logfile_fd);
517
518 /* Once logging is started, we can safely send messages pertaining
519 to failures in initialisation. */
520 VG_(startup_logging)();
521
522 /* Magically find the client's argc/argv/envp. This kludge is
523 entirely dependent on the stack layout imposed by libc at
524 startup. Hence the magic offsets. Then check (heuristically)
525 that the results are plausible. There must be a better way to
526 do this ... */
527
528# if 0
529 /* Use this to search for the correct offsets if the tests below
530 barf. */
531 { Int i;
532 VG_(printf)("startup %%esp is %p\n", VG_(esp_at_startup) );
533 for (i = 0; i < 10; i++) {
534 Char* p = ((Char**)VG_(esp_at_startup))[i];
535 VG_(printf)("%d: %p\n", i, p);
536 }
537 }
538# endif
539
sewardja88ebf62002-03-24 12:22:39 +0000540# if defined(GLIBC_2_2)
sewardjde4a1d02002-03-22 01:27:54 +0000541 /* These offsets (5,6,7) are right for my RedHat 7.2 (glibc-2.2.4)
542 box. */
543
544 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [5] );
545 VG_(client_argv) = (Char**)( ((void**)VG_(esp_at_startup)) [6] );
546 VG_(client_envp) = (Char**)( ((void**)VG_(esp_at_startup)) [7] );
547
548 if ( ((UInt)VG_(client_argc)) > 0 &&
549 ((UInt)VG_(client_argc)) < 10000 &&
550 (Addr)VG_(client_argv) >= 0x8000000 &&
551 (Addr)VG_(client_envp) >= 0x8000000)
552 goto argc_argv_envp_OK;
553
554 /* If that's no good, try some other offsets discovered by KDE
555 folks on 8 Feb 02:
556 For glibc > 2.2.4 the offset 9/10/11 did the trick. Coolo found
557 out those, on I think a Caldera 3.1 with glibc 2.2.4 -- the same
558 offsets worked for on a debian sid with glibc 2.2.5. */
559
560 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [9] );
561 VG_(client_argv) = (Char**)( ((void**)VG_(esp_at_startup)) [10] );
562 VG_(client_envp) = (Char**)( ((void**)VG_(esp_at_startup)) [11] );
563
564 if ( ((UInt)VG_(client_argc)) > 0 &&
565 ((UInt)VG_(client_argc)) < 10000 &&
566 (Addr)VG_(client_argv) >= 0x8000000 &&
567 (Addr)VG_(client_envp) >= 0x8000000)
568 goto argc_argv_envp_OK;
569
sewardja88ebf62002-03-24 12:22:39 +0000570# endif /* defined(GLIBC_2_2) */
571
572# if defined(GLIBC_2_1)
sewardjde4a1d02002-03-22 01:27:54 +0000573 /* Doesn't look promising. Try offsets for RedHat 6.2
574 (glibc-2.1.3) instead. In this case, the argv and envp vectors
575 are actually on the stack (bizarrely). */
576
577 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [4] );
578 VG_(client_argv) = (Char**) & ( ((void**)VG_(esp_at_startup)) [5] );
579 VG_(client_envp)
580 = (Char**) & ( ((void**)VG_(esp_at_startup)) [6 + VG_(client_argc)] );
581
582 if ( ((UInt)VG_(client_argc)) > 0 &&
583 ((UInt)VG_(client_argc)) < 10000 &&
584 (Addr)VG_(client_argv) >= 0x8000000 &&
585 (Addr)VG_(client_envp) >= 0x8000000)
586 goto argc_argv_envp_OK;
587
588 /* Here's yet another variant, from <hansen> (irc.kde.org). */
589
590 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [9] );
591 VG_(client_argv) = (Char**) & ( ((void**)VG_(esp_at_startup)) [10] );
592 VG_(client_envp)
593 = (Char**) & ( ((void**)VG_(esp_at_startup)) [11 + VG_(client_argc)] );
594
595 if ( ((UInt)VG_(client_argc)) > 0 &&
596 ((UInt)VG_(client_argc)) < 10000 &&
597 (Addr)VG_(client_argv) >= 0x8000000 &&
598 (Addr)VG_(client_envp) >= 0x8000000)
599 goto argc_argv_envp_OK;
sewardja88ebf62002-03-24 12:22:39 +0000600# endif /* defined(GLIBC_2_1) */
601
602# if !defined(GLIBC_2_2) && !defined(GLIBC_2_1)
603 config_error("autoconf/configure detected neither glibc 2.1.X nor 2.2.X");
604# endif
sewardjde4a1d02002-03-22 01:27:54 +0000605
606 /* VG_(printf)("%d %p %p\n", VG_(client_argc), VG_(client_argv),
607 VG_(client_envp));
608 */
609 /* We're hosed. Give up :-( */
610 config_error(
611 "Can't get plausible values for client's argc/argv/envp.\n\t"
612 "You may be able to fix this; see process_cmd_line_options()\n\t"
613 "in vg_main.c"
614 );
615 /* NOTREACHED */
616
617 argc_argv_envp_OK:
618
619 /* Now that VG_(client_envp) has been set, we can extract the args
620 for Valgrind itself. Copy into global var so that we don't have to
621 write zeroes to the getenv'd value itself. */
622 str = VG_(getenv)("VG_ARGS");
623 argc = 0;
624
625 if (!str) {
626 config_error("Can't read options from env var VG_ARGS.");
627 }
628
629 if (VG_(strlen)(str) >= M_VG_CMDLINE_STRLEN-1) {
630 config_error("Command line length exceeds M_CMDLINE_STRLEN.");
631 }
632 VG_(strcpy)(vg_cmdline_copy, str);
633 str = NULL;
634
635 p = &vg_cmdline_copy[0];
636 while (True) {
637 while (ISSPACE(*p)) { *p = 0; p++; }
638 if (*p == 0) break;
639 if (argc < M_VG_CMDLINE_OPTS-1) {
640 argv[argc] = p; argc++;
641 } else {
642 config_error(
643 "Found more than M_CMDLINE_OPTS command-line opts.");
644 }
645 while (*p != 0 && !ISSPACE(*p)) p++;
646 }
647
648 for (i = 0; i < argc; i++) {
649
650 if (STREQ(argv[i], "-v") || STREQ(argv[i], "--verbose"))
651 VG_(clo_verbosity)++;
652 else if (STREQ(argv[i], "-q") || STREQ(argv[i], "--quiet"))
653 VG_(clo_verbosity)--;
654
sewardj97ced732002-03-25 00:07:36 +0000655 else if (STREQ(argv[i], "--check-addrVs=yes"))
656 VG_(clo_check_addrVs) = True;
657 else if (STREQ(argv[i], "--check-addrVs=no"))
658 VG_(clo_check_addrVs) = False;
659
sewardjde4a1d02002-03-22 01:27:54 +0000660 else if (STREQ(argv[i], "--gdb-attach=yes"))
661 VG_(clo_GDB_attach) = True;
662 else if (STREQ(argv[i], "--gdb-attach=no"))
663 VG_(clo_GDB_attach) = False;
664
665 else if (STREQ(argv[i], "--demangle=yes"))
666 VG_(clo_demangle) = True;
667 else if (STREQ(argv[i], "--demangle=no"))
668 VG_(clo_demangle) = False;
669
670 else if (STREQ(argv[i], "--partial-loads-ok=yes"))
671 VG_(clo_partial_loads_ok) = True;
672 else if (STREQ(argv[i], "--partial-loads-ok=no"))
673 VG_(clo_partial_loads_ok) = False;
674
675 else if (STREQ(argv[i], "--leak-check=yes"))
676 VG_(clo_leak_check) = True;
677 else if (STREQ(argv[i], "--leak-check=no"))
678 VG_(clo_leak_check) = False;
679
680 else if (STREQ(argv[i], "--show-reachable=yes"))
681 VG_(clo_show_reachable) = True;
682 else if (STREQ(argv[i], "--show-reachable=no"))
683 VG_(clo_show_reachable) = False;
684
685 else if (STREQ(argv[i], "--leak-resolution=low"))
686 VG_(clo_leak_resolution) = 2;
687 else if (STREQ(argv[i], "--leak-resolution=med"))
688 VG_(clo_leak_resolution) = 4;
689 else if (STREQ(argv[i], "--leak-resolution=high"))
690 VG_(clo_leak_resolution) = VG_DEEPEST_BACKTRACE;
691
692 else if (STREQ(argv[i], "--sloppy-malloc=yes"))
693 VG_(clo_sloppy_malloc) = True;
694 else if (STREQ(argv[i], "--sloppy-malloc=no"))
695 VG_(clo_sloppy_malloc) = False;
696
697 else if (STREQ(argv[i], "--trace-children=yes"))
698 VG_(clo_trace_children) = True;
699 else if (STREQ(argv[i], "--trace-children=no"))
700 VG_(clo_trace_children) = False;
701
702 else if (STREQ(argv[i], "--workaround-gcc296-bugs=yes"))
703 VG_(clo_workaround_gcc296_bugs) = True;
704 else if (STREQ(argv[i], "--workaround-gcc296-bugs=no"))
705 VG_(clo_workaround_gcc296_bugs) = False;
706
707 else if (STREQN(15, argv[i], "--sanity-level="))
708 VG_(sanity_level) = (Int)VG_(atoll)(&argv[i][15]);
709
710 else if (STREQN(13, argv[i], "--logfile-fd="))
711 eventually_logfile_fd = (Int)VG_(atoll)(&argv[i][13]);
712
713 else if (STREQN(15, argv[i], "--freelist-vol=")) {
714 VG_(clo_freelist_vol) = (Int)VG_(atoll)(&argv[i][15]);
715 if (VG_(clo_freelist_vol) < 0) VG_(clo_freelist_vol) = 2;
716 }
717
718 else if (STREQN(15, argv[i], "--suppressions=")) {
719 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
720 VG_(message)(Vg_UserMsg, "Too many logfiles specified.");
721 VG_(message)(Vg_UserMsg,
722 "Increase VG_CLO_MAX_SFILES and recompile.");
723 bad_option(argv[i]);
724 }
725 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &argv[i][15];
726 VG_(clo_n_suppressions)++;
727 }
728 else if (STREQ(argv[i], "--single-step=yes"))
729 VG_(clo_single_step) = True;
730 else if (STREQ(argv[i], "--single-step=no"))
731 VG_(clo_single_step) = False;
732
733 else if (STREQ(argv[i], "--optimise=yes"))
734 VG_(clo_optimise) = True;
735 else if (STREQ(argv[i], "--optimise=no"))
736 VG_(clo_optimise) = False;
737
738 else if (STREQ(argv[i], "--instrument=yes"))
739 VG_(clo_instrument) = True;
740 else if (STREQ(argv[i], "--instrument=no"))
741 VG_(clo_instrument) = False;
742
743 else if (STREQ(argv[i], "--cleanup=yes"))
744 VG_(clo_cleanup) = True;
745 else if (STREQ(argv[i], "--cleanup=no"))
746 VG_(clo_cleanup) = False;
747
sewardjde4a1d02002-03-22 01:27:54 +0000748 else if (STREQ(argv[i], "--smc-check=none"))
749 VG_(clo_smc_check) = VG_CLO_SMC_NONE;
750 else if (STREQ(argv[i], "--smc-check=some"))
751 VG_(clo_smc_check) = VG_CLO_SMC_SOME;
752 else if (STREQ(argv[i], "--smc-check=all"))
753 VG_(clo_smc_check) = VG_CLO_SMC_ALL;
754
755 else if (STREQ(argv[i], "--trace-syscalls=yes"))
756 VG_(clo_trace_syscalls) = True;
757 else if (STREQ(argv[i], "--trace-syscalls=no"))
758 VG_(clo_trace_syscalls) = False;
759
760 else if (STREQ(argv[i], "--trace-signals=yes"))
761 VG_(clo_trace_signals) = True;
762 else if (STREQ(argv[i], "--trace-signals=no"))
763 VG_(clo_trace_signals) = False;
764
765 else if (STREQ(argv[i], "--trace-symtab=yes"))
766 VG_(clo_trace_symtab) = True;
767 else if (STREQ(argv[i], "--trace-symtab=no"))
768 VG_(clo_trace_symtab) = False;
769
770 else if (STREQ(argv[i], "--trace-malloc=yes"))
771 VG_(clo_trace_malloc) = True;
772 else if (STREQ(argv[i], "--trace-malloc=no"))
773 VG_(clo_trace_malloc) = False;
774
sewardj8937c812002-04-12 20:12:20 +0000775 else if (STREQ(argv[i], "--trace-sched=yes"))
776 VG_(clo_trace_sched) = True;
777 else if (STREQ(argv[i], "--trace-sched=no"))
778 VG_(clo_trace_sched) = False;
779
sewardj45b4b372002-04-16 22:50:32 +0000780 else if (STREQ(argv[i], "--trace-pthread=none"))
781 VG_(clo_trace_pthread_level) = 0;
782 else if (STREQ(argv[i], "--trace-pthread=some"))
783 VG_(clo_trace_pthread_level) = 1;
784 else if (STREQ(argv[i], "--trace-pthread=all"))
785 VG_(clo_trace_pthread_level) = 2;
sewardj8937c812002-04-12 20:12:20 +0000786
sewardjde4a1d02002-03-22 01:27:54 +0000787 else if (STREQN(13, argv[i], "--stop-after="))
788 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
789
790 else if (STREQN(13, argv[i], "--dump-error="))
791 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
792
793 else if (STREQN(14, argv[i], "--num-callers=")) {
794 /* Make sure it's sane. */
795 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
796 if (VG_(clo_backtrace_size) < 2)
797 VG_(clo_backtrace_size) = 2;
798 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
799 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
800 }
801
802 else
803 bad_option(argv[i]);
804 }
805
806# undef ISSPACE
807# undef STREQ
808# undef STREQN
809
810 if (VG_(clo_verbosity < 0))
811 VG_(clo_verbosity) = 0;
812
813 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
814 VG_(message)(Vg_UserMsg, "");
815 VG_(message)(Vg_UserMsg,
816 "--gdb-attach=yes conflicts with --trace-children=yes");
817 VG_(message)(Vg_UserMsg,
818 "Please choose one or the other, but not both.");
819 bad_option("--gdb-attach=yes and --trace-children=yes");
820 }
821
sewardjde4a1d02002-03-22 01:27:54 +0000822 VG_(clo_logfile_fd) = eventually_logfile_fd;
823
sewardjde4a1d02002-03-22 01:27:54 +0000824 if (VG_(clo_verbosity > 0))
825 VG_(message)(Vg_UserMsg,
826 "valgrind-%s, a memory error detector for x86 GNU/Linux.",
sewardj3b2736a2002-03-24 12:18:35 +0000827 VERSION);
828
sewardjde4a1d02002-03-22 01:27:54 +0000829 if (VG_(clo_verbosity > 0))
830 VG_(message)(Vg_UserMsg,
831 "Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.");
832 if (VG_(clo_verbosity) > 1) {
833 VG_(message)(Vg_UserMsg, "Startup, with flags:");
834 for (i = 0; i < argc; i++) {
835 VG_(message)(Vg_UserMsg, " %s", argv[i]);
836 }
837 }
838
839 if (VG_(clo_n_suppressions) == 0) {
840 config_error("No error-suppression files were specified.");
841 }
842}
843
844
845/* ---------------------------------------------------------------------
846 Copying to/from m_state_static.
847 ------------------------------------------------------------------ */
848
849UInt VG_(m_state_static) [8 /* int regs, in Intel order */
850 + 1 /* %eflags */
851 + 1 /* %eip */
852 + VG_SIZE_OF_FPUSTATE_W /* FPU state */
853 ];
854
855void VG_(copy_baseBlock_to_m_state_static) ( void )
856{
857 Int i;
858 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
859 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
860 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
861 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
862 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
863 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
864 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
865 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
866
867 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_eflags)];
868 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
869
870 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
871 VG_(m_state_static)[40/4 + i]
872 = VG_(baseBlock)[VGOFF_(m_fpustate) + i];
873}
874
875
876void VG_(copy_m_state_static_to_baseBlock) ( void )
877{
878 Int i;
879 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
880 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
881 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
882 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
883 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
884 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
885 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
886 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
887
888 VG_(baseBlock)[VGOFF_(m_eflags)] = VG_(m_state_static)[32/4];
889 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
890
891 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
892 VG_(baseBlock)[VGOFF_(m_fpustate) + i]
893 = VG_(m_state_static)[40/4 + i];
894}
895
896
897/* ---------------------------------------------------------------------
898 Show accumulated counts.
899 ------------------------------------------------------------------ */
900
901static void vg_show_counts ( void )
902{
903 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000904 " lru: %d epochs, %d clearings.",
905 VG_(current_epoch),
906 VG_(number_of_lrus) );
sewardjde4a1d02002-03-22 01:27:54 +0000907 VG_(message)(Vg_DebugMsg,
908 "translate: new %d (%d -> %d), discard %d (%d -> %d).",
909 VG_(overall_in_count),
910 VG_(overall_in_osize),
911 VG_(overall_in_tsize),
912 VG_(overall_out_count),
913 VG_(overall_out_osize),
914 VG_(overall_out_tsize) );
915 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000916 " dispatch: %lu basic blocks, %d/%d sched events, %d tt_fast misses.",
917 VG_(bbs_done), VG_(num_scheduling_events_MAJOR),
918 VG_(num_scheduling_events_MINOR),
919 VG_(tt_fast_misses));
sewardjde4a1d02002-03-22 01:27:54 +0000920 VG_(message)(Vg_DebugMsg,
921 "reg-alloc: %d t-req-spill, "
922 "%d+%d orig+spill uis, %d total-reg-r.",
923 VG_(translations_needing_spill),
924 VG_(uinstrs_prealloc),
925 VG_(uinstrs_spill),
926 VG_(total_reg_rank) );
927 VG_(message)(Vg_DebugMsg,
928 "smc-check: %d checks, %d fast pass, "
929 "%d slow pass, %d discards.",
930 VG_(smc_total_check4s),
931 VG_(smc_cache_passed),
932 VG_(smc_fancy_passed),
933 VG_(smc_discard_count) );
934 VG_(message)(Vg_DebugMsg,
935 " sanity: %d cheap, %d expensive checks.",
936 VG_(sanity_fast_count),
937 VG_(sanity_slow_count) );
938}
939
940
941/* ---------------------------------------------------------------------
942 Main!
943 ------------------------------------------------------------------ */
944
945/* Where we jump to once Valgrind has got control, and the real
946 machine's state has been copied to the m_state_static. */
947
948void VG_(main) ( void )
949{
sewardj2e93c502002-04-12 11:12:52 +0000950 Int i;
951 VgSchedReturnCode src;
sewardjde4a1d02002-03-22 01:27:54 +0000952
953 /* Set up our stack sanity-check words. */
954 for (i = 0; i < 10; i++) {
955 VG_(stack)[i] = (UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1;
956 VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321;
957 }
958
959 /* Set up baseBlock offsets and copy the saved machine's state into
960 it. */
961 vg_init_baseBlock();
962 VG_(copy_m_state_static_to_baseBlock)();
963
964 /* Process Valgrind's command-line opts (from env var VG_OPTS). */
965 process_cmd_line_options();
966
967 /* Initialise the signal handling subsystem. */
968 VG_(sigstartup_actions)();
969
970# ifdef VG_PROFILE
971 VGP_(init_profiling)();
972# endif
973
sewardjb3c26872002-03-24 10:05:14 +0000974 /* Hook to delay things long enough so we can get the pid and
975 attach GDB in another shell. */
976 /* {extern unsigned int sleep(unsigned int seconds); sleep(10);} */
977
sewardjde4a1d02002-03-22 01:27:54 +0000978 if (VG_(clo_instrument)) {
979 VGP_PUSHCC(VgpInitAudit);
980 VGM_(init_memory_audit)();
981 VGP_POPCC;
982 VGP_PUSHCC(VgpReadSyms);
983 VG_(read_symbols)();
984 VGP_POPCC;
985 }
986
987 /* This should come after init_memory_audit; otherwise the latter
988 carefully sets up the permissions maps to cover the anonymous
989 mmaps for the translation table and translation cache, which
990 wastes > 20M of virtual address space. */
991 VG_(init_transtab_and_SMC)();
992
993 if (VG_(clo_verbosity) == 1) {
994 VG_(message)(Vg_UserMsg,
995 "For more details, rerun with: -v");
996 }
997
998 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
999 instrumented-ly. */
1000 VG_(running_on_simd_CPU) = True;
1001 if (VG_(clo_instrument)) {
1002 VGM_(make_readable) ( (Addr)&VG_(running_on_simd_CPU), 1 );
1003 VGM_(make_readable) ( (Addr)&VG_(clo_instrument), 1 );
1004 VGM_(make_readable) ( (Addr)&VG_(clo_trace_malloc), 1 );
1005 VGM_(make_readable) ( (Addr)&VG_(clo_sloppy_malloc), 1 );
1006 }
1007
1008 if (VG_(clo_verbosity) > 0)
1009 VG_(message)(Vg_UserMsg, "");
1010
1011 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001012
1013 VG_(scheduler_init)();
1014 src = VG_(scheduler)();
sewardjde4a1d02002-03-22 01:27:54 +00001015
1016 if (VG_(clo_verbosity) > 0)
1017 VG_(message)(Vg_UserMsg, "");
1018
sewardj2e93c502002-04-12 11:12:52 +00001019 if (src == VgSrc_Deadlock) {
1020 VG_(message)(Vg_UserMsg,
1021 "Warning: pthread scheduler exited due to deadlock");
1022 }
1023
sewardjde4a1d02002-03-22 01:27:54 +00001024 if (VG_(clo_instrument)) {
1025 VG_(show_all_errors)();
1026 VG_(clientmalloc_done)();
1027 if (VG_(clo_verbosity) == 1) {
1028 VG_(message)(Vg_UserMsg,
1029 "For counts of detected errors, rerun with: -v");
1030 }
1031 if (VG_(clo_leak_check)) VG_(detect_memory_leaks)();
1032 }
1033 VG_(running_on_simd_CPU) = False;
sewardj2e93c502002-04-12 11:12:52 +00001034
1035 VG_(do_sanity_checks)( 0 /* root thread */,
1036 True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001037
1038 if (VG_(clo_verbosity) > 1)
1039 vg_show_counts();
1040
1041 if (0) {
1042 VG_(message)(Vg_DebugMsg, "");
1043 VG_(message)(Vg_DebugMsg,
1044 "------ Valgrind's internal memory use stats follow ------" );
1045 VG_(mallocSanityCheckAll)();
1046 VG_(show_all_arena_stats)();
1047 VG_(message)(Vg_DebugMsg,
1048 "------ Valgrind's ExeContext management stats follow ------" );
1049 VG_(show_ExeContext_stats)();
1050 VG_(message)(Vg_DebugMsg,
1051 "------ Valgrind's client block stats follow ---------------" );
1052 VG_(show_client_block_stats)();
1053 }
1054
1055# ifdef VG_PROFILE
1056 VGP_(done_profiling)();
1057# endif
1058
1059 VG_(done_prof_mem)();
1060
1061 VG_(shutdown_logging)();
1062
1063 /* In LD_PRELOAD, convert "valgrind.so" into "valgrinq.so", so that
1064 child processes don't get traced into. Also done on simulated
1065 execve system call. */
1066 if (!VG_(clo_trace_children)) {
1067 VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
1068 }
1069
1070 /* Prepare to restore state to the real CPU. */
sewardj2e93c502002-04-12 11:12:52 +00001071 VG_(load_thread_state)(0);
sewardjde4a1d02002-03-22 01:27:54 +00001072 VG_(copy_baseBlock_to_m_state_static)();
1073
1074 /* This pushes a return address on the simulator's stack, which
1075 is abandoned. We call vg_sigshutdown_actions() at the end
1076 of vg_switch_to_real_CPU(), so as to ensure that the original
1077 stack and machine state is restored before the real signal
1078 mechanism is restored.
1079 */
1080 VG_(switch_to_real_CPU)();
1081}
1082
1083
1084/* Debugging thing .. can be called from assembly with OYNK macro. */
1085void VG_(oynk) ( Int n )
1086{
1087 OINK(n);
1088}
1089
1090
1091/* Find "valgrind.so" in a LD_PRELOAD=... string, and convert it to
1092 "valgrinq.so", which doesn't do anything. This is used to avoid
1093 tracing into child processes. To make this work the build system
1094 also supplies a dummy file, "valgrinq.so".
1095*/
1096void VG_(mash_LD_PRELOAD_string)( Char* ld_preload_str )
1097{
1098 Char* p;
1099 if (ld_preload_str == NULL)
1100 return;
1101 p = VG_(strstr)(ld_preload_str, "valgrind.so");
1102 if (p == NULL)
1103 return;
1104 p[7] = 'q';
1105}
1106
1107/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1108 it to attach to this process. Called if the user requests this
1109 service after an error has been shown, so she can poke around and
1110 look at parameters, memory, etc. You can't meaningfully get GDB to
1111 continue the program, though; to continue, quit GDB. */
1112extern void VG_(start_GDB_whilst_on_client_stack) ( void )
1113{
1114 UChar buf[100];
1115 VG_(sprintf)(buf,
1116 "/usr/bin/gdb -nw /proc/%d/exe %d",
1117 VG_(getpid)(), VG_(getpid)());
1118 VG_(printf)("starting GDB with cmd: %s\n", buf);
1119 VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
1120 { /* HACK ALERT */
1121 extern int system ( const char * );
1122 system(buf);
1123 /* end of HACK ALERT */
1124 }
1125 VG_(message)(Vg_UserMsg, "");
1126 VG_(message)(Vg_UserMsg,
1127 "GDB has detached. Valgrind regains control. We continue.");
1128}
1129
1130
1131/* Print some helpful-ish text about unimplemented things, and give
1132 up. */
1133extern void VG_(unimplemented) ( Char* msg )
1134{
1135 VG_(message)(Vg_UserMsg, "");
1136 VG_(message)(Vg_UserMsg,
1137 "Valgrind detected that your program requires");
1138 VG_(message)(Vg_UserMsg,
1139 "the following unimplemented functionality:");
1140 VG_(message)(Vg_UserMsg, " %s", msg);
1141 VG_(message)(Vg_UserMsg,
1142 "This may be because the functionality is hard to implement,");
1143 VG_(message)(Vg_UserMsg,
1144 "or because no reasonable program would behave this way,");
1145 VG_(message)(Vg_UserMsg,
1146 "or because nobody has yet needed it. In any case, let me know");
1147 VG_(message)(Vg_UserMsg,
1148 "(jseward@acm.org) and/or try to work around the problem, if you can.");
1149 VG_(message)(Vg_UserMsg,
1150 "");
1151 VG_(message)(Vg_UserMsg,
1152 "Valgrind has to exit now. Sorry. Bye!");
1153 VG_(message)(Vg_UserMsg,
1154 "");
sewardj15a43e12002-04-17 19:35:12 +00001155 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +00001156 VG_(exit)(1);
1157}
1158
1159
sewardjde4a1d02002-03-22 01:27:54 +00001160/*--------------------------------------------------------------------*/
1161/*--- end vg_main.c ---*/
1162/*--------------------------------------------------------------------*/