blob: 6df3e92a2d8ac6d29ae7279d750e08c8109717ce [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
3/*--- C startup stuff, reached from vg_startup.S. ---*/
4/*--- vg_main.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, an x86 protected-mode emulator
9 designed for debugging and profiling binaries on x86-Unixes.
10
11 Copyright (C) 2000-2002 Julian Seward
12 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000013
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file LICENSE.
30*/
31
32#include "vg_include.h"
33#include "vg_constants.h"
sewardjde4a1d02002-03-22 01:27:54 +000034
35
36/* ---------------------------------------------------------------------
37 Compute offsets into baseBlock. See comments in vg_include.h.
38 ------------------------------------------------------------------ */
39
40/* The variables storing offsets. */
41
42#define INVALID_OFFSET (-1)
43
44Int VGOFF_(m_eax) = INVALID_OFFSET;
45Int VGOFF_(m_ecx) = INVALID_OFFSET;
46Int VGOFF_(m_edx) = INVALID_OFFSET;
47Int VGOFF_(m_ebx) = INVALID_OFFSET;
48Int VGOFF_(m_esp) = INVALID_OFFSET;
49Int VGOFF_(m_ebp) = INVALID_OFFSET;
50Int VGOFF_(m_esi) = INVALID_OFFSET;
51Int VGOFF_(m_edi) = INVALID_OFFSET;
52Int VGOFF_(m_eflags) = INVALID_OFFSET;
53Int VGOFF_(m_fpustate) = INVALID_OFFSET;
54Int VGOFF_(m_eip) = INVALID_OFFSET;
55Int VGOFF_(spillslots) = INVALID_OFFSET;
56Int VGOFF_(sh_eax) = INVALID_OFFSET;
57Int VGOFF_(sh_ecx) = INVALID_OFFSET;
58Int VGOFF_(sh_edx) = INVALID_OFFSET;
59Int VGOFF_(sh_ebx) = INVALID_OFFSET;
60Int VGOFF_(sh_esp) = INVALID_OFFSET;
61Int VGOFF_(sh_ebp) = INVALID_OFFSET;
62Int VGOFF_(sh_esi) = INVALID_OFFSET;
63Int VGOFF_(sh_edi) = INVALID_OFFSET;
64Int VGOFF_(sh_eflags) = INVALID_OFFSET;
65Int VGOFF_(helper_idiv_64_32) = INVALID_OFFSET;
66Int VGOFF_(helper_div_64_32) = INVALID_OFFSET;
67Int VGOFF_(helper_idiv_32_16) = INVALID_OFFSET;
68Int VGOFF_(helper_div_32_16) = INVALID_OFFSET;
69Int VGOFF_(helper_idiv_16_8) = INVALID_OFFSET;
70Int VGOFF_(helper_div_16_8) = INVALID_OFFSET;
71Int VGOFF_(helper_imul_32_64) = INVALID_OFFSET;
72Int VGOFF_(helper_mul_32_64) = INVALID_OFFSET;
73Int VGOFF_(helper_imul_16_32) = INVALID_OFFSET;
74Int VGOFF_(helper_mul_16_32) = INVALID_OFFSET;
75Int VGOFF_(helper_imul_8_16) = INVALID_OFFSET;
76Int VGOFF_(helper_mul_8_16) = INVALID_OFFSET;
77Int VGOFF_(helper_CLD) = INVALID_OFFSET;
78Int VGOFF_(helper_STD) = INVALID_OFFSET;
79Int VGOFF_(helper_get_dirflag) = INVALID_OFFSET;
80Int VGOFF_(helper_shldl) = INVALID_OFFSET;
81Int VGOFF_(helper_shldw) = INVALID_OFFSET;
82Int VGOFF_(helper_shrdl) = INVALID_OFFSET;
83Int VGOFF_(helper_shrdw) = INVALID_OFFSET;
84Int VGOFF_(helper_RDTSC) = INVALID_OFFSET;
85Int VGOFF_(helper_CPUID) = INVALID_OFFSET;
86Int VGOFF_(helper_BSWAP) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000087Int VGOFF_(helper_bsf) = INVALID_OFFSET;
88Int VGOFF_(helper_bsr) = INVALID_OFFSET;
89Int VGOFF_(helper_fstsw_AX) = INVALID_OFFSET;
90Int VGOFF_(helper_SAHF) = INVALID_OFFSET;
sewardj4d0ab1f2002-03-24 10:00:09 +000091Int VGOFF_(helper_DAS) = INVALID_OFFSET;
sewardjfe8a1662002-03-24 11:54:07 +000092Int VGOFF_(helper_DAA) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000093Int VGOFF_(helper_value_check4_fail) = INVALID_OFFSET;
94Int VGOFF_(helper_value_check2_fail) = INVALID_OFFSET;
95Int VGOFF_(helper_value_check1_fail) = INVALID_OFFSET;
96Int VGOFF_(helper_value_check0_fail) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000097Int VGOFF_(helperc_LOADV4) = INVALID_OFFSET;
98Int VGOFF_(helperc_LOADV2) = INVALID_OFFSET;
99Int VGOFF_(helperc_LOADV1) = INVALID_OFFSET;
100Int VGOFF_(helperc_STOREV4) = INVALID_OFFSET;
101Int VGOFF_(helperc_STOREV2) = INVALID_OFFSET;
102Int VGOFF_(helperc_STOREV1) = INVALID_OFFSET;
103Int VGOFF_(handle_esp_assignment) = INVALID_OFFSET;
104Int VGOFF_(fpu_write_check) = INVALID_OFFSET;
105Int VGOFF_(fpu_read_check) = INVALID_OFFSET;
njn4f9c9342002-04-29 16:03:24 +0000106Int VGOFF_(cachesim_log_non_mem_instr) = INVALID_OFFSET;
107Int VGOFF_(cachesim_log_mem_instr) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +0000108
109/* This is the actual defn of baseblock. */
110UInt VG_(baseBlock)[VG_BASEBLOCK_WORDS];
111
112/* Words. */
113static Int baB_off = 0;
114
115/* Returns the offset, in words. */
116static Int alloc_BaB ( Int words )
117{
118 Int off = baB_off;
119 baB_off += words;
120 if (baB_off >= VG_BASEBLOCK_WORDS)
121 VG_(panic)( "alloc_BaB: baseBlock is too small");
122
123 return off;
124}
125
126/* Allocate 1 word in baseBlock and set it to the given value. */
127static Int alloc_BaB_1_set ( Addr a )
128{
129 Int off = alloc_BaB(1);
130 VG_(baseBlock)[off] = (UInt)a;
131 return off;
132}
133
134
135/* Here we assign actual offsets. It's important to get the most
136 popular referents within 128 bytes of the start, so we can take
137 advantage of short addressing modes relative to %ebp. Popularity
138 of offsets was measured on 22 Feb 02 running a KDE application, and
139 the slots rearranged accordingly, with a 1.5% reduction in total
140 size of translations. */
141
142static void vg_init_baseBlock ( void )
143{
144 baB_off = 0;
145
146 /* Those with offsets under 128 are carefully chosen. */
147
148 /* WORD offsets in this column */
149 /* 0 */ VGOFF_(m_eax) = alloc_BaB(1);
150 /* 1 */ VGOFF_(m_ecx) = alloc_BaB(1);
151 /* 2 */ VGOFF_(m_edx) = alloc_BaB(1);
152 /* 3 */ VGOFF_(m_ebx) = alloc_BaB(1);
153 /* 4 */ VGOFF_(m_esp) = alloc_BaB(1);
154 /* 5 */ VGOFF_(m_ebp) = alloc_BaB(1);
155 /* 6 */ VGOFF_(m_esi) = alloc_BaB(1);
156 /* 7 */ VGOFF_(m_edi) = alloc_BaB(1);
157 /* 8 */ VGOFF_(m_eflags) = alloc_BaB(1);
158
159 /* 9 */ VGOFF_(sh_eax) = alloc_BaB(1);
160 /* 10 */ VGOFF_(sh_ecx) = alloc_BaB(1);
161 /* 11 */ VGOFF_(sh_edx) = alloc_BaB(1);
162 /* 12 */ VGOFF_(sh_ebx) = alloc_BaB(1);
163 /* 13 */ VGOFF_(sh_esp) = alloc_BaB(1);
164 /* 14 */ VGOFF_(sh_ebp) = alloc_BaB(1);
165 /* 15 */ VGOFF_(sh_esi) = alloc_BaB(1);
166 /* 16 */ VGOFF_(sh_edi) = alloc_BaB(1);
167 /* 17 */ VGOFF_(sh_eflags) = alloc_BaB(1);
168
njn4f9c9342002-04-29 16:03:24 +0000169 /* 17a */
170 VGOFF_(cachesim_log_non_mem_instr)
171 = alloc_BaB_1_set( (Addr) & VG_(cachesim_log_non_mem_instr) );
172 /* 17b */
173 VGOFF_(cachesim_log_mem_instr)
174 = alloc_BaB_1_set( (Addr) & VG_(cachesim_log_mem_instr) );
175
sewardjde4a1d02002-03-22 01:27:54 +0000176 /* 18 */
177 VGOFF_(helper_value_check4_fail)
178 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check4_fail) );
179 /* 19 */
180 VGOFF_(helper_value_check0_fail)
181 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check0_fail) );
182
183 /* 20 */
184 VGOFF_(helperc_STOREV4)
185 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV4) );
186 /* 21 */
187 VGOFF_(helperc_STOREV1)
188 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV1) );
189
190 /* 22 */
191 VGOFF_(helperc_LOADV4)
192 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV4) );
193 /* 23 */
194 VGOFF_(helperc_LOADV1)
195 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV1) );
196
197 /* 24 */
198 VGOFF_(handle_esp_assignment)
199 = alloc_BaB_1_set( (Addr) & VGM_(handle_esp_assignment) );
200
201 /* 25 */
202 VGOFF_(m_eip) = alloc_BaB(1);
203
204 /* There are currently 24 spill slots */
205 /* 26 .. 49 This overlaps the magic boundary at >= 32 words, but
206 most spills are to low numbered spill slots, so the ones above
207 the boundary don't see much action. */
208 VGOFF_(spillslots) = alloc_BaB(VG_MAX_SPILLSLOTS);
209
210 /* These two pushed beyond the boundary because 2-byte transactions
211 are rare. */
212 /* 50 */
213 VGOFF_(helperc_STOREV2)
214 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV2) );
215 /* 51 */
216 VGOFF_(helperc_LOADV2)
217 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV2) );
218
219 /* 52 */
220 VGOFF_(fpu_write_check)
221 = alloc_BaB_1_set( (Addr) & VGM_(fpu_write_check) );
222 /* 53 */
223 VGOFF_(fpu_read_check)
224 = alloc_BaB_1_set( (Addr) & VGM_(fpu_read_check) );
225
226 /* Actually I don't think these two are ever used. */
227 /* 54 */
228 VGOFF_(helper_value_check2_fail)
229 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check2_fail) );
230 /* 55 */
231 VGOFF_(helper_value_check1_fail)
232 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check1_fail) );
233
234 /* I gave up counting at this point. Since they're way above the
235 short-amode-boundary, there's no point. */
236
237 VGOFF_(m_fpustate) = alloc_BaB(VG_SIZE_OF_FPUSTATE_W);
238
239 VGOFF_(helper_idiv_64_32)
240 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_64_32) );
241 VGOFF_(helper_div_64_32)
242 = alloc_BaB_1_set( (Addr) & VG_(helper_div_64_32) );
243 VGOFF_(helper_idiv_32_16)
244 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_32_16) );
245 VGOFF_(helper_div_32_16)
246 = alloc_BaB_1_set( (Addr) & VG_(helper_div_32_16) );
247 VGOFF_(helper_idiv_16_8)
248 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_16_8) );
249 VGOFF_(helper_div_16_8)
250 = alloc_BaB_1_set( (Addr) & VG_(helper_div_16_8) );
251
252 VGOFF_(helper_imul_32_64)
253 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_32_64) );
254 VGOFF_(helper_mul_32_64)
255 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_32_64) );
256 VGOFF_(helper_imul_16_32)
257 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_16_32) );
258 VGOFF_(helper_mul_16_32)
259 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_16_32) );
260 VGOFF_(helper_imul_8_16)
261 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_8_16) );
262 VGOFF_(helper_mul_8_16)
263 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_8_16) );
264
265 VGOFF_(helper_CLD)
266 = alloc_BaB_1_set( (Addr) & VG_(helper_CLD) );
267 VGOFF_(helper_STD)
268 = alloc_BaB_1_set( (Addr) & VG_(helper_STD) );
269 VGOFF_(helper_get_dirflag)
270 = alloc_BaB_1_set( (Addr) & VG_(helper_get_dirflag) );
271
272 VGOFF_(helper_shldl)
273 = alloc_BaB_1_set( (Addr) & VG_(helper_shldl) );
274 VGOFF_(helper_shldw)
275 = alloc_BaB_1_set( (Addr) & VG_(helper_shldw) );
276 VGOFF_(helper_shrdl)
277 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdl) );
278 VGOFF_(helper_shrdw)
279 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdw) );
280
281 VGOFF_(helper_RDTSC)
282 = alloc_BaB_1_set( (Addr) & VG_(helper_RDTSC) );
283 VGOFF_(helper_CPUID)
284 = alloc_BaB_1_set( (Addr) & VG_(helper_CPUID) );
285
sewardjde4a1d02002-03-22 01:27:54 +0000286 VGOFF_(helper_bsf)
287 = alloc_BaB_1_set( (Addr) & VG_(helper_bsf) );
288 VGOFF_(helper_bsr)
289 = alloc_BaB_1_set( (Addr) & VG_(helper_bsr) );
290
291 VGOFF_(helper_fstsw_AX)
292 = alloc_BaB_1_set( (Addr) & VG_(helper_fstsw_AX) );
293 VGOFF_(helper_SAHF)
294 = alloc_BaB_1_set( (Addr) & VG_(helper_SAHF) );
sewardj4d0ab1f2002-03-24 10:00:09 +0000295 VGOFF_(helper_DAS)
296 = alloc_BaB_1_set( (Addr) & VG_(helper_DAS) );
sewardjfe8a1662002-03-24 11:54:07 +0000297 VGOFF_(helper_DAA)
298 = alloc_BaB_1_set( (Addr) & VG_(helper_DAA) );
sewardjde4a1d02002-03-22 01:27:54 +0000299}
300
301
302/* ---------------------------------------------------------------------
303 Global entities which are not referenced from generated code.
304 ------------------------------------------------------------------ */
305
306/* The stack on which Valgrind runs. We can't use the same stack as
307 the simulatee -- that's an important design decision. */
308UInt VG_(stack)[10000];
309
310/* Ditto our signal delivery stack. */
311UInt VG_(sigstack)[10000];
312
313/* Saving stuff across system calls. */
314UInt VG_(real_fpu_state_saved_over_syscall_d1)[VG_SIZE_OF_FPUSTATE_W];
315UInt VG_(real_fpu_state_saved_over_syscall_d2)[VG_SIZE_OF_FPUSTATE_W];
316Addr VG_(esp_saved_over_syscall_d1);
317Addr VG_(esp_saved_over_syscall_d2);
318
319/* Counts downwards in vg_run_innerloop. */
320UInt VG_(dispatch_ctr);
321
sewardjde4a1d02002-03-22 01:27:54 +0000322
323/* 64-bit counter for the number of basic blocks done. */
324ULong VG_(bbs_done);
325/* 64-bit counter for the number of bbs to go before a debug exit. */
326ULong VG_(bbs_to_go);
327
328/* Produce debugging output? */
329Bool VG_(disassemble) = False;
330
331/* The current LRU epoch. */
332UInt VG_(current_epoch) = 0;
333
sewardj7e87e382002-05-03 19:09:05 +0000334/* This is the ThreadId of the last thread the scheduler ran. */
335ThreadId VG_(last_run_tid) = 0;
336
sewardjde4a1d02002-03-22 01:27:54 +0000337
338/* ---------------------------------------------------------------------
339 Counters, for informational purposes only.
340 ------------------------------------------------------------------ */
341
342/* Number of lookups which miss the fast tt helper. */
343UInt VG_(tt_fast_misses) = 0;
344
345
346/* Counts for LRU informational messages. */
347
348/* Number and total o/t size of new translations this epoch. */
349UInt VG_(this_epoch_in_count) = 0;
350UInt VG_(this_epoch_in_osize) = 0;
351UInt VG_(this_epoch_in_tsize) = 0;
352/* Number and total o/t size of discarded translations this epoch. */
353UInt VG_(this_epoch_out_count) = 0;
354UInt VG_(this_epoch_out_osize) = 0;
355UInt VG_(this_epoch_out_tsize) = 0;
356/* Number and total o/t size of translations overall. */
357UInt VG_(overall_in_count) = 0;
358UInt VG_(overall_in_osize) = 0;
359UInt VG_(overall_in_tsize) = 0;
360/* Number and total o/t size of discards overall. */
361UInt VG_(overall_out_count) = 0;
362UInt VG_(overall_out_osize) = 0;
363UInt VG_(overall_out_tsize) = 0;
364
365/* The number of LRU-clearings of TT/TC. */
366UInt VG_(number_of_lrus) = 0;
367
368
369/* Counts pertaining to the register allocator. */
370
371/* total number of uinstrs input to reg-alloc */
372UInt VG_(uinstrs_prealloc) = 0;
373
374/* total number of uinstrs added due to spill code */
375UInt VG_(uinstrs_spill) = 0;
376
377/* number of bbs requiring spill code */
378UInt VG_(translations_needing_spill) = 0;
379
380/* total of register ranks over all translations */
381UInt VG_(total_reg_rank) = 0;
382
383
384/* Counts pertaining to the self-modifying-code detection machinery. */
385
386/* Total number of writes checked. */
387UInt VG_(smc_total_check4s) = 0;
388
389/* Number of writes which the fast smc check couldn't show were
390 harmless. */
391UInt VG_(smc_cache_passed) = 0;
392
393/* Numnber of writes which really did write on original code. */
394UInt VG_(smc_fancy_passed) = 0;
395
396/* Number of translations discarded as a result. */
397UInt VG_(smc_discard_count) = 0;
398
399
400/* Counts pertaining to internal sanity checking. */
sewardjde4a1d02002-03-22 01:27:54 +0000401UInt VG_(sanity_fast_count) = 0;
402UInt VG_(sanity_slow_count) = 0;
403
sewardj2e93c502002-04-12 11:12:52 +0000404/* Counts pertaining to the scheduler. */
405UInt VG_(num_scheduling_events_MINOR) = 0;
406UInt VG_(num_scheduling_events_MAJOR) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000407
408
409/* ---------------------------------------------------------------------
410 Values derived from command-line options.
411 ------------------------------------------------------------------ */
412
sewardj97ced732002-03-25 00:07:36 +0000413Bool VG_(clo_check_addrVs);
sewardjde4a1d02002-03-22 01:27:54 +0000414Bool VG_(clo_GDB_attach);
415Int VG_(sanity_level);
416Int VG_(clo_verbosity);
417Bool VG_(clo_demangle);
418Bool VG_(clo_leak_check);
419Bool VG_(clo_show_reachable);
420Int VG_(clo_leak_resolution);
421Bool VG_(clo_sloppy_malloc);
422Bool VG_(clo_partial_loads_ok);
423Bool VG_(clo_trace_children);
424Int VG_(clo_logfile_fd);
425Int VG_(clo_freelist_vol);
426Bool VG_(clo_workaround_gcc296_bugs);
427Int VG_(clo_n_suppressions);
428Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
429Bool VG_(clo_single_step);
430Bool VG_(clo_optimise);
431Bool VG_(clo_instrument);
432Bool VG_(clo_cleanup);
njn4f9c9342002-04-29 16:03:24 +0000433Bool VG_(clo_cachesim);
sewardjde4a1d02002-03-22 01:27:54 +0000434Int VG_(clo_smc_check);
435Bool VG_(clo_trace_syscalls);
436Bool VG_(clo_trace_signals);
437Bool VG_(clo_trace_symtab);
438Bool VG_(clo_trace_malloc);
sewardj8937c812002-04-12 20:12:20 +0000439Bool VG_(clo_trace_sched);
sewardj45b4b372002-04-16 22:50:32 +0000440Int VG_(clo_trace_pthread_level);
sewardjde4a1d02002-03-22 01:27:54 +0000441ULong VG_(clo_stop_after);
442Int VG_(clo_dump_error);
443Int VG_(clo_backtrace_size);
444
445/* This Bool is needed by wrappers in vg_clientmalloc.c to decide how
446 to behave. Initially we say False. */
447Bool VG_(running_on_simd_CPU) = False;
448
449/* Holds client's %esp at the point we gained control. */
450Addr VG_(esp_at_startup);
451
452/* As deduced from VG_(esp_at_startup), the client's argc, argv[] and
453 envp[] as extracted from the client's stack at startup-time. */
454Int VG_(client_argc);
455Char** VG_(client_argv);
456Char** VG_(client_envp);
457
458/* A place into which to copy the value of env var VG_ARGS, so we
459 don't have to modify the original. */
460static Char vg_cmdline_copy[M_VG_CMDLINE_STRLEN];
461
462
463/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000464 Processing of command-line options.
465 ------------------------------------------------------------------ */
466
467static void bad_option ( Char* opt )
468{
469 VG_(shutdown_logging)();
470 VG_(clo_logfile_fd) = 2; /* stderr */
471 VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
472 VG_(exit)(1);
473}
474
475static void config_error ( Char* msg )
476{
477 VG_(shutdown_logging)();
478 VG_(clo_logfile_fd) = 2; /* stderr */
479 VG_(printf)("valgrind.so: Startup or configuration error:\n\t%s\n", msg);
480 VG_(printf)("valgrind.so: Unable to start up properly. Giving up.\n");
481 VG_(exit)(1);
482}
483
484
485static void process_cmd_line_options ( void )
486{
487 UChar* argv[M_VG_CMDLINE_OPTS];
488 UInt argc;
489 UChar* p;
490 UChar* str;
491 Int i, eventually_logfile_fd;
492
493# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
494# define STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2)))
495# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
496
497 /* Set defaults. */
sewardj97ced732002-03-25 00:07:36 +0000498 VG_(clo_check_addrVs) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000499 VG_(clo_GDB_attach) = False;
500 VG_(sanity_level) = 1;
501 VG_(clo_verbosity) = 1;
502 VG_(clo_demangle) = True;
503 VG_(clo_leak_check) = False;
504 VG_(clo_show_reachable) = False;
505 VG_(clo_leak_resolution) = 2;
506 VG_(clo_sloppy_malloc) = False;
507 VG_(clo_partial_loads_ok) = True;
508 VG_(clo_trace_children) = False;
509 VG_(clo_logfile_fd) = 2; /* stderr */
510 VG_(clo_freelist_vol) = 1000000;
511 VG_(clo_workaround_gcc296_bugs) = False;
512 VG_(clo_n_suppressions) = 0;
513 VG_(clo_single_step) = False;
514 VG_(clo_optimise) = True;
515 VG_(clo_instrument) = True;
516 VG_(clo_cleanup) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000517 VG_(clo_smc_check) = /* VG_CLO_SMC_SOME */ VG_CLO_SMC_NONE;
518 VG_(clo_trace_syscalls) = False;
519 VG_(clo_trace_signals) = False;
520 VG_(clo_trace_symtab) = False;
521 VG_(clo_trace_malloc) = False;
sewardj8937c812002-04-12 20:12:20 +0000522 VG_(clo_trace_sched) = False;
sewardj45b4b372002-04-16 22:50:32 +0000523 VG_(clo_trace_pthread_level) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000524 VG_(clo_stop_after) = 1000000000000LL;
525 VG_(clo_dump_error) = 0;
526 VG_(clo_backtrace_size) = 4;
527
528 eventually_logfile_fd = VG_(clo_logfile_fd);
529
530 /* Once logging is started, we can safely send messages pertaining
531 to failures in initialisation. */
532 VG_(startup_logging)();
533
sewardj38170912002-05-10 21:07:22 +0000534
535 /* We look for the Linux ELF table and go down until we find the
536 envc & envp. It is not full proof, but these structures should
537 change less often than the libc ones. */
538 {
539 unsigned long *sp;
540 int i;
541 /* locate the top of the stack */
542 sp = (unsigned long *)(((unsigned long)VG_(esp_at_startup) &
543 0xF0000000) + 0x10000000);
544 /* we locate: NEW_AUX_ENT(1, AT_PAGESZ, ELF_EXEC_PAGESIZE) in
545 the elf interpreter table */
546 sp -= 2;
547
548#define VKI_AT_PAGESZ 6
549
550 while (sp[0] != VKI_AT_PAGESZ || sp[1] != 4096) {
551 /* VG_(printf)("trying %p\n", sp); */
552 sp--;
553 }
554#define VKI_AT_BASE 7 /* base address of interpreter */
555#define VKI_AT_PAGESZ 6 /* system page size */
556#define VKI_AT_PHNUM 5 /* number of program headers */
557#define VKI_AT_PHENT 4 /* size of program header entry */
558#define VKI_AT_PHDR 3 /* program headers for program */
559
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) {
565 VG_(printf)("Looks like you've got a 2.2.X kernel here.\n");
566 sp -= 6;
567 }
568
569 sp--;
570 vg_assert(*sp == 0);
571 /* sp now points to NULL at the end of env[] */
572 while (True) {
573 sp --;
574 if (*sp == 0) break;
575 }
576 /* sp now points to NULL at the end of argv[] */
577 VG_(client_envp) = sp+1;
578
579 VG_(client_argc) = 0;
580 while (True) {
581 sp--;
582 if (*sp == VG_(client_argc))
583 break;
584 VG_(client_argc)++;
585 }
586
587 VG_(client_argv) = sp+1;
588 }
589
590
591#if 0
sewardjde4a1d02002-03-22 01:27:54 +0000592 /* Magically find the client's argc/argv/envp. This kludge is
593 entirely dependent on the stack layout imposed by libc at
594 startup. Hence the magic offsets. Then check (heuristically)
595 that the results are plausible. There must be a better way to
596 do this ... */
597
sewardj38170912002-05-10 21:07:22 +0000598# if 1
sewardjde4a1d02002-03-22 01:27:54 +0000599 /* Use this to search for the correct offsets if the tests below
600 barf. */
601 { Int i;
602 VG_(printf)("startup %%esp is %p\n", VG_(esp_at_startup) );
sewardj38170912002-05-10 21:07:22 +0000603 for (i = -10; i < 20; i++) {
sewardjde4a1d02002-03-22 01:27:54 +0000604 Char* p = ((Char**)VG_(esp_at_startup))[i];
605 VG_(printf)("%d: %p\n", i, p);
606 }
607 }
608# endif
609
sewardja88ebf62002-03-24 12:22:39 +0000610# if defined(GLIBC_2_2)
sewardjde4a1d02002-03-22 01:27:54 +0000611 /* These offsets (5,6,7) are right for my RedHat 7.2 (glibc-2.2.4)
612 box. */
613
614 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [5] );
615 VG_(client_argv) = (Char**)( ((void**)VG_(esp_at_startup)) [6] );
616 VG_(client_envp) = (Char**)( ((void**)VG_(esp_at_startup)) [7] );
617
618 if ( ((UInt)VG_(client_argc)) > 0 &&
619 ((UInt)VG_(client_argc)) < 10000 &&
620 (Addr)VG_(client_argv) >= 0x8000000 &&
621 (Addr)VG_(client_envp) >= 0x8000000)
622 goto argc_argv_envp_OK;
623
624 /* If that's no good, try some other offsets discovered by KDE
625 folks on 8 Feb 02:
626 For glibc > 2.2.4 the offset 9/10/11 did the trick. Coolo found
627 out those, on I think a Caldera 3.1 with glibc 2.2.4 -- the same
628 offsets worked for on a debian sid with glibc 2.2.5. */
629
630 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [9] );
631 VG_(client_argv) = (Char**)( ((void**)VG_(esp_at_startup)) [10] );
632 VG_(client_envp) = (Char**)( ((void**)VG_(esp_at_startup)) [11] );
633
634 if ( ((UInt)VG_(client_argc)) > 0 &&
635 ((UInt)VG_(client_argc)) < 10000 &&
636 (Addr)VG_(client_argv) >= 0x8000000 &&
637 (Addr)VG_(client_envp) >= 0x8000000)
638 goto argc_argv_envp_OK;
639
sewardja88ebf62002-03-24 12:22:39 +0000640# endif /* defined(GLIBC_2_2) */
641
642# if defined(GLIBC_2_1)
sewardjde4a1d02002-03-22 01:27:54 +0000643 /* Doesn't look promising. Try offsets for RedHat 6.2
644 (glibc-2.1.3) instead. In this case, the argv and envp vectors
645 are actually on the stack (bizarrely). */
646
647 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [4] );
648 VG_(client_argv) = (Char**) & ( ((void**)VG_(esp_at_startup)) [5] );
649 VG_(client_envp)
650 = (Char**) & ( ((void**)VG_(esp_at_startup)) [6 + VG_(client_argc)] );
651
652 if ( ((UInt)VG_(client_argc)) > 0 &&
653 ((UInt)VG_(client_argc)) < 10000 &&
654 (Addr)VG_(client_argv) >= 0x8000000 &&
655 (Addr)VG_(client_envp) >= 0x8000000)
656 goto argc_argv_envp_OK;
657
658 /* Here's yet another variant, from <hansen> (irc.kde.org). */
659
660 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [9] );
661 VG_(client_argv) = (Char**) & ( ((void**)VG_(esp_at_startup)) [10] );
662 VG_(client_envp)
663 = (Char**) & ( ((void**)VG_(esp_at_startup)) [11 + VG_(client_argc)] );
664
665 if ( ((UInt)VG_(client_argc)) > 0 &&
666 ((UInt)VG_(client_argc)) < 10000 &&
667 (Addr)VG_(client_argv) >= 0x8000000 &&
668 (Addr)VG_(client_envp) >= 0x8000000)
669 goto argc_argv_envp_OK;
sewardja88ebf62002-03-24 12:22:39 +0000670# endif /* defined(GLIBC_2_1) */
671
672# if !defined(GLIBC_2_2) && !defined(GLIBC_2_1)
673 config_error("autoconf/configure detected neither glibc 2.1.X nor 2.2.X");
674# endif
sewardjde4a1d02002-03-22 01:27:54 +0000675
676 /* VG_(printf)("%d %p %p\n", VG_(client_argc), VG_(client_argv),
677 VG_(client_envp));
678 */
679 /* We're hosed. Give up :-( */
680 config_error(
681 "Can't get plausible values for client's argc/argv/envp.\n\t"
682 "You may be able to fix this; see process_cmd_line_options()\n\t"
683 "in vg_main.c"
684 );
685 /* NOTREACHED */
686
687 argc_argv_envp_OK:
sewardj38170912002-05-10 21:07:22 +0000688#endif
sewardjde4a1d02002-03-22 01:27:54 +0000689
690 /* Now that VG_(client_envp) has been set, we can extract the args
691 for Valgrind itself. Copy into global var so that we don't have to
692 write zeroes to the getenv'd value itself. */
693 str = VG_(getenv)("VG_ARGS");
694 argc = 0;
695
696 if (!str) {
697 config_error("Can't read options from env var VG_ARGS.");
698 }
699
700 if (VG_(strlen)(str) >= M_VG_CMDLINE_STRLEN-1) {
701 config_error("Command line length exceeds M_CMDLINE_STRLEN.");
702 }
703 VG_(strcpy)(vg_cmdline_copy, str);
704 str = NULL;
705
706 p = &vg_cmdline_copy[0];
707 while (True) {
708 while (ISSPACE(*p)) { *p = 0; p++; }
709 if (*p == 0) break;
710 if (argc < M_VG_CMDLINE_OPTS-1) {
711 argv[argc] = p; argc++;
712 } else {
713 config_error(
714 "Found more than M_CMDLINE_OPTS command-line opts.");
715 }
716 while (*p != 0 && !ISSPACE(*p)) p++;
717 }
718
719 for (i = 0; i < argc; i++) {
720
721 if (STREQ(argv[i], "-v") || STREQ(argv[i], "--verbose"))
722 VG_(clo_verbosity)++;
723 else if (STREQ(argv[i], "-q") || STREQ(argv[i], "--quiet"))
724 VG_(clo_verbosity)--;
725
sewardj97ced732002-03-25 00:07:36 +0000726 else if (STREQ(argv[i], "--check-addrVs=yes"))
727 VG_(clo_check_addrVs) = True;
728 else if (STREQ(argv[i], "--check-addrVs=no"))
729 VG_(clo_check_addrVs) = False;
730
sewardjde4a1d02002-03-22 01:27:54 +0000731 else if (STREQ(argv[i], "--gdb-attach=yes"))
732 VG_(clo_GDB_attach) = True;
733 else if (STREQ(argv[i], "--gdb-attach=no"))
734 VG_(clo_GDB_attach) = False;
735
736 else if (STREQ(argv[i], "--demangle=yes"))
737 VG_(clo_demangle) = True;
738 else if (STREQ(argv[i], "--demangle=no"))
739 VG_(clo_demangle) = False;
740
741 else if (STREQ(argv[i], "--partial-loads-ok=yes"))
742 VG_(clo_partial_loads_ok) = True;
743 else if (STREQ(argv[i], "--partial-loads-ok=no"))
744 VG_(clo_partial_loads_ok) = False;
745
746 else if (STREQ(argv[i], "--leak-check=yes"))
747 VG_(clo_leak_check) = True;
748 else if (STREQ(argv[i], "--leak-check=no"))
749 VG_(clo_leak_check) = False;
750
751 else if (STREQ(argv[i], "--show-reachable=yes"))
752 VG_(clo_show_reachable) = True;
753 else if (STREQ(argv[i], "--show-reachable=no"))
754 VG_(clo_show_reachable) = False;
755
756 else if (STREQ(argv[i], "--leak-resolution=low"))
757 VG_(clo_leak_resolution) = 2;
758 else if (STREQ(argv[i], "--leak-resolution=med"))
759 VG_(clo_leak_resolution) = 4;
760 else if (STREQ(argv[i], "--leak-resolution=high"))
761 VG_(clo_leak_resolution) = VG_DEEPEST_BACKTRACE;
762
763 else if (STREQ(argv[i], "--sloppy-malloc=yes"))
764 VG_(clo_sloppy_malloc) = True;
765 else if (STREQ(argv[i], "--sloppy-malloc=no"))
766 VG_(clo_sloppy_malloc) = False;
767
768 else if (STREQ(argv[i], "--trace-children=yes"))
769 VG_(clo_trace_children) = True;
770 else if (STREQ(argv[i], "--trace-children=no"))
771 VG_(clo_trace_children) = False;
772
773 else if (STREQ(argv[i], "--workaround-gcc296-bugs=yes"))
774 VG_(clo_workaround_gcc296_bugs) = True;
775 else if (STREQ(argv[i], "--workaround-gcc296-bugs=no"))
776 VG_(clo_workaround_gcc296_bugs) = False;
777
778 else if (STREQN(15, argv[i], "--sanity-level="))
779 VG_(sanity_level) = (Int)VG_(atoll)(&argv[i][15]);
780
781 else if (STREQN(13, argv[i], "--logfile-fd="))
782 eventually_logfile_fd = (Int)VG_(atoll)(&argv[i][13]);
783
784 else if (STREQN(15, argv[i], "--freelist-vol=")) {
785 VG_(clo_freelist_vol) = (Int)VG_(atoll)(&argv[i][15]);
786 if (VG_(clo_freelist_vol) < 0) VG_(clo_freelist_vol) = 2;
787 }
788
789 else if (STREQN(15, argv[i], "--suppressions=")) {
790 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
791 VG_(message)(Vg_UserMsg, "Too many logfiles specified.");
792 VG_(message)(Vg_UserMsg,
793 "Increase VG_CLO_MAX_SFILES and recompile.");
794 bad_option(argv[i]);
795 }
796 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &argv[i][15];
797 VG_(clo_n_suppressions)++;
798 }
799 else if (STREQ(argv[i], "--single-step=yes"))
800 VG_(clo_single_step) = True;
801 else if (STREQ(argv[i], "--single-step=no"))
802 VG_(clo_single_step) = False;
803
804 else if (STREQ(argv[i], "--optimise=yes"))
805 VG_(clo_optimise) = True;
806 else if (STREQ(argv[i], "--optimise=no"))
807 VG_(clo_optimise) = False;
808
809 else if (STREQ(argv[i], "--instrument=yes"))
810 VG_(clo_instrument) = True;
811 else if (STREQ(argv[i], "--instrument=no"))
812 VG_(clo_instrument) = False;
813
814 else if (STREQ(argv[i], "--cleanup=yes"))
815 VG_(clo_cleanup) = True;
816 else if (STREQ(argv[i], "--cleanup=no"))
817 VG_(clo_cleanup) = False;
818
njn4f9c9342002-04-29 16:03:24 +0000819 else if (STREQ(argv[i], "--cachesim=yes"))
820 VG_(clo_cachesim) = True;
821 else if (STREQ(argv[i], "--cachesim=no"))
822 VG_(clo_cachesim) = False;
823
sewardjde4a1d02002-03-22 01:27:54 +0000824 else if (STREQ(argv[i], "--smc-check=none"))
825 VG_(clo_smc_check) = VG_CLO_SMC_NONE;
826 else if (STREQ(argv[i], "--smc-check=some"))
827 VG_(clo_smc_check) = VG_CLO_SMC_SOME;
828 else if (STREQ(argv[i], "--smc-check=all"))
829 VG_(clo_smc_check) = VG_CLO_SMC_ALL;
830
831 else if (STREQ(argv[i], "--trace-syscalls=yes"))
832 VG_(clo_trace_syscalls) = True;
833 else if (STREQ(argv[i], "--trace-syscalls=no"))
834 VG_(clo_trace_syscalls) = False;
835
836 else if (STREQ(argv[i], "--trace-signals=yes"))
837 VG_(clo_trace_signals) = True;
838 else if (STREQ(argv[i], "--trace-signals=no"))
839 VG_(clo_trace_signals) = False;
840
841 else if (STREQ(argv[i], "--trace-symtab=yes"))
842 VG_(clo_trace_symtab) = True;
843 else if (STREQ(argv[i], "--trace-symtab=no"))
844 VG_(clo_trace_symtab) = False;
845
846 else if (STREQ(argv[i], "--trace-malloc=yes"))
847 VG_(clo_trace_malloc) = True;
848 else if (STREQ(argv[i], "--trace-malloc=no"))
849 VG_(clo_trace_malloc) = False;
850
sewardj8937c812002-04-12 20:12:20 +0000851 else if (STREQ(argv[i], "--trace-sched=yes"))
852 VG_(clo_trace_sched) = True;
853 else if (STREQ(argv[i], "--trace-sched=no"))
854 VG_(clo_trace_sched) = False;
855
sewardj45b4b372002-04-16 22:50:32 +0000856 else if (STREQ(argv[i], "--trace-pthread=none"))
857 VG_(clo_trace_pthread_level) = 0;
858 else if (STREQ(argv[i], "--trace-pthread=some"))
859 VG_(clo_trace_pthread_level) = 1;
860 else if (STREQ(argv[i], "--trace-pthread=all"))
861 VG_(clo_trace_pthread_level) = 2;
sewardj8937c812002-04-12 20:12:20 +0000862
sewardjde4a1d02002-03-22 01:27:54 +0000863 else if (STREQN(13, argv[i], "--stop-after="))
864 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
865
866 else if (STREQN(13, argv[i], "--dump-error="))
867 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
868
869 else if (STREQN(14, argv[i], "--num-callers=")) {
870 /* Make sure it's sane. */
871 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
872 if (VG_(clo_backtrace_size) < 2)
873 VG_(clo_backtrace_size) = 2;
874 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
875 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
876 }
877
878 else
879 bad_option(argv[i]);
880 }
881
882# undef ISSPACE
883# undef STREQ
884# undef STREQN
885
886 if (VG_(clo_verbosity < 0))
887 VG_(clo_verbosity) = 0;
888
889 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
890 VG_(message)(Vg_UserMsg, "");
891 VG_(message)(Vg_UserMsg,
892 "--gdb-attach=yes conflicts with --trace-children=yes");
893 VG_(message)(Vg_UserMsg,
894 "Please choose one or the other, but not both.");
895 bad_option("--gdb-attach=yes and --trace-children=yes");
896 }
897
sewardjde4a1d02002-03-22 01:27:54 +0000898 VG_(clo_logfile_fd) = eventually_logfile_fd;
899
njn4f9c9342002-04-29 16:03:24 +0000900 /* Don't do memory checking if simulating the cache. */
901 if (VG_(clo_cachesim)) {
902 VG_(clo_instrument) = False;
903 }
904
sewardj83adf412002-05-01 01:25:45 +0000905 if (VG_(clo_verbosity > 0)) {
906 if (VG_(clo_cachesim)) {
907 VG_(message)(Vg_UserMsg,
908 "cachegrind-%s, an I1/D1/L2 cache profiler for x86 GNU/Linux.",
909 VERSION);
910 } else {
911 VG_(message)(Vg_UserMsg,
912 "valgrind-%s, a memory error detector for x86 GNU/Linux.",
913 VERSION);
914 }
915 }
sewardj3b2736a2002-03-24 12:18:35 +0000916
sewardjde4a1d02002-03-22 01:27:54 +0000917 if (VG_(clo_verbosity > 0))
918 VG_(message)(Vg_UserMsg,
919 "Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.");
920 if (VG_(clo_verbosity) > 1) {
921 VG_(message)(Vg_UserMsg, "Startup, with flags:");
922 for (i = 0; i < argc; i++) {
923 VG_(message)(Vg_UserMsg, " %s", argv[i]);
924 }
925 }
926
sewardj83adf412002-05-01 01:25:45 +0000927 if (VG_(clo_n_suppressions) == 0 && !VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +0000928 config_error("No error-suppression files were specified.");
929 }
930}
931
932
933/* ---------------------------------------------------------------------
934 Copying to/from m_state_static.
935 ------------------------------------------------------------------ */
936
937UInt VG_(m_state_static) [8 /* int regs, in Intel order */
938 + 1 /* %eflags */
939 + 1 /* %eip */
940 + VG_SIZE_OF_FPUSTATE_W /* FPU state */
941 ];
942
943void VG_(copy_baseBlock_to_m_state_static) ( void )
944{
945 Int i;
946 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
947 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
948 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
949 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
950 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
951 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
952 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
953 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
954
955 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_eflags)];
956 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
957
958 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
959 VG_(m_state_static)[40/4 + i]
960 = VG_(baseBlock)[VGOFF_(m_fpustate) + i];
961}
962
963
964void VG_(copy_m_state_static_to_baseBlock) ( void )
965{
966 Int i;
967 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
968 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
969 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
970 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
971 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
972 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
973 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
974 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
975
976 VG_(baseBlock)[VGOFF_(m_eflags)] = VG_(m_state_static)[32/4];
977 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
978
979 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
980 VG_(baseBlock)[VGOFF_(m_fpustate) + i]
981 = VG_(m_state_static)[40/4 + i];
982}
983
984
985/* ---------------------------------------------------------------------
986 Show accumulated counts.
987 ------------------------------------------------------------------ */
988
989static void vg_show_counts ( void )
990{
991 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000992 " lru: %d epochs, %d clearings.",
993 VG_(current_epoch),
994 VG_(number_of_lrus) );
sewardjde4a1d02002-03-22 01:27:54 +0000995 VG_(message)(Vg_DebugMsg,
996 "translate: new %d (%d -> %d), discard %d (%d -> %d).",
997 VG_(overall_in_count),
998 VG_(overall_in_osize),
999 VG_(overall_in_tsize),
1000 VG_(overall_out_count),
1001 VG_(overall_out_osize),
1002 VG_(overall_out_tsize) );
1003 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +00001004 " dispatch: %lu basic blocks, %d/%d sched events, %d tt_fast misses.",
1005 VG_(bbs_done), VG_(num_scheduling_events_MAJOR),
1006 VG_(num_scheduling_events_MINOR),
1007 VG_(tt_fast_misses));
sewardjde4a1d02002-03-22 01:27:54 +00001008 VG_(message)(Vg_DebugMsg,
1009 "reg-alloc: %d t-req-spill, "
1010 "%d+%d orig+spill uis, %d total-reg-r.",
1011 VG_(translations_needing_spill),
1012 VG_(uinstrs_prealloc),
1013 VG_(uinstrs_spill),
1014 VG_(total_reg_rank) );
1015 VG_(message)(Vg_DebugMsg,
1016 "smc-check: %d checks, %d fast pass, "
1017 "%d slow pass, %d discards.",
1018 VG_(smc_total_check4s),
1019 VG_(smc_cache_passed),
1020 VG_(smc_fancy_passed),
1021 VG_(smc_discard_count) );
1022 VG_(message)(Vg_DebugMsg,
1023 " sanity: %d cheap, %d expensive checks.",
1024 VG_(sanity_fast_count),
1025 VG_(sanity_slow_count) );
1026}
1027
1028
1029/* ---------------------------------------------------------------------
1030 Main!
1031 ------------------------------------------------------------------ */
1032
1033/* Where we jump to once Valgrind has got control, and the real
1034 machine's state has been copied to the m_state_static. */
1035
1036void VG_(main) ( void )
1037{
sewardj2e93c502002-04-12 11:12:52 +00001038 Int i;
1039 VgSchedReturnCode src;
sewardj7e87e382002-05-03 19:09:05 +00001040 ThreadState* tst;
sewardjde4a1d02002-03-22 01:27:54 +00001041
1042 /* Set up our stack sanity-check words. */
1043 for (i = 0; i < 10; i++) {
1044 VG_(stack)[i] = (UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1;
1045 VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321;
1046 }
1047
1048 /* Set up baseBlock offsets and copy the saved machine's state into
1049 it. */
1050 vg_init_baseBlock();
1051 VG_(copy_m_state_static_to_baseBlock)();
1052
1053 /* Process Valgrind's command-line opts (from env var VG_OPTS). */
1054 process_cmd_line_options();
1055
1056 /* Initialise the signal handling subsystem. */
1057 VG_(sigstartup_actions)();
1058
1059# ifdef VG_PROFILE
1060 VGP_(init_profiling)();
1061# endif
1062
sewardj5f07b662002-04-23 16:52:51 +00001063 /* Start calibration of our RDTSC-based clock. */
1064 VG_(start_rdtsc_calibration)();
1065
sewardjb3c26872002-03-24 10:05:14 +00001066 /* Hook to delay things long enough so we can get the pid and
1067 attach GDB in another shell. */
1068 /* {extern unsigned int sleep(unsigned int seconds); sleep(10);} */
1069
njn4f9c9342002-04-29 16:03:24 +00001070 if (VG_(clo_instrument) || VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +00001071 VGP_PUSHCC(VgpInitAudit);
1072 VGM_(init_memory_audit)();
1073 VGP_POPCC;
1074 VGP_PUSHCC(VgpReadSyms);
1075 VG_(read_symbols)();
1076 VGP_POPCC;
1077 }
1078
sewardj5f07b662002-04-23 16:52:51 +00001079 /* End calibration of our RDTSC-based clock, leaving it as long as
1080 we can. */
1081 VG_(end_rdtsc_calibration)();
1082
sewardjde4a1d02002-03-22 01:27:54 +00001083 /* This should come after init_memory_audit; otherwise the latter
1084 carefully sets up the permissions maps to cover the anonymous
1085 mmaps for the translation table and translation cache, which
1086 wastes > 20M of virtual address space. */
1087 VG_(init_transtab_and_SMC)();
1088
1089 if (VG_(clo_verbosity) == 1) {
1090 VG_(message)(Vg_UserMsg,
1091 "For more details, rerun with: -v");
1092 }
1093
1094 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1095 instrumented-ly. */
1096 VG_(running_on_simd_CPU) = True;
1097 if (VG_(clo_instrument)) {
1098 VGM_(make_readable) ( (Addr)&VG_(running_on_simd_CPU), 1 );
1099 VGM_(make_readable) ( (Addr)&VG_(clo_instrument), 1 );
1100 VGM_(make_readable) ( (Addr)&VG_(clo_trace_malloc), 1 );
1101 VGM_(make_readable) ( (Addr)&VG_(clo_sloppy_malloc), 1 );
1102 }
1103
njn4f9c9342002-04-29 16:03:24 +00001104 if (VG_(clo_cachesim))
1105 VG_(init_cachesim)();
1106
sewardjde4a1d02002-03-22 01:27:54 +00001107 if (VG_(clo_verbosity) > 0)
1108 VG_(message)(Vg_UserMsg, "");
1109
1110 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001111
sewardj671ff542002-05-07 09:25:30 +00001112 VGP_PUSHCC(VgpSched);
sewardj2e93c502002-04-12 11:12:52 +00001113 VG_(scheduler_init)();
1114 src = VG_(scheduler)();
sewardj671ff542002-05-07 09:25:30 +00001115 VGP_POPCC;
sewardjde4a1d02002-03-22 01:27:54 +00001116
1117 if (VG_(clo_verbosity) > 0)
1118 VG_(message)(Vg_UserMsg, "");
1119
sewardj2e93c502002-04-12 11:12:52 +00001120 if (src == VgSrc_Deadlock) {
1121 VG_(message)(Vg_UserMsg,
1122 "Warning: pthread scheduler exited due to deadlock");
1123 }
1124
sewardjde4a1d02002-03-22 01:27:54 +00001125 if (VG_(clo_instrument)) {
1126 VG_(show_all_errors)();
1127 VG_(clientmalloc_done)();
1128 if (VG_(clo_verbosity) == 1) {
1129 VG_(message)(Vg_UserMsg,
1130 "For counts of detected errors, rerun with: -v");
1131 }
1132 if (VG_(clo_leak_check)) VG_(detect_memory_leaks)();
1133 }
1134 VG_(running_on_simd_CPU) = False;
sewardj2e93c502002-04-12 11:12:52 +00001135
njn4f9c9342002-04-29 16:03:24 +00001136 if (VG_(clo_cachesim))
1137 VG_(show_cachesim_results)(VG_(client_argc), VG_(client_argv));
1138
sewardj0c3b53f2002-05-01 01:58:35 +00001139 VG_(do_sanity_checks)( True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001140
1141 if (VG_(clo_verbosity) > 1)
1142 vg_show_counts();
1143
1144 if (0) {
1145 VG_(message)(Vg_DebugMsg, "");
1146 VG_(message)(Vg_DebugMsg,
1147 "------ Valgrind's internal memory use stats follow ------" );
1148 VG_(mallocSanityCheckAll)();
1149 VG_(show_all_arena_stats)();
1150 VG_(message)(Vg_DebugMsg,
1151 "------ Valgrind's ExeContext management stats follow ------" );
1152 VG_(show_ExeContext_stats)();
1153 VG_(message)(Vg_DebugMsg,
1154 "------ Valgrind's client block stats follow ---------------" );
1155 VG_(show_client_block_stats)();
1156 }
1157
1158# ifdef VG_PROFILE
1159 VGP_(done_profiling)();
1160# endif
1161
1162 VG_(done_prof_mem)();
1163
1164 VG_(shutdown_logging)();
1165
1166 /* In LD_PRELOAD, convert "valgrind.so" into "valgrinq.so", so that
1167 child processes don't get traced into. Also done on simulated
1168 execve system call. */
1169 if (!VG_(clo_trace_children)) {
1170 VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
1171 }
1172
sewardj7e87e382002-05-03 19:09:05 +00001173 /* Decide how to exit. This depends on what the scheduler
1174 returned. */
1175 switch (src) {
1176 case VgSrc_ExitSyscall: /* the normal way out */
1177 vg_assert(VG_(last_run_tid) > 0
1178 && VG_(last_run_tid) < VG_N_THREADS);
1179 tst = VG_(get_thread_state)(VG_(last_run_tid));
1180 vg_assert(tst->status == VgTs_Runnable);
1181 /* The thread's %EBX will hold the arg to exit(), so we just
1182 do exit with that arg. */
1183 VG_(exit)( tst->m_ebx );
1184 /* NOT ALIVE HERE! */
1185 VG_(panic)("entered the afterlife in vg_main() -- ExitSyscall");
1186 break; /* what the hell :) */
sewardjde4a1d02002-03-22 01:27:54 +00001187
sewardj7e87e382002-05-03 19:09:05 +00001188 case VgSrc_Deadlock:
1189 /* Just exit now. No point in continuing. */
1190 VG_(exit)(0);
1191 VG_(panic)("entered the afterlife in vg_main() -- Deadlock");
1192 break;
1193
1194 case VgSrc_BbsDone:
1195 /* Tricky; we have to try and switch back to the real CPU.
1196 This is all very dodgy and won't work at all in the
1197 presence of threads, or if the client happened to be
1198 running a signal handler. */
1199 /* Prepare to restore state to the real CPU. */
1200 VG_(load_thread_state)(1 /* root thread */ );
1201 VG_(copy_baseBlock_to_m_state_static)();
1202
1203 /* This pushes a return address on the simulator's stack,
1204 which is abandoned. We call vg_sigshutdown_actions() at
1205 the end of vg_switch_to_real_CPU(), so as to ensure that
1206 the original stack and machine state is restored before
1207 the real signal mechanism is restored. */
1208 VG_(switch_to_real_CPU)();
1209
1210 default:
1211 VG_(panic)("vg_main(): unexpected scheduler return code");
1212 }
sewardjde4a1d02002-03-22 01:27:54 +00001213}
1214
1215
1216/* Debugging thing .. can be called from assembly with OYNK macro. */
1217void VG_(oynk) ( Int n )
1218{
1219 OINK(n);
1220}
1221
1222
1223/* Find "valgrind.so" in a LD_PRELOAD=... string, and convert it to
1224 "valgrinq.so", which doesn't do anything. This is used to avoid
1225 tracing into child processes. To make this work the build system
1226 also supplies a dummy file, "valgrinq.so".
1227*/
1228void VG_(mash_LD_PRELOAD_string)( Char* ld_preload_str )
1229{
1230 Char* p;
1231 if (ld_preload_str == NULL)
1232 return;
1233 p = VG_(strstr)(ld_preload_str, "valgrind.so");
1234 if (p == NULL)
1235 return;
1236 p[7] = 'q';
1237}
1238
1239/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1240 it to attach to this process. Called if the user requests this
1241 service after an error has been shown, so she can poke around and
1242 look at parameters, memory, etc. You can't meaningfully get GDB to
1243 continue the program, though; to continue, quit GDB. */
1244extern void VG_(start_GDB_whilst_on_client_stack) ( void )
1245{
sewardje6a25242002-04-21 22:03:07 +00001246 Int res;
sewardjde4a1d02002-03-22 01:27:54 +00001247 UChar buf[100];
1248 VG_(sprintf)(buf,
1249 "/usr/bin/gdb -nw /proc/%d/exe %d",
1250 VG_(getpid)(), VG_(getpid)());
sewardje6a25242002-04-21 22:03:07 +00001251 VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
1252 res = VG_(system)(buf);
1253 if (res == 0) {
1254 VG_(message)(Vg_UserMsg, "");
1255 VG_(message)(Vg_UserMsg,
1256 "GDB has detached. Valgrind regains control. We continue.");
1257 } else {
1258 VG_(message)(Vg_UserMsg, "Apparently failed!");
1259 VG_(message)(Vg_UserMsg, "");
sewardjde4a1d02002-03-22 01:27:54 +00001260 }
sewardjde4a1d02002-03-22 01:27:54 +00001261}
1262
1263
1264/* Print some helpful-ish text about unimplemented things, and give
1265 up. */
sewardjcfc39b22002-05-08 01:58:18 +00001266void VG_(unimplemented) ( Char* msg )
sewardjde4a1d02002-03-22 01:27:54 +00001267{
1268 VG_(message)(Vg_UserMsg, "");
1269 VG_(message)(Vg_UserMsg,
1270 "Valgrind detected that your program requires");
1271 VG_(message)(Vg_UserMsg,
1272 "the following unimplemented functionality:");
1273 VG_(message)(Vg_UserMsg, " %s", msg);
1274 VG_(message)(Vg_UserMsg,
1275 "This may be because the functionality is hard to implement,");
1276 VG_(message)(Vg_UserMsg,
1277 "or because no reasonable program would behave this way,");
1278 VG_(message)(Vg_UserMsg,
1279 "or because nobody has yet needed it. In any case, let me know");
1280 VG_(message)(Vg_UserMsg,
1281 "(jseward@acm.org) and/or try to work around the problem, if you can.");
1282 VG_(message)(Vg_UserMsg,
1283 "");
1284 VG_(message)(Vg_UserMsg,
1285 "Valgrind has to exit now. Sorry. Bye!");
1286 VG_(message)(Vg_UserMsg,
1287 "");
sewardj15a43e12002-04-17 19:35:12 +00001288 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +00001289 VG_(exit)(1);
1290}
1291
1292
sewardjcfc39b22002-05-08 01:58:18 +00001293void VG_(nvidia_moan) ( void)
1294{
1295 VG_(message)(Vg_UserMsg,
1296 "The following failure _might_ be caused by linking to NVidia's\n "
1297 "libGL.so, so avoiding it, if you can, _might_ help you. For example,\n "
1298 "re-build any Qt libraries you are using without OpenGL support.");
1299}
1300
1301
sewardjde4a1d02002-03-22 01:27:54 +00001302/*--------------------------------------------------------------------*/
1303/*--- end vg_main.c ---*/
1304/*--------------------------------------------------------------------*/