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