blob: 1b6bba33be98896ad0369ba6aba1c6a7845d83d1 [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
484
485static void process_cmd_line_options ( void )
486{
487 UChar* argv[M_VG_CMDLINE_OPTS];
488 UInt argc;
489 UChar* p;
490 UChar* str;
491 Int i, eventually_logfile_fd;
492
493# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
494# define STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2)))
495# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
496
497 /* Set defaults. */
sewardj97ced732002-03-25 00:07:36 +0000498 VG_(clo_check_addrVs) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000499 VG_(clo_GDB_attach) = False;
500 VG_(sanity_level) = 1;
501 VG_(clo_verbosity) = 1;
502 VG_(clo_demangle) = True;
503 VG_(clo_leak_check) = False;
504 VG_(clo_show_reachable) = False;
505 VG_(clo_leak_resolution) = 2;
506 VG_(clo_sloppy_malloc) = False;
507 VG_(clo_partial_loads_ok) = True;
508 VG_(clo_trace_children) = False;
509 VG_(clo_logfile_fd) = 2; /* stderr */
510 VG_(clo_freelist_vol) = 1000000;
511 VG_(clo_workaround_gcc296_bugs) = False;
512 VG_(clo_n_suppressions) = 0;
513 VG_(clo_single_step) = False;
514 VG_(clo_optimise) = True;
515 VG_(clo_instrument) = True;
516 VG_(clo_cleanup) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000517 VG_(clo_smc_check) = /* VG_CLO_SMC_SOME */ VG_CLO_SMC_NONE;
518 VG_(clo_trace_syscalls) = False;
519 VG_(clo_trace_signals) = False;
520 VG_(clo_trace_symtab) = False;
521 VG_(clo_trace_malloc) = False;
sewardj8937c812002-04-12 20:12:20 +0000522 VG_(clo_trace_sched) = False;
sewardj45b4b372002-04-16 22:50:32 +0000523 VG_(clo_trace_pthread_level) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000524 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
njn4f9c9342002-04-29 16:03:24 +0000760 else if (STREQ(argv[i], "--cachesim=yes"))
761 VG_(clo_cachesim) = True;
762 else if (STREQ(argv[i], "--cachesim=no"))
763 VG_(clo_cachesim) = False;
764
sewardjde4a1d02002-03-22 01:27:54 +0000765 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
sewardj8937c812002-04-12 20:12:20 +0000792 else if (STREQ(argv[i], "--trace-sched=yes"))
793 VG_(clo_trace_sched) = True;
794 else if (STREQ(argv[i], "--trace-sched=no"))
795 VG_(clo_trace_sched) = False;
796
sewardj45b4b372002-04-16 22:50:32 +0000797 else if (STREQ(argv[i], "--trace-pthread=none"))
798 VG_(clo_trace_pthread_level) = 0;
799 else if (STREQ(argv[i], "--trace-pthread=some"))
800 VG_(clo_trace_pthread_level) = 1;
801 else if (STREQ(argv[i], "--trace-pthread=all"))
802 VG_(clo_trace_pthread_level) = 2;
sewardj8937c812002-04-12 20:12:20 +0000803
sewardjde4a1d02002-03-22 01:27:54 +0000804 else if (STREQN(13, argv[i], "--stop-after="))
805 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
806
807 else if (STREQN(13, argv[i], "--dump-error="))
808 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
809
810 else if (STREQN(14, argv[i], "--num-callers=")) {
811 /* Make sure it's sane. */
812 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
813 if (VG_(clo_backtrace_size) < 2)
814 VG_(clo_backtrace_size) = 2;
815 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
816 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
817 }
818
819 else
820 bad_option(argv[i]);
821 }
822
823# undef ISSPACE
824# undef STREQ
825# undef STREQN
826
827 if (VG_(clo_verbosity < 0))
828 VG_(clo_verbosity) = 0;
829
830 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
831 VG_(message)(Vg_UserMsg, "");
832 VG_(message)(Vg_UserMsg,
833 "--gdb-attach=yes conflicts with --trace-children=yes");
834 VG_(message)(Vg_UserMsg,
835 "Please choose one or the other, but not both.");
836 bad_option("--gdb-attach=yes and --trace-children=yes");
837 }
838
sewardjde4a1d02002-03-22 01:27:54 +0000839 VG_(clo_logfile_fd) = eventually_logfile_fd;
840
njn4f9c9342002-04-29 16:03:24 +0000841 /* Don't do memory checking if simulating the cache. */
842 if (VG_(clo_cachesim)) {
843 VG_(clo_instrument) = False;
844 }
845
sewardj83adf412002-05-01 01:25:45 +0000846 if (VG_(clo_verbosity > 0)) {
847 if (VG_(clo_cachesim)) {
848 VG_(message)(Vg_UserMsg,
849 "cachegrind-%s, an I1/D1/L2 cache profiler for x86 GNU/Linux.",
850 VERSION);
851 } else {
852 VG_(message)(Vg_UserMsg,
853 "valgrind-%s, a memory error detector for x86 GNU/Linux.",
854 VERSION);
855 }
856 }
sewardj3b2736a2002-03-24 12:18:35 +0000857
sewardjde4a1d02002-03-22 01:27:54 +0000858 if (VG_(clo_verbosity > 0))
859 VG_(message)(Vg_UserMsg,
860 "Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.");
861 if (VG_(clo_verbosity) > 1) {
862 VG_(message)(Vg_UserMsg, "Startup, with flags:");
863 for (i = 0; i < argc; i++) {
864 VG_(message)(Vg_UserMsg, " %s", argv[i]);
865 }
866 }
867
sewardj83adf412002-05-01 01:25:45 +0000868 if (VG_(clo_n_suppressions) == 0 && !VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +0000869 config_error("No error-suppression files were specified.");
870 }
871}
872
873
874/* ---------------------------------------------------------------------
875 Copying to/from m_state_static.
876 ------------------------------------------------------------------ */
877
878UInt VG_(m_state_static) [8 /* int regs, in Intel order */
879 + 1 /* %eflags */
880 + 1 /* %eip */
881 + VG_SIZE_OF_FPUSTATE_W /* FPU state */
882 ];
883
884void VG_(copy_baseBlock_to_m_state_static) ( void )
885{
886 Int i;
887 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
888 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
889 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
890 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
891 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
892 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
893 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
894 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
895
896 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_eflags)];
897 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
898
899 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
900 VG_(m_state_static)[40/4 + i]
901 = VG_(baseBlock)[VGOFF_(m_fpustate) + i];
902}
903
904
905void VG_(copy_m_state_static_to_baseBlock) ( void )
906{
907 Int i;
908 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
909 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
910 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
911 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
912 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
913 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
914 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
915 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
916
917 VG_(baseBlock)[VGOFF_(m_eflags)] = VG_(m_state_static)[32/4];
918 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
919
920 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
921 VG_(baseBlock)[VGOFF_(m_fpustate) + i]
922 = VG_(m_state_static)[40/4 + i];
923}
924
925
926/* ---------------------------------------------------------------------
927 Show accumulated counts.
928 ------------------------------------------------------------------ */
929
930static void vg_show_counts ( void )
931{
932 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000933 " lru: %d epochs, %d clearings.",
934 VG_(current_epoch),
935 VG_(number_of_lrus) );
sewardjde4a1d02002-03-22 01:27:54 +0000936 VG_(message)(Vg_DebugMsg,
937 "translate: new %d (%d -> %d), discard %d (%d -> %d).",
938 VG_(overall_in_count),
939 VG_(overall_in_osize),
940 VG_(overall_in_tsize),
941 VG_(overall_out_count),
942 VG_(overall_out_osize),
943 VG_(overall_out_tsize) );
944 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000945 " dispatch: %lu basic blocks, %d/%d sched events, %d tt_fast misses.",
946 VG_(bbs_done), VG_(num_scheduling_events_MAJOR),
947 VG_(num_scheduling_events_MINOR),
948 VG_(tt_fast_misses));
sewardjde4a1d02002-03-22 01:27:54 +0000949 VG_(message)(Vg_DebugMsg,
950 "reg-alloc: %d t-req-spill, "
951 "%d+%d orig+spill uis, %d total-reg-r.",
952 VG_(translations_needing_spill),
953 VG_(uinstrs_prealloc),
954 VG_(uinstrs_spill),
955 VG_(total_reg_rank) );
956 VG_(message)(Vg_DebugMsg,
957 "smc-check: %d checks, %d fast pass, "
958 "%d slow pass, %d discards.",
959 VG_(smc_total_check4s),
960 VG_(smc_cache_passed),
961 VG_(smc_fancy_passed),
962 VG_(smc_discard_count) );
963 VG_(message)(Vg_DebugMsg,
964 " sanity: %d cheap, %d expensive checks.",
965 VG_(sanity_fast_count),
966 VG_(sanity_slow_count) );
967}
968
969
970/* ---------------------------------------------------------------------
971 Main!
972 ------------------------------------------------------------------ */
973
974/* Where we jump to once Valgrind has got control, and the real
975 machine's state has been copied to the m_state_static. */
976
977void VG_(main) ( void )
978{
sewardj2e93c502002-04-12 11:12:52 +0000979 Int i;
980 VgSchedReturnCode src;
sewardj7e87e382002-05-03 19:09:05 +0000981 ThreadState* tst;
sewardjde4a1d02002-03-22 01:27:54 +0000982
983 /* Set up our stack sanity-check words. */
984 for (i = 0; i < 10; i++) {
985 VG_(stack)[i] = (UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1;
986 VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321;
987 }
988
989 /* Set up baseBlock offsets and copy the saved machine's state into
990 it. */
991 vg_init_baseBlock();
992 VG_(copy_m_state_static_to_baseBlock)();
993
994 /* Process Valgrind's command-line opts (from env var VG_OPTS). */
995 process_cmd_line_options();
996
997 /* Initialise the signal handling subsystem. */
998 VG_(sigstartup_actions)();
999
1000# ifdef VG_PROFILE
1001 VGP_(init_profiling)();
1002# endif
1003
sewardj5f07b662002-04-23 16:52:51 +00001004 /* Start calibration of our RDTSC-based clock. */
1005 VG_(start_rdtsc_calibration)();
1006
sewardjb3c26872002-03-24 10:05:14 +00001007 /* Hook to delay things long enough so we can get the pid and
1008 attach GDB in another shell. */
1009 /* {extern unsigned int sleep(unsigned int seconds); sleep(10);} */
1010
njn4f9c9342002-04-29 16:03:24 +00001011 if (VG_(clo_instrument) || VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +00001012 VGP_PUSHCC(VgpInitAudit);
1013 VGM_(init_memory_audit)();
1014 VGP_POPCC;
1015 VGP_PUSHCC(VgpReadSyms);
1016 VG_(read_symbols)();
1017 VGP_POPCC;
1018 }
1019
sewardj5f07b662002-04-23 16:52:51 +00001020 /* End calibration of our RDTSC-based clock, leaving it as long as
1021 we can. */
1022 VG_(end_rdtsc_calibration)();
1023
sewardjde4a1d02002-03-22 01:27:54 +00001024 /* This should come after init_memory_audit; otherwise the latter
1025 carefully sets up the permissions maps to cover the anonymous
1026 mmaps for the translation table and translation cache, which
1027 wastes > 20M of virtual address space. */
1028 VG_(init_transtab_and_SMC)();
1029
1030 if (VG_(clo_verbosity) == 1) {
1031 VG_(message)(Vg_UserMsg,
1032 "For more details, rerun with: -v");
1033 }
1034
1035 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1036 instrumented-ly. */
1037 VG_(running_on_simd_CPU) = True;
1038 if (VG_(clo_instrument)) {
1039 VGM_(make_readable) ( (Addr)&VG_(running_on_simd_CPU), 1 );
1040 VGM_(make_readable) ( (Addr)&VG_(clo_instrument), 1 );
1041 VGM_(make_readable) ( (Addr)&VG_(clo_trace_malloc), 1 );
1042 VGM_(make_readable) ( (Addr)&VG_(clo_sloppy_malloc), 1 );
1043 }
1044
njn4f9c9342002-04-29 16:03:24 +00001045 if (VG_(clo_cachesim))
1046 VG_(init_cachesim)();
1047
sewardjde4a1d02002-03-22 01:27:54 +00001048 if (VG_(clo_verbosity) > 0)
1049 VG_(message)(Vg_UserMsg, "");
1050
1051 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001052
1053 VG_(scheduler_init)();
1054 src = VG_(scheduler)();
sewardjde4a1d02002-03-22 01:27:54 +00001055
1056 if (VG_(clo_verbosity) > 0)
1057 VG_(message)(Vg_UserMsg, "");
1058
sewardj2e93c502002-04-12 11:12:52 +00001059 if (src == VgSrc_Deadlock) {
1060 VG_(message)(Vg_UserMsg,
1061 "Warning: pthread scheduler exited due to deadlock");
1062 }
1063
sewardjde4a1d02002-03-22 01:27:54 +00001064 if (VG_(clo_instrument)) {
1065 VG_(show_all_errors)();
1066 VG_(clientmalloc_done)();
1067 if (VG_(clo_verbosity) == 1) {
1068 VG_(message)(Vg_UserMsg,
1069 "For counts of detected errors, rerun with: -v");
1070 }
1071 if (VG_(clo_leak_check)) VG_(detect_memory_leaks)();
1072 }
1073 VG_(running_on_simd_CPU) = False;
sewardj2e93c502002-04-12 11:12:52 +00001074
njn4f9c9342002-04-29 16:03:24 +00001075 if (VG_(clo_cachesim))
1076 VG_(show_cachesim_results)(VG_(client_argc), VG_(client_argv));
1077
sewardj0c3b53f2002-05-01 01:58:35 +00001078 VG_(do_sanity_checks)( True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001079
1080 if (VG_(clo_verbosity) > 1)
1081 vg_show_counts();
1082
1083 if (0) {
1084 VG_(message)(Vg_DebugMsg, "");
1085 VG_(message)(Vg_DebugMsg,
1086 "------ Valgrind's internal memory use stats follow ------" );
1087 VG_(mallocSanityCheckAll)();
1088 VG_(show_all_arena_stats)();
1089 VG_(message)(Vg_DebugMsg,
1090 "------ Valgrind's ExeContext management stats follow ------" );
1091 VG_(show_ExeContext_stats)();
1092 VG_(message)(Vg_DebugMsg,
1093 "------ Valgrind's client block stats follow ---------------" );
1094 VG_(show_client_block_stats)();
1095 }
1096
1097# ifdef VG_PROFILE
1098 VGP_(done_profiling)();
1099# endif
1100
1101 VG_(done_prof_mem)();
1102
1103 VG_(shutdown_logging)();
1104
1105 /* In LD_PRELOAD, convert "valgrind.so" into "valgrinq.so", so that
1106 child processes don't get traced into. Also done on simulated
1107 execve system call. */
1108 if (!VG_(clo_trace_children)) {
1109 VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
1110 }
1111
sewardj7e87e382002-05-03 19:09:05 +00001112 /* Decide how to exit. This depends on what the scheduler
1113 returned. */
1114 switch (src) {
1115 case VgSrc_ExitSyscall: /* the normal way out */
1116 vg_assert(VG_(last_run_tid) > 0
1117 && VG_(last_run_tid) < VG_N_THREADS);
1118 tst = VG_(get_thread_state)(VG_(last_run_tid));
1119 vg_assert(tst->status == VgTs_Runnable);
1120 /* The thread's %EBX will hold the arg to exit(), so we just
1121 do exit with that arg. */
1122 VG_(exit)( tst->m_ebx );
1123 /* NOT ALIVE HERE! */
1124 VG_(panic)("entered the afterlife in vg_main() -- ExitSyscall");
1125 break; /* what the hell :) */
sewardjde4a1d02002-03-22 01:27:54 +00001126
sewardj7e87e382002-05-03 19:09:05 +00001127 case VgSrc_Deadlock:
1128 /* Just exit now. No point in continuing. */
1129 VG_(exit)(0);
1130 VG_(panic)("entered the afterlife in vg_main() -- Deadlock");
1131 break;
1132
1133 case VgSrc_BbsDone:
1134 /* Tricky; we have to try and switch back to the real CPU.
1135 This is all very dodgy and won't work at all in the
1136 presence of threads, or if the client happened to be
1137 running a signal handler. */
1138 /* Prepare to restore state to the real CPU. */
1139 VG_(load_thread_state)(1 /* root thread */ );
1140 VG_(copy_baseBlock_to_m_state_static)();
1141
1142 /* This pushes a return address on the simulator's stack,
1143 which is abandoned. We call vg_sigshutdown_actions() at
1144 the end of vg_switch_to_real_CPU(), so as to ensure that
1145 the original stack and machine state is restored before
1146 the real signal mechanism is restored. */
1147 VG_(switch_to_real_CPU)();
1148
1149 default:
1150 VG_(panic)("vg_main(): unexpected scheduler return code");
1151 }
sewardjde4a1d02002-03-22 01:27:54 +00001152}
1153
1154
1155/* Debugging thing .. can be called from assembly with OYNK macro. */
1156void VG_(oynk) ( Int n )
1157{
1158 OINK(n);
1159}
1160
1161
1162/* Find "valgrind.so" in a LD_PRELOAD=... string, and convert it to
1163 "valgrinq.so", which doesn't do anything. This is used to avoid
1164 tracing into child processes. To make this work the build system
1165 also supplies a dummy file, "valgrinq.so".
1166*/
1167void VG_(mash_LD_PRELOAD_string)( Char* ld_preload_str )
1168{
1169 Char* p;
1170 if (ld_preload_str == NULL)
1171 return;
1172 p = VG_(strstr)(ld_preload_str, "valgrind.so");
1173 if (p == NULL)
1174 return;
1175 p[7] = 'q';
1176}
1177
1178/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1179 it to attach to this process. Called if the user requests this
1180 service after an error has been shown, so she can poke around and
1181 look at parameters, memory, etc. You can't meaningfully get GDB to
1182 continue the program, though; to continue, quit GDB. */
1183extern void VG_(start_GDB_whilst_on_client_stack) ( void )
1184{
sewardje6a25242002-04-21 22:03:07 +00001185 Int res;
sewardjde4a1d02002-03-22 01:27:54 +00001186 UChar buf[100];
1187 VG_(sprintf)(buf,
1188 "/usr/bin/gdb -nw /proc/%d/exe %d",
1189 VG_(getpid)(), VG_(getpid)());
sewardje6a25242002-04-21 22:03:07 +00001190 VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
1191 res = VG_(system)(buf);
1192 if (res == 0) {
1193 VG_(message)(Vg_UserMsg, "");
1194 VG_(message)(Vg_UserMsg,
1195 "GDB has detached. Valgrind regains control. We continue.");
1196 } else {
1197 VG_(message)(Vg_UserMsg, "Apparently failed!");
1198 VG_(message)(Vg_UserMsg, "");
sewardjde4a1d02002-03-22 01:27:54 +00001199 }
sewardjde4a1d02002-03-22 01:27:54 +00001200}
1201
1202
1203/* Print some helpful-ish text about unimplemented things, and give
1204 up. */
1205extern void VG_(unimplemented) ( Char* msg )
1206{
1207 VG_(message)(Vg_UserMsg, "");
1208 VG_(message)(Vg_UserMsg,
1209 "Valgrind detected that your program requires");
1210 VG_(message)(Vg_UserMsg,
1211 "the following unimplemented functionality:");
1212 VG_(message)(Vg_UserMsg, " %s", msg);
1213 VG_(message)(Vg_UserMsg,
1214 "This may be because the functionality is hard to implement,");
1215 VG_(message)(Vg_UserMsg,
1216 "or because no reasonable program would behave this way,");
1217 VG_(message)(Vg_UserMsg,
1218 "or because nobody has yet needed it. In any case, let me know");
1219 VG_(message)(Vg_UserMsg,
1220 "(jseward@acm.org) and/or try to work around the problem, if you can.");
1221 VG_(message)(Vg_UserMsg,
1222 "");
1223 VG_(message)(Vg_UserMsg,
1224 "Valgrind has to exit now. Sorry. Bye!");
1225 VG_(message)(Vg_UserMsg,
1226 "");
sewardj15a43e12002-04-17 19:35:12 +00001227 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +00001228 VG_(exit)(1);
1229}
1230
1231
sewardjde4a1d02002-03-22 01:27:54 +00001232/*--------------------------------------------------------------------*/
1233/*--- end vg_main.c ---*/
1234/*--------------------------------------------------------------------*/