blob: 7665d86dc5cf1cbfef2dac0f2973adb42ed4adec [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
3/*--- C startup stuff, reached from vg_startup.S. ---*/
4/*--- vg_main.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, an x86 protected-mode emulator
9 designed for debugging and profiling binaries on x86-Unixes.
10
11 Copyright (C) 2000-2002 Julian Seward
12 jseward@acm.org
13 Julian_Seward@muraroa.demon.co.uk
14
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 02111-1307, USA.
29
30 The GNU General Public License is contained in the file LICENSE.
31*/
32
33#include "vg_include.h"
34#include "vg_constants.h"
35#include "vg_version.h"
36
37
38/* ---------------------------------------------------------------------
39 Compute offsets into baseBlock. See comments in vg_include.h.
40 ------------------------------------------------------------------ */
41
42/* The variables storing offsets. */
43
44#define INVALID_OFFSET (-1)
45
46Int VGOFF_(m_eax) = INVALID_OFFSET;
47Int VGOFF_(m_ecx) = INVALID_OFFSET;
48Int VGOFF_(m_edx) = INVALID_OFFSET;
49Int VGOFF_(m_ebx) = INVALID_OFFSET;
50Int VGOFF_(m_esp) = INVALID_OFFSET;
51Int VGOFF_(m_ebp) = INVALID_OFFSET;
52Int VGOFF_(m_esi) = INVALID_OFFSET;
53Int VGOFF_(m_edi) = INVALID_OFFSET;
54Int VGOFF_(m_eflags) = INVALID_OFFSET;
55Int VGOFF_(m_fpustate) = INVALID_OFFSET;
56Int VGOFF_(m_eip) = INVALID_OFFSET;
57Int VGOFF_(spillslots) = INVALID_OFFSET;
58Int VGOFF_(sh_eax) = INVALID_OFFSET;
59Int VGOFF_(sh_ecx) = INVALID_OFFSET;
60Int VGOFF_(sh_edx) = INVALID_OFFSET;
61Int VGOFF_(sh_ebx) = INVALID_OFFSET;
62Int VGOFF_(sh_esp) = INVALID_OFFSET;
63Int VGOFF_(sh_ebp) = INVALID_OFFSET;
64Int VGOFF_(sh_esi) = INVALID_OFFSET;
65Int VGOFF_(sh_edi) = INVALID_OFFSET;
66Int VGOFF_(sh_eflags) = INVALID_OFFSET;
67Int VGOFF_(helper_idiv_64_32) = INVALID_OFFSET;
68Int VGOFF_(helper_div_64_32) = INVALID_OFFSET;
69Int VGOFF_(helper_idiv_32_16) = INVALID_OFFSET;
70Int VGOFF_(helper_div_32_16) = INVALID_OFFSET;
71Int VGOFF_(helper_idiv_16_8) = INVALID_OFFSET;
72Int VGOFF_(helper_div_16_8) = INVALID_OFFSET;
73Int VGOFF_(helper_imul_32_64) = INVALID_OFFSET;
74Int VGOFF_(helper_mul_32_64) = INVALID_OFFSET;
75Int VGOFF_(helper_imul_16_32) = INVALID_OFFSET;
76Int VGOFF_(helper_mul_16_32) = INVALID_OFFSET;
77Int VGOFF_(helper_imul_8_16) = INVALID_OFFSET;
78Int VGOFF_(helper_mul_8_16) = INVALID_OFFSET;
79Int VGOFF_(helper_CLD) = INVALID_OFFSET;
80Int VGOFF_(helper_STD) = INVALID_OFFSET;
81Int VGOFF_(helper_get_dirflag) = INVALID_OFFSET;
82Int 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;
89Int VGOFF_(helper_bt) = INVALID_OFFSET;
90Int VGOFF_(helper_bts) = INVALID_OFFSET;
91Int VGOFF_(helper_btr) = INVALID_OFFSET;
92Int VGOFF_(helper_btc) = INVALID_OFFSET;
93Int VGOFF_(helper_bsf) = INVALID_OFFSET;
94Int VGOFF_(helper_bsr) = INVALID_OFFSET;
95Int VGOFF_(helper_fstsw_AX) = INVALID_OFFSET;
96Int VGOFF_(helper_SAHF) = INVALID_OFFSET;
sewardj4d0ab1f2002-03-24 10:00:09 +000097Int VGOFF_(helper_DAS) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000098Int VGOFF_(helper_value_check4_fail) = INVALID_OFFSET;
99Int VGOFF_(helper_value_check2_fail) = INVALID_OFFSET;
100Int VGOFF_(helper_value_check1_fail) = INVALID_OFFSET;
101Int VGOFF_(helper_value_check0_fail) = INVALID_OFFSET;
102Int VGOFF_(helper_do_syscall) = INVALID_OFFSET;
103Int VGOFF_(helper_do_client_request) = INVALID_OFFSET;
104Int VGOFF_(helperc_LOADV4) = INVALID_OFFSET;
105Int VGOFF_(helperc_LOADV2) = INVALID_OFFSET;
106Int VGOFF_(helperc_LOADV1) = INVALID_OFFSET;
107Int VGOFF_(helperc_STOREV4) = INVALID_OFFSET;
108Int VGOFF_(helperc_STOREV2) = INVALID_OFFSET;
109Int VGOFF_(helperc_STOREV1) = INVALID_OFFSET;
110Int VGOFF_(handle_esp_assignment) = INVALID_OFFSET;
111Int VGOFF_(fpu_write_check) = INVALID_OFFSET;
112Int VGOFF_(fpu_read_check) = INVALID_OFFSET;
113Int VGOFF_(helper_request_normal_exit) = INVALID_OFFSET;
114
115
116/* This is the actual defn of baseblock. */
117UInt VG_(baseBlock)[VG_BASEBLOCK_WORDS];
118
119/* Words. */
120static Int baB_off = 0;
121
122/* Returns the offset, in words. */
123static Int alloc_BaB ( Int words )
124{
125 Int off = baB_off;
126 baB_off += words;
127 if (baB_off >= VG_BASEBLOCK_WORDS)
128 VG_(panic)( "alloc_BaB: baseBlock is too small");
129
130 return off;
131}
132
133/* Allocate 1 word in baseBlock and set it to the given value. */
134static Int alloc_BaB_1_set ( Addr a )
135{
136 Int off = alloc_BaB(1);
137 VG_(baseBlock)[off] = (UInt)a;
138 return off;
139}
140
141
142/* Here we assign actual offsets. It's important to get the most
143 popular referents within 128 bytes of the start, so we can take
144 advantage of short addressing modes relative to %ebp. Popularity
145 of offsets was measured on 22 Feb 02 running a KDE application, and
146 the slots rearranged accordingly, with a 1.5% reduction in total
147 size of translations. */
148
149static void vg_init_baseBlock ( void )
150{
151 baB_off = 0;
152
153 /* Those with offsets under 128 are carefully chosen. */
154
155 /* WORD offsets in this column */
156 /* 0 */ VGOFF_(m_eax) = alloc_BaB(1);
157 /* 1 */ VGOFF_(m_ecx) = alloc_BaB(1);
158 /* 2 */ VGOFF_(m_edx) = alloc_BaB(1);
159 /* 3 */ VGOFF_(m_ebx) = alloc_BaB(1);
160 /* 4 */ VGOFF_(m_esp) = alloc_BaB(1);
161 /* 5 */ VGOFF_(m_ebp) = alloc_BaB(1);
162 /* 6 */ VGOFF_(m_esi) = alloc_BaB(1);
163 /* 7 */ VGOFF_(m_edi) = alloc_BaB(1);
164 /* 8 */ VGOFF_(m_eflags) = alloc_BaB(1);
165
166 /* 9 */ VGOFF_(sh_eax) = alloc_BaB(1);
167 /* 10 */ VGOFF_(sh_ecx) = alloc_BaB(1);
168 /* 11 */ VGOFF_(sh_edx) = alloc_BaB(1);
169 /* 12 */ VGOFF_(sh_ebx) = alloc_BaB(1);
170 /* 13 */ VGOFF_(sh_esp) = alloc_BaB(1);
171 /* 14 */ VGOFF_(sh_ebp) = alloc_BaB(1);
172 /* 15 */ VGOFF_(sh_esi) = alloc_BaB(1);
173 /* 16 */ VGOFF_(sh_edi) = alloc_BaB(1);
174 /* 17 */ VGOFF_(sh_eflags) = alloc_BaB(1);
175
176 /* 18 */
177 VGOFF_(helper_value_check4_fail)
178 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check4_fail) );
179 /* 19 */
180 VGOFF_(helper_value_check0_fail)
181 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check0_fail) );
182
183 /* 20 */
184 VGOFF_(helperc_STOREV4)
185 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV4) );
186 /* 21 */
187 VGOFF_(helperc_STOREV1)
188 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV1) );
189
190 /* 22 */
191 VGOFF_(helperc_LOADV4)
192 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV4) );
193 /* 23 */
194 VGOFF_(helperc_LOADV1)
195 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV1) );
196
197 /* 24 */
198 VGOFF_(handle_esp_assignment)
199 = alloc_BaB_1_set( (Addr) & VGM_(handle_esp_assignment) );
200
201 /* 25 */
202 VGOFF_(m_eip) = alloc_BaB(1);
203
204 /* There are currently 24 spill slots */
205 /* 26 .. 49 This overlaps the magic boundary at >= 32 words, but
206 most spills are to low numbered spill slots, so the ones above
207 the boundary don't see much action. */
208 VGOFF_(spillslots) = alloc_BaB(VG_MAX_SPILLSLOTS);
209
210 /* These two pushed beyond the boundary because 2-byte transactions
211 are rare. */
212 /* 50 */
213 VGOFF_(helperc_STOREV2)
214 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV2) );
215 /* 51 */
216 VGOFF_(helperc_LOADV2)
217 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV2) );
218
219 /* 52 */
220 VGOFF_(fpu_write_check)
221 = alloc_BaB_1_set( (Addr) & VGM_(fpu_write_check) );
222 /* 53 */
223 VGOFF_(fpu_read_check)
224 = alloc_BaB_1_set( (Addr) & VGM_(fpu_read_check) );
225
226 /* Actually I don't think these two are ever used. */
227 /* 54 */
228 VGOFF_(helper_value_check2_fail)
229 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check2_fail) );
230 /* 55 */
231 VGOFF_(helper_value_check1_fail)
232 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check1_fail) );
233
234 /* I gave up counting at this point. Since they're way above the
235 short-amode-boundary, there's no point. */
236
237 VGOFF_(m_fpustate) = alloc_BaB(VG_SIZE_OF_FPUSTATE_W);
238
239 VGOFF_(helper_idiv_64_32)
240 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_64_32) );
241 VGOFF_(helper_div_64_32)
242 = alloc_BaB_1_set( (Addr) & VG_(helper_div_64_32) );
243 VGOFF_(helper_idiv_32_16)
244 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_32_16) );
245 VGOFF_(helper_div_32_16)
246 = alloc_BaB_1_set( (Addr) & VG_(helper_div_32_16) );
247 VGOFF_(helper_idiv_16_8)
248 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_16_8) );
249 VGOFF_(helper_div_16_8)
250 = alloc_BaB_1_set( (Addr) & VG_(helper_div_16_8) );
251
252 VGOFF_(helper_imul_32_64)
253 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_32_64) );
254 VGOFF_(helper_mul_32_64)
255 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_32_64) );
256 VGOFF_(helper_imul_16_32)
257 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_16_32) );
258 VGOFF_(helper_mul_16_32)
259 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_16_32) );
260 VGOFF_(helper_imul_8_16)
261 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_8_16) );
262 VGOFF_(helper_mul_8_16)
263 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_8_16) );
264
265 VGOFF_(helper_CLD)
266 = alloc_BaB_1_set( (Addr) & VG_(helper_CLD) );
267 VGOFF_(helper_STD)
268 = alloc_BaB_1_set( (Addr) & VG_(helper_STD) );
269 VGOFF_(helper_get_dirflag)
270 = alloc_BaB_1_set( (Addr) & VG_(helper_get_dirflag) );
271
272 VGOFF_(helper_shldl)
273 = alloc_BaB_1_set( (Addr) & VG_(helper_shldl) );
274 VGOFF_(helper_shldw)
275 = alloc_BaB_1_set( (Addr) & VG_(helper_shldw) );
276 VGOFF_(helper_shrdl)
277 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdl) );
278 VGOFF_(helper_shrdw)
279 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdw) );
280
281 VGOFF_(helper_RDTSC)
282 = alloc_BaB_1_set( (Addr) & VG_(helper_RDTSC) );
283 VGOFF_(helper_CPUID)
284 = alloc_BaB_1_set( (Addr) & VG_(helper_CPUID) );
285
286 VGOFF_(helper_bt)
287 = alloc_BaB_1_set( (Addr) & VG_(helper_bt) );
288 VGOFF_(helper_bts)
289 = alloc_BaB_1_set( (Addr) & VG_(helper_bts) );
290 VGOFF_(helper_btr)
291 = alloc_BaB_1_set( (Addr) & VG_(helper_btr) );
292 VGOFF_(helper_btc)
293 = alloc_BaB_1_set( (Addr) & VG_(helper_btc) );
294
295 VGOFF_(helper_bsf)
296 = alloc_BaB_1_set( (Addr) & VG_(helper_bsf) );
297 VGOFF_(helper_bsr)
298 = alloc_BaB_1_set( (Addr) & VG_(helper_bsr) );
299
300 VGOFF_(helper_fstsw_AX)
301 = alloc_BaB_1_set( (Addr) & VG_(helper_fstsw_AX) );
302 VGOFF_(helper_SAHF)
303 = alloc_BaB_1_set( (Addr) & VG_(helper_SAHF) );
sewardj4d0ab1f2002-03-24 10:00:09 +0000304 VGOFF_(helper_DAS)
305 = alloc_BaB_1_set( (Addr) & VG_(helper_DAS) );
sewardjde4a1d02002-03-22 01:27:54 +0000306
307 VGOFF_(helper_request_normal_exit)
308 = alloc_BaB_1_set( (Addr) & VG_(helper_request_normal_exit) );
309
310 VGOFF_(helper_do_syscall)
311 = alloc_BaB_1_set( (Addr) & VG_(helper_do_syscall) );
312 VGOFF_(helper_do_client_request)
313 = alloc_BaB_1_set( (Addr) & VG_(helper_do_client_request) );
314}
315
316
317/* ---------------------------------------------------------------------
318 Global entities which are not referenced from generated code.
319 ------------------------------------------------------------------ */
320
321/* The stack on which Valgrind runs. We can't use the same stack as
322 the simulatee -- that's an important design decision. */
323UInt VG_(stack)[10000];
324
325/* Ditto our signal delivery stack. */
326UInt VG_(sigstack)[10000];
327
328/* Saving stuff across system calls. */
329UInt VG_(real_fpu_state_saved_over_syscall_d1)[VG_SIZE_OF_FPUSTATE_W];
330UInt VG_(real_fpu_state_saved_over_syscall_d2)[VG_SIZE_OF_FPUSTATE_W];
331Addr VG_(esp_saved_over_syscall_d1);
332Addr VG_(esp_saved_over_syscall_d2);
333
334/* Counts downwards in vg_run_innerloop. */
335UInt VG_(dispatch_ctr);
336
337/* If vg_dispatch_ctr is set to 1 to force a stop, its
338 previous value is saved here. */
339UInt VG_(dispatch_ctr_SAVED);
340
341/* This is why vg_run_innerloop() exited. */
342UInt VG_(interrupt_reason);
343
344/* vg_oursignalhandler() might longjmp(). Here's the jmp_buf. */
345jmp_buf VG_(toploop_jmpbuf);
346/* ... and if so, here's the signal which caused it to do so. */
347Int VG_(longjmpd_on_signal);
348
349/* 64-bit counter for the number of basic blocks done. */
350ULong VG_(bbs_done);
351/* 64-bit counter for the number of bbs to go before a debug exit. */
352ULong VG_(bbs_to_go);
353
354/* Produce debugging output? */
355Bool VG_(disassemble) = False;
356
357/* The current LRU epoch. */
358UInt VG_(current_epoch) = 0;
359
360
361/* ---------------------------------------------------------------------
362 Counters, for informational purposes only.
363 ------------------------------------------------------------------ */
364
365/* Number of lookups which miss the fast tt helper. */
366UInt VG_(tt_fast_misses) = 0;
367
368
369/* Counts for LRU informational messages. */
370
371/* Number and total o/t size of new translations this epoch. */
372UInt VG_(this_epoch_in_count) = 0;
373UInt VG_(this_epoch_in_osize) = 0;
374UInt VG_(this_epoch_in_tsize) = 0;
375/* Number and total o/t size of discarded translations this epoch. */
376UInt VG_(this_epoch_out_count) = 0;
377UInt VG_(this_epoch_out_osize) = 0;
378UInt VG_(this_epoch_out_tsize) = 0;
379/* Number and total o/t size of translations overall. */
380UInt VG_(overall_in_count) = 0;
381UInt VG_(overall_in_osize) = 0;
382UInt VG_(overall_in_tsize) = 0;
383/* Number and total o/t size of discards overall. */
384UInt VG_(overall_out_count) = 0;
385UInt VG_(overall_out_osize) = 0;
386UInt VG_(overall_out_tsize) = 0;
387
388/* The number of LRU-clearings of TT/TC. */
389UInt VG_(number_of_lrus) = 0;
390
391
392/* Counts pertaining to the register allocator. */
393
394/* total number of uinstrs input to reg-alloc */
395UInt VG_(uinstrs_prealloc) = 0;
396
397/* total number of uinstrs added due to spill code */
398UInt VG_(uinstrs_spill) = 0;
399
400/* number of bbs requiring spill code */
401UInt VG_(translations_needing_spill) = 0;
402
403/* total of register ranks over all translations */
404UInt VG_(total_reg_rank) = 0;
405
406
407/* Counts pertaining to the self-modifying-code detection machinery. */
408
409/* Total number of writes checked. */
410UInt VG_(smc_total_check4s) = 0;
411
412/* Number of writes which the fast smc check couldn't show were
413 harmless. */
414UInt VG_(smc_cache_passed) = 0;
415
416/* Numnber of writes which really did write on original code. */
417UInt VG_(smc_fancy_passed) = 0;
418
419/* Number of translations discarded as a result. */
420UInt VG_(smc_discard_count) = 0;
421
422
423/* Counts pertaining to internal sanity checking. */
424
425UInt VG_(sanity_fast_count) = 0;
426UInt VG_(sanity_slow_count) = 0;
427
428
429
430/* ---------------------------------------------------------------------
431 Values derived from command-line options.
432 ------------------------------------------------------------------ */
433
434Bool VG_(clo_GDB_attach);
435Int VG_(sanity_level);
436Int VG_(clo_verbosity);
437Bool VG_(clo_demangle);
438Bool VG_(clo_leak_check);
439Bool VG_(clo_show_reachable);
440Int VG_(clo_leak_resolution);
441Bool VG_(clo_sloppy_malloc);
442Bool VG_(clo_partial_loads_ok);
443Bool VG_(clo_trace_children);
444Int VG_(clo_logfile_fd);
445Int VG_(clo_freelist_vol);
446Bool VG_(clo_workaround_gcc296_bugs);
447Int VG_(clo_n_suppressions);
448Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
449Bool VG_(clo_single_step);
450Bool VG_(clo_optimise);
451Bool VG_(clo_instrument);
452Bool VG_(clo_cleanup);
453Bool VG_(clo_client_perms);
454Int VG_(clo_smc_check);
455Bool VG_(clo_trace_syscalls);
456Bool VG_(clo_trace_signals);
457Bool VG_(clo_trace_symtab);
458Bool VG_(clo_trace_malloc);
459ULong VG_(clo_stop_after);
460Int VG_(clo_dump_error);
461Int VG_(clo_backtrace_size);
462
463/* This Bool is needed by wrappers in vg_clientmalloc.c to decide how
464 to behave. Initially we say False. */
465Bool VG_(running_on_simd_CPU) = False;
466
467/* Holds client's %esp at the point we gained control. */
468Addr VG_(esp_at_startup);
469
470/* As deduced from VG_(esp_at_startup), the client's argc, argv[] and
471 envp[] as extracted from the client's stack at startup-time. */
472Int VG_(client_argc);
473Char** VG_(client_argv);
474Char** VG_(client_envp);
475
476/* A place into which to copy the value of env var VG_ARGS, so we
477 don't have to modify the original. */
478static Char vg_cmdline_copy[M_VG_CMDLINE_STRLEN];
479
480
481/* ---------------------------------------------------------------------
482 Top level simulation loop.
483 ------------------------------------------------------------------ */
484
485/* Create a translation of the client basic block beginning at
486 orig_addr, and add it to the translation cache & translation table.
487 This probably doesn't really belong here, but, hey ... */
488void VG_(create_translation_for) ( Addr orig_addr )
489{
490 Addr trans_addr;
491 TTEntry tte;
492 Int orig_size, trans_size;
493 /* Ensure there is space to hold a translation. */
494 VG_(maybe_do_lru_pass)();
495 VG_(translate)( orig_addr, &orig_size, &trans_addr, &trans_size );
496 /* Copy data at trans_addr into the translation cache.
497 Returned pointer is to the code, not to the 4-byte
498 header. */
499 /* Since the .orig_size and .trans_size fields are
500 UShort, be paranoid. */
501 vg_assert(orig_size > 0 && orig_size < 65536);
502 vg_assert(trans_size > 0 && trans_size < 65536);
503 tte.orig_size = orig_size;
504 tte.orig_addr = orig_addr;
505 tte.trans_size = trans_size;
506 tte.trans_addr = VG_(copy_to_transcache)
507 ( trans_addr, trans_size );
508 tte.mru_epoch = VG_(current_epoch);
509 /* Free the intermediary -- was allocated by VG_(emit_code). */
510 VG_(jitfree)( (void*)trans_addr );
511 /* Add to trans tab and set back pointer. */
512 VG_(add_to_trans_tab) ( &tte );
513 /* Update stats. */
514 VG_(this_epoch_in_count) ++;
515 VG_(this_epoch_in_osize) += orig_size;
516 VG_(this_epoch_in_tsize) += trans_size;
517 VG_(overall_in_count) ++;
518 VG_(overall_in_osize) += orig_size;
519 VG_(overall_in_tsize) += trans_size;
520 /* Record translated area for SMC detection. */
521 VG_(smc_mark_original) (
522 VG_(baseBlock)[VGOFF_(m_eip)], orig_size );
523}
524
525
526/* Runs the client program from %EIP (baseBlock[off_eip]) until it
527 asks to exit, or until vg_bbs_to_go jumps have happened (the latter
528 case is for debugging). */
529
530void VG_(toploop) ( void )
531{
532 volatile UInt dispatch_ctr_SAVED;
533 volatile Int done_this_time;
534
535 /* For the LRU structures, records when the epoch began. */
536 volatile ULong epoch_started_at = 0;
537
538 while (True) {
539 next_outer_loop:
540
541 /* Age the LRU structures if an epoch has been completed. */
542 if (VG_(bbs_done) - epoch_started_at >= VG_BBS_PER_EPOCH) {
543 VG_(current_epoch)++;
544 epoch_started_at = VG_(bbs_done);
545 if (VG_(clo_verbosity) > 2) {
546 UInt tt_used, tc_used;
547 VG_(get_tt_tc_used) ( &tt_used, &tc_used );
548 VG_(message)(Vg_UserMsg,
549 "%lu bbs, in: %d (%d -> %d), out %d (%d -> %d), TT %d, TC %d",
550 VG_(bbs_done),
551 VG_(this_epoch_in_count),
552 VG_(this_epoch_in_osize),
553 VG_(this_epoch_in_tsize),
554 VG_(this_epoch_out_count),
555 VG_(this_epoch_out_osize),
556 VG_(this_epoch_out_tsize),
557 tt_used, tc_used
558 );
559 }
560 VG_(this_epoch_in_count) = 0;
561 VG_(this_epoch_in_osize) = 0;
562 VG_(this_epoch_in_tsize) = 0;
563 VG_(this_epoch_out_count) = 0;
564 VG_(this_epoch_out_osize) = 0;
565 VG_(this_epoch_out_tsize) = 0;
566 }
567
568 /* Figure out how many bbs to ask vg_run_innerloop to do. */
569 if (VG_(bbs_to_go) >= VG_SIGCHECK_INTERVAL)
570 VG_(dispatch_ctr) = 1 + VG_SIGCHECK_INTERVAL;
571 else
572 VG_(dispatch_ctr) = 1 + (UInt)VG_(bbs_to_go);
573
574 /* ... and remember what we asked for. */
575 dispatch_ctr_SAVED = VG_(dispatch_ctr);
576
577 /* Now have a go at doing them. */
578 VG_(interrupt_reason) = VG_Y_SIGCHECK;
579 if (__builtin_setjmp(VG_(toploop_jmpbuf)) == 0) {
580 /* try this ... */
581 VG_(run_innerloop)();
582 /* We get here if the client didn't take a fault. */
583 switch (VG_(interrupt_reason)) {
584 case VG_Y_SIGCHECK:
585 /* The counter fell to zero and no other situation has
586 been detected. */
587 vg_assert(VG_(dispatch_ctr) == 0);
588 done_this_time = dispatch_ctr_SAVED - 1;
589 VG_(bbs_to_go) -= (ULong)done_this_time;
590 VG_(bbs_done) += (ULong)done_this_time;
591 /* Exit if the debug run has ended. */
592 if (VG_(bbs_to_go) == 0) goto debug_stop;
593 VG_(deliver_signals)();
594 VG_(do_sanity_checks)(False);
595 goto next_outer_loop;
596 case VG_Y_EXIT:
597 /* The target program tried to exit. */
598 done_this_time = dispatch_ctr_SAVED - VG_(dispatch_ctr_SAVED);
599 done_this_time --;
600 VG_(bbs_to_go) -= (ULong)done_this_time;
601 VG_(bbs_done) += (ULong)done_this_time;
602 return;
603 case VG_Y_SMC:
604 /* A write to original code was detected. */
605 done_this_time = dispatch_ctr_SAVED - VG_(dispatch_ctr_SAVED);
606 VG_(bbs_to_go) -= (ULong)done_this_time;
607 VG_(bbs_done) += (ULong)done_this_time;
608 VG_(flush_transtab)();
609 goto next_outer_loop;
610 case VG_Y_TRANSLATE: {
611 /* Need to provide a translation of code at vg_m_eip. */
612 done_this_time = dispatch_ctr_SAVED - VG_(dispatch_ctr);
613 vg_assert(done_this_time > 0);
614 done_this_time --;
615 VG_(bbs_to_go) -= (ULong)done_this_time;
616 VG_(bbs_done) += (ULong)done_this_time;
617 VG_(create_translation_for)(VG_(baseBlock)[VGOFF_(m_eip)]);
618 goto next_outer_loop;
619 }
620 default:
621 VG_(panic)("vg_toploop: invalid interrupt reason");
622 }
623 } else {
624 /* We get here if the client took a fault, which caused our
625 signal handler to longjmp. */
626 done_this_time = dispatch_ctr_SAVED - VG_(dispatch_ctr);
627 VG_(bbs_to_go) -= (ULong)done_this_time;
628 VG_(bbs_done) += (ULong)done_this_time;
629 if (VG_(interrupt_reason) == VG_Y_EXIT) return;
630 VG_(deliver_signals)();
631 VG_(do_sanity_checks)(False);
632 VG_(unblock_host_signal)(VG_(longjmpd_on_signal));
633 }
634 }
635
636 /* NOTREACHED */
637
638 debug_stop:
639 /* If we exited because of a debug stop, print the translation
640 of the last block executed -- by translating it again, and
641 throwing away the result. */
642 VG_(printf)(
643 "======vvvvvvvv====== LAST TRANSLATION ======vvvvvvvv======\n");
644 VG_(translate)( VG_(baseBlock)[VGOFF_(m_eip)], NULL, NULL, NULL );
645 VG_(printf)("\n");
646 VG_(printf)(
647 "======^^^^^^^^====== LAST TRANSLATION ======^^^^^^^^======\n");
648}
649
650
651/* ---------------------------------------------------------------------
652 Processing of command-line options.
653 ------------------------------------------------------------------ */
654
655static void bad_option ( Char* opt )
656{
657 VG_(shutdown_logging)();
658 VG_(clo_logfile_fd) = 2; /* stderr */
659 VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
660 VG_(exit)(1);
661}
662
663static void config_error ( Char* msg )
664{
665 VG_(shutdown_logging)();
666 VG_(clo_logfile_fd) = 2; /* stderr */
667 VG_(printf)("valgrind.so: Startup or configuration error:\n\t%s\n", msg);
668 VG_(printf)("valgrind.so: Unable to start up properly. Giving up.\n");
669 VG_(exit)(1);
670}
671
672
673static void process_cmd_line_options ( void )
674{
675 UChar* argv[M_VG_CMDLINE_OPTS];
676 UInt argc;
677 UChar* p;
678 UChar* str;
679 Int i, eventually_logfile_fd;
680
681# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
682# define STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2)))
683# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
684
685 /* Set defaults. */
686 VG_(clo_GDB_attach) = False;
687 VG_(sanity_level) = 1;
688 VG_(clo_verbosity) = 1;
689 VG_(clo_demangle) = True;
690 VG_(clo_leak_check) = False;
691 VG_(clo_show_reachable) = False;
692 VG_(clo_leak_resolution) = 2;
693 VG_(clo_sloppy_malloc) = False;
694 VG_(clo_partial_loads_ok) = True;
695 VG_(clo_trace_children) = False;
696 VG_(clo_logfile_fd) = 2; /* stderr */
697 VG_(clo_freelist_vol) = 1000000;
698 VG_(clo_workaround_gcc296_bugs) = False;
699 VG_(clo_n_suppressions) = 0;
700 VG_(clo_single_step) = False;
701 VG_(clo_optimise) = True;
702 VG_(clo_instrument) = True;
703 VG_(clo_cleanup) = True;
704 VG_(clo_client_perms) = False;
705 VG_(clo_smc_check) = /* VG_CLO_SMC_SOME */ VG_CLO_SMC_NONE;
706 VG_(clo_trace_syscalls) = False;
707 VG_(clo_trace_signals) = False;
708 VG_(clo_trace_symtab) = False;
709 VG_(clo_trace_malloc) = False;
710 VG_(clo_stop_after) = 1000000000000LL;
711 VG_(clo_dump_error) = 0;
712 VG_(clo_backtrace_size) = 4;
713
714 eventually_logfile_fd = VG_(clo_logfile_fd);
715
716 /* Once logging is started, we can safely send messages pertaining
717 to failures in initialisation. */
718 VG_(startup_logging)();
719
720 /* Magically find the client's argc/argv/envp. This kludge is
721 entirely dependent on the stack layout imposed by libc at
722 startup. Hence the magic offsets. Then check (heuristically)
723 that the results are plausible. There must be a better way to
724 do this ... */
725
726# if 0
727 /* Use this to search for the correct offsets if the tests below
728 barf. */
729 { Int i;
730 VG_(printf)("startup %%esp is %p\n", VG_(esp_at_startup) );
731 for (i = 0; i < 10; i++) {
732 Char* p = ((Char**)VG_(esp_at_startup))[i];
733 VG_(printf)("%d: %p\n", i, p);
734 }
735 }
736# endif
737
738 /* These offsets (5,6,7) are right for my RedHat 7.2 (glibc-2.2.4)
739 box. */
740
741 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [5] );
742 VG_(client_argv) = (Char**)( ((void**)VG_(esp_at_startup)) [6] );
743 VG_(client_envp) = (Char**)( ((void**)VG_(esp_at_startup)) [7] );
744
745 if ( ((UInt)VG_(client_argc)) > 0 &&
746 ((UInt)VG_(client_argc)) < 10000 &&
747 (Addr)VG_(client_argv) >= 0x8000000 &&
748 (Addr)VG_(client_envp) >= 0x8000000)
749 goto argc_argv_envp_OK;
750
751 /* If that's no good, try some other offsets discovered by KDE
752 folks on 8 Feb 02:
753 For glibc > 2.2.4 the offset 9/10/11 did the trick. Coolo found
754 out those, on I think a Caldera 3.1 with glibc 2.2.4 -- the same
755 offsets worked for on a debian sid with glibc 2.2.5. */
756
757 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [9] );
758 VG_(client_argv) = (Char**)( ((void**)VG_(esp_at_startup)) [10] );
759 VG_(client_envp) = (Char**)( ((void**)VG_(esp_at_startup)) [11] );
760
761 if ( ((UInt)VG_(client_argc)) > 0 &&
762 ((UInt)VG_(client_argc)) < 10000 &&
763 (Addr)VG_(client_argv) >= 0x8000000 &&
764 (Addr)VG_(client_envp) >= 0x8000000)
765 goto argc_argv_envp_OK;
766
767 /* Doesn't look promising. Try offsets for RedHat 6.2
768 (glibc-2.1.3) instead. In this case, the argv and envp vectors
769 are actually on the stack (bizarrely). */
770
771 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [4] );
772 VG_(client_argv) = (Char**) & ( ((void**)VG_(esp_at_startup)) [5] );
773 VG_(client_envp)
774 = (Char**) & ( ((void**)VG_(esp_at_startup)) [6 + VG_(client_argc)] );
775
776 if ( ((UInt)VG_(client_argc)) > 0 &&
777 ((UInt)VG_(client_argc)) < 10000 &&
778 (Addr)VG_(client_argv) >= 0x8000000 &&
779 (Addr)VG_(client_envp) >= 0x8000000)
780 goto argc_argv_envp_OK;
781
782 /* Here's yet another variant, from <hansen> (irc.kde.org). */
783
784 VG_(client_argc) = (Int) ( ((void**)VG_(esp_at_startup)) [9] );
785 VG_(client_argv) = (Char**) & ( ((void**)VG_(esp_at_startup)) [10] );
786 VG_(client_envp)
787 = (Char**) & ( ((void**)VG_(esp_at_startup)) [11 + VG_(client_argc)] );
788
789 if ( ((UInt)VG_(client_argc)) > 0 &&
790 ((UInt)VG_(client_argc)) < 10000 &&
791 (Addr)VG_(client_argv) >= 0x8000000 &&
792 (Addr)VG_(client_envp) >= 0x8000000)
793 goto argc_argv_envp_OK;
794
795 /* VG_(printf)("%d %p %p\n", VG_(client_argc), VG_(client_argv),
796 VG_(client_envp));
797 */
798 /* We're hosed. Give up :-( */
799 config_error(
800 "Can't get plausible values for client's argc/argv/envp.\n\t"
801 "You may be able to fix this; see process_cmd_line_options()\n\t"
802 "in vg_main.c"
803 );
804 /* NOTREACHED */
805
806 argc_argv_envp_OK:
807
808 /* Now that VG_(client_envp) has been set, we can extract the args
809 for Valgrind itself. Copy into global var so that we don't have to
810 write zeroes to the getenv'd value itself. */
811 str = VG_(getenv)("VG_ARGS");
812 argc = 0;
813
814 if (!str) {
815 config_error("Can't read options from env var VG_ARGS.");
816 }
817
818 if (VG_(strlen)(str) >= M_VG_CMDLINE_STRLEN-1) {
819 config_error("Command line length exceeds M_CMDLINE_STRLEN.");
820 }
821 VG_(strcpy)(vg_cmdline_copy, str);
822 str = NULL;
823
824 p = &vg_cmdline_copy[0];
825 while (True) {
826 while (ISSPACE(*p)) { *p = 0; p++; }
827 if (*p == 0) break;
828 if (argc < M_VG_CMDLINE_OPTS-1) {
829 argv[argc] = p; argc++;
830 } else {
831 config_error(
832 "Found more than M_CMDLINE_OPTS command-line opts.");
833 }
834 while (*p != 0 && !ISSPACE(*p)) p++;
835 }
836
837 for (i = 0; i < argc; i++) {
838
839 if (STREQ(argv[i], "-v") || STREQ(argv[i], "--verbose"))
840 VG_(clo_verbosity)++;
841 else if (STREQ(argv[i], "-q") || STREQ(argv[i], "--quiet"))
842 VG_(clo_verbosity)--;
843
844 else if (STREQ(argv[i], "--gdb-attach=yes"))
845 VG_(clo_GDB_attach) = True;
846 else if (STREQ(argv[i], "--gdb-attach=no"))
847 VG_(clo_GDB_attach) = False;
848
849 else if (STREQ(argv[i], "--demangle=yes"))
850 VG_(clo_demangle) = True;
851 else if (STREQ(argv[i], "--demangle=no"))
852 VG_(clo_demangle) = False;
853
854 else if (STREQ(argv[i], "--partial-loads-ok=yes"))
855 VG_(clo_partial_loads_ok) = True;
856 else if (STREQ(argv[i], "--partial-loads-ok=no"))
857 VG_(clo_partial_loads_ok) = False;
858
859 else if (STREQ(argv[i], "--leak-check=yes"))
860 VG_(clo_leak_check) = True;
861 else if (STREQ(argv[i], "--leak-check=no"))
862 VG_(clo_leak_check) = False;
863
864 else if (STREQ(argv[i], "--show-reachable=yes"))
865 VG_(clo_show_reachable) = True;
866 else if (STREQ(argv[i], "--show-reachable=no"))
867 VG_(clo_show_reachable) = False;
868
869 else if (STREQ(argv[i], "--leak-resolution=low"))
870 VG_(clo_leak_resolution) = 2;
871 else if (STREQ(argv[i], "--leak-resolution=med"))
872 VG_(clo_leak_resolution) = 4;
873 else if (STREQ(argv[i], "--leak-resolution=high"))
874 VG_(clo_leak_resolution) = VG_DEEPEST_BACKTRACE;
875
876 else if (STREQ(argv[i], "--sloppy-malloc=yes"))
877 VG_(clo_sloppy_malloc) = True;
878 else if (STREQ(argv[i], "--sloppy-malloc=no"))
879 VG_(clo_sloppy_malloc) = False;
880
881 else if (STREQ(argv[i], "--trace-children=yes"))
882 VG_(clo_trace_children) = True;
883 else if (STREQ(argv[i], "--trace-children=no"))
884 VG_(clo_trace_children) = False;
885
886 else if (STREQ(argv[i], "--workaround-gcc296-bugs=yes"))
887 VG_(clo_workaround_gcc296_bugs) = True;
888 else if (STREQ(argv[i], "--workaround-gcc296-bugs=no"))
889 VG_(clo_workaround_gcc296_bugs) = False;
890
891 else if (STREQN(15, argv[i], "--sanity-level="))
892 VG_(sanity_level) = (Int)VG_(atoll)(&argv[i][15]);
893
894 else if (STREQN(13, argv[i], "--logfile-fd="))
895 eventually_logfile_fd = (Int)VG_(atoll)(&argv[i][13]);
896
897 else if (STREQN(15, argv[i], "--freelist-vol=")) {
898 VG_(clo_freelist_vol) = (Int)VG_(atoll)(&argv[i][15]);
899 if (VG_(clo_freelist_vol) < 0) VG_(clo_freelist_vol) = 2;
900 }
901
902 else if (STREQN(15, argv[i], "--suppressions=")) {
903 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
904 VG_(message)(Vg_UserMsg, "Too many logfiles specified.");
905 VG_(message)(Vg_UserMsg,
906 "Increase VG_CLO_MAX_SFILES and recompile.");
907 bad_option(argv[i]);
908 }
909 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &argv[i][15];
910 VG_(clo_n_suppressions)++;
911 }
912 else if (STREQ(argv[i], "--single-step=yes"))
913 VG_(clo_single_step) = True;
914 else if (STREQ(argv[i], "--single-step=no"))
915 VG_(clo_single_step) = False;
916
917 else if (STREQ(argv[i], "--optimise=yes"))
918 VG_(clo_optimise) = True;
919 else if (STREQ(argv[i], "--optimise=no"))
920 VG_(clo_optimise) = False;
921
922 else if (STREQ(argv[i], "--instrument=yes"))
923 VG_(clo_instrument) = True;
924 else if (STREQ(argv[i], "--instrument=no"))
925 VG_(clo_instrument) = False;
926
927 else if (STREQ(argv[i], "--cleanup=yes"))
928 VG_(clo_cleanup) = True;
929 else if (STREQ(argv[i], "--cleanup=no"))
930 VG_(clo_cleanup) = False;
931
932 else if (STREQ(argv[i], "--client-perms=yes"))
933 VG_(clo_client_perms) = True;
934 else if (STREQ(argv[i], "--client-perms=no"))
935 VG_(clo_client_perms) = False;
936
937 else if (STREQ(argv[i], "--smc-check=none"))
938 VG_(clo_smc_check) = VG_CLO_SMC_NONE;
939 else if (STREQ(argv[i], "--smc-check=some"))
940 VG_(clo_smc_check) = VG_CLO_SMC_SOME;
941 else if (STREQ(argv[i], "--smc-check=all"))
942 VG_(clo_smc_check) = VG_CLO_SMC_ALL;
943
944 else if (STREQ(argv[i], "--trace-syscalls=yes"))
945 VG_(clo_trace_syscalls) = True;
946 else if (STREQ(argv[i], "--trace-syscalls=no"))
947 VG_(clo_trace_syscalls) = False;
948
949 else if (STREQ(argv[i], "--trace-signals=yes"))
950 VG_(clo_trace_signals) = True;
951 else if (STREQ(argv[i], "--trace-signals=no"))
952 VG_(clo_trace_signals) = False;
953
954 else if (STREQ(argv[i], "--trace-symtab=yes"))
955 VG_(clo_trace_symtab) = True;
956 else if (STREQ(argv[i], "--trace-symtab=no"))
957 VG_(clo_trace_symtab) = False;
958
959 else if (STREQ(argv[i], "--trace-malloc=yes"))
960 VG_(clo_trace_malloc) = True;
961 else if (STREQ(argv[i], "--trace-malloc=no"))
962 VG_(clo_trace_malloc) = False;
963
964 else if (STREQN(13, argv[i], "--stop-after="))
965 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
966
967 else if (STREQN(13, argv[i], "--dump-error="))
968 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
969
970 else if (STREQN(14, argv[i], "--num-callers=")) {
971 /* Make sure it's sane. */
972 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
973 if (VG_(clo_backtrace_size) < 2)
974 VG_(clo_backtrace_size) = 2;
975 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
976 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
977 }
978
979 else
980 bad_option(argv[i]);
981 }
982
983# undef ISSPACE
984# undef STREQ
985# undef STREQN
986
987 if (VG_(clo_verbosity < 0))
988 VG_(clo_verbosity) = 0;
989
990 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
991 VG_(message)(Vg_UserMsg, "");
992 VG_(message)(Vg_UserMsg,
993 "--gdb-attach=yes conflicts with --trace-children=yes");
994 VG_(message)(Vg_UserMsg,
995 "Please choose one or the other, but not both.");
996 bad_option("--gdb-attach=yes and --trace-children=yes");
997 }
998
999 if (VG_(clo_client_perms) && !VG_(clo_instrument)) {
1000 VG_(message)(Vg_UserMsg, "");
1001 VG_(message)(Vg_UserMsg,
1002 "--client-perms=yes requires --instrument=yes");
1003 bad_option("--client-perms=yes without --instrument=yes");
1004 }
1005
1006 if (VG_(clo_client_perms))
1007 vg_assert(VG_(clo_instrument));
1008
1009 VG_(clo_logfile_fd) = eventually_logfile_fd;
1010
1011# define STRINGIFY(xx) __STRING(xx)
1012 if (VG_(clo_verbosity > 0))
1013 VG_(message)(Vg_UserMsg,
1014 "valgrind-%s, a memory error detector for x86 GNU/Linux.",
1015 STRINGIFY(VG_VERSION));
1016# undef STRINGIFY
1017 if (VG_(clo_verbosity > 0))
1018 VG_(message)(Vg_UserMsg,
1019 "Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.");
1020 if (VG_(clo_verbosity) > 1) {
1021 VG_(message)(Vg_UserMsg, "Startup, with flags:");
1022 for (i = 0; i < argc; i++) {
1023 VG_(message)(Vg_UserMsg, " %s", argv[i]);
1024 }
1025 }
1026
1027 if (VG_(clo_n_suppressions) == 0) {
1028 config_error("No error-suppression files were specified.");
1029 }
1030}
1031
1032
1033/* ---------------------------------------------------------------------
1034 Copying to/from m_state_static.
1035 ------------------------------------------------------------------ */
1036
1037UInt VG_(m_state_static) [8 /* int regs, in Intel order */
1038 + 1 /* %eflags */
1039 + 1 /* %eip */
1040 + VG_SIZE_OF_FPUSTATE_W /* FPU state */
1041 ];
1042
1043void VG_(copy_baseBlock_to_m_state_static) ( void )
1044{
1045 Int i;
1046 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
1047 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
1048 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
1049 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
1050 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
1051 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
1052 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
1053 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
1054
1055 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_eflags)];
1056 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
1057
1058 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
1059 VG_(m_state_static)[40/4 + i]
1060 = VG_(baseBlock)[VGOFF_(m_fpustate) + i];
1061}
1062
1063
1064void VG_(copy_m_state_static_to_baseBlock) ( void )
1065{
1066 Int i;
1067 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
1068 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
1069 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
1070 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
1071 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
1072 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
1073 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
1074 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
1075
1076 VG_(baseBlock)[VGOFF_(m_eflags)] = VG_(m_state_static)[32/4];
1077 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
1078
1079 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
1080 VG_(baseBlock)[VGOFF_(m_fpustate) + i]
1081 = VG_(m_state_static)[40/4 + i];
1082}
1083
1084
1085/* ---------------------------------------------------------------------
1086 Show accumulated counts.
1087 ------------------------------------------------------------------ */
1088
1089static void vg_show_counts ( void )
1090{
1091 VG_(message)(Vg_DebugMsg,
1092 " dispatch: %lu basic blocks, %d tt_fast misses.",
1093 VG_(bbs_done), VG_(tt_fast_misses));
1094 VG_(message)(Vg_DebugMsg,
1095 "translate: new %d (%d -> %d), discard %d (%d -> %d).",
1096 VG_(overall_in_count),
1097 VG_(overall_in_osize),
1098 VG_(overall_in_tsize),
1099 VG_(overall_out_count),
1100 VG_(overall_out_osize),
1101 VG_(overall_out_tsize) );
1102 VG_(message)(Vg_DebugMsg,
1103 " lru: %d epochs, %d clearings.",
1104 VG_(current_epoch),
1105 VG_(number_of_lrus) );
1106 VG_(message)(Vg_DebugMsg,
1107 "reg-alloc: %d t-req-spill, "
1108 "%d+%d orig+spill uis, %d total-reg-r.",
1109 VG_(translations_needing_spill),
1110 VG_(uinstrs_prealloc),
1111 VG_(uinstrs_spill),
1112 VG_(total_reg_rank) );
1113 VG_(message)(Vg_DebugMsg,
1114 "smc-check: %d checks, %d fast pass, "
1115 "%d slow pass, %d discards.",
1116 VG_(smc_total_check4s),
1117 VG_(smc_cache_passed),
1118 VG_(smc_fancy_passed),
1119 VG_(smc_discard_count) );
1120 VG_(message)(Vg_DebugMsg,
1121 " sanity: %d cheap, %d expensive checks.",
1122 VG_(sanity_fast_count),
1123 VG_(sanity_slow_count) );
1124}
1125
1126
1127/* ---------------------------------------------------------------------
1128 Main!
1129 ------------------------------------------------------------------ */
1130
1131/* Where we jump to once Valgrind has got control, and the real
1132 machine's state has been copied to the m_state_static. */
1133
1134void VG_(main) ( void )
1135{
1136 Int i;
1137
1138 /* Set up our stack sanity-check words. */
1139 for (i = 0; i < 10; i++) {
1140 VG_(stack)[i] = (UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1;
1141 VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321;
1142 }
1143
1144 /* Set up baseBlock offsets and copy the saved machine's state into
1145 it. */
1146 vg_init_baseBlock();
1147 VG_(copy_m_state_static_to_baseBlock)();
1148
1149 /* Process Valgrind's command-line opts (from env var VG_OPTS). */
1150 process_cmd_line_options();
1151
1152 /* Initialise the signal handling subsystem. */
1153 VG_(sigstartup_actions)();
1154
1155# ifdef VG_PROFILE
1156 VGP_(init_profiling)();
1157# endif
1158
sewardjb3c26872002-03-24 10:05:14 +00001159 /* Hook to delay things long enough so we can get the pid and
1160 attach GDB in another shell. */
1161 /* {extern unsigned int sleep(unsigned int seconds); sleep(10);} */
1162
sewardjde4a1d02002-03-22 01:27:54 +00001163 if (VG_(clo_instrument)) {
1164 VGP_PUSHCC(VgpInitAudit);
1165 VGM_(init_memory_audit)();
1166 VGP_POPCC;
1167 VGP_PUSHCC(VgpReadSyms);
1168 VG_(read_symbols)();
1169 VGP_POPCC;
1170 }
1171
1172 /* This should come after init_memory_audit; otherwise the latter
1173 carefully sets up the permissions maps to cover the anonymous
1174 mmaps for the translation table and translation cache, which
1175 wastes > 20M of virtual address space. */
1176 VG_(init_transtab_and_SMC)();
1177
1178 if (VG_(clo_verbosity) == 1) {
1179 VG_(message)(Vg_UserMsg,
1180 "For more details, rerun with: -v");
1181 }
1182
1183 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1184 instrumented-ly. */
1185 VG_(running_on_simd_CPU) = True;
1186 if (VG_(clo_instrument)) {
1187 VGM_(make_readable) ( (Addr)&VG_(running_on_simd_CPU), 1 );
1188 VGM_(make_readable) ( (Addr)&VG_(clo_instrument), 1 );
1189 VGM_(make_readable) ( (Addr)&VG_(clo_trace_malloc), 1 );
1190 VGM_(make_readable) ( (Addr)&VG_(clo_sloppy_malloc), 1 );
1191 }
1192
1193 if (VG_(clo_verbosity) > 0)
1194 VG_(message)(Vg_UserMsg, "");
1195
1196 VG_(bbs_to_go) = VG_(clo_stop_after);
1197 VG_(toploop)();
1198
1199 if (VG_(clo_verbosity) > 0)
1200 VG_(message)(Vg_UserMsg, "");
1201
1202 if (VG_(clo_instrument)) {
1203 VG_(show_all_errors)();
1204 VG_(clientmalloc_done)();
1205 if (VG_(clo_verbosity) == 1) {
1206 VG_(message)(Vg_UserMsg,
1207 "For counts of detected errors, rerun with: -v");
1208 }
1209 if (VG_(clo_leak_check)) VG_(detect_memory_leaks)();
1210 }
1211 VG_(running_on_simd_CPU) = False;
1212
1213 VG_(do_sanity_checks)(True /*include expensive checks*/ );
1214
1215 if (VG_(clo_verbosity) > 1)
1216 vg_show_counts();
1217
1218 if (0) {
1219 VG_(message)(Vg_DebugMsg, "");
1220 VG_(message)(Vg_DebugMsg,
1221 "------ Valgrind's internal memory use stats follow ------" );
1222 VG_(mallocSanityCheckAll)();
1223 VG_(show_all_arena_stats)();
1224 VG_(message)(Vg_DebugMsg,
1225 "------ Valgrind's ExeContext management stats follow ------" );
1226 VG_(show_ExeContext_stats)();
1227 VG_(message)(Vg_DebugMsg,
1228 "------ Valgrind's client block stats follow ---------------" );
1229 VG_(show_client_block_stats)();
1230 }
1231
1232# ifdef VG_PROFILE
1233 VGP_(done_profiling)();
1234# endif
1235
1236 VG_(done_prof_mem)();
1237
1238 VG_(shutdown_logging)();
1239
1240 /* In LD_PRELOAD, convert "valgrind.so" into "valgrinq.so", so that
1241 child processes don't get traced into. Also done on simulated
1242 execve system call. */
1243 if (!VG_(clo_trace_children)) {
1244 VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
1245 }
1246
1247 /* Prepare to restore state to the real CPU. */
1248 VG_(copy_baseBlock_to_m_state_static)();
1249
1250 /* This pushes a return address on the simulator's stack, which
1251 is abandoned. We call vg_sigshutdown_actions() at the end
1252 of vg_switch_to_real_CPU(), so as to ensure that the original
1253 stack and machine state is restored before the real signal
1254 mechanism is restored.
1255 */
1256 VG_(switch_to_real_CPU)();
1257}
1258
1259
1260/* Debugging thing .. can be called from assembly with OYNK macro. */
1261void VG_(oynk) ( Int n )
1262{
1263 OINK(n);
1264}
1265
1266
1267/* Find "valgrind.so" in a LD_PRELOAD=... string, and convert it to
1268 "valgrinq.so", which doesn't do anything. This is used to avoid
1269 tracing into child processes. To make this work the build system
1270 also supplies a dummy file, "valgrinq.so".
1271*/
1272void VG_(mash_LD_PRELOAD_string)( Char* ld_preload_str )
1273{
1274 Char* p;
1275 if (ld_preload_str == NULL)
1276 return;
1277 p = VG_(strstr)(ld_preload_str, "valgrind.so");
1278 if (p == NULL)
1279 return;
1280 p[7] = 'q';
1281}
1282
1283/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1284 it to attach to this process. Called if the user requests this
1285 service after an error has been shown, so she can poke around and
1286 look at parameters, memory, etc. You can't meaningfully get GDB to
1287 continue the program, though; to continue, quit GDB. */
1288extern void VG_(start_GDB_whilst_on_client_stack) ( void )
1289{
1290 UChar buf[100];
1291 VG_(sprintf)(buf,
1292 "/usr/bin/gdb -nw /proc/%d/exe %d",
1293 VG_(getpid)(), VG_(getpid)());
1294 VG_(printf)("starting GDB with cmd: %s\n", buf);
1295 VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
1296 { /* HACK ALERT */
1297 extern int system ( const char * );
1298 system(buf);
1299 /* end of HACK ALERT */
1300 }
1301 VG_(message)(Vg_UserMsg, "");
1302 VG_(message)(Vg_UserMsg,
1303 "GDB has detached. Valgrind regains control. We continue.");
1304}
1305
1306
1307/* Print some helpful-ish text about unimplemented things, and give
1308 up. */
1309extern void VG_(unimplemented) ( Char* msg )
1310{
1311 VG_(message)(Vg_UserMsg, "");
1312 VG_(message)(Vg_UserMsg,
1313 "Valgrind detected that your program requires");
1314 VG_(message)(Vg_UserMsg,
1315 "the following unimplemented functionality:");
1316 VG_(message)(Vg_UserMsg, " %s", msg);
1317 VG_(message)(Vg_UserMsg,
1318 "This may be because the functionality is hard to implement,");
1319 VG_(message)(Vg_UserMsg,
1320 "or because no reasonable program would behave this way,");
1321 VG_(message)(Vg_UserMsg,
1322 "or because nobody has yet needed it. In any case, let me know");
1323 VG_(message)(Vg_UserMsg,
1324 "(jseward@acm.org) and/or try to work around the problem, if you can.");
1325 VG_(message)(Vg_UserMsg,
1326 "");
1327 VG_(message)(Vg_UserMsg,
1328 "Valgrind has to exit now. Sorry. Bye!");
1329 VG_(message)(Vg_UserMsg,
1330 "");
1331 VG_(exit)(1);
1332}
1333
1334
1335/*-------------------------------------------------------------*/
1336/*--- Replace some C lib things with equivs which don't get ---*/
1337/*--- spurious value warnings. THEY RUN ON SIMD CPU! ---*/
1338/*-------------------------------------------------------------*/
1339
1340char* strrchr ( const char* s, int c )
1341{
1342 UChar ch = (UChar)((UInt)c);
1343 UChar* p = (UChar*)s;
1344 UChar* last = NULL;
1345 while (True) {
1346 if (*p == ch) last = p;
1347 if (*p == 0) return last;
1348 p++;
1349 }
1350}
1351
1352char* strchr ( const char* s, int c )
1353{
1354 UChar ch = (UChar)((UInt)c);
1355 UChar* p = (UChar*)s;
1356 while (True) {
1357 if (*p == ch) return p;
1358 if (*p == 0) return NULL;
1359 p++;
1360 }
1361}
1362
1363char* strcat ( char* dest, const char* src )
1364{
1365 Char* dest_orig = dest;
1366 while (*dest) dest++;
1367 while (*src) *dest++ = *src++;
1368 *dest = 0;
1369 return dest_orig;
1370}
1371
1372unsigned int strlen ( const char* str )
1373{
1374 UInt i = 0;
1375 while (str[i] != 0) i++;
1376 return i;
1377}
1378
1379char* strcpy ( char* dest, const char* src )
1380{
1381 Char* dest_orig = dest;
1382 while (*src) *dest++ = *src++;
1383 *dest = 0;
1384 return dest_orig;
1385}
1386
1387int strncmp ( const char* s1, const char* s2, unsigned int nmax )
1388{
1389 unsigned int n = 0;
1390 while (True) {
1391 if (n >= nmax) return 0;
1392 if (*s1 == 0 && *s2 == 0) return 0;
1393 if (*s1 == 0) return -1;
1394 if (*s2 == 0) return 1;
1395
1396 if (*(UChar*)s1 < *(UChar*)s2) return -1;
1397 if (*(UChar*)s1 > *(UChar*)s2) return 1;
1398
1399 s1++; s2++; n++;
1400 }
1401}
1402
1403int strcmp ( const char* s1, const char* s2 )
1404{
1405 while (True) {
1406 if (*s1 == 0 && *s2 == 0) return 0;
1407 if (*s1 == 0) return -1;
1408 if (*s2 == 0) return 1;
1409
1410 if (*(char*)s1 < *(char*)s2) return -1;
1411 if (*(char*)s1 > *(char*)s2) return 1;
1412
1413 s1++; s2++;
1414 }
1415}
1416
1417void* memchr(const void *s, int c, unsigned int n)
1418{
1419 unsigned int i;
1420 UChar c0 = (UChar)c;
1421 UChar* p = (UChar*)s;
1422 for (i = 0; i < n; i++)
1423 if (p[i] == c0) return (void*)(&p[i]);
1424 return NULL;
1425}
1426
1427void* memcpy( void *dst, const void *src, unsigned int len )
1428{
1429 register char *d;
1430 register char *s;
1431 if ( dst > src ) {
1432 d = (char *)dst + len - 1;
1433 s = (char *)src + len - 1;
1434 while ( len-- )
1435 *d-- = *s--;
1436 } else if ( dst < src ) {
1437 d = (char *)dst;
1438 s = (char *)src;
1439 while ( len-- )
1440 *d++ = *s++;
1441 }
1442 return dst;
1443}
1444
1445/*--------------------------------------------------------------------*/
1446/*--- end vg_main.c ---*/
1447/*--------------------------------------------------------------------*/