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