blob: 94e175c70c77d2c243e2d4f3d2af85547d9e3e2f [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
sewardjde4a1d02002-03-22 01:27:54 +0000384/* Counts pertaining to internal sanity checking. */
sewardjde4a1d02002-03-22 01:27:54 +0000385UInt VG_(sanity_fast_count) = 0;
386UInt VG_(sanity_slow_count) = 0;
387
sewardj2e93c502002-04-12 11:12:52 +0000388/* Counts pertaining to the scheduler. */
389UInt VG_(num_scheduling_events_MINOR) = 0;
390UInt VG_(num_scheduling_events_MAJOR) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000391
392
393/* ---------------------------------------------------------------------
394 Values derived from command-line options.
395 ------------------------------------------------------------------ */
396
sewardj97ced732002-03-25 00:07:36 +0000397Bool VG_(clo_check_addrVs);
sewardjde4a1d02002-03-22 01:27:54 +0000398Bool VG_(clo_GDB_attach);
399Int VG_(sanity_level);
400Int VG_(clo_verbosity);
401Bool VG_(clo_demangle);
402Bool VG_(clo_leak_check);
403Bool VG_(clo_show_reachable);
404Int VG_(clo_leak_resolution);
405Bool VG_(clo_sloppy_malloc);
406Bool VG_(clo_partial_loads_ok);
407Bool VG_(clo_trace_children);
408Int VG_(clo_logfile_fd);
409Int VG_(clo_freelist_vol);
410Bool VG_(clo_workaround_gcc296_bugs);
411Int VG_(clo_n_suppressions);
412Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
413Bool VG_(clo_single_step);
414Bool VG_(clo_optimise);
415Bool VG_(clo_instrument);
416Bool VG_(clo_cleanup);
njn4f9c9342002-04-29 16:03:24 +0000417Bool VG_(clo_cachesim);
sewardjde4a1d02002-03-22 01:27:54 +0000418Int VG_(clo_smc_check);
419Bool VG_(clo_trace_syscalls);
420Bool VG_(clo_trace_signals);
421Bool VG_(clo_trace_symtab);
422Bool VG_(clo_trace_malloc);
sewardj8937c812002-04-12 20:12:20 +0000423Bool VG_(clo_trace_sched);
sewardj45b4b372002-04-16 22:50:32 +0000424Int VG_(clo_trace_pthread_level);
sewardjde4a1d02002-03-22 01:27:54 +0000425ULong VG_(clo_stop_after);
426Int VG_(clo_dump_error);
427Int VG_(clo_backtrace_size);
sewardj8d365b52002-05-12 10:52:16 +0000428Char* VG_(clo_weird_hacks);
sewardjde4a1d02002-03-22 01:27:54 +0000429
430/* This Bool is needed by wrappers in vg_clientmalloc.c to decide how
431 to behave. Initially we say False. */
432Bool VG_(running_on_simd_CPU) = False;
433
434/* Holds client's %esp at the point we gained control. */
435Addr VG_(esp_at_startup);
436
437/* As deduced from VG_(esp_at_startup), the client's argc, argv[] and
438 envp[] as extracted from the client's stack at startup-time. */
439Int VG_(client_argc);
440Char** VG_(client_argv);
441Char** VG_(client_envp);
442
443/* A place into which to copy the value of env var VG_ARGS, so we
444 don't have to modify the original. */
445static Char vg_cmdline_copy[M_VG_CMDLINE_STRLEN];
446
447
448/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000449 Processing of command-line options.
450 ------------------------------------------------------------------ */
451
452static void bad_option ( Char* opt )
453{
454 VG_(shutdown_logging)();
455 VG_(clo_logfile_fd) = 2; /* stderr */
456 VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
457 VG_(exit)(1);
458}
459
460static void config_error ( Char* msg )
461{
462 VG_(shutdown_logging)();
463 VG_(clo_logfile_fd) = 2; /* stderr */
464 VG_(printf)("valgrind.so: Startup or configuration error:\n\t%s\n", msg);
465 VG_(printf)("valgrind.so: Unable to start up properly. Giving up.\n");
466 VG_(exit)(1);
467}
468
sewardja1679dd2002-05-10 22:31:40 +0000469static void args_grok_error ( Char* msg )
470{
471 VG_(shutdown_logging)();
472 VG_(clo_logfile_fd) = 2; /* stderr */
473 VG_(printf)("valgrind.so: When searching for "
474 "client's argc/argc/envp:\n\t%s\n", msg);
475 config_error("couldn't find client's argc/argc/envp");
476}
477
sewardjde4a1d02002-03-22 01:27:54 +0000478
479static void process_cmd_line_options ( void )
480{
481 UChar* argv[M_VG_CMDLINE_OPTS];
482 UInt argc;
483 UChar* p;
484 UChar* str;
sewardja1679dd2002-05-10 22:31:40 +0000485 Int i, eventually_logfile_fd, ctr;
sewardjde4a1d02002-03-22 01:27:54 +0000486
487# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
488# define STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2)))
489# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
490
491 /* Set defaults. */
sewardj97ced732002-03-25 00:07:36 +0000492 VG_(clo_check_addrVs) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000493 VG_(clo_GDB_attach) = False;
494 VG_(sanity_level) = 1;
495 VG_(clo_verbosity) = 1;
496 VG_(clo_demangle) = True;
497 VG_(clo_leak_check) = False;
498 VG_(clo_show_reachable) = False;
499 VG_(clo_leak_resolution) = 2;
500 VG_(clo_sloppy_malloc) = False;
501 VG_(clo_partial_loads_ok) = True;
502 VG_(clo_trace_children) = False;
503 VG_(clo_logfile_fd) = 2; /* stderr */
504 VG_(clo_freelist_vol) = 1000000;
505 VG_(clo_workaround_gcc296_bugs) = False;
506 VG_(clo_n_suppressions) = 0;
507 VG_(clo_single_step) = False;
508 VG_(clo_optimise) = True;
509 VG_(clo_instrument) = True;
510 VG_(clo_cleanup) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000511 VG_(clo_smc_check) = /* VG_CLO_SMC_SOME */ VG_CLO_SMC_NONE;
512 VG_(clo_trace_syscalls) = False;
513 VG_(clo_trace_signals) = False;
514 VG_(clo_trace_symtab) = False;
515 VG_(clo_trace_malloc) = False;
sewardj8937c812002-04-12 20:12:20 +0000516 VG_(clo_trace_sched) = False;
sewardj45b4b372002-04-16 22:50:32 +0000517 VG_(clo_trace_pthread_level) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000518 VG_(clo_stop_after) = 1000000000000LL;
519 VG_(clo_dump_error) = 0;
520 VG_(clo_backtrace_size) = 4;
sewardj8d365b52002-05-12 10:52:16 +0000521 VG_(clo_weird_hacks) = NULL;
sewardjde4a1d02002-03-22 01:27:54 +0000522
523 eventually_logfile_fd = VG_(clo_logfile_fd);
524
525 /* Once logging is started, we can safely send messages pertaining
526 to failures in initialisation. */
527 VG_(startup_logging)();
528
sewardj38170912002-05-10 21:07:22 +0000529
sewardja1679dd2002-05-10 22:31:40 +0000530 /* (Suggested by Fabrice Bellard ... )
531 We look for the Linux ELF table and go down until we find the
sewardj38170912002-05-10 21:07:22 +0000532 envc & envp. It is not full proof, but these structures should
533 change less often than the libc ones. */
534 {
sewardja1679dd2002-05-10 22:31:40 +0000535 UInt* sp = 0; /* bogus init to keep gcc -O happy */
536
sewardj38170912002-05-10 21:07:22 +0000537 /* locate the top of the stack */
sewardja1679dd2002-05-10 22:31:40 +0000538 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
539 VG_STARTUP_STACK_BASE_1 )) {
540 sp = (UInt*)VG_STARTUP_STACK_BASE_1;
541 } else
542 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
543 VG_STARTUP_STACK_BASE_2 )) {
544 sp = (UInt*)VG_STARTUP_STACK_BASE_2;
545 } else {
546 args_grok_error(
547 "startup %esp is not near any VG_STARTUP_STACK_BASE_*\n "
548 "constants defined in vg_include.h. You should investigate."
549 );
550 }
551
sewardj38170912002-05-10 21:07:22 +0000552 /* we locate: NEW_AUX_ENT(1, AT_PAGESZ, ELF_EXEC_PAGESIZE) in
553 the elf interpreter table */
554 sp -= 2;
sewardj38170912002-05-10 21:07:22 +0000555 while (sp[0] != VKI_AT_PAGESZ || sp[1] != 4096) {
sewardja1679dd2002-05-10 22:31:40 +0000556 /* VG_(printf)("trying %p\n", sp); */
sewardj38170912002-05-10 21:07:22 +0000557 sp--;
558 }
sewardj38170912002-05-10 21:07:22 +0000559
560 if (sp[2] == VKI_AT_BASE
561 && sp[0] == VKI_AT_PAGESZ
562 && sp[-2] == VKI_AT_PHNUM
563 && sp[-4] == VKI_AT_PHENT
564 && sp[-6] == VKI_AT_PHDR) {
sewardja1679dd2002-05-10 22:31:40 +0000565 if (0)
566 VG_(printf)("Looks like you've got a 2.2.X kernel here.\n");
sewardj38170912002-05-10 21:07:22 +0000567 sp -= 6;
sewardja1679dd2002-05-10 22:31:40 +0000568 } else
569 if (sp[2] == VKI_AT_CLKTCK
570 && sp[0] == VKI_AT_PAGESZ
571 && sp[-2] == VKI_AT_HWCAP) {
572 if (0)
573 VG_(printf)("Looks like you've got a 2.4.X kernel here.\n");
574 sp -= 2;
575 } else
576 args_grok_error(
577 "ELF frame does not look like 2.2.X or 2.4.X.\n "
578 "See kernel sources linux/fs/binfmt_elf.c to make sense of this."
579 );
sewardj38170912002-05-10 21:07:22 +0000580
581 sp--;
sewardja1679dd2002-05-10 22:31:40 +0000582 if (*sp != 0)
583 args_grok_error("can't find NULL at end of env[]");
584
sewardj38170912002-05-10 21:07:22 +0000585 /* sp now points to NULL at the end of env[] */
sewardja1679dd2002-05-10 22:31:40 +0000586 ctr = 0;
sewardj38170912002-05-10 21:07:22 +0000587 while (True) {
588 sp --;
589 if (*sp == 0) break;
sewardja1679dd2002-05-10 22:31:40 +0000590 if (++ctr >= 1000)
591 args_grok_error(
592 "suspiciously many (1000) env[] entries; giving up");
593
sewardj38170912002-05-10 21:07:22 +0000594 }
595 /* sp now points to NULL at the end of argv[] */
sewardja1679dd2002-05-10 22:31:40 +0000596 VG_(client_envp) = (Char**)(sp+1);
sewardj38170912002-05-10 21:07:22 +0000597
sewardja1679dd2002-05-10 22:31:40 +0000598 ctr = 0;
sewardj38170912002-05-10 21:07:22 +0000599 VG_(client_argc) = 0;
600 while (True) {
601 sp--;
602 if (*sp == VG_(client_argc))
603 break;
604 VG_(client_argc)++;
sewardja1679dd2002-05-10 22:31:40 +0000605 if (++ctr >= 1000)
606 args_grok_error(
607 "suspiciously many (1000) argv[] entries; giving up");
sewardj38170912002-05-10 21:07:22 +0000608 }
609
sewardja1679dd2002-05-10 22:31:40 +0000610 VG_(client_argv) = (Char**)(sp+1);
sewardj38170912002-05-10 21:07:22 +0000611 }
612
sewardjde4a1d02002-03-22 01:27:54 +0000613 /* Now that VG_(client_envp) has been set, we can extract the args
614 for Valgrind itself. Copy into global var so that we don't have to
615 write zeroes to the getenv'd value itself. */
616 str = VG_(getenv)("VG_ARGS");
617 argc = 0;
618
619 if (!str) {
620 config_error("Can't read options from env var VG_ARGS.");
621 }
622
623 if (VG_(strlen)(str) >= M_VG_CMDLINE_STRLEN-1) {
624 config_error("Command line length exceeds M_CMDLINE_STRLEN.");
625 }
626 VG_(strcpy)(vg_cmdline_copy, str);
627 str = NULL;
628
629 p = &vg_cmdline_copy[0];
630 while (True) {
631 while (ISSPACE(*p)) { *p = 0; p++; }
632 if (*p == 0) break;
633 if (argc < M_VG_CMDLINE_OPTS-1) {
634 argv[argc] = p; argc++;
635 } else {
636 config_error(
637 "Found more than M_CMDLINE_OPTS command-line opts.");
638 }
639 while (*p != 0 && !ISSPACE(*p)) p++;
640 }
641
642 for (i = 0; i < argc; i++) {
643
644 if (STREQ(argv[i], "-v") || STREQ(argv[i], "--verbose"))
645 VG_(clo_verbosity)++;
646 else if (STREQ(argv[i], "-q") || STREQ(argv[i], "--quiet"))
647 VG_(clo_verbosity)--;
648
sewardj97ced732002-03-25 00:07:36 +0000649 else if (STREQ(argv[i], "--check-addrVs=yes"))
650 VG_(clo_check_addrVs) = True;
651 else if (STREQ(argv[i], "--check-addrVs=no"))
652 VG_(clo_check_addrVs) = False;
653
sewardjde4a1d02002-03-22 01:27:54 +0000654 else if (STREQ(argv[i], "--gdb-attach=yes"))
655 VG_(clo_GDB_attach) = True;
656 else if (STREQ(argv[i], "--gdb-attach=no"))
657 VG_(clo_GDB_attach) = False;
658
659 else if (STREQ(argv[i], "--demangle=yes"))
660 VG_(clo_demangle) = True;
661 else if (STREQ(argv[i], "--demangle=no"))
662 VG_(clo_demangle) = False;
663
664 else if (STREQ(argv[i], "--partial-loads-ok=yes"))
665 VG_(clo_partial_loads_ok) = True;
666 else if (STREQ(argv[i], "--partial-loads-ok=no"))
667 VG_(clo_partial_loads_ok) = False;
668
669 else if (STREQ(argv[i], "--leak-check=yes"))
670 VG_(clo_leak_check) = True;
671 else if (STREQ(argv[i], "--leak-check=no"))
672 VG_(clo_leak_check) = False;
673
674 else if (STREQ(argv[i], "--show-reachable=yes"))
675 VG_(clo_show_reachable) = True;
676 else if (STREQ(argv[i], "--show-reachable=no"))
677 VG_(clo_show_reachable) = False;
678
679 else if (STREQ(argv[i], "--leak-resolution=low"))
680 VG_(clo_leak_resolution) = 2;
681 else if (STREQ(argv[i], "--leak-resolution=med"))
682 VG_(clo_leak_resolution) = 4;
683 else if (STREQ(argv[i], "--leak-resolution=high"))
684 VG_(clo_leak_resolution) = VG_DEEPEST_BACKTRACE;
685
686 else if (STREQ(argv[i], "--sloppy-malloc=yes"))
687 VG_(clo_sloppy_malloc) = True;
688 else if (STREQ(argv[i], "--sloppy-malloc=no"))
689 VG_(clo_sloppy_malloc) = False;
690
691 else if (STREQ(argv[i], "--trace-children=yes"))
692 VG_(clo_trace_children) = True;
693 else if (STREQ(argv[i], "--trace-children=no"))
694 VG_(clo_trace_children) = False;
695
696 else if (STREQ(argv[i], "--workaround-gcc296-bugs=yes"))
697 VG_(clo_workaround_gcc296_bugs) = True;
698 else if (STREQ(argv[i], "--workaround-gcc296-bugs=no"))
699 VG_(clo_workaround_gcc296_bugs) = False;
700
701 else if (STREQN(15, argv[i], "--sanity-level="))
702 VG_(sanity_level) = (Int)VG_(atoll)(&argv[i][15]);
703
704 else if (STREQN(13, argv[i], "--logfile-fd="))
705 eventually_logfile_fd = (Int)VG_(atoll)(&argv[i][13]);
706
707 else if (STREQN(15, argv[i], "--freelist-vol=")) {
708 VG_(clo_freelist_vol) = (Int)VG_(atoll)(&argv[i][15]);
709 if (VG_(clo_freelist_vol) < 0) VG_(clo_freelist_vol) = 2;
710 }
711
712 else if (STREQN(15, argv[i], "--suppressions=")) {
713 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
714 VG_(message)(Vg_UserMsg, "Too many logfiles specified.");
715 VG_(message)(Vg_UserMsg,
716 "Increase VG_CLO_MAX_SFILES and recompile.");
717 bad_option(argv[i]);
718 }
719 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &argv[i][15];
720 VG_(clo_n_suppressions)++;
721 }
722 else if (STREQ(argv[i], "--single-step=yes"))
723 VG_(clo_single_step) = True;
724 else if (STREQ(argv[i], "--single-step=no"))
725 VG_(clo_single_step) = False;
726
727 else if (STREQ(argv[i], "--optimise=yes"))
728 VG_(clo_optimise) = True;
729 else if (STREQ(argv[i], "--optimise=no"))
730 VG_(clo_optimise) = False;
731
732 else if (STREQ(argv[i], "--instrument=yes"))
733 VG_(clo_instrument) = True;
734 else if (STREQ(argv[i], "--instrument=no"))
735 VG_(clo_instrument) = False;
736
737 else if (STREQ(argv[i], "--cleanup=yes"))
738 VG_(clo_cleanup) = True;
739 else if (STREQ(argv[i], "--cleanup=no"))
740 VG_(clo_cleanup) = False;
741
njn4f9c9342002-04-29 16:03:24 +0000742 else if (STREQ(argv[i], "--cachesim=yes"))
743 VG_(clo_cachesim) = True;
744 else if (STREQ(argv[i], "--cachesim=no"))
745 VG_(clo_cachesim) = False;
746
sewardjde4a1d02002-03-22 01:27:54 +0000747 else if (STREQ(argv[i], "--smc-check=none"))
748 VG_(clo_smc_check) = VG_CLO_SMC_NONE;
749 else if (STREQ(argv[i], "--smc-check=some"))
750 VG_(clo_smc_check) = VG_CLO_SMC_SOME;
751 else if (STREQ(argv[i], "--smc-check=all"))
752 VG_(clo_smc_check) = VG_CLO_SMC_ALL;
753
754 else if (STREQ(argv[i], "--trace-syscalls=yes"))
755 VG_(clo_trace_syscalls) = True;
756 else if (STREQ(argv[i], "--trace-syscalls=no"))
757 VG_(clo_trace_syscalls) = False;
758
759 else if (STREQ(argv[i], "--trace-signals=yes"))
760 VG_(clo_trace_signals) = True;
761 else if (STREQ(argv[i], "--trace-signals=no"))
762 VG_(clo_trace_signals) = False;
763
764 else if (STREQ(argv[i], "--trace-symtab=yes"))
765 VG_(clo_trace_symtab) = True;
766 else if (STREQ(argv[i], "--trace-symtab=no"))
767 VG_(clo_trace_symtab) = False;
768
769 else if (STREQ(argv[i], "--trace-malloc=yes"))
770 VG_(clo_trace_malloc) = True;
771 else if (STREQ(argv[i], "--trace-malloc=no"))
772 VG_(clo_trace_malloc) = False;
773
sewardj8937c812002-04-12 20:12:20 +0000774 else if (STREQ(argv[i], "--trace-sched=yes"))
775 VG_(clo_trace_sched) = True;
776 else if (STREQ(argv[i], "--trace-sched=no"))
777 VG_(clo_trace_sched) = False;
778
sewardj45b4b372002-04-16 22:50:32 +0000779 else if (STREQ(argv[i], "--trace-pthread=none"))
780 VG_(clo_trace_pthread_level) = 0;
781 else if (STREQ(argv[i], "--trace-pthread=some"))
782 VG_(clo_trace_pthread_level) = 1;
783 else if (STREQ(argv[i], "--trace-pthread=all"))
784 VG_(clo_trace_pthread_level) = 2;
sewardj8937c812002-04-12 20:12:20 +0000785
sewardj8d365b52002-05-12 10:52:16 +0000786 else if (STREQN(14, argv[i], "--weird-hacks="))
787 VG_(clo_weird_hacks) = &argv[i][14];
sewardj3984b852002-05-12 03:00:17 +0000788
sewardjde4a1d02002-03-22 01:27:54 +0000789 else if (STREQN(13, argv[i], "--stop-after="))
790 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
791
792 else if (STREQN(13, argv[i], "--dump-error="))
793 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
794
795 else if (STREQN(14, argv[i], "--num-callers=")) {
796 /* Make sure it's sane. */
797 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
798 if (VG_(clo_backtrace_size) < 2)
799 VG_(clo_backtrace_size) = 2;
800 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
801 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
802 }
803
804 else
805 bad_option(argv[i]);
806 }
807
808# undef ISSPACE
809# undef STREQ
810# undef STREQN
811
812 if (VG_(clo_verbosity < 0))
813 VG_(clo_verbosity) = 0;
814
815 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
816 VG_(message)(Vg_UserMsg, "");
817 VG_(message)(Vg_UserMsg,
818 "--gdb-attach=yes conflicts with --trace-children=yes");
819 VG_(message)(Vg_UserMsg,
820 "Please choose one or the other, but not both.");
821 bad_option("--gdb-attach=yes and --trace-children=yes");
822 }
823
sewardjde4a1d02002-03-22 01:27:54 +0000824 VG_(clo_logfile_fd) = eventually_logfile_fd;
825
njn4f9c9342002-04-29 16:03:24 +0000826 /* Don't do memory checking if simulating the cache. */
827 if (VG_(clo_cachesim)) {
828 VG_(clo_instrument) = False;
829 }
830
sewardj83adf412002-05-01 01:25:45 +0000831 if (VG_(clo_verbosity > 0)) {
832 if (VG_(clo_cachesim)) {
833 VG_(message)(Vg_UserMsg,
834 "cachegrind-%s, an I1/D1/L2 cache profiler for x86 GNU/Linux.",
835 VERSION);
836 } else {
837 VG_(message)(Vg_UserMsg,
838 "valgrind-%s, a memory error detector for x86 GNU/Linux.",
839 VERSION);
840 }
841 }
sewardj3b2736a2002-03-24 12:18:35 +0000842
sewardjde4a1d02002-03-22 01:27:54 +0000843 if (VG_(clo_verbosity > 0))
844 VG_(message)(Vg_UserMsg,
845 "Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.");
846 if (VG_(clo_verbosity) > 1) {
847 VG_(message)(Vg_UserMsg, "Startup, with flags:");
848 for (i = 0; i < argc; i++) {
849 VG_(message)(Vg_UserMsg, " %s", argv[i]);
850 }
851 }
852
sewardj83adf412002-05-01 01:25:45 +0000853 if (VG_(clo_n_suppressions) == 0 && !VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +0000854 config_error("No error-suppression files were specified.");
855 }
856}
857
858
859/* ---------------------------------------------------------------------
860 Copying to/from m_state_static.
861 ------------------------------------------------------------------ */
862
863UInt VG_(m_state_static) [8 /* int regs, in Intel order */
864 + 1 /* %eflags */
865 + 1 /* %eip */
866 + VG_SIZE_OF_FPUSTATE_W /* FPU state */
867 ];
868
869void VG_(copy_baseBlock_to_m_state_static) ( void )
870{
871 Int i;
872 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
873 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
874 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
875 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
876 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
877 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
878 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
879 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
880
881 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_eflags)];
882 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
883
884 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
885 VG_(m_state_static)[40/4 + i]
886 = VG_(baseBlock)[VGOFF_(m_fpustate) + i];
887}
888
889
890void VG_(copy_m_state_static_to_baseBlock) ( void )
891{
892 Int i;
893 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
894 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
895 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
896 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
897 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
898 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
899 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
900 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
901
902 VG_(baseBlock)[VGOFF_(m_eflags)] = VG_(m_state_static)[32/4];
903 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
904
905 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
906 VG_(baseBlock)[VGOFF_(m_fpustate) + i]
907 = VG_(m_state_static)[40/4 + i];
908}
909
910
911/* ---------------------------------------------------------------------
912 Show accumulated counts.
913 ------------------------------------------------------------------ */
914
915static void vg_show_counts ( void )
916{
917 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000918 " lru: %d epochs, %d clearings.",
919 VG_(current_epoch),
920 VG_(number_of_lrus) );
sewardjde4a1d02002-03-22 01:27:54 +0000921 VG_(message)(Vg_DebugMsg,
922 "translate: new %d (%d -> %d), discard %d (%d -> %d).",
923 VG_(overall_in_count),
924 VG_(overall_in_osize),
925 VG_(overall_in_tsize),
926 VG_(overall_out_count),
927 VG_(overall_out_osize),
928 VG_(overall_out_tsize) );
929 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000930 " dispatch: %lu basic blocks, %d/%d sched events, %d tt_fast misses.",
931 VG_(bbs_done), VG_(num_scheduling_events_MAJOR),
932 VG_(num_scheduling_events_MINOR),
933 VG_(tt_fast_misses));
sewardjde4a1d02002-03-22 01:27:54 +0000934 VG_(message)(Vg_DebugMsg,
935 "reg-alloc: %d t-req-spill, "
936 "%d+%d orig+spill uis, %d total-reg-r.",
937 VG_(translations_needing_spill),
938 VG_(uinstrs_prealloc),
939 VG_(uinstrs_spill),
940 VG_(total_reg_rank) );
941 VG_(message)(Vg_DebugMsg,
sewardjde4a1d02002-03-22 01:27:54 +0000942 " sanity: %d cheap, %d expensive checks.",
943 VG_(sanity_fast_count),
944 VG_(sanity_slow_count) );
945}
946
947
948/* ---------------------------------------------------------------------
949 Main!
950 ------------------------------------------------------------------ */
951
952/* Where we jump to once Valgrind has got control, and the real
953 machine's state has been copied to the m_state_static. */
954
955void VG_(main) ( void )
956{
sewardj2e93c502002-04-12 11:12:52 +0000957 Int i;
958 VgSchedReturnCode src;
sewardj7e87e382002-05-03 19:09:05 +0000959 ThreadState* tst;
sewardjde4a1d02002-03-22 01:27:54 +0000960
961 /* Set up our stack sanity-check words. */
962 for (i = 0; i < 10; i++) {
963 VG_(stack)[i] = (UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1;
964 VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321;
965 }
966
967 /* Set up baseBlock offsets and copy the saved machine's state into
968 it. */
969 vg_init_baseBlock();
970 VG_(copy_m_state_static_to_baseBlock)();
971
972 /* Process Valgrind's command-line opts (from env var VG_OPTS). */
973 process_cmd_line_options();
974
sewardj018f7622002-05-15 21:13:39 +0000975 /* Initialise the scheduler, and copy the client's state from
976 baseBlock into VG_(threads)[1]. This has to come before signal
977 initialisations. */
978 VG_(scheduler_init)();
979
980 /* Initialise the signal handling subsystem, temporarily parking
981 the saved blocking-mask in saved_sigmask. */
sewardjde4a1d02002-03-22 01:27:54 +0000982 VG_(sigstartup_actions)();
983
sewardj018f7622002-05-15 21:13:39 +0000984 /* Perhaps we're profiling Valgrind? */
sewardjde4a1d02002-03-22 01:27:54 +0000985# ifdef VG_PROFILE
986 VGP_(init_profiling)();
987# endif
988
sewardj5f07b662002-04-23 16:52:51 +0000989 /* Start calibration of our RDTSC-based clock. */
990 VG_(start_rdtsc_calibration)();
991
sewardjb3c26872002-03-24 10:05:14 +0000992 /* Hook to delay things long enough so we can get the pid and
993 attach GDB in another shell. */
994 /* {extern unsigned int sleep(unsigned int seconds); sleep(10);} */
995
njn4f9c9342002-04-29 16:03:24 +0000996 if (VG_(clo_instrument) || VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +0000997 VGP_PUSHCC(VgpInitAudit);
998 VGM_(init_memory_audit)();
999 VGP_POPCC;
sewardjde4a1d02002-03-22 01:27:54 +00001000 }
1001
sewardj18d75132002-05-16 11:06:21 +00001002 VGP_PUSHCC(VgpReadSyms);
1003 VG_(read_symbols)();
1004 VGP_POPCC;
1005
sewardj5f07b662002-04-23 16:52:51 +00001006 /* End calibration of our RDTSC-based clock, leaving it as long as
1007 we can. */
1008 VG_(end_rdtsc_calibration)();
1009
sewardjde4a1d02002-03-22 01:27:54 +00001010 /* This should come after init_memory_audit; otherwise the latter
1011 carefully sets up the permissions maps to cover the anonymous
1012 mmaps for the translation table and translation cache, which
1013 wastes > 20M of virtual address space. */
sewardj18d75132002-05-16 11:06:21 +00001014 VG_(init_tt_tc)();
sewardjde4a1d02002-03-22 01:27:54 +00001015
1016 if (VG_(clo_verbosity) == 1) {
1017 VG_(message)(Vg_UserMsg,
1018 "For more details, rerun with: -v");
1019 }
1020
1021 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1022 instrumented-ly. */
1023 VG_(running_on_simd_CPU) = True;
1024 if (VG_(clo_instrument)) {
1025 VGM_(make_readable) ( (Addr)&VG_(running_on_simd_CPU), 1 );
1026 VGM_(make_readable) ( (Addr)&VG_(clo_instrument), 1 );
1027 VGM_(make_readable) ( (Addr)&VG_(clo_trace_malloc), 1 );
1028 VGM_(make_readable) ( (Addr)&VG_(clo_sloppy_malloc), 1 );
1029 }
1030
njn4f9c9342002-04-29 16:03:24 +00001031 if (VG_(clo_cachesim))
1032 VG_(init_cachesim)();
1033
sewardjde4a1d02002-03-22 01:27:54 +00001034 if (VG_(clo_verbosity) > 0)
1035 VG_(message)(Vg_UserMsg, "");
1036
1037 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001038
sewardj018f7622002-05-15 21:13:39 +00001039 /* Run! */
sewardj671ff542002-05-07 09:25:30 +00001040 VGP_PUSHCC(VgpSched);
sewardj2e93c502002-04-12 11:12:52 +00001041 src = VG_(scheduler)();
sewardj671ff542002-05-07 09:25:30 +00001042 VGP_POPCC;
sewardjde4a1d02002-03-22 01:27:54 +00001043
1044 if (VG_(clo_verbosity) > 0)
1045 VG_(message)(Vg_UserMsg, "");
1046
sewardj2e93c502002-04-12 11:12:52 +00001047 if (src == VgSrc_Deadlock) {
1048 VG_(message)(Vg_UserMsg,
1049 "Warning: pthread scheduler exited due to deadlock");
1050 }
1051
sewardjde4a1d02002-03-22 01:27:54 +00001052 if (VG_(clo_instrument)) {
1053 VG_(show_all_errors)();
1054 VG_(clientmalloc_done)();
1055 if (VG_(clo_verbosity) == 1) {
1056 VG_(message)(Vg_UserMsg,
1057 "For counts of detected errors, rerun with: -v");
1058 }
1059 if (VG_(clo_leak_check)) VG_(detect_memory_leaks)();
1060 }
1061 VG_(running_on_simd_CPU) = False;
sewardj2e93c502002-04-12 11:12:52 +00001062
njn4f9c9342002-04-29 16:03:24 +00001063 if (VG_(clo_cachesim))
1064 VG_(show_cachesim_results)(VG_(client_argc), VG_(client_argv));
1065
sewardj0c3b53f2002-05-01 01:58:35 +00001066 VG_(do_sanity_checks)( True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001067
1068 if (VG_(clo_verbosity) > 1)
1069 vg_show_counts();
1070
1071 if (0) {
1072 VG_(message)(Vg_DebugMsg, "");
1073 VG_(message)(Vg_DebugMsg,
1074 "------ Valgrind's internal memory use stats follow ------" );
1075 VG_(mallocSanityCheckAll)();
1076 VG_(show_all_arena_stats)();
1077 VG_(message)(Vg_DebugMsg,
1078 "------ Valgrind's ExeContext management stats follow ------" );
1079 VG_(show_ExeContext_stats)();
1080 VG_(message)(Vg_DebugMsg,
1081 "------ Valgrind's client block stats follow ---------------" );
1082 VG_(show_client_block_stats)();
1083 }
1084
1085# ifdef VG_PROFILE
1086 VGP_(done_profiling)();
1087# endif
1088
1089 VG_(done_prof_mem)();
1090
1091 VG_(shutdown_logging)();
1092
1093 /* In LD_PRELOAD, convert "valgrind.so" into "valgrinq.so", so that
1094 child processes don't get traced into. Also done on simulated
1095 execve system call. */
1096 if (!VG_(clo_trace_children)) {
1097 VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
1098 }
1099
sewardj7e87e382002-05-03 19:09:05 +00001100 /* Decide how to exit. This depends on what the scheduler
1101 returned. */
1102 switch (src) {
1103 case VgSrc_ExitSyscall: /* the normal way out */
1104 vg_assert(VG_(last_run_tid) > 0
1105 && VG_(last_run_tid) < VG_N_THREADS);
sewardj018f7622002-05-15 21:13:39 +00001106 tst = & VG_(threads)[VG_(last_run_tid)];
sewardj7e87e382002-05-03 19:09:05 +00001107 vg_assert(tst->status == VgTs_Runnable);
1108 /* The thread's %EBX will hold the arg to exit(), so we just
1109 do exit with that arg. */
1110 VG_(exit)( tst->m_ebx );
1111 /* NOT ALIVE HERE! */
1112 VG_(panic)("entered the afterlife in vg_main() -- ExitSyscall");
1113 break; /* what the hell :) */
sewardjde4a1d02002-03-22 01:27:54 +00001114
sewardj7e87e382002-05-03 19:09:05 +00001115 case VgSrc_Deadlock:
1116 /* Just exit now. No point in continuing. */
1117 VG_(exit)(0);
1118 VG_(panic)("entered the afterlife in vg_main() -- Deadlock");
1119 break;
1120
1121 case VgSrc_BbsDone:
1122 /* Tricky; we have to try and switch back to the real CPU.
1123 This is all very dodgy and won't work at all in the
1124 presence of threads, or if the client happened to be
1125 running a signal handler. */
1126 /* Prepare to restore state to the real CPU. */
1127 VG_(load_thread_state)(1 /* root thread */ );
1128 VG_(copy_baseBlock_to_m_state_static)();
1129
1130 /* This pushes a return address on the simulator's stack,
1131 which is abandoned. We call vg_sigshutdown_actions() at
1132 the end of vg_switch_to_real_CPU(), so as to ensure that
1133 the original stack and machine state is restored before
1134 the real signal mechanism is restored. */
1135 VG_(switch_to_real_CPU)();
1136
1137 default:
1138 VG_(panic)("vg_main(): unexpected scheduler return code");
1139 }
sewardjde4a1d02002-03-22 01:27:54 +00001140}
1141
1142
1143/* Debugging thing .. can be called from assembly with OYNK macro. */
1144void VG_(oynk) ( Int n )
1145{
1146 OINK(n);
1147}
1148
1149
1150/* Find "valgrind.so" in a LD_PRELOAD=... string, and convert it to
1151 "valgrinq.so", which doesn't do anything. This is used to avoid
1152 tracing into child processes. To make this work the build system
1153 also supplies a dummy file, "valgrinq.so".
1154*/
1155void VG_(mash_LD_PRELOAD_string)( Char* ld_preload_str )
1156{
1157 Char* p;
1158 if (ld_preload_str == NULL)
1159 return;
1160 p = VG_(strstr)(ld_preload_str, "valgrind.so");
1161 if (p == NULL)
1162 return;
1163 p[7] = 'q';
1164}
1165
1166/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1167 it to attach to this process. Called if the user requests this
1168 service after an error has been shown, so she can poke around and
1169 look at parameters, memory, etc. You can't meaningfully get GDB to
1170 continue the program, though; to continue, quit GDB. */
1171extern void VG_(start_GDB_whilst_on_client_stack) ( void )
1172{
sewardje6a25242002-04-21 22:03:07 +00001173 Int res;
sewardjde4a1d02002-03-22 01:27:54 +00001174 UChar buf[100];
1175 VG_(sprintf)(buf,
1176 "/usr/bin/gdb -nw /proc/%d/exe %d",
1177 VG_(getpid)(), VG_(getpid)());
sewardje6a25242002-04-21 22:03:07 +00001178 VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
1179 res = VG_(system)(buf);
1180 if (res == 0) {
1181 VG_(message)(Vg_UserMsg, "");
1182 VG_(message)(Vg_UserMsg,
1183 "GDB has detached. Valgrind regains control. We continue.");
1184 } else {
1185 VG_(message)(Vg_UserMsg, "Apparently failed!");
1186 VG_(message)(Vg_UserMsg, "");
sewardjde4a1d02002-03-22 01:27:54 +00001187 }
sewardjde4a1d02002-03-22 01:27:54 +00001188}
1189
1190
1191/* Print some helpful-ish text about unimplemented things, and give
1192 up. */
sewardjcfc39b22002-05-08 01:58:18 +00001193void VG_(unimplemented) ( Char* msg )
sewardjde4a1d02002-03-22 01:27:54 +00001194{
1195 VG_(message)(Vg_UserMsg, "");
1196 VG_(message)(Vg_UserMsg,
1197 "Valgrind detected that your program requires");
1198 VG_(message)(Vg_UserMsg,
1199 "the following unimplemented functionality:");
1200 VG_(message)(Vg_UserMsg, " %s", msg);
1201 VG_(message)(Vg_UserMsg,
1202 "This may be because the functionality is hard to implement,");
1203 VG_(message)(Vg_UserMsg,
1204 "or because no reasonable program would behave this way,");
1205 VG_(message)(Vg_UserMsg,
1206 "or because nobody has yet needed it. In any case, let me know");
1207 VG_(message)(Vg_UserMsg,
1208 "(jseward@acm.org) and/or try to work around the problem, if you can.");
1209 VG_(message)(Vg_UserMsg,
1210 "");
1211 VG_(message)(Vg_UserMsg,
1212 "Valgrind has to exit now. Sorry. Bye!");
1213 VG_(message)(Vg_UserMsg,
1214 "");
sewardj15a43e12002-04-17 19:35:12 +00001215 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +00001216 VG_(exit)(1);
1217}
1218
1219
sewardjcfc39b22002-05-08 01:58:18 +00001220void VG_(nvidia_moan) ( void)
1221{
1222 VG_(message)(Vg_UserMsg,
1223 "The following failure _might_ be caused by linking to NVidia's\n "
1224 "libGL.so, so avoiding it, if you can, _might_ help you. For example,\n "
1225 "re-build any Qt libraries you are using without OpenGL support.");
1226}
1227
1228
sewardjde4a1d02002-03-22 01:27:54 +00001229/*--------------------------------------------------------------------*/
1230/*--- end vg_main.c ---*/
1231/*--------------------------------------------------------------------*/