blob: 8784499d5d34b2f64101ed50ce74f1675d7919c6 [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;
sewardj7d78e782002-06-02 00:04:00 +000080Int VGOFF_(helper_CLC) = INVALID_OFFSET;
81Int VGOFF_(helper_STC) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000082Int VGOFF_(helper_shldl) = INVALID_OFFSET;
83Int VGOFF_(helper_shldw) = INVALID_OFFSET;
84Int VGOFF_(helper_shrdl) = INVALID_OFFSET;
85Int VGOFF_(helper_shrdw) = INVALID_OFFSET;
86Int VGOFF_(helper_RDTSC) = INVALID_OFFSET;
87Int VGOFF_(helper_CPUID) = INVALID_OFFSET;
88Int VGOFF_(helper_BSWAP) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000089Int VGOFF_(helper_bsf) = INVALID_OFFSET;
90Int VGOFF_(helper_bsr) = INVALID_OFFSET;
91Int VGOFF_(helper_fstsw_AX) = INVALID_OFFSET;
92Int VGOFF_(helper_SAHF) = INVALID_OFFSET;
sewardj4d0ab1f2002-03-24 10:00:09 +000093Int VGOFF_(helper_DAS) = INVALID_OFFSET;
sewardjfe8a1662002-03-24 11:54:07 +000094Int VGOFF_(helper_DAA) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000095Int VGOFF_(helper_value_check4_fail) = INVALID_OFFSET;
96Int VGOFF_(helper_value_check2_fail) = INVALID_OFFSET;
97Int VGOFF_(helper_value_check1_fail) = INVALID_OFFSET;
98Int VGOFF_(helper_value_check0_fail) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000099Int VGOFF_(helperc_LOADV4) = INVALID_OFFSET;
100Int VGOFF_(helperc_LOADV2) = INVALID_OFFSET;
101Int VGOFF_(helperc_LOADV1) = INVALID_OFFSET;
102Int VGOFF_(helperc_STOREV4) = INVALID_OFFSET;
103Int VGOFF_(helperc_STOREV2) = INVALID_OFFSET;
104Int VGOFF_(helperc_STOREV1) = INVALID_OFFSET;
105Int VGOFF_(handle_esp_assignment) = INVALID_OFFSET;
106Int VGOFF_(fpu_write_check) = INVALID_OFFSET;
107Int VGOFF_(fpu_read_check) = INVALID_OFFSET;
njn4f9c9342002-04-29 16:03:24 +0000108Int VGOFF_(cachesim_log_non_mem_instr) = INVALID_OFFSET;
109Int VGOFF_(cachesim_log_mem_instr) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +0000110
111/* This is the actual defn of baseblock. */
112UInt VG_(baseBlock)[VG_BASEBLOCK_WORDS];
113
114/* Words. */
115static Int baB_off = 0;
116
117/* Returns the offset, in words. */
118static Int alloc_BaB ( Int words )
119{
120 Int off = baB_off;
121 baB_off += words;
122 if (baB_off >= VG_BASEBLOCK_WORDS)
123 VG_(panic)( "alloc_BaB: baseBlock is too small");
124
125 return off;
126}
127
128/* Allocate 1 word in baseBlock and set it to the given value. */
129static Int alloc_BaB_1_set ( Addr a )
130{
131 Int off = alloc_BaB(1);
132 VG_(baseBlock)[off] = (UInt)a;
133 return off;
134}
135
136
137/* Here we assign actual offsets. It's important to get the most
138 popular referents within 128 bytes of the start, so we can take
139 advantage of short addressing modes relative to %ebp. Popularity
140 of offsets was measured on 22 Feb 02 running a KDE application, and
141 the slots rearranged accordingly, with a 1.5% reduction in total
142 size of translations. */
143
144static void vg_init_baseBlock ( void )
145{
146 baB_off = 0;
147
148 /* Those with offsets under 128 are carefully chosen. */
149
150 /* WORD offsets in this column */
151 /* 0 */ VGOFF_(m_eax) = alloc_BaB(1);
152 /* 1 */ VGOFF_(m_ecx) = alloc_BaB(1);
153 /* 2 */ VGOFF_(m_edx) = alloc_BaB(1);
154 /* 3 */ VGOFF_(m_ebx) = alloc_BaB(1);
155 /* 4 */ VGOFF_(m_esp) = alloc_BaB(1);
156 /* 5 */ VGOFF_(m_ebp) = alloc_BaB(1);
157 /* 6 */ VGOFF_(m_esi) = alloc_BaB(1);
158 /* 7 */ VGOFF_(m_edi) = alloc_BaB(1);
159 /* 8 */ VGOFF_(m_eflags) = alloc_BaB(1);
160
161 /* 9 */ VGOFF_(sh_eax) = alloc_BaB(1);
162 /* 10 */ VGOFF_(sh_ecx) = alloc_BaB(1);
163 /* 11 */ VGOFF_(sh_edx) = alloc_BaB(1);
164 /* 12 */ VGOFF_(sh_ebx) = alloc_BaB(1);
165 /* 13 */ VGOFF_(sh_esp) = alloc_BaB(1);
166 /* 14 */ VGOFF_(sh_ebp) = alloc_BaB(1);
167 /* 15 */ VGOFF_(sh_esi) = alloc_BaB(1);
168 /* 16 */ VGOFF_(sh_edi) = alloc_BaB(1);
169 /* 17 */ VGOFF_(sh_eflags) = alloc_BaB(1);
170
njn4f9c9342002-04-29 16:03:24 +0000171 /* 17a */
172 VGOFF_(cachesim_log_non_mem_instr)
173 = alloc_BaB_1_set( (Addr) & VG_(cachesim_log_non_mem_instr) );
174 /* 17b */
175 VGOFF_(cachesim_log_mem_instr)
176 = alloc_BaB_1_set( (Addr) & VG_(cachesim_log_mem_instr) );
177
sewardjde4a1d02002-03-22 01:27:54 +0000178 /* 18 */
179 VGOFF_(helper_value_check4_fail)
180 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check4_fail) );
181 /* 19 */
182 VGOFF_(helper_value_check0_fail)
183 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check0_fail) );
184
185 /* 20 */
186 VGOFF_(helperc_STOREV4)
187 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV4) );
188 /* 21 */
189 VGOFF_(helperc_STOREV1)
190 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV1) );
191
192 /* 22 */
193 VGOFF_(helperc_LOADV4)
194 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV4) );
195 /* 23 */
196 VGOFF_(helperc_LOADV1)
197 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV1) );
198
199 /* 24 */
200 VGOFF_(handle_esp_assignment)
201 = alloc_BaB_1_set( (Addr) & VGM_(handle_esp_assignment) );
202
203 /* 25 */
204 VGOFF_(m_eip) = alloc_BaB(1);
205
206 /* There are currently 24 spill slots */
207 /* 26 .. 49 This overlaps the magic boundary at >= 32 words, but
208 most spills are to low numbered spill slots, so the ones above
209 the boundary don't see much action. */
210 VGOFF_(spillslots) = alloc_BaB(VG_MAX_SPILLSLOTS);
211
212 /* These two pushed beyond the boundary because 2-byte transactions
213 are rare. */
214 /* 50 */
215 VGOFF_(helperc_STOREV2)
216 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV2) );
217 /* 51 */
218 VGOFF_(helperc_LOADV2)
219 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV2) );
220
221 /* 52 */
222 VGOFF_(fpu_write_check)
223 = alloc_BaB_1_set( (Addr) & VGM_(fpu_write_check) );
224 /* 53 */
225 VGOFF_(fpu_read_check)
226 = alloc_BaB_1_set( (Addr) & VGM_(fpu_read_check) );
227
228 /* Actually I don't think these two are ever used. */
229 /* 54 */
230 VGOFF_(helper_value_check2_fail)
231 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check2_fail) );
232 /* 55 */
233 VGOFF_(helper_value_check1_fail)
234 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check1_fail) );
235
236 /* I gave up counting at this point. Since they're way above the
237 short-amode-boundary, there's no point. */
238
239 VGOFF_(m_fpustate) = alloc_BaB(VG_SIZE_OF_FPUSTATE_W);
240
241 VGOFF_(helper_idiv_64_32)
242 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_64_32) );
243 VGOFF_(helper_div_64_32)
244 = alloc_BaB_1_set( (Addr) & VG_(helper_div_64_32) );
245 VGOFF_(helper_idiv_32_16)
246 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_32_16) );
247 VGOFF_(helper_div_32_16)
248 = alloc_BaB_1_set( (Addr) & VG_(helper_div_32_16) );
249 VGOFF_(helper_idiv_16_8)
250 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_16_8) );
251 VGOFF_(helper_div_16_8)
252 = alloc_BaB_1_set( (Addr) & VG_(helper_div_16_8) );
253
254 VGOFF_(helper_imul_32_64)
255 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_32_64) );
256 VGOFF_(helper_mul_32_64)
257 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_32_64) );
258 VGOFF_(helper_imul_16_32)
259 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_16_32) );
260 VGOFF_(helper_mul_16_32)
261 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_16_32) );
262 VGOFF_(helper_imul_8_16)
263 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_8_16) );
264 VGOFF_(helper_mul_8_16)
265 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_8_16) );
266
267 VGOFF_(helper_CLD)
268 = alloc_BaB_1_set( (Addr) & VG_(helper_CLD) );
269 VGOFF_(helper_STD)
270 = alloc_BaB_1_set( (Addr) & VG_(helper_STD) );
271 VGOFF_(helper_get_dirflag)
272 = alloc_BaB_1_set( (Addr) & VG_(helper_get_dirflag) );
273
sewardj7d78e782002-06-02 00:04:00 +0000274 VGOFF_(helper_CLC)
275 = alloc_BaB_1_set( (Addr) & VG_(helper_CLC) );
276 VGOFF_(helper_STC)
277 = alloc_BaB_1_set( (Addr) & VG_(helper_STC) );
278
sewardjde4a1d02002-03-22 01:27:54 +0000279 VGOFF_(helper_shldl)
280 = alloc_BaB_1_set( (Addr) & VG_(helper_shldl) );
281 VGOFF_(helper_shldw)
282 = alloc_BaB_1_set( (Addr) & VG_(helper_shldw) );
283 VGOFF_(helper_shrdl)
284 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdl) );
285 VGOFF_(helper_shrdw)
286 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdw) );
287
288 VGOFF_(helper_RDTSC)
289 = alloc_BaB_1_set( (Addr) & VG_(helper_RDTSC) );
290 VGOFF_(helper_CPUID)
291 = alloc_BaB_1_set( (Addr) & VG_(helper_CPUID) );
292
sewardjde4a1d02002-03-22 01:27:54 +0000293 VGOFF_(helper_bsf)
294 = alloc_BaB_1_set( (Addr) & VG_(helper_bsf) );
295 VGOFF_(helper_bsr)
296 = alloc_BaB_1_set( (Addr) & VG_(helper_bsr) );
297
298 VGOFF_(helper_fstsw_AX)
299 = alloc_BaB_1_set( (Addr) & VG_(helper_fstsw_AX) );
300 VGOFF_(helper_SAHF)
301 = alloc_BaB_1_set( (Addr) & VG_(helper_SAHF) );
sewardj4d0ab1f2002-03-24 10:00:09 +0000302 VGOFF_(helper_DAS)
303 = alloc_BaB_1_set( (Addr) & VG_(helper_DAS) );
sewardjfe8a1662002-03-24 11:54:07 +0000304 VGOFF_(helper_DAA)
305 = alloc_BaB_1_set( (Addr) & VG_(helper_DAA) );
sewardjde4a1d02002-03-22 01:27:54 +0000306}
307
308
309/* ---------------------------------------------------------------------
310 Global entities which are not referenced from generated code.
311 ------------------------------------------------------------------ */
312
313/* The stack on which Valgrind runs. We can't use the same stack as
314 the simulatee -- that's an important design decision. */
315UInt VG_(stack)[10000];
316
317/* Ditto our signal delivery stack. */
318UInt VG_(sigstack)[10000];
319
320/* Saving stuff across system calls. */
sewardj43c356f2002-06-02 00:21:08 +0000321UInt VG_(real_fpu_state_saved_over_syscall)[VG_SIZE_OF_FPUSTATE_W];
322Addr VG_(esp_saved_over_syscall);
sewardjde4a1d02002-03-22 01:27:54 +0000323
324/* Counts downwards in vg_run_innerloop. */
325UInt VG_(dispatch_ctr);
326
sewardjde4a1d02002-03-22 01:27:54 +0000327
328/* 64-bit counter for the number of basic blocks done. */
329ULong VG_(bbs_done);
330/* 64-bit counter for the number of bbs to go before a debug exit. */
331ULong VG_(bbs_to_go);
332
333/* Produce debugging output? */
334Bool VG_(disassemble) = False;
335
336/* The current LRU epoch. */
337UInt VG_(current_epoch) = 0;
338
sewardj7e87e382002-05-03 19:09:05 +0000339/* This is the ThreadId of the last thread the scheduler ran. */
340ThreadId VG_(last_run_tid) = 0;
341
sewardjde4a1d02002-03-22 01:27:54 +0000342
343/* ---------------------------------------------------------------------
344 Counters, for informational purposes only.
345 ------------------------------------------------------------------ */
346
347/* Number of lookups which miss the fast tt helper. */
348UInt VG_(tt_fast_misses) = 0;
349
350
351/* Counts for LRU informational messages. */
352
353/* Number and total o/t size of new translations this epoch. */
354UInt VG_(this_epoch_in_count) = 0;
355UInt VG_(this_epoch_in_osize) = 0;
356UInt VG_(this_epoch_in_tsize) = 0;
357/* Number and total o/t size of discarded translations this epoch. */
358UInt VG_(this_epoch_out_count) = 0;
359UInt VG_(this_epoch_out_osize) = 0;
360UInt VG_(this_epoch_out_tsize) = 0;
361/* Number and total o/t size of translations overall. */
362UInt VG_(overall_in_count) = 0;
363UInt VG_(overall_in_osize) = 0;
364UInt VG_(overall_in_tsize) = 0;
365/* Number and total o/t size of discards overall. */
366UInt VG_(overall_out_count) = 0;
367UInt VG_(overall_out_osize) = 0;
368UInt VG_(overall_out_tsize) = 0;
369
370/* The number of LRU-clearings of TT/TC. */
371UInt VG_(number_of_lrus) = 0;
372
373
374/* Counts pertaining to the register allocator. */
375
376/* total number of uinstrs input to reg-alloc */
377UInt VG_(uinstrs_prealloc) = 0;
378
379/* total number of uinstrs added due to spill code */
380UInt VG_(uinstrs_spill) = 0;
381
382/* number of bbs requiring spill code */
383UInt VG_(translations_needing_spill) = 0;
384
385/* total of register ranks over all translations */
386UInt VG_(total_reg_rank) = 0;
387
388
sewardjde4a1d02002-03-22 01:27:54 +0000389/* Counts pertaining to internal sanity checking. */
sewardjde4a1d02002-03-22 01:27:54 +0000390UInt VG_(sanity_fast_count) = 0;
391UInt VG_(sanity_slow_count) = 0;
392
sewardj2e93c502002-04-12 11:12:52 +0000393/* Counts pertaining to the scheduler. */
394UInt VG_(num_scheduling_events_MINOR) = 0;
395UInt VG_(num_scheduling_events_MAJOR) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000396
397
398/* ---------------------------------------------------------------------
399 Values derived from command-line options.
400 ------------------------------------------------------------------ */
401
sewardj97ced732002-03-25 00:07:36 +0000402Bool VG_(clo_check_addrVs);
sewardjde4a1d02002-03-22 01:27:54 +0000403Bool VG_(clo_GDB_attach);
404Int VG_(sanity_level);
405Int VG_(clo_verbosity);
406Bool VG_(clo_demangle);
407Bool VG_(clo_leak_check);
408Bool VG_(clo_show_reachable);
409Int VG_(clo_leak_resolution);
410Bool VG_(clo_sloppy_malloc);
411Bool VG_(clo_partial_loads_ok);
412Bool VG_(clo_trace_children);
413Int VG_(clo_logfile_fd);
414Int VG_(clo_freelist_vol);
415Bool VG_(clo_workaround_gcc296_bugs);
416Int VG_(clo_n_suppressions);
417Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
418Bool VG_(clo_single_step);
419Bool VG_(clo_optimise);
420Bool VG_(clo_instrument);
421Bool VG_(clo_cleanup);
njn4f9c9342002-04-29 16:03:24 +0000422Bool VG_(clo_cachesim);
sewardjde4a1d02002-03-22 01:27:54 +0000423Int VG_(clo_smc_check);
424Bool VG_(clo_trace_syscalls);
425Bool VG_(clo_trace_signals);
426Bool VG_(clo_trace_symtab);
427Bool VG_(clo_trace_malloc);
sewardj8937c812002-04-12 20:12:20 +0000428Bool VG_(clo_trace_sched);
sewardj45b4b372002-04-16 22:50:32 +0000429Int VG_(clo_trace_pthread_level);
sewardjde4a1d02002-03-22 01:27:54 +0000430ULong VG_(clo_stop_after);
431Int VG_(clo_dump_error);
432Int VG_(clo_backtrace_size);
sewardj8d365b52002-05-12 10:52:16 +0000433Char* VG_(clo_weird_hacks);
sewardjde4a1d02002-03-22 01:27:54 +0000434
435/* This Bool is needed by wrappers in vg_clientmalloc.c to decide how
436 to behave. Initially we say False. */
437Bool VG_(running_on_simd_CPU) = False;
438
439/* Holds client's %esp at the point we gained control. */
440Addr VG_(esp_at_startup);
441
442/* As deduced from VG_(esp_at_startup), the client's argc, argv[] and
443 envp[] as extracted from the client's stack at startup-time. */
444Int VG_(client_argc);
445Char** VG_(client_argv);
446Char** VG_(client_envp);
447
448/* A place into which to copy the value of env var VG_ARGS, so we
449 don't have to modify the original. */
450static Char vg_cmdline_copy[M_VG_CMDLINE_STRLEN];
451
452
453/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000454 Processing of command-line options.
455 ------------------------------------------------------------------ */
456
457static void bad_option ( Char* opt )
458{
459 VG_(shutdown_logging)();
460 VG_(clo_logfile_fd) = 2; /* stderr */
461 VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
462 VG_(exit)(1);
463}
464
465static void config_error ( Char* msg )
466{
467 VG_(shutdown_logging)();
468 VG_(clo_logfile_fd) = 2; /* stderr */
sewardj19d81412002-06-03 01:10:40 +0000469 VG_(printf)(
470 "valgrind.so: Startup or configuration error:\n %s\n", msg);
471 VG_(printf)(
472 "valgrind.so: Unable to start up properly. Giving up.\n");
sewardjde4a1d02002-03-22 01:27:54 +0000473 VG_(exit)(1);
474}
475
sewardja1679dd2002-05-10 22:31:40 +0000476static void args_grok_error ( Char* msg )
477{
478 VG_(shutdown_logging)();
479 VG_(clo_logfile_fd) = 2; /* stderr */
480 VG_(printf)("valgrind.so: When searching for "
481 "client's argc/argc/envp:\n\t%s\n", msg);
482 config_error("couldn't find client's argc/argc/envp");
483}
484
sewardjde4a1d02002-03-22 01:27:54 +0000485
486static void process_cmd_line_options ( void )
487{
488 UChar* argv[M_VG_CMDLINE_OPTS];
489 UInt argc;
490 UChar* p;
491 UChar* str;
sewardja1679dd2002-05-10 22:31:40 +0000492 Int i, eventually_logfile_fd, ctr;
sewardjde4a1d02002-03-22 01:27:54 +0000493
494# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
495# define STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2)))
496# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
497
498 /* Set defaults. */
sewardj97ced732002-03-25 00:07:36 +0000499 VG_(clo_check_addrVs) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000500 VG_(clo_GDB_attach) = False;
501 VG_(sanity_level) = 1;
502 VG_(clo_verbosity) = 1;
503 VG_(clo_demangle) = True;
504 VG_(clo_leak_check) = False;
505 VG_(clo_show_reachable) = False;
506 VG_(clo_leak_resolution) = 2;
507 VG_(clo_sloppy_malloc) = False;
508 VG_(clo_partial_loads_ok) = True;
509 VG_(clo_trace_children) = False;
510 VG_(clo_logfile_fd) = 2; /* stderr */
511 VG_(clo_freelist_vol) = 1000000;
512 VG_(clo_workaround_gcc296_bugs) = False;
513 VG_(clo_n_suppressions) = 0;
514 VG_(clo_single_step) = False;
515 VG_(clo_optimise) = True;
516 VG_(clo_instrument) = True;
517 VG_(clo_cleanup) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000518 VG_(clo_smc_check) = /* VG_CLO_SMC_SOME */ VG_CLO_SMC_NONE;
519 VG_(clo_trace_syscalls) = False;
520 VG_(clo_trace_signals) = False;
521 VG_(clo_trace_symtab) = False;
522 VG_(clo_trace_malloc) = False;
sewardj8937c812002-04-12 20:12:20 +0000523 VG_(clo_trace_sched) = False;
sewardj45b4b372002-04-16 22:50:32 +0000524 VG_(clo_trace_pthread_level) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000525 VG_(clo_stop_after) = 1000000000000LL;
526 VG_(clo_dump_error) = 0;
527 VG_(clo_backtrace_size) = 4;
sewardj8d365b52002-05-12 10:52:16 +0000528 VG_(clo_weird_hacks) = NULL;
sewardjde4a1d02002-03-22 01:27:54 +0000529
530 eventually_logfile_fd = VG_(clo_logfile_fd);
531
532 /* Once logging is started, we can safely send messages pertaining
533 to failures in initialisation. */
534 VG_(startup_logging)();
535
sewardj19d81412002-06-03 01:10:40 +0000536 /* Check for sane path in ./configure --prefix=... */
537 if (VG_(strlen)(VG_LIBDIR) < 1
538 || VG_LIBDIR[0] != '/')
539 config_error("Please use absolute paths in "
540 "./configure --prefix=... or --libdir=...");
sewardj38170912002-05-10 21:07:22 +0000541
sewardja1679dd2002-05-10 22:31:40 +0000542 /* (Suggested by Fabrice Bellard ... )
543 We look for the Linux ELF table and go down until we find the
sewardj38170912002-05-10 21:07:22 +0000544 envc & envp. It is not full proof, but these structures should
545 change less often than the libc ones. */
546 {
sewardja1679dd2002-05-10 22:31:40 +0000547 UInt* sp = 0; /* bogus init to keep gcc -O happy */
548
sewardj38170912002-05-10 21:07:22 +0000549 /* locate the top of the stack */
sewardja1679dd2002-05-10 22:31:40 +0000550 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
551 VG_STARTUP_STACK_BASE_1 )) {
552 sp = (UInt*)VG_STARTUP_STACK_BASE_1;
553 } else
554 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
555 VG_STARTUP_STACK_BASE_2 )) {
556 sp = (UInt*)VG_STARTUP_STACK_BASE_2;
557 } else {
558 args_grok_error(
559 "startup %esp is not near any VG_STARTUP_STACK_BASE_*\n "
560 "constants defined in vg_include.h. You should investigate."
561 );
562 }
563
sewardj38170912002-05-10 21:07:22 +0000564 /* we locate: NEW_AUX_ENT(1, AT_PAGESZ, ELF_EXEC_PAGESIZE) in
565 the elf interpreter table */
566 sp -= 2;
sewardj38170912002-05-10 21:07:22 +0000567 while (sp[0] != VKI_AT_PAGESZ || sp[1] != 4096) {
sewardja1679dd2002-05-10 22:31:40 +0000568 /* VG_(printf)("trying %p\n", sp); */
sewardj38170912002-05-10 21:07:22 +0000569 sp--;
570 }
sewardj38170912002-05-10 21:07:22 +0000571
572 if (sp[2] == VKI_AT_BASE
573 && sp[0] == VKI_AT_PAGESZ
574 && sp[-2] == VKI_AT_PHNUM
575 && sp[-4] == VKI_AT_PHENT
sewardjd9c2d6d2002-05-18 11:55:05 +0000576 && sp[-6] == VKI_AT_PHDR
577 && sp[-6-1] == 0) {
sewardja1679dd2002-05-10 22:31:40 +0000578 if (0)
579 VG_(printf)("Looks like you've got a 2.2.X kernel here.\n");
sewardj38170912002-05-10 21:07:22 +0000580 sp -= 6;
sewardja1679dd2002-05-10 22:31:40 +0000581 } else
582 if (sp[2] == VKI_AT_CLKTCK
583 && sp[0] == VKI_AT_PAGESZ
sewardjd9c2d6d2002-05-18 11:55:05 +0000584 && sp[-2] == VKI_AT_HWCAP
585 && sp[-2-1] == 0) {
sewardja1679dd2002-05-10 22:31:40 +0000586 if (0)
587 VG_(printf)("Looks like you've got a 2.4.X kernel here.\n");
588 sp -= 2;
589 } else
sewardjd9c2d6d2002-05-18 11:55:05 +0000590 if (sp[2] == VKI_AT_CLKTCK
591 && sp[0] == VKI_AT_PAGESZ
592 && sp[-2] == VKI_AT_HWCAP
593 && sp[-2-20-1] == 0) {
594 if (0)
595 VG_(printf)("Looks like you've got a early 2.4.X kernel here.\n");
596 sp -= 22;
597 } else
sewardja1679dd2002-05-10 22:31:40 +0000598 args_grok_error(
599 "ELF frame does not look like 2.2.X or 2.4.X.\n "
600 "See kernel sources linux/fs/binfmt_elf.c to make sense of this."
601 );
sewardj38170912002-05-10 21:07:22 +0000602
603 sp--;
sewardja1679dd2002-05-10 22:31:40 +0000604 if (*sp != 0)
605 args_grok_error("can't find NULL at end of env[]");
606
sewardj38170912002-05-10 21:07:22 +0000607 /* sp now points to NULL at the end of env[] */
sewardja1679dd2002-05-10 22:31:40 +0000608 ctr = 0;
sewardj38170912002-05-10 21:07:22 +0000609 while (True) {
610 sp --;
611 if (*sp == 0) break;
sewardja1679dd2002-05-10 22:31:40 +0000612 if (++ctr >= 1000)
613 args_grok_error(
614 "suspiciously many (1000) env[] entries; giving up");
615
sewardj38170912002-05-10 21:07:22 +0000616 }
617 /* sp now points to NULL at the end of argv[] */
sewardja1679dd2002-05-10 22:31:40 +0000618 VG_(client_envp) = (Char**)(sp+1);
sewardj38170912002-05-10 21:07:22 +0000619
sewardja1679dd2002-05-10 22:31:40 +0000620 ctr = 0;
sewardj38170912002-05-10 21:07:22 +0000621 VG_(client_argc) = 0;
622 while (True) {
623 sp--;
624 if (*sp == VG_(client_argc))
625 break;
626 VG_(client_argc)++;
sewardja1679dd2002-05-10 22:31:40 +0000627 if (++ctr >= 1000)
628 args_grok_error(
629 "suspiciously many (1000) argv[] entries; giving up");
sewardj38170912002-05-10 21:07:22 +0000630 }
631
sewardja1679dd2002-05-10 22:31:40 +0000632 VG_(client_argv) = (Char**)(sp+1);
sewardj38170912002-05-10 21:07:22 +0000633 }
634
sewardjde4a1d02002-03-22 01:27:54 +0000635 /* 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
njn4f9c9342002-04-29 16:03:24 +0000764 else if (STREQ(argv[i], "--cachesim=yes"))
765 VG_(clo_cachesim) = True;
766 else if (STREQ(argv[i], "--cachesim=no"))
767 VG_(clo_cachesim) = False;
768
sewardjde4a1d02002-03-22 01:27:54 +0000769 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
sewardj45b4b372002-04-16 22:50:32 +0000801 else if (STREQ(argv[i], "--trace-pthread=none"))
802 VG_(clo_trace_pthread_level) = 0;
803 else if (STREQ(argv[i], "--trace-pthread=some"))
804 VG_(clo_trace_pthread_level) = 1;
805 else if (STREQ(argv[i], "--trace-pthread=all"))
806 VG_(clo_trace_pthread_level) = 2;
sewardj8937c812002-04-12 20:12:20 +0000807
sewardj8d365b52002-05-12 10:52:16 +0000808 else if (STREQN(14, argv[i], "--weird-hacks="))
809 VG_(clo_weird_hacks) = &argv[i][14];
sewardj3984b852002-05-12 03:00:17 +0000810
sewardjde4a1d02002-03-22 01:27:54 +0000811 else if (STREQN(13, argv[i], "--stop-after="))
812 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
813
814 else if (STREQN(13, argv[i], "--dump-error="))
815 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
816
817 else if (STREQN(14, argv[i], "--num-callers=")) {
818 /* Make sure it's sane. */
819 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
820 if (VG_(clo_backtrace_size) < 2)
821 VG_(clo_backtrace_size) = 2;
822 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
823 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
824 }
825
826 else
827 bad_option(argv[i]);
828 }
829
830# undef ISSPACE
831# undef STREQ
832# undef STREQN
833
834 if (VG_(clo_verbosity < 0))
835 VG_(clo_verbosity) = 0;
836
837 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
838 VG_(message)(Vg_UserMsg, "");
839 VG_(message)(Vg_UserMsg,
840 "--gdb-attach=yes conflicts with --trace-children=yes");
841 VG_(message)(Vg_UserMsg,
842 "Please choose one or the other, but not both.");
843 bad_option("--gdb-attach=yes and --trace-children=yes");
844 }
845
sewardjde4a1d02002-03-22 01:27:54 +0000846 VG_(clo_logfile_fd) = eventually_logfile_fd;
847
njn4f9c9342002-04-29 16:03:24 +0000848 /* Don't do memory checking if simulating the cache. */
849 if (VG_(clo_cachesim)) {
850 VG_(clo_instrument) = False;
851 }
852
sewardj83adf412002-05-01 01:25:45 +0000853 if (VG_(clo_verbosity > 0)) {
854 if (VG_(clo_cachesim)) {
855 VG_(message)(Vg_UserMsg,
856 "cachegrind-%s, an I1/D1/L2 cache profiler for x86 GNU/Linux.",
857 VERSION);
858 } else {
859 VG_(message)(Vg_UserMsg,
860 "valgrind-%s, a memory error detector for x86 GNU/Linux.",
861 VERSION);
862 }
863 }
sewardj3b2736a2002-03-24 12:18:35 +0000864
sewardjde4a1d02002-03-22 01:27:54 +0000865 if (VG_(clo_verbosity > 0))
866 VG_(message)(Vg_UserMsg,
867 "Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.");
868 if (VG_(clo_verbosity) > 1) {
869 VG_(message)(Vg_UserMsg, "Startup, with flags:");
870 for (i = 0; i < argc; i++) {
871 VG_(message)(Vg_UserMsg, " %s", argv[i]);
872 }
873 }
874
sewardj83adf412002-05-01 01:25:45 +0000875 if (VG_(clo_n_suppressions) == 0 && !VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +0000876 config_error("No error-suppression files were specified.");
877 }
878}
879
880
881/* ---------------------------------------------------------------------
882 Copying to/from m_state_static.
883 ------------------------------------------------------------------ */
884
885UInt VG_(m_state_static) [8 /* int regs, in Intel order */
886 + 1 /* %eflags */
887 + 1 /* %eip */
888 + VG_SIZE_OF_FPUSTATE_W /* FPU state */
889 ];
890
891void VG_(copy_baseBlock_to_m_state_static) ( void )
892{
893 Int i;
894 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
895 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
896 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
897 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
898 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
899 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
900 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
901 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
902
903 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_eflags)];
904 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
905
906 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
907 VG_(m_state_static)[40/4 + i]
908 = VG_(baseBlock)[VGOFF_(m_fpustate) + i];
909}
910
911
912void VG_(copy_m_state_static_to_baseBlock) ( void )
913{
914 Int i;
915 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
916 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
917 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
918 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
919 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
920 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
921 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
922 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
923
924 VG_(baseBlock)[VGOFF_(m_eflags)] = VG_(m_state_static)[32/4];
925 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
926
927 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
928 VG_(baseBlock)[VGOFF_(m_fpustate) + i]
929 = VG_(m_state_static)[40/4 + i];
930}
931
932
933/* ---------------------------------------------------------------------
934 Show accumulated counts.
935 ------------------------------------------------------------------ */
936
937static void vg_show_counts ( void )
938{
939 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000940 " lru: %d epochs, %d clearings.",
941 VG_(current_epoch),
942 VG_(number_of_lrus) );
sewardjde4a1d02002-03-22 01:27:54 +0000943 VG_(message)(Vg_DebugMsg,
944 "translate: new %d (%d -> %d), discard %d (%d -> %d).",
945 VG_(overall_in_count),
946 VG_(overall_in_osize),
947 VG_(overall_in_tsize),
948 VG_(overall_out_count),
949 VG_(overall_out_osize),
950 VG_(overall_out_tsize) );
951 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000952 " dispatch: %lu basic blocks, %d/%d sched events, %d tt_fast misses.",
953 VG_(bbs_done), VG_(num_scheduling_events_MAJOR),
954 VG_(num_scheduling_events_MINOR),
955 VG_(tt_fast_misses));
sewardjde4a1d02002-03-22 01:27:54 +0000956 VG_(message)(Vg_DebugMsg,
957 "reg-alloc: %d t-req-spill, "
958 "%d+%d orig+spill uis, %d total-reg-r.",
959 VG_(translations_needing_spill),
960 VG_(uinstrs_prealloc),
961 VG_(uinstrs_spill),
962 VG_(total_reg_rank) );
963 VG_(message)(Vg_DebugMsg,
sewardjde4a1d02002-03-22 01:27:54 +0000964 " sanity: %d cheap, %d expensive checks.",
965 VG_(sanity_fast_count),
966 VG_(sanity_slow_count) );
967}
968
969
970/* ---------------------------------------------------------------------
971 Main!
972 ------------------------------------------------------------------ */
973
974/* Where we jump to once Valgrind has got control, and the real
975 machine's state has been copied to the m_state_static. */
976
977void VG_(main) ( void )
978{
sewardj2e93c502002-04-12 11:12:52 +0000979 Int i;
980 VgSchedReturnCode src;
sewardj7e87e382002-05-03 19:09:05 +0000981 ThreadState* tst;
sewardjde4a1d02002-03-22 01:27:54 +0000982
983 /* Set up our stack sanity-check words. */
984 for (i = 0; i < 10; i++) {
985 VG_(stack)[i] = (UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1;
986 VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321;
987 }
988
989 /* Set up baseBlock offsets and copy the saved machine's state into
990 it. */
991 vg_init_baseBlock();
992 VG_(copy_m_state_static_to_baseBlock)();
993
994 /* Process Valgrind's command-line opts (from env var VG_OPTS). */
995 process_cmd_line_options();
996
sewardj64039bb2002-06-03 00:58:18 +0000997 /* Hook to delay things long enough so we can get the pid and
998 attach GDB in another shell. */
999 if (0) {
1000 Int p, q;
1001 for (p = 0; p < 50000; p++)
1002 for (q = 0; q < 50000; q++) ;
1003 }
1004
sewardj018f7622002-05-15 21:13:39 +00001005 /* Initialise the scheduler, and copy the client's state from
1006 baseBlock into VG_(threads)[1]. This has to come before signal
1007 initialisations. */
1008 VG_(scheduler_init)();
1009
1010 /* Initialise the signal handling subsystem, temporarily parking
1011 the saved blocking-mask in saved_sigmask. */
sewardjde4a1d02002-03-22 01:27:54 +00001012 VG_(sigstartup_actions)();
1013
sewardj018f7622002-05-15 21:13:39 +00001014 /* Perhaps we're profiling Valgrind? */
sewardjde4a1d02002-03-22 01:27:54 +00001015# ifdef VG_PROFILE
1016 VGP_(init_profiling)();
1017# endif
1018
sewardj5f07b662002-04-23 16:52:51 +00001019 /* Start calibration of our RDTSC-based clock. */
1020 VG_(start_rdtsc_calibration)();
1021
njn4f9c9342002-04-29 16:03:24 +00001022 if (VG_(clo_instrument) || VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +00001023 VGP_PUSHCC(VgpInitAudit);
1024 VGM_(init_memory_audit)();
1025 VGP_POPCC;
sewardjde4a1d02002-03-22 01:27:54 +00001026 }
1027
sewardj18d75132002-05-16 11:06:21 +00001028 VGP_PUSHCC(VgpReadSyms);
1029 VG_(read_symbols)();
1030 VGP_POPCC;
1031
sewardj5f07b662002-04-23 16:52:51 +00001032 /* End calibration of our RDTSC-based clock, leaving it as long as
1033 we can. */
1034 VG_(end_rdtsc_calibration)();
1035
sewardjde4a1d02002-03-22 01:27:54 +00001036 /* This should come after init_memory_audit; otherwise the latter
1037 carefully sets up the permissions maps to cover the anonymous
1038 mmaps for the translation table and translation cache, which
1039 wastes > 20M of virtual address space. */
sewardj18d75132002-05-16 11:06:21 +00001040 VG_(init_tt_tc)();
sewardjde4a1d02002-03-22 01:27:54 +00001041
1042 if (VG_(clo_verbosity) == 1) {
1043 VG_(message)(Vg_UserMsg,
1044 "For more details, rerun with: -v");
1045 }
1046
1047 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1048 instrumented-ly. */
1049 VG_(running_on_simd_CPU) = True;
1050 if (VG_(clo_instrument)) {
1051 VGM_(make_readable) ( (Addr)&VG_(running_on_simd_CPU), 1 );
1052 VGM_(make_readable) ( (Addr)&VG_(clo_instrument), 1 );
1053 VGM_(make_readable) ( (Addr)&VG_(clo_trace_malloc), 1 );
1054 VGM_(make_readable) ( (Addr)&VG_(clo_sloppy_malloc), 1 );
1055 }
1056
njn4f9c9342002-04-29 16:03:24 +00001057 if (VG_(clo_cachesim))
1058 VG_(init_cachesim)();
1059
sewardjde4a1d02002-03-22 01:27:54 +00001060 if (VG_(clo_verbosity) > 0)
1061 VG_(message)(Vg_UserMsg, "");
1062
1063 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001064
sewardj018f7622002-05-15 21:13:39 +00001065 /* Run! */
sewardj671ff542002-05-07 09:25:30 +00001066 VGP_PUSHCC(VgpSched);
sewardj2e93c502002-04-12 11:12:52 +00001067 src = VG_(scheduler)();
sewardj671ff542002-05-07 09:25:30 +00001068 VGP_POPCC;
sewardjde4a1d02002-03-22 01:27:54 +00001069
1070 if (VG_(clo_verbosity) > 0)
1071 VG_(message)(Vg_UserMsg, "");
1072
sewardj2e93c502002-04-12 11:12:52 +00001073 if (src == VgSrc_Deadlock) {
1074 VG_(message)(Vg_UserMsg,
1075 "Warning: pthread scheduler exited due to deadlock");
1076 }
1077
sewardjde4a1d02002-03-22 01:27:54 +00001078 if (VG_(clo_instrument)) {
1079 VG_(show_all_errors)();
1080 VG_(clientmalloc_done)();
1081 if (VG_(clo_verbosity) == 1) {
1082 VG_(message)(Vg_UserMsg,
1083 "For counts of detected errors, rerun with: -v");
1084 }
1085 if (VG_(clo_leak_check)) VG_(detect_memory_leaks)();
1086 }
1087 VG_(running_on_simd_CPU) = False;
sewardj2e93c502002-04-12 11:12:52 +00001088
njn4f9c9342002-04-29 16:03:24 +00001089 if (VG_(clo_cachesim))
1090 VG_(show_cachesim_results)(VG_(client_argc), VG_(client_argv));
1091
sewardj0c3b53f2002-05-01 01:58:35 +00001092 VG_(do_sanity_checks)( True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001093
1094 if (VG_(clo_verbosity) > 1)
1095 vg_show_counts();
1096
1097 if (0) {
1098 VG_(message)(Vg_DebugMsg, "");
1099 VG_(message)(Vg_DebugMsg,
1100 "------ Valgrind's internal memory use stats follow ------" );
1101 VG_(mallocSanityCheckAll)();
1102 VG_(show_all_arena_stats)();
1103 VG_(message)(Vg_DebugMsg,
1104 "------ Valgrind's ExeContext management stats follow ------" );
1105 VG_(show_ExeContext_stats)();
1106 VG_(message)(Vg_DebugMsg,
1107 "------ Valgrind's client block stats follow ---------------" );
1108 VG_(show_client_block_stats)();
1109 }
1110
1111# ifdef VG_PROFILE
1112 VGP_(done_profiling)();
1113# endif
1114
1115 VG_(done_prof_mem)();
1116
1117 VG_(shutdown_logging)();
1118
sewardj3e1eb1f2002-05-18 13:14:17 +00001119 /* Remove valgrind.so from a LD_PRELOAD=... string so child
1120 processes don't get traced into. Also mess up $libdir/valgrind
1121 so that our libpthread.so disappears from view. */
sewardjde4a1d02002-03-22 01:27:54 +00001122 if (!VG_(clo_trace_children)) {
sewardj3e1eb1f2002-05-18 13:14:17 +00001123 VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH)(
1124 VG_(getenv)("LD_PRELOAD"),
1125 VG_(getenv)("LD_LIBRARY_PATH")
1126 );
sewardjde4a1d02002-03-22 01:27:54 +00001127 }
1128
sewardj7e87e382002-05-03 19:09:05 +00001129 /* Decide how to exit. This depends on what the scheduler
1130 returned. */
1131 switch (src) {
1132 case VgSrc_ExitSyscall: /* the normal way out */
1133 vg_assert(VG_(last_run_tid) > 0
1134 && VG_(last_run_tid) < VG_N_THREADS);
sewardj018f7622002-05-15 21:13:39 +00001135 tst = & VG_(threads)[VG_(last_run_tid)];
sewardj7e87e382002-05-03 19:09:05 +00001136 vg_assert(tst->status == VgTs_Runnable);
1137 /* The thread's %EBX will hold the arg to exit(), so we just
1138 do exit with that arg. */
1139 VG_(exit)( tst->m_ebx );
1140 /* NOT ALIVE HERE! */
1141 VG_(panic)("entered the afterlife in vg_main() -- ExitSyscall");
1142 break; /* what the hell :) */
sewardjde4a1d02002-03-22 01:27:54 +00001143
sewardj7e87e382002-05-03 19:09:05 +00001144 case VgSrc_Deadlock:
1145 /* Just exit now. No point in continuing. */
1146 VG_(exit)(0);
1147 VG_(panic)("entered the afterlife in vg_main() -- Deadlock");
1148 break;
1149
1150 case VgSrc_BbsDone:
1151 /* Tricky; we have to try and switch back to the real CPU.
1152 This is all very dodgy and won't work at all in the
1153 presence of threads, or if the client happened to be
1154 running a signal handler. */
1155 /* Prepare to restore state to the real CPU. */
1156 VG_(load_thread_state)(1 /* root thread */ );
1157 VG_(copy_baseBlock_to_m_state_static)();
1158
1159 /* This pushes a return address on the simulator's stack,
1160 which is abandoned. We call vg_sigshutdown_actions() at
1161 the end of vg_switch_to_real_CPU(), so as to ensure that
1162 the original stack and machine state is restored before
1163 the real signal mechanism is restored. */
1164 VG_(switch_to_real_CPU)();
1165
1166 default:
1167 VG_(panic)("vg_main(): unexpected scheduler return code");
1168 }
sewardjde4a1d02002-03-22 01:27:54 +00001169}
1170
1171
1172/* Debugging thing .. can be called from assembly with OYNK macro. */
1173void VG_(oynk) ( Int n )
1174{
1175 OINK(n);
1176}
1177
1178
1179/* Find "valgrind.so" in a LD_PRELOAD=... string, and convert it to
1180 "valgrinq.so", which doesn't do anything. This is used to avoid
1181 tracing into child processes. To make this work the build system
1182 also supplies a dummy file, "valgrinq.so".
sewardj78e25c92002-05-20 23:38:33 +00001183
1184 Also look for $(libdir)/lib/valgrind in LD_LIBRARY_PATH and change
1185 it to $(libdir)/lib/valgrinq, so as to make our libpthread.so
1186 disappear.
sewardjde4a1d02002-03-22 01:27:54 +00001187*/
sewardj3e1eb1f2002-05-18 13:14:17 +00001188void VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH) ( Char* ld_preload_str,
1189 Char* ld_library_path_str )
sewardjde4a1d02002-03-22 01:27:54 +00001190{
sewardj78e25c92002-05-20 23:38:33 +00001191 Char* p_prel = NULL;
1192 Char* p_path = NULL;
1193 Int what = 0;
1194 if (ld_preload_str == NULL || ld_library_path_str == NULL)
1195 goto mutancy;
sewardj3e1eb1f2002-05-18 13:14:17 +00001196
sewardj78e25c92002-05-20 23:38:33 +00001197 /* VG_(printf)("%s %s\n", ld_preload_str, ld_library_path_str); */
1198
1199 p_prel = VG_(strstr)(ld_preload_str, "valgrind.so");
1200 p_path = VG_(strstr)(ld_library_path_str, VG_LIBDIR);
1201
1202 if (p_prel == NULL) {
sewardj3e1eb1f2002-05-18 13:14:17 +00001203 /* perhaps already happened? */
sewardj78e25c92002-05-20 23:38:33 +00001204 what = 1;
1205 if (VG_(strstr)(ld_preload_str, "valgrinq.so") == NULL)
1206 goto mutancy;
1207 if (VG_(strstr)(ld_library_path_str, "lib/valgrinq") == NULL)
1208 goto mutancy;
sewardjde4a1d02002-03-22 01:27:54 +00001209 return;
sewardj3e1eb1f2002-05-18 13:14:17 +00001210 }
1211
sewardj78e25c92002-05-20 23:38:33 +00001212 what = 2;
1213 if (p_path == NULL) goto mutancy;
1214
1215 /* in LD_PRELOAD, turn valgrind.so into valgrinq.so. */
1216 what = 3;
1217 if (p_prel[7] != 'd') goto mutancy;
1218 p_prel[7] = 'q';
sewardj3e1eb1f2002-05-18 13:14:17 +00001219
1220 /* in LD_LIBRARY_PATH, turn $libdir/valgrind (as configure'd) from
1221 .../lib/valgrind .../lib/valgrinq, which doesn't exist,
1222 so that our own libpthread.so goes out of scope. */
sewardj78e25c92002-05-20 23:38:33 +00001223 p_path += VG_(strlen)(VG_LIBDIR);
1224 what = 4;
1225 if (p_path[0] != '/') goto mutancy;
1226 p_path++; /* step over / */
1227 what = 5;
1228 if (p_path[7] != 'd') goto mutancy;
1229 p_path[7] = 'q';
1230 return;
1231
1232 mutancy:
1233 VG_(printf)(
1234 "\nVG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH): internal error:\n"
1235 " what = %d\n"
1236 " ld_preload_str = `%s'\n"
1237 " ld_library_path_str = `%s'\n"
1238 " p_prel = `%s'\n"
1239 " p_path = `%s'\n"
1240 " VG_LIBDIR = `%s'\n",
sewardj19d81412002-06-03 01:10:40 +00001241 what, ld_preload_str, ld_library_path_str,
1242 p_prel, p_path, VG_LIBDIR
1243 );
sewardj78e25c92002-05-20 23:38:33 +00001244 VG_(panic)("VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH) failed\n");
sewardjde4a1d02002-03-22 01:27:54 +00001245}
1246
sewardj3e1eb1f2002-05-18 13:14:17 +00001247
sewardjde4a1d02002-03-22 01:27:54 +00001248/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1249 it to attach to this process. Called if the user requests this
1250 service after an error has been shown, so she can poke around and
1251 look at parameters, memory, etc. You can't meaningfully get GDB to
1252 continue the program, though; to continue, quit GDB. */
1253extern void VG_(start_GDB_whilst_on_client_stack) ( void )
1254{
sewardje6a25242002-04-21 22:03:07 +00001255 Int res;
sewardjde4a1d02002-03-22 01:27:54 +00001256 UChar buf[100];
1257 VG_(sprintf)(buf,
1258 "/usr/bin/gdb -nw /proc/%d/exe %d",
1259 VG_(getpid)(), VG_(getpid)());
sewardje6a25242002-04-21 22:03:07 +00001260 VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
1261 res = VG_(system)(buf);
1262 if (res == 0) {
1263 VG_(message)(Vg_UserMsg, "");
1264 VG_(message)(Vg_UserMsg,
1265 "GDB has detached. Valgrind regains control. We continue.");
1266 } else {
1267 VG_(message)(Vg_UserMsg, "Apparently failed!");
1268 VG_(message)(Vg_UserMsg, "");
sewardjde4a1d02002-03-22 01:27:54 +00001269 }
sewardjde4a1d02002-03-22 01:27:54 +00001270}
1271
1272
1273/* Print some helpful-ish text about unimplemented things, and give
1274 up. */
sewardjcfc39b22002-05-08 01:58:18 +00001275void VG_(unimplemented) ( Char* msg )
sewardjde4a1d02002-03-22 01:27:54 +00001276{
1277 VG_(message)(Vg_UserMsg, "");
1278 VG_(message)(Vg_UserMsg,
1279 "Valgrind detected that your program requires");
1280 VG_(message)(Vg_UserMsg,
1281 "the following unimplemented functionality:");
1282 VG_(message)(Vg_UserMsg, " %s", msg);
1283 VG_(message)(Vg_UserMsg,
1284 "This may be because the functionality is hard to implement,");
1285 VG_(message)(Vg_UserMsg,
1286 "or because no reasonable program would behave this way,");
1287 VG_(message)(Vg_UserMsg,
1288 "or because nobody has yet needed it. In any case, let me know");
1289 VG_(message)(Vg_UserMsg,
1290 "(jseward@acm.org) and/or try to work around the problem, if you can.");
1291 VG_(message)(Vg_UserMsg,
1292 "");
1293 VG_(message)(Vg_UserMsg,
1294 "Valgrind has to exit now. Sorry. Bye!");
1295 VG_(message)(Vg_UserMsg,
1296 "");
sewardj15a43e12002-04-17 19:35:12 +00001297 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +00001298 VG_(exit)(1);
1299}
1300
1301
sewardjcfc39b22002-05-08 01:58:18 +00001302void VG_(nvidia_moan) ( void)
1303{
1304 VG_(message)(Vg_UserMsg,
1305 "The following failure _might_ be caused by linking to NVidia's\n "
1306 "libGL.so, so avoiding it, if you can, _might_ help you. For example,\n "
1307 "re-build any Qt libraries you are using without OpenGL support.");
1308}
1309
1310
sewardjde4a1d02002-03-22 01:27:54 +00001311/*--------------------------------------------------------------------*/
1312/*--- end vg_main.c ---*/
1313/*--------------------------------------------------------------------*/