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