blob: ee875e226b77f6ec037ef7e4a72ee257e5d35394 [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
334
335/* ---------------------------------------------------------------------
336 Counters, for informational purposes only.
337 ------------------------------------------------------------------ */
338
339/* Number of lookups which miss the fast tt helper. */
340UInt VG_(tt_fast_misses) = 0;
341
342
343/* Counts for LRU informational messages. */
344
345/* Number and total o/t size of new translations this epoch. */
346UInt VG_(this_epoch_in_count) = 0;
347UInt VG_(this_epoch_in_osize) = 0;
348UInt VG_(this_epoch_in_tsize) = 0;
349/* Number and total o/t size of discarded translations this epoch. */
350UInt VG_(this_epoch_out_count) = 0;
351UInt VG_(this_epoch_out_osize) = 0;
352UInt VG_(this_epoch_out_tsize) = 0;
353/* Number and total o/t size of translations overall. */
354UInt VG_(overall_in_count) = 0;
355UInt VG_(overall_in_osize) = 0;
356UInt VG_(overall_in_tsize) = 0;
357/* Number and total o/t size of discards overall. */
358UInt VG_(overall_out_count) = 0;
359UInt VG_(overall_out_osize) = 0;
360UInt VG_(overall_out_tsize) = 0;
361
362/* The number of LRU-clearings of TT/TC. */
363UInt VG_(number_of_lrus) = 0;
364
365
366/* Counts pertaining to the register allocator. */
367
368/* total number of uinstrs input to reg-alloc */
369UInt VG_(uinstrs_prealloc) = 0;
370
371/* total number of uinstrs added due to spill code */
372UInt VG_(uinstrs_spill) = 0;
373
374/* number of bbs requiring spill code */
375UInt VG_(translations_needing_spill) = 0;
376
377/* total of register ranks over all translations */
378UInt VG_(total_reg_rank) = 0;
379
380
381/* Counts pertaining to the self-modifying-code detection machinery. */
382
383/* Total number of writes checked. */
384UInt VG_(smc_total_check4s) = 0;
385
386/* Number of writes which the fast smc check couldn't show were
387 harmless. */
388UInt VG_(smc_cache_passed) = 0;
389
390/* Numnber of writes which really did write on original code. */
391UInt VG_(smc_fancy_passed) = 0;
392
393/* Number of translations discarded as a result. */
394UInt VG_(smc_discard_count) = 0;
395
396
397/* Counts pertaining to internal sanity checking. */
sewardjde4a1d02002-03-22 01:27:54 +0000398UInt VG_(sanity_fast_count) = 0;
399UInt VG_(sanity_slow_count) = 0;
400
sewardj2e93c502002-04-12 11:12:52 +0000401/* Counts pertaining to the scheduler. */
402UInt VG_(num_scheduling_events_MINOR) = 0;
403UInt VG_(num_scheduling_events_MAJOR) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000404
405
406/* ---------------------------------------------------------------------
407 Values derived from command-line options.
408 ------------------------------------------------------------------ */
409
sewardj97ced732002-03-25 00:07:36 +0000410Bool VG_(clo_check_addrVs);
sewardjde4a1d02002-03-22 01:27:54 +0000411Bool VG_(clo_GDB_attach);
412Int VG_(sanity_level);
413Int VG_(clo_verbosity);
414Bool VG_(clo_demangle);
415Bool VG_(clo_leak_check);
416Bool VG_(clo_show_reachable);
417Int VG_(clo_leak_resolution);
418Bool VG_(clo_sloppy_malloc);
419Bool VG_(clo_partial_loads_ok);
420Bool VG_(clo_trace_children);
421Int VG_(clo_logfile_fd);
422Int VG_(clo_freelist_vol);
423Bool VG_(clo_workaround_gcc296_bugs);
424Int VG_(clo_n_suppressions);
425Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
426Bool VG_(clo_single_step);
427Bool VG_(clo_optimise);
428Bool VG_(clo_instrument);
429Bool VG_(clo_cleanup);
njn4f9c9342002-04-29 16:03:24 +0000430Bool VG_(clo_cachesim);
sewardjde4a1d02002-03-22 01:27:54 +0000431Int VG_(clo_smc_check);
432Bool VG_(clo_trace_syscalls);
433Bool VG_(clo_trace_signals);
434Bool VG_(clo_trace_symtab);
435Bool VG_(clo_trace_malloc);
sewardj8937c812002-04-12 20:12:20 +0000436Bool VG_(clo_trace_sched);
sewardj45b4b372002-04-16 22:50:32 +0000437Int VG_(clo_trace_pthread_level);
sewardjde4a1d02002-03-22 01:27:54 +0000438ULong VG_(clo_stop_after);
439Int VG_(clo_dump_error);
440Int VG_(clo_backtrace_size);
441
442/* This Bool is needed by wrappers in vg_clientmalloc.c to decide how
443 to behave. Initially we say False. */
444Bool VG_(running_on_simd_CPU) = False;
445
446/* Holds client's %esp at the point we gained control. */
447Addr VG_(esp_at_startup);
448
449/* As deduced from VG_(esp_at_startup), the client's argc, argv[] and
450 envp[] as extracted from the client's stack at startup-time. */
451Int VG_(client_argc);
452Char** VG_(client_argv);
453Char** VG_(client_envp);
454
455/* A place into which to copy the value of env var VG_ARGS, so we
456 don't have to modify the original. */
457static Char vg_cmdline_copy[M_VG_CMDLINE_STRLEN];
458
459
460/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000461 Processing of command-line options.
462 ------------------------------------------------------------------ */
463
464static void bad_option ( Char* opt )
465{
466 VG_(shutdown_logging)();
467 VG_(clo_logfile_fd) = 2; /* stderr */
468 VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
469 VG_(exit)(1);
470}
471
472static void config_error ( Char* msg )
473{
474 VG_(shutdown_logging)();
475 VG_(clo_logfile_fd) = 2; /* stderr */
476 VG_(printf)("valgrind.so: Startup or configuration error:\n\t%s\n", msg);
477 VG_(printf)("valgrind.so: Unable to start up properly. Giving up.\n");
478 VG_(exit)(1);
479}
480
481
482static void process_cmd_line_options ( void )
483{
484 UChar* argv[M_VG_CMDLINE_OPTS];
485 UInt argc;
486 UChar* p;
487 UChar* str;
488 Int i, eventually_logfile_fd;
489
490# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
491# define STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2)))
492# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
493
494 /* Set defaults. */
sewardj97ced732002-03-25 00:07:36 +0000495 VG_(clo_check_addrVs) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000496 VG_(clo_GDB_attach) = False;
497 VG_(sanity_level) = 1;
498 VG_(clo_verbosity) = 1;
499 VG_(clo_demangle) = True;
500 VG_(clo_leak_check) = False;
501 VG_(clo_show_reachable) = False;
502 VG_(clo_leak_resolution) = 2;
503 VG_(clo_sloppy_malloc) = False;
504 VG_(clo_partial_loads_ok) = True;
505 VG_(clo_trace_children) = False;
506 VG_(clo_logfile_fd) = 2; /* stderr */
507 VG_(clo_freelist_vol) = 1000000;
508 VG_(clo_workaround_gcc296_bugs) = False;
509 VG_(clo_n_suppressions) = 0;
510 VG_(clo_single_step) = False;
511 VG_(clo_optimise) = True;
512 VG_(clo_instrument) = True;
513 VG_(clo_cleanup) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000514 VG_(clo_smc_check) = /* VG_CLO_SMC_SOME */ VG_CLO_SMC_NONE;
515 VG_(clo_trace_syscalls) = False;
516 VG_(clo_trace_signals) = False;
517 VG_(clo_trace_symtab) = False;
518 VG_(clo_trace_malloc) = False;
sewardj8937c812002-04-12 20:12:20 +0000519 VG_(clo_trace_sched) = False;
sewardj45b4b372002-04-16 22:50:32 +0000520 VG_(clo_trace_pthread_level) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000521 VG_(clo_stop_after) = 1000000000000LL;
522 VG_(clo_dump_error) = 0;
523 VG_(clo_backtrace_size) = 4;
524
525 eventually_logfile_fd = VG_(clo_logfile_fd);
526
527 /* Once logging is started, we can safely send messages pertaining
528 to failures in initialisation. */
529 VG_(startup_logging)();
530
531 /* Magically find the client's argc/argv/envp. This kludge is
532 entirely dependent on the stack layout imposed by libc at
533 startup. Hence the magic offsets. Then check (heuristically)
534 that the results are plausible. There must be a better way to
535 do this ... */
536
537# if 0
538 /* Use this to search for the correct offsets if the tests below
539 barf. */
540 { Int i;
541 VG_(printf)("startup %%esp is %p\n", VG_(esp_at_startup) );
542 for (i = 0; i < 10; i++) {
543 Char* p = ((Char**)VG_(esp_at_startup))[i];
544 VG_(printf)("%d: %p\n", i, p);
545 }
546 }
547# endif
548
sewardja88ebf62002-03-24 12:22:39 +0000549# if defined(GLIBC_2_2)
sewardjde4a1d02002-03-22 01:27:54 +0000550 /* These offsets (5,6,7) are right for my RedHat 7.2 (glibc-2.2.4)
551 box. */
552
553 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [5] );
554 VG_(client_argv) = (Char**)( ((void**)VG_(esp_at_startup)) [6] );
555 VG_(client_envp) = (Char**)( ((void**)VG_(esp_at_startup)) [7] );
556
557 if ( ((UInt)VG_(client_argc)) > 0 &&
558 ((UInt)VG_(client_argc)) < 10000 &&
559 (Addr)VG_(client_argv) >= 0x8000000 &&
560 (Addr)VG_(client_envp) >= 0x8000000)
561 goto argc_argv_envp_OK;
562
563 /* If that's no good, try some other offsets discovered by KDE
564 folks on 8 Feb 02:
565 For glibc > 2.2.4 the offset 9/10/11 did the trick. Coolo found
566 out those, on I think a Caldera 3.1 with glibc 2.2.4 -- the same
567 offsets worked for on a debian sid with glibc 2.2.5. */
568
569 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [9] );
570 VG_(client_argv) = (Char**)( ((void**)VG_(esp_at_startup)) [10] );
571 VG_(client_envp) = (Char**)( ((void**)VG_(esp_at_startup)) [11] );
572
573 if ( ((UInt)VG_(client_argc)) > 0 &&
574 ((UInt)VG_(client_argc)) < 10000 &&
575 (Addr)VG_(client_argv) >= 0x8000000 &&
576 (Addr)VG_(client_envp) >= 0x8000000)
577 goto argc_argv_envp_OK;
578
sewardja88ebf62002-03-24 12:22:39 +0000579# endif /* defined(GLIBC_2_2) */
580
581# if defined(GLIBC_2_1)
sewardjde4a1d02002-03-22 01:27:54 +0000582 /* Doesn't look promising. Try offsets for RedHat 6.2
583 (glibc-2.1.3) instead. In this case, the argv and envp vectors
584 are actually on the stack (bizarrely). */
585
586 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [4] );
587 VG_(client_argv) = (Char**) & ( ((void**)VG_(esp_at_startup)) [5] );
588 VG_(client_envp)
589 = (Char**) & ( ((void**)VG_(esp_at_startup)) [6 + VG_(client_argc)] );
590
591 if ( ((UInt)VG_(client_argc)) > 0 &&
592 ((UInt)VG_(client_argc)) < 10000 &&
593 (Addr)VG_(client_argv) >= 0x8000000 &&
594 (Addr)VG_(client_envp) >= 0x8000000)
595 goto argc_argv_envp_OK;
596
597 /* Here's yet another variant, from <hansen> (irc.kde.org). */
598
599 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [9] );
600 VG_(client_argv) = (Char**) & ( ((void**)VG_(esp_at_startup)) [10] );
601 VG_(client_envp)
602 = (Char**) & ( ((void**)VG_(esp_at_startup)) [11 + VG_(client_argc)] );
603
604 if ( ((UInt)VG_(client_argc)) > 0 &&
605 ((UInt)VG_(client_argc)) < 10000 &&
606 (Addr)VG_(client_argv) >= 0x8000000 &&
607 (Addr)VG_(client_envp) >= 0x8000000)
608 goto argc_argv_envp_OK;
sewardja88ebf62002-03-24 12:22:39 +0000609# endif /* defined(GLIBC_2_1) */
610
611# if !defined(GLIBC_2_2) && !defined(GLIBC_2_1)
612 config_error("autoconf/configure detected neither glibc 2.1.X nor 2.2.X");
613# endif
sewardjde4a1d02002-03-22 01:27:54 +0000614
615 /* VG_(printf)("%d %p %p\n", VG_(client_argc), VG_(client_argv),
616 VG_(client_envp));
617 */
618 /* We're hosed. Give up :-( */
619 config_error(
620 "Can't get plausible values for client's argc/argv/envp.\n\t"
621 "You may be able to fix this; see process_cmd_line_options()\n\t"
622 "in vg_main.c"
623 );
624 /* NOTREACHED */
625
626 argc_argv_envp_OK:
627
628 /* Now that VG_(client_envp) has been set, we can extract the args
629 for Valgrind itself. Copy into global var so that we don't have to
630 write zeroes to the getenv'd value itself. */
631 str = VG_(getenv)("VG_ARGS");
632 argc = 0;
633
634 if (!str) {
635 config_error("Can't read options from env var VG_ARGS.");
636 }
637
638 if (VG_(strlen)(str) >= M_VG_CMDLINE_STRLEN-1) {
639 config_error("Command line length exceeds M_CMDLINE_STRLEN.");
640 }
641 VG_(strcpy)(vg_cmdline_copy, str);
642 str = NULL;
643
644 p = &vg_cmdline_copy[0];
645 while (True) {
646 while (ISSPACE(*p)) { *p = 0; p++; }
647 if (*p == 0) break;
648 if (argc < M_VG_CMDLINE_OPTS-1) {
649 argv[argc] = p; argc++;
650 } else {
651 config_error(
652 "Found more than M_CMDLINE_OPTS command-line opts.");
653 }
654 while (*p != 0 && !ISSPACE(*p)) p++;
655 }
656
657 for (i = 0; i < argc; i++) {
658
659 if (STREQ(argv[i], "-v") || STREQ(argv[i], "--verbose"))
660 VG_(clo_verbosity)++;
661 else if (STREQ(argv[i], "-q") || STREQ(argv[i], "--quiet"))
662 VG_(clo_verbosity)--;
663
sewardj97ced732002-03-25 00:07:36 +0000664 else if (STREQ(argv[i], "--check-addrVs=yes"))
665 VG_(clo_check_addrVs) = True;
666 else if (STREQ(argv[i], "--check-addrVs=no"))
667 VG_(clo_check_addrVs) = False;
668
sewardjde4a1d02002-03-22 01:27:54 +0000669 else if (STREQ(argv[i], "--gdb-attach=yes"))
670 VG_(clo_GDB_attach) = True;
671 else if (STREQ(argv[i], "--gdb-attach=no"))
672 VG_(clo_GDB_attach) = False;
673
674 else if (STREQ(argv[i], "--demangle=yes"))
675 VG_(clo_demangle) = True;
676 else if (STREQ(argv[i], "--demangle=no"))
677 VG_(clo_demangle) = False;
678
679 else if (STREQ(argv[i], "--partial-loads-ok=yes"))
680 VG_(clo_partial_loads_ok) = True;
681 else if (STREQ(argv[i], "--partial-loads-ok=no"))
682 VG_(clo_partial_loads_ok) = False;
683
684 else if (STREQ(argv[i], "--leak-check=yes"))
685 VG_(clo_leak_check) = True;
686 else if (STREQ(argv[i], "--leak-check=no"))
687 VG_(clo_leak_check) = False;
688
689 else if (STREQ(argv[i], "--show-reachable=yes"))
690 VG_(clo_show_reachable) = True;
691 else if (STREQ(argv[i], "--show-reachable=no"))
692 VG_(clo_show_reachable) = False;
693
694 else if (STREQ(argv[i], "--leak-resolution=low"))
695 VG_(clo_leak_resolution) = 2;
696 else if (STREQ(argv[i], "--leak-resolution=med"))
697 VG_(clo_leak_resolution) = 4;
698 else if (STREQ(argv[i], "--leak-resolution=high"))
699 VG_(clo_leak_resolution) = VG_DEEPEST_BACKTRACE;
700
701 else if (STREQ(argv[i], "--sloppy-malloc=yes"))
702 VG_(clo_sloppy_malloc) = True;
703 else if (STREQ(argv[i], "--sloppy-malloc=no"))
704 VG_(clo_sloppy_malloc) = False;
705
706 else if (STREQ(argv[i], "--trace-children=yes"))
707 VG_(clo_trace_children) = True;
708 else if (STREQ(argv[i], "--trace-children=no"))
709 VG_(clo_trace_children) = False;
710
711 else if (STREQ(argv[i], "--workaround-gcc296-bugs=yes"))
712 VG_(clo_workaround_gcc296_bugs) = True;
713 else if (STREQ(argv[i], "--workaround-gcc296-bugs=no"))
714 VG_(clo_workaround_gcc296_bugs) = False;
715
716 else if (STREQN(15, argv[i], "--sanity-level="))
717 VG_(sanity_level) = (Int)VG_(atoll)(&argv[i][15]);
718
719 else if (STREQN(13, argv[i], "--logfile-fd="))
720 eventually_logfile_fd = (Int)VG_(atoll)(&argv[i][13]);
721
722 else if (STREQN(15, argv[i], "--freelist-vol=")) {
723 VG_(clo_freelist_vol) = (Int)VG_(atoll)(&argv[i][15]);
724 if (VG_(clo_freelist_vol) < 0) VG_(clo_freelist_vol) = 2;
725 }
726
727 else if (STREQN(15, argv[i], "--suppressions=")) {
728 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
729 VG_(message)(Vg_UserMsg, "Too many logfiles specified.");
730 VG_(message)(Vg_UserMsg,
731 "Increase VG_CLO_MAX_SFILES and recompile.");
732 bad_option(argv[i]);
733 }
734 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &argv[i][15];
735 VG_(clo_n_suppressions)++;
736 }
737 else if (STREQ(argv[i], "--single-step=yes"))
738 VG_(clo_single_step) = True;
739 else if (STREQ(argv[i], "--single-step=no"))
740 VG_(clo_single_step) = False;
741
742 else if (STREQ(argv[i], "--optimise=yes"))
743 VG_(clo_optimise) = True;
744 else if (STREQ(argv[i], "--optimise=no"))
745 VG_(clo_optimise) = False;
746
747 else if (STREQ(argv[i], "--instrument=yes"))
748 VG_(clo_instrument) = True;
749 else if (STREQ(argv[i], "--instrument=no"))
750 VG_(clo_instrument) = False;
751
752 else if (STREQ(argv[i], "--cleanup=yes"))
753 VG_(clo_cleanup) = True;
754 else if (STREQ(argv[i], "--cleanup=no"))
755 VG_(clo_cleanup) = False;
756
njn4f9c9342002-04-29 16:03:24 +0000757 else if (STREQ(argv[i], "--cachesim=yes"))
758 VG_(clo_cachesim) = True;
759 else if (STREQ(argv[i], "--cachesim=no"))
760 VG_(clo_cachesim) = False;
761
sewardjde4a1d02002-03-22 01:27:54 +0000762 else if (STREQ(argv[i], "--smc-check=none"))
763 VG_(clo_smc_check) = VG_CLO_SMC_NONE;
764 else if (STREQ(argv[i], "--smc-check=some"))
765 VG_(clo_smc_check) = VG_CLO_SMC_SOME;
766 else if (STREQ(argv[i], "--smc-check=all"))
767 VG_(clo_smc_check) = VG_CLO_SMC_ALL;
768
769 else if (STREQ(argv[i], "--trace-syscalls=yes"))
770 VG_(clo_trace_syscalls) = True;
771 else if (STREQ(argv[i], "--trace-syscalls=no"))
772 VG_(clo_trace_syscalls) = False;
773
774 else if (STREQ(argv[i], "--trace-signals=yes"))
775 VG_(clo_trace_signals) = True;
776 else if (STREQ(argv[i], "--trace-signals=no"))
777 VG_(clo_trace_signals) = False;
778
779 else if (STREQ(argv[i], "--trace-symtab=yes"))
780 VG_(clo_trace_symtab) = True;
781 else if (STREQ(argv[i], "--trace-symtab=no"))
782 VG_(clo_trace_symtab) = False;
783
784 else if (STREQ(argv[i], "--trace-malloc=yes"))
785 VG_(clo_trace_malloc) = True;
786 else if (STREQ(argv[i], "--trace-malloc=no"))
787 VG_(clo_trace_malloc) = False;
788
sewardj8937c812002-04-12 20:12:20 +0000789 else if (STREQ(argv[i], "--trace-sched=yes"))
790 VG_(clo_trace_sched) = True;
791 else if (STREQ(argv[i], "--trace-sched=no"))
792 VG_(clo_trace_sched) = False;
793
sewardj45b4b372002-04-16 22:50:32 +0000794 else if (STREQ(argv[i], "--trace-pthread=none"))
795 VG_(clo_trace_pthread_level) = 0;
796 else if (STREQ(argv[i], "--trace-pthread=some"))
797 VG_(clo_trace_pthread_level) = 1;
798 else if (STREQ(argv[i], "--trace-pthread=all"))
799 VG_(clo_trace_pthread_level) = 2;
sewardj8937c812002-04-12 20:12:20 +0000800
sewardjde4a1d02002-03-22 01:27:54 +0000801 else if (STREQN(13, argv[i], "--stop-after="))
802 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
803
804 else if (STREQN(13, argv[i], "--dump-error="))
805 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
806
807 else if (STREQN(14, argv[i], "--num-callers=")) {
808 /* Make sure it's sane. */
809 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
810 if (VG_(clo_backtrace_size) < 2)
811 VG_(clo_backtrace_size) = 2;
812 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
813 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
814 }
815
816 else
817 bad_option(argv[i]);
818 }
819
820# undef ISSPACE
821# undef STREQ
822# undef STREQN
823
824 if (VG_(clo_verbosity < 0))
825 VG_(clo_verbosity) = 0;
826
827 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
828 VG_(message)(Vg_UserMsg, "");
829 VG_(message)(Vg_UserMsg,
830 "--gdb-attach=yes conflicts with --trace-children=yes");
831 VG_(message)(Vg_UserMsg,
832 "Please choose one or the other, but not both.");
833 bad_option("--gdb-attach=yes and --trace-children=yes");
834 }
835
sewardjde4a1d02002-03-22 01:27:54 +0000836 VG_(clo_logfile_fd) = eventually_logfile_fd;
837
njn4f9c9342002-04-29 16:03:24 +0000838 /* Don't do memory checking if simulating the cache. */
839 if (VG_(clo_cachesim)) {
840 VG_(clo_instrument) = False;
841 }
842
sewardjde4a1d02002-03-22 01:27:54 +0000843 if (VG_(clo_verbosity > 0))
844 VG_(message)(Vg_UserMsg,
845 "valgrind-%s, a memory error detector for x86 GNU/Linux.",
sewardj3b2736a2002-03-24 12:18:35 +0000846 VERSION);
847
sewardjde4a1d02002-03-22 01:27:54 +0000848 if (VG_(clo_verbosity > 0))
849 VG_(message)(Vg_UserMsg,
850 "Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.");
851 if (VG_(clo_verbosity) > 1) {
852 VG_(message)(Vg_UserMsg, "Startup, with flags:");
853 for (i = 0; i < argc; i++) {
854 VG_(message)(Vg_UserMsg, " %s", argv[i]);
855 }
856 }
857
858 if (VG_(clo_n_suppressions) == 0) {
859 config_error("No error-suppression files were specified.");
860 }
861}
862
863
864/* ---------------------------------------------------------------------
865 Copying to/from m_state_static.
866 ------------------------------------------------------------------ */
867
868UInt VG_(m_state_static) [8 /* int regs, in Intel order */
869 + 1 /* %eflags */
870 + 1 /* %eip */
871 + VG_SIZE_OF_FPUSTATE_W /* FPU state */
872 ];
873
874void VG_(copy_baseBlock_to_m_state_static) ( void )
875{
876 Int i;
877 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
878 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
879 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
880 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
881 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
882 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
883 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
884 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
885
886 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_eflags)];
887 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
888
889 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
890 VG_(m_state_static)[40/4 + i]
891 = VG_(baseBlock)[VGOFF_(m_fpustate) + i];
892}
893
894
895void VG_(copy_m_state_static_to_baseBlock) ( void )
896{
897 Int i;
898 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
899 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
900 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
901 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
902 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
903 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
904 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
905 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
906
907 VG_(baseBlock)[VGOFF_(m_eflags)] = VG_(m_state_static)[32/4];
908 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
909
910 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
911 VG_(baseBlock)[VGOFF_(m_fpustate) + i]
912 = VG_(m_state_static)[40/4 + i];
913}
914
915
916/* ---------------------------------------------------------------------
917 Show accumulated counts.
918 ------------------------------------------------------------------ */
919
920static void vg_show_counts ( void )
921{
922 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000923 " lru: %d epochs, %d clearings.",
924 VG_(current_epoch),
925 VG_(number_of_lrus) );
sewardjde4a1d02002-03-22 01:27:54 +0000926 VG_(message)(Vg_DebugMsg,
927 "translate: new %d (%d -> %d), discard %d (%d -> %d).",
928 VG_(overall_in_count),
929 VG_(overall_in_osize),
930 VG_(overall_in_tsize),
931 VG_(overall_out_count),
932 VG_(overall_out_osize),
933 VG_(overall_out_tsize) );
934 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000935 " dispatch: %lu basic blocks, %d/%d sched events, %d tt_fast misses.",
936 VG_(bbs_done), VG_(num_scheduling_events_MAJOR),
937 VG_(num_scheduling_events_MINOR),
938 VG_(tt_fast_misses));
sewardjde4a1d02002-03-22 01:27:54 +0000939 VG_(message)(Vg_DebugMsg,
940 "reg-alloc: %d t-req-spill, "
941 "%d+%d orig+spill uis, %d total-reg-r.",
942 VG_(translations_needing_spill),
943 VG_(uinstrs_prealloc),
944 VG_(uinstrs_spill),
945 VG_(total_reg_rank) );
946 VG_(message)(Vg_DebugMsg,
947 "smc-check: %d checks, %d fast pass, "
948 "%d slow pass, %d discards.",
949 VG_(smc_total_check4s),
950 VG_(smc_cache_passed),
951 VG_(smc_fancy_passed),
952 VG_(smc_discard_count) );
953 VG_(message)(Vg_DebugMsg,
954 " sanity: %d cheap, %d expensive checks.",
955 VG_(sanity_fast_count),
956 VG_(sanity_slow_count) );
957}
958
959
960/* ---------------------------------------------------------------------
961 Main!
962 ------------------------------------------------------------------ */
963
964/* Where we jump to once Valgrind has got control, and the real
965 machine's state has been copied to the m_state_static. */
966
967void VG_(main) ( void )
968{
sewardj2e93c502002-04-12 11:12:52 +0000969 Int i;
970 VgSchedReturnCode src;
sewardjde4a1d02002-03-22 01:27:54 +0000971
972 /* Set up our stack sanity-check words. */
973 for (i = 0; i < 10; i++) {
974 VG_(stack)[i] = (UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1;
975 VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321;
976 }
977
978 /* Set up baseBlock offsets and copy the saved machine's state into
979 it. */
980 vg_init_baseBlock();
981 VG_(copy_m_state_static_to_baseBlock)();
982
983 /* Process Valgrind's command-line opts (from env var VG_OPTS). */
984 process_cmd_line_options();
985
986 /* Initialise the signal handling subsystem. */
987 VG_(sigstartup_actions)();
988
989# ifdef VG_PROFILE
990 VGP_(init_profiling)();
991# endif
992
sewardj5f07b662002-04-23 16:52:51 +0000993 /* Start calibration of our RDTSC-based clock. */
994 VG_(start_rdtsc_calibration)();
995
sewardjb3c26872002-03-24 10:05:14 +0000996 /* Hook to delay things long enough so we can get the pid and
997 attach GDB in another shell. */
998 /* {extern unsigned int sleep(unsigned int seconds); sleep(10);} */
999
njn4f9c9342002-04-29 16:03:24 +00001000 if (VG_(clo_instrument) || VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +00001001 VGP_PUSHCC(VgpInitAudit);
1002 VGM_(init_memory_audit)();
1003 VGP_POPCC;
1004 VGP_PUSHCC(VgpReadSyms);
1005 VG_(read_symbols)();
1006 VGP_POPCC;
1007 }
1008
sewardj5f07b662002-04-23 16:52:51 +00001009 /* End calibration of our RDTSC-based clock, leaving it as long as
1010 we can. */
1011 VG_(end_rdtsc_calibration)();
1012
sewardjde4a1d02002-03-22 01:27:54 +00001013 /* This should come after init_memory_audit; otherwise the latter
1014 carefully sets up the permissions maps to cover the anonymous
1015 mmaps for the translation table and translation cache, which
1016 wastes > 20M of virtual address space. */
1017 VG_(init_transtab_and_SMC)();
1018
1019 if (VG_(clo_verbosity) == 1) {
1020 VG_(message)(Vg_UserMsg,
1021 "For more details, rerun with: -v");
1022 }
1023
1024 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1025 instrumented-ly. */
1026 VG_(running_on_simd_CPU) = True;
1027 if (VG_(clo_instrument)) {
1028 VGM_(make_readable) ( (Addr)&VG_(running_on_simd_CPU), 1 );
1029 VGM_(make_readable) ( (Addr)&VG_(clo_instrument), 1 );
1030 VGM_(make_readable) ( (Addr)&VG_(clo_trace_malloc), 1 );
1031 VGM_(make_readable) ( (Addr)&VG_(clo_sloppy_malloc), 1 );
1032 }
1033
njn4f9c9342002-04-29 16:03:24 +00001034 if (VG_(clo_cachesim))
1035 VG_(init_cachesim)();
1036
sewardjde4a1d02002-03-22 01:27:54 +00001037 if (VG_(clo_verbosity) > 0)
1038 VG_(message)(Vg_UserMsg, "");
1039
1040 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001041
1042 VG_(scheduler_init)();
1043 src = VG_(scheduler)();
sewardjde4a1d02002-03-22 01:27:54 +00001044
1045 if (VG_(clo_verbosity) > 0)
1046 VG_(message)(Vg_UserMsg, "");
1047
sewardj2e93c502002-04-12 11:12:52 +00001048 if (src == VgSrc_Deadlock) {
1049 VG_(message)(Vg_UserMsg,
1050 "Warning: pthread scheduler exited due to deadlock");
1051 }
1052
sewardjde4a1d02002-03-22 01:27:54 +00001053 if (VG_(clo_instrument)) {
1054 VG_(show_all_errors)();
1055 VG_(clientmalloc_done)();
1056 if (VG_(clo_verbosity) == 1) {
1057 VG_(message)(Vg_UserMsg,
1058 "For counts of detected errors, rerun with: -v");
1059 }
1060 if (VG_(clo_leak_check)) VG_(detect_memory_leaks)();
1061 }
1062 VG_(running_on_simd_CPU) = False;
sewardj2e93c502002-04-12 11:12:52 +00001063
njn4f9c9342002-04-29 16:03:24 +00001064 if (VG_(clo_cachesim))
1065 VG_(show_cachesim_results)(VG_(client_argc), VG_(client_argv));
1066
sewardj6072c362002-04-19 14:40:57 +00001067 VG_(do_sanity_checks)( 1 /* root thread */,
sewardj2e93c502002-04-12 11:12:52 +00001068 True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001069
1070 if (VG_(clo_verbosity) > 1)
1071 vg_show_counts();
1072
1073 if (0) {
1074 VG_(message)(Vg_DebugMsg, "");
1075 VG_(message)(Vg_DebugMsg,
1076 "------ Valgrind's internal memory use stats follow ------" );
1077 VG_(mallocSanityCheckAll)();
1078 VG_(show_all_arena_stats)();
1079 VG_(message)(Vg_DebugMsg,
1080 "------ Valgrind's ExeContext management stats follow ------" );
1081 VG_(show_ExeContext_stats)();
1082 VG_(message)(Vg_DebugMsg,
1083 "------ Valgrind's client block stats follow ---------------" );
1084 VG_(show_client_block_stats)();
1085 }
1086
1087# ifdef VG_PROFILE
1088 VGP_(done_profiling)();
1089# endif
1090
1091 VG_(done_prof_mem)();
1092
1093 VG_(shutdown_logging)();
1094
1095 /* In LD_PRELOAD, convert "valgrind.so" into "valgrinq.so", so that
1096 child processes don't get traced into. Also done on simulated
1097 execve system call. */
1098 if (!VG_(clo_trace_children)) {
1099 VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
1100 }
1101
1102 /* Prepare to restore state to the real CPU. */
sewardj6072c362002-04-19 14:40:57 +00001103 VG_(load_thread_state)(1 /* root thread */);
sewardjde4a1d02002-03-22 01:27:54 +00001104 VG_(copy_baseBlock_to_m_state_static)();
1105
1106 /* This pushes a return address on the simulator's stack, which
1107 is abandoned. We call vg_sigshutdown_actions() at the end
1108 of vg_switch_to_real_CPU(), so as to ensure that the original
1109 stack and machine state is restored before the real signal
1110 mechanism is restored.
1111 */
1112 VG_(switch_to_real_CPU)();
1113}
1114
1115
1116/* Debugging thing .. can be called from assembly with OYNK macro. */
1117void VG_(oynk) ( Int n )
1118{
1119 OINK(n);
1120}
1121
1122
1123/* Find "valgrind.so" in a LD_PRELOAD=... string, and convert it to
1124 "valgrinq.so", which doesn't do anything. This is used to avoid
1125 tracing into child processes. To make this work the build system
1126 also supplies a dummy file, "valgrinq.so".
1127*/
1128void VG_(mash_LD_PRELOAD_string)( Char* ld_preload_str )
1129{
1130 Char* p;
1131 if (ld_preload_str == NULL)
1132 return;
1133 p = VG_(strstr)(ld_preload_str, "valgrind.so");
1134 if (p == NULL)
1135 return;
1136 p[7] = 'q';
1137}
1138
1139/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1140 it to attach to this process. Called if the user requests this
1141 service after an error has been shown, so she can poke around and
1142 look at parameters, memory, etc. You can't meaningfully get GDB to
1143 continue the program, though; to continue, quit GDB. */
1144extern void VG_(start_GDB_whilst_on_client_stack) ( void )
1145{
sewardje6a25242002-04-21 22:03:07 +00001146 Int res;
sewardjde4a1d02002-03-22 01:27:54 +00001147 UChar buf[100];
1148 VG_(sprintf)(buf,
1149 "/usr/bin/gdb -nw /proc/%d/exe %d",
1150 VG_(getpid)(), VG_(getpid)());
sewardje6a25242002-04-21 22:03:07 +00001151 VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
1152 res = VG_(system)(buf);
1153 if (res == 0) {
1154 VG_(message)(Vg_UserMsg, "");
1155 VG_(message)(Vg_UserMsg,
1156 "GDB has detached. Valgrind regains control. We continue.");
1157 } else {
1158 VG_(message)(Vg_UserMsg, "Apparently failed!");
1159 VG_(message)(Vg_UserMsg, "");
sewardjde4a1d02002-03-22 01:27:54 +00001160 }
sewardjde4a1d02002-03-22 01:27:54 +00001161}
1162
1163
1164/* Print some helpful-ish text about unimplemented things, and give
1165 up. */
1166extern void VG_(unimplemented) ( Char* msg )
1167{
1168 VG_(message)(Vg_UserMsg, "");
1169 VG_(message)(Vg_UserMsg,
1170 "Valgrind detected that your program requires");
1171 VG_(message)(Vg_UserMsg,
1172 "the following unimplemented functionality:");
1173 VG_(message)(Vg_UserMsg, " %s", msg);
1174 VG_(message)(Vg_UserMsg,
1175 "This may be because the functionality is hard to implement,");
1176 VG_(message)(Vg_UserMsg,
1177 "or because no reasonable program would behave this way,");
1178 VG_(message)(Vg_UserMsg,
1179 "or because nobody has yet needed it. In any case, let me know");
1180 VG_(message)(Vg_UserMsg,
1181 "(jseward@acm.org) and/or try to work around the problem, if you can.");
1182 VG_(message)(Vg_UserMsg,
1183 "");
1184 VG_(message)(Vg_UserMsg,
1185 "Valgrind has to exit now. Sorry. Bye!");
1186 VG_(message)(Vg_UserMsg,
1187 "");
sewardj15a43e12002-04-17 19:35:12 +00001188 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +00001189 VG_(exit)(1);
1190}
1191
1192
sewardjde4a1d02002-03-22 01:27:54 +00001193/*--------------------------------------------------------------------*/
1194/*--- end vg_main.c ---*/
1195/*--------------------------------------------------------------------*/