blob: 986ddf32a6309dbf8132eea964051e7a95a2b44b [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
sewardjde4a1d02002-03-22 01:27:54 +000013
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file LICENSE.
30*/
31
32#include "vg_include.h"
33#include "vg_constants.h"
sewardjde4a1d02002-03-22 01:27:54 +000034
35
36/* ---------------------------------------------------------------------
37 Compute offsets into baseBlock. See comments in vg_include.h.
38 ------------------------------------------------------------------ */
39
40/* The variables storing offsets. */
41
42#define INVALID_OFFSET (-1)
43
44Int VGOFF_(m_eax) = INVALID_OFFSET;
45Int VGOFF_(m_ecx) = INVALID_OFFSET;
46Int VGOFF_(m_edx) = INVALID_OFFSET;
47Int VGOFF_(m_ebx) = INVALID_OFFSET;
48Int VGOFF_(m_esp) = INVALID_OFFSET;
49Int VGOFF_(m_ebp) = INVALID_OFFSET;
50Int VGOFF_(m_esi) = INVALID_OFFSET;
51Int VGOFF_(m_edi) = INVALID_OFFSET;
52Int VGOFF_(m_eflags) = INVALID_OFFSET;
53Int VGOFF_(m_fpustate) = INVALID_OFFSET;
54Int VGOFF_(m_eip) = INVALID_OFFSET;
55Int VGOFF_(spillslots) = INVALID_OFFSET;
56Int VGOFF_(sh_eax) = INVALID_OFFSET;
57Int VGOFF_(sh_ecx) = INVALID_OFFSET;
58Int VGOFF_(sh_edx) = INVALID_OFFSET;
59Int VGOFF_(sh_ebx) = INVALID_OFFSET;
60Int VGOFF_(sh_esp) = INVALID_OFFSET;
61Int VGOFF_(sh_ebp) = INVALID_OFFSET;
62Int VGOFF_(sh_esi) = INVALID_OFFSET;
63Int VGOFF_(sh_edi) = INVALID_OFFSET;
64Int VGOFF_(sh_eflags) = INVALID_OFFSET;
65Int VGOFF_(helper_idiv_64_32) = INVALID_OFFSET;
66Int VGOFF_(helper_div_64_32) = INVALID_OFFSET;
67Int VGOFF_(helper_idiv_32_16) = INVALID_OFFSET;
68Int VGOFF_(helper_div_32_16) = INVALID_OFFSET;
69Int VGOFF_(helper_idiv_16_8) = INVALID_OFFSET;
70Int VGOFF_(helper_div_16_8) = INVALID_OFFSET;
71Int VGOFF_(helper_imul_32_64) = INVALID_OFFSET;
72Int VGOFF_(helper_mul_32_64) = INVALID_OFFSET;
73Int VGOFF_(helper_imul_16_32) = INVALID_OFFSET;
74Int VGOFF_(helper_mul_16_32) = INVALID_OFFSET;
75Int VGOFF_(helper_imul_8_16) = INVALID_OFFSET;
76Int VGOFF_(helper_mul_8_16) = INVALID_OFFSET;
77Int VGOFF_(helper_CLD) = INVALID_OFFSET;
78Int VGOFF_(helper_STD) = INVALID_OFFSET;
79Int VGOFF_(helper_get_dirflag) = INVALID_OFFSET;
sewardj7d78e782002-06-02 00:04:00 +000080Int VGOFF_(helper_CLC) = INVALID_OFFSET;
81Int VGOFF_(helper_STC) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000082Int 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;
sewardjde4a1d02002-03-22 01:27:54 +000089Int VGOFF_(helper_bsf) = INVALID_OFFSET;
90Int VGOFF_(helper_bsr) = INVALID_OFFSET;
91Int VGOFF_(helper_fstsw_AX) = INVALID_OFFSET;
92Int VGOFF_(helper_SAHF) = INVALID_OFFSET;
sewardj4d0ab1f2002-03-24 10:00:09 +000093Int VGOFF_(helper_DAS) = INVALID_OFFSET;
sewardjfe8a1662002-03-24 11:54:07 +000094Int VGOFF_(helper_DAA) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000095Int VGOFF_(helper_value_check4_fail) = INVALID_OFFSET;
96Int VGOFF_(helper_value_check2_fail) = INVALID_OFFSET;
97Int VGOFF_(helper_value_check1_fail) = INVALID_OFFSET;
98Int VGOFF_(helper_value_check0_fail) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000099Int VGOFF_(helperc_LOADV4) = INVALID_OFFSET;
100Int VGOFF_(helperc_LOADV2) = INVALID_OFFSET;
101Int VGOFF_(helperc_LOADV1) = INVALID_OFFSET;
102Int VGOFF_(helperc_STOREV4) = INVALID_OFFSET;
103Int VGOFF_(helperc_STOREV2) = INVALID_OFFSET;
104Int VGOFF_(helperc_STOREV1) = INVALID_OFFSET;
105Int VGOFF_(handle_esp_assignment) = INVALID_OFFSET;
106Int VGOFF_(fpu_write_check) = INVALID_OFFSET;
107Int VGOFF_(fpu_read_check) = INVALID_OFFSET;
njn4f9c9342002-04-29 16:03:24 +0000108Int VGOFF_(cachesim_log_non_mem_instr) = INVALID_OFFSET;
109Int VGOFF_(cachesim_log_mem_instr) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +0000110
111/* This is the actual defn of baseblock. */
112UInt VG_(baseBlock)[VG_BASEBLOCK_WORDS];
113
114/* Words. */
115static Int baB_off = 0;
116
117/* Returns the offset, in words. */
118static Int alloc_BaB ( Int words )
119{
120 Int off = baB_off;
121 baB_off += words;
122 if (baB_off >= VG_BASEBLOCK_WORDS)
123 VG_(panic)( "alloc_BaB: baseBlock is too small");
124
125 return off;
126}
127
128/* Allocate 1 word in baseBlock and set it to the given value. */
129static Int alloc_BaB_1_set ( Addr a )
130{
131 Int off = alloc_BaB(1);
132 VG_(baseBlock)[off] = (UInt)a;
133 return off;
134}
135
136
137/* Here we assign actual offsets. It's important to get the most
138 popular referents within 128 bytes of the start, so we can take
139 advantage of short addressing modes relative to %ebp. Popularity
140 of offsets was measured on 22 Feb 02 running a KDE application, and
141 the slots rearranged accordingly, with a 1.5% reduction in total
142 size of translations. */
143
144static void vg_init_baseBlock ( void )
145{
146 baB_off = 0;
147
148 /* Those with offsets under 128 are carefully chosen. */
149
150 /* WORD offsets in this column */
151 /* 0 */ VGOFF_(m_eax) = alloc_BaB(1);
152 /* 1 */ VGOFF_(m_ecx) = alloc_BaB(1);
153 /* 2 */ VGOFF_(m_edx) = alloc_BaB(1);
154 /* 3 */ VGOFF_(m_ebx) = alloc_BaB(1);
155 /* 4 */ VGOFF_(m_esp) = alloc_BaB(1);
156 /* 5 */ VGOFF_(m_ebp) = alloc_BaB(1);
157 /* 6 */ VGOFF_(m_esi) = alloc_BaB(1);
158 /* 7 */ VGOFF_(m_edi) = alloc_BaB(1);
159 /* 8 */ VGOFF_(m_eflags) = alloc_BaB(1);
160
161 /* 9 */ VGOFF_(sh_eax) = alloc_BaB(1);
162 /* 10 */ VGOFF_(sh_ecx) = alloc_BaB(1);
163 /* 11 */ VGOFF_(sh_edx) = alloc_BaB(1);
164 /* 12 */ VGOFF_(sh_ebx) = alloc_BaB(1);
165 /* 13 */ VGOFF_(sh_esp) = alloc_BaB(1);
166 /* 14 */ VGOFF_(sh_ebp) = alloc_BaB(1);
167 /* 15 */ VGOFF_(sh_esi) = alloc_BaB(1);
168 /* 16 */ VGOFF_(sh_edi) = alloc_BaB(1);
169 /* 17 */ VGOFF_(sh_eflags) = alloc_BaB(1);
170
njn4f9c9342002-04-29 16:03:24 +0000171 /* 17a */
172 VGOFF_(cachesim_log_non_mem_instr)
173 = alloc_BaB_1_set( (Addr) & VG_(cachesim_log_non_mem_instr) );
174 /* 17b */
175 VGOFF_(cachesim_log_mem_instr)
176 = alloc_BaB_1_set( (Addr) & VG_(cachesim_log_mem_instr) );
177
sewardjde4a1d02002-03-22 01:27:54 +0000178 /* 18 */
179 VGOFF_(helper_value_check4_fail)
180 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check4_fail) );
181 /* 19 */
182 VGOFF_(helper_value_check0_fail)
183 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check0_fail) );
184
185 /* 20 */
186 VGOFF_(helperc_STOREV4)
187 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV4) );
188 /* 21 */
189 VGOFF_(helperc_STOREV1)
190 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV1) );
191
192 /* 22 */
193 VGOFF_(helperc_LOADV4)
194 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV4) );
195 /* 23 */
196 VGOFF_(helperc_LOADV1)
197 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV1) );
198
199 /* 24 */
200 VGOFF_(handle_esp_assignment)
201 = alloc_BaB_1_set( (Addr) & VGM_(handle_esp_assignment) );
202
203 /* 25 */
204 VGOFF_(m_eip) = alloc_BaB(1);
205
206 /* There are currently 24 spill slots */
207 /* 26 .. 49 This overlaps the magic boundary at >= 32 words, but
208 most spills are to low numbered spill slots, so the ones above
209 the boundary don't see much action. */
210 VGOFF_(spillslots) = alloc_BaB(VG_MAX_SPILLSLOTS);
211
212 /* These two pushed beyond the boundary because 2-byte transactions
213 are rare. */
214 /* 50 */
215 VGOFF_(helperc_STOREV2)
216 = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV2) );
217 /* 51 */
218 VGOFF_(helperc_LOADV2)
219 = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV2) );
220
221 /* 52 */
222 VGOFF_(fpu_write_check)
223 = alloc_BaB_1_set( (Addr) & VGM_(fpu_write_check) );
224 /* 53 */
225 VGOFF_(fpu_read_check)
226 = alloc_BaB_1_set( (Addr) & VGM_(fpu_read_check) );
227
228 /* Actually I don't think these two are ever used. */
229 /* 54 */
230 VGOFF_(helper_value_check2_fail)
231 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check2_fail) );
232 /* 55 */
233 VGOFF_(helper_value_check1_fail)
234 = alloc_BaB_1_set( (Addr) & VG_(helper_value_check1_fail) );
235
236 /* I gave up counting at this point. Since they're way above the
237 short-amode-boundary, there's no point. */
238
239 VGOFF_(m_fpustate) = alloc_BaB(VG_SIZE_OF_FPUSTATE_W);
240
241 VGOFF_(helper_idiv_64_32)
242 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_64_32) );
243 VGOFF_(helper_div_64_32)
244 = alloc_BaB_1_set( (Addr) & VG_(helper_div_64_32) );
245 VGOFF_(helper_idiv_32_16)
246 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_32_16) );
247 VGOFF_(helper_div_32_16)
248 = alloc_BaB_1_set( (Addr) & VG_(helper_div_32_16) );
249 VGOFF_(helper_idiv_16_8)
250 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_16_8) );
251 VGOFF_(helper_div_16_8)
252 = alloc_BaB_1_set( (Addr) & VG_(helper_div_16_8) );
253
254 VGOFF_(helper_imul_32_64)
255 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_32_64) );
256 VGOFF_(helper_mul_32_64)
257 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_32_64) );
258 VGOFF_(helper_imul_16_32)
259 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_16_32) );
260 VGOFF_(helper_mul_16_32)
261 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_16_32) );
262 VGOFF_(helper_imul_8_16)
263 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_8_16) );
264 VGOFF_(helper_mul_8_16)
265 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_8_16) );
266
267 VGOFF_(helper_CLD)
268 = alloc_BaB_1_set( (Addr) & VG_(helper_CLD) );
269 VGOFF_(helper_STD)
270 = alloc_BaB_1_set( (Addr) & VG_(helper_STD) );
271 VGOFF_(helper_get_dirflag)
272 = alloc_BaB_1_set( (Addr) & VG_(helper_get_dirflag) );
273
sewardj7d78e782002-06-02 00:04:00 +0000274 VGOFF_(helper_CLC)
275 = alloc_BaB_1_set( (Addr) & VG_(helper_CLC) );
276 VGOFF_(helper_STC)
277 = alloc_BaB_1_set( (Addr) & VG_(helper_STC) );
278
sewardjde4a1d02002-03-22 01:27:54 +0000279 VGOFF_(helper_shldl)
280 = alloc_BaB_1_set( (Addr) & VG_(helper_shldl) );
281 VGOFF_(helper_shldw)
282 = alloc_BaB_1_set( (Addr) & VG_(helper_shldw) );
283 VGOFF_(helper_shrdl)
284 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdl) );
285 VGOFF_(helper_shrdw)
286 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdw) );
287
288 VGOFF_(helper_RDTSC)
289 = alloc_BaB_1_set( (Addr) & VG_(helper_RDTSC) );
290 VGOFF_(helper_CPUID)
291 = alloc_BaB_1_set( (Addr) & VG_(helper_CPUID) );
292
sewardjde4a1d02002-03-22 01:27:54 +0000293 VGOFF_(helper_bsf)
294 = alloc_BaB_1_set( (Addr) & VG_(helper_bsf) );
295 VGOFF_(helper_bsr)
296 = alloc_BaB_1_set( (Addr) & VG_(helper_bsr) );
297
298 VGOFF_(helper_fstsw_AX)
299 = alloc_BaB_1_set( (Addr) & VG_(helper_fstsw_AX) );
300 VGOFF_(helper_SAHF)
301 = alloc_BaB_1_set( (Addr) & VG_(helper_SAHF) );
sewardj4d0ab1f2002-03-24 10:00:09 +0000302 VGOFF_(helper_DAS)
303 = alloc_BaB_1_set( (Addr) & VG_(helper_DAS) );
sewardjfe8a1662002-03-24 11:54:07 +0000304 VGOFF_(helper_DAA)
305 = alloc_BaB_1_set( (Addr) & VG_(helper_DAA) );
sewardjde4a1d02002-03-22 01:27:54 +0000306}
307
308
309/* ---------------------------------------------------------------------
310 Global entities which are not referenced from generated code.
311 ------------------------------------------------------------------ */
312
313/* The stack on which Valgrind runs. We can't use the same stack as
314 the simulatee -- that's an important design decision. */
315UInt VG_(stack)[10000];
316
317/* Ditto our signal delivery stack. */
318UInt VG_(sigstack)[10000];
319
320/* Saving stuff across system calls. */
321UInt VG_(real_fpu_state_saved_over_syscall_d1)[VG_SIZE_OF_FPUSTATE_W];
322UInt VG_(real_fpu_state_saved_over_syscall_d2)[VG_SIZE_OF_FPUSTATE_W];
323Addr VG_(esp_saved_over_syscall_d1);
324Addr VG_(esp_saved_over_syscall_d2);
325
326/* Counts downwards in vg_run_innerloop. */
327UInt VG_(dispatch_ctr);
328
sewardjde4a1d02002-03-22 01:27:54 +0000329
330/* 64-bit counter for the number of basic blocks done. */
331ULong VG_(bbs_done);
332/* 64-bit counter for the number of bbs to go before a debug exit. */
333ULong VG_(bbs_to_go);
334
335/* Produce debugging output? */
336Bool VG_(disassemble) = False;
337
338/* The current LRU epoch. */
339UInt VG_(current_epoch) = 0;
340
sewardj7e87e382002-05-03 19:09:05 +0000341/* This is the ThreadId of the last thread the scheduler ran. */
342ThreadId VG_(last_run_tid) = 0;
343
sewardjde4a1d02002-03-22 01:27:54 +0000344
345/* ---------------------------------------------------------------------
346 Counters, for informational purposes only.
347 ------------------------------------------------------------------ */
348
349/* Number of lookups which miss the fast tt helper. */
350UInt VG_(tt_fast_misses) = 0;
351
352
353/* Counts for LRU informational messages. */
354
355/* Number and total o/t size of new translations this epoch. */
356UInt VG_(this_epoch_in_count) = 0;
357UInt VG_(this_epoch_in_osize) = 0;
358UInt VG_(this_epoch_in_tsize) = 0;
359/* Number and total o/t size of discarded translations this epoch. */
360UInt VG_(this_epoch_out_count) = 0;
361UInt VG_(this_epoch_out_osize) = 0;
362UInt VG_(this_epoch_out_tsize) = 0;
363/* Number and total o/t size of translations overall. */
364UInt VG_(overall_in_count) = 0;
365UInt VG_(overall_in_osize) = 0;
366UInt VG_(overall_in_tsize) = 0;
367/* Number and total o/t size of discards overall. */
368UInt VG_(overall_out_count) = 0;
369UInt VG_(overall_out_osize) = 0;
370UInt VG_(overall_out_tsize) = 0;
371
372/* The number of LRU-clearings of TT/TC. */
373UInt VG_(number_of_lrus) = 0;
374
375
376/* Counts pertaining to the register allocator. */
377
378/* total number of uinstrs input to reg-alloc */
379UInt VG_(uinstrs_prealloc) = 0;
380
381/* total number of uinstrs added due to spill code */
382UInt VG_(uinstrs_spill) = 0;
383
384/* number of bbs requiring spill code */
385UInt VG_(translations_needing_spill) = 0;
386
387/* total of register ranks over all translations */
388UInt VG_(total_reg_rank) = 0;
389
390
sewardjde4a1d02002-03-22 01:27:54 +0000391/* Counts pertaining to internal sanity checking. */
sewardjde4a1d02002-03-22 01:27:54 +0000392UInt VG_(sanity_fast_count) = 0;
393UInt VG_(sanity_slow_count) = 0;
394
sewardj2e93c502002-04-12 11:12:52 +0000395/* Counts pertaining to the scheduler. */
396UInt VG_(num_scheduling_events_MINOR) = 0;
397UInt VG_(num_scheduling_events_MAJOR) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000398
399
400/* ---------------------------------------------------------------------
401 Values derived from command-line options.
402 ------------------------------------------------------------------ */
403
sewardj97ced732002-03-25 00:07:36 +0000404Bool VG_(clo_check_addrVs);
sewardjde4a1d02002-03-22 01:27:54 +0000405Bool VG_(clo_GDB_attach);
406Int VG_(sanity_level);
407Int VG_(clo_verbosity);
408Bool VG_(clo_demangle);
409Bool VG_(clo_leak_check);
410Bool VG_(clo_show_reachable);
411Int VG_(clo_leak_resolution);
412Bool VG_(clo_sloppy_malloc);
413Bool VG_(clo_partial_loads_ok);
414Bool VG_(clo_trace_children);
415Int VG_(clo_logfile_fd);
416Int VG_(clo_freelist_vol);
417Bool VG_(clo_workaround_gcc296_bugs);
418Int VG_(clo_n_suppressions);
419Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
420Bool VG_(clo_single_step);
421Bool VG_(clo_optimise);
422Bool VG_(clo_instrument);
423Bool VG_(clo_cleanup);
njn4f9c9342002-04-29 16:03:24 +0000424Bool VG_(clo_cachesim);
sewardjde4a1d02002-03-22 01:27:54 +0000425Int VG_(clo_smc_check);
426Bool VG_(clo_trace_syscalls);
427Bool VG_(clo_trace_signals);
428Bool VG_(clo_trace_symtab);
429Bool VG_(clo_trace_malloc);
sewardj8937c812002-04-12 20:12:20 +0000430Bool VG_(clo_trace_sched);
sewardj45b4b372002-04-16 22:50:32 +0000431Int VG_(clo_trace_pthread_level);
sewardjde4a1d02002-03-22 01:27:54 +0000432ULong VG_(clo_stop_after);
433Int VG_(clo_dump_error);
434Int VG_(clo_backtrace_size);
sewardj8d365b52002-05-12 10:52:16 +0000435Char* VG_(clo_weird_hacks);
sewardjde4a1d02002-03-22 01:27:54 +0000436
437/* This Bool is needed by wrappers in vg_clientmalloc.c to decide how
438 to behave. Initially we say False. */
439Bool VG_(running_on_simd_CPU) = False;
440
441/* Holds client's %esp at the point we gained control. */
442Addr VG_(esp_at_startup);
443
444/* As deduced from VG_(esp_at_startup), the client's argc, argv[] and
445 envp[] as extracted from the client's stack at startup-time. */
446Int VG_(client_argc);
447Char** VG_(client_argv);
448Char** VG_(client_envp);
449
450/* A place into which to copy the value of env var VG_ARGS, so we
451 don't have to modify the original. */
452static Char vg_cmdline_copy[M_VG_CMDLINE_STRLEN];
453
454
455/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000456 Processing of command-line options.
457 ------------------------------------------------------------------ */
458
459static void bad_option ( Char* opt )
460{
461 VG_(shutdown_logging)();
462 VG_(clo_logfile_fd) = 2; /* stderr */
463 VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
464 VG_(exit)(1);
465}
466
467static void config_error ( Char* msg )
468{
469 VG_(shutdown_logging)();
470 VG_(clo_logfile_fd) = 2; /* stderr */
471 VG_(printf)("valgrind.so: Startup or configuration error:\n\t%s\n", msg);
472 VG_(printf)("valgrind.so: Unable to start up properly. Giving up.\n");
473 VG_(exit)(1);
474}
475
sewardja1679dd2002-05-10 22:31:40 +0000476static void args_grok_error ( Char* msg )
477{
478 VG_(shutdown_logging)();
479 VG_(clo_logfile_fd) = 2; /* stderr */
480 VG_(printf)("valgrind.so: When searching for "
481 "client's argc/argc/envp:\n\t%s\n", msg);
482 config_error("couldn't find client's argc/argc/envp");
483}
484
sewardjde4a1d02002-03-22 01:27:54 +0000485
486static void process_cmd_line_options ( void )
487{
488 UChar* argv[M_VG_CMDLINE_OPTS];
489 UInt argc;
490 UChar* p;
491 UChar* str;
sewardja1679dd2002-05-10 22:31:40 +0000492 Int i, eventually_logfile_fd, ctr;
sewardjde4a1d02002-03-22 01:27:54 +0000493
494# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
495# define STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2)))
496# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
497
498 /* Set defaults. */
sewardj97ced732002-03-25 00:07:36 +0000499 VG_(clo_check_addrVs) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000500 VG_(clo_GDB_attach) = False;
501 VG_(sanity_level) = 1;
502 VG_(clo_verbosity) = 1;
503 VG_(clo_demangle) = True;
504 VG_(clo_leak_check) = False;
505 VG_(clo_show_reachable) = False;
506 VG_(clo_leak_resolution) = 2;
507 VG_(clo_sloppy_malloc) = False;
508 VG_(clo_partial_loads_ok) = True;
509 VG_(clo_trace_children) = False;
510 VG_(clo_logfile_fd) = 2; /* stderr */
511 VG_(clo_freelist_vol) = 1000000;
512 VG_(clo_workaround_gcc296_bugs) = False;
513 VG_(clo_n_suppressions) = 0;
514 VG_(clo_single_step) = False;
515 VG_(clo_optimise) = True;
516 VG_(clo_instrument) = True;
517 VG_(clo_cleanup) = True;
sewardjde4a1d02002-03-22 01:27:54 +0000518 VG_(clo_smc_check) = /* VG_CLO_SMC_SOME */ VG_CLO_SMC_NONE;
519 VG_(clo_trace_syscalls) = False;
520 VG_(clo_trace_signals) = False;
521 VG_(clo_trace_symtab) = False;
522 VG_(clo_trace_malloc) = False;
sewardj8937c812002-04-12 20:12:20 +0000523 VG_(clo_trace_sched) = False;
sewardj45b4b372002-04-16 22:50:32 +0000524 VG_(clo_trace_pthread_level) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000525 VG_(clo_stop_after) = 1000000000000LL;
526 VG_(clo_dump_error) = 0;
527 VG_(clo_backtrace_size) = 4;
sewardj8d365b52002-05-12 10:52:16 +0000528 VG_(clo_weird_hacks) = NULL;
sewardjde4a1d02002-03-22 01:27:54 +0000529
530 eventually_logfile_fd = VG_(clo_logfile_fd);
531
532 /* Once logging is started, we can safely send messages pertaining
533 to failures in initialisation. */
534 VG_(startup_logging)();
535
sewardj38170912002-05-10 21:07:22 +0000536
sewardja1679dd2002-05-10 22:31:40 +0000537 /* (Suggested by Fabrice Bellard ... )
538 We look for the Linux ELF table and go down until we find the
sewardj38170912002-05-10 21:07:22 +0000539 envc & envp. It is not full proof, but these structures should
540 change less often than the libc ones. */
541 {
sewardja1679dd2002-05-10 22:31:40 +0000542 UInt* sp = 0; /* bogus init to keep gcc -O happy */
543
sewardj38170912002-05-10 21:07:22 +0000544 /* locate the top of the stack */
sewardja1679dd2002-05-10 22:31:40 +0000545 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
546 VG_STARTUP_STACK_BASE_1 )) {
547 sp = (UInt*)VG_STARTUP_STACK_BASE_1;
548 } else
549 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
550 VG_STARTUP_STACK_BASE_2 )) {
551 sp = (UInt*)VG_STARTUP_STACK_BASE_2;
552 } else {
553 args_grok_error(
554 "startup %esp is not near any VG_STARTUP_STACK_BASE_*\n "
555 "constants defined in vg_include.h. You should investigate."
556 );
557 }
558
sewardj38170912002-05-10 21:07:22 +0000559 /* we locate: NEW_AUX_ENT(1, AT_PAGESZ, ELF_EXEC_PAGESIZE) in
560 the elf interpreter table */
561 sp -= 2;
sewardj38170912002-05-10 21:07:22 +0000562 while (sp[0] != VKI_AT_PAGESZ || sp[1] != 4096) {
sewardja1679dd2002-05-10 22:31:40 +0000563 /* VG_(printf)("trying %p\n", sp); */
sewardj38170912002-05-10 21:07:22 +0000564 sp--;
565 }
sewardj38170912002-05-10 21:07:22 +0000566
567 if (sp[2] == VKI_AT_BASE
568 && sp[0] == VKI_AT_PAGESZ
569 && sp[-2] == VKI_AT_PHNUM
570 && sp[-4] == VKI_AT_PHENT
sewardjd9c2d6d2002-05-18 11:55:05 +0000571 && sp[-6] == VKI_AT_PHDR
572 && sp[-6-1] == 0) {
sewardja1679dd2002-05-10 22:31:40 +0000573 if (0)
574 VG_(printf)("Looks like you've got a 2.2.X kernel here.\n");
sewardj38170912002-05-10 21:07:22 +0000575 sp -= 6;
sewardja1679dd2002-05-10 22:31:40 +0000576 } else
577 if (sp[2] == VKI_AT_CLKTCK
578 && sp[0] == VKI_AT_PAGESZ
sewardjd9c2d6d2002-05-18 11:55:05 +0000579 && sp[-2] == VKI_AT_HWCAP
580 && sp[-2-1] == 0) {
sewardja1679dd2002-05-10 22:31:40 +0000581 if (0)
582 VG_(printf)("Looks like you've got a 2.4.X kernel here.\n");
583 sp -= 2;
584 } else
sewardjd9c2d6d2002-05-18 11:55:05 +0000585 if (sp[2] == VKI_AT_CLKTCK
586 && sp[0] == VKI_AT_PAGESZ
587 && sp[-2] == VKI_AT_HWCAP
588 && sp[-2-20-1] == 0) {
589 if (0)
590 VG_(printf)("Looks like you've got a early 2.4.X kernel here.\n");
591 sp -= 22;
592 } else
sewardja1679dd2002-05-10 22:31:40 +0000593 args_grok_error(
594 "ELF frame does not look like 2.2.X or 2.4.X.\n "
595 "See kernel sources linux/fs/binfmt_elf.c to make sense of this."
596 );
sewardj38170912002-05-10 21:07:22 +0000597
598 sp--;
sewardja1679dd2002-05-10 22:31:40 +0000599 if (*sp != 0)
600 args_grok_error("can't find NULL at end of env[]");
601
sewardj38170912002-05-10 21:07:22 +0000602 /* sp now points to NULL at the end of env[] */
sewardja1679dd2002-05-10 22:31:40 +0000603 ctr = 0;
sewardj38170912002-05-10 21:07:22 +0000604 while (True) {
605 sp --;
606 if (*sp == 0) break;
sewardja1679dd2002-05-10 22:31:40 +0000607 if (++ctr >= 1000)
608 args_grok_error(
609 "suspiciously many (1000) env[] entries; giving up");
610
sewardj38170912002-05-10 21:07:22 +0000611 }
612 /* sp now points to NULL at the end of argv[] */
sewardja1679dd2002-05-10 22:31:40 +0000613 VG_(client_envp) = (Char**)(sp+1);
sewardj38170912002-05-10 21:07:22 +0000614
sewardja1679dd2002-05-10 22:31:40 +0000615 ctr = 0;
sewardj38170912002-05-10 21:07:22 +0000616 VG_(client_argc) = 0;
617 while (True) {
618 sp--;
619 if (*sp == VG_(client_argc))
620 break;
621 VG_(client_argc)++;
sewardja1679dd2002-05-10 22:31:40 +0000622 if (++ctr >= 1000)
623 args_grok_error(
624 "suspiciously many (1000) argv[] entries; giving up");
sewardj38170912002-05-10 21:07:22 +0000625 }
626
sewardja1679dd2002-05-10 22:31:40 +0000627 VG_(client_argv) = (Char**)(sp+1);
sewardj38170912002-05-10 21:07:22 +0000628 }
629
sewardjde4a1d02002-03-22 01:27:54 +0000630 /* Now that VG_(client_envp) has been set, we can extract the args
631 for Valgrind itself. Copy into global var so that we don't have to
632 write zeroes to the getenv'd value itself. */
633 str = VG_(getenv)("VG_ARGS");
634 argc = 0;
635
636 if (!str) {
637 config_error("Can't read options from env var VG_ARGS.");
638 }
639
640 if (VG_(strlen)(str) >= M_VG_CMDLINE_STRLEN-1) {
641 config_error("Command line length exceeds M_CMDLINE_STRLEN.");
642 }
643 VG_(strcpy)(vg_cmdline_copy, str);
644 str = NULL;
645
646 p = &vg_cmdline_copy[0];
647 while (True) {
648 while (ISSPACE(*p)) { *p = 0; p++; }
649 if (*p == 0) break;
650 if (argc < M_VG_CMDLINE_OPTS-1) {
651 argv[argc] = p; argc++;
652 } else {
653 config_error(
654 "Found more than M_CMDLINE_OPTS command-line opts.");
655 }
656 while (*p != 0 && !ISSPACE(*p)) p++;
657 }
658
659 for (i = 0; i < argc; i++) {
660
661 if (STREQ(argv[i], "-v") || STREQ(argv[i], "--verbose"))
662 VG_(clo_verbosity)++;
663 else if (STREQ(argv[i], "-q") || STREQ(argv[i], "--quiet"))
664 VG_(clo_verbosity)--;
665
sewardj97ced732002-03-25 00:07:36 +0000666 else if (STREQ(argv[i], "--check-addrVs=yes"))
667 VG_(clo_check_addrVs) = True;
668 else if (STREQ(argv[i], "--check-addrVs=no"))
669 VG_(clo_check_addrVs) = False;
670
sewardjde4a1d02002-03-22 01:27:54 +0000671 else if (STREQ(argv[i], "--gdb-attach=yes"))
672 VG_(clo_GDB_attach) = True;
673 else if (STREQ(argv[i], "--gdb-attach=no"))
674 VG_(clo_GDB_attach) = False;
675
676 else if (STREQ(argv[i], "--demangle=yes"))
677 VG_(clo_demangle) = True;
678 else if (STREQ(argv[i], "--demangle=no"))
679 VG_(clo_demangle) = False;
680
681 else if (STREQ(argv[i], "--partial-loads-ok=yes"))
682 VG_(clo_partial_loads_ok) = True;
683 else if (STREQ(argv[i], "--partial-loads-ok=no"))
684 VG_(clo_partial_loads_ok) = False;
685
686 else if (STREQ(argv[i], "--leak-check=yes"))
687 VG_(clo_leak_check) = True;
688 else if (STREQ(argv[i], "--leak-check=no"))
689 VG_(clo_leak_check) = False;
690
691 else if (STREQ(argv[i], "--show-reachable=yes"))
692 VG_(clo_show_reachable) = True;
693 else if (STREQ(argv[i], "--show-reachable=no"))
694 VG_(clo_show_reachable) = False;
695
696 else if (STREQ(argv[i], "--leak-resolution=low"))
697 VG_(clo_leak_resolution) = 2;
698 else if (STREQ(argv[i], "--leak-resolution=med"))
699 VG_(clo_leak_resolution) = 4;
700 else if (STREQ(argv[i], "--leak-resolution=high"))
701 VG_(clo_leak_resolution) = VG_DEEPEST_BACKTRACE;
702
703 else if (STREQ(argv[i], "--sloppy-malloc=yes"))
704 VG_(clo_sloppy_malloc) = True;
705 else if (STREQ(argv[i], "--sloppy-malloc=no"))
706 VG_(clo_sloppy_malloc) = False;
707
708 else if (STREQ(argv[i], "--trace-children=yes"))
709 VG_(clo_trace_children) = True;
710 else if (STREQ(argv[i], "--trace-children=no"))
711 VG_(clo_trace_children) = False;
712
713 else if (STREQ(argv[i], "--workaround-gcc296-bugs=yes"))
714 VG_(clo_workaround_gcc296_bugs) = True;
715 else if (STREQ(argv[i], "--workaround-gcc296-bugs=no"))
716 VG_(clo_workaround_gcc296_bugs) = False;
717
718 else if (STREQN(15, argv[i], "--sanity-level="))
719 VG_(sanity_level) = (Int)VG_(atoll)(&argv[i][15]);
720
721 else if (STREQN(13, argv[i], "--logfile-fd="))
722 eventually_logfile_fd = (Int)VG_(atoll)(&argv[i][13]);
723
724 else if (STREQN(15, argv[i], "--freelist-vol=")) {
725 VG_(clo_freelist_vol) = (Int)VG_(atoll)(&argv[i][15]);
726 if (VG_(clo_freelist_vol) < 0) VG_(clo_freelist_vol) = 2;
727 }
728
729 else if (STREQN(15, argv[i], "--suppressions=")) {
730 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
731 VG_(message)(Vg_UserMsg, "Too many logfiles specified.");
732 VG_(message)(Vg_UserMsg,
733 "Increase VG_CLO_MAX_SFILES and recompile.");
734 bad_option(argv[i]);
735 }
736 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &argv[i][15];
737 VG_(clo_n_suppressions)++;
738 }
739 else if (STREQ(argv[i], "--single-step=yes"))
740 VG_(clo_single_step) = True;
741 else if (STREQ(argv[i], "--single-step=no"))
742 VG_(clo_single_step) = False;
743
744 else if (STREQ(argv[i], "--optimise=yes"))
745 VG_(clo_optimise) = True;
746 else if (STREQ(argv[i], "--optimise=no"))
747 VG_(clo_optimise) = False;
748
749 else if (STREQ(argv[i], "--instrument=yes"))
750 VG_(clo_instrument) = True;
751 else if (STREQ(argv[i], "--instrument=no"))
752 VG_(clo_instrument) = False;
753
754 else if (STREQ(argv[i], "--cleanup=yes"))
755 VG_(clo_cleanup) = True;
756 else if (STREQ(argv[i], "--cleanup=no"))
757 VG_(clo_cleanup) = False;
758
njn4f9c9342002-04-29 16:03:24 +0000759 else if (STREQ(argv[i], "--cachesim=yes"))
760 VG_(clo_cachesim) = True;
761 else if (STREQ(argv[i], "--cachesim=no"))
762 VG_(clo_cachesim) = False;
763
sewardjde4a1d02002-03-22 01:27:54 +0000764 else if (STREQ(argv[i], "--smc-check=none"))
765 VG_(clo_smc_check) = VG_CLO_SMC_NONE;
766 else if (STREQ(argv[i], "--smc-check=some"))
767 VG_(clo_smc_check) = VG_CLO_SMC_SOME;
768 else if (STREQ(argv[i], "--smc-check=all"))
769 VG_(clo_smc_check) = VG_CLO_SMC_ALL;
770
771 else if (STREQ(argv[i], "--trace-syscalls=yes"))
772 VG_(clo_trace_syscalls) = True;
773 else if (STREQ(argv[i], "--trace-syscalls=no"))
774 VG_(clo_trace_syscalls) = False;
775
776 else if (STREQ(argv[i], "--trace-signals=yes"))
777 VG_(clo_trace_signals) = True;
778 else if (STREQ(argv[i], "--trace-signals=no"))
779 VG_(clo_trace_signals) = False;
780
781 else if (STREQ(argv[i], "--trace-symtab=yes"))
782 VG_(clo_trace_symtab) = True;
783 else if (STREQ(argv[i], "--trace-symtab=no"))
784 VG_(clo_trace_symtab) = False;
785
786 else if (STREQ(argv[i], "--trace-malloc=yes"))
787 VG_(clo_trace_malloc) = True;
788 else if (STREQ(argv[i], "--trace-malloc=no"))
789 VG_(clo_trace_malloc) = False;
790
sewardj8937c812002-04-12 20:12:20 +0000791 else if (STREQ(argv[i], "--trace-sched=yes"))
792 VG_(clo_trace_sched) = True;
793 else if (STREQ(argv[i], "--trace-sched=no"))
794 VG_(clo_trace_sched) = False;
795
sewardj45b4b372002-04-16 22:50:32 +0000796 else if (STREQ(argv[i], "--trace-pthread=none"))
797 VG_(clo_trace_pthread_level) = 0;
798 else if (STREQ(argv[i], "--trace-pthread=some"))
799 VG_(clo_trace_pthread_level) = 1;
800 else if (STREQ(argv[i], "--trace-pthread=all"))
801 VG_(clo_trace_pthread_level) = 2;
sewardj8937c812002-04-12 20:12:20 +0000802
sewardj8d365b52002-05-12 10:52:16 +0000803 else if (STREQN(14, argv[i], "--weird-hacks="))
804 VG_(clo_weird_hacks) = &argv[i][14];
sewardj3984b852002-05-12 03:00:17 +0000805
sewardjde4a1d02002-03-22 01:27:54 +0000806 else if (STREQN(13, argv[i], "--stop-after="))
807 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
808
809 else if (STREQN(13, argv[i], "--dump-error="))
810 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
811
812 else if (STREQN(14, argv[i], "--num-callers=")) {
813 /* Make sure it's sane. */
814 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
815 if (VG_(clo_backtrace_size) < 2)
816 VG_(clo_backtrace_size) = 2;
817 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
818 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
819 }
820
821 else
822 bad_option(argv[i]);
823 }
824
825# undef ISSPACE
826# undef STREQ
827# undef STREQN
828
829 if (VG_(clo_verbosity < 0))
830 VG_(clo_verbosity) = 0;
831
832 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
833 VG_(message)(Vg_UserMsg, "");
834 VG_(message)(Vg_UserMsg,
835 "--gdb-attach=yes conflicts with --trace-children=yes");
836 VG_(message)(Vg_UserMsg,
837 "Please choose one or the other, but not both.");
838 bad_option("--gdb-attach=yes and --trace-children=yes");
839 }
840
sewardjde4a1d02002-03-22 01:27:54 +0000841 VG_(clo_logfile_fd) = eventually_logfile_fd;
842
njn4f9c9342002-04-29 16:03:24 +0000843 /* Don't do memory checking if simulating the cache. */
844 if (VG_(clo_cachesim)) {
845 VG_(clo_instrument) = False;
846 }
847
sewardj83adf412002-05-01 01:25:45 +0000848 if (VG_(clo_verbosity > 0)) {
849 if (VG_(clo_cachesim)) {
850 VG_(message)(Vg_UserMsg,
851 "cachegrind-%s, an I1/D1/L2 cache profiler for x86 GNU/Linux.",
852 VERSION);
853 } else {
854 VG_(message)(Vg_UserMsg,
855 "valgrind-%s, a memory error detector for x86 GNU/Linux.",
856 VERSION);
857 }
858 }
sewardj3b2736a2002-03-24 12:18:35 +0000859
sewardjde4a1d02002-03-22 01:27:54 +0000860 if (VG_(clo_verbosity > 0))
861 VG_(message)(Vg_UserMsg,
862 "Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.");
863 if (VG_(clo_verbosity) > 1) {
864 VG_(message)(Vg_UserMsg, "Startup, with flags:");
865 for (i = 0; i < argc; i++) {
866 VG_(message)(Vg_UserMsg, " %s", argv[i]);
867 }
868 }
869
sewardj83adf412002-05-01 01:25:45 +0000870 if (VG_(clo_n_suppressions) == 0 && !VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +0000871 config_error("No error-suppression files were specified.");
872 }
873}
874
875
876/* ---------------------------------------------------------------------
877 Copying to/from m_state_static.
878 ------------------------------------------------------------------ */
879
880UInt VG_(m_state_static) [8 /* int regs, in Intel order */
881 + 1 /* %eflags */
882 + 1 /* %eip */
883 + VG_SIZE_OF_FPUSTATE_W /* FPU state */
884 ];
885
886void VG_(copy_baseBlock_to_m_state_static) ( void )
887{
888 Int i;
889 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
890 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
891 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
892 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
893 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
894 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
895 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
896 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
897
898 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_eflags)];
899 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
900
901 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
902 VG_(m_state_static)[40/4 + i]
903 = VG_(baseBlock)[VGOFF_(m_fpustate) + i];
904}
905
906
907void VG_(copy_m_state_static_to_baseBlock) ( void )
908{
909 Int i;
910 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
911 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
912 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
913 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
914 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
915 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
916 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
917 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
918
919 VG_(baseBlock)[VGOFF_(m_eflags)] = VG_(m_state_static)[32/4];
920 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
921
922 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
923 VG_(baseBlock)[VGOFF_(m_fpustate) + i]
924 = VG_(m_state_static)[40/4 + i];
925}
926
927
928/* ---------------------------------------------------------------------
929 Show accumulated counts.
930 ------------------------------------------------------------------ */
931
932static void vg_show_counts ( void )
933{
934 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000935 " lru: %d epochs, %d clearings.",
936 VG_(current_epoch),
937 VG_(number_of_lrus) );
sewardjde4a1d02002-03-22 01:27:54 +0000938 VG_(message)(Vg_DebugMsg,
939 "translate: new %d (%d -> %d), discard %d (%d -> %d).",
940 VG_(overall_in_count),
941 VG_(overall_in_osize),
942 VG_(overall_in_tsize),
943 VG_(overall_out_count),
944 VG_(overall_out_osize),
945 VG_(overall_out_tsize) );
946 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +0000947 " dispatch: %lu basic blocks, %d/%d sched events, %d tt_fast misses.",
948 VG_(bbs_done), VG_(num_scheduling_events_MAJOR),
949 VG_(num_scheduling_events_MINOR),
950 VG_(tt_fast_misses));
sewardjde4a1d02002-03-22 01:27:54 +0000951 VG_(message)(Vg_DebugMsg,
952 "reg-alloc: %d t-req-spill, "
953 "%d+%d orig+spill uis, %d total-reg-r.",
954 VG_(translations_needing_spill),
955 VG_(uinstrs_prealloc),
956 VG_(uinstrs_spill),
957 VG_(total_reg_rank) );
958 VG_(message)(Vg_DebugMsg,
sewardjde4a1d02002-03-22 01:27:54 +0000959 " sanity: %d cheap, %d expensive checks.",
960 VG_(sanity_fast_count),
961 VG_(sanity_slow_count) );
962}
963
964
965/* ---------------------------------------------------------------------
966 Main!
967 ------------------------------------------------------------------ */
968
969/* Where we jump to once Valgrind has got control, and the real
970 machine's state has been copied to the m_state_static. */
971
972void VG_(main) ( void )
973{
sewardj2e93c502002-04-12 11:12:52 +0000974 Int i;
975 VgSchedReturnCode src;
sewardj7e87e382002-05-03 19:09:05 +0000976 ThreadState* tst;
sewardjde4a1d02002-03-22 01:27:54 +0000977
978 /* Set up our stack sanity-check words. */
979 for (i = 0; i < 10; i++) {
980 VG_(stack)[i] = (UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1;
981 VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321;
982 }
983
984 /* Set up baseBlock offsets and copy the saved machine's state into
985 it. */
986 vg_init_baseBlock();
987 VG_(copy_m_state_static_to_baseBlock)();
988
989 /* Process Valgrind's command-line opts (from env var VG_OPTS). */
990 process_cmd_line_options();
991
sewardj018f7622002-05-15 21:13:39 +0000992 /* Initialise the scheduler, and copy the client's state from
993 baseBlock into VG_(threads)[1]. This has to come before signal
994 initialisations. */
995 VG_(scheduler_init)();
996
997 /* Initialise the signal handling subsystem, temporarily parking
998 the saved blocking-mask in saved_sigmask. */
sewardjde4a1d02002-03-22 01:27:54 +0000999 VG_(sigstartup_actions)();
1000
sewardj018f7622002-05-15 21:13:39 +00001001 /* Perhaps we're profiling Valgrind? */
sewardjde4a1d02002-03-22 01:27:54 +00001002# ifdef VG_PROFILE
1003 VGP_(init_profiling)();
1004# endif
1005
sewardj5f07b662002-04-23 16:52:51 +00001006 /* Start calibration of our RDTSC-based clock. */
1007 VG_(start_rdtsc_calibration)();
1008
sewardjb3c26872002-03-24 10:05:14 +00001009 /* Hook to delay things long enough so we can get the pid and
1010 attach GDB in another shell. */
1011 /* {extern unsigned int sleep(unsigned int seconds); sleep(10);} */
1012
njn4f9c9342002-04-29 16:03:24 +00001013 if (VG_(clo_instrument) || VG_(clo_cachesim)) {
sewardjde4a1d02002-03-22 01:27:54 +00001014 VGP_PUSHCC(VgpInitAudit);
1015 VGM_(init_memory_audit)();
1016 VGP_POPCC;
sewardjde4a1d02002-03-22 01:27:54 +00001017 }
1018
sewardj18d75132002-05-16 11:06:21 +00001019 VGP_PUSHCC(VgpReadSyms);
1020 VG_(read_symbols)();
1021 VGP_POPCC;
1022
sewardj5f07b662002-04-23 16:52:51 +00001023 /* End calibration of our RDTSC-based clock, leaving it as long as
1024 we can. */
1025 VG_(end_rdtsc_calibration)();
1026
sewardjde4a1d02002-03-22 01:27:54 +00001027 /* This should come after init_memory_audit; otherwise the latter
1028 carefully sets up the permissions maps to cover the anonymous
1029 mmaps for the translation table and translation cache, which
1030 wastes > 20M of virtual address space. */
sewardj18d75132002-05-16 11:06:21 +00001031 VG_(init_tt_tc)();
sewardjde4a1d02002-03-22 01:27:54 +00001032
1033 if (VG_(clo_verbosity) == 1) {
1034 VG_(message)(Vg_UserMsg,
1035 "For more details, rerun with: -v");
1036 }
1037
1038 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1039 instrumented-ly. */
1040 VG_(running_on_simd_CPU) = True;
1041 if (VG_(clo_instrument)) {
1042 VGM_(make_readable) ( (Addr)&VG_(running_on_simd_CPU), 1 );
1043 VGM_(make_readable) ( (Addr)&VG_(clo_instrument), 1 );
1044 VGM_(make_readable) ( (Addr)&VG_(clo_trace_malloc), 1 );
1045 VGM_(make_readable) ( (Addr)&VG_(clo_sloppy_malloc), 1 );
1046 }
1047
njn4f9c9342002-04-29 16:03:24 +00001048 if (VG_(clo_cachesim))
1049 VG_(init_cachesim)();
1050
sewardjde4a1d02002-03-22 01:27:54 +00001051 if (VG_(clo_verbosity) > 0)
1052 VG_(message)(Vg_UserMsg, "");
1053
1054 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001055
sewardj018f7622002-05-15 21:13:39 +00001056 /* Run! */
sewardj671ff542002-05-07 09:25:30 +00001057 VGP_PUSHCC(VgpSched);
sewardj2e93c502002-04-12 11:12:52 +00001058 src = VG_(scheduler)();
sewardj671ff542002-05-07 09:25:30 +00001059 VGP_POPCC;
sewardjde4a1d02002-03-22 01:27:54 +00001060
1061 if (VG_(clo_verbosity) > 0)
1062 VG_(message)(Vg_UserMsg, "");
1063
sewardj2e93c502002-04-12 11:12:52 +00001064 if (src == VgSrc_Deadlock) {
1065 VG_(message)(Vg_UserMsg,
1066 "Warning: pthread scheduler exited due to deadlock");
1067 }
1068
sewardjde4a1d02002-03-22 01:27:54 +00001069 if (VG_(clo_instrument)) {
1070 VG_(show_all_errors)();
1071 VG_(clientmalloc_done)();
1072 if (VG_(clo_verbosity) == 1) {
1073 VG_(message)(Vg_UserMsg,
1074 "For counts of detected errors, rerun with: -v");
1075 }
1076 if (VG_(clo_leak_check)) VG_(detect_memory_leaks)();
1077 }
1078 VG_(running_on_simd_CPU) = False;
sewardj2e93c502002-04-12 11:12:52 +00001079
njn4f9c9342002-04-29 16:03:24 +00001080 if (VG_(clo_cachesim))
1081 VG_(show_cachesim_results)(VG_(client_argc), VG_(client_argv));
1082
sewardj0c3b53f2002-05-01 01:58:35 +00001083 VG_(do_sanity_checks)( True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001084
1085 if (VG_(clo_verbosity) > 1)
1086 vg_show_counts();
1087
1088 if (0) {
1089 VG_(message)(Vg_DebugMsg, "");
1090 VG_(message)(Vg_DebugMsg,
1091 "------ Valgrind's internal memory use stats follow ------" );
1092 VG_(mallocSanityCheckAll)();
1093 VG_(show_all_arena_stats)();
1094 VG_(message)(Vg_DebugMsg,
1095 "------ Valgrind's ExeContext management stats follow ------" );
1096 VG_(show_ExeContext_stats)();
1097 VG_(message)(Vg_DebugMsg,
1098 "------ Valgrind's client block stats follow ---------------" );
1099 VG_(show_client_block_stats)();
1100 }
1101
1102# ifdef VG_PROFILE
1103 VGP_(done_profiling)();
1104# endif
1105
1106 VG_(done_prof_mem)();
1107
1108 VG_(shutdown_logging)();
1109
sewardj3e1eb1f2002-05-18 13:14:17 +00001110 /* Remove valgrind.so from a LD_PRELOAD=... string so child
1111 processes don't get traced into. Also mess up $libdir/valgrind
1112 so that our libpthread.so disappears from view. */
sewardjde4a1d02002-03-22 01:27:54 +00001113 if (!VG_(clo_trace_children)) {
sewardj3e1eb1f2002-05-18 13:14:17 +00001114 VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH)(
1115 VG_(getenv)("LD_PRELOAD"),
1116 VG_(getenv)("LD_LIBRARY_PATH")
1117 );
sewardjde4a1d02002-03-22 01:27:54 +00001118 }
1119
sewardj7e87e382002-05-03 19:09:05 +00001120 /* Decide how to exit. This depends on what the scheduler
1121 returned. */
1122 switch (src) {
1123 case VgSrc_ExitSyscall: /* the normal way out */
1124 vg_assert(VG_(last_run_tid) > 0
1125 && VG_(last_run_tid) < VG_N_THREADS);
sewardj018f7622002-05-15 21:13:39 +00001126 tst = & VG_(threads)[VG_(last_run_tid)];
sewardj7e87e382002-05-03 19:09:05 +00001127 vg_assert(tst->status == VgTs_Runnable);
1128 /* The thread's %EBX will hold the arg to exit(), so we just
1129 do exit with that arg. */
1130 VG_(exit)( tst->m_ebx );
1131 /* NOT ALIVE HERE! */
1132 VG_(panic)("entered the afterlife in vg_main() -- ExitSyscall");
1133 break; /* what the hell :) */
sewardjde4a1d02002-03-22 01:27:54 +00001134
sewardj7e87e382002-05-03 19:09:05 +00001135 case VgSrc_Deadlock:
1136 /* Just exit now. No point in continuing. */
1137 VG_(exit)(0);
1138 VG_(panic)("entered the afterlife in vg_main() -- Deadlock");
1139 break;
1140
1141 case VgSrc_BbsDone:
1142 /* Tricky; we have to try and switch back to the real CPU.
1143 This is all very dodgy and won't work at all in the
1144 presence of threads, or if the client happened to be
1145 running a signal handler. */
1146 /* Prepare to restore state to the real CPU. */
1147 VG_(load_thread_state)(1 /* root thread */ );
1148 VG_(copy_baseBlock_to_m_state_static)();
1149
1150 /* This pushes a return address on the simulator's stack,
1151 which is abandoned. We call vg_sigshutdown_actions() at
1152 the end of vg_switch_to_real_CPU(), so as to ensure that
1153 the original stack and machine state is restored before
1154 the real signal mechanism is restored. */
1155 VG_(switch_to_real_CPU)();
1156
1157 default:
1158 VG_(panic)("vg_main(): unexpected scheduler return code");
1159 }
sewardjde4a1d02002-03-22 01:27:54 +00001160}
1161
1162
1163/* Debugging thing .. can be called from assembly with OYNK macro. */
1164void VG_(oynk) ( Int n )
1165{
1166 OINK(n);
1167}
1168
1169
1170/* Find "valgrind.so" in a LD_PRELOAD=... string, and convert it to
1171 "valgrinq.so", which doesn't do anything. This is used to avoid
1172 tracing into child processes. To make this work the build system
1173 also supplies a dummy file, "valgrinq.so".
sewardj78e25c92002-05-20 23:38:33 +00001174
1175 Also look for $(libdir)/lib/valgrind in LD_LIBRARY_PATH and change
1176 it to $(libdir)/lib/valgrinq, so as to make our libpthread.so
1177 disappear.
sewardjde4a1d02002-03-22 01:27:54 +00001178*/
sewardj3e1eb1f2002-05-18 13:14:17 +00001179void VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH) ( Char* ld_preload_str,
1180 Char* ld_library_path_str )
sewardjde4a1d02002-03-22 01:27:54 +00001181{
sewardj78e25c92002-05-20 23:38:33 +00001182 Char* p_prel = NULL;
1183 Char* p_path = NULL;
1184 Int what = 0;
1185 if (ld_preload_str == NULL || ld_library_path_str == NULL)
1186 goto mutancy;
sewardj3e1eb1f2002-05-18 13:14:17 +00001187
sewardj78e25c92002-05-20 23:38:33 +00001188 /* VG_(printf)("%s %s\n", ld_preload_str, ld_library_path_str); */
1189
1190 p_prel = VG_(strstr)(ld_preload_str, "valgrind.so");
1191 p_path = VG_(strstr)(ld_library_path_str, VG_LIBDIR);
1192
1193 if (p_prel == NULL) {
sewardj3e1eb1f2002-05-18 13:14:17 +00001194 /* perhaps already happened? */
sewardj78e25c92002-05-20 23:38:33 +00001195 what = 1;
1196 if (VG_(strstr)(ld_preload_str, "valgrinq.so") == NULL)
1197 goto mutancy;
1198 if (VG_(strstr)(ld_library_path_str, "lib/valgrinq") == NULL)
1199 goto mutancy;
sewardjde4a1d02002-03-22 01:27:54 +00001200 return;
sewardj3e1eb1f2002-05-18 13:14:17 +00001201 }
1202
sewardj78e25c92002-05-20 23:38:33 +00001203 what = 2;
1204 if (p_path == NULL) goto mutancy;
1205
1206 /* in LD_PRELOAD, turn valgrind.so into valgrinq.so. */
1207 what = 3;
1208 if (p_prel[7] != 'd') goto mutancy;
1209 p_prel[7] = 'q';
sewardj3e1eb1f2002-05-18 13:14:17 +00001210
1211 /* in LD_LIBRARY_PATH, turn $libdir/valgrind (as configure'd) from
1212 .../lib/valgrind .../lib/valgrinq, which doesn't exist,
1213 so that our own libpthread.so goes out of scope. */
sewardj78e25c92002-05-20 23:38:33 +00001214 p_path += VG_(strlen)(VG_LIBDIR);
1215 what = 4;
1216 if (p_path[0] != '/') goto mutancy;
1217 p_path++; /* step over / */
1218 what = 5;
1219 if (p_path[7] != 'd') goto mutancy;
1220 p_path[7] = 'q';
1221 return;
1222
1223 mutancy:
1224 VG_(printf)(
1225 "\nVG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH): internal error:\n"
1226 " what = %d\n"
1227 " ld_preload_str = `%s'\n"
1228 " ld_library_path_str = `%s'\n"
1229 " p_prel = `%s'\n"
1230 " p_path = `%s'\n"
1231 " VG_LIBDIR = `%s'\n",
1232 what, ld_preload_str, ld_library_path_str, p_prel, p_path, VG_LIBDIR );
1233 VG_(panic)("VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH) failed\n");
sewardjde4a1d02002-03-22 01:27:54 +00001234}
1235
sewardj3e1eb1f2002-05-18 13:14:17 +00001236
sewardjde4a1d02002-03-22 01:27:54 +00001237/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1238 it to attach to this process. Called if the user requests this
1239 service after an error has been shown, so she can poke around and
1240 look at parameters, memory, etc. You can't meaningfully get GDB to
1241 continue the program, though; to continue, quit GDB. */
1242extern void VG_(start_GDB_whilst_on_client_stack) ( void )
1243{
sewardje6a25242002-04-21 22:03:07 +00001244 Int res;
sewardjde4a1d02002-03-22 01:27:54 +00001245 UChar buf[100];
1246 VG_(sprintf)(buf,
1247 "/usr/bin/gdb -nw /proc/%d/exe %d",
1248 VG_(getpid)(), VG_(getpid)());
sewardje6a25242002-04-21 22:03:07 +00001249 VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
1250 res = VG_(system)(buf);
1251 if (res == 0) {
1252 VG_(message)(Vg_UserMsg, "");
1253 VG_(message)(Vg_UserMsg,
1254 "GDB has detached. Valgrind regains control. We continue.");
1255 } else {
1256 VG_(message)(Vg_UserMsg, "Apparently failed!");
1257 VG_(message)(Vg_UserMsg, "");
sewardjde4a1d02002-03-22 01:27:54 +00001258 }
sewardjde4a1d02002-03-22 01:27:54 +00001259}
1260
1261
1262/* Print some helpful-ish text about unimplemented things, and give
1263 up. */
sewardjcfc39b22002-05-08 01:58:18 +00001264void VG_(unimplemented) ( Char* msg )
sewardjde4a1d02002-03-22 01:27:54 +00001265{
1266 VG_(message)(Vg_UserMsg, "");
1267 VG_(message)(Vg_UserMsg,
1268 "Valgrind detected that your program requires");
1269 VG_(message)(Vg_UserMsg,
1270 "the following unimplemented functionality:");
1271 VG_(message)(Vg_UserMsg, " %s", msg);
1272 VG_(message)(Vg_UserMsg,
1273 "This may be because the functionality is hard to implement,");
1274 VG_(message)(Vg_UserMsg,
1275 "or because no reasonable program would behave this way,");
1276 VG_(message)(Vg_UserMsg,
1277 "or because nobody has yet needed it. In any case, let me know");
1278 VG_(message)(Vg_UserMsg,
1279 "(jseward@acm.org) and/or try to work around the problem, if you can.");
1280 VG_(message)(Vg_UserMsg,
1281 "");
1282 VG_(message)(Vg_UserMsg,
1283 "Valgrind has to exit now. Sorry. Bye!");
1284 VG_(message)(Vg_UserMsg,
1285 "");
sewardj15a43e12002-04-17 19:35:12 +00001286 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +00001287 VG_(exit)(1);
1288}
1289
1290
sewardjcfc39b22002-05-08 01:58:18 +00001291void VG_(nvidia_moan) ( void)
1292{
1293 VG_(message)(Vg_UserMsg,
1294 "The following failure _might_ be caused by linking to NVidia's\n "
1295 "libGL.so, so avoiding it, if you can, _might_ help you. For example,\n "
1296 "re-build any Qt libraries you are using without OpenGL support.");
1297}
1298
1299
sewardjde4a1d02002-03-22 01:27:54 +00001300/*--------------------------------------------------------------------*/
1301/*--- end vg_main.c ---*/
1302/*--------------------------------------------------------------------*/