blob: 3fbaca8706d017cbd1dffe772aa428803dd9058d [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
sewardj83adf412002-05-01 01:25:45 +0000843 if (VG_(clo_verbosity > 0)) {
844 if (VG_(clo_cachesim)) {
845 VG_(message)(Vg_UserMsg,
846 "cachegrind-%s, an I1/D1/L2 cache profiler for x86 GNU/Linux.",
847 VERSION);
848 } else {
849 VG_(message)(Vg_UserMsg,
850 "valgrind-%s, a memory error detector for x86 GNU/Linux.",
851 VERSION);
852 }
853 }
sewardj3b2736a2002-03-24 12:18:35 +0000854
sewardjde4a1d02002-03-22 01:27:54 +0000855 if (VG_(clo_verbosity > 0))
856 VG_(message)(Vg_UserMsg,
857 "Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.");
858 if (VG_(clo_verbosity) > 1) {
859 VG_(message)(Vg_UserMsg, "Startup, with flags:");
860 for (i = 0; i < argc; i++) {
861 VG_(message)(Vg_UserMsg, " %s", argv[i]);
862 }
863 }
864
sewardj83adf412002-05-01 01:25:45 +0000865 if (VG_(clo_n_suppressions) == 0 && !VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +0000866 config_error("No error-suppression files were specified.");
867 }
868}
869
870
871/* ---------------------------------------------------------------------
872 Copying to/from m_state_static.
873 ------------------------------------------------------------------ */
874
875UInt VG_(m_state_static) [8 /* int regs, in Intel order */
876 + 1 /* %eflags */
877 + 1 /* %eip */
878 + VG_SIZE_OF_FPUSTATE_W /* FPU state */
879 ];
880
881void VG_(copy_baseBlock_to_m_state_static) ( void )
882{
883 Int i;
884 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
885 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
886 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
887 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
888 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
889 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
890 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
891 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
892
893 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_eflags)];
894 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
895
896 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
897 VG_(m_state_static)[40/4 + i]
898 = VG_(baseBlock)[VGOFF_(m_fpustate) + i];
899}
900
901
902void VG_(copy_m_state_static_to_baseBlock) ( void )
903{
904 Int i;
905 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
906 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
907 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
908 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
909 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
910 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
911 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
912 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
913
914 VG_(baseBlock)[VGOFF_(m_eflags)] = VG_(m_state_static)[32/4];
915 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
916
917 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
918 VG_(baseBlock)[VGOFF_(m_fpustate) + i]
919 = VG_(m_state_static)[40/4 + i];
920}
921
922
923/* ---------------------------------------------------------------------
924 Show accumulated counts.
925 ------------------------------------------------------------------ */
926
927static void vg_show_counts ( void )
928{
929 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000930 " lru: %d epochs, %d clearings.",
931 VG_(current_epoch),
932 VG_(number_of_lrus) );
sewardjde4a1d02002-03-22 01:27:54 +0000933 VG_(message)(Vg_DebugMsg,
934 "translate: new %d (%d -> %d), discard %d (%d -> %d).",
935 VG_(overall_in_count),
936 VG_(overall_in_osize),
937 VG_(overall_in_tsize),
938 VG_(overall_out_count),
939 VG_(overall_out_osize),
940 VG_(overall_out_tsize) );
941 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000942 " dispatch: %lu basic blocks, %d/%d sched events, %d tt_fast misses.",
943 VG_(bbs_done), VG_(num_scheduling_events_MAJOR),
944 VG_(num_scheduling_events_MINOR),
945 VG_(tt_fast_misses));
sewardjde4a1d02002-03-22 01:27:54 +0000946 VG_(message)(Vg_DebugMsg,
947 "reg-alloc: %d t-req-spill, "
948 "%d+%d orig+spill uis, %d total-reg-r.",
949 VG_(translations_needing_spill),
950 VG_(uinstrs_prealloc),
951 VG_(uinstrs_spill),
952 VG_(total_reg_rank) );
953 VG_(message)(Vg_DebugMsg,
954 "smc-check: %d checks, %d fast pass, "
955 "%d slow pass, %d discards.",
956 VG_(smc_total_check4s),
957 VG_(smc_cache_passed),
958 VG_(smc_fancy_passed),
959 VG_(smc_discard_count) );
960 VG_(message)(Vg_DebugMsg,
961 " sanity: %d cheap, %d expensive checks.",
962 VG_(sanity_fast_count),
963 VG_(sanity_slow_count) );
964}
965
966
967/* ---------------------------------------------------------------------
968 Main!
969 ------------------------------------------------------------------ */
970
971/* Where we jump to once Valgrind has got control, and the real
972 machine's state has been copied to the m_state_static. */
973
974void VG_(main) ( void )
975{
sewardj2e93c502002-04-12 11:12:52 +0000976 Int i;
977 VgSchedReturnCode src;
sewardjde4a1d02002-03-22 01:27:54 +0000978
979 /* Set up our stack sanity-check words. */
980 for (i = 0; i < 10; i++) {
981 VG_(stack)[i] = (UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1;
982 VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321;
983 }
984
985 /* Set up baseBlock offsets and copy the saved machine's state into
986 it. */
987 vg_init_baseBlock();
988 VG_(copy_m_state_static_to_baseBlock)();
989
990 /* Process Valgrind's command-line opts (from env var VG_OPTS). */
991 process_cmd_line_options();
992
993 /* Initialise the signal handling subsystem. */
994 VG_(sigstartup_actions)();
995
996# ifdef VG_PROFILE
997 VGP_(init_profiling)();
998# endif
999
sewardj5f07b662002-04-23 16:52:51 +00001000 /* Start calibration of our RDTSC-based clock. */
1001 VG_(start_rdtsc_calibration)();
1002
sewardjb3c26872002-03-24 10:05:14 +00001003 /* Hook to delay things long enough so we can get the pid and
1004 attach GDB in another shell. */
1005 /* {extern unsigned int sleep(unsigned int seconds); sleep(10);} */
1006
njn4f9c9342002-04-29 16:03:24 +00001007 if (VG_(clo_instrument) || VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +00001008 VGP_PUSHCC(VgpInitAudit);
1009 VGM_(init_memory_audit)();
1010 VGP_POPCC;
1011 VGP_PUSHCC(VgpReadSyms);
1012 VG_(read_symbols)();
1013 VGP_POPCC;
1014 }
1015
sewardj5f07b662002-04-23 16:52:51 +00001016 /* End calibration of our RDTSC-based clock, leaving it as long as
1017 we can. */
1018 VG_(end_rdtsc_calibration)();
1019
sewardjde4a1d02002-03-22 01:27:54 +00001020 /* This should come after init_memory_audit; otherwise the latter
1021 carefully sets up the permissions maps to cover the anonymous
1022 mmaps for the translation table and translation cache, which
1023 wastes > 20M of virtual address space. */
1024 VG_(init_transtab_and_SMC)();
1025
1026 if (VG_(clo_verbosity) == 1) {
1027 VG_(message)(Vg_UserMsg,
1028 "For more details, rerun with: -v");
1029 }
1030
1031 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1032 instrumented-ly. */
1033 VG_(running_on_simd_CPU) = True;
1034 if (VG_(clo_instrument)) {
1035 VGM_(make_readable) ( (Addr)&VG_(running_on_simd_CPU), 1 );
1036 VGM_(make_readable) ( (Addr)&VG_(clo_instrument), 1 );
1037 VGM_(make_readable) ( (Addr)&VG_(clo_trace_malloc), 1 );
1038 VGM_(make_readable) ( (Addr)&VG_(clo_sloppy_malloc), 1 );
1039 }
1040
njn4f9c9342002-04-29 16:03:24 +00001041 if (VG_(clo_cachesim))
1042 VG_(init_cachesim)();
1043
sewardjde4a1d02002-03-22 01:27:54 +00001044 if (VG_(clo_verbosity) > 0)
1045 VG_(message)(Vg_UserMsg, "");
1046
1047 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001048
1049 VG_(scheduler_init)();
1050 src = VG_(scheduler)();
sewardjde4a1d02002-03-22 01:27:54 +00001051
1052 if (VG_(clo_verbosity) > 0)
1053 VG_(message)(Vg_UserMsg, "");
1054
sewardj2e93c502002-04-12 11:12:52 +00001055 if (src == VgSrc_Deadlock) {
1056 VG_(message)(Vg_UserMsg,
1057 "Warning: pthread scheduler exited due to deadlock");
1058 }
1059
sewardjde4a1d02002-03-22 01:27:54 +00001060 if (VG_(clo_instrument)) {
1061 VG_(show_all_errors)();
1062 VG_(clientmalloc_done)();
1063 if (VG_(clo_verbosity) == 1) {
1064 VG_(message)(Vg_UserMsg,
1065 "For counts of detected errors, rerun with: -v");
1066 }
1067 if (VG_(clo_leak_check)) VG_(detect_memory_leaks)();
1068 }
1069 VG_(running_on_simd_CPU) = False;
sewardj2e93c502002-04-12 11:12:52 +00001070
njn4f9c9342002-04-29 16:03:24 +00001071 if (VG_(clo_cachesim))
1072 VG_(show_cachesim_results)(VG_(client_argc), VG_(client_argv));
1073
sewardj6072c362002-04-19 14:40:57 +00001074 VG_(do_sanity_checks)( 1 /* root thread */,
sewardj2e93c502002-04-12 11:12:52 +00001075 True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001076
1077 if (VG_(clo_verbosity) > 1)
1078 vg_show_counts();
1079
1080 if (0) {
1081 VG_(message)(Vg_DebugMsg, "");
1082 VG_(message)(Vg_DebugMsg,
1083 "------ Valgrind's internal memory use stats follow ------" );
1084 VG_(mallocSanityCheckAll)();
1085 VG_(show_all_arena_stats)();
1086 VG_(message)(Vg_DebugMsg,
1087 "------ Valgrind's ExeContext management stats follow ------" );
1088 VG_(show_ExeContext_stats)();
1089 VG_(message)(Vg_DebugMsg,
1090 "------ Valgrind's client block stats follow ---------------" );
1091 VG_(show_client_block_stats)();
1092 }
1093
1094# ifdef VG_PROFILE
1095 VGP_(done_profiling)();
1096# endif
1097
1098 VG_(done_prof_mem)();
1099
1100 VG_(shutdown_logging)();
1101
1102 /* In LD_PRELOAD, convert "valgrind.so" into "valgrinq.so", so that
1103 child processes don't get traced into. Also done on simulated
1104 execve system call. */
1105 if (!VG_(clo_trace_children)) {
1106 VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
1107 }
1108
1109 /* Prepare to restore state to the real CPU. */
sewardj6072c362002-04-19 14:40:57 +00001110 VG_(load_thread_state)(1 /* root thread */);
sewardjde4a1d02002-03-22 01:27:54 +00001111 VG_(copy_baseBlock_to_m_state_static)();
1112
1113 /* This pushes a return address on the simulator's stack, which
1114 is abandoned. We call vg_sigshutdown_actions() at the end
1115 of vg_switch_to_real_CPU(), so as to ensure that the original
1116 stack and machine state is restored before the real signal
1117 mechanism is restored.
1118 */
1119 VG_(switch_to_real_CPU)();
1120}
1121
1122
1123/* Debugging thing .. can be called from assembly with OYNK macro. */
1124void VG_(oynk) ( Int n )
1125{
1126 OINK(n);
1127}
1128
1129
1130/* Find "valgrind.so" in a LD_PRELOAD=... string, and convert it to
1131 "valgrinq.so", which doesn't do anything. This is used to avoid
1132 tracing into child processes. To make this work the build system
1133 also supplies a dummy file, "valgrinq.so".
1134*/
1135void VG_(mash_LD_PRELOAD_string)( Char* ld_preload_str )
1136{
1137 Char* p;
1138 if (ld_preload_str == NULL)
1139 return;
1140 p = VG_(strstr)(ld_preload_str, "valgrind.so");
1141 if (p == NULL)
1142 return;
1143 p[7] = 'q';
1144}
1145
1146/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1147 it to attach to this process. Called if the user requests this
1148 service after an error has been shown, so she can poke around and
1149 look at parameters, memory, etc. You can't meaningfully get GDB to
1150 continue the program, though; to continue, quit GDB. */
1151extern void VG_(start_GDB_whilst_on_client_stack) ( void )
1152{
sewardje6a25242002-04-21 22:03:07 +00001153 Int res;
sewardjde4a1d02002-03-22 01:27:54 +00001154 UChar buf[100];
1155 VG_(sprintf)(buf,
1156 "/usr/bin/gdb -nw /proc/%d/exe %d",
1157 VG_(getpid)(), VG_(getpid)());
sewardje6a25242002-04-21 22:03:07 +00001158 VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
1159 res = VG_(system)(buf);
1160 if (res == 0) {
1161 VG_(message)(Vg_UserMsg, "");
1162 VG_(message)(Vg_UserMsg,
1163 "GDB has detached. Valgrind regains control. We continue.");
1164 } else {
1165 VG_(message)(Vg_UserMsg, "Apparently failed!");
1166 VG_(message)(Vg_UserMsg, "");
sewardjde4a1d02002-03-22 01:27:54 +00001167 }
sewardjde4a1d02002-03-22 01:27:54 +00001168}
1169
1170
1171/* Print some helpful-ish text about unimplemented things, and give
1172 up. */
1173extern void VG_(unimplemented) ( Char* msg )
1174{
1175 VG_(message)(Vg_UserMsg, "");
1176 VG_(message)(Vg_UserMsg,
1177 "Valgrind detected that your program requires");
1178 VG_(message)(Vg_UserMsg,
1179 "the following unimplemented functionality:");
1180 VG_(message)(Vg_UserMsg, " %s", msg);
1181 VG_(message)(Vg_UserMsg,
1182 "This may be because the functionality is hard to implement,");
1183 VG_(message)(Vg_UserMsg,
1184 "or because no reasonable program would behave this way,");
1185 VG_(message)(Vg_UserMsg,
1186 "or because nobody has yet needed it. In any case, let me know");
1187 VG_(message)(Vg_UserMsg,
1188 "(jseward@acm.org) and/or try to work around the problem, if you can.");
1189 VG_(message)(Vg_UserMsg,
1190 "");
1191 VG_(message)(Vg_UserMsg,
1192 "Valgrind has to exit now. Sorry. Bye!");
1193 VG_(message)(Vg_UserMsg,
1194 "");
sewardj15a43e12002-04-17 19:35:12 +00001195 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +00001196 VG_(exit)(1);
1197}
1198
1199
sewardjde4a1d02002-03-22 01:27:54 +00001200/*--------------------------------------------------------------------*/
1201/*--- end vg_main.c ---*/
1202/*--------------------------------------------------------------------*/