blob: 330068db79cce6ec00c9db613bc86d59b5cc74c6 [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;
njn4f9c9342002-04-29 16:03:24 +0000106Int VGOFF_(cachesim_log_non_mem_instr) = INVALID_OFFSET;
107Int VGOFF_(cachesim_log_mem_instr) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +0000108
109/* This is the actual defn of baseblock. */
110UInt VG_(baseBlock)[VG_BASEBLOCK_WORDS];
111
112/* Words. */
113static Int baB_off = 0;
114
115/* Returns the offset, in words. */
116static Int alloc_BaB ( Int words )
117{
118 Int off = baB_off;
119 baB_off += words;
120 if (baB_off >= VG_BASEBLOCK_WORDS)
121 VG_(panic)( "alloc_BaB: baseBlock is too small");
122
123 return off;
124}
125
126/* Allocate 1 word in baseBlock and set it to the given value. */
127static Int alloc_BaB_1_set ( Addr a )
128{
129 Int off = alloc_BaB(1);
130 VG_(baseBlock)[off] = (UInt)a;
131 return off;
132}
133
134
135/* Here we assign actual offsets. It's important to get the most
136 popular referents within 128 bytes of the start, so we can take
137 advantage of short addressing modes relative to %ebp. Popularity
138 of offsets was measured on 22 Feb 02 running a KDE application, and
139 the slots rearranged accordingly, with a 1.5% reduction in total
140 size of translations. */
141
142static void vg_init_baseBlock ( void )
143{
144 baB_off = 0;
145
146 /* Those with offsets under 128 are carefully chosen. */
147
148 /* WORD offsets in this column */
149 /* 0 */ VGOFF_(m_eax) = alloc_BaB(1);
150 /* 1 */ VGOFF_(m_ecx) = alloc_BaB(1);
151 /* 2 */ VGOFF_(m_edx) = alloc_BaB(1);
152 /* 3 */ VGOFF_(m_ebx) = alloc_BaB(1);
153 /* 4 */ VGOFF_(m_esp) = alloc_BaB(1);
154 /* 5 */ VGOFF_(m_ebp) = alloc_BaB(1);
155 /* 6 */ VGOFF_(m_esi) = alloc_BaB(1);
156 /* 7 */ VGOFF_(m_edi) = alloc_BaB(1);
157 /* 8 */ VGOFF_(m_eflags) = alloc_BaB(1);
158
159 /* 9 */ VGOFF_(sh_eax) = alloc_BaB(1);
160 /* 10 */ VGOFF_(sh_ecx) = alloc_BaB(1);
161 /* 11 */ VGOFF_(sh_edx) = alloc_BaB(1);
162 /* 12 */ VGOFF_(sh_ebx) = alloc_BaB(1);
163 /* 13 */ VGOFF_(sh_esp) = alloc_BaB(1);
164 /* 14 */ VGOFF_(sh_ebp) = alloc_BaB(1);
165 /* 15 */ VGOFF_(sh_esi) = alloc_BaB(1);
166 /* 16 */ VGOFF_(sh_edi) = alloc_BaB(1);
167 /* 17 */ VGOFF_(sh_eflags) = alloc_BaB(1);
168
njn4f9c9342002-04-29 16:03:24 +0000169 /* 17a */
170 VGOFF_(cachesim_log_non_mem_instr)
171 = alloc_BaB_1_set( (Addr) & VG_(cachesim_log_non_mem_instr) );
172 /* 17b */
173 VGOFF_(cachesim_log_mem_instr)
174 = alloc_BaB_1_set( (Addr) & VG_(cachesim_log_mem_instr) );
175
sewardjde4a1d02002-03-22 01:27:54 +0000176 /* 18 */
177 VGOFF_(helper_value_check4_fail)
178 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check4_fail) );
179 /* 19 */
180 VGOFF_(helper_value_check0_fail)
181 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check0_fail) );
182
183 /* 20 */
184 VGOFF_(helperc_STOREV4)
185 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV4) );
186 /* 21 */
187 VGOFF_(helperc_STOREV1)
188 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV1) );
189
190 /* 22 */
191 VGOFF_(helperc_LOADV4)
192 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV4) );
193 /* 23 */
194 VGOFF_(helperc_LOADV1)
195 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV1) );
196
197 /* 24 */
198 VGOFF_(handle_esp_assignment)
199 = alloc_BaB_1_set( (Addr) & VGM_(handle_esp_assignment) );
200
201 /* 25 */
202 VGOFF_(m_eip) = alloc_BaB(1);
203
204 /* There are currently 24 spill slots */
205 /* 26 .. 49 This overlaps the magic boundary at >= 32 words, but
206 most spills are to low numbered spill slots, so the ones above
207 the boundary don't see much action. */
208 VGOFF_(spillslots) = alloc_BaB(VG_MAX_SPILLSLOTS);
209
210 /* These two pushed beyond the boundary because 2-byte transactions
211 are rare. */
212 /* 50 */
213 VGOFF_(helperc_STOREV2)
214 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV2) );
215 /* 51 */
216 VGOFF_(helperc_LOADV2)
217 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV2) );
218
219 /* 52 */
220 VGOFF_(fpu_write_check)
221 = alloc_BaB_1_set( (Addr) & VGM_(fpu_write_check) );
222 /* 53 */
223 VGOFF_(fpu_read_check)
224 = alloc_BaB_1_set( (Addr) & VGM_(fpu_read_check) );
225
226 /* Actually I don't think these two are ever used. */
227 /* 54 */
228 VGOFF_(helper_value_check2_fail)
229 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check2_fail) );
230 /* 55 */
231 VGOFF_(helper_value_check1_fail)
232 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check1_fail) );
233
234 /* I gave up counting at this point. Since they're way above the
235 short-amode-boundary, there's no point. */
236
237 VGOFF_(m_fpustate) = alloc_BaB(VG_SIZE_OF_FPUSTATE_W);
238
239 VGOFF_(helper_idiv_64_32)
240 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_64_32) );
241 VGOFF_(helper_div_64_32)
242 = alloc_BaB_1_set( (Addr) & VG_(helper_div_64_32) );
243 VGOFF_(helper_idiv_32_16)
244 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_32_16) );
245 VGOFF_(helper_div_32_16)
246 = alloc_BaB_1_set( (Addr) & VG_(helper_div_32_16) );
247 VGOFF_(helper_idiv_16_8)
248 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_16_8) );
249 VGOFF_(helper_div_16_8)
250 = alloc_BaB_1_set( (Addr) & VG_(helper_div_16_8) );
251
252 VGOFF_(helper_imul_32_64)
253 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_32_64) );
254 VGOFF_(helper_mul_32_64)
255 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_32_64) );
256 VGOFF_(helper_imul_16_32)
257 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_16_32) );
258 VGOFF_(helper_mul_16_32)
259 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_16_32) );
260 VGOFF_(helper_imul_8_16)
261 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_8_16) );
262 VGOFF_(helper_mul_8_16)
263 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_8_16) );
264
265 VGOFF_(helper_CLD)
266 = alloc_BaB_1_set( (Addr) & VG_(helper_CLD) );
267 VGOFF_(helper_STD)
268 = alloc_BaB_1_set( (Addr) & VG_(helper_STD) );
269 VGOFF_(helper_get_dirflag)
270 = alloc_BaB_1_set( (Addr) & VG_(helper_get_dirflag) );
271
272 VGOFF_(helper_shldl)
273 = alloc_BaB_1_set( (Addr) & VG_(helper_shldl) );
274 VGOFF_(helper_shldw)
275 = alloc_BaB_1_set( (Addr) & VG_(helper_shldw) );
276 VGOFF_(helper_shrdl)
277 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdl) );
278 VGOFF_(helper_shrdw)
279 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdw) );
280
281 VGOFF_(helper_RDTSC)
282 = alloc_BaB_1_set( (Addr) & VG_(helper_RDTSC) );
283 VGOFF_(helper_CPUID)
284 = alloc_BaB_1_set( (Addr) & VG_(helper_CPUID) );
285
sewardjde4a1d02002-03-22 01:27:54 +0000286 VGOFF_(helper_bsf)
287 = alloc_BaB_1_set( (Addr) & VG_(helper_bsf) );
288 VGOFF_(helper_bsr)
289 = alloc_BaB_1_set( (Addr) & VG_(helper_bsr) );
290
291 VGOFF_(helper_fstsw_AX)
292 = alloc_BaB_1_set( (Addr) & VG_(helper_fstsw_AX) );
293 VGOFF_(helper_SAHF)
294 = alloc_BaB_1_set( (Addr) & VG_(helper_SAHF) );
sewardj4d0ab1f2002-03-24 10:00:09 +0000295 VGOFF_(helper_DAS)
296 = alloc_BaB_1_set( (Addr) & VG_(helper_DAS) );
sewardjfe8a1662002-03-24 11:54:07 +0000297 VGOFF_(helper_DAA)
298 = alloc_BaB_1_set( (Addr) & VG_(helper_DAA) );
sewardjde4a1d02002-03-22 01:27:54 +0000299}
300
301
302/* ---------------------------------------------------------------------
303 Global entities which are not referenced from generated code.
304 ------------------------------------------------------------------ */
305
306/* The stack on which Valgrind runs. We can't use the same stack as
307 the simulatee -- that's an important design decision. */
308UInt VG_(stack)[10000];
309
310/* Ditto our signal delivery stack. */
311UInt VG_(sigstack)[10000];
312
313/* Saving stuff across system calls. */
314UInt VG_(real_fpu_state_saved_over_syscall_d1)[VG_SIZE_OF_FPUSTATE_W];
315UInt VG_(real_fpu_state_saved_over_syscall_d2)[VG_SIZE_OF_FPUSTATE_W];
316Addr VG_(esp_saved_over_syscall_d1);
317Addr VG_(esp_saved_over_syscall_d2);
318
319/* Counts downwards in vg_run_innerloop. */
320UInt VG_(dispatch_ctr);
321
sewardjde4a1d02002-03-22 01:27:54 +0000322
323/* 64-bit counter for the number of basic blocks done. */
324ULong VG_(bbs_done);
325/* 64-bit counter for the number of bbs to go before a debug exit. */
326ULong VG_(bbs_to_go);
327
328/* Produce debugging output? */
329Bool VG_(disassemble) = False;
330
331/* The current LRU epoch. */
332UInt VG_(current_epoch) = 0;
333
sewardj7e87e382002-05-03 19:09:05 +0000334/* This is the ThreadId of the last thread the scheduler ran. */
335ThreadId VG_(last_run_tid) = 0;
336
sewardjde4a1d02002-03-22 01:27:54 +0000337
338/* ---------------------------------------------------------------------
339 Counters, for informational purposes only.
340 ------------------------------------------------------------------ */
341
342/* Number of lookups which miss the fast tt helper. */
343UInt VG_(tt_fast_misses) = 0;
344
345
346/* Counts for LRU informational messages. */
347
348/* Number and total o/t size of new translations this epoch. */
349UInt VG_(this_epoch_in_count) = 0;
350UInt VG_(this_epoch_in_osize) = 0;
351UInt VG_(this_epoch_in_tsize) = 0;
352/* Number and total o/t size of discarded translations this epoch. */
353UInt VG_(this_epoch_out_count) = 0;
354UInt VG_(this_epoch_out_osize) = 0;
355UInt VG_(this_epoch_out_tsize) = 0;
356/* Number and total o/t size of translations overall. */
357UInt VG_(overall_in_count) = 0;
358UInt VG_(overall_in_osize) = 0;
359UInt VG_(overall_in_tsize) = 0;
360/* Number and total o/t size of discards overall. */
361UInt VG_(overall_out_count) = 0;
362UInt VG_(overall_out_osize) = 0;
363UInt VG_(overall_out_tsize) = 0;
364
365/* The number of LRU-clearings of TT/TC. */
366UInt VG_(number_of_lrus) = 0;
367
368
369/* Counts pertaining to the register allocator. */
370
371/* total number of uinstrs input to reg-alloc */
372UInt VG_(uinstrs_prealloc) = 0;
373
374/* total number of uinstrs added due to spill code */
375UInt VG_(uinstrs_spill) = 0;
376
377/* number of bbs requiring spill code */
378UInt VG_(translations_needing_spill) = 0;
379
380/* total of register ranks over all translations */
381UInt VG_(total_reg_rank) = 0;
382
383
384/* Counts pertaining to the self-modifying-code detection machinery. */
385
386/* Total number of writes checked. */
387UInt VG_(smc_total_check4s) = 0;
388
389/* Number of writes which the fast smc check couldn't show were
390 harmless. */
391UInt VG_(smc_cache_passed) = 0;
392
393/* Numnber of writes which really did write on original code. */
394UInt VG_(smc_fancy_passed) = 0;
395
396/* Number of translations discarded as a result. */
397UInt VG_(smc_discard_count) = 0;
398
399
400/* Counts pertaining to internal sanity checking. */
sewardjde4a1d02002-03-22 01:27:54 +0000401UInt VG_(sanity_fast_count) = 0;
402UInt VG_(sanity_slow_count) = 0;
403
sewardj2e93c502002-04-12 11:12:52 +0000404/* Counts pertaining to the scheduler. */
405UInt VG_(num_scheduling_events_MINOR) = 0;
406UInt VG_(num_scheduling_events_MAJOR) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000407
408
409/* ---------------------------------------------------------------------
410 Values derived from command-line options.
411 ------------------------------------------------------------------ */
412
sewardj97ced732002-03-25 00:07:36 +0000413Bool VG_(clo_check_addrVs);
sewardjde4a1d02002-03-22 01:27:54 +0000414Bool VG_(clo_GDB_attach);
415Int VG_(sanity_level);
416Int VG_(clo_verbosity);
417Bool VG_(clo_demangle);
418Bool VG_(clo_leak_check);
419Bool VG_(clo_show_reachable);
420Int VG_(clo_leak_resolution);
421Bool VG_(clo_sloppy_malloc);
422Bool VG_(clo_partial_loads_ok);
423Bool VG_(clo_trace_children);
424Int VG_(clo_logfile_fd);
425Int VG_(clo_freelist_vol);
426Bool VG_(clo_workaround_gcc296_bugs);
427Int VG_(clo_n_suppressions);
428Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
429Bool VG_(clo_single_step);
430Bool VG_(clo_optimise);
431Bool VG_(clo_instrument);
432Bool VG_(clo_cleanup);
njn4f9c9342002-04-29 16:03:24 +0000433Bool VG_(clo_cachesim);
sewardjde4a1d02002-03-22 01:27:54 +0000434Int VG_(clo_smc_check);
435Bool VG_(clo_trace_syscalls);
436Bool VG_(clo_trace_signals);
437Bool VG_(clo_trace_symtab);
438Bool VG_(clo_trace_malloc);
sewardj8937c812002-04-12 20:12:20 +0000439Bool VG_(clo_trace_sched);
sewardj45b4b372002-04-16 22:50:32 +0000440Int VG_(clo_trace_pthread_level);
sewardjde4a1d02002-03-22 01:27:54 +0000441ULong VG_(clo_stop_after);
442Int VG_(clo_dump_error);
443Int VG_(clo_backtrace_size);
444
445/* This Bool is needed by wrappers in vg_clientmalloc.c to decide how
446 to behave. Initially we say False. */
447Bool VG_(running_on_simd_CPU) = False;
448
449/* Holds client's %esp at the point we gained control. */
450Addr VG_(esp_at_startup);
451
452/* As deduced from VG_(esp_at_startup), the client's argc, argv[] and
453 envp[] as extracted from the client's stack at startup-time. */
454Int VG_(client_argc);
455Char** VG_(client_argv);
456Char** VG_(client_envp);
457
458/* A place into which to copy the value of env var VG_ARGS, so we
459 don't have to modify the original. */
460static Char vg_cmdline_copy[M_VG_CMDLINE_STRLEN];
461
462
463/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000464 Processing of command-line options.
465 ------------------------------------------------------------------ */
466
467static void bad_option ( Char* opt )
468{
469 VG_(shutdown_logging)();
470 VG_(clo_logfile_fd) = 2; /* stderr */
471 VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
472 VG_(exit)(1);
473}
474
475static void config_error ( Char* msg )
476{
477 VG_(shutdown_logging)();
478 VG_(clo_logfile_fd) = 2; /* stderr */
479 VG_(printf)("valgrind.so: Startup or configuration error:\n\t%s\n", msg);
480 VG_(printf)("valgrind.so: Unable to start up properly. Giving up.\n");
481 VG_(exit)(1);
482}
483
sewardja1679dd2002-05-10 22:31:40 +0000484static void args_grok_error ( Char* msg )
485{
486 VG_(shutdown_logging)();
487 VG_(clo_logfile_fd) = 2; /* stderr */
488 VG_(printf)("valgrind.so: When searching for "
489 "client's argc/argc/envp:\n\t%s\n", msg);
490 config_error("couldn't find client's argc/argc/envp");
491}
492
sewardjde4a1d02002-03-22 01:27:54 +0000493
494static void process_cmd_line_options ( void )
495{
496 UChar* argv[M_VG_CMDLINE_OPTS];
497 UInt argc;
498 UChar* p;
499 UChar* str;
sewardja1679dd2002-05-10 22:31:40 +0000500 Int i, eventually_logfile_fd, ctr;
sewardjde4a1d02002-03-22 01:27:54 +0000501
502# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
503# define STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2)))
504# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
505
506 /* Set defaults. */
sewardj97ced732002-03-25 00:07:36 +0000507 VG_(clo_check_addrVs) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000508 VG_(clo_GDB_attach) = False;
509 VG_(sanity_level) = 1;
510 VG_(clo_verbosity) = 1;
511 VG_(clo_demangle) = True;
512 VG_(clo_leak_check) = False;
513 VG_(clo_show_reachable) = False;
514 VG_(clo_leak_resolution) = 2;
515 VG_(clo_sloppy_malloc) = False;
516 VG_(clo_partial_loads_ok) = True;
517 VG_(clo_trace_children) = False;
518 VG_(clo_logfile_fd) = 2; /* stderr */
519 VG_(clo_freelist_vol) = 1000000;
520 VG_(clo_workaround_gcc296_bugs) = False;
521 VG_(clo_n_suppressions) = 0;
522 VG_(clo_single_step) = False;
523 VG_(clo_optimise) = True;
524 VG_(clo_instrument) = True;
525 VG_(clo_cleanup) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000526 VG_(clo_smc_check) = /* VG_CLO_SMC_SOME */ VG_CLO_SMC_NONE;
527 VG_(clo_trace_syscalls) = False;
528 VG_(clo_trace_signals) = False;
529 VG_(clo_trace_symtab) = False;
530 VG_(clo_trace_malloc) = False;
sewardj8937c812002-04-12 20:12:20 +0000531 VG_(clo_trace_sched) = False;
sewardj45b4b372002-04-16 22:50:32 +0000532 VG_(clo_trace_pthread_level) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000533 VG_(clo_stop_after) = 1000000000000LL;
534 VG_(clo_dump_error) = 0;
535 VG_(clo_backtrace_size) = 4;
536
537 eventually_logfile_fd = VG_(clo_logfile_fd);
538
539 /* Once logging is started, we can safely send messages pertaining
540 to failures in initialisation. */
541 VG_(startup_logging)();
542
sewardj38170912002-05-10 21:07:22 +0000543
sewardja1679dd2002-05-10 22:31:40 +0000544 /* (Suggested by Fabrice Bellard ... )
545 We look for the Linux ELF table and go down until we find the
sewardj38170912002-05-10 21:07:22 +0000546 envc & envp. It is not full proof, but these structures should
547 change less often than the libc ones. */
548 {
sewardja1679dd2002-05-10 22:31:40 +0000549 UInt* sp = 0; /* bogus init to keep gcc -O happy */
550
sewardj38170912002-05-10 21:07:22 +0000551 /* locate the top of the stack */
sewardja1679dd2002-05-10 22:31:40 +0000552 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
553 VG_STARTUP_STACK_BASE_1 )) {
554 sp = (UInt*)VG_STARTUP_STACK_BASE_1;
555 } else
556 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
557 VG_STARTUP_STACK_BASE_2 )) {
558 sp = (UInt*)VG_STARTUP_STACK_BASE_2;
559 } else {
560 args_grok_error(
561 "startup %esp is not near any VG_STARTUP_STACK_BASE_*\n "
562 "constants defined in vg_include.h. You should investigate."
563 );
564 }
565
sewardj38170912002-05-10 21:07:22 +0000566 /* we locate: NEW_AUX_ENT(1, AT_PAGESZ, ELF_EXEC_PAGESIZE) in
567 the elf interpreter table */
568 sp -= 2;
sewardj38170912002-05-10 21:07:22 +0000569 while (sp[0] != VKI_AT_PAGESZ || sp[1] != 4096) {
sewardja1679dd2002-05-10 22:31:40 +0000570 /* VG_(printf)("trying %p\n", sp); */
sewardj38170912002-05-10 21:07:22 +0000571 sp--;
572 }
sewardj38170912002-05-10 21:07:22 +0000573
574 if (sp[2] == VKI_AT_BASE
575 && sp[0] == VKI_AT_PAGESZ
576 && sp[-2] == VKI_AT_PHNUM
577 && sp[-4] == VKI_AT_PHENT
578 && sp[-6] == VKI_AT_PHDR) {
sewardja1679dd2002-05-10 22:31:40 +0000579 if (0)
580 VG_(printf)("Looks like you've got a 2.2.X kernel here.\n");
sewardj38170912002-05-10 21:07:22 +0000581 sp -= 6;
sewardja1679dd2002-05-10 22:31:40 +0000582 } else
583 if (sp[2] == VKI_AT_CLKTCK
584 && sp[0] == VKI_AT_PAGESZ
585 && sp[-2] == VKI_AT_HWCAP) {
586 if (0)
587 VG_(printf)("Looks like you've got a 2.4.X kernel here.\n");
588 sp -= 2;
589 } else
590 args_grok_error(
591 "ELF frame does not look like 2.2.X or 2.4.X.\n "
592 "See kernel sources linux/fs/binfmt_elf.c to make sense of this."
593 );
sewardj38170912002-05-10 21:07:22 +0000594
595 sp--;
sewardja1679dd2002-05-10 22:31:40 +0000596 if (*sp != 0)
597 args_grok_error("can't find NULL at end of env[]");
598
sewardj38170912002-05-10 21:07:22 +0000599 /* sp now points to NULL at the end of env[] */
sewardja1679dd2002-05-10 22:31:40 +0000600 ctr = 0;
sewardj38170912002-05-10 21:07:22 +0000601 while (True) {
602 sp --;
603 if (*sp == 0) break;
sewardja1679dd2002-05-10 22:31:40 +0000604 if (++ctr >= 1000)
605 args_grok_error(
606 "suspiciously many (1000) env[] entries; giving up");
607
sewardj38170912002-05-10 21:07:22 +0000608 }
609 /* sp now points to NULL at the end of argv[] */
sewardja1679dd2002-05-10 22:31:40 +0000610 VG_(client_envp) = (Char**)(sp+1);
sewardj38170912002-05-10 21:07:22 +0000611
sewardja1679dd2002-05-10 22:31:40 +0000612 ctr = 0;
sewardj38170912002-05-10 21:07:22 +0000613 VG_(client_argc) = 0;
614 while (True) {
615 sp--;
616 if (*sp == VG_(client_argc))
617 break;
618 VG_(client_argc)++;
sewardja1679dd2002-05-10 22:31:40 +0000619 if (++ctr >= 1000)
620 args_grok_error(
621 "suspiciously many (1000) argv[] entries; giving up");
sewardj38170912002-05-10 21:07:22 +0000622 }
623
sewardja1679dd2002-05-10 22:31:40 +0000624 VG_(client_argv) = (Char**)(sp+1);
sewardj38170912002-05-10 21:07:22 +0000625 }
626
sewardjde4a1d02002-03-22 01:27:54 +0000627 /* Now that VG_(client_envp) has been set, we can extract the args
628 for Valgrind itself. Copy into global var so that we don't have to
629 write zeroes to the getenv'd value itself. */
630 str = VG_(getenv)("VG_ARGS");
631 argc = 0;
632
633 if (!str) {
634 config_error("Can't read options from env var VG_ARGS.");
635 }
636
637 if (VG_(strlen)(str) >= M_VG_CMDLINE_STRLEN-1) {
638 config_error("Command line length exceeds M_CMDLINE_STRLEN.");
639 }
640 VG_(strcpy)(vg_cmdline_copy, str);
641 str = NULL;
642
643 p = &vg_cmdline_copy[0];
644 while (True) {
645 while (ISSPACE(*p)) { *p = 0; p++; }
646 if (*p == 0) break;
647 if (argc < M_VG_CMDLINE_OPTS-1) {
648 argv[argc] = p; argc++;
649 } else {
650 config_error(
651 "Found more than M_CMDLINE_OPTS command-line opts.");
652 }
653 while (*p != 0 && !ISSPACE(*p)) p++;
654 }
655
656 for (i = 0; i < argc; i++) {
657
658 if (STREQ(argv[i], "-v") || STREQ(argv[i], "--verbose"))
659 VG_(clo_verbosity)++;
660 else if (STREQ(argv[i], "-q") || STREQ(argv[i], "--quiet"))
661 VG_(clo_verbosity)--;
662
sewardj97ced732002-03-25 00:07:36 +0000663 else if (STREQ(argv[i], "--check-addrVs=yes"))
664 VG_(clo_check_addrVs) = True;
665 else if (STREQ(argv[i], "--check-addrVs=no"))
666 VG_(clo_check_addrVs) = False;
667
sewardjde4a1d02002-03-22 01:27:54 +0000668 else if (STREQ(argv[i], "--gdb-attach=yes"))
669 VG_(clo_GDB_attach) = True;
670 else if (STREQ(argv[i], "--gdb-attach=no"))
671 VG_(clo_GDB_attach) = False;
672
673 else if (STREQ(argv[i], "--demangle=yes"))
674 VG_(clo_demangle) = True;
675 else if (STREQ(argv[i], "--demangle=no"))
676 VG_(clo_demangle) = False;
677
678 else if (STREQ(argv[i], "--partial-loads-ok=yes"))
679 VG_(clo_partial_loads_ok) = True;
680 else if (STREQ(argv[i], "--partial-loads-ok=no"))
681 VG_(clo_partial_loads_ok) = False;
682
683 else if (STREQ(argv[i], "--leak-check=yes"))
684 VG_(clo_leak_check) = True;
685 else if (STREQ(argv[i], "--leak-check=no"))
686 VG_(clo_leak_check) = False;
687
688 else if (STREQ(argv[i], "--show-reachable=yes"))
689 VG_(clo_show_reachable) = True;
690 else if (STREQ(argv[i], "--show-reachable=no"))
691 VG_(clo_show_reachable) = False;
692
693 else if (STREQ(argv[i], "--leak-resolution=low"))
694 VG_(clo_leak_resolution) = 2;
695 else if (STREQ(argv[i], "--leak-resolution=med"))
696 VG_(clo_leak_resolution) = 4;
697 else if (STREQ(argv[i], "--leak-resolution=high"))
698 VG_(clo_leak_resolution) = VG_DEEPEST_BACKTRACE;
699
700 else if (STREQ(argv[i], "--sloppy-malloc=yes"))
701 VG_(clo_sloppy_malloc) = True;
702 else if (STREQ(argv[i], "--sloppy-malloc=no"))
703 VG_(clo_sloppy_malloc) = False;
704
705 else if (STREQ(argv[i], "--trace-children=yes"))
706 VG_(clo_trace_children) = True;
707 else if (STREQ(argv[i], "--trace-children=no"))
708 VG_(clo_trace_children) = False;
709
710 else if (STREQ(argv[i], "--workaround-gcc296-bugs=yes"))
711 VG_(clo_workaround_gcc296_bugs) = True;
712 else if (STREQ(argv[i], "--workaround-gcc296-bugs=no"))
713 VG_(clo_workaround_gcc296_bugs) = False;
714
715 else if (STREQN(15, argv[i], "--sanity-level="))
716 VG_(sanity_level) = (Int)VG_(atoll)(&argv[i][15]);
717
718 else if (STREQN(13, argv[i], "--logfile-fd="))
719 eventually_logfile_fd = (Int)VG_(atoll)(&argv[i][13]);
720
721 else if (STREQN(15, argv[i], "--freelist-vol=")) {
722 VG_(clo_freelist_vol) = (Int)VG_(atoll)(&argv[i][15]);
723 if (VG_(clo_freelist_vol) < 0) VG_(clo_freelist_vol) = 2;
724 }
725
726 else if (STREQN(15, argv[i], "--suppressions=")) {
727 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
728 VG_(message)(Vg_UserMsg, "Too many logfiles specified.");
729 VG_(message)(Vg_UserMsg,
730 "Increase VG_CLO_MAX_SFILES and recompile.");
731 bad_option(argv[i]);
732 }
733 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &argv[i][15];
734 VG_(clo_n_suppressions)++;
735 }
736 else if (STREQ(argv[i], "--single-step=yes"))
737 VG_(clo_single_step) = True;
738 else if (STREQ(argv[i], "--single-step=no"))
739 VG_(clo_single_step) = False;
740
741 else if (STREQ(argv[i], "--optimise=yes"))
742 VG_(clo_optimise) = True;
743 else if (STREQ(argv[i], "--optimise=no"))
744 VG_(clo_optimise) = False;
745
746 else if (STREQ(argv[i], "--instrument=yes"))
747 VG_(clo_instrument) = True;
748 else if (STREQ(argv[i], "--instrument=no"))
749 VG_(clo_instrument) = False;
750
751 else if (STREQ(argv[i], "--cleanup=yes"))
752 VG_(clo_cleanup) = True;
753 else if (STREQ(argv[i], "--cleanup=no"))
754 VG_(clo_cleanup) = False;
755
njn4f9c9342002-04-29 16:03:24 +0000756 else if (STREQ(argv[i], "--cachesim=yes"))
757 VG_(clo_cachesim) = True;
758 else if (STREQ(argv[i], "--cachesim=no"))
759 VG_(clo_cachesim) = False;
760
sewardjde4a1d02002-03-22 01:27:54 +0000761 else if (STREQ(argv[i], "--smc-check=none"))
762 VG_(clo_smc_check) = VG_CLO_SMC_NONE;
763 else if (STREQ(argv[i], "--smc-check=some"))
764 VG_(clo_smc_check) = VG_CLO_SMC_SOME;
765 else if (STREQ(argv[i], "--smc-check=all"))
766 VG_(clo_smc_check) = VG_CLO_SMC_ALL;
767
768 else if (STREQ(argv[i], "--trace-syscalls=yes"))
769 VG_(clo_trace_syscalls) = True;
770 else if (STREQ(argv[i], "--trace-syscalls=no"))
771 VG_(clo_trace_syscalls) = False;
772
773 else if (STREQ(argv[i], "--trace-signals=yes"))
774 VG_(clo_trace_signals) = True;
775 else if (STREQ(argv[i], "--trace-signals=no"))
776 VG_(clo_trace_signals) = False;
777
778 else if (STREQ(argv[i], "--trace-symtab=yes"))
779 VG_(clo_trace_symtab) = True;
780 else if (STREQ(argv[i], "--trace-symtab=no"))
781 VG_(clo_trace_symtab) = False;
782
783 else if (STREQ(argv[i], "--trace-malloc=yes"))
784 VG_(clo_trace_malloc) = True;
785 else if (STREQ(argv[i], "--trace-malloc=no"))
786 VG_(clo_trace_malloc) = False;
787
sewardj8937c812002-04-12 20:12:20 +0000788 else if (STREQ(argv[i], "--trace-sched=yes"))
789 VG_(clo_trace_sched) = True;
790 else if (STREQ(argv[i], "--trace-sched=no"))
791 VG_(clo_trace_sched) = False;
792
sewardj45b4b372002-04-16 22:50:32 +0000793 else if (STREQ(argv[i], "--trace-pthread=none"))
794 VG_(clo_trace_pthread_level) = 0;
795 else if (STREQ(argv[i], "--trace-pthread=some"))
796 VG_(clo_trace_pthread_level) = 1;
797 else if (STREQ(argv[i], "--trace-pthread=all"))
798 VG_(clo_trace_pthread_level) = 2;
sewardj8937c812002-04-12 20:12:20 +0000799
sewardjde4a1d02002-03-22 01:27:54 +0000800 else if (STREQN(13, argv[i], "--stop-after="))
801 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
802
803 else if (STREQN(13, argv[i], "--dump-error="))
804 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
805
806 else if (STREQN(14, argv[i], "--num-callers=")) {
807 /* Make sure it's sane. */
808 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
809 if (VG_(clo_backtrace_size) < 2)
810 VG_(clo_backtrace_size) = 2;
811 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
812 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
813 }
814
815 else
816 bad_option(argv[i]);
817 }
818
819# undef ISSPACE
820# undef STREQ
821# undef STREQN
822
823 if (VG_(clo_verbosity < 0))
824 VG_(clo_verbosity) = 0;
825
826 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
827 VG_(message)(Vg_UserMsg, "");
828 VG_(message)(Vg_UserMsg,
829 "--gdb-attach=yes conflicts with --trace-children=yes");
830 VG_(message)(Vg_UserMsg,
831 "Please choose one or the other, but not both.");
832 bad_option("--gdb-attach=yes and --trace-children=yes");
833 }
834
sewardjde4a1d02002-03-22 01:27:54 +0000835 VG_(clo_logfile_fd) = eventually_logfile_fd;
836
njn4f9c9342002-04-29 16:03:24 +0000837 /* Don't do memory checking if simulating the cache. */
838 if (VG_(clo_cachesim)) {
839 VG_(clo_instrument) = False;
840 }
841
sewardj83adf412002-05-01 01:25:45 +0000842 if (VG_(clo_verbosity > 0)) {
843 if (VG_(clo_cachesim)) {
844 VG_(message)(Vg_UserMsg,
845 "cachegrind-%s, an I1/D1/L2 cache profiler for x86 GNU/Linux.",
846 VERSION);
847 } else {
848 VG_(message)(Vg_UserMsg,
849 "valgrind-%s, a memory error detector for x86 GNU/Linux.",
850 VERSION);
851 }
852 }
sewardj3b2736a2002-03-24 12:18:35 +0000853
sewardjde4a1d02002-03-22 01:27:54 +0000854 if (VG_(clo_verbosity > 0))
855 VG_(message)(Vg_UserMsg,
856 "Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.");
857 if (VG_(clo_verbosity) > 1) {
858 VG_(message)(Vg_UserMsg, "Startup, with flags:");
859 for (i = 0; i < argc; i++) {
860 VG_(message)(Vg_UserMsg, " %s", argv[i]);
861 }
862 }
863
sewardj83adf412002-05-01 01:25:45 +0000864 if (VG_(clo_n_suppressions) == 0 && !VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +0000865 config_error("No error-suppression files were specified.");
866 }
867}
868
869
870/* ---------------------------------------------------------------------
871 Copying to/from m_state_static.
872 ------------------------------------------------------------------ */
873
874UInt VG_(m_state_static) [8 /* int regs, in Intel order */
875 + 1 /* %eflags */
876 + 1 /* %eip */
877 + VG_SIZE_OF_FPUSTATE_W /* FPU state */
878 ];
879
880void VG_(copy_baseBlock_to_m_state_static) ( void )
881{
882 Int i;
883 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
884 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
885 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
886 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
887 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
888 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
889 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
890 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
891
892 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_eflags)];
893 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
894
895 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
896 VG_(m_state_static)[40/4 + i]
897 = VG_(baseBlock)[VGOFF_(m_fpustate) + i];
898}
899
900
901void VG_(copy_m_state_static_to_baseBlock) ( void )
902{
903 Int i;
904 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
905 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
906 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
907 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
908 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
909 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
910 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
911 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
912
913 VG_(baseBlock)[VGOFF_(m_eflags)] = VG_(m_state_static)[32/4];
914 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
915
916 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
917 VG_(baseBlock)[VGOFF_(m_fpustate) + i]
918 = VG_(m_state_static)[40/4 + i];
919}
920
921
922/* ---------------------------------------------------------------------
923 Show accumulated counts.
924 ------------------------------------------------------------------ */
925
926static void vg_show_counts ( void )
927{
928 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000929 " lru: %d epochs, %d clearings.",
930 VG_(current_epoch),
931 VG_(number_of_lrus) );
sewardjde4a1d02002-03-22 01:27:54 +0000932 VG_(message)(Vg_DebugMsg,
933 "translate: new %d (%d -> %d), discard %d (%d -> %d).",
934 VG_(overall_in_count),
935 VG_(overall_in_osize),
936 VG_(overall_in_tsize),
937 VG_(overall_out_count),
938 VG_(overall_out_osize),
939 VG_(overall_out_tsize) );
940 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000941 " dispatch: %lu basic blocks, %d/%d sched events, %d tt_fast misses.",
942 VG_(bbs_done), VG_(num_scheduling_events_MAJOR),
943 VG_(num_scheduling_events_MINOR),
944 VG_(tt_fast_misses));
sewardjde4a1d02002-03-22 01:27:54 +0000945 VG_(message)(Vg_DebugMsg,
946 "reg-alloc: %d t-req-spill, "
947 "%d+%d orig+spill uis, %d total-reg-r.",
948 VG_(translations_needing_spill),
949 VG_(uinstrs_prealloc),
950 VG_(uinstrs_spill),
951 VG_(total_reg_rank) );
952 VG_(message)(Vg_DebugMsg,
953 "smc-check: %d checks, %d fast pass, "
954 "%d slow pass, %d discards.",
955 VG_(smc_total_check4s),
956 VG_(smc_cache_passed),
957 VG_(smc_fancy_passed),
958 VG_(smc_discard_count) );
959 VG_(message)(Vg_DebugMsg,
960 " sanity: %d cheap, %d expensive checks.",
961 VG_(sanity_fast_count),
962 VG_(sanity_slow_count) );
963}
964
965
966/* ---------------------------------------------------------------------
967 Main!
968 ------------------------------------------------------------------ */
969
970/* Where we jump to once Valgrind has got control, and the real
971 machine's state has been copied to the m_state_static. */
972
973void VG_(main) ( void )
974{
sewardj2e93c502002-04-12 11:12:52 +0000975 Int i;
976 VgSchedReturnCode src;
sewardj7e87e382002-05-03 19:09:05 +0000977 ThreadState* tst;
sewardjde4a1d02002-03-22 01:27:54 +0000978
979 /* Set up our stack sanity-check words. */
980 for (i = 0; i < 10; i++) {
981 VG_(stack)[i] = (UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1;
982 VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321;
983 }
984
985 /* Set up baseBlock offsets and copy the saved machine's state into
986 it. */
987 vg_init_baseBlock();
988 VG_(copy_m_state_static_to_baseBlock)();
989
990 /* Process Valgrind's command-line opts (from env var VG_OPTS). */
991 process_cmd_line_options();
992
993 /* Initialise the signal handling subsystem. */
994 VG_(sigstartup_actions)();
995
996# ifdef VG_PROFILE
997 VGP_(init_profiling)();
998# endif
999
sewardj5f07b662002-04-23 16:52:51 +00001000 /* Start calibration of our RDTSC-based clock. */
1001 VG_(start_rdtsc_calibration)();
1002
sewardjb3c26872002-03-24 10:05:14 +00001003 /* Hook to delay things long enough so we can get the pid and
1004 attach GDB in another shell. */
1005 /* {extern unsigned int sleep(unsigned int seconds); sleep(10);} */
1006
njn4f9c9342002-04-29 16:03:24 +00001007 if (VG_(clo_instrument) || VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +00001008 VGP_PUSHCC(VgpInitAudit);
1009 VGM_(init_memory_audit)();
1010 VGP_POPCC;
1011 VGP_PUSHCC(VgpReadSyms);
1012 VG_(read_symbols)();
1013 VGP_POPCC;
1014 }
1015
sewardj5f07b662002-04-23 16:52:51 +00001016 /* End calibration of our RDTSC-based clock, leaving it as long as
1017 we can. */
1018 VG_(end_rdtsc_calibration)();
1019
sewardjde4a1d02002-03-22 01:27:54 +00001020 /* This should come after init_memory_audit; otherwise the latter
1021 carefully sets up the permissions maps to cover the anonymous
1022 mmaps for the translation table and translation cache, which
1023 wastes > 20M of virtual address space. */
1024 VG_(init_transtab_and_SMC)();
1025
1026 if (VG_(clo_verbosity) == 1) {
1027 VG_(message)(Vg_UserMsg,
1028 "For more details, rerun with: -v");
1029 }
1030
1031 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1032 instrumented-ly. */
1033 VG_(running_on_simd_CPU) = True;
1034 if (VG_(clo_instrument)) {
1035 VGM_(make_readable) ( (Addr)&VG_(running_on_simd_CPU), 1 );
1036 VGM_(make_readable) ( (Addr)&VG_(clo_instrument), 1 );
1037 VGM_(make_readable) ( (Addr)&VG_(clo_trace_malloc), 1 );
1038 VGM_(make_readable) ( (Addr)&VG_(clo_sloppy_malloc), 1 );
1039 }
1040
njn4f9c9342002-04-29 16:03:24 +00001041 if (VG_(clo_cachesim))
1042 VG_(init_cachesim)();
1043
sewardjde4a1d02002-03-22 01:27:54 +00001044 if (VG_(clo_verbosity) > 0)
1045 VG_(message)(Vg_UserMsg, "");
1046
1047 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001048
sewardj671ff542002-05-07 09:25:30 +00001049 VGP_PUSHCC(VgpSched);
sewardj2e93c502002-04-12 11:12:52 +00001050 VG_(scheduler_init)();
1051 src = VG_(scheduler)();
sewardj671ff542002-05-07 09:25:30 +00001052 VGP_POPCC;
sewardjde4a1d02002-03-22 01:27:54 +00001053
1054 if (VG_(clo_verbosity) > 0)
1055 VG_(message)(Vg_UserMsg, "");
1056
sewardj2e93c502002-04-12 11:12:52 +00001057 if (src == VgSrc_Deadlock) {
1058 VG_(message)(Vg_UserMsg,
1059 "Warning: pthread scheduler exited due to deadlock");
1060 }
1061
sewardjde4a1d02002-03-22 01:27:54 +00001062 if (VG_(clo_instrument)) {
1063 VG_(show_all_errors)();
1064 VG_(clientmalloc_done)();
1065 if (VG_(clo_verbosity) == 1) {
1066 VG_(message)(Vg_UserMsg,
1067 "For counts of detected errors, rerun with: -v");
1068 }
1069 if (VG_(clo_leak_check)) VG_(detect_memory_leaks)();
1070 }
1071 VG_(running_on_simd_CPU) = False;
sewardj2e93c502002-04-12 11:12:52 +00001072
njn4f9c9342002-04-29 16:03:24 +00001073 if (VG_(clo_cachesim))
1074 VG_(show_cachesim_results)(VG_(client_argc), VG_(client_argv));
1075
sewardj0c3b53f2002-05-01 01:58:35 +00001076 VG_(do_sanity_checks)( True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001077
1078 if (VG_(clo_verbosity) > 1)
1079 vg_show_counts();
1080
1081 if (0) {
1082 VG_(message)(Vg_DebugMsg, "");
1083 VG_(message)(Vg_DebugMsg,
1084 "------ Valgrind's internal memory use stats follow ------" );
1085 VG_(mallocSanityCheckAll)();
1086 VG_(show_all_arena_stats)();
1087 VG_(message)(Vg_DebugMsg,
1088 "------ Valgrind's ExeContext management stats follow ------" );
1089 VG_(show_ExeContext_stats)();
1090 VG_(message)(Vg_DebugMsg,
1091 "------ Valgrind's client block stats follow ---------------" );
1092 VG_(show_client_block_stats)();
1093 }
1094
1095# ifdef VG_PROFILE
1096 VGP_(done_profiling)();
1097# endif
1098
1099 VG_(done_prof_mem)();
1100
1101 VG_(shutdown_logging)();
1102
1103 /* In LD_PRELOAD, convert "valgrind.so" into "valgrinq.so", so that
1104 child processes don't get traced into. Also done on simulated
1105 execve system call. */
1106 if (!VG_(clo_trace_children)) {
1107 VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
1108 }
1109
sewardj7e87e382002-05-03 19:09:05 +00001110 /* Decide how to exit. This depends on what the scheduler
1111 returned. */
1112 switch (src) {
1113 case VgSrc_ExitSyscall: /* the normal way out */
1114 vg_assert(VG_(last_run_tid) > 0
1115 && VG_(last_run_tid) < VG_N_THREADS);
1116 tst = VG_(get_thread_state)(VG_(last_run_tid));
1117 vg_assert(tst->status == VgTs_Runnable);
1118 /* The thread's %EBX will hold the arg to exit(), so we just
1119 do exit with that arg. */
1120 VG_(exit)( tst->m_ebx );
1121 /* NOT ALIVE HERE! */
1122 VG_(panic)("entered the afterlife in vg_main() -- ExitSyscall");
1123 break; /* what the hell :) */
sewardjde4a1d02002-03-22 01:27:54 +00001124
sewardj7e87e382002-05-03 19:09:05 +00001125 case VgSrc_Deadlock:
1126 /* Just exit now. No point in continuing. */
1127 VG_(exit)(0);
1128 VG_(panic)("entered the afterlife in vg_main() -- Deadlock");
1129 break;
1130
1131 case VgSrc_BbsDone:
1132 /* Tricky; we have to try and switch back to the real CPU.
1133 This is all very dodgy and won't work at all in the
1134 presence of threads, or if the client happened to be
1135 running a signal handler. */
1136 /* Prepare to restore state to the real CPU. */
1137 VG_(load_thread_state)(1 /* root thread */ );
1138 VG_(copy_baseBlock_to_m_state_static)();
1139
1140 /* This pushes a return address on the simulator's stack,
1141 which is abandoned. We call vg_sigshutdown_actions() at
1142 the end of vg_switch_to_real_CPU(), so as to ensure that
1143 the original stack and machine state is restored before
1144 the real signal mechanism is restored. */
1145 VG_(switch_to_real_CPU)();
1146
1147 default:
1148 VG_(panic)("vg_main(): unexpected scheduler return code");
1149 }
sewardjde4a1d02002-03-22 01:27:54 +00001150}
1151
1152
1153/* Debugging thing .. can be called from assembly with OYNK macro. */
1154void VG_(oynk) ( Int n )
1155{
1156 OINK(n);
1157}
1158
1159
1160/* Find "valgrind.so" in a LD_PRELOAD=... string, and convert it to
1161 "valgrinq.so", which doesn't do anything. This is used to avoid
1162 tracing into child processes. To make this work the build system
1163 also supplies a dummy file, "valgrinq.so".
1164*/
1165void VG_(mash_LD_PRELOAD_string)( Char* ld_preload_str )
1166{
1167 Char* p;
1168 if (ld_preload_str == NULL)
1169 return;
1170 p = VG_(strstr)(ld_preload_str, "valgrind.so");
1171 if (p == NULL)
1172 return;
1173 p[7] = 'q';
1174}
1175
1176/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1177 it to attach to this process. Called if the user requests this
1178 service after an error has been shown, so she can poke around and
1179 look at parameters, memory, etc. You can't meaningfully get GDB to
1180 continue the program, though; to continue, quit GDB. */
1181extern void VG_(start_GDB_whilst_on_client_stack) ( void )
1182{
sewardje6a25242002-04-21 22:03:07 +00001183 Int res;
sewardjde4a1d02002-03-22 01:27:54 +00001184 UChar buf[100];
1185 VG_(sprintf)(buf,
1186 "/usr/bin/gdb -nw /proc/%d/exe %d",
1187 VG_(getpid)(), VG_(getpid)());
sewardje6a25242002-04-21 22:03:07 +00001188 VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
1189 res = VG_(system)(buf);
1190 if (res == 0) {
1191 VG_(message)(Vg_UserMsg, "");
1192 VG_(message)(Vg_UserMsg,
1193 "GDB has detached. Valgrind regains control. We continue.");
1194 } else {
1195 VG_(message)(Vg_UserMsg, "Apparently failed!");
1196 VG_(message)(Vg_UserMsg, "");
sewardjde4a1d02002-03-22 01:27:54 +00001197 }
sewardjde4a1d02002-03-22 01:27:54 +00001198}
1199
1200
1201/* Print some helpful-ish text about unimplemented things, and give
1202 up. */
sewardjcfc39b22002-05-08 01:58:18 +00001203void VG_(unimplemented) ( Char* msg )
sewardjde4a1d02002-03-22 01:27:54 +00001204{
1205 VG_(message)(Vg_UserMsg, "");
1206 VG_(message)(Vg_UserMsg,
1207 "Valgrind detected that your program requires");
1208 VG_(message)(Vg_UserMsg,
1209 "the following unimplemented functionality:");
1210 VG_(message)(Vg_UserMsg, " %s", msg);
1211 VG_(message)(Vg_UserMsg,
1212 "This may be because the functionality is hard to implement,");
1213 VG_(message)(Vg_UserMsg,
1214 "or because no reasonable program would behave this way,");
1215 VG_(message)(Vg_UserMsg,
1216 "or because nobody has yet needed it. In any case, let me know");
1217 VG_(message)(Vg_UserMsg,
1218 "(jseward@acm.org) and/or try to work around the problem, if you can.");
1219 VG_(message)(Vg_UserMsg,
1220 "");
1221 VG_(message)(Vg_UserMsg,
1222 "Valgrind has to exit now. Sorry. Bye!");
1223 VG_(message)(Vg_UserMsg,
1224 "");
sewardj15a43e12002-04-17 19:35:12 +00001225 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +00001226 VG_(exit)(1);
1227}
1228
1229
sewardjcfc39b22002-05-08 01:58:18 +00001230void VG_(nvidia_moan) ( void)
1231{
1232 VG_(message)(Vg_UserMsg,
1233 "The following failure _might_ be caused by linking to NVidia's\n "
1234 "libGL.so, so avoiding it, if you can, _might_ help you. For example,\n "
1235 "re-build any Qt libraries you are using without OpenGL support.");
1236}
1237
1238
sewardjde4a1d02002-03-22 01:27:54 +00001239/*--------------------------------------------------------------------*/
1240/*--- end vg_main.c ---*/
1241/*--------------------------------------------------------------------*/