blob: 128bfddff3f80d3f22fadc45580afa32e7159b26 [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
13 Julian_Seward@muraroa.demon.co.uk
14
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 02111-1307, USA.
29
30 The GNU General Public License is contained in the file LICENSE.
31*/
32
33#include "vg_include.h"
34#include "vg_constants.h"
sewardjde4a1d02002-03-22 01:27:54 +000035
36
37/* ---------------------------------------------------------------------
38 Compute offsets into baseBlock. See comments in vg_include.h.
39 ------------------------------------------------------------------ */
40
41/* The variables storing offsets. */
42
43#define INVALID_OFFSET (-1)
44
45Int VGOFF_(m_eax) = INVALID_OFFSET;
46Int VGOFF_(m_ecx) = INVALID_OFFSET;
47Int VGOFF_(m_edx) = INVALID_OFFSET;
48Int VGOFF_(m_ebx) = INVALID_OFFSET;
49Int VGOFF_(m_esp) = INVALID_OFFSET;
50Int VGOFF_(m_ebp) = INVALID_OFFSET;
51Int VGOFF_(m_esi) = INVALID_OFFSET;
52Int VGOFF_(m_edi) = INVALID_OFFSET;
53Int VGOFF_(m_eflags) = INVALID_OFFSET;
54Int VGOFF_(m_fpustate) = INVALID_OFFSET;
55Int VGOFF_(m_eip) = INVALID_OFFSET;
56Int VGOFF_(spillslots) = INVALID_OFFSET;
57Int VGOFF_(sh_eax) = INVALID_OFFSET;
58Int VGOFF_(sh_ecx) = INVALID_OFFSET;
59Int VGOFF_(sh_edx) = INVALID_OFFSET;
60Int VGOFF_(sh_ebx) = INVALID_OFFSET;
61Int VGOFF_(sh_esp) = INVALID_OFFSET;
62Int VGOFF_(sh_ebp) = INVALID_OFFSET;
63Int VGOFF_(sh_esi) = INVALID_OFFSET;
64Int VGOFF_(sh_edi) = INVALID_OFFSET;
65Int VGOFF_(sh_eflags) = INVALID_OFFSET;
66Int VGOFF_(helper_idiv_64_32) = INVALID_OFFSET;
67Int VGOFF_(helper_div_64_32) = INVALID_OFFSET;
68Int VGOFF_(helper_idiv_32_16) = INVALID_OFFSET;
69Int VGOFF_(helper_div_32_16) = INVALID_OFFSET;
70Int VGOFF_(helper_idiv_16_8) = INVALID_OFFSET;
71Int VGOFF_(helper_div_16_8) = INVALID_OFFSET;
72Int VGOFF_(helper_imul_32_64) = INVALID_OFFSET;
73Int VGOFF_(helper_mul_32_64) = INVALID_OFFSET;
74Int VGOFF_(helper_imul_16_32) = INVALID_OFFSET;
75Int VGOFF_(helper_mul_16_32) = INVALID_OFFSET;
76Int VGOFF_(helper_imul_8_16) = INVALID_OFFSET;
77Int VGOFF_(helper_mul_8_16) = INVALID_OFFSET;
78Int VGOFF_(helper_CLD) = INVALID_OFFSET;
79Int VGOFF_(helper_STD) = INVALID_OFFSET;
80Int VGOFF_(helper_get_dirflag) = INVALID_OFFSET;
81Int VGOFF_(helper_shldl) = INVALID_OFFSET;
82Int VGOFF_(helper_shldw) = INVALID_OFFSET;
83Int VGOFF_(helper_shrdl) = INVALID_OFFSET;
84Int VGOFF_(helper_shrdw) = INVALID_OFFSET;
85Int VGOFF_(helper_RDTSC) = INVALID_OFFSET;
86Int VGOFF_(helper_CPUID) = INVALID_OFFSET;
87Int VGOFF_(helper_BSWAP) = INVALID_OFFSET;
88Int VGOFF_(helper_bt) = INVALID_OFFSET;
89Int VGOFF_(helper_bts) = INVALID_OFFSET;
90Int VGOFF_(helper_btr) = INVALID_OFFSET;
91Int VGOFF_(helper_btc) = INVALID_OFFSET;
92Int VGOFF_(helper_bsf) = INVALID_OFFSET;
93Int VGOFF_(helper_bsr) = INVALID_OFFSET;
94Int VGOFF_(helper_fstsw_AX) = INVALID_OFFSET;
95Int VGOFF_(helper_SAHF) = INVALID_OFFSET;
sewardj4d0ab1f2002-03-24 10:00:09 +000096Int VGOFF_(helper_DAS) = INVALID_OFFSET;
sewardjfe8a1662002-03-24 11:54:07 +000097Int VGOFF_(helper_DAA) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000098Int VGOFF_(helper_value_check4_fail) = INVALID_OFFSET;
99Int VGOFF_(helper_value_check2_fail) = INVALID_OFFSET;
100Int VGOFF_(helper_value_check1_fail) = INVALID_OFFSET;
101Int VGOFF_(helper_value_check0_fail) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +0000102Int VGOFF_(helperc_LOADV4) = INVALID_OFFSET;
103Int VGOFF_(helperc_LOADV2) = INVALID_OFFSET;
104Int VGOFF_(helperc_LOADV1) = INVALID_OFFSET;
105Int VGOFF_(helperc_STOREV4) = INVALID_OFFSET;
106Int VGOFF_(helperc_STOREV2) = INVALID_OFFSET;
107Int VGOFF_(helperc_STOREV1) = INVALID_OFFSET;
108Int VGOFF_(handle_esp_assignment) = INVALID_OFFSET;
109Int VGOFF_(fpu_write_check) = INVALID_OFFSET;
110Int VGOFF_(fpu_read_check) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +0000111
112
113/* This is the actual defn of baseblock. */
114UInt VG_(baseBlock)[VG_BASEBLOCK_WORDS];
115
116/* Words. */
117static Int baB_off = 0;
118
119/* Returns the offset, in words. */
120static Int alloc_BaB ( Int words )
121{
122 Int off = baB_off;
123 baB_off += words;
124 if (baB_off >= VG_BASEBLOCK_WORDS)
125 VG_(panic)( "alloc_BaB: baseBlock is too small");
126
127 return off;
128}
129
130/* Allocate 1 word in baseBlock and set it to the given value. */
131static Int alloc_BaB_1_set ( Addr a )
132{
133 Int off = alloc_BaB(1);
134 VG_(baseBlock)[off] = (UInt)a;
135 return off;
136}
137
138
139/* Here we assign actual offsets. It's important to get the most
140 popular referents within 128 bytes of the start, so we can take
141 advantage of short addressing modes relative to %ebp. Popularity
142 of offsets was measured on 22 Feb 02 running a KDE application, and
143 the slots rearranged accordingly, with a 1.5% reduction in total
144 size of translations. */
145
146static void vg_init_baseBlock ( void )
147{
148 baB_off = 0;
149
150 /* Those with offsets under 128 are carefully chosen. */
151
152 /* WORD offsets in this column */
153 /* 0 */ VGOFF_(m_eax) = alloc_BaB(1);
154 /* 1 */ VGOFF_(m_ecx) = alloc_BaB(1);
155 /* 2 */ VGOFF_(m_edx) = alloc_BaB(1);
156 /* 3 */ VGOFF_(m_ebx) = alloc_BaB(1);
157 /* 4 */ VGOFF_(m_esp) = alloc_BaB(1);
158 /* 5 */ VGOFF_(m_ebp) = alloc_BaB(1);
159 /* 6 */ VGOFF_(m_esi) = alloc_BaB(1);
160 /* 7 */ VGOFF_(m_edi) = alloc_BaB(1);
161 /* 8 */ VGOFF_(m_eflags) = alloc_BaB(1);
162
163 /* 9 */ VGOFF_(sh_eax) = alloc_BaB(1);
164 /* 10 */ VGOFF_(sh_ecx) = alloc_BaB(1);
165 /* 11 */ VGOFF_(sh_edx) = alloc_BaB(1);
166 /* 12 */ VGOFF_(sh_ebx) = alloc_BaB(1);
167 /* 13 */ VGOFF_(sh_esp) = alloc_BaB(1);
168 /* 14 */ VGOFF_(sh_ebp) = alloc_BaB(1);
169 /* 15 */ VGOFF_(sh_esi) = alloc_BaB(1);
170 /* 16 */ VGOFF_(sh_edi) = alloc_BaB(1);
171 /* 17 */ VGOFF_(sh_eflags) = alloc_BaB(1);
172
173 /* 18 */
174 VGOFF_(helper_value_check4_fail)
175 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check4_fail) );
176 /* 19 */
177 VGOFF_(helper_value_check0_fail)
178 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check0_fail) );
179
180 /* 20 */
181 VGOFF_(helperc_STOREV4)
182 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV4) );
183 /* 21 */
184 VGOFF_(helperc_STOREV1)
185 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV1) );
186
187 /* 22 */
188 VGOFF_(helperc_LOADV4)
189 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV4) );
190 /* 23 */
191 VGOFF_(helperc_LOADV1)
192 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV1) );
193
194 /* 24 */
195 VGOFF_(handle_esp_assignment)
196 = alloc_BaB_1_set( (Addr) & VGM_(handle_esp_assignment) );
197
198 /* 25 */
199 VGOFF_(m_eip) = alloc_BaB(1);
200
201 /* There are currently 24 spill slots */
202 /* 26 .. 49 This overlaps the magic boundary at >= 32 words, but
203 most spills are to low numbered spill slots, so the ones above
204 the boundary don't see much action. */
205 VGOFF_(spillslots) = alloc_BaB(VG_MAX_SPILLSLOTS);
206
207 /* These two pushed beyond the boundary because 2-byte transactions
208 are rare. */
209 /* 50 */
210 VGOFF_(helperc_STOREV2)
211 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV2) );
212 /* 51 */
213 VGOFF_(helperc_LOADV2)
214 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV2) );
215
216 /* 52 */
217 VGOFF_(fpu_write_check)
218 = alloc_BaB_1_set( (Addr) & VGM_(fpu_write_check) );
219 /* 53 */
220 VGOFF_(fpu_read_check)
221 = alloc_BaB_1_set( (Addr) & VGM_(fpu_read_check) );
222
223 /* Actually I don't think these two are ever used. */
224 /* 54 */
225 VGOFF_(helper_value_check2_fail)
226 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check2_fail) );
227 /* 55 */
228 VGOFF_(helper_value_check1_fail)
229 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check1_fail) );
230
231 /* I gave up counting at this point. Since they're way above the
232 short-amode-boundary, there's no point. */
233
234 VGOFF_(m_fpustate) = alloc_BaB(VG_SIZE_OF_FPUSTATE_W);
235
236 VGOFF_(helper_idiv_64_32)
237 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_64_32) );
238 VGOFF_(helper_div_64_32)
239 = alloc_BaB_1_set( (Addr) & VG_(helper_div_64_32) );
240 VGOFF_(helper_idiv_32_16)
241 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_32_16) );
242 VGOFF_(helper_div_32_16)
243 = alloc_BaB_1_set( (Addr) & VG_(helper_div_32_16) );
244 VGOFF_(helper_idiv_16_8)
245 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_16_8) );
246 VGOFF_(helper_div_16_8)
247 = alloc_BaB_1_set( (Addr) & VG_(helper_div_16_8) );
248
249 VGOFF_(helper_imul_32_64)
250 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_32_64) );
251 VGOFF_(helper_mul_32_64)
252 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_32_64) );
253 VGOFF_(helper_imul_16_32)
254 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_16_32) );
255 VGOFF_(helper_mul_16_32)
256 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_16_32) );
257 VGOFF_(helper_imul_8_16)
258 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_8_16) );
259 VGOFF_(helper_mul_8_16)
260 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_8_16) );
261
262 VGOFF_(helper_CLD)
263 = alloc_BaB_1_set( (Addr) & VG_(helper_CLD) );
264 VGOFF_(helper_STD)
265 = alloc_BaB_1_set( (Addr) & VG_(helper_STD) );
266 VGOFF_(helper_get_dirflag)
267 = alloc_BaB_1_set( (Addr) & VG_(helper_get_dirflag) );
268
269 VGOFF_(helper_shldl)
270 = alloc_BaB_1_set( (Addr) & VG_(helper_shldl) );
271 VGOFF_(helper_shldw)
272 = alloc_BaB_1_set( (Addr) & VG_(helper_shldw) );
273 VGOFF_(helper_shrdl)
274 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdl) );
275 VGOFF_(helper_shrdw)
276 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdw) );
277
278 VGOFF_(helper_RDTSC)
279 = alloc_BaB_1_set( (Addr) & VG_(helper_RDTSC) );
280 VGOFF_(helper_CPUID)
281 = alloc_BaB_1_set( (Addr) & VG_(helper_CPUID) );
282
283 VGOFF_(helper_bt)
284 = alloc_BaB_1_set( (Addr) & VG_(helper_bt) );
285 VGOFF_(helper_bts)
286 = alloc_BaB_1_set( (Addr) & VG_(helper_bts) );
287 VGOFF_(helper_btr)
288 = alloc_BaB_1_set( (Addr) & VG_(helper_btr) );
289 VGOFF_(helper_btc)
290 = alloc_BaB_1_set( (Addr) & VG_(helper_btc) );
291
292 VGOFF_(helper_bsf)
293 = alloc_BaB_1_set( (Addr) & VG_(helper_bsf) );
294 VGOFF_(helper_bsr)
295 = alloc_BaB_1_set( (Addr) & VG_(helper_bsr) );
296
297 VGOFF_(helper_fstsw_AX)
298 = alloc_BaB_1_set( (Addr) & VG_(helper_fstsw_AX) );
299 VGOFF_(helper_SAHF)
300 = alloc_BaB_1_set( (Addr) & VG_(helper_SAHF) );
sewardj4d0ab1f2002-03-24 10:00:09 +0000301 VGOFF_(helper_DAS)
302 = alloc_BaB_1_set( (Addr) & VG_(helper_DAS) );
sewardjfe8a1662002-03-24 11:54:07 +0000303 VGOFF_(helper_DAA)
304 = alloc_BaB_1_set( (Addr) & VG_(helper_DAA) );
sewardjde4a1d02002-03-22 01:27:54 +0000305}
306
307
308/* ---------------------------------------------------------------------
309 Global entities which are not referenced from generated code.
310 ------------------------------------------------------------------ */
311
312/* The stack on which Valgrind runs. We can't use the same stack as
313 the simulatee -- that's an important design decision. */
314UInt VG_(stack)[10000];
315
316/* Ditto our signal delivery stack. */
317UInt VG_(sigstack)[10000];
318
319/* Saving stuff across system calls. */
320UInt VG_(real_fpu_state_saved_over_syscall_d1)[VG_SIZE_OF_FPUSTATE_W];
321UInt VG_(real_fpu_state_saved_over_syscall_d2)[VG_SIZE_OF_FPUSTATE_W];
322Addr VG_(esp_saved_over_syscall_d1);
323Addr VG_(esp_saved_over_syscall_d2);
324
325/* Counts downwards in vg_run_innerloop. */
326UInt VG_(dispatch_ctr);
327
sewardjde4a1d02002-03-22 01:27:54 +0000328
329/* 64-bit counter for the number of basic blocks done. */
330ULong VG_(bbs_done);
331/* 64-bit counter for the number of bbs to go before a debug exit. */
332ULong VG_(bbs_to_go);
333
334/* Produce debugging output? */
335Bool VG_(disassemble) = False;
336
337/* The current LRU epoch. */
338UInt VG_(current_epoch) = 0;
339
340
341/* ---------------------------------------------------------------------
342 Counters, for informational purposes only.
343 ------------------------------------------------------------------ */
344
345/* Number of lookups which miss the fast tt helper. */
346UInt VG_(tt_fast_misses) = 0;
347
348
349/* Counts for LRU informational messages. */
350
351/* Number and total o/t size of new translations this epoch. */
352UInt VG_(this_epoch_in_count) = 0;
353UInt VG_(this_epoch_in_osize) = 0;
354UInt VG_(this_epoch_in_tsize) = 0;
355/* Number and total o/t size of discarded translations this epoch. */
356UInt VG_(this_epoch_out_count) = 0;
357UInt VG_(this_epoch_out_osize) = 0;
358UInt VG_(this_epoch_out_tsize) = 0;
359/* Number and total o/t size of translations overall. */
360UInt VG_(overall_in_count) = 0;
361UInt VG_(overall_in_osize) = 0;
362UInt VG_(overall_in_tsize) = 0;
363/* Number and total o/t size of discards overall. */
364UInt VG_(overall_out_count) = 0;
365UInt VG_(overall_out_osize) = 0;
366UInt VG_(overall_out_tsize) = 0;
367
368/* The number of LRU-clearings of TT/TC. */
369UInt VG_(number_of_lrus) = 0;
370
371
372/* Counts pertaining to the register allocator. */
373
374/* total number of uinstrs input to reg-alloc */
375UInt VG_(uinstrs_prealloc) = 0;
376
377/* total number of uinstrs added due to spill code */
378UInt VG_(uinstrs_spill) = 0;
379
380/* number of bbs requiring spill code */
381UInt VG_(translations_needing_spill) = 0;
382
383/* total of register ranks over all translations */
384UInt VG_(total_reg_rank) = 0;
385
386
387/* Counts pertaining to the self-modifying-code detection machinery. */
388
389/* Total number of writes checked. */
390UInt VG_(smc_total_check4s) = 0;
391
392/* Number of writes which the fast smc check couldn't show were
393 harmless. */
394UInt VG_(smc_cache_passed) = 0;
395
396/* Numnber of writes which really did write on original code. */
397UInt VG_(smc_fancy_passed) = 0;
398
399/* Number of translations discarded as a result. */
400UInt VG_(smc_discard_count) = 0;
401
402
403/* Counts pertaining to internal sanity checking. */
sewardjde4a1d02002-03-22 01:27:54 +0000404UInt VG_(sanity_fast_count) = 0;
405UInt VG_(sanity_slow_count) = 0;
406
sewardj2e93c502002-04-12 11:12:52 +0000407/* Counts pertaining to the scheduler. */
408UInt VG_(num_scheduling_events_MINOR) = 0;
409UInt VG_(num_scheduling_events_MAJOR) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000410
411
412/* ---------------------------------------------------------------------
413 Values derived from command-line options.
414 ------------------------------------------------------------------ */
415
sewardj97ced732002-03-25 00:07:36 +0000416Bool VG_(clo_check_addrVs);
sewardjde4a1d02002-03-22 01:27:54 +0000417Bool VG_(clo_GDB_attach);
418Int VG_(sanity_level);
419Int VG_(clo_verbosity);
420Bool VG_(clo_demangle);
421Bool VG_(clo_leak_check);
422Bool VG_(clo_show_reachable);
423Int VG_(clo_leak_resolution);
424Bool VG_(clo_sloppy_malloc);
425Bool VG_(clo_partial_loads_ok);
426Bool VG_(clo_trace_children);
427Int VG_(clo_logfile_fd);
428Int VG_(clo_freelist_vol);
429Bool VG_(clo_workaround_gcc296_bugs);
430Int VG_(clo_n_suppressions);
431Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
432Bool VG_(clo_single_step);
433Bool VG_(clo_optimise);
434Bool VG_(clo_instrument);
435Bool VG_(clo_cleanup);
436Bool VG_(clo_client_perms);
437Int VG_(clo_smc_check);
438Bool VG_(clo_trace_syscalls);
439Bool VG_(clo_trace_signals);
440Bool VG_(clo_trace_symtab);
441Bool VG_(clo_trace_malloc);
sewardj8937c812002-04-12 20:12:20 +0000442Bool VG_(clo_trace_sched);
443Bool VG_(clo_trace_pthread);
sewardjde4a1d02002-03-22 01:27:54 +0000444ULong VG_(clo_stop_after);
445Int VG_(clo_dump_error);
446Int VG_(clo_backtrace_size);
447
448/* This Bool is needed by wrappers in vg_clientmalloc.c to decide how
449 to behave. Initially we say False. */
450Bool VG_(running_on_simd_CPU) = False;
451
452/* Holds client's %esp at the point we gained control. */
453Addr VG_(esp_at_startup);
454
455/* As deduced from VG_(esp_at_startup), the client's argc, argv[] and
456 envp[] as extracted from the client's stack at startup-time. */
457Int VG_(client_argc);
458Char** VG_(client_argv);
459Char** VG_(client_envp);
460
461/* A place into which to copy the value of env var VG_ARGS, so we
462 don't have to modify the original. */
463static Char vg_cmdline_copy[M_VG_CMDLINE_STRLEN];
464
465
466/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000467 Processing of command-line options.
468 ------------------------------------------------------------------ */
469
470static void bad_option ( Char* opt )
471{
472 VG_(shutdown_logging)();
473 VG_(clo_logfile_fd) = 2; /* stderr */
474 VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
475 VG_(exit)(1);
476}
477
478static void config_error ( Char* msg )
479{
480 VG_(shutdown_logging)();
481 VG_(clo_logfile_fd) = 2; /* stderr */
482 VG_(printf)("valgrind.so: Startup or configuration error:\n\t%s\n", msg);
483 VG_(printf)("valgrind.so: Unable to start up properly. Giving up.\n");
484 VG_(exit)(1);
485}
486
487
488static void process_cmd_line_options ( void )
489{
490 UChar* argv[M_VG_CMDLINE_OPTS];
491 UInt argc;
492 UChar* p;
493 UChar* str;
494 Int i, eventually_logfile_fd;
495
496# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
497# define STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2)))
498# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
499
500 /* Set defaults. */
sewardj97ced732002-03-25 00:07:36 +0000501 VG_(clo_check_addrVs) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000502 VG_(clo_GDB_attach) = False;
503 VG_(sanity_level) = 1;
504 VG_(clo_verbosity) = 1;
505 VG_(clo_demangle) = True;
506 VG_(clo_leak_check) = False;
507 VG_(clo_show_reachable) = False;
508 VG_(clo_leak_resolution) = 2;
509 VG_(clo_sloppy_malloc) = False;
510 VG_(clo_partial_loads_ok) = True;
511 VG_(clo_trace_children) = False;
512 VG_(clo_logfile_fd) = 2; /* stderr */
513 VG_(clo_freelist_vol) = 1000000;
514 VG_(clo_workaround_gcc296_bugs) = False;
515 VG_(clo_n_suppressions) = 0;
516 VG_(clo_single_step) = False;
517 VG_(clo_optimise) = True;
518 VG_(clo_instrument) = True;
519 VG_(clo_cleanup) = True;
sewardj2e93c502002-04-12 11:12:52 +0000520 VG_(clo_client_perms) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000521 VG_(clo_smc_check) = /* VG_CLO_SMC_SOME */ VG_CLO_SMC_NONE;
522 VG_(clo_trace_syscalls) = False;
523 VG_(clo_trace_signals) = False;
524 VG_(clo_trace_symtab) = False;
525 VG_(clo_trace_malloc) = False;
sewardj8937c812002-04-12 20:12:20 +0000526 VG_(clo_trace_sched) = False;
527 VG_(clo_trace_pthread) = False;
sewardjde4a1d02002-03-22 01:27:54 +0000528 VG_(clo_stop_after) = 1000000000000LL;
529 VG_(clo_dump_error) = 0;
530 VG_(clo_backtrace_size) = 4;
531
532 eventually_logfile_fd = VG_(clo_logfile_fd);
533
534 /* Once logging is started, we can safely send messages pertaining
535 to failures in initialisation. */
536 VG_(startup_logging)();
537
538 /* Magically find the client's argc/argv/envp. This kludge is
539 entirely dependent on the stack layout imposed by libc at
540 startup. Hence the magic offsets. Then check (heuristically)
541 that the results are plausible. There must be a better way to
542 do this ... */
543
544# if 0
545 /* Use this to search for the correct offsets if the tests below
546 barf. */
547 { Int i;
548 VG_(printf)("startup %%esp is %p\n", VG_(esp_at_startup) );
549 for (i = 0; i < 10; i++) {
550 Char* p = ((Char**)VG_(esp_at_startup))[i];
551 VG_(printf)("%d: %p\n", i, p);
552 }
553 }
554# endif
555
sewardja88ebf62002-03-24 12:22:39 +0000556# if defined(GLIBC_2_2)
sewardjde4a1d02002-03-22 01:27:54 +0000557 /* These offsets (5,6,7) are right for my RedHat 7.2 (glibc-2.2.4)
558 box. */
559
560 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [5] );
561 VG_(client_argv) = (Char**)( ((void**)VG_(esp_at_startup)) [6] );
562 VG_(client_envp) = (Char**)( ((void**)VG_(esp_at_startup)) [7] );
563
564 if ( ((UInt)VG_(client_argc)) > 0 &&
565 ((UInt)VG_(client_argc)) < 10000 &&
566 (Addr)VG_(client_argv) >= 0x8000000 &&
567 (Addr)VG_(client_envp) >= 0x8000000)
568 goto argc_argv_envp_OK;
569
570 /* If that's no good, try some other offsets discovered by KDE
571 folks on 8 Feb 02:
572 For glibc > 2.2.4 the offset 9/10/11 did the trick. Coolo found
573 out those, on I think a Caldera 3.1 with glibc 2.2.4 -- the same
574 offsets worked for on a debian sid with glibc 2.2.5. */
575
576 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [9] );
577 VG_(client_argv) = (Char**)( ((void**)VG_(esp_at_startup)) [10] );
578 VG_(client_envp) = (Char**)( ((void**)VG_(esp_at_startup)) [11] );
579
580 if ( ((UInt)VG_(client_argc)) > 0 &&
581 ((UInt)VG_(client_argc)) < 10000 &&
582 (Addr)VG_(client_argv) >= 0x8000000 &&
583 (Addr)VG_(client_envp) >= 0x8000000)
584 goto argc_argv_envp_OK;
585
sewardja88ebf62002-03-24 12:22:39 +0000586# endif /* defined(GLIBC_2_2) */
587
588# if defined(GLIBC_2_1)
sewardjde4a1d02002-03-22 01:27:54 +0000589 /* Doesn't look promising. Try offsets for RedHat 6.2
590 (glibc-2.1.3) instead. In this case, the argv and envp vectors
591 are actually on the stack (bizarrely). */
592
593 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [4] );
594 VG_(client_argv) = (Char**) & ( ((void**)VG_(esp_at_startup)) [5] );
595 VG_(client_envp)
596 = (Char**) & ( ((void**)VG_(esp_at_startup)) [6 + VG_(client_argc)] );
597
598 if ( ((UInt)VG_(client_argc)) > 0 &&
599 ((UInt)VG_(client_argc)) < 10000 &&
600 (Addr)VG_(client_argv) >= 0x8000000 &&
601 (Addr)VG_(client_envp) >= 0x8000000)
602 goto argc_argv_envp_OK;
603
604 /* Here's yet another variant, from <hansen> (irc.kde.org). */
605
606 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [9] );
607 VG_(client_argv) = (Char**) & ( ((void**)VG_(esp_at_startup)) [10] );
608 VG_(client_envp)
609 = (Char**) & ( ((void**)VG_(esp_at_startup)) [11 + VG_(client_argc)] );
610
611 if ( ((UInt)VG_(client_argc)) > 0 &&
612 ((UInt)VG_(client_argc)) < 10000 &&
613 (Addr)VG_(client_argv) >= 0x8000000 &&
614 (Addr)VG_(client_envp) >= 0x8000000)
615 goto argc_argv_envp_OK;
sewardja88ebf62002-03-24 12:22:39 +0000616# endif /* defined(GLIBC_2_1) */
617
618# if !defined(GLIBC_2_2) && !defined(GLIBC_2_1)
619 config_error("autoconf/configure detected neither glibc 2.1.X nor 2.2.X");
620# endif
sewardjde4a1d02002-03-22 01:27:54 +0000621
622 /* VG_(printf)("%d %p %p\n", VG_(client_argc), VG_(client_argv),
623 VG_(client_envp));
624 */
625 /* We're hosed. Give up :-( */
626 config_error(
627 "Can't get plausible values for client's argc/argv/envp.\n\t"
628 "You may be able to fix this; see process_cmd_line_options()\n\t"
629 "in vg_main.c"
630 );
631 /* NOTREACHED */
632
633 argc_argv_envp_OK:
634
635 /* Now that VG_(client_envp) has been set, we can extract the args
636 for Valgrind itself. Copy into global var so that we don't have to
637 write zeroes to the getenv'd value itself. */
638 str = VG_(getenv)("VG_ARGS");
639 argc = 0;
640
641 if (!str) {
642 config_error("Can't read options from env var VG_ARGS.");
643 }
644
645 if (VG_(strlen)(str) >= M_VG_CMDLINE_STRLEN-1) {
646 config_error("Command line length exceeds M_CMDLINE_STRLEN.");
647 }
648 VG_(strcpy)(vg_cmdline_copy, str);
649 str = NULL;
650
651 p = &vg_cmdline_copy[0];
652 while (True) {
653 while (ISSPACE(*p)) { *p = 0; p++; }
654 if (*p == 0) break;
655 if (argc < M_VG_CMDLINE_OPTS-1) {
656 argv[argc] = p; argc++;
657 } else {
658 config_error(
659 "Found more than M_CMDLINE_OPTS command-line opts.");
660 }
661 while (*p != 0 && !ISSPACE(*p)) p++;
662 }
663
664 for (i = 0; i < argc; i++) {
665
666 if (STREQ(argv[i], "-v") || STREQ(argv[i], "--verbose"))
667 VG_(clo_verbosity)++;
668 else if (STREQ(argv[i], "-q") || STREQ(argv[i], "--quiet"))
669 VG_(clo_verbosity)--;
670
sewardj97ced732002-03-25 00:07:36 +0000671 else if (STREQ(argv[i], "--check-addrVs=yes"))
672 VG_(clo_check_addrVs) = True;
673 else if (STREQ(argv[i], "--check-addrVs=no"))
674 VG_(clo_check_addrVs) = False;
675
sewardjde4a1d02002-03-22 01:27:54 +0000676 else if (STREQ(argv[i], "--gdb-attach=yes"))
677 VG_(clo_GDB_attach) = True;
678 else if (STREQ(argv[i], "--gdb-attach=no"))
679 VG_(clo_GDB_attach) = False;
680
681 else if (STREQ(argv[i], "--demangle=yes"))
682 VG_(clo_demangle) = True;
683 else if (STREQ(argv[i], "--demangle=no"))
684 VG_(clo_demangle) = False;
685
686 else if (STREQ(argv[i], "--partial-loads-ok=yes"))
687 VG_(clo_partial_loads_ok) = True;
688 else if (STREQ(argv[i], "--partial-loads-ok=no"))
689 VG_(clo_partial_loads_ok) = False;
690
691 else if (STREQ(argv[i], "--leak-check=yes"))
692 VG_(clo_leak_check) = True;
693 else if (STREQ(argv[i], "--leak-check=no"))
694 VG_(clo_leak_check) = False;
695
696 else if (STREQ(argv[i], "--show-reachable=yes"))
697 VG_(clo_show_reachable) = True;
698 else if (STREQ(argv[i], "--show-reachable=no"))
699 VG_(clo_show_reachable) = False;
700
701 else if (STREQ(argv[i], "--leak-resolution=low"))
702 VG_(clo_leak_resolution) = 2;
703 else if (STREQ(argv[i], "--leak-resolution=med"))
704 VG_(clo_leak_resolution) = 4;
705 else if (STREQ(argv[i], "--leak-resolution=high"))
706 VG_(clo_leak_resolution) = VG_DEEPEST_BACKTRACE;
707
708 else if (STREQ(argv[i], "--sloppy-malloc=yes"))
709 VG_(clo_sloppy_malloc) = True;
710 else if (STREQ(argv[i], "--sloppy-malloc=no"))
711 VG_(clo_sloppy_malloc) = False;
712
713 else if (STREQ(argv[i], "--trace-children=yes"))
714 VG_(clo_trace_children) = True;
715 else if (STREQ(argv[i], "--trace-children=no"))
716 VG_(clo_trace_children) = False;
717
718 else if (STREQ(argv[i], "--workaround-gcc296-bugs=yes"))
719 VG_(clo_workaround_gcc296_bugs) = True;
720 else if (STREQ(argv[i], "--workaround-gcc296-bugs=no"))
721 VG_(clo_workaround_gcc296_bugs) = False;
722
723 else if (STREQN(15, argv[i], "--sanity-level="))
724 VG_(sanity_level) = (Int)VG_(atoll)(&argv[i][15]);
725
726 else if (STREQN(13, argv[i], "--logfile-fd="))
727 eventually_logfile_fd = (Int)VG_(atoll)(&argv[i][13]);
728
729 else if (STREQN(15, argv[i], "--freelist-vol=")) {
730 VG_(clo_freelist_vol) = (Int)VG_(atoll)(&argv[i][15]);
731 if (VG_(clo_freelist_vol) < 0) VG_(clo_freelist_vol) = 2;
732 }
733
734 else if (STREQN(15, argv[i], "--suppressions=")) {
735 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
736 VG_(message)(Vg_UserMsg, "Too many logfiles specified.");
737 VG_(message)(Vg_UserMsg,
738 "Increase VG_CLO_MAX_SFILES and recompile.");
739 bad_option(argv[i]);
740 }
741 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &argv[i][15];
742 VG_(clo_n_suppressions)++;
743 }
744 else if (STREQ(argv[i], "--single-step=yes"))
745 VG_(clo_single_step) = True;
746 else if (STREQ(argv[i], "--single-step=no"))
747 VG_(clo_single_step) = False;
748
749 else if (STREQ(argv[i], "--optimise=yes"))
750 VG_(clo_optimise) = True;
751 else if (STREQ(argv[i], "--optimise=no"))
752 VG_(clo_optimise) = False;
753
754 else if (STREQ(argv[i], "--instrument=yes"))
755 VG_(clo_instrument) = True;
756 else if (STREQ(argv[i], "--instrument=no"))
757 VG_(clo_instrument) = False;
758
759 else if (STREQ(argv[i], "--cleanup=yes"))
760 VG_(clo_cleanup) = True;
761 else if (STREQ(argv[i], "--cleanup=no"))
762 VG_(clo_cleanup) = False;
763
764 else if (STREQ(argv[i], "--client-perms=yes"))
765 VG_(clo_client_perms) = True;
766 else if (STREQ(argv[i], "--client-perms=no"))
767 VG_(clo_client_perms) = False;
768
769 else if (STREQ(argv[i], "--smc-check=none"))
770 VG_(clo_smc_check) = VG_CLO_SMC_NONE;
771 else if (STREQ(argv[i], "--smc-check=some"))
772 VG_(clo_smc_check) = VG_CLO_SMC_SOME;
773 else if (STREQ(argv[i], "--smc-check=all"))
774 VG_(clo_smc_check) = VG_CLO_SMC_ALL;
775
776 else if (STREQ(argv[i], "--trace-syscalls=yes"))
777 VG_(clo_trace_syscalls) = True;
778 else if (STREQ(argv[i], "--trace-syscalls=no"))
779 VG_(clo_trace_syscalls) = False;
780
781 else if (STREQ(argv[i], "--trace-signals=yes"))
782 VG_(clo_trace_signals) = True;
783 else if (STREQ(argv[i], "--trace-signals=no"))
784 VG_(clo_trace_signals) = False;
785
786 else if (STREQ(argv[i], "--trace-symtab=yes"))
787 VG_(clo_trace_symtab) = True;
788 else if (STREQ(argv[i], "--trace-symtab=no"))
789 VG_(clo_trace_symtab) = False;
790
791 else if (STREQ(argv[i], "--trace-malloc=yes"))
792 VG_(clo_trace_malloc) = True;
793 else if (STREQ(argv[i], "--trace-malloc=no"))
794 VG_(clo_trace_malloc) = False;
795
sewardj8937c812002-04-12 20:12:20 +0000796 else if (STREQ(argv[i], "--trace-sched=yes"))
797 VG_(clo_trace_sched) = True;
798 else if (STREQ(argv[i], "--trace-sched=no"))
799 VG_(clo_trace_sched) = False;
800
801 else if (STREQ(argv[i], "--trace-pthread=yes"))
802 VG_(clo_trace_pthread) = True;
803 else if (STREQ(argv[i], "--trace-pthread=no"))
804 VG_(clo_trace_pthread) = False;
805
sewardjde4a1d02002-03-22 01:27:54 +0000806 else if (STREQN(13, argv[i], "--stop-after="))
807 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
808
809 else if (STREQN(13, argv[i], "--dump-error="))
810 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
811
812 else if (STREQN(14, argv[i], "--num-callers=")) {
813 /* Make sure it's sane. */
814 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
815 if (VG_(clo_backtrace_size) < 2)
816 VG_(clo_backtrace_size) = 2;
817 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
818 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
819 }
820
821 else
822 bad_option(argv[i]);
823 }
824
825# undef ISSPACE
826# undef STREQ
827# undef STREQN
828
829 if (VG_(clo_verbosity < 0))
830 VG_(clo_verbosity) = 0;
831
832 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
833 VG_(message)(Vg_UserMsg, "");
834 VG_(message)(Vg_UserMsg,
835 "--gdb-attach=yes conflicts with --trace-children=yes");
836 VG_(message)(Vg_UserMsg,
837 "Please choose one or the other, but not both.");
838 bad_option("--gdb-attach=yes and --trace-children=yes");
839 }
840
sewardj2e93c502002-04-12 11:12:52 +0000841#if 0
sewardjde4a1d02002-03-22 01:27:54 +0000842 if (VG_(clo_client_perms) && !VG_(clo_instrument)) {
843 VG_(message)(Vg_UserMsg, "");
844 VG_(message)(Vg_UserMsg,
845 "--client-perms=yes requires --instrument=yes");
846 bad_option("--client-perms=yes without --instrument=yes");
847 }
848
849 if (VG_(clo_client_perms))
850 vg_assert(VG_(clo_instrument));
sewardj2e93c502002-04-12 11:12:52 +0000851#endif
sewardjde4a1d02002-03-22 01:27:54 +0000852
853 VG_(clo_logfile_fd) = eventually_logfile_fd;
854
sewardjde4a1d02002-03-22 01:27:54 +0000855 if (VG_(clo_verbosity > 0))
856 VG_(message)(Vg_UserMsg,
857 "valgrind-%s, a memory error detector for x86 GNU/Linux.",
sewardj3b2736a2002-03-24 12:18:35 +0000858 VERSION);
859
sewardjde4a1d02002-03-22 01:27:54 +0000860 if (VG_(clo_verbosity > 0))
861 VG_(message)(Vg_UserMsg,
862 "Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.");
863 if (VG_(clo_verbosity) > 1) {
864 VG_(message)(Vg_UserMsg, "Startup, with flags:");
865 for (i = 0; i < argc; i++) {
866 VG_(message)(Vg_UserMsg, " %s", argv[i]);
867 }
868 }
869
870 if (VG_(clo_n_suppressions) == 0) {
871 config_error("No error-suppression files were specified.");
872 }
873}
874
875
876/* ---------------------------------------------------------------------
877 Copying to/from m_state_static.
878 ------------------------------------------------------------------ */
879
880UInt VG_(m_state_static) [8 /* int regs, in Intel order */
881 + 1 /* %eflags */
882 + 1 /* %eip */
883 + VG_SIZE_OF_FPUSTATE_W /* FPU state */
884 ];
885
886void VG_(copy_baseBlock_to_m_state_static) ( void )
887{
888 Int i;
889 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
890 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
891 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
892 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
893 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
894 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
895 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
896 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
897
898 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_eflags)];
899 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
900
901 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
902 VG_(m_state_static)[40/4 + i]
903 = VG_(baseBlock)[VGOFF_(m_fpustate) + i];
904}
905
906
907void VG_(copy_m_state_static_to_baseBlock) ( void )
908{
909 Int i;
910 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
911 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
912 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
913 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
914 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
915 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
916 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
917 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
918
919 VG_(baseBlock)[VGOFF_(m_eflags)] = VG_(m_state_static)[32/4];
920 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
921
922 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
923 VG_(baseBlock)[VGOFF_(m_fpustate) + i]
924 = VG_(m_state_static)[40/4 + i];
925}
926
927
928/* ---------------------------------------------------------------------
929 Show accumulated counts.
930 ------------------------------------------------------------------ */
931
932static void vg_show_counts ( void )
933{
934 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000935 " lru: %d epochs, %d clearings.",
936 VG_(current_epoch),
937 VG_(number_of_lrus) );
sewardjde4a1d02002-03-22 01:27:54 +0000938 VG_(message)(Vg_DebugMsg,
939 "translate: new %d (%d -> %d), discard %d (%d -> %d).",
940 VG_(overall_in_count),
941 VG_(overall_in_osize),
942 VG_(overall_in_tsize),
943 VG_(overall_out_count),
944 VG_(overall_out_osize),
945 VG_(overall_out_tsize) );
946 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000947 " dispatch: %lu basic blocks, %d/%d sched events, %d tt_fast misses.",
948 VG_(bbs_done), VG_(num_scheduling_events_MAJOR),
949 VG_(num_scheduling_events_MINOR),
950 VG_(tt_fast_misses));
sewardjde4a1d02002-03-22 01:27:54 +0000951 VG_(message)(Vg_DebugMsg,
952 "reg-alloc: %d t-req-spill, "
953 "%d+%d orig+spill uis, %d total-reg-r.",
954 VG_(translations_needing_spill),
955 VG_(uinstrs_prealloc),
956 VG_(uinstrs_spill),
957 VG_(total_reg_rank) );
958 VG_(message)(Vg_DebugMsg,
959 "smc-check: %d checks, %d fast pass, "
960 "%d slow pass, %d discards.",
961 VG_(smc_total_check4s),
962 VG_(smc_cache_passed),
963 VG_(smc_fancy_passed),
964 VG_(smc_discard_count) );
965 VG_(message)(Vg_DebugMsg,
966 " sanity: %d cheap, %d expensive checks.",
967 VG_(sanity_fast_count),
968 VG_(sanity_slow_count) );
969}
970
971
972/* ---------------------------------------------------------------------
973 Main!
974 ------------------------------------------------------------------ */
975
976/* Where we jump to once Valgrind has got control, and the real
977 machine's state has been copied to the m_state_static. */
978
979void VG_(main) ( void )
980{
sewardj2e93c502002-04-12 11:12:52 +0000981 Int i;
982 VgSchedReturnCode src;
sewardjde4a1d02002-03-22 01:27:54 +0000983
984 /* Set up our stack sanity-check words. */
985 for (i = 0; i < 10; i++) {
986 VG_(stack)[i] = (UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1;
987 VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321;
988 }
989
990 /* Set up baseBlock offsets and copy the saved machine's state into
991 it. */
992 vg_init_baseBlock();
993 VG_(copy_m_state_static_to_baseBlock)();
994
995 /* Process Valgrind's command-line opts (from env var VG_OPTS). */
996 process_cmd_line_options();
997
998 /* Initialise the signal handling subsystem. */
999 VG_(sigstartup_actions)();
1000
1001# ifdef VG_PROFILE
1002 VGP_(init_profiling)();
1003# endif
1004
sewardjb3c26872002-03-24 10:05:14 +00001005 /* Hook to delay things long enough so we can get the pid and
1006 attach GDB in another shell. */
1007 /* {extern unsigned int sleep(unsigned int seconds); sleep(10);} */
1008
sewardjde4a1d02002-03-22 01:27:54 +00001009 if (VG_(clo_instrument)) {
1010 VGP_PUSHCC(VgpInitAudit);
1011 VGM_(init_memory_audit)();
1012 VGP_POPCC;
1013 VGP_PUSHCC(VgpReadSyms);
1014 VG_(read_symbols)();
1015 VGP_POPCC;
1016 }
1017
1018 /* This should come after init_memory_audit; otherwise the latter
1019 carefully sets up the permissions maps to cover the anonymous
1020 mmaps for the translation table and translation cache, which
1021 wastes > 20M of virtual address space. */
1022 VG_(init_transtab_and_SMC)();
1023
1024 if (VG_(clo_verbosity) == 1) {
1025 VG_(message)(Vg_UserMsg,
1026 "For more details, rerun with: -v");
1027 }
1028
1029 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1030 instrumented-ly. */
1031 VG_(running_on_simd_CPU) = True;
1032 if (VG_(clo_instrument)) {
1033 VGM_(make_readable) ( (Addr)&VG_(running_on_simd_CPU), 1 );
1034 VGM_(make_readable) ( (Addr)&VG_(clo_instrument), 1 );
1035 VGM_(make_readable) ( (Addr)&VG_(clo_trace_malloc), 1 );
1036 VGM_(make_readable) ( (Addr)&VG_(clo_sloppy_malloc), 1 );
1037 }
1038
1039 if (VG_(clo_verbosity) > 0)
1040 VG_(message)(Vg_UserMsg, "");
1041
1042 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001043
1044 VG_(scheduler_init)();
1045 src = VG_(scheduler)();
sewardjde4a1d02002-03-22 01:27:54 +00001046
1047 if (VG_(clo_verbosity) > 0)
1048 VG_(message)(Vg_UserMsg, "");
1049
sewardj2e93c502002-04-12 11:12:52 +00001050 if (src == VgSrc_Deadlock) {
1051 VG_(message)(Vg_UserMsg,
1052 "Warning: pthread scheduler exited due to deadlock");
1053 }
1054
sewardjde4a1d02002-03-22 01:27:54 +00001055 if (VG_(clo_instrument)) {
1056 VG_(show_all_errors)();
1057 VG_(clientmalloc_done)();
1058 if (VG_(clo_verbosity) == 1) {
1059 VG_(message)(Vg_UserMsg,
1060 "For counts of detected errors, rerun with: -v");
1061 }
1062 if (VG_(clo_leak_check)) VG_(detect_memory_leaks)();
1063 }
1064 VG_(running_on_simd_CPU) = False;
sewardj2e93c502002-04-12 11:12:52 +00001065
1066 VG_(do_sanity_checks)( 0 /* root thread */,
1067 True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001068
1069 if (VG_(clo_verbosity) > 1)
1070 vg_show_counts();
1071
1072 if (0) {
1073 VG_(message)(Vg_DebugMsg, "");
1074 VG_(message)(Vg_DebugMsg,
1075 "------ Valgrind's internal memory use stats follow ------" );
1076 VG_(mallocSanityCheckAll)();
1077 VG_(show_all_arena_stats)();
1078 VG_(message)(Vg_DebugMsg,
1079 "------ Valgrind's ExeContext management stats follow ------" );
1080 VG_(show_ExeContext_stats)();
1081 VG_(message)(Vg_DebugMsg,
1082 "------ Valgrind's client block stats follow ---------------" );
1083 VG_(show_client_block_stats)();
1084 }
1085
1086# ifdef VG_PROFILE
1087 VGP_(done_profiling)();
1088# endif
1089
1090 VG_(done_prof_mem)();
1091
1092 VG_(shutdown_logging)();
1093
1094 /* In LD_PRELOAD, convert "valgrind.so" into "valgrinq.so", so that
1095 child processes don't get traced into. Also done on simulated
1096 execve system call. */
1097 if (!VG_(clo_trace_children)) {
1098 VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
1099 }
1100
1101 /* Prepare to restore state to the real CPU. */
sewardj2e93c502002-04-12 11:12:52 +00001102 VG_(load_thread_state)(0);
sewardjde4a1d02002-03-22 01:27:54 +00001103 VG_(copy_baseBlock_to_m_state_static)();
1104
1105 /* This pushes a return address on the simulator's stack, which
1106 is abandoned. We call vg_sigshutdown_actions() at the end
1107 of vg_switch_to_real_CPU(), so as to ensure that the original
1108 stack and machine state is restored before the real signal
1109 mechanism is restored.
1110 */
1111 VG_(switch_to_real_CPU)();
1112}
1113
1114
1115/* Debugging thing .. can be called from assembly with OYNK macro. */
1116void VG_(oynk) ( Int n )
1117{
1118 OINK(n);
1119}
1120
1121
1122/* Find "valgrind.so" in a LD_PRELOAD=... string, and convert it to
1123 "valgrinq.so", which doesn't do anything. This is used to avoid
1124 tracing into child processes. To make this work the build system
1125 also supplies a dummy file, "valgrinq.so".
1126*/
1127void VG_(mash_LD_PRELOAD_string)( Char* ld_preload_str )
1128{
1129 Char* p;
1130 if (ld_preload_str == NULL)
1131 return;
1132 p = VG_(strstr)(ld_preload_str, "valgrind.so");
1133 if (p == NULL)
1134 return;
1135 p[7] = 'q';
1136}
1137
1138/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1139 it to attach to this process. Called if the user requests this
1140 service after an error has been shown, so she can poke around and
1141 look at parameters, memory, etc. You can't meaningfully get GDB to
1142 continue the program, though; to continue, quit GDB. */
1143extern void VG_(start_GDB_whilst_on_client_stack) ( void )
1144{
1145 UChar buf[100];
1146 VG_(sprintf)(buf,
1147 "/usr/bin/gdb -nw /proc/%d/exe %d",
1148 VG_(getpid)(), VG_(getpid)());
1149 VG_(printf)("starting GDB with cmd: %s\n", buf);
1150 VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
1151 { /* HACK ALERT */
1152 extern int system ( const char * );
1153 system(buf);
1154 /* end of HACK ALERT */
1155 }
1156 VG_(message)(Vg_UserMsg, "");
1157 VG_(message)(Vg_UserMsg,
1158 "GDB has detached. Valgrind regains control. We continue.");
1159}
1160
1161
1162/* Print some helpful-ish text about unimplemented things, and give
1163 up. */
1164extern void VG_(unimplemented) ( Char* msg )
1165{
1166 VG_(message)(Vg_UserMsg, "");
1167 VG_(message)(Vg_UserMsg,
1168 "Valgrind detected that your program requires");
1169 VG_(message)(Vg_UserMsg,
1170 "the following unimplemented functionality:");
1171 VG_(message)(Vg_UserMsg, " %s", msg);
1172 VG_(message)(Vg_UserMsg,
1173 "This may be because the functionality is hard to implement,");
1174 VG_(message)(Vg_UserMsg,
1175 "or because no reasonable program would behave this way,");
1176 VG_(message)(Vg_UserMsg,
1177 "or because nobody has yet needed it. In any case, let me know");
1178 VG_(message)(Vg_UserMsg,
1179 "(jseward@acm.org) and/or try to work around the problem, if you can.");
1180 VG_(message)(Vg_UserMsg,
1181 "");
1182 VG_(message)(Vg_UserMsg,
1183 "Valgrind has to exit now. Sorry. Bye!");
1184 VG_(message)(Vg_UserMsg,
1185 "");
1186 VG_(exit)(1);
1187}
1188
1189
sewardjde4a1d02002-03-22 01:27:54 +00001190/*--------------------------------------------------------------------*/
1191/*--- end vg_main.c ---*/
1192/*--------------------------------------------------------------------*/