blob: 0d965a6b2e4630f7d28fe977f7c76c837c0978cd [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);
sewardj8d365b52002-05-12 10:52:16 +0000444Char* VG_(clo_weird_hacks);
sewardjde4a1d02002-03-22 01:27:54 +0000445
446/* This Bool is needed by wrappers in vg_clientmalloc.c to decide how
447 to behave. Initially we say False. */
448Bool VG_(running_on_simd_CPU) = False;
449
450/* Holds client's %esp at the point we gained control. */
451Addr VG_(esp_at_startup);
452
453/* As deduced from VG_(esp_at_startup), the client's argc, argv[] and
454 envp[] as extracted from the client's stack at startup-time. */
455Int VG_(client_argc);
456Char** VG_(client_argv);
457Char** VG_(client_envp);
458
459/* A place into which to copy the value of env var VG_ARGS, so we
460 don't have to modify the original. */
461static Char vg_cmdline_copy[M_VG_CMDLINE_STRLEN];
462
463
464/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000465 Processing of command-line options.
466 ------------------------------------------------------------------ */
467
468static void bad_option ( Char* opt )
469{
470 VG_(shutdown_logging)();
471 VG_(clo_logfile_fd) = 2; /* stderr */
472 VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
473 VG_(exit)(1);
474}
475
476static void config_error ( Char* msg )
477{
478 VG_(shutdown_logging)();
479 VG_(clo_logfile_fd) = 2; /* stderr */
480 VG_(printf)("valgrind.so: Startup or configuration error:\n\t%s\n", msg);
481 VG_(printf)("valgrind.so: Unable to start up properly. Giving up.\n");
482 VG_(exit)(1);
483}
484
sewardja1679dd2002-05-10 22:31:40 +0000485static void args_grok_error ( Char* msg )
486{
487 VG_(shutdown_logging)();
488 VG_(clo_logfile_fd) = 2; /* stderr */
489 VG_(printf)("valgrind.so: When searching for "
490 "client's argc/argc/envp:\n\t%s\n", msg);
491 config_error("couldn't find client's argc/argc/envp");
492}
493
sewardjde4a1d02002-03-22 01:27:54 +0000494
495static void process_cmd_line_options ( void )
496{
497 UChar* argv[M_VG_CMDLINE_OPTS];
498 UInt argc;
499 UChar* p;
500 UChar* str;
sewardja1679dd2002-05-10 22:31:40 +0000501 Int i, eventually_logfile_fd, ctr;
sewardjde4a1d02002-03-22 01:27:54 +0000502
503# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
504# define STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2)))
505# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
506
507 /* Set defaults. */
sewardj97ced732002-03-25 00:07:36 +0000508 VG_(clo_check_addrVs) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000509 VG_(clo_GDB_attach) = False;
510 VG_(sanity_level) = 1;
511 VG_(clo_verbosity) = 1;
512 VG_(clo_demangle) = True;
513 VG_(clo_leak_check) = False;
514 VG_(clo_show_reachable) = False;
515 VG_(clo_leak_resolution) = 2;
516 VG_(clo_sloppy_malloc) = False;
517 VG_(clo_partial_loads_ok) = True;
518 VG_(clo_trace_children) = False;
519 VG_(clo_logfile_fd) = 2; /* stderr */
520 VG_(clo_freelist_vol) = 1000000;
521 VG_(clo_workaround_gcc296_bugs) = False;
522 VG_(clo_n_suppressions) = 0;
523 VG_(clo_single_step) = False;
524 VG_(clo_optimise) = True;
525 VG_(clo_instrument) = True;
526 VG_(clo_cleanup) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000527 VG_(clo_smc_check) = /* VG_CLO_SMC_SOME */ VG_CLO_SMC_NONE;
528 VG_(clo_trace_syscalls) = False;
529 VG_(clo_trace_signals) = False;
530 VG_(clo_trace_symtab) = False;
531 VG_(clo_trace_malloc) = False;
sewardj8937c812002-04-12 20:12:20 +0000532 VG_(clo_trace_sched) = False;
sewardj45b4b372002-04-16 22:50:32 +0000533 VG_(clo_trace_pthread_level) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000534 VG_(clo_stop_after) = 1000000000000LL;
535 VG_(clo_dump_error) = 0;
536 VG_(clo_backtrace_size) = 4;
sewardj8d365b52002-05-12 10:52:16 +0000537 VG_(clo_weird_hacks) = NULL;
sewardjde4a1d02002-03-22 01:27:54 +0000538
539 eventually_logfile_fd = VG_(clo_logfile_fd);
540
541 /* Once logging is started, we can safely send messages pertaining
542 to failures in initialisation. */
543 VG_(startup_logging)();
544
sewardj38170912002-05-10 21:07:22 +0000545
sewardja1679dd2002-05-10 22:31:40 +0000546 /* (Suggested by Fabrice Bellard ... )
547 We look for the Linux ELF table and go down until we find the
sewardj38170912002-05-10 21:07:22 +0000548 envc & envp. It is not full proof, but these structures should
549 change less often than the libc ones. */
550 {
sewardja1679dd2002-05-10 22:31:40 +0000551 UInt* sp = 0; /* bogus init to keep gcc -O happy */
552
sewardj38170912002-05-10 21:07:22 +0000553 /* locate the top of the stack */
sewardja1679dd2002-05-10 22:31:40 +0000554 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
555 VG_STARTUP_STACK_BASE_1 )) {
556 sp = (UInt*)VG_STARTUP_STACK_BASE_1;
557 } else
558 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
559 VG_STARTUP_STACK_BASE_2 )) {
560 sp = (UInt*)VG_STARTUP_STACK_BASE_2;
561 } else {
562 args_grok_error(
563 "startup %esp is not near any VG_STARTUP_STACK_BASE_*\n "
564 "constants defined in vg_include.h. You should investigate."
565 );
566 }
567
sewardj38170912002-05-10 21:07:22 +0000568 /* we locate: NEW_AUX_ENT(1, AT_PAGESZ, ELF_EXEC_PAGESIZE) in
569 the elf interpreter table */
570 sp -= 2;
sewardj38170912002-05-10 21:07:22 +0000571 while (sp[0] != VKI_AT_PAGESZ || sp[1] != 4096) {
sewardja1679dd2002-05-10 22:31:40 +0000572 /* VG_(printf)("trying %p\n", sp); */
sewardj38170912002-05-10 21:07:22 +0000573 sp--;
574 }
sewardj38170912002-05-10 21:07:22 +0000575
576 if (sp[2] == VKI_AT_BASE
577 && sp[0] == VKI_AT_PAGESZ
578 && sp[-2] == VKI_AT_PHNUM
579 && sp[-4] == VKI_AT_PHENT
580 && sp[-6] == VKI_AT_PHDR) {
sewardja1679dd2002-05-10 22:31:40 +0000581 if (0)
582 VG_(printf)("Looks like you've got a 2.2.X kernel here.\n");
sewardj38170912002-05-10 21:07:22 +0000583 sp -= 6;
sewardja1679dd2002-05-10 22:31:40 +0000584 } else
585 if (sp[2] == VKI_AT_CLKTCK
586 && sp[0] == VKI_AT_PAGESZ
587 && sp[-2] == VKI_AT_HWCAP) {
588 if (0)
589 VG_(printf)("Looks like you've got a 2.4.X kernel here.\n");
590 sp -= 2;
591 } else
592 args_grok_error(
593 "ELF frame does not look like 2.2.X or 2.4.X.\n "
594 "See kernel sources linux/fs/binfmt_elf.c to make sense of this."
595 );
sewardj38170912002-05-10 21:07:22 +0000596
597 sp--;
sewardja1679dd2002-05-10 22:31:40 +0000598 if (*sp != 0)
599 args_grok_error("can't find NULL at end of env[]");
600
sewardj38170912002-05-10 21:07:22 +0000601 /* sp now points to NULL at the end of env[] */
sewardja1679dd2002-05-10 22:31:40 +0000602 ctr = 0;
sewardj38170912002-05-10 21:07:22 +0000603 while (True) {
604 sp --;
605 if (*sp == 0) break;
sewardja1679dd2002-05-10 22:31:40 +0000606 if (++ctr >= 1000)
607 args_grok_error(
608 "suspiciously many (1000) env[] entries; giving up");
609
sewardj38170912002-05-10 21:07:22 +0000610 }
611 /* sp now points to NULL at the end of argv[] */
sewardja1679dd2002-05-10 22:31:40 +0000612 VG_(client_envp) = (Char**)(sp+1);
sewardj38170912002-05-10 21:07:22 +0000613
sewardja1679dd2002-05-10 22:31:40 +0000614 ctr = 0;
sewardj38170912002-05-10 21:07:22 +0000615 VG_(client_argc) = 0;
616 while (True) {
617 sp--;
618 if (*sp == VG_(client_argc))
619 break;
620 VG_(client_argc)++;
sewardja1679dd2002-05-10 22:31:40 +0000621 if (++ctr >= 1000)
622 args_grok_error(
623 "suspiciously many (1000) argv[] entries; giving up");
sewardj38170912002-05-10 21:07:22 +0000624 }
625
sewardja1679dd2002-05-10 22:31:40 +0000626 VG_(client_argv) = (Char**)(sp+1);
sewardj38170912002-05-10 21:07:22 +0000627 }
628
sewardjde4a1d02002-03-22 01:27:54 +0000629 /* Now that VG_(client_envp) has been set, we can extract the args
630 for Valgrind itself. Copy into global var so that we don't have to
631 write zeroes to the getenv'd value itself. */
632 str = VG_(getenv)("VG_ARGS");
633 argc = 0;
634
635 if (!str) {
636 config_error("Can't read options from env var VG_ARGS.");
637 }
638
639 if (VG_(strlen)(str) >= M_VG_CMDLINE_STRLEN-1) {
640 config_error("Command line length exceeds M_CMDLINE_STRLEN.");
641 }
642 VG_(strcpy)(vg_cmdline_copy, str);
643 str = NULL;
644
645 p = &vg_cmdline_copy[0];
646 while (True) {
647 while (ISSPACE(*p)) { *p = 0; p++; }
648 if (*p == 0) break;
649 if (argc < M_VG_CMDLINE_OPTS-1) {
650 argv[argc] = p; argc++;
651 } else {
652 config_error(
653 "Found more than M_CMDLINE_OPTS command-line opts.");
654 }
655 while (*p != 0 && !ISSPACE(*p)) p++;
656 }
657
658 for (i = 0; i < argc; i++) {
659
660 if (STREQ(argv[i], "-v") || STREQ(argv[i], "--verbose"))
661 VG_(clo_verbosity)++;
662 else if (STREQ(argv[i], "-q") || STREQ(argv[i], "--quiet"))
663 VG_(clo_verbosity)--;
664
sewardj97ced732002-03-25 00:07:36 +0000665 else if (STREQ(argv[i], "--check-addrVs=yes"))
666 VG_(clo_check_addrVs) = True;
667 else if (STREQ(argv[i], "--check-addrVs=no"))
668 VG_(clo_check_addrVs) = False;
669
sewardjde4a1d02002-03-22 01:27:54 +0000670 else if (STREQ(argv[i], "--gdb-attach=yes"))
671 VG_(clo_GDB_attach) = True;
672 else if (STREQ(argv[i], "--gdb-attach=no"))
673 VG_(clo_GDB_attach) = False;
674
675 else if (STREQ(argv[i], "--demangle=yes"))
676 VG_(clo_demangle) = True;
677 else if (STREQ(argv[i], "--demangle=no"))
678 VG_(clo_demangle) = False;
679
680 else if (STREQ(argv[i], "--partial-loads-ok=yes"))
681 VG_(clo_partial_loads_ok) = True;
682 else if (STREQ(argv[i], "--partial-loads-ok=no"))
683 VG_(clo_partial_loads_ok) = False;
684
685 else if (STREQ(argv[i], "--leak-check=yes"))
686 VG_(clo_leak_check) = True;
687 else if (STREQ(argv[i], "--leak-check=no"))
688 VG_(clo_leak_check) = False;
689
690 else if (STREQ(argv[i], "--show-reachable=yes"))
691 VG_(clo_show_reachable) = True;
692 else if (STREQ(argv[i], "--show-reachable=no"))
693 VG_(clo_show_reachable) = False;
694
695 else if (STREQ(argv[i], "--leak-resolution=low"))
696 VG_(clo_leak_resolution) = 2;
697 else if (STREQ(argv[i], "--leak-resolution=med"))
698 VG_(clo_leak_resolution) = 4;
699 else if (STREQ(argv[i], "--leak-resolution=high"))
700 VG_(clo_leak_resolution) = VG_DEEPEST_BACKTRACE;
701
702 else if (STREQ(argv[i], "--sloppy-malloc=yes"))
703 VG_(clo_sloppy_malloc) = True;
704 else if (STREQ(argv[i], "--sloppy-malloc=no"))
705 VG_(clo_sloppy_malloc) = False;
706
707 else if (STREQ(argv[i], "--trace-children=yes"))
708 VG_(clo_trace_children) = True;
709 else if (STREQ(argv[i], "--trace-children=no"))
710 VG_(clo_trace_children) = False;
711
712 else if (STREQ(argv[i], "--workaround-gcc296-bugs=yes"))
713 VG_(clo_workaround_gcc296_bugs) = True;
714 else if (STREQ(argv[i], "--workaround-gcc296-bugs=no"))
715 VG_(clo_workaround_gcc296_bugs) = False;
716
717 else if (STREQN(15, argv[i], "--sanity-level="))
718 VG_(sanity_level) = (Int)VG_(atoll)(&argv[i][15]);
719
720 else if (STREQN(13, argv[i], "--logfile-fd="))
721 eventually_logfile_fd = (Int)VG_(atoll)(&argv[i][13]);
722
723 else if (STREQN(15, argv[i], "--freelist-vol=")) {
724 VG_(clo_freelist_vol) = (Int)VG_(atoll)(&argv[i][15]);
725 if (VG_(clo_freelist_vol) < 0) VG_(clo_freelist_vol) = 2;
726 }
727
728 else if (STREQN(15, argv[i], "--suppressions=")) {
729 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
730 VG_(message)(Vg_UserMsg, "Too many logfiles specified.");
731 VG_(message)(Vg_UserMsg,
732 "Increase VG_CLO_MAX_SFILES and recompile.");
733 bad_option(argv[i]);
734 }
735 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &argv[i][15];
736 VG_(clo_n_suppressions)++;
737 }
738 else if (STREQ(argv[i], "--single-step=yes"))
739 VG_(clo_single_step) = True;
740 else if (STREQ(argv[i], "--single-step=no"))
741 VG_(clo_single_step) = False;
742
743 else if (STREQ(argv[i], "--optimise=yes"))
744 VG_(clo_optimise) = True;
745 else if (STREQ(argv[i], "--optimise=no"))
746 VG_(clo_optimise) = False;
747
748 else if (STREQ(argv[i], "--instrument=yes"))
749 VG_(clo_instrument) = True;
750 else if (STREQ(argv[i], "--instrument=no"))
751 VG_(clo_instrument) = False;
752
753 else if (STREQ(argv[i], "--cleanup=yes"))
754 VG_(clo_cleanup) = True;
755 else if (STREQ(argv[i], "--cleanup=no"))
756 VG_(clo_cleanup) = False;
757
njn4f9c9342002-04-29 16:03:24 +0000758 else if (STREQ(argv[i], "--cachesim=yes"))
759 VG_(clo_cachesim) = True;
760 else if (STREQ(argv[i], "--cachesim=no"))
761 VG_(clo_cachesim) = False;
762
sewardjde4a1d02002-03-22 01:27:54 +0000763 else if (STREQ(argv[i], "--smc-check=none"))
764 VG_(clo_smc_check) = VG_CLO_SMC_NONE;
765 else if (STREQ(argv[i], "--smc-check=some"))
766 VG_(clo_smc_check) = VG_CLO_SMC_SOME;
767 else if (STREQ(argv[i], "--smc-check=all"))
768 VG_(clo_smc_check) = VG_CLO_SMC_ALL;
769
770 else if (STREQ(argv[i], "--trace-syscalls=yes"))
771 VG_(clo_trace_syscalls) = True;
772 else if (STREQ(argv[i], "--trace-syscalls=no"))
773 VG_(clo_trace_syscalls) = False;
774
775 else if (STREQ(argv[i], "--trace-signals=yes"))
776 VG_(clo_trace_signals) = True;
777 else if (STREQ(argv[i], "--trace-signals=no"))
778 VG_(clo_trace_signals) = False;
779
780 else if (STREQ(argv[i], "--trace-symtab=yes"))
781 VG_(clo_trace_symtab) = True;
782 else if (STREQ(argv[i], "--trace-symtab=no"))
783 VG_(clo_trace_symtab) = False;
784
785 else if (STREQ(argv[i], "--trace-malloc=yes"))
786 VG_(clo_trace_malloc) = True;
787 else if (STREQ(argv[i], "--trace-malloc=no"))
788 VG_(clo_trace_malloc) = False;
789
sewardj8937c812002-04-12 20:12:20 +0000790 else if (STREQ(argv[i], "--trace-sched=yes"))
791 VG_(clo_trace_sched) = True;
792 else if (STREQ(argv[i], "--trace-sched=no"))
793 VG_(clo_trace_sched) = False;
794
sewardj45b4b372002-04-16 22:50:32 +0000795 else if (STREQ(argv[i], "--trace-pthread=none"))
796 VG_(clo_trace_pthread_level) = 0;
797 else if (STREQ(argv[i], "--trace-pthread=some"))
798 VG_(clo_trace_pthread_level) = 1;
799 else if (STREQ(argv[i], "--trace-pthread=all"))
800 VG_(clo_trace_pthread_level) = 2;
sewardj8937c812002-04-12 20:12:20 +0000801
sewardj8d365b52002-05-12 10:52:16 +0000802 else if (STREQN(14, argv[i], "--weird-hacks="))
803 VG_(clo_weird_hacks) = &argv[i][14];
sewardj3984b852002-05-12 03:00:17 +0000804
sewardjde4a1d02002-03-22 01:27:54 +0000805 else if (STREQN(13, argv[i], "--stop-after="))
806 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
807
808 else if (STREQN(13, argv[i], "--dump-error="))
809 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
810
811 else if (STREQN(14, argv[i], "--num-callers=")) {
812 /* Make sure it's sane. */
813 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
814 if (VG_(clo_backtrace_size) < 2)
815 VG_(clo_backtrace_size) = 2;
816 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
817 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
818 }
819
820 else
821 bad_option(argv[i]);
822 }
823
824# undef ISSPACE
825# undef STREQ
826# undef STREQN
827
828 if (VG_(clo_verbosity < 0))
829 VG_(clo_verbosity) = 0;
830
831 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
832 VG_(message)(Vg_UserMsg, "");
833 VG_(message)(Vg_UserMsg,
834 "--gdb-attach=yes conflicts with --trace-children=yes");
835 VG_(message)(Vg_UserMsg,
836 "Please choose one or the other, but not both.");
837 bad_option("--gdb-attach=yes and --trace-children=yes");
838 }
839
sewardjde4a1d02002-03-22 01:27:54 +0000840 VG_(clo_logfile_fd) = eventually_logfile_fd;
841
njn4f9c9342002-04-29 16:03:24 +0000842 /* Don't do memory checking if simulating the cache. */
843 if (VG_(clo_cachesim)) {
844 VG_(clo_instrument) = False;
845 }
846
sewardj83adf412002-05-01 01:25:45 +0000847 if (VG_(clo_verbosity > 0)) {
848 if (VG_(clo_cachesim)) {
849 VG_(message)(Vg_UserMsg,
850 "cachegrind-%s, an I1/D1/L2 cache profiler for x86 GNU/Linux.",
851 VERSION);
852 } else {
853 VG_(message)(Vg_UserMsg,
854 "valgrind-%s, a memory error detector for x86 GNU/Linux.",
855 VERSION);
856 }
857 }
sewardj3b2736a2002-03-24 12:18:35 +0000858
sewardjde4a1d02002-03-22 01:27:54 +0000859 if (VG_(clo_verbosity > 0))
860 VG_(message)(Vg_UserMsg,
861 "Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.");
862 if (VG_(clo_verbosity) > 1) {
863 VG_(message)(Vg_UserMsg, "Startup, with flags:");
864 for (i = 0; i < argc; i++) {
865 VG_(message)(Vg_UserMsg, " %s", argv[i]);
866 }
867 }
868
sewardj83adf412002-05-01 01:25:45 +0000869 if (VG_(clo_n_suppressions) == 0 && !VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +0000870 config_error("No error-suppression files were specified.");
871 }
872}
873
874
875/* ---------------------------------------------------------------------
876 Copying to/from m_state_static.
877 ------------------------------------------------------------------ */
878
879UInt VG_(m_state_static) [8 /* int regs, in Intel order */
880 + 1 /* %eflags */
881 + 1 /* %eip */
882 + VG_SIZE_OF_FPUSTATE_W /* FPU state */
883 ];
884
885void VG_(copy_baseBlock_to_m_state_static) ( void )
886{
887 Int i;
888 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
889 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
890 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
891 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
892 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
893 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
894 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
895 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
896
897 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_eflags)];
898 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
899
900 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
901 VG_(m_state_static)[40/4 + i]
902 = VG_(baseBlock)[VGOFF_(m_fpustate) + i];
903}
904
905
906void VG_(copy_m_state_static_to_baseBlock) ( void )
907{
908 Int i;
909 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
910 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
911 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
912 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
913 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
914 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
915 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
916 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
917
918 VG_(baseBlock)[VGOFF_(m_eflags)] = VG_(m_state_static)[32/4];
919 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
920
921 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
922 VG_(baseBlock)[VGOFF_(m_fpustate) + i]
923 = VG_(m_state_static)[40/4 + i];
924}
925
926
927/* ---------------------------------------------------------------------
928 Show accumulated counts.
929 ------------------------------------------------------------------ */
930
931static void vg_show_counts ( void )
932{
933 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000934 " lru: %d epochs, %d clearings.",
935 VG_(current_epoch),
936 VG_(number_of_lrus) );
sewardjde4a1d02002-03-22 01:27:54 +0000937 VG_(message)(Vg_DebugMsg,
938 "translate: new %d (%d -> %d), discard %d (%d -> %d).",
939 VG_(overall_in_count),
940 VG_(overall_in_osize),
941 VG_(overall_in_tsize),
942 VG_(overall_out_count),
943 VG_(overall_out_osize),
944 VG_(overall_out_tsize) );
945 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000946 " dispatch: %lu basic blocks, %d/%d sched events, %d tt_fast misses.",
947 VG_(bbs_done), VG_(num_scheduling_events_MAJOR),
948 VG_(num_scheduling_events_MINOR),
949 VG_(tt_fast_misses));
sewardjde4a1d02002-03-22 01:27:54 +0000950 VG_(message)(Vg_DebugMsg,
951 "reg-alloc: %d t-req-spill, "
952 "%d+%d orig+spill uis, %d total-reg-r.",
953 VG_(translations_needing_spill),
954 VG_(uinstrs_prealloc),
955 VG_(uinstrs_spill),
956 VG_(total_reg_rank) );
957 VG_(message)(Vg_DebugMsg,
958 "smc-check: %d checks, %d fast pass, "
959 "%d slow pass, %d discards.",
960 VG_(smc_total_check4s),
961 VG_(smc_cache_passed),
962 VG_(smc_fancy_passed),
963 VG_(smc_discard_count) );
964 VG_(message)(Vg_DebugMsg,
965 " sanity: %d cheap, %d expensive checks.",
966 VG_(sanity_fast_count),
967 VG_(sanity_slow_count) );
968}
969
970
971/* ---------------------------------------------------------------------
972 Main!
973 ------------------------------------------------------------------ */
974
975/* Where we jump to once Valgrind has got control, and the real
976 machine's state has been copied to the m_state_static. */
977
978void VG_(main) ( void )
979{
sewardj2e93c502002-04-12 11:12:52 +0000980 Int i;
981 VgSchedReturnCode src;
sewardj7e87e382002-05-03 19:09:05 +0000982 ThreadState* tst;
sewardjde4a1d02002-03-22 01:27:54 +0000983
984 /* Set up our stack sanity-check words. */
985 for (i = 0; i < 10; i++) {
986 VG_(stack)[i] = (UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1;
987 VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321;
988 }
989
990 /* Set up baseBlock offsets and copy the saved machine's state into
991 it. */
992 vg_init_baseBlock();
993 VG_(copy_m_state_static_to_baseBlock)();
994
995 /* Process Valgrind's command-line opts (from env var VG_OPTS). */
996 process_cmd_line_options();
997
998 /* Initialise the signal handling subsystem. */
999 VG_(sigstartup_actions)();
1000
1001# ifdef VG_PROFILE
1002 VGP_(init_profiling)();
1003# endif
1004
sewardj5f07b662002-04-23 16:52:51 +00001005 /* Start calibration of our RDTSC-based clock. */
1006 VG_(start_rdtsc_calibration)();
1007
sewardjb3c26872002-03-24 10:05:14 +00001008 /* Hook to delay things long enough so we can get the pid and
1009 attach GDB in another shell. */
1010 /* {extern unsigned int sleep(unsigned int seconds); sleep(10);} */
1011
njn4f9c9342002-04-29 16:03:24 +00001012 if (VG_(clo_instrument) || VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +00001013 VGP_PUSHCC(VgpInitAudit);
1014 VGM_(init_memory_audit)();
1015 VGP_POPCC;
1016 VGP_PUSHCC(VgpReadSyms);
1017 VG_(read_symbols)();
1018 VGP_POPCC;
1019 }
1020
sewardj5f07b662002-04-23 16:52:51 +00001021 /* End calibration of our RDTSC-based clock, leaving it as long as
1022 we can. */
1023 VG_(end_rdtsc_calibration)();
1024
sewardjde4a1d02002-03-22 01:27:54 +00001025 /* This should come after init_memory_audit; otherwise the latter
1026 carefully sets up the permissions maps to cover the anonymous
1027 mmaps for the translation table and translation cache, which
1028 wastes > 20M of virtual address space. */
1029 VG_(init_transtab_and_SMC)();
1030
1031 if (VG_(clo_verbosity) == 1) {
1032 VG_(message)(Vg_UserMsg,
1033 "For more details, rerun with: -v");
1034 }
1035
1036 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1037 instrumented-ly. */
1038 VG_(running_on_simd_CPU) = True;
1039 if (VG_(clo_instrument)) {
1040 VGM_(make_readable) ( (Addr)&VG_(running_on_simd_CPU), 1 );
1041 VGM_(make_readable) ( (Addr)&VG_(clo_instrument), 1 );
1042 VGM_(make_readable) ( (Addr)&VG_(clo_trace_malloc), 1 );
1043 VGM_(make_readable) ( (Addr)&VG_(clo_sloppy_malloc), 1 );
1044 }
1045
njn4f9c9342002-04-29 16:03:24 +00001046 if (VG_(clo_cachesim))
1047 VG_(init_cachesim)();
1048
sewardjde4a1d02002-03-22 01:27:54 +00001049 if (VG_(clo_verbosity) > 0)
1050 VG_(message)(Vg_UserMsg, "");
1051
1052 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001053
sewardj671ff542002-05-07 09:25:30 +00001054 VGP_PUSHCC(VgpSched);
sewardj2e93c502002-04-12 11:12:52 +00001055 VG_(scheduler_init)();
1056 src = VG_(scheduler)();
sewardj671ff542002-05-07 09:25:30 +00001057 VGP_POPCC;
sewardjde4a1d02002-03-22 01:27:54 +00001058
1059 if (VG_(clo_verbosity) > 0)
1060 VG_(message)(Vg_UserMsg, "");
1061
sewardj2e93c502002-04-12 11:12:52 +00001062 if (src == VgSrc_Deadlock) {
1063 VG_(message)(Vg_UserMsg,
1064 "Warning: pthread scheduler exited due to deadlock");
1065 }
1066
sewardjde4a1d02002-03-22 01:27:54 +00001067 if (VG_(clo_instrument)) {
1068 VG_(show_all_errors)();
1069 VG_(clientmalloc_done)();
1070 if (VG_(clo_verbosity) == 1) {
1071 VG_(message)(Vg_UserMsg,
1072 "For counts of detected errors, rerun with: -v");
1073 }
1074 if (VG_(clo_leak_check)) VG_(detect_memory_leaks)();
1075 }
1076 VG_(running_on_simd_CPU) = False;
sewardj2e93c502002-04-12 11:12:52 +00001077
njn4f9c9342002-04-29 16:03:24 +00001078 if (VG_(clo_cachesim))
1079 VG_(show_cachesim_results)(VG_(client_argc), VG_(client_argv));
1080
sewardj0c3b53f2002-05-01 01:58:35 +00001081 VG_(do_sanity_checks)( True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001082
1083 if (VG_(clo_verbosity) > 1)
1084 vg_show_counts();
1085
1086 if (0) {
1087 VG_(message)(Vg_DebugMsg, "");
1088 VG_(message)(Vg_DebugMsg,
1089 "------ Valgrind's internal memory use stats follow ------" );
1090 VG_(mallocSanityCheckAll)();
1091 VG_(show_all_arena_stats)();
1092 VG_(message)(Vg_DebugMsg,
1093 "------ Valgrind's ExeContext management stats follow ------" );
1094 VG_(show_ExeContext_stats)();
1095 VG_(message)(Vg_DebugMsg,
1096 "------ Valgrind's client block stats follow ---------------" );
1097 VG_(show_client_block_stats)();
1098 }
1099
1100# ifdef VG_PROFILE
1101 VGP_(done_profiling)();
1102# endif
1103
1104 VG_(done_prof_mem)();
1105
1106 VG_(shutdown_logging)();
1107
1108 /* In LD_PRELOAD, convert "valgrind.so" into "valgrinq.so", so that
1109 child processes don't get traced into. Also done on simulated
1110 execve system call. */
1111 if (!VG_(clo_trace_children)) {
1112 VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
1113 }
1114
sewardj7e87e382002-05-03 19:09:05 +00001115 /* Decide how to exit. This depends on what the scheduler
1116 returned. */
1117 switch (src) {
1118 case VgSrc_ExitSyscall: /* the normal way out */
1119 vg_assert(VG_(last_run_tid) > 0
1120 && VG_(last_run_tid) < VG_N_THREADS);
1121 tst = VG_(get_thread_state)(VG_(last_run_tid));
1122 vg_assert(tst->status == VgTs_Runnable);
1123 /* The thread's %EBX will hold the arg to exit(), so we just
1124 do exit with that arg. */
1125 VG_(exit)( tst->m_ebx );
1126 /* NOT ALIVE HERE! */
1127 VG_(panic)("entered the afterlife in vg_main() -- ExitSyscall");
1128 break; /* what the hell :) */
sewardjde4a1d02002-03-22 01:27:54 +00001129
sewardj7e87e382002-05-03 19:09:05 +00001130 case VgSrc_Deadlock:
1131 /* Just exit now. No point in continuing. */
1132 VG_(exit)(0);
1133 VG_(panic)("entered the afterlife in vg_main() -- Deadlock");
1134 break;
1135
1136 case VgSrc_BbsDone:
1137 /* Tricky; we have to try and switch back to the real CPU.
1138 This is all very dodgy and won't work at all in the
1139 presence of threads, or if the client happened to be
1140 running a signal handler. */
1141 /* Prepare to restore state to the real CPU. */
1142 VG_(load_thread_state)(1 /* root thread */ );
1143 VG_(copy_baseBlock_to_m_state_static)();
1144
1145 /* This pushes a return address on the simulator's stack,
1146 which is abandoned. We call vg_sigshutdown_actions() at
1147 the end of vg_switch_to_real_CPU(), so as to ensure that
1148 the original stack and machine state is restored before
1149 the real signal mechanism is restored. */
1150 VG_(switch_to_real_CPU)();
1151
1152 default:
1153 VG_(panic)("vg_main(): unexpected scheduler return code");
1154 }
sewardjde4a1d02002-03-22 01:27:54 +00001155}
1156
1157
1158/* Debugging thing .. can be called from assembly with OYNK macro. */
1159void VG_(oynk) ( Int n )
1160{
1161 OINK(n);
1162}
1163
1164
1165/* Find "valgrind.so" in a LD_PRELOAD=... string, and convert it to
1166 "valgrinq.so", which doesn't do anything. This is used to avoid
1167 tracing into child processes. To make this work the build system
1168 also supplies a dummy file, "valgrinq.so".
1169*/
1170void VG_(mash_LD_PRELOAD_string)( Char* ld_preload_str )
1171{
1172 Char* p;
1173 if (ld_preload_str == NULL)
1174 return;
1175 p = VG_(strstr)(ld_preload_str, "valgrind.so");
1176 if (p == NULL)
1177 return;
1178 p[7] = 'q';
1179}
1180
1181/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1182 it to attach to this process. Called if the user requests this
1183 service after an error has been shown, so she can poke around and
1184 look at parameters, memory, etc. You can't meaningfully get GDB to
1185 continue the program, though; to continue, quit GDB. */
1186extern void VG_(start_GDB_whilst_on_client_stack) ( void )
1187{
sewardje6a25242002-04-21 22:03:07 +00001188 Int res;
sewardjde4a1d02002-03-22 01:27:54 +00001189 UChar buf[100];
1190 VG_(sprintf)(buf,
1191 "/usr/bin/gdb -nw /proc/%d/exe %d",
1192 VG_(getpid)(), VG_(getpid)());
sewardje6a25242002-04-21 22:03:07 +00001193 VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
1194 res = VG_(system)(buf);
1195 if (res == 0) {
1196 VG_(message)(Vg_UserMsg, "");
1197 VG_(message)(Vg_UserMsg,
1198 "GDB has detached. Valgrind regains control. We continue.");
1199 } else {
1200 VG_(message)(Vg_UserMsg, "Apparently failed!");
1201 VG_(message)(Vg_UserMsg, "");
sewardjde4a1d02002-03-22 01:27:54 +00001202 }
sewardjde4a1d02002-03-22 01:27:54 +00001203}
1204
1205
1206/* Print some helpful-ish text about unimplemented things, and give
1207 up. */
sewardjcfc39b22002-05-08 01:58:18 +00001208void VG_(unimplemented) ( Char* msg )
sewardjde4a1d02002-03-22 01:27:54 +00001209{
1210 VG_(message)(Vg_UserMsg, "");
1211 VG_(message)(Vg_UserMsg,
1212 "Valgrind detected that your program requires");
1213 VG_(message)(Vg_UserMsg,
1214 "the following unimplemented functionality:");
1215 VG_(message)(Vg_UserMsg, " %s", msg);
1216 VG_(message)(Vg_UserMsg,
1217 "This may be because the functionality is hard to implement,");
1218 VG_(message)(Vg_UserMsg,
1219 "or because no reasonable program would behave this way,");
1220 VG_(message)(Vg_UserMsg,
1221 "or because nobody has yet needed it. In any case, let me know");
1222 VG_(message)(Vg_UserMsg,
1223 "(jseward@acm.org) and/or try to work around the problem, if you can.");
1224 VG_(message)(Vg_UserMsg,
1225 "");
1226 VG_(message)(Vg_UserMsg,
1227 "Valgrind has to exit now. Sorry. Bye!");
1228 VG_(message)(Vg_UserMsg,
1229 "");
sewardj15a43e12002-04-17 19:35:12 +00001230 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +00001231 VG_(exit)(1);
1232}
1233
1234
sewardjcfc39b22002-05-08 01:58:18 +00001235void VG_(nvidia_moan) ( void)
1236{
1237 VG_(message)(Vg_UserMsg,
1238 "The following failure _might_ be caused by linking to NVidia's\n "
1239 "libGL.so, so avoiding it, if you can, _might_ help you. For example,\n "
1240 "re-build any Qt libraries you are using without OpenGL support.");
1241}
1242
1243
sewardjde4a1d02002-03-22 01:27:54 +00001244/*--------------------------------------------------------------------*/
1245/*--- end vg_main.c ---*/
1246/*--------------------------------------------------------------------*/