blob: ceec5d0452fa378393d67cd3fc9ebae2ef78f113 [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
sewardj72f98ff2002-06-13 17:23:38 +0000402Bool VG_(clo_event_horizon);
sewardj97ced732002-03-25 00:07:36 +0000403Bool VG_(clo_check_addrVs);
sewardjde4a1d02002-03-22 01:27:54 +0000404Bool VG_(clo_GDB_attach);
405Int VG_(sanity_level);
406Int VG_(clo_verbosity);
407Bool VG_(clo_demangle);
408Bool VG_(clo_leak_check);
409Bool VG_(clo_show_reachable);
410Int VG_(clo_leak_resolution);
411Bool VG_(clo_sloppy_malloc);
412Bool VG_(clo_partial_loads_ok);
413Bool VG_(clo_trace_children);
414Int VG_(clo_logfile_fd);
415Int VG_(clo_freelist_vol);
416Bool VG_(clo_workaround_gcc296_bugs);
417Int VG_(clo_n_suppressions);
418Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
419Bool VG_(clo_single_step);
420Bool VG_(clo_optimise);
421Bool VG_(clo_instrument);
422Bool VG_(clo_cleanup);
njn4f9c9342002-04-29 16:03:24 +0000423Bool VG_(clo_cachesim);
njn7cf0bd32002-06-08 13:36:03 +0000424cache_t VG_(clo_I1_cache);
425cache_t VG_(clo_D1_cache);
426cache_t VG_(clo_L2_cache);
sewardjde4a1d02002-03-22 01:27:54 +0000427Int VG_(clo_smc_check);
428Bool VG_(clo_trace_syscalls);
429Bool VG_(clo_trace_signals);
430Bool VG_(clo_trace_symtab);
431Bool VG_(clo_trace_malloc);
sewardj8937c812002-04-12 20:12:20 +0000432Bool VG_(clo_trace_sched);
sewardj45b4b372002-04-16 22:50:32 +0000433Int VG_(clo_trace_pthread_level);
sewardjde4a1d02002-03-22 01:27:54 +0000434ULong VG_(clo_stop_after);
435Int VG_(clo_dump_error);
436Int VG_(clo_backtrace_size);
sewardj8d365b52002-05-12 10:52:16 +0000437Char* VG_(clo_weird_hacks);
sewardjde4a1d02002-03-22 01:27:54 +0000438
439/* This Bool is needed by wrappers in vg_clientmalloc.c to decide how
440 to behave. Initially we say False. */
441Bool VG_(running_on_simd_CPU) = False;
442
443/* Holds client's %esp at the point we gained control. */
444Addr VG_(esp_at_startup);
445
446/* As deduced from VG_(esp_at_startup), the client's argc, argv[] and
447 envp[] as extracted from the client's stack at startup-time. */
448Int VG_(client_argc);
449Char** VG_(client_argv);
450Char** VG_(client_envp);
451
452/* A place into which to copy the value of env var VG_ARGS, so we
453 don't have to modify the original. */
454static Char vg_cmdline_copy[M_VG_CMDLINE_STRLEN];
455
456
457/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000458 Processing of command-line options.
459 ------------------------------------------------------------------ */
460
461static void bad_option ( Char* opt )
462{
463 VG_(shutdown_logging)();
464 VG_(clo_logfile_fd) = 2; /* stderr */
465 VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
466 VG_(exit)(1);
467}
468
469static void config_error ( Char* msg )
470{
471 VG_(shutdown_logging)();
472 VG_(clo_logfile_fd) = 2; /* stderr */
sewardj19d81412002-06-03 01:10:40 +0000473 VG_(printf)(
474 "valgrind.so: Startup or configuration error:\n %s\n", msg);
475 VG_(printf)(
476 "valgrind.so: Unable to start up properly. Giving up.\n");
sewardjde4a1d02002-03-22 01:27:54 +0000477 VG_(exit)(1);
478}
479
sewardja1679dd2002-05-10 22:31:40 +0000480static void args_grok_error ( Char* msg )
481{
482 VG_(shutdown_logging)();
483 VG_(clo_logfile_fd) = 2; /* stderr */
484 VG_(printf)("valgrind.so: When searching for "
485 "client's argc/argc/envp:\n\t%s\n", msg);
486 config_error("couldn't find client's argc/argc/envp");
487}
488
njn7cf0bd32002-06-08 13:36:03 +0000489static void parse_cache_opt ( cache_t* cache, char* orig_opt, int opt_len )
490{
491 int i1, i2, i3;
492 int i;
493 char *opt = VG_(strdup)(VG_AR_PRIVATE, orig_opt);
494
495 i = i1 = opt_len;
496
497 /* Option looks like "--I1=65536,2,64".
498 * Find commas, replace with NULs to make three independent
499 * strings, then extract numbers. Yuck. */
500 while (VG_(isdigit)(opt[i])) i++;
501 if (',' == opt[i]) {
502 opt[i++] = '\0';
503 i2 = i;
504 } else goto bad;
505 while (VG_(isdigit)(opt[i])) i++;
506 if (',' == opt[i]) {
507 opt[i++] = '\0';
508 i3 = i;
509 } else goto bad;
510 while (VG_(isdigit)(opt[i])) i++;
511 if ('\0' != opt[i]) goto bad;
512
513 cache->size = (Int)VG_(atoll)(opt + i1);
514 cache->assoc = (Int)VG_(atoll)(opt + i2);
515 cache->line_size = (Int)VG_(atoll)(opt + i3);
516
517 return;
518
519bad:
520 bad_option(orig_opt);
521}
sewardjde4a1d02002-03-22 01:27:54 +0000522
523static void process_cmd_line_options ( void )
524{
525 UChar* argv[M_VG_CMDLINE_OPTS];
526 UInt argc;
527 UChar* p;
528 UChar* str;
sewardja1679dd2002-05-10 22:31:40 +0000529 Int i, eventually_logfile_fd, ctr;
sewardjde4a1d02002-03-22 01:27:54 +0000530
531# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
532# define STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2)))
533# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
534
535 /* Set defaults. */
sewardj72f98ff2002-06-13 17:23:38 +0000536 VG_(clo_event_horizon) = True;
sewardj97ced732002-03-25 00:07:36 +0000537 VG_(clo_check_addrVs) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000538 VG_(clo_GDB_attach) = False;
539 VG_(sanity_level) = 1;
540 VG_(clo_verbosity) = 1;
541 VG_(clo_demangle) = True;
542 VG_(clo_leak_check) = False;
543 VG_(clo_show_reachable) = False;
544 VG_(clo_leak_resolution) = 2;
545 VG_(clo_sloppy_malloc) = False;
546 VG_(clo_partial_loads_ok) = True;
547 VG_(clo_trace_children) = False;
548 VG_(clo_logfile_fd) = 2; /* stderr */
549 VG_(clo_freelist_vol) = 1000000;
550 VG_(clo_workaround_gcc296_bugs) = False;
551 VG_(clo_n_suppressions) = 0;
552 VG_(clo_single_step) = False;
553 VG_(clo_optimise) = True;
554 VG_(clo_instrument) = True;
njn7cf0bd32002-06-08 13:36:03 +0000555 VG_(clo_cachesim) = False;
556 VG_(clo_I1_cache) = UNDEFINED_CACHE;
557 VG_(clo_D1_cache) = UNDEFINED_CACHE;
558 VG_(clo_L2_cache) = UNDEFINED_CACHE;
sewardjde4a1d02002-03-22 01:27:54 +0000559 VG_(clo_cleanup) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000560 VG_(clo_smc_check) = /* VG_CLO_SMC_SOME */ VG_CLO_SMC_NONE;
561 VG_(clo_trace_syscalls) = False;
562 VG_(clo_trace_signals) = False;
563 VG_(clo_trace_symtab) = False;
564 VG_(clo_trace_malloc) = False;
sewardj8937c812002-04-12 20:12:20 +0000565 VG_(clo_trace_sched) = False;
sewardj45b4b372002-04-16 22:50:32 +0000566 VG_(clo_trace_pthread_level) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000567 VG_(clo_stop_after) = 1000000000000LL;
568 VG_(clo_dump_error) = 0;
569 VG_(clo_backtrace_size) = 4;
sewardj8d365b52002-05-12 10:52:16 +0000570 VG_(clo_weird_hacks) = NULL;
sewardjde4a1d02002-03-22 01:27:54 +0000571
572 eventually_logfile_fd = VG_(clo_logfile_fd);
573
574 /* Once logging is started, we can safely send messages pertaining
575 to failures in initialisation. */
576 VG_(startup_logging)();
577
sewardj19d81412002-06-03 01:10:40 +0000578 /* Check for sane path in ./configure --prefix=... */
579 if (VG_(strlen)(VG_LIBDIR) < 1
580 || VG_LIBDIR[0] != '/')
581 config_error("Please use absolute paths in "
582 "./configure --prefix=... or --libdir=...");
sewardj38170912002-05-10 21:07:22 +0000583
sewardja1679dd2002-05-10 22:31:40 +0000584 /* (Suggested by Fabrice Bellard ... )
585 We look for the Linux ELF table and go down until we find the
njn7cf0bd32002-06-08 13:36:03 +0000586 envc & envp. It is not fool-proof, but these structures should
sewardj38170912002-05-10 21:07:22 +0000587 change less often than the libc ones. */
588 {
sewardja1679dd2002-05-10 22:31:40 +0000589 UInt* sp = 0; /* bogus init to keep gcc -O happy */
590
sewardj38170912002-05-10 21:07:22 +0000591 /* locate the top of the stack */
sewardja1679dd2002-05-10 22:31:40 +0000592 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
593 VG_STARTUP_STACK_BASE_1 )) {
594 sp = (UInt*)VG_STARTUP_STACK_BASE_1;
595 } else
596 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
597 VG_STARTUP_STACK_BASE_2 )) {
598 sp = (UInt*)VG_STARTUP_STACK_BASE_2;
599 } else {
600 args_grok_error(
601 "startup %esp is not near any VG_STARTUP_STACK_BASE_*\n "
602 "constants defined in vg_include.h. You should investigate."
603 );
604 }
605
sewardj38170912002-05-10 21:07:22 +0000606 /* we locate: NEW_AUX_ENT(1, AT_PAGESZ, ELF_EXEC_PAGESIZE) in
607 the elf interpreter table */
608 sp -= 2;
sewardj38170912002-05-10 21:07:22 +0000609 while (sp[0] != VKI_AT_PAGESZ || sp[1] != 4096) {
sewardja1679dd2002-05-10 22:31:40 +0000610 /* VG_(printf)("trying %p\n", sp); */
sewardj38170912002-05-10 21:07:22 +0000611 sp--;
612 }
sewardj38170912002-05-10 21:07:22 +0000613
614 if (sp[2] == VKI_AT_BASE
615 && sp[0] == VKI_AT_PAGESZ
616 && sp[-2] == VKI_AT_PHNUM
617 && sp[-4] == VKI_AT_PHENT
sewardjd9c2d6d2002-05-18 11:55:05 +0000618 && sp[-6] == VKI_AT_PHDR
619 && sp[-6-1] == 0) {
sewardja1679dd2002-05-10 22:31:40 +0000620 if (0)
621 VG_(printf)("Looks like you've got a 2.2.X kernel here.\n");
sewardj38170912002-05-10 21:07:22 +0000622 sp -= 6;
sewardja1679dd2002-05-10 22:31:40 +0000623 } else
624 if (sp[2] == VKI_AT_CLKTCK
625 && sp[0] == VKI_AT_PAGESZ
sewardjd9c2d6d2002-05-18 11:55:05 +0000626 && sp[-2] == VKI_AT_HWCAP
627 && sp[-2-1] == 0) {
sewardja1679dd2002-05-10 22:31:40 +0000628 if (0)
629 VG_(printf)("Looks like you've got a 2.4.X kernel here.\n");
630 sp -= 2;
631 } else
sewardjd9c2d6d2002-05-18 11:55:05 +0000632 if (sp[2] == VKI_AT_CLKTCK
633 && sp[0] == VKI_AT_PAGESZ
634 && sp[-2] == VKI_AT_HWCAP
635 && sp[-2-20-1] == 0) {
636 if (0)
637 VG_(printf)("Looks like you've got a early 2.4.X kernel here.\n");
638 sp -= 22;
639 } else
sewardja1679dd2002-05-10 22:31:40 +0000640 args_grok_error(
641 "ELF frame does not look like 2.2.X or 2.4.X.\n "
642 "See kernel sources linux/fs/binfmt_elf.c to make sense of this."
643 );
sewardj38170912002-05-10 21:07:22 +0000644
645 sp--;
sewardja1679dd2002-05-10 22:31:40 +0000646 if (*sp != 0)
647 args_grok_error("can't find NULL at end of env[]");
648
sewardj38170912002-05-10 21:07:22 +0000649 /* sp now points to NULL at the end of env[] */
sewardja1679dd2002-05-10 22:31:40 +0000650 ctr = 0;
sewardj38170912002-05-10 21:07:22 +0000651 while (True) {
652 sp --;
653 if (*sp == 0) break;
sewardja1679dd2002-05-10 22:31:40 +0000654 if (++ctr >= 1000)
655 args_grok_error(
656 "suspiciously many (1000) env[] entries; giving up");
657
sewardj38170912002-05-10 21:07:22 +0000658 }
659 /* sp now points to NULL at the end of argv[] */
sewardja1679dd2002-05-10 22:31:40 +0000660 VG_(client_envp) = (Char**)(sp+1);
sewardj38170912002-05-10 21:07:22 +0000661
sewardja1679dd2002-05-10 22:31:40 +0000662 ctr = 0;
sewardj38170912002-05-10 21:07:22 +0000663 VG_(client_argc) = 0;
664 while (True) {
665 sp--;
666 if (*sp == VG_(client_argc))
667 break;
668 VG_(client_argc)++;
sewardja1679dd2002-05-10 22:31:40 +0000669 if (++ctr >= 1000)
670 args_grok_error(
671 "suspiciously many (1000) argv[] entries; giving up");
sewardj38170912002-05-10 21:07:22 +0000672 }
673
sewardja1679dd2002-05-10 22:31:40 +0000674 VG_(client_argv) = (Char**)(sp+1);
sewardj38170912002-05-10 21:07:22 +0000675 }
676
sewardjde4a1d02002-03-22 01:27:54 +0000677 /* Now that VG_(client_envp) has been set, we can extract the args
678 for Valgrind itself. Copy into global var so that we don't have to
679 write zeroes to the getenv'd value itself. */
680 str = VG_(getenv)("VG_ARGS");
681 argc = 0;
682
683 if (!str) {
684 config_error("Can't read options from env var VG_ARGS.");
685 }
686
687 if (VG_(strlen)(str) >= M_VG_CMDLINE_STRLEN-1) {
688 config_error("Command line length exceeds M_CMDLINE_STRLEN.");
689 }
690 VG_(strcpy)(vg_cmdline_copy, str);
691 str = NULL;
692
693 p = &vg_cmdline_copy[0];
694 while (True) {
695 while (ISSPACE(*p)) { *p = 0; p++; }
696 if (*p == 0) break;
697 if (argc < M_VG_CMDLINE_OPTS-1) {
698 argv[argc] = p; argc++;
699 } else {
700 config_error(
701 "Found more than M_CMDLINE_OPTS command-line opts.");
702 }
703 while (*p != 0 && !ISSPACE(*p)) p++;
704 }
705
706 for (i = 0; i < argc; i++) {
707
708 if (STREQ(argv[i], "-v") || STREQ(argv[i], "--verbose"))
709 VG_(clo_verbosity)++;
710 else if (STREQ(argv[i], "-q") || STREQ(argv[i], "--quiet"))
711 VG_(clo_verbosity)--;
712
sewardj72f98ff2002-06-13 17:23:38 +0000713 else if (STREQ(argv[i], "--event-horizon=yes"))
714 VG_(clo_event_horizon) = True;
715 else if (STREQ(argv[i], "--event-horizon=no"))
716 VG_(clo_event_horizon) = False;
717
sewardj97ced732002-03-25 00:07:36 +0000718 else if (STREQ(argv[i], "--check-addrVs=yes"))
719 VG_(clo_check_addrVs) = True;
720 else if (STREQ(argv[i], "--check-addrVs=no"))
721 VG_(clo_check_addrVs) = False;
722
sewardjde4a1d02002-03-22 01:27:54 +0000723 else if (STREQ(argv[i], "--gdb-attach=yes"))
724 VG_(clo_GDB_attach) = True;
725 else if (STREQ(argv[i], "--gdb-attach=no"))
726 VG_(clo_GDB_attach) = False;
727
728 else if (STREQ(argv[i], "--demangle=yes"))
729 VG_(clo_demangle) = True;
730 else if (STREQ(argv[i], "--demangle=no"))
731 VG_(clo_demangle) = False;
732
733 else if (STREQ(argv[i], "--partial-loads-ok=yes"))
734 VG_(clo_partial_loads_ok) = True;
735 else if (STREQ(argv[i], "--partial-loads-ok=no"))
736 VG_(clo_partial_loads_ok) = False;
737
738 else if (STREQ(argv[i], "--leak-check=yes"))
739 VG_(clo_leak_check) = True;
740 else if (STREQ(argv[i], "--leak-check=no"))
741 VG_(clo_leak_check) = False;
742
743 else if (STREQ(argv[i], "--show-reachable=yes"))
744 VG_(clo_show_reachable) = True;
745 else if (STREQ(argv[i], "--show-reachable=no"))
746 VG_(clo_show_reachable) = False;
747
748 else if (STREQ(argv[i], "--leak-resolution=low"))
749 VG_(clo_leak_resolution) = 2;
750 else if (STREQ(argv[i], "--leak-resolution=med"))
751 VG_(clo_leak_resolution) = 4;
752 else if (STREQ(argv[i], "--leak-resolution=high"))
753 VG_(clo_leak_resolution) = VG_DEEPEST_BACKTRACE;
754
755 else if (STREQ(argv[i], "--sloppy-malloc=yes"))
756 VG_(clo_sloppy_malloc) = True;
757 else if (STREQ(argv[i], "--sloppy-malloc=no"))
758 VG_(clo_sloppy_malloc) = False;
759
760 else if (STREQ(argv[i], "--trace-children=yes"))
761 VG_(clo_trace_children) = True;
762 else if (STREQ(argv[i], "--trace-children=no"))
763 VG_(clo_trace_children) = False;
764
765 else if (STREQ(argv[i], "--workaround-gcc296-bugs=yes"))
766 VG_(clo_workaround_gcc296_bugs) = True;
767 else if (STREQ(argv[i], "--workaround-gcc296-bugs=no"))
768 VG_(clo_workaround_gcc296_bugs) = False;
769
770 else if (STREQN(15, argv[i], "--sanity-level="))
771 VG_(sanity_level) = (Int)VG_(atoll)(&argv[i][15]);
772
773 else if (STREQN(13, argv[i], "--logfile-fd="))
774 eventually_logfile_fd = (Int)VG_(atoll)(&argv[i][13]);
775
776 else if (STREQN(15, argv[i], "--freelist-vol=")) {
777 VG_(clo_freelist_vol) = (Int)VG_(atoll)(&argv[i][15]);
778 if (VG_(clo_freelist_vol) < 0) VG_(clo_freelist_vol) = 2;
779 }
780
781 else if (STREQN(15, argv[i], "--suppressions=")) {
782 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
783 VG_(message)(Vg_UserMsg, "Too many logfiles specified.");
784 VG_(message)(Vg_UserMsg,
785 "Increase VG_CLO_MAX_SFILES and recompile.");
786 bad_option(argv[i]);
787 }
788 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &argv[i][15];
789 VG_(clo_n_suppressions)++;
790 }
791 else if (STREQ(argv[i], "--single-step=yes"))
792 VG_(clo_single_step) = True;
793 else if (STREQ(argv[i], "--single-step=no"))
794 VG_(clo_single_step) = False;
795
796 else if (STREQ(argv[i], "--optimise=yes"))
797 VG_(clo_optimise) = True;
798 else if (STREQ(argv[i], "--optimise=no"))
799 VG_(clo_optimise) = False;
800
801 else if (STREQ(argv[i], "--instrument=yes"))
802 VG_(clo_instrument) = True;
803 else if (STREQ(argv[i], "--instrument=no"))
804 VG_(clo_instrument) = False;
805
806 else if (STREQ(argv[i], "--cleanup=yes"))
807 VG_(clo_cleanup) = True;
808 else if (STREQ(argv[i], "--cleanup=no"))
809 VG_(clo_cleanup) = False;
810
njn4f9c9342002-04-29 16:03:24 +0000811 else if (STREQ(argv[i], "--cachesim=yes"))
812 VG_(clo_cachesim) = True;
813 else if (STREQ(argv[i], "--cachesim=no"))
814 VG_(clo_cachesim) = False;
815
njn7cf0bd32002-06-08 13:36:03 +0000816 /* 5 is length of "--I1=" */
817 else if (0 == VG_(strncmp)(argv[i], "--I1=", 5))
818 parse_cache_opt(&VG_(clo_I1_cache), argv[i], 5);
819 else if (0 == VG_(strncmp)(argv[i], "--D1=", 5))
820 parse_cache_opt(&VG_(clo_D1_cache), argv[i], 5);
821 else if (0 == VG_(strncmp)(argv[i], "--L2=", 5))
822 parse_cache_opt(&VG_(clo_L2_cache), argv[i], 5);
823
sewardjde4a1d02002-03-22 01:27:54 +0000824 else if (STREQ(argv[i], "--smc-check=none"))
825 VG_(clo_smc_check) = VG_CLO_SMC_NONE;
826 else if (STREQ(argv[i], "--smc-check=some"))
827 VG_(clo_smc_check) = VG_CLO_SMC_SOME;
828 else if (STREQ(argv[i], "--smc-check=all"))
829 VG_(clo_smc_check) = VG_CLO_SMC_ALL;
830
831 else if (STREQ(argv[i], "--trace-syscalls=yes"))
832 VG_(clo_trace_syscalls) = True;
833 else if (STREQ(argv[i], "--trace-syscalls=no"))
834 VG_(clo_trace_syscalls) = False;
835
836 else if (STREQ(argv[i], "--trace-signals=yes"))
837 VG_(clo_trace_signals) = True;
838 else if (STREQ(argv[i], "--trace-signals=no"))
839 VG_(clo_trace_signals) = False;
840
841 else if (STREQ(argv[i], "--trace-symtab=yes"))
842 VG_(clo_trace_symtab) = True;
843 else if (STREQ(argv[i], "--trace-symtab=no"))
844 VG_(clo_trace_symtab) = False;
845
846 else if (STREQ(argv[i], "--trace-malloc=yes"))
847 VG_(clo_trace_malloc) = True;
848 else if (STREQ(argv[i], "--trace-malloc=no"))
849 VG_(clo_trace_malloc) = False;
850
sewardj8937c812002-04-12 20:12:20 +0000851 else if (STREQ(argv[i], "--trace-sched=yes"))
852 VG_(clo_trace_sched) = True;
853 else if (STREQ(argv[i], "--trace-sched=no"))
854 VG_(clo_trace_sched) = False;
855
sewardj45b4b372002-04-16 22:50:32 +0000856 else if (STREQ(argv[i], "--trace-pthread=none"))
857 VG_(clo_trace_pthread_level) = 0;
858 else if (STREQ(argv[i], "--trace-pthread=some"))
859 VG_(clo_trace_pthread_level) = 1;
860 else if (STREQ(argv[i], "--trace-pthread=all"))
861 VG_(clo_trace_pthread_level) = 2;
sewardj8937c812002-04-12 20:12:20 +0000862
sewardj8d365b52002-05-12 10:52:16 +0000863 else if (STREQN(14, argv[i], "--weird-hacks="))
864 VG_(clo_weird_hacks) = &argv[i][14];
sewardj3984b852002-05-12 03:00:17 +0000865
sewardjde4a1d02002-03-22 01:27:54 +0000866 else if (STREQN(13, argv[i], "--stop-after="))
867 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
868
869 else if (STREQN(13, argv[i], "--dump-error="))
870 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
871
872 else if (STREQN(14, argv[i], "--num-callers=")) {
873 /* Make sure it's sane. */
874 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
875 if (VG_(clo_backtrace_size) < 2)
876 VG_(clo_backtrace_size) = 2;
877 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
878 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
879 }
880
881 else
882 bad_option(argv[i]);
883 }
884
885# undef ISSPACE
886# undef STREQ
887# undef STREQN
888
889 if (VG_(clo_verbosity < 0))
890 VG_(clo_verbosity) = 0;
891
892 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
893 VG_(message)(Vg_UserMsg, "");
894 VG_(message)(Vg_UserMsg,
895 "--gdb-attach=yes conflicts with --trace-children=yes");
896 VG_(message)(Vg_UserMsg,
897 "Please choose one or the other, but not both.");
898 bad_option("--gdb-attach=yes and --trace-children=yes");
899 }
900
sewardjde4a1d02002-03-22 01:27:54 +0000901 VG_(clo_logfile_fd) = eventually_logfile_fd;
902
njn4f9c9342002-04-29 16:03:24 +0000903 /* Don't do memory checking if simulating the cache. */
904 if (VG_(clo_cachesim)) {
905 VG_(clo_instrument) = False;
906 }
907
sewardj83adf412002-05-01 01:25:45 +0000908 if (VG_(clo_verbosity > 0)) {
909 if (VG_(clo_cachesim)) {
910 VG_(message)(Vg_UserMsg,
911 "cachegrind-%s, an I1/D1/L2 cache profiler for x86 GNU/Linux.",
912 VERSION);
913 } else {
914 VG_(message)(Vg_UserMsg,
915 "valgrind-%s, a memory error detector for x86 GNU/Linux.",
916 VERSION);
917 }
918 }
sewardj3b2736a2002-03-24 12:18:35 +0000919
sewardjde4a1d02002-03-22 01:27:54 +0000920 if (VG_(clo_verbosity > 0))
921 VG_(message)(Vg_UserMsg,
922 "Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.");
923 if (VG_(clo_verbosity) > 1) {
924 VG_(message)(Vg_UserMsg, "Startup, with flags:");
925 for (i = 0; i < argc; i++) {
926 VG_(message)(Vg_UserMsg, " %s", argv[i]);
927 }
928 }
929
sewardj83adf412002-05-01 01:25:45 +0000930 if (VG_(clo_n_suppressions) == 0 && !VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +0000931 config_error("No error-suppression files were specified.");
932 }
933}
934
935
936/* ---------------------------------------------------------------------
937 Copying to/from m_state_static.
938 ------------------------------------------------------------------ */
939
940UInt VG_(m_state_static) [8 /* int regs, in Intel order */
941 + 1 /* %eflags */
942 + 1 /* %eip */
943 + VG_SIZE_OF_FPUSTATE_W /* FPU state */
944 ];
945
946void VG_(copy_baseBlock_to_m_state_static) ( void )
947{
948 Int i;
949 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
950 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
951 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
952 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
953 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
954 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
955 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
956 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
957
958 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_eflags)];
959 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
960
961 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
962 VG_(m_state_static)[40/4 + i]
963 = VG_(baseBlock)[VGOFF_(m_fpustate) + i];
964}
965
966
967void VG_(copy_m_state_static_to_baseBlock) ( void )
968{
969 Int i;
970 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
971 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
972 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
973 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
974 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
975 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
976 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
977 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
978
979 VG_(baseBlock)[VGOFF_(m_eflags)] = VG_(m_state_static)[32/4];
980 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
981
982 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
983 VG_(baseBlock)[VGOFF_(m_fpustate) + i]
984 = VG_(m_state_static)[40/4 + i];
985}
986
987
988/* ---------------------------------------------------------------------
989 Show accumulated counts.
990 ------------------------------------------------------------------ */
991
992static void vg_show_counts ( void )
993{
994 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000995 " lru: %d epochs, %d clearings.",
996 VG_(current_epoch),
997 VG_(number_of_lrus) );
sewardjde4a1d02002-03-22 01:27:54 +0000998 VG_(message)(Vg_DebugMsg,
999 "translate: new %d (%d -> %d), discard %d (%d -> %d).",
1000 VG_(overall_in_count),
1001 VG_(overall_in_osize),
1002 VG_(overall_in_tsize),
1003 VG_(overall_out_count),
1004 VG_(overall_out_osize),
1005 VG_(overall_out_tsize) );
1006 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +00001007 " dispatch: %lu basic blocks, %d/%d sched events, %d tt_fast misses.",
1008 VG_(bbs_done), VG_(num_scheduling_events_MAJOR),
1009 VG_(num_scheduling_events_MINOR),
1010 VG_(tt_fast_misses));
sewardjde4a1d02002-03-22 01:27:54 +00001011 VG_(message)(Vg_DebugMsg,
1012 "reg-alloc: %d t-req-spill, "
1013 "%d+%d orig+spill uis, %d total-reg-r.",
1014 VG_(translations_needing_spill),
1015 VG_(uinstrs_prealloc),
1016 VG_(uinstrs_spill),
1017 VG_(total_reg_rank) );
1018 VG_(message)(Vg_DebugMsg,
sewardjde4a1d02002-03-22 01:27:54 +00001019 " sanity: %d cheap, %d expensive checks.",
1020 VG_(sanity_fast_count),
1021 VG_(sanity_slow_count) );
1022}
1023
1024
1025/* ---------------------------------------------------------------------
1026 Main!
1027 ------------------------------------------------------------------ */
1028
1029/* Where we jump to once Valgrind has got control, and the real
1030 machine's state has been copied to the m_state_static. */
1031
1032void VG_(main) ( void )
1033{
sewardj2e93c502002-04-12 11:12:52 +00001034 Int i;
1035 VgSchedReturnCode src;
sewardj7e87e382002-05-03 19:09:05 +00001036 ThreadState* tst;
sewardjde4a1d02002-03-22 01:27:54 +00001037
1038 /* Set up our stack sanity-check words. */
1039 for (i = 0; i < 10; i++) {
1040 VG_(stack)[i] = (UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1;
1041 VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321;
1042 }
1043
1044 /* Set up baseBlock offsets and copy the saved machine's state into
1045 it. */
1046 vg_init_baseBlock();
1047 VG_(copy_m_state_static_to_baseBlock)();
1048
1049 /* Process Valgrind's command-line opts (from env var VG_OPTS). */
1050 process_cmd_line_options();
1051
sewardj64039bb2002-06-03 00:58:18 +00001052 /* Hook to delay things long enough so we can get the pid and
1053 attach GDB in another shell. */
1054 if (0) {
1055 Int p, q;
1056 for (p = 0; p < 50000; p++)
1057 for (q = 0; q < 50000; q++) ;
1058 }
1059
sewardj018f7622002-05-15 21:13:39 +00001060 /* Initialise the scheduler, and copy the client's state from
1061 baseBlock into VG_(threads)[1]. This has to come before signal
1062 initialisations. */
1063 VG_(scheduler_init)();
1064
1065 /* Initialise the signal handling subsystem, temporarily parking
1066 the saved blocking-mask in saved_sigmask. */
sewardjde4a1d02002-03-22 01:27:54 +00001067 VG_(sigstartup_actions)();
1068
sewardj018f7622002-05-15 21:13:39 +00001069 /* Perhaps we're profiling Valgrind? */
sewardjde4a1d02002-03-22 01:27:54 +00001070# ifdef VG_PROFILE
1071 VGP_(init_profiling)();
1072# endif
1073
sewardj5f07b662002-04-23 16:52:51 +00001074 /* Start calibration of our RDTSC-based clock. */
1075 VG_(start_rdtsc_calibration)();
1076
njn4f9c9342002-04-29 16:03:24 +00001077 if (VG_(clo_instrument) || VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +00001078 VGP_PUSHCC(VgpInitAudit);
1079 VGM_(init_memory_audit)();
1080 VGP_POPCC;
sewardjde4a1d02002-03-22 01:27:54 +00001081 }
1082
sewardj18d75132002-05-16 11:06:21 +00001083 VGP_PUSHCC(VgpReadSyms);
1084 VG_(read_symbols)();
1085 VGP_POPCC;
1086
sewardj5f07b662002-04-23 16:52:51 +00001087 /* End calibration of our RDTSC-based clock, leaving it as long as
1088 we can. */
1089 VG_(end_rdtsc_calibration)();
1090
sewardjde4a1d02002-03-22 01:27:54 +00001091 /* This should come after init_memory_audit; otherwise the latter
1092 carefully sets up the permissions maps to cover the anonymous
1093 mmaps for the translation table and translation cache, which
1094 wastes > 20M of virtual address space. */
sewardj18d75132002-05-16 11:06:21 +00001095 VG_(init_tt_tc)();
sewardjde4a1d02002-03-22 01:27:54 +00001096
1097 if (VG_(clo_verbosity) == 1) {
1098 VG_(message)(Vg_UserMsg,
1099 "For more details, rerun with: -v");
1100 }
1101
1102 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1103 instrumented-ly. */
1104 VG_(running_on_simd_CPU) = True;
1105 if (VG_(clo_instrument)) {
1106 VGM_(make_readable) ( (Addr)&VG_(running_on_simd_CPU), 1 );
1107 VGM_(make_readable) ( (Addr)&VG_(clo_instrument), 1 );
1108 VGM_(make_readable) ( (Addr)&VG_(clo_trace_malloc), 1 );
1109 VGM_(make_readable) ( (Addr)&VG_(clo_sloppy_malloc), 1 );
1110 }
1111
njn4f9c9342002-04-29 16:03:24 +00001112 if (VG_(clo_cachesim))
1113 VG_(init_cachesim)();
1114
sewardjde4a1d02002-03-22 01:27:54 +00001115 if (VG_(clo_verbosity) > 0)
1116 VG_(message)(Vg_UserMsg, "");
1117
1118 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001119
sewardj018f7622002-05-15 21:13:39 +00001120 /* Run! */
sewardj671ff542002-05-07 09:25:30 +00001121 VGP_PUSHCC(VgpSched);
sewardj2e93c502002-04-12 11:12:52 +00001122 src = VG_(scheduler)();
sewardj671ff542002-05-07 09:25:30 +00001123 VGP_POPCC;
sewardjde4a1d02002-03-22 01:27:54 +00001124
1125 if (VG_(clo_verbosity) > 0)
1126 VG_(message)(Vg_UserMsg, "");
1127
sewardj2e93c502002-04-12 11:12:52 +00001128 if (src == VgSrc_Deadlock) {
1129 VG_(message)(Vg_UserMsg,
1130 "Warning: pthread scheduler exited due to deadlock");
1131 }
1132
sewardjde4a1d02002-03-22 01:27:54 +00001133 if (VG_(clo_instrument)) {
1134 VG_(show_all_errors)();
1135 VG_(clientmalloc_done)();
1136 if (VG_(clo_verbosity) == 1) {
1137 VG_(message)(Vg_UserMsg,
1138 "For counts of detected errors, rerun with: -v");
1139 }
1140 if (VG_(clo_leak_check)) VG_(detect_memory_leaks)();
1141 }
1142 VG_(running_on_simd_CPU) = False;
sewardj2e93c502002-04-12 11:12:52 +00001143
njn4f9c9342002-04-29 16:03:24 +00001144 if (VG_(clo_cachesim))
njn7cf0bd32002-06-08 13:36:03 +00001145 VG_(do_cachesim_results)(VG_(client_argc), VG_(client_argv));
njn4f9c9342002-04-29 16:03:24 +00001146
sewardj0c3b53f2002-05-01 01:58:35 +00001147 VG_(do_sanity_checks)( True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001148
1149 if (VG_(clo_verbosity) > 1)
1150 vg_show_counts();
1151
1152 if (0) {
1153 VG_(message)(Vg_DebugMsg, "");
1154 VG_(message)(Vg_DebugMsg,
1155 "------ Valgrind's internal memory use stats follow ------" );
1156 VG_(mallocSanityCheckAll)();
1157 VG_(show_all_arena_stats)();
1158 VG_(message)(Vg_DebugMsg,
1159 "------ Valgrind's ExeContext management stats follow ------" );
1160 VG_(show_ExeContext_stats)();
1161 VG_(message)(Vg_DebugMsg,
1162 "------ Valgrind's client block stats follow ---------------" );
1163 VG_(show_client_block_stats)();
1164 }
1165
1166# ifdef VG_PROFILE
1167 VGP_(done_profiling)();
1168# endif
1169
1170 VG_(done_prof_mem)();
1171
1172 VG_(shutdown_logging)();
1173
sewardj3e1eb1f2002-05-18 13:14:17 +00001174 /* Remove valgrind.so from a LD_PRELOAD=... string so child
1175 processes don't get traced into. Also mess up $libdir/valgrind
1176 so that our libpthread.so disappears from view. */
sewardjde4a1d02002-03-22 01:27:54 +00001177 if (!VG_(clo_trace_children)) {
sewardj3e1eb1f2002-05-18 13:14:17 +00001178 VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH)(
1179 VG_(getenv)("LD_PRELOAD"),
1180 VG_(getenv)("LD_LIBRARY_PATH")
1181 );
sewardjde4a1d02002-03-22 01:27:54 +00001182 }
1183
sewardj7e87e382002-05-03 19:09:05 +00001184 /* Decide how to exit. This depends on what the scheduler
1185 returned. */
1186 switch (src) {
1187 case VgSrc_ExitSyscall: /* the normal way out */
1188 vg_assert(VG_(last_run_tid) > 0
1189 && VG_(last_run_tid) < VG_N_THREADS);
sewardj018f7622002-05-15 21:13:39 +00001190 tst = & VG_(threads)[VG_(last_run_tid)];
sewardj7e87e382002-05-03 19:09:05 +00001191 vg_assert(tst->status == VgTs_Runnable);
1192 /* The thread's %EBX will hold the arg to exit(), so we just
1193 do exit with that arg. */
1194 VG_(exit)( tst->m_ebx );
1195 /* NOT ALIVE HERE! */
1196 VG_(panic)("entered the afterlife in vg_main() -- ExitSyscall");
1197 break; /* what the hell :) */
sewardjde4a1d02002-03-22 01:27:54 +00001198
sewardj7e87e382002-05-03 19:09:05 +00001199 case VgSrc_Deadlock:
1200 /* Just exit now. No point in continuing. */
1201 VG_(exit)(0);
1202 VG_(panic)("entered the afterlife in vg_main() -- Deadlock");
1203 break;
1204
1205 case VgSrc_BbsDone:
1206 /* Tricky; we have to try and switch back to the real CPU.
1207 This is all very dodgy and won't work at all in the
1208 presence of threads, or if the client happened to be
1209 running a signal handler. */
1210 /* Prepare to restore state to the real CPU. */
1211 VG_(load_thread_state)(1 /* root thread */ );
1212 VG_(copy_baseBlock_to_m_state_static)();
1213
1214 /* This pushes a return address on the simulator's stack,
1215 which is abandoned. We call vg_sigshutdown_actions() at
1216 the end of vg_switch_to_real_CPU(), so as to ensure that
1217 the original stack and machine state is restored before
1218 the real signal mechanism is restored. */
1219 VG_(switch_to_real_CPU)();
1220
1221 default:
1222 VG_(panic)("vg_main(): unexpected scheduler return code");
1223 }
sewardjde4a1d02002-03-22 01:27:54 +00001224}
1225
1226
1227/* Debugging thing .. can be called from assembly with OYNK macro. */
1228void VG_(oynk) ( Int n )
1229{
1230 OINK(n);
1231}
1232
1233
1234/* Find "valgrind.so" in a LD_PRELOAD=... string, and convert it to
1235 "valgrinq.so", which doesn't do anything. This is used to avoid
1236 tracing into child processes. To make this work the build system
1237 also supplies a dummy file, "valgrinq.so".
sewardj78e25c92002-05-20 23:38:33 +00001238
1239 Also look for $(libdir)/lib/valgrind in LD_LIBRARY_PATH and change
1240 it to $(libdir)/lib/valgrinq, so as to make our libpthread.so
1241 disappear.
sewardjde4a1d02002-03-22 01:27:54 +00001242*/
sewardj3e1eb1f2002-05-18 13:14:17 +00001243void VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH) ( Char* ld_preload_str,
1244 Char* ld_library_path_str )
sewardjde4a1d02002-03-22 01:27:54 +00001245{
sewardj78e25c92002-05-20 23:38:33 +00001246 Char* p_prel = NULL;
1247 Char* p_path = NULL;
1248 Int what = 0;
1249 if (ld_preload_str == NULL || ld_library_path_str == NULL)
1250 goto mutancy;
sewardj3e1eb1f2002-05-18 13:14:17 +00001251
sewardj78e25c92002-05-20 23:38:33 +00001252 /* VG_(printf)("%s %s\n", ld_preload_str, ld_library_path_str); */
1253
1254 p_prel = VG_(strstr)(ld_preload_str, "valgrind.so");
1255 p_path = VG_(strstr)(ld_library_path_str, VG_LIBDIR);
1256
1257 if (p_prel == NULL) {
sewardj3e1eb1f2002-05-18 13:14:17 +00001258 /* perhaps already happened? */
sewardj78e25c92002-05-20 23:38:33 +00001259 what = 1;
1260 if (VG_(strstr)(ld_preload_str, "valgrinq.so") == NULL)
1261 goto mutancy;
1262 if (VG_(strstr)(ld_library_path_str, "lib/valgrinq") == NULL)
1263 goto mutancy;
sewardjde4a1d02002-03-22 01:27:54 +00001264 return;
sewardj3e1eb1f2002-05-18 13:14:17 +00001265 }
1266
sewardj78e25c92002-05-20 23:38:33 +00001267 what = 2;
1268 if (p_path == NULL) goto mutancy;
1269
1270 /* in LD_PRELOAD, turn valgrind.so into valgrinq.so. */
1271 what = 3;
1272 if (p_prel[7] != 'd') goto mutancy;
1273 p_prel[7] = 'q';
sewardj3e1eb1f2002-05-18 13:14:17 +00001274
1275 /* in LD_LIBRARY_PATH, turn $libdir/valgrind (as configure'd) from
1276 .../lib/valgrind .../lib/valgrinq, which doesn't exist,
1277 so that our own libpthread.so goes out of scope. */
sewardj78e25c92002-05-20 23:38:33 +00001278 p_path += VG_(strlen)(VG_LIBDIR);
1279 what = 4;
1280 if (p_path[0] != '/') goto mutancy;
1281 p_path++; /* step over / */
1282 what = 5;
1283 if (p_path[7] != 'd') goto mutancy;
1284 p_path[7] = 'q';
1285 return;
1286
1287 mutancy:
1288 VG_(printf)(
1289 "\nVG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH): internal error:\n"
1290 " what = %d\n"
1291 " ld_preload_str = `%s'\n"
1292 " ld_library_path_str = `%s'\n"
1293 " p_prel = `%s'\n"
1294 " p_path = `%s'\n"
1295 " VG_LIBDIR = `%s'\n",
sewardj19d81412002-06-03 01:10:40 +00001296 what, ld_preload_str, ld_library_path_str,
1297 p_prel, p_path, VG_LIBDIR
1298 );
sewardj78e25c92002-05-20 23:38:33 +00001299 VG_(panic)("VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH) failed\n");
sewardjde4a1d02002-03-22 01:27:54 +00001300}
1301
sewardj3e1eb1f2002-05-18 13:14:17 +00001302
sewardjde4a1d02002-03-22 01:27:54 +00001303/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1304 it to attach to this process. Called if the user requests this
1305 service after an error has been shown, so she can poke around and
1306 look at parameters, memory, etc. You can't meaningfully get GDB to
1307 continue the program, though; to continue, quit GDB. */
1308extern void VG_(start_GDB_whilst_on_client_stack) ( void )
1309{
sewardje6a25242002-04-21 22:03:07 +00001310 Int res;
sewardjde4a1d02002-03-22 01:27:54 +00001311 UChar buf[100];
1312 VG_(sprintf)(buf,
1313 "/usr/bin/gdb -nw /proc/%d/exe %d",
1314 VG_(getpid)(), VG_(getpid)());
sewardje6a25242002-04-21 22:03:07 +00001315 VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
1316 res = VG_(system)(buf);
1317 if (res == 0) {
1318 VG_(message)(Vg_UserMsg, "");
1319 VG_(message)(Vg_UserMsg,
1320 "GDB has detached. Valgrind regains control. We continue.");
1321 } else {
1322 VG_(message)(Vg_UserMsg, "Apparently failed!");
1323 VG_(message)(Vg_UserMsg, "");
sewardjde4a1d02002-03-22 01:27:54 +00001324 }
sewardjde4a1d02002-03-22 01:27:54 +00001325}
1326
1327
1328/* Print some helpful-ish text about unimplemented things, and give
1329 up. */
sewardjcfc39b22002-05-08 01:58:18 +00001330void VG_(unimplemented) ( Char* msg )
sewardjde4a1d02002-03-22 01:27:54 +00001331{
1332 VG_(message)(Vg_UserMsg, "");
1333 VG_(message)(Vg_UserMsg,
1334 "Valgrind detected that your program requires");
1335 VG_(message)(Vg_UserMsg,
1336 "the following unimplemented functionality:");
1337 VG_(message)(Vg_UserMsg, " %s", msg);
1338 VG_(message)(Vg_UserMsg,
1339 "This may be because the functionality is hard to implement,");
1340 VG_(message)(Vg_UserMsg,
1341 "or because no reasonable program would behave this way,");
1342 VG_(message)(Vg_UserMsg,
1343 "or because nobody has yet needed it. In any case, let me know");
1344 VG_(message)(Vg_UserMsg,
1345 "(jseward@acm.org) and/or try to work around the problem, if you can.");
1346 VG_(message)(Vg_UserMsg,
1347 "");
1348 VG_(message)(Vg_UserMsg,
1349 "Valgrind has to exit now. Sorry. Bye!");
1350 VG_(message)(Vg_UserMsg,
1351 "");
sewardj15a43e12002-04-17 19:35:12 +00001352 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +00001353 VG_(exit)(1);
1354}
1355
1356
sewardjcfc39b22002-05-08 01:58:18 +00001357void VG_(nvidia_moan) ( void)
1358{
1359 VG_(message)(Vg_UserMsg,
1360 "The following failure _might_ be caused by linking to NVidia's\n "
1361 "libGL.so, so avoiding it, if you can, _might_ help you. For example,\n "
1362 "re-build any Qt libraries you are using without OpenGL support.");
1363}
1364
1365
sewardjde4a1d02002-03-22 01:27:54 +00001366/*--------------------------------------------------------------------*/
1367/*--- end vg_main.c ---*/
1368/*--------------------------------------------------------------------*/