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