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